summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README19
-rw-r--r--Roadmap7
-rw-r--r--WHATSNEW.txt446
-rw-r--r--docs/VFS.txt9
-rw-r--r--docs/announce8
-rw-r--r--docs/faq/sambafaq-2.html13
-rw-r--r--docs/htmldocs/DOMAIN_MEMBER.html25
-rw-r--r--docs/htmldocs/LDAP.html147
-rw-r--r--docs/htmldocs/debug2html.1.html68
-rw-r--r--docs/htmldocs/nmbd.8.html8
-rw-r--r--docs/htmldocs/nmblookup.1.html16
-rw-r--r--docs/htmldocs/rpcclient.1.html651
-rw-r--r--docs/htmldocs/samba.7.html8
-rw-r--r--docs/htmldocs/smb.conf.5.html976
-rw-r--r--docs/htmldocs/smbclient.1.html18
-rw-r--r--docs/htmldocs/smbd.8.html29
-rw-r--r--docs/htmldocs/smbstatus.1.html2
-rw-r--r--docs/htmldocs/swat.8.html2
-rw-r--r--docs/htmldocs/testparm.1.html11
-rw-r--r--docs/manpages/debug2html.154
-rw-r--r--docs/manpages/lmhosts.52
-rw-r--r--docs/manpages/make_smbcodepage.12
-rw-r--r--docs/manpages/nmbd.813
-rw-r--r--docs/manpages/nmblookup.119
-rw-r--r--docs/manpages/rpcclient.1809
-rw-r--r--docs/manpages/samba.714
-rw-r--r--docs/manpages/smb.conf.51258
-rw-r--r--docs/manpages/smbclient.122
-rw-r--r--docs/manpages/smbd.836
-rw-r--r--docs/manpages/smbmnt.8133
-rw-r--r--docs/manpages/smbmount.8131
-rw-r--r--docs/manpages/smbpasswd.52
-rw-r--r--docs/manpages/smbpasswd.82
-rw-r--r--docs/manpages/smbrun.12
-rw-r--r--docs/manpages/smbstatus.14
-rw-r--r--docs/manpages/smbtar.12
-rw-r--r--docs/manpages/smbumount.82
-rw-r--r--docs/manpages/swat.84
-rw-r--r--docs/manpages/testparm.116
-rw-r--r--docs/manpages/testprns.12
-rw-r--r--docs/samba.lsm11
-rw-r--r--docs/textdocs/Application_Serving.txt2
-rw-r--r--docs/textdocs/BROWSING-Config.txt2
-rw-r--r--docs/textdocs/BROWSING.txt2
-rw-r--r--docs/textdocs/BUGS.txt2
-rw-r--r--docs/textdocs/CVS_ACCESS.txt2
-rw-r--r--docs/textdocs/DHCP-Server-Configuration.txt2
-rw-r--r--docs/textdocs/DIAGNOSIS.txt52
-rw-r--r--docs/textdocs/DNIX.txt2
-rw-r--r--docs/textdocs/DOMAIN.txt2
-rw-r--r--docs/textdocs/DOMAIN_CONTROL.txt2
-rw-r--r--docs/textdocs/DOMAIN_MEMBER.txt32
-rw-r--r--docs/textdocs/ENCRYPTION.txt43
-rw-r--r--docs/textdocs/Faxing.txt2
-rw-r--r--docs/textdocs/GOTCHAS.txt2
-rw-r--r--docs/textdocs/HINTS.txt2
-rw-r--r--docs/textdocs/LDAP.txt153
-rwxr-xr-xdocs/textdocs/MIRRORS.txt2
-rw-r--r--docs/textdocs/Macintosh_Clients.txt2
-rw-r--r--docs/textdocs/NTDOMAIN.txt2
-rw-r--r--docs/textdocs/NetBIOS.txt2
-rw-r--r--docs/textdocs/OS2-Client-HOWTO.txt2
-rw-r--r--docs/textdocs/PRINTER_DRIVER.txt2
-rw-r--r--docs/textdocs/PROFILES.txt2
-rw-r--r--docs/textdocs/Passwords.txt8
-rw-r--r--docs/textdocs/Printing.txt37
-rw-r--r--docs/textdocs/README.smbmount51
-rw-r--r--docs/textdocs/Recent-FAQs.txt2
-rw-r--r--docs/textdocs/RoutedNetworks.txt2
-rw-r--r--docs/textdocs/SCO.txt2
-rw-r--r--docs/textdocs/SSLeay.txt2
-rw-r--r--docs/textdocs/Speed.txt20
-rw-r--r--docs/textdocs/Speed2.txt2
-rw-r--r--docs/textdocs/Support.txt4
-rw-r--r--docs/textdocs/Tracing.txt2
-rw-r--r--docs/textdocs/UNIX-SMB.txt2
-rw-r--r--docs/textdocs/UNIX_INSTALL.txt13
-rw-r--r--docs/textdocs/UNIX_SECURITY.txt2
-rw-r--r--docs/textdocs/Win95.txt2
-rw-r--r--docs/textdocs/WinNT.txt2
-rw-r--r--docs/textdocs/cifsntdomain.txt2
-rw-r--r--docs/textdocs/rpcclient.1.txt688
-rw-r--r--docs/textdocs/security_level.txt22
-rw-r--r--docs/yodldocs/DOMAIN_MEMBER.yo35
-rw-r--r--docs/yodldocs/LDAP.yo161
-rw-r--r--docs/yodldocs/debug2html.1.yo62
-rw-r--r--docs/yodldocs/nmbd.8.yo19
-rw-r--r--docs/yodldocs/nmblookup.1.yo17
-rw-r--r--docs/yodldocs/rpcclient.1.yo861
-rw-r--r--docs/yodldocs/samba.7.yo9
-rw-r--r--docs/yodldocs/smb.conf.5.yo1361
-rw-r--r--docs/yodldocs/smbclient.1.yo20
-rw-r--r--docs/yodldocs/smbd.8.yo42
-rw-r--r--docs/yodldocs/smbstatus.1.yo2
-rw-r--r--docs/yodldocs/swat.8.yo2
-rw-r--r--docs/yodldocs/testparm.1.yo14
-rw-r--r--examples/autofs/auto.a11
-rw-r--r--examples/autofs/mount-smb.doc65
-rw-r--r--examples/autofs/mount.smb441
-rw-r--r--examples/printer-accounting/hp5-redir3
-rw-r--r--examples/printer-accounting/lp-acct3
-rwxr-xr-xexamples/printing/smbprint2
-rw-r--r--examples/rpcclient/README11
-rw-r--r--examples/rpcclient/nettime23
-rw-r--r--examples/rpcclient/ntsd.c259
-rw-r--r--examples/validchars/validchr.combin8824 -> 9792 bytes
-rw-r--r--packaging/Caldera/README11
-rw-r--r--packaging/Caldera/findsmb141
-rw-r--r--packaging/Caldera/makefile-path.patch44
-rw-r--r--packaging/Caldera/makerpms.sh.tmpl14
-rw-r--r--packaging/Caldera/samba.log11
-rw-r--r--packaging/Caldera/samba.pamd2
-rw-r--r--packaging/Caldera/samba2.spec.tmpl282
-rw-r--r--packaging/Caldera/smb.conf291
-rwxr-xr-xpackaging/Caldera/smb.init48
-rwxr-xr-xpackaging/Caldera/smbadduser73
-rwxr-xr-xpackaging/Caldera/smbprint77
-rw-r--r--packaging/Caldera/smbusers3
-rw-r--r--packaging/Caldera/smbw.patch10
-rwxr-xr-xpackaging/Digital/package-prep16
-rwxr-xr-xpackaging/Digital/samba.init4
-rwxr-xr-xpackaging/Example/package-prep7
-rw-r--r--packaging/PHT/TurboLinux/makefile-path.patch50
-rw-r--r--packaging/PHT/TurboLinux/smb.conf2
-rw-r--r--packaging/RedHat/makefile-path.patch52
-rw-r--r--packaging/RedHat/makerpms.sh.tmpl43
-rw-r--r--packaging/RedHat/samba.log4
-rw-r--r--packaging/RedHat/samba2.spec.tmpl232
-rw-r--r--packaging/RedHat/smb.conf2
-rwxr-xr-xpackaging/SGI/idb.pl15
-rwxr-xr-xpackaging/SGI/inst.msg2
-rwxr-xr-xpackaging/SGI/mkman5
-rwxr-xr-xpackaging/SGI/mkrelease.sh10
-rw-r--r--packaging/SGI/sambalp11
-rw-r--r--packaging/SGI/smb.conf10
-rwxr-xr-xpackaging/SGI/spec.pl4
-rw-r--r--packaging/Solaris/pkg-specs/Packaging.script5
-rw-r--r--packaging/Solaris/pkg-specs/mkprototype31
-rw-r--r--packaging/Solaris/pkg-specs/pkginfo10
-rw-r--r--packaging/Solaris/pkg-specs/postinstall37
-rw-r--r--packaging/Solaris/pkg-specs/postremove30
-rw-r--r--packaging/SuSE/5.2/samba.spec3
-rw-r--r--source/.cvsignore1
-rw-r--r--source/Makefile.in1082
-rw-r--r--source/README75
-rw-r--r--source/acconfig.h51
-rw-r--r--source/aclocal.m4431
-rw-r--r--source/architecture.doc7
-rw-r--r--source/auth/pass_check.c213
-rw-r--r--source/bin/.cvsignore15
-rw-r--r--source/browserd/browserd.c142
-rw-r--r--source/browserd/srv_browserd_nt.c53
-rw-r--r--source/client/client.c785
-rw-r--r--source/client/clientutil.c975
-rw-r--r--source/client/clitar.c104
-rw-r--r--source/client/smbmnt.c201
-rw-r--r--source/client/smbmount.c1198
-rw-r--r--source/client/smbspool.c366
-rw-r--r--source/client/smbumount.c27
-rw-r--r--source/codepages/codepage_def.8521
-rw-r--r--source/codepages/codepage_def.9321
-rwxr-xr-xsource/config.guess709
-rwxr-xr-xsource/config.sub521
-rwxr-xr-xsource/configure4172
-rwxr-xr-xsource/configure.developer2
-rw-r--r--source/configure.in1062
-rwxr-xr-xsource/configure.nodebug.developer3
-rw-r--r--source/groupdb/.cvsignore1
-rw-r--r--source/groupdb/aliasdb.c151
-rw-r--r--source/groupdb/aliasfile.c111
-rw-r--r--source/groupdb/aliasldap.c425
-rw-r--r--source/groupdb/aliasnt5ldap.c476
-rw-r--r--source/groupdb/aliasunix.c331
-rw-r--r--source/groupdb/builtindb.c475
-rw-r--r--source/groupdb/builtinldap.c426
-rw-r--r--source/groupdb/builtinnt5ldap.c487
-rw-r--r--source/groupdb/builtinunix.c324
-rw-r--r--source/groupdb/groupdb.c145
-rw-r--r--source/groupdb/groupfile.c108
-rw-r--r--source/groupdb/groupldap.c436
-rw-r--r--source/groupdb/groupnt5ldap.c488
-rw-r--r--source/groupdb/groupunix.c338
-rw-r--r--source/include/DesktopDB.h32
-rw-r--r--source/include/byteorder.h31
-rw-r--r--source/include/charset.h16
-rw-r--r--source/include/client.h47
-rw-r--r--source/include/config.h.in132
-rw-r--r--source/include/debug.h18
-rw-r--r--source/include/dfs.h53
-rw-r--r--source/include/hmacmd5.h33
-rw-r--r--source/include/includes.h285
-rw-r--r--source/include/ldapdb.h319
-rw-r--r--source/include/lib_smb_proto.h682
-rw-r--r--source/include/local.h53
-rw-r--r--source/include/md5.h32
-rw-r--r--source/include/nameserv.h8
-rw-r--r--source/include/nt_printing.h135
-rw-r--r--source/include/ntdomain.h367
-rw-r--r--source/include/nterr.h1010
-rw-r--r--source/include/profile.h6
-rw-r--r--source/include/proto.h4688
-rw-r--r--source/include/rpc_atsvc.h155
-rw-r--r--source/include/rpc_brs.h81
-rw-r--r--source/include/rpc_client_proto.h721
-rw-r--r--source/include/rpc_creds.h27
-rw-r--r--source/include/rpc_dce.h198
-rw-r--r--source/include/rpc_eventlog.h133
-rw-r--r--source/include/rpc_lsa.h246
-rw-r--r--source/include/rpc_misc.h175
-rw-r--r--source/include/rpc_netlogon.h382
-rw-r--r--source/include/rpc_netsec.h61
-rw-r--r--source/include/rpc_ntlmssp.h121
-rw-r--r--source/include/rpc_parse.h33
-rw-r--r--source/include/rpc_parse_proto.h1095
-rw-r--r--source/include/rpc_reg.h99
-rw-r--r--source/include/rpc_samr.h1154
-rw-r--r--source/include/rpc_secdes.h13
-rwxr-xr-xsource/include/rpc_spoolss.h588
-rw-r--r--source/include/rpc_srvsvc.h233
-rw-r--r--source/include/rpc_svcctl.h290
-rw-r--r--source/include/rpcclient.h55
-rw-r--r--source/include/safe_string.h5
-rw-r--r--source/include/sam.h58
-rw-r--r--source/include/sids.h39
-rw-r--r--source/include/smb.h1550
-rw-r--r--source/include/smb_macros.h82
-rw-r--r--source/include/stamp-h.in2
-rw-r--r--source/include/trans2.h20
-rw-r--r--source/include/ustring.h68
-rw-r--r--source/include/vagent.h51
-rw-r--r--source/include/version.h2
-rw-r--r--source/include/vfs.h11
-rw-r--r--source/include/winbindd_proto.h2628
-rw-r--r--source/lib/.cvsignore2
-rw-r--r--source/lib/access.c38
-rw-r--r--source/lib/bitmap.c2
-rw-r--r--source/lib/charcnv.c205
-rw-r--r--source/lib/charset.c2
-rw-r--r--source/lib/cmd_interp.c1502
-rw-r--r--source/lib/crc32.c8
-rw-r--r--source/lib/debug.c268
-rw-r--r--source/lib/domain_namemap.c292
-rw-r--r--source/lib/doscalls.c39
-rw-r--r--source/lib/fault.c9
-rw-r--r--source/lib/genrand.c6
-rw-r--r--source/lib/hmacmd5.c136
-rw-r--r--source/lib/interface.c452
-rw-r--r--source/lib/kanji.c218
-rw-r--r--source/lib/md4.c4
-rw-r--r--source/lib/md5.c315
-rw-r--r--source/lib/membuffer.c393
-rw-r--r--source/lib/msrpc-agent.c247
-rw-r--r--source/lib/msrpc-client.c240
-rw-r--r--source/lib/msrpc_use.c330
-rw-r--r--source/lib/netmask.c358
-rw-r--r--source/lib/passcheck.c200
-rw-r--r--source/lib/pidfile.c9
-rw-r--r--source/lib/replace.c19
-rw-r--r--source/lib/set_uid.c391
-rw-r--r--source/lib/set_vuid.c69
-rw-r--r--source/lib/sids.c578
-rw-r--r--source/lib/smbd_creds_db.c129
-rw-r--r--source/lib/smbrun.c1
-rw-r--r--source/lib/snprintf.c70
-rw-r--r--source/lib/streams.c140
-rw-r--r--source/lib/stub_uid.c36
-rw-r--r--source/lib/surs.c54
-rw-r--r--source/lib/sursalgdomonly.c164
-rw-r--r--source/lib/sursalgnt5ldap.c95
-rw-r--r--source/lib/surstdb.c544
-rw-r--r--source/lib/system.c577
-rw-r--r--source/lib/time.c68
-rw-r--r--source/lib/unix_sec_ctxt.c303
-rw-r--r--source/lib/username.c547
-rw-r--r--source/lib/ustring.c351
-rw-r--r--source/lib/util.c4737
-rw-r--r--source/lib/util_array.c23
-rw-r--r--source/lib/util_file.c182
-rw-r--r--source/lib/util_hnd.c514
-rw-r--r--source/lib/util_pwdb.c393
-rw-r--r--source/lib/util_seaccess.c277
-rw-r--r--source/lib/util_sec.c54
-rw-r--r--source/lib/util_sid.c446
-rw-r--r--source/lib/util_sock.c515
-rw-r--r--source/lib/util_status.c160
-rw-r--r--source/lib/util_str.c340
-rw-r--r--source/lib/util_unistr.c1990
-rw-r--r--source/lib/vagent.c242
-rw-r--r--source/lib/vuser.c209
-rw-r--r--source/lib/vuser_db.c168
-rw-r--r--source/libsmb/.cvsignore2
-rw-r--r--source/libsmb/clientgen.c2034
-rw-r--r--source/libsmb/clienttrust.c1
-rw-r--r--source/libsmb/credentials.c14
-rw-r--r--source/libsmb/namequery.c903
-rw-r--r--source/libsmb/nmblib.c702
-rw-r--r--source/libsmb/nterr.c26
-rw-r--r--source/libsmb/passchange.c9
-rw-r--r--source/libsmb/pwd_cache.c225
-rw-r--r--source/libsmb/smbdes.c91
-rw-r--r--source/libsmb/smbencrypt.c587
-rw-r--r--source/libsmb/smberr.c85
-rw-r--r--source/locking/locking.c82
-rw-r--r--source/locking/locking_shm.c708
-rw-r--r--source/locking/locking_slow.c1098
-rw-r--r--source/locking/shmem.c963
-rw-r--r--source/locking/shmem_sysv.c716
-rw-r--r--source/lsarpcd/lsarpcd.c256
-rw-r--r--source/lsarpcd/secret_db.c222
-rw-r--r--source/lsarpcd/srv_lsa.c609
-rw-r--r--source/lsarpcd/srv_lsa_samdb.c735
-rw-r--r--source/ltconfig3078
-rw-r--r--source/ltmain.sh4018
-rw-r--r--source/mem_man/mem_man.c742
-rw-r--r--source/mem_man/mem_man.h92
-rw-r--r--source/msrpc/msrpcd.c577
-rw-r--r--source/msrpc/msrpcd_process.c530
-rw-r--r--source/netlogond/creds_db.c137
-rw-r--r--source/netlogond/netlogond.c134
-rw-r--r--source/netlogond/srv_netlogon_nt.c1237
-rw-r--r--source/nmbd/asyncdns.c4
-rw-r--r--source/nmbd/nmbd.c266
-rw-r--r--source/nmbd/nmbd_become_dmb.c17
-rw-r--r--source/nmbd/nmbd_become_lmb.c7
-rw-r--r--source/nmbd/nmbd_browserdb.c2
-rw-r--r--source/nmbd/nmbd_browsesync.c21
-rw-r--r--source/nmbd/nmbd_elections.c11
-rw-r--r--source/nmbd/nmbd_incomingdgrams.c34
-rw-r--r--source/nmbd/nmbd_incomingrequests.c7
-rw-r--r--source/nmbd/nmbd_logonnames.c3
-rw-r--r--source/nmbd/nmbd_mynames.c89
-rw-r--r--source/nmbd/nmbd_namelistdb.c19
-rw-r--r--source/nmbd/nmbd_namequery.c8
-rw-r--r--source/nmbd/nmbd_nameregister.c10
-rw-r--r--source/nmbd/nmbd_namerelease.c2
-rw-r--r--source/nmbd/nmbd_nodestatus.c2
-rw-r--r--source/nmbd/nmbd_packets.c160
-rw-r--r--source/nmbd/nmbd_processlogon.c89
-rw-r--r--source/nmbd/nmbd_responserecordsdb.c3
-rw-r--r--source/nmbd/nmbd_sendannounce.c12
-rw-r--r--source/nmbd/nmbd_serverlistdb.c5
-rw-r--r--source/nmbd/nmbd_subnetdb.c70
-rw-r--r--source/nmbd/nmbd_synclists.c13
-rw-r--r--source/nmbd/nmbd_winsproxy.c6
-rw-r--r--source/nmbd/nmbd_winsserver.c91
-rw-r--r--source/nmbd/nmbd_workgroupdb.c31
-rw-r--r--source/nsswitch/.cvsignore1
-rw-r--r--source/nsswitch/README13
-rw-r--r--source/nsswitch/winbind_nss.c238
-rw-r--r--source/nsswitch/winbindd.c371
-rw-r--r--source/nsswitch/winbindd.h88
-rw-r--r--source/nsswitch/winbindd_group.c172
-rw-r--r--source/nsswitch/winbindd_surs.c63
-rw-r--r--source/nsswitch/winbindd_user.c202
-rw-r--r--source/nsswitch/wins.c129
-rw-r--r--source/param/.cvsignore2
-rw-r--r--source/param/loadparm.c1229
-rw-r--r--source/param/params.c48
-rw-r--r--source/passdb/.cvsignore1
-rw-r--r--source/passdb/ldap.c1164
-rw-r--r--source/passdb/ldapdb.c1920
-rw-r--r--source/passdb/mysqlpass.c673
-rw-r--r--source/passdb/mysqlsampass.c241
-rw-r--r--source/passdb/nispass.c649
-rw-r--r--source/passdb/nt5ldap.c751
-rw-r--r--source/passdb/pass_check.c213
-rw-r--r--source/passdb/passdb.c945
-rw-r--r--source/passdb/passgrp.c58
-rw-r--r--source/passdb/passgrpldap.c190
-rw-r--r--source/passdb/passgrpnt5ldap.c243
-rw-r--r--source/passdb/sampass.c283
-rw-r--r--source/passdb/sampassdb.c818
-rw-r--r--source/passdb/sampassldap.c428
-rw-r--r--source/passdb/sampassnt5ldap.c598
-rw-r--r--source/passdb/smbpass.c988
-rw-r--r--source/passdb/smbpasschange.c198
-rw-r--r--source/passdb/smbpassfile.c189
-rw-r--r--source/passdb/smbpassgroup.c47
-rw-r--r--source/passdb/smbpassgroupunix.c227
-rw-r--r--source/passdb/smbpassnt5ldap.c542
-rw-r--r--source/printing/nt_printing.c144
-rw-r--r--source/printing/pcap.c23
-rw-r--r--source/printing/print_svid.c21
-rw-r--r--source/printing/printing.c180
-rw-r--r--source/profile/profile.c10
-rw-r--r--source/rpc_client/.cvsignore1
-rw-r--r--source/rpc_client/cli_atsvc.c270
-rw-r--r--source/rpc_client/cli_brs.c96
-rw-r--r--source/rpc_client/cli_connect.c859
-rw-r--r--source/rpc_client/cli_eventlog.c207
-rw-r--r--source/rpc_client/cli_login.c362
-rw-r--r--source/rpc_client/cli_lsarpc.c1316
-rw-r--r--source/rpc_client/cli_netlogon.c808
-rw-r--r--source/rpc_client/cli_netlogon_sync.c110
-rw-r--r--source/rpc_client/cli_pipe.c1549
-rw-r--r--source/rpc_client/cli_pipe_netsec.c338
-rw-r--r--source/rpc_client/cli_pipe_noauth.c180
-rw-r--r--source/rpc_client/cli_pipe_ntlmssp.c576
-rw-r--r--source/rpc_client/cli_reg.c1360
-rw-r--r--source/rpc_client/cli_samr.c2691
-rw-r--r--source/rpc_client/cli_spoolss.c326
-rw-r--r--source/rpc_client/cli_srvsvc.c645
-rw-r--r--source/rpc_client/cli_svcctl.c593
-rw-r--r--source/rpc_client/cli_use.c446
-rw-r--r--source/rpc_client/cli_wkssvc.c75
-rw-r--r--source/rpc_client/msrpc_lsarpc.c365
-rw-r--r--source/rpc_client/msrpc_netlogon.c259
-rw-r--r--source/rpc_client/msrpc_samr.c2027
-rw-r--r--source/rpc_client/ncacn_np_use.c487
-rw-r--r--source/rpc_client/ncalrpc_l_use.c393
-rw-r--r--source/rpc_client/ntclienttrust.c10
-rw-r--r--source/rpc_parse/.cvsignore1
-rw-r--r--source/rpc_parse/parse_at.c300
-rw-r--r--source/rpc_parse/parse_brs.c181
-rw-r--r--source/rpc_parse/parse_creds.c150
-rw-r--r--source/rpc_parse/parse_eventlog.c275
-rw-r--r--source/rpc_parse/parse_lsa.c1409
-rw-r--r--source/rpc_parse/parse_misc.c1362
-rw-r--r--source/rpc_parse/parse_net.c2249
-rw-r--r--source/rpc_parse/parse_netsec.c351
-rw-r--r--source/rpc_parse/parse_ntlmssp.c394
-rw-r--r--source/rpc_parse/parse_prs.c1204
-rw-r--r--source/rpc_parse/parse_reg.c1361
-rw-r--r--source/rpc_parse/parse_rpc.c1149
-rw-r--r--source/rpc_parse/parse_samr.c6838
-rw-r--r--source/rpc_parse/parse_sec.c706
-rw-r--r--source/rpc_parse/parse_spoolss.c4349
-rw-r--r--source/rpc_parse/parse_srv.c2543
-rw-r--r--source/rpc_parse/parse_svc.c888
-rw-r--r--source/rpc_parse/parse_vuid.c159
-rw-r--r--source/rpc_parse/parse_wks.c131
-rw-r--r--source/rpc_server/.cvsignore1
-rw-r--r--source/rpc_server/srv_brs.c76
-rw-r--r--source/rpc_server/srv_lookup.c636
-rw-r--r--source/rpc_server/srv_lsa.c652
-rw-r--r--source/rpc_server/srv_lsa_hnd.c309
-rw-r--r--source/rpc_server/srv_netlog.c983
-rw-r--r--source/rpc_server/srv_pipe.c71
-rw-r--r--source/rpc_server/srv_pipe_hnd.c408
-rw-r--r--source/rpc_server/srv_pipe_netsec.c391
-rw-r--r--source/rpc_server/srv_pipe_noauth.c174
-rw-r--r--source/rpc_server/srv_pipe_ntlmssp.c657
-rw-r--r--source/rpc_server/srv_pipe_srv.c1462
-rw-r--r--source/rpc_server/srv_reg.c260
-rw-r--r--source/rpc_server/srv_samr.c1871
-rw-r--r--source/rpc_server/srv_sid.c22
-rwxr-xr-xsource/rpc_server/srv_spoolss.c1001
-rw-r--r--source/rpc_server/srv_srvsvc.c1113
-rw-r--r--source/rpc_server/srv_svcctl.c252
-rw-r--r--source/rpc_server/srv_util.c323
-rw-r--r--source/rpc_server/srv_wkssvc.c75
-rw-r--r--source/rpcclient/cmd_atsvc.c353
-rw-r--r--source/rpcclient/cmd_brs.c84
-rw-r--r--source/rpcclient/cmd_eventlog.c92
-rw-r--r--source/rpcclient/cmd_lsarpc.c408
-rw-r--r--source/rpcclient/cmd_netlogon.c284
-rw-r--r--source/rpcclient/cmd_reg.c779
-rw-r--r--source/rpcclient/cmd_samr.c3187
-rw-r--r--source/rpcclient/cmd_spoolss.c264
-rw-r--r--source/rpcclient/cmd_srvsvc.c294
-rw-r--r--source/rpcclient/cmd_svcctl.c407
-rw-r--r--source/rpcclient/cmd_wkssvc.c22
-rw-r--r--source/rpcclient/cmdat.c35
-rw-r--r--source/rpcclient/cmdat_cmds.c57
-rw-r--r--source/rpcclient/display.c1325
-rw-r--r--source/rpcclient/display_at.c190
-rw-r--r--source/rpcclient/display_event.c101
-rw-r--r--source/rpcclient/display_reg.c168
-rw-r--r--source/rpcclient/display_sam.c685
-rw-r--r--source/rpcclient/display_sec.c236
-rw-r--r--source/rpcclient/display_spool.c457
-rw-r--r--source/rpcclient/display_srv.c1184
-rw-r--r--source/rpcclient/display_svc.c126
-rw-r--r--source/rpcclient/display_sync.c116
-rw-r--r--source/rpcclient/eventlog.c35
-rw-r--r--source/rpcclient/eventlog_cmds.c56
-rw-r--r--source/rpcclient/lsa.c35
-rw-r--r--source/rpcclient/lsa_cmds.c101
-rw-r--r--source/rpcclient/net.c35
-rw-r--r--source/rpcclient/net_cmds.c111
-rw-r--r--source/rpcclient/netlogon_cmds.c71
-rw-r--r--source/rpcclient/regedit.c34
-rw-r--r--source/rpcclient/regedit_cmds.c200
-rw-r--r--source/rpcclient/rpcclient.c764
-rw-r--r--source/rpcclient/samedit.c36
-rw-r--r--source/rpcclient/samedit_cmds.c226
-rw-r--r--source/rpcclient/spoolss.c35
-rw-r--r--source/rpcclient/spoolss_cmds.c117
-rw-r--r--source/rpcclient/svcctrl.c34
-rw-r--r--source/rpcclient/svcctrl_cmds.c133
-rw-r--r--source/samrd/.cvsignore1
-rw-r--r--source/samrd/samrd.c132
-rw-r--r--source/samrd/srv_samr_als_nt5ldap.c403
-rw-r--r--source/samrd/srv_samr_als_tdb.c406
-rw-r--r--source/samrd/srv_samr_dom_nt5ldap.c623
-rw-r--r--source/samrd/srv_samr_dom_tdb.c907
-rw-r--r--source/samrd/srv_samr_grp_tdb.c552
-rw-r--r--source/samrd/srv_samr_nt5ldap.c332
-rw-r--r--source/samrd/srv_samr_passdb.c2530
-rw-r--r--source/samrd/srv_samr_sam_tdb.c365
-rw-r--r--source/samrd/srv_samr_tdb.c480
-rw-r--r--source/samrd/srv_samr_tdb_init.c182
-rw-r--r--source/samrd/srv_samr_usr_nt5ldap.c809
-rw-r--r--source/samrd/srv_samr_usr_tdb.c1000
-rwxr-xr-xsource/script/installbin.sh7
-rwxr-xr-xsource/script/installcp.sh10
-rwxr-xr-xsource/script/installscripts.sh1
-rwxr-xr-xsource/script/installswat.sh2
-rw-r--r--source/script/makeunicodecasemap.awk59
-rwxr-xr-xsource/script/makeyodldocs.sh10
-rw-r--r--source/script/mkproto.awk34
-rw-r--r--source/script/mysql_convert.pl433
-rw-r--r--source/script/samba48
-rwxr-xr-xsource/script/samba-init.d-solaris48
-rw-r--r--source/script/samba-init.d-sysv64
-rw-r--r--source/script/smbtar11
-rw-r--r--source/smbd/.cvsignore1
-rw-r--r--source/smbd/blocking.c72
-rw-r--r--source/smbd/challenge.c61
-rw-r--r--source/smbd/chgpasswd.c636
-rw-r--r--source/smbd/close.c98
-rw-r--r--source/smbd/conn.c9
-rw-r--r--source/smbd/connection.c215
-rw-r--r--source/smbd/dfree.c87
-rw-r--r--source/smbd/dfs.c255
-rw-r--r--source/smbd/dir.c743
-rw-r--r--source/smbd/dosmode.c88
-rw-r--r--source/smbd/fileio.c562
-rw-r--r--source/smbd/filename.c401
-rw-r--r--source/smbd/files.c20
-rw-r--r--source/smbd/groupname.c223
-rw-r--r--source/smbd/ipc.c3547
-rw-r--r--source/smbd/lanman.c3219
-rw-r--r--source/smbd/mangle.c111
-rw-r--r--source/smbd/message.c30
-rw-r--r--source/smbd/negprot.c112
-rw-r--r--source/smbd/nttrans.c1227
-rw-r--r--source/smbd/open.c534
-rw-r--r--source/smbd/oplock.c663
-rw-r--r--source/smbd/password.c1496
-rw-r--r--source/smbd/pipes.c94
-rw-r--r--source/smbd/predict.c4
-rw-r--r--source/smbd/process.c483
-rw-r--r--source/smbd/quotas.c111
-rw-r--r--source/smbd/reply.c1979
-rw-r--r--source/smbd/server.c329
-rw-r--r--source/smbd/service.c346
-rw-r--r--source/smbd/ssl.c12
-rw-r--r--source/smbd/trans2.c1055
-rw-r--r--source/smbd/uid.c354
-rw-r--r--source/smbd/vfs-wrap.c19
-rw-r--r--source/smbd/vfs.c108
-rw-r--r--source/smbwrapper/realcalls.h45
-rw-r--r--source/smbwrapper/shared.c2
-rw-r--r--source/smbwrapper/smbsh.c2
-rw-r--r--source/smbwrapper/smbw.c27
-rw-r--r--source/smbwrapper/smbw_dir.c5
-rw-r--r--source/smbwrapper/wrapped.c7
-rw-r--r--source/spoolssd/spoolssd.c121
-rwxr-xr-x[-rw-r--r--]source/spoolssd/srv_spoolss_nt.c (renamed from source/rpc_server/srv_spoolss_nt.c)3547
-rw-r--r--source/srvsvcd/srv_srvsvc_nt.c1102
-rw-r--r--source/srvsvcd/srvsvcd.c119
-rw-r--r--source/svcctld/srv_svcctl_nt.c345
-rw-r--r--source/svcctld/svcctld.c119
-rw-r--r--source/tdb/.cvsignore7
-rw-r--r--source/tdb/README10
-rw-r--r--source/tdb/tdb.c231
-rw-r--r--source/tdb/tdbtest.c2
-rw-r--r--source/tdb/tdbtool.c17
-rw-r--r--source/tdb/tdbtorture.c3
-rw-r--r--source/tests/fcntl_lock.c17
-rw-r--r--source/tests/ftruncate.c3
-rw-r--r--source/tests/getgroups.c4
-rw-r--r--source/tests/sgi_sysv_hack.c46
-rw-r--r--source/tests/shared_mmap.c4
-rw-r--r--source/tests/sysv_ipc.c2
-rw-r--r--source/tests/trapdoor.c25
-rw-r--r--source/ubiqx/.cvsignore2
-rw-r--r--source/ubiqx/debugparse.c6
-rw-r--r--source/ubiqx/debugparse.h4
-rw-r--r--source/ubiqx/sys_include.h7
-rw-r--r--source/ubiqx/ubi_BinTree.c12
-rw-r--r--source/ubiqx/ubi_BinTree.h6
-rw-r--r--source/ubiqx/ubi_Cache.c4
-rw-r--r--source/ubiqx/ubi_Cache.h4
-rw-r--r--source/ubiqx/ubi_SplayTree.c12
-rw-r--r--source/ubiqx/ubi_SplayTree.h8
-rw-r--r--source/ubiqx/ubi_dLinkList.c8
-rw-r--r--source/ubiqx/ubi_dLinkList.h12
-rw-r--r--source/ubiqx/ubi_sLinkList.c8
-rw-r--r--source/ubiqx/ubi_sLinkList.h12
-rw-r--r--source/utils/debug2html.c186
-rw-r--r--source/utils/make_printerdef.c51
-rw-r--r--source/utils/make_smbcodepage.c10
-rw-r--r--source/utils/masktest.c481
-rw-r--r--source/utils/nmb-agent.c306
-rw-r--r--source/utils/nmblookup.c164
-rw-r--r--source/utils/rpctorture.c781
-rw-r--r--source/utils/smb-agent.c396
-rw-r--r--source/utils/smbfilter.c4
-rw-r--r--source/utils/smbpasswd.c447
-rw-r--r--source/utils/smbrun.c28
-rw-r--r--source/utils/status.c37
-rw-r--r--source/utils/testparm.c247
-rw-r--r--source/utils/torture.c1347
-rw-r--r--source/web/cgi.c4
-rw-r--r--source/web/diagnose.c4
-rw-r--r--source/web/startstop.c4
-rw-r--r--source/web/statuspage.c6
-rw-r--r--source/web/swat.c254
-rw-r--r--source/winregd/srv_reg_nt.c224
-rw-r--r--source/winregd/winregd.c119
-rw-r--r--source/wkssvcd/srv_wkssvc_nt.c75
-rw-r--r--source/wkssvcd/wkssvcd.c119
-rw-r--r--swat/help/welcome.html4
615 files changed, 142654 insertions, 65276 deletions
diff --git a/README b/README
index 70b4b76ac35..d1e50585c84 100644
--- a/README
+++ b/README
@@ -1,13 +1,10 @@
-This is version 2.0.X of Samba, the free SMB and CIFS client and
+This is version 2.1.0alphaX of Samba, the free SMB and CIFS client and
server for unix and other operating systems. Samba is maintained by
the Samba Team, who support the original author, Andrew Tridgell.
>>>> Please read THE WHOLE of this file as it gives important information
>>>> about the configuration and use of Samba.
-NOTE: Installation instructions may be found in
- docs/textdocs/UNIX_INSTALL.txt
-
This software is freely distributable under the GNU public license, a
copy of which you should have received with this software (in a file
called COPYING).
@@ -139,7 +136,14 @@ available on the web page.
If you would like to help with the documentation (and we _need_ help!)
then have a look at the mailing list samba-docs, archived at
-http://lists.samba.org/
+http://samba.org/listproc/samba-docs.
+
+
+FTP SITE
+--------
+
+Please use a mirror site! The list of mirrors is in docs/MIRRORS.txt.
+The master ftp site is samba.org in the directory pub/samba.
MAILING LIST
@@ -157,7 +161,7 @@ body of "subscribe samba-announce Your Name". All announcements also
go to the samba list.
For details of other Samba mailing lists and for access to archives, see
-http://lists.samba.org/
+http://samba.org/listproc.
NEWS GROUP
@@ -182,3 +186,6 @@ As well as general information and documentation, this also has searchable
archives of the mailing list and a user survey that shows who else is using
this package. Have you registered with the survey yet? :-)
+It is maintained by Paul Blackman (thanks Paul!). You can contact him
+as ictinus@samba.org.
+
diff --git a/Roadmap b/Roadmap
index 83b0bcc0e6b..2af17985d1b 100644
--- a/Roadmap
+++ b/Roadmap
@@ -1,9 +1,9 @@
-Copyright (C) 1997-1999 - Samba-Team
+Copyright (C) 1997-1998 - Samba-Team
The Samba-Team are committed to an aggressive program to deliver quality
controlled software to a well defined roadmap.
-The current Samba release 2.0.4 is called the "NT Security update".
+The current Samba release 2.0.0 is called the "Domain Client Release"
It correctly implements the Windows NT specific SMB calls,
and will operate correctly as a client in a Windows NT
@@ -24,9 +24,6 @@ are in place:
2.0.x - "NT Security update" - Allowing Windows NT Clients to
manipulate file security and ownership using native tools.
-Note that the "NT Security update" part of the Roadmap has been
-achieved with the Samba 2.0.4 release.
-
2.0.xx - "Thin Server" mode, allowing a Samba server to be
inserted into a network with no UNIX setup required.
Some management capabilities for Samba using native NT tools.
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index ab78957cca0..aec91f6edd3 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,370 +1,96 @@
- WHATS NEW IN Samba 2.0.4b
- =========================
+ WHATS NEW IN Samba (The Next Generation) 0.6
+ ============================================
-This is the latest stable release of Samba. This is the
-version that all production Samba servers should be running
-for all current bug-fixes.
+This is an ALPHA release of Samba TNG, the UNIX based SMB/CIFS file,
+print and login server for Windows systems.
-New/Changed parameters in 2.0.4
--------------------------------
+This release is to enlist the help of people who are unable to use
+cvs (http://samba.org/cvs.html) in a major development project to
+integrate Samba into a Windows NT (tm) Domain environment - the
+NT Domains for Unix project.
-There are 5 new parameters and one modified parameter in
-the smb.conf file.
+If you are running Windows 9x and do not forsee the need for or
+need to use any Windows NT Workstations on your network in the near
+future, you will not need Samba TNG or any of its functionality,
+and your assistance is not being solicited in the development of
+this project.
-allow trusted domains
-restrict anonymous
-mangle locks
-oplock break wait time
-oplock contention limit
-
-The new parameters are :
-
-allow trusted domains
----------------------
-
-This option is used in "security=domain" settings and allows
-the Samba admin to restrict access to users within the domain
-the the Samba server is in.
-
-restrict anonymous
-------------------
-
-This parameter allows the Samba admin to cause Samba to
-refuse access to anonymous users. Use of this parameter
-is only recommened for homogenous NT client environments.
-
-mangle locks
-------------
-
-This parameter was added to get around a bug in Windows NT
-when dealing with Samba running on 32-bit systems (such
-as Linux x86). This bug causes NT to send 64 bit locking
-requests to 32-bit systems even though Samba correctly
-tells the NT client not to do so. This option causes Samba
-to map the lock requests from 64 bits to 32 bits on these
-systems.
-
-oplock break wait time
-----------------------
-
-This tuning parameter, added to help with clients that don't
-respond to oplock break requests, causes Samba to deley for
-this number of milliseconds before sending an oplock break
-request to a client that caused the break to be sent. The
-default is 10ms. This is an advanced tuning parameter and
-should not be changed lightly.
-
-oplock contention limit
------------------------
-
-This tuning parameter causes Samba not to grant oplocks
-when an smbd daemon notices that there have been this
-many concurrent requests for an oplock on a file. This
-prevents the "baton passing" oplock problem where many
-clients accessing one file pass the oplock between themselves
-like a baton. The default is 2. This is an advanced tuning
-parameter and should not be changed lightly.
-
-The modified parameter is :
-
-nt acl support
---------------
-
-This is a global parameter that defaulted to False in
-the previous release (2.0.3) and now defaults to True
-as the RPC code has been added to Samba to allow it to
-map UNIX permissions to NT ACLs.
-
-All of these new parameters and changes are documented in the
-smb.conf man pages and html pages.
-
-Updated and New documentation
------------------------------
-
-A new document describing the manipulation of UNIX permissions
-via the Windows NT security dialogs and their interaction with
-Samba 2.0.4 is provided as :
-
-docs/textdocs/NT_Security.txt
-docs/htmldocs/NT_Security.html
-
-Changes in 2.0.4b
------------------
-
-A bug with MS-Word 97 saving files with zero UNIX permissions
-was fixed. Even though a workaround is available (set force
-create mode = 644 on the share) Word is such an important
-application that a point fix was neccessary.
-
-Changes in 2.0.4a
------------------
-
-The text and html versions of NT_Security were missing from
-the shipping tarball. Also a compile bug for platforms that
-don't have usleep was fixed.
-
-Bugfixes added since 2.0.3
---------------------------
-
-1). Fix for 8 character password problem when using HPUX and
-plaintext passwords.
-2). --with-pam option added to ./configure.
-3). Client fixes for memory leak and display of 64 bit values.
-4). Fixes for -E and -s option with smbclient.
-5). smbclient now allows -L //server or -L \\server
-6). smbtar fix for display of 64 bit values.
-7). Endian independence added to DCE/RPC code.
-8). DCE/RPC marshalling/unmarshalling code re-written to provide
-overflow reporting and sign and seal support.
-9). Bind NAK reply packet added to DCE/RPC code, used to correctly
-refuse bind requests (prevents NT system event log messages).
-10). Mapping of UNIX permissions into NT ACL's for get and set
-added.
-11). DCE/RPC enumeration of numbers of shares made dynamic.
-Samba now has no limit on the number of exported shares seen.
-12). Fix to speed up random number seed generation on /dev/urandom
-being unavailable.
-13). Several memory fixes added by running Purify on the code.
-14). Read from client error messages improved.
-15). Fixed endianness used in UNICODE strings.
-16). Cope with ERRORmoredata in an RPC pipe client call.
-17). Check for malformed responses in nmbd register name.
-18). NT Encrypted password changing from the NT password dialog box
-now fully implmented.
-19). Mangle 64-bit lock ranges into 32-bits (NT bug!) on a 32-bit
-Samba platform.
-20). Allow file to be pseudo-openend in order to read security only.
-21). Improve filename mangling to reduce chance of collisions.
-22). Added code to prevent granting of oplocks when a file is under
-contention.
-23). Added tunable wait time before sending an oplock break request
-to a client if the client caused the break request. Helps with clients
-not responding to oplock breaks.
-24). Always respond negatively to queued local oplock break messages
-before shutdown. This can prevent "freezes" on an oplock error.
-25). Allow admin to restrict logons to correct domain when in domain
-level security.
-26). Added "restrict anonymous" patch from Andy (thwartedefforts@wonky.org)
-to prevent parameter substitution problems with anonymous connections.
-27). Fix SMBseek where seeking to a negative number sets the offset
-to zero.
-28). Fixed problem with mode getting corrupted in trans2 request
-(setting to zero means please ignore it).
-29). Correctly become the authenticated user on an authenticated
-DCE/RPC pipe request.
-30). Correctly reset debug level in nmbd if someone set it on the
-command line.
-31). Added more checking into testparm
-32). NetBench simulator added to smbtorture by Andrew.
-33). Fixed NIS+ option compile (was broken in 2.0.3).
-34). Recursive smbclient directory listing fix. Patch from E. Jay Berkenbilt
-(ejb@ql.org)
-
-Bugfixes added since 2.0.2
---------------------------
-
-1). --with-ssl configure now include ssl include directory. Fix
-from Richard Sharpe.
-2). Patch for configure for glibc2.1 support (large files etc.).
-3). Several bugfixes for smbclient tar mode from Bob Boehmer
-(boehmer@worldnet.att.net) to fix smbclient aborting problems
-when restoring tar files.
-4). Some automount fixes for smbmount.
-5). Attempt to fix the AIX 4.1.x/3.x problems where smbd runs as
-root. As no-one has given us root access to such a server this
-cannot be tested fully, but should work.
-6). Crash bug fix in debug code where *real* uid rather than
-*effective* uid was being checked before attempting to rotate
-log files. This fix should help a *lot* of people who were
-reporting smbd aborting in the middle of a copy operation.
-7). SIGALRM bugfix to ensure infinate file locks time out.
-8). New code to implement NT ACL reporting for cacls.exe program.
-9). UDP loopback socket rebind fix for Solaris.
-10). Ensure all UNICODE strings are correctly in little-endian
-format.
-11). smbpasswd file locking fix.
-12). Fixes for strncpy problems with glibc2.1.
-13). Ensure smbd correctly reports major and minor version number
-and server type when queried via NT rpc calls.
-14). Bugfix for short mangled names not being pulled off the
-mangled stack correctly.
-15). Fix for mapping of rwx bits being incorrectly overwritten
-when doing ATTRIB.EXE
-16). Fix for returning multiple PDU packets in NT rpc code. Should
-allow multiple shares to be returned correctly).
-17). Improved mapping of NT open access requests into UNIX open
-modes.
-18). Fix for copying files from an NTFS volume that contain
-multiple data forks. Added 'magic' error code NT needs.
-19). Fixed crash bug when primary NT authentication server
-is down, rolls over to secondaries correctly now.
-20). Fixed timeout processing to be timer based. Now will
-always occur even if smbd is under load.
-21). Fixed signed/unsigned problem in quotas code.
-22). Fixed bug where setting the password of a completely fresh
-user would end up setting the account disabled flag.
-23). Improved user logon messages to help admins having
-trouble with user authentication.
-
-Bugfixes added since 2.0.1
+Major changes in Samba TNG
--------------------------
-Note that due to a critical signal handling bug in 2.0.1,
-this release has been removed and replaced immediately with
-2.0.2. The Samba Team would like to apologise for any problem
-this may have caused.
-
-1). Fixed smbd looping on SIGCLD problem. This was
- caused by a missing break statement in a critical
- piece of code.
-
-Bugfixes added since 2.0.0
---------------------------
+There are many major changes in Samba TNG. Here are some of them:
-1). Autoconf changes for gcc2.7.x and Solaris 2.5/2.6
-2). Autoconf changes to help HPUX configure correctly.
-3). Autoconf changes to allow lock directory to be set.
-4). Client fix to allow port to be set.
-5). clitar fix to send debug messages to stderr.
-6). smbmount race condition fix.
-7). Fix for bug where trying to browse large numbers of shares
- generated an error from an NT client.
-8). Wrapper for setgroups for SunOS 4.x
-9). Fix for directory deleting failing from multiuser NT.
-10). Fix for crash bug if bitmap was full.
-11). Fix for Linux genrand where /dev/random could cause
- clients to timeout on connect if the entropy pool was
- empty.
-12). The default PASSWD_CHAT may now be overridden in local.h
-13). HPUX printing fixes for default programs.
-14). Reverted (erroneous) code in MACHINE.SID generation that
- was setting the sid to 0x21 - should be *decimal* 21.
-15). Fix for printing to remote machine under SVR4.
-16). Fix for chgpasswd wait being interrupted with EINTR.
-17). Fix for disk free routine. NT and Win98 now correctly
- show greater than 2GB disks.
-18). Fix for crash bug in stat cache statistics printing.
-19). Fix for filenames ending in .~xx.
-20). Fix for access check code wait being interrupted with EINTR.
-21). Fix for password changes from "invalid password" to a valid
- one setting the account disabled bit.
-22). Fix for smbd crash bug in SMBreadraw cache prime code.
-23). Fix for overly zealous lock range overflow reporting.
-24). Fix for large disk disk free reporting (NT SMB code).
-25). Fix for NT failing to truncate files correctly.
-26). Fix for smbd crash bug with SMBcancel calls.
-27). Additional -T flag to nmblookup to do reverse DNS on addresses.
-28). SWAT fix to start/stop smbd/nmbd correctly.
-
-Major changes in Samba 2.0
---------------------------
-
-This is a MAJOR new release of Samba, the UNIX based SMB/CIFS file
-and print server for Windows systems.
-
-There have been many changes in Samba since the last major release,
-1.9.18. These have mainly been in the areas of performance and
-SMB protocol correctness. In addition, a Web based GUI interface
-for configuring Samba has been added.
+=====================================================================
-In addition, Samba has been re-written to help portability to
-other POSIX-based systems, based on the GNU autoconf tool.
+1). Windows NT (tm) Primary Domain Controller compatibility
+-----------------------------------------------------------
-There are many major changes in Samba for version 2.0. Here are
-some of them:
+Samba TNG can act as a Primary Domain Controller to Windows NT 3.5,
+4.0 and 5.0 (in 4.0 backwards-compatible mode) Workstations. Backup
+Domain Controller and Inter-Domain Trust Relationships are at an
+early, but functional and very hands-on, stage.
-=====================================================================
+2). Support for Windows NT (tm) Administrative tools
+----------------------------------------------------
-1). Speed
----------
+Significant in-roads have been made into providing support for at least
+the following Windows NT (tm) tools and services:
-Samba has been benchmarked on high-end UNIX hardware as out-performing
-all other SMB/CIFS servers using the Ziff-Davis NetBench benchmark.
-Many changes to the code to optimise high-end performance have been made.
+- User Manager for Domains
+- Server Manager for Domains
+- Event Log
+- Service Control Manager
+- Registry Editor
-2). Correctness
----------------
+A command-line tool named rpcclient, with a command-syntax similar to
+smbclient, has over sixty five commands that provide equivalent
+functionality for the same Windows NT (tm) Administrative tools,
+including the ability to remotely shut down a Windows NT (tm) Server.
-Samba now supports the Windows NT specific SMB requests. This
-means that on platforms that are capable Samba now presents a
-64 bit view of the filesystem to Windows NT clients and is
-capable of handling very large files.
+rpcclient has now been joined by net, samedit, regedit, spoolss,
+eventlog, lsa, cmdat and svccontrol. If anyone can think of better
+names for these, suggestions are welcomed.
3). Portability
---------------
-Samba is now self-configuring using GNU autoconf, removing
+Samba is now self-configuring using GNU autoconf and libtool, removing
the need for people installing Samba to have to hand configure
Makefiles, as was needed in previous versions.
You now configure Samba by running "./configure" then "make". See
docs/textdocs/UNIX_INSTALL.txt for details.
-4). Web based GUI configuration
--------------------------------
-
-Samba now comes with SWAT, a web based GUI config system. See
-the swat man page for details on how to set it up.
-
-5). Cross protocol data integrity
----------------------------------
+The use of libtool dramatically reduces the size of samba binaries.
+As we are using libtool in a slightly different way from usual,
+you may encounter run-time or compilation errors, so please repoty
+them to us.
-An open function interface has been defined to allow
-"opportunistic locks" (oplocks for short) granted by Samba
-to be seen by other UNIX processes. This allows complete
-cross protocol (NFS and SMB) data integrety using Samba
-with platforms that support this feature.
-
-6). Domain client capability
+4). New SAM Database Daemons
----------------------------
-Samba is now capable of using a Windows NT PDC for user
-authentication in exactly the same way that a Windows NT
-workstation does, i.e. it can be a member of a Domain. See
-docs/textdocs/DOMAIN_MEMBER.txt for details.
-
-7). Documentation Updates
--------------------------
+The SAM database daemon, samrd, is being considered "legacy", and
+the aim is to replace it. To this end, some new SAM database
+daemons are being developed - samrtdbd and samrnt5ldapd.
+They need to be run with their counterparts, netlogontdbd or
+netlogonnt5ldapd. None of these are build as part of the standard
+make, they have to be explicitly built because they are in
+development.
-All the reference parts of the Samba documentation (the
-manual pages) have been updated and converted to a document
-format that allows automatic generation of HTML, SGML, and
-text formats. These documents now ship as standard in HTML
-and manpage format.
=====================================================================
-NOTE - Some important option defaults changed
----------------------------------------------
-
-Several parameters have changed their default values. The most
-important of these is that the default security mode is now user
-level security rather than share level security.
-
-This (incompatible) change was made to ease new Samba installs
-as user level security is easier to use for Windows 95/98 and
-Windows NT clients.
-
-********IMPORTANT NOTE****************
-
-If you have no "security=" line in the [global] section of
-your current smb.conf and you update to Samba 2.0 you will
-need to add the line :
-
-security=share
-
-to get exactly the same behaviour with Samba 2.0 as you
-did with previous versions of Samba.
+NOTE - Some important information
+---------------------------------------
-********END IMPORTANT NOTE*************
+Samba TNG up to alpha-0.3 required that the samba server be joined
+to its own Domain. This requirement has been removed.
-In addition, Samba now defaults to case sensitivity options that
-match a Windows NT server precisely, that is, case insensitive
-but case preserving.
+It is important that you read the source/README file for
+instructions, and it is recommended that you join samba-ntdom@samba.org
+for update information and status reports. For details, please see:
-The default format of the smbpasswd file has also been
-changed for this release, although the new tools will read
-and write the old format, for backwards compatibility.
+http://samba.org/listproc/samba-ntdom
=====================================================================
@@ -378,12 +104,8 @@ Domain Controller than serving Windows NT logon requests.
A useful version of a Primary Domain Controller contains
many remote procedure calls to do things like enumerate users,
-groups, and security information, only some of which Samba currently
-implements. In addition, there are outstanding (known) bugs with
-using Samba as a PDC in this release that the Samba Team are actively
-working on. For this reason we have chosen not to advertise and
-actively support Primary Domain Controller functionality with this
-release.
+groups, and security information, 98% of which Samba TNG currently
+implements.
This work is being done in the CVS (developer) versions of Samba,
development of which continues at a fast pace. If you are
@@ -398,12 +120,56 @@ are available at:
http://samba.org/cvs.html
+For this version, use a tag of SAMBA_TNG
+
+
+=====================================================================
+
+NOTE - Known Bugs
+-----------------
+
+It is *not* recommended that this version of Samba be run in a
+production environment, for at least the following reasons:
+
+1) nmbd is known to fork() every 20 minutes, resulting in an extra
+process that hangs around. It has also been reported, in a large
+network neighbourhood environment with "wins support = no"
+and "wins server = x.x.x.x" to flood the WINS server with about
+3 requests per second to resolve every single name in the
+network neighbourhood. Be Warned!
+
+This issue appears to have been resolved, cause unknown, fix unknown.
+
+You can avoid this by using a stable, production release of nmbd, such
+as can be found in 2.0.6a or later.
+
+2) The new MSRPC architecture forks() one MSRPC daemon per incoming
+service request. The msrpc daemon stays around for as long as
+the remote server maintains a connection to it. An investigation
+is underway to attempt to minimise the number of outstanding
+connections, because a *single* NT user logon can result in up to
+5 or 6 msrpc daemons waiting around, doing nothing but take up
+process table space.
+
+Connection reuse has now been added and debugged: the number of
+incoming connections is reduced but still fairly large.
+
+
+3) The Samba TNG code base was cut from the 2.0 development tree
+approximately eighteen months ago. That means that it does not have
+any of the file and print server improvements or bug-fixes since
+that time. The use of Samba TNG as a file and print server is
+therefore not recommended, and can be avoided by setting user
+profiles and home directories to be on another Windows NT (tm) or
+compatible file server.
+
+
=====================================================================
If you have problems, or think you have found a bug please email
a report to :
- samba-bugs@samba.org
+ samba-technical@samba.org
As always, all bugs are our responsibility.
diff --git a/docs/VFS.txt b/docs/VFS.txt
new file mode 100644
index 00000000000..455fde910ad
--- /dev/null
+++ b/docs/VFS.txt
@@ -0,0 +1,9 @@
+!==
+!== VFS.txt
+!==
+Contributor: Tim Potter
+Updated: April 5, 1999
+
+Subject: Implementing a virtual filesystem for Samba
+===========================================================
+
diff --git a/docs/announce b/docs/announce
index 856fd000364..6548a515548 100644
--- a/docs/announce
+++ b/docs/announce
@@ -1,4 +1,4 @@
- Announcing Samba version 2.0
+ Announcing Samba version 1.9
============================
What is Samba?
@@ -47,12 +47,10 @@ umask support, guest connections, name mangling and hidden and system
attribute mapping. Look at the FAQs included with the package for
a full list of features.
-What's new since 1.9?
+What's new since 1.8?
---------------------
Lots of stuff. See the change log and man pages for details.
-In particular, please check the WHATSNEW.txt file in the root directory
-of each release. This file has current change/update information.
Where can I get a client for my PC?
-----------------------------------
@@ -138,7 +136,7 @@ There is also often quite a bit of discussion about Samba on the
newsgroup comp.protocols.smb.
A WWW site with lots of Samba info can be found at
-http://samba.org/samba/
+http://samba.org/
The Samba Team (Contact: samba-bugs@samba.org)
June 1996
diff --git a/docs/faq/sambafaq-2.html b/docs/faq/sambafaq-2.html
index d78f5d627c7..dfababb66a4 100644
--- a/docs/faq/sambafaq-2.html
+++ b/docs/faq/sambafaq-2.html
@@ -18,11 +18,14 @@
<P>
<A NAME="no_browse"></A>
-See BROWSING.txt for more information on browsing. BROWSING.txt can
-be found in the docs directory of the Samba source.</P> <P>If your GUI
-client does not permit you to select non-browsable servers, you may
-need to do so on the command line. For example, under Lan Manager you
-might connect to the above service as disk drive M: thusly:
+See
+<A HREF="ftp://samba.org/pub/samba/BROWSING.txt">BROWSING.txt</A>
+for more information on browsing. Browsing.txt can also be found
+in the docs directory of the Samba source.</P>
+<P>If your GUI client does not permit you to select non-browsable
+servers, you may need to do so on the command line. For example, under
+Lan Manager you might connect to the above service as disk drive M:
+thusly:
<BLOCKQUOTE><CODE>
<PRE>
net use M: \\mary\fred
diff --git a/docs/htmldocs/DOMAIN_MEMBER.html b/docs/htmldocs/DOMAIN_MEMBER.html
index 409534c99ef..6d9741f2f27 100644
--- a/docs/htmldocs/DOMAIN_MEMBER.html
+++ b/docs/htmldocs/DOMAIN_MEMBER.html
@@ -13,7 +13,7 @@
<h1>Joining an NT Domain with Samba 2.0</h1>
<h2>Jeremy Allison, Samba Team</h2>
-<h2>7th October 1999</h2>
+<h2>11th November 1998</h2>
@@ -23,8 +23,7 @@
<p><br>In order for a Samba-2 server to join an NT domain, you must first add
the NetBIOS name of the Samba server to the NT domain on the PDC using
Server Manager for Domains. This creates the machine account in the
-domain (PDC) SAM. Note that you should add the Samba server as a "Windows
-NT Workstation or Server", <em>NOT</em> as a Primary or backup domain controller.
+domain (PDC) SAM.
<p><br>Assume you have a Samba-2 server with a NetBIOS name of <code>SERV1</code> and are
joining an NT domain called <code>DOM</code>, which has a PDC with a NetBIOS name
of <code>DOMPDC</code> and two backup domain controllers with NetBIOS names <code>DOMBDC1</code>
@@ -64,9 +63,6 @@ use domain security.
<p><br>line in the <a href="smb.conf.5.html#global"><strong>[global]</strong></a> section to read:
<p><br><code>workgroup = DOM</code>
<p><br>as this is the name of the domain we are joining.
-<p><br>You must also have the parameter <a href="smb.conf.5.html#encryptpasswords"><strong>"encrypt passwords"</strong></a>
-set to <code>"yes"</code> in order for your users to authenticate to the
-NT PDC.
<p><br>Finally, add (or modify) a:
<p><br><a href="smb.conf.5.html#passwordserver"><strong>"password server ="</strong></a>
<p><br>line in the <a href="smb.conf.5.html#global"><strong>[global]</strong></a> section to read:
@@ -76,13 +72,18 @@ to contact in order to authenticate users. Samba will try to contact
each of these servers in order, so you may want to rearrange this list
in order to spread out the authentication load among domain
controllers.
-<p><br>Alternatively, if you want smbd to automatically determine the
-list of Domain controllers to use for authentication, you may set this line to be :
-<p><br><code>password server = *</code>
-<p><br>This method, which is new in Samba 2.0.6 and above, allows Samba
-to use exactly the same mechanism that NT does. This method either broadcasts or
-uses a WINS database in order to find domain controllers to
+<p><br>Currently, Samba requires that a defined list of domain controllers be
+listed in this parameter in order to authenticate with domain-level
+security. NT does not use this method, and will either broadcast or
+use a WINS database in order to find domain controllers to
authenticate against.
+<p><br>Originally, I considered this idea for Samba, but dropped it because
+it seemed so insecure. However several Samba-2 alpha users have
+requested that this feature be added to make Samba more NT-like, so
+I'll probably add a special name of <code>'*'</code> (which means: act like NT
+when looking for domain controllers) in a future release of the
+code. At present, however, you need to know where your domain
+controllers are.
<p><br>Finally, restart your Samba daemons and get ready for clients to begin
using domain security!
<p><br><center>Why is this better than security = server? </center>
diff --git a/docs/htmldocs/LDAP.html b/docs/htmldocs/LDAP.html
new file mode 100644
index 00000000000..1cc8f8213fd
--- /dev/null
+++ b/docs/htmldocs/LDAP.html
@@ -0,0 +1,147 @@
+
+
+
+
+<html><head><title>LDAP Support in Samba</title>
+
+<link rev="made" href="mailto:samba-bugs@samba.org">
+</head>
+<body>
+
+<hr>
+
+<h1>LDAP Support in Samba</h1>
+<h2>Matthew Chapman</h2>
+<h2>29th November 1998
+<p> <hr> <h2>
+WARNING: This is experimental code. Use at your own risk, and please report
+any bugs (after reading BUGS.txt).
+</h2> <br>
+</h2>
+
+
+<a href="LDAP.html#l1"><h2>1: What is LDAP?</h2> </a>
+<a href="LDAP.html#l2"><h2>2: Why LDAP and Samba?</h2> </a>
+<a href="LDAP.html#l3"><h2>3: Using LDAP with Samba</h2> </a>
+<a href="LDAP.html#l4"><h2>4: Using LDAP for Unix authentication</h2> </a>
+<a href="LDAP.html#l5"><h2>5: Compatibility with Active Directory</h2> </a>
+
+<p><hr><p><br>
+<p>
+ <a name="l1"></a>
+<h2>1: What is LDAP?</h2>
+A directory is a type of hierarchical database optimised for simple query
+operations, often used for storing user information. LDAP is the
+Lightweight Directory Access Protocol, a protocol which is rapidly
+becoming the Internet standard for accessing directories.<p>
+ Many client applications now support LDAP (including Microsoft's Active
+Directory), and there are a number of servers available. The most popular
+implementation for Unix is from the <em>University of Michigan</em>; its
+homepage is at <a href="http://www.umich.edu/~dirsvcs/ldap/"><code>http://www.umich.edu/~dirsvcs/ldap/</code></a>.<p>
+ Information in an LDAP tree always comes in <code>attribute=value</code> pairs.
+The following is an example of a Samba user entry:<p>
+ <pre>
+uid=jbloggs, dc=samba, dc=org
+objectclass=sambaAccount
+uid=jbloggs
+cn=Joe Bloggs
+description=Samba User
+uidNumber=500
+gidNumber=500
+rid=2000
+grouprid=2001
+lmPassword=46E389809F8D55BB78A48108148AD508
+ntPassword=1944CCE1AD6F80D8AEC9FC5BE77696F4
+pwdLastSet=35C11F1B
+smbHome=\\samba1\jbloggs
+homeDrive=Z
+script=logon.bat
+profile=\\samba1\jbloggs\profile
+workstations=JOE
+</pre>
+<p>
+ Note that the top line is a special set of attributes called a
+<em>distinguished name</em> which identifies the location of this entry beneath
+the directory's root node. Recent Internet standards suggest the use of
+domain-based naming using <code>dc</code> attributes (for instance, a microsoft.com
+directory should have a root node of <code>dc=microsoft, dc=com</code>), although
+this is not strictly necessary for isolated servers.<p>
+ There are a number of LDAP-related FAQ's on the internet, although
+generally the best source of information is the documentation for the
+individual servers.<p>
+ <br>
+<a name="l2"></a>
+<h2>2: Why LDAP and Samba?</h2><p>
+ Using an LDAP directory allows Samba to store user and group information
+more reliably and flexibly than the current combination of smbpasswd,
+smbgroup, groupdb and aliasdb with the Unix databases. If a need emerges
+for extra user information to be stored, this can easily be added without
+loss of backwards compatibility.<p>
+ In addition, the Samba LDAP schema is compatible with RFC2307, allowing
+Unix password database information to be stored in the same entries. This
+provides a single, consistent repository for both Unix and Windows user
+information.<p>
+ <br>
+<a name="l3"></a>
+<h2>3: Using LDAP with Samba</h2><p>
+ <ol><p>
+ <li> Install and configure an LDAP server if you do not already have
+one. You should read your LDAP server's documentation and set up the
+configuration file and access control as desired.<p>
+ <li> Build Samba (latest CVS is required) with:<p>
+ <pre>
+ ./configure --with-ldap
+ make clean; make install
+</pre>
+<p>
+ <li> Add the following options to the global section of <code>smb.conf</code> as
+required.<p>
+ <ul>
+<li><strong>ldap suffix</strong><p>
+ This parameter specifies the node of the LDAP tree beneath which
+Samba should store its information. This parameter MUST be provided
+when using LDAP with Samba.<p>
+ <strong>Default:</strong> <code>none</code><p>
+ <strong>Example:</strong> <code>ldap suffix = "dc=mydomain, dc=org"</code><p>
+ <li><strong>ldap bind as</strong><p>
+ This parameter specifies the entity to bind to an LDAP directory as.
+Usually it should be safe to use the LDAP root account; for larger
+installations it may be preferable to restrict Samba's access.<p>
+ <strong>Default:</strong> <code>none (bind anonymously)</code><p>
+ <strong>Example:</strong> <code>ldap bind as = "uid=root, dc=mydomain, dc=org"</code><p>
+ <li><strong>ldap passwd file</strong><p>
+ This parameter specifies a file containing the password with which
+Samba should bind to an LDAP server. For obvious security reasons
+this file must be set to mode 700 or less.<p>
+ <strong>Default:</strong> <code>none (bind anonymously)</code><p>
+ <strong>Example:</strong> <code>ldap passwd file = /usr/local/samba/private/ldappasswd</code><p>
+ <li><strong>ldap server</strong><p>
+ This parameter specifies the DNS name of the LDAP server to use
+when storing and retrieving information about Samba users and
+groups.<p>
+ <strong>Default:</strong> <code>ldap server = localhost</code><p>
+ <li><strong>ldap port</strong><p>
+ This parameter specifies the TCP port number of the LDAP server.<p>
+ <strong>Default:</strong> <code>ldap port = 389</code><p>
+ </ul><p>
+ <li> You should then be able to use the normal smbpasswd(8) command for
+account administration (or User Manager in the near future).<p>
+ </ol><p>
+ <br>
+<a name="l4"></a>
+<h2>4: Using LDAP for Unix authentication</h2><p>
+ The Samba LDAP code was designed to utilise RFC2307-compliant directory
+entries if available. RFC2307 is a proposed standard for LDAP user
+information which has been adopted by a number of vendors. Further
+information is available at <a href="http://www.xedoc.com.au/~lukeh/ldap"><code>http://www.xedoc.com.au/~lukeh/ldap/</code></a>.<p>
+ Of particular interest is Luke Howard's nameservice switch module
+(nss_ldap) and PAM module (pam_ldap) implementing this standard, providing
+LDAP-based password databases for Unix. If you are setting up a server to
+provide integrated Unix/NT services than these are worth investigating.<p>
+ <br>
+<a name="l5"></a>
+<h2>5: Compatibility with Active Directory</h2><p>
+ The current implementation is not designed to be used with Microsoft
+Active Directory, although compatibility may be added in the future.<p>
+ </body>
+</html>
diff --git a/docs/htmldocs/debug2html.1.html b/docs/htmldocs/debug2html.1.html
new file mode 100644
index 00000000000..d0d6373a3d1
--- /dev/null
+++ b/docs/htmldocs/debug2html.1.html
@@ -0,0 +1,68 @@
+
+
+
+
+
+<html><head><title>debug2html(1)</title>
+
+<link rev="made" href="mailto:samba-bugs@samba.org">
+</head>
+<body>
+
+<hr>
+
+<h1>debug2html(1)</h1>
+<h2>Samba</h2>
+<h2>29 Dec 1998</h2>
+
+
+
+
+<p><br><a name="NAME"></a>
+<h2>NAME</h2>
+ debug2html - Samba DEBUG to HTML translation filter
+<p><br><a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<p><br>debug2html [input-file [output-file]]
+<p><br><a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<p><br>This program is part of the <strong>Samba</strong> suite.
+<p><br><strong>debug2html</strong> generates HTML files from Samba log files. Log files
+produced by <strong>nmbd</strong>(8) or <strong>smbd</strong>(8) may then be viewed by a web
+browser. The output conforms to the HTML 3.2 specification.
+<p><br>The filenames specified on the command line are optional. If the
+output-file is ommitted, output will go to <strong>stdout</strong>. If the input-file
+is ommitted, <strong>debug2html</strong> will read from <strong>stdin</strong>. The filename "-"
+can be used to indicate that input should be read from <strong>stdin</strong>. For
+example:
+<p><br><code>cat /usr/local/samba/var/log.nmb | debug2html - nmblog.html</code> <br>
+<p><br><a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<p><br>This man page is correct for version 2.0 of the Samba suite.
+<p><br><a name="SEEALSO"></a>
+<h2>SEE ALSO</h2>
+
+<p><br><a href="nmbd.8.html"><strong>nmbd</strong>(8)</a>, <a href="smbd.8.html"><strong>smbd</strong>(8)</a>,
+<a href="samba.7.html"><strong>samba</strong>(7)</a>.
+<p><br><a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<p><br>The original Samba software and related utilities were created by
+Andrew Tridgell <a href="mailto:samba-bugs@samba.org"><em>samba-bugs@samba.org</em></a>. Samba is now developed
+by the Samba Team as an Open Source project similar to the way the
+Linux kernel is developed.
+<p><br>The original Samba man pages were written by Karl Auer. The man page
+sources were converted to YODL format (another excellent piece of Open
+Source software, available at
+<a href="ftp://ftp.icce.rug.nl/pub/unix/"><strong>ftp://ftp.icce.rug.nl/pub/unix/</strong></a>)
+and updated for the Samba2.0 release by Jeremy Allison.
+<a href="mailto:samba-bugs@samba.org"><em>samba-bugs@samba.org</em></a>.
+<p><br><strong>debug2html</strong> was added by Chris Hertel.
+<p><br>See <a href="samba.7.html"><strong>samba</strong>(7)</a> to find out how to get a full
+list of contributors and details on how to submit bug reports,
+comments etc.
+</body>
+</html>
diff --git a/docs/htmldocs/nmbd.8.html b/docs/htmldocs/nmbd.8.html
index 03fd3588e26..3139e90ad12 100644
--- a/docs/htmldocs/nmbd.8.html
+++ b/docs/htmldocs/nmbd.8.html
@@ -25,7 +25,7 @@ naming services to clients
<p><br><a name="SYNOPSIS"></a>
<h2>SYNOPSIS</h2>
-<p><br><strong>nmbd</strong> [<a href="nmbd.8.html#minusD">-D</a>] [<a href="nmbd.8.html#minusa">-a</a>] [<a href="nmbd.8.html#minuso">-o</a>] [<a href="nmbd.8.html#minush">-h</a>] [<a href="nmbd.8.html#minusV">-V</a>] [<a href="nmbd.8.html#minusH">-H lmhosts file</a>] [<a href="nmbd.8.html#minusd">-d debuglevel</a>] [<a href="nmbd.8.html#minusl">-l log file basename</a>] [<a href="nmbd.8.html#minusn">-n primary NetBIOS name</a>] [<a href="nmbd.8.html#minusp">-p port number</a>] [<a href="nmbd.8.html#minuss">-s configuration file</a>] [<a href="nmbd.8.html#minusi">-i NetBIOS scope</a>]
+<p><br><strong>nmbd</strong> [<a href="nmbd.8.html#minusD">-D</a>] [<a href="nmbd.8.html#minuso">-o</a>] [<a href="nmbd.8.html#minusa">-a</a>] [<a href="nmbd.8.html#minusH">-H lmhosts file</a>] [<a href="nmbd.8.html#minusd">-d debuglevel</a>] [<a href="nmbd.8.html#minusl">-l log file basename</a>] [<a href="nmbd.8.html#minusn">-n primary NetBIOS name</a>] [<a href="nmbd.8.html#minusp">-p port number</a>] [<a href="nmbd.8.html#minuss">-s configuration file</a>] [<a href="nmbd.8.html#minusi">-i NetBIOS scope</a>] [<a href="nmbd.8.html#minush">-h</a>]
<p><br><a name="DESCRIPTION"></a>
<h2>DESCRIPTION</h2>
@@ -70,10 +70,6 @@ append log messages to the log file. This is the default.
<li><strong><strong>-o</strong></strong> If this parameter is specified, the log files will be
overwritten when opened. By default, the log files will be appended
to.
-<p><br><a name="minush"></a>
-<li><strong><strong>-h</strong></strong> Prints the help information (usage) for <strong>nmbd</strong>.
-<p><br><a name="minusV"></a>
-<li><strong><strong>-V</strong></strong> Prints the version number for <strong>nmbd</strong>.
<p><br><a name="minusH"></a>
<li><strong><strong>-H filename</strong></strong> NetBIOS lmhosts file.
<p><br>The lmhosts file is a list of NetBIOS names to IP addresses that is
@@ -137,6 +133,8 @@ use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
are <em>very</em> rarely used, only set this parameter if you are the
system administrator in charge of all the NetBIOS systems you
communicate with.
+<p><br><a name="minush"></a>
+<li><strong><strong>-h</strong></strong> Prints the help information (usage) for <strong>nmbd</strong>.
<p><br></ul>
<p><br><a name="FILES"></a>
<h2>FILES</h2>
diff --git a/docs/htmldocs/nmblookup.1.html b/docs/htmldocs/nmblookup.1.html
index 2c3e80c76e2..5ff58e5b401 100644
--- a/docs/htmldocs/nmblookup.1.html
+++ b/docs/htmldocs/nmblookup.1.html
@@ -24,7 +24,7 @@
<p><br><a name="SYNOPSIS"></a>
<h2>SYNOPSIS</h2>
-<p><br><strong>nmblookup</strong> [<a href="nmblookup.1.html#minusM">-M</a>] [<a href="nmblookup.1.html#minusR">-R</a>] [<a href="nmblookup.1.html#minusS">-S</a>] [<a href="nmblookup.1.html#minusr">-r</a>] [<a href="nmblookup.1.html#minusA">-A</a>] [<a href="nmblookup.1.html#minush">-h</a>] [<a href="nmblookup.1.html#minusB">-B broadcast address</a>] [<a href="nmblookup.1.html#minusU">-U unicast address</a>] [<a href="nmblookup.1.html#minusd">-d debuglevel</a>] [<a href="nmblookup.1.html#minuss">-s smb config file</a>] [<a href="nmblookup.1.html#minusi">-i NetBIOS scope</a>] [<a href="nmblookup.1.html#minusT">-T</a>] <a href="nmblookup.1.html#name">name</a>
+<p><br><strong>nmblookup</strong> [<a href="nmblookup.1.html#minusM">-M</a>] [<a href="nmblookup.1.html#minusR">-R</a>] [<a href="nmblookup.1.html#minusS">-S</a>] [<a href="nmblookup.1.html#minusr">-r</a>] [<a href="nmblookup.1.html#minusA">-A</a>] [<a href="nmblookup.1.html#minush">-h</a>] [<a href="nmblookup.1.html#minusB">-B broadcast address</a>] [<a href="nmblookup.1.html#minusU">-U unicast address</a>] [<a href="nmblookup.1.html#minusd">-d debuglevel</a>] [<a href="nmblookup.1.html#minuss">-s smb config file</a>] [<a href="nmblookup.1.html#minusi">-i NetBIOS scope</a>] <a href="nmblookup.1.html#name">name</a>
<p><br><a name="DESCRIPTION"></a>
<h2>DESCRIPTION</h2>
@@ -38,9 +38,8 @@ or to a particular machine. All queries are done over UDP.
<p><br><ul>
<p><br><a name="minusM"></a>
-<li><strong><strong>-M</strong></strong> Searches for a master browser by looking up the
-NetBIOS name <a href="nmblookup.1.html#name"><strong>name</strong></a> with a type of 0x1d. If <a href="nmblookup.1.html#name"><strong>name</strong></a>
-is <code>"-"</code> then it does a lookup on the special name <code>__MSBROWSE__</code>.
+<li><strong><strong>-M</strong></strong> Searches for a master browser. This is done by doing a
+broadcast lookup on the special name <code>__MSBROWSE__</code>.
<p><br><a name="minusR"></a>
<li><strong><strong>-R</strong></strong> Set the recursion desired bit in the packet to do a
recursive lookup. This is used when sending a name query to a machine
@@ -68,8 +67,8 @@ query on this address.
<p><br><a name="minusB"></a>
<li><strong><strong>-B broadcast address</strong></strong> Send the query to the given broadcast
address. Without this option the default behavior of nmblookup is to
-send the query to the broadcast address of the network
-interfaces as either auto-detected or defined in the
+send the query to the broadcast address of the primary network
+interface as either auto-detected or defined in the
<a href="smb.conf.5.html#interfaces"><strong>interfaces</strong></a> parameter of the
<a href="smb.conf.5.html"><strong>smb.conf (5)</strong></a> file.
<p><br><a name="minusU"></a>
@@ -101,11 +100,6 @@ use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
are <em>very</em> rarely used, only set this parameter if you are the
system administrator in charge of all the NetBIOS systems you
communicate with.
-<p><br><a name="minusT"></a>
-<li><strong><strong>-T</strong></strong> This causes any IP addresses found in the lookup to be
-looked up via a reverse DNS lookup into a DNS name, and printed out
-before each <code>"IP address NetBIOS name"</code> pair that is the normal
-output.
<p><br><a name="name"></a>
<li><strong><strong>name</strong></strong> This is the NetBIOS name being queried. Depending upon
the previous options this may be a NetBIOS name or IP address. If a
diff --git a/docs/htmldocs/rpcclient.1.html b/docs/htmldocs/rpcclient.1.html
new file mode 100644
index 00000000000..6e5cf888661
--- /dev/null
+++ b/docs/htmldocs/rpcclient.1.html
@@ -0,0 +1,651 @@
+
+
+
+
+
+<html><head><title>rpcclient (1)</title>
+
+<link rev="made" href="mailto:samba-bugs@samba.org">
+</head>
+<body>
+
+<hr>
+
+<h1>rpcclient (1)</h1>
+<h2>Samba</h2>
+<h2>23 Oct 1998</h2>
+
+
+
+
+<p><br><a name="NAME"></a>
+<h2>NAME</h2>
+ rpcclient - utility to manage MSRPC resources on servers
+<p><br><a name="SYNOPSIS"></a>
+<h2>SYNOPSIS</h2>
+
+<p><br><strong>rpcclient</strong>
+[<a href="rpcclient.1.html#password">password</a>]
+<a href="rpcclient.1.html#servername">-S servername</a>
+[<a href="rpcclient.1.html#minusU">-U [username][%][password]</a>]
+[<a href="rpcclient.1.html#minusW">-W domain</a>]
+[<a href="rpcclient.1.html#minusl">-l log basename</a>]
+[<a href="rpcclient.1.html#minusd">-d debuglevel</a>]
+[<a href="rpcclient.1.html#minusO">-O socket options</a>]
+[<a href="rpcclient.1.html#minusi">-i scope</a>]
+[<a href="rpcclient.1.html#minusN">-N</a>]
+[<a href="rpcclient.1.html#minusn">-n NetBIOS name</a>]
+[<a href="rpcclient.1.html#minush">-h</a>]
+[<a href="rpcclient.1.html#minusI">-I dest IP</a>]
+[<a href="rpcclient.1.html#minusE">-E</a>]
+[<a href="rpcclient.1.html#minust">-t terminal code</a>]
+[<a href="rpcclient.1.html#minusc">-c command string</a>]
+[<a href="rpcclient.1.html#minusB">-B IP addr</a>]
+[<a href="rpcclient.1.html#minuss">-s smb.conf</a>]
+[<a href="rpcclient.1.html#minusm">-m max protocol</a>]
+<p><br><a name="DESCRIPTION"></a>
+<h2>DESCRIPTION</h2>
+
+<p><br>This program is part of the <strong>Samba</strong> suite.
+<p><br><strong>rpcclient</strong> is a client that can 'talk' to an SMB/CIFS MSRPC server.
+Operations include things like managing a SAM Database (users, groups
+and aliases) in the same way as the Windows NT programs
+<strong>User Manager for Domains</strong> and <strong>Server Manager for Domains</strong>;
+managing a remote registry in the same way as the Windows NT programs
+<strong>REGEDT32.EXE</strong> and <strong>REGEDIT.EXE</strong>; viewing a remote event log (same
+as <strong>EVENTVWR.EXE</strong>) etc.
+<p><br>Typical usage is like this: <br>
+<code>rpcclient -I 192.168.32.1 -S "*SMBSERVER" -U fred%secret -l log</code>
+<br>
+<p><br><a name="OPTIONS"></a>
+<h2>OPTIONS</h2>
+
+<p><br><ul>
+<p><br><a name="servername"></a>
+<li><strong><strong>servername</strong></strong> servername is the name of the server you want
+to use on the server. This should be the NetBIOS name of the SMB/CIFS
+server, which can be <strong>*SMBSERVER</strong> on Windows NT 4.0 or Samba Servers.
+<p><br>Note that the server name required is NOT necessarily the IP (DNS)
+host name of the server! The name required is a NetBIOS server name,
+which may or may not be the same as the IP hostname of the machine
+running the server. Also, remember that having a period in a NetBIOS
+name (such as an IP hostname) may cause connectivity problems on your
+network: NT tends to strip NetBIOS names from the leading period
+onwards.
+<p><br>The server name is looked up according to either the
+<a href="rpcclient.1.html#minusR"><strong>-R</strong></a> parameter to <strong>rpcclient</strong> or using the
+<a href="smb.conf.5.html#nameresolveorder"><strong>name resolve order</strong></a>
+parameter in the smb.conf file, allowing an administrator to change
+the order and methods by which server names are looked up.
+<p><br><a name="password"></a>
+<li><strong><strong>password</strong></strong> password is the password required to access the
+specified service on the specified server. If this parameter is
+supplied, the <a href="rpcclient.1.html#minusN"><strong>-N</strong></a> option (suppress password prompt) is assumed.
+<p><br>There is no default password. If no password is supplied on the
+command line (either by using this parameter or adding a password to
+the <a href="rpcclient.1.html#minusU"><strong>-U</strong></a> option (see below)) and the <a href="rpcclient.1.html#minusN"><strong>-N</strong></a> option is not specified,
+the client will prompt for a password, even if the desired service
+does not require one. (If no password is required, simply press ENTER
+to provide a null password.)
+<p><br>Note: Some servers (including OS/2 and Windows for Workgroups) insist
+on an uppercase password. Lowercase or mixed case passwords may be
+rejected by these servers.
+<p><br>Be cautious about including passwords in scripts.
+<p><br><a name="minuss"></a>
+<li><strong><strong>-s smb.conf</strong></strong> This parameter specifies the pathname to the
+Samba configuration file, smb.conf. This file controls all aspects of
+the Samba setup on the machine and rpcclient also needs to read this
+file.
+<p><br><a name="minusB"></a>
+<li><strong><strong>-B IP addr</strong></strong> The IP address to use when sending a broadcast packet.
+<p><br><a name="minusO"></a>
+<li><strong><strong>-O socket options</strong></strong> TCP socket options to set on the client
+socket. See the <a href="smb.conf.5.html#socketoptions">socket options</a>
+parameter in the <a href="smb.conf.5.html"><strong>smb.conf (5)</strong></a> manpage for
+the list of valid options.
+<p><br><a name="minusR"></a>
+<li><strong><strong>-R name resolve order</strong></strong> This option allows the user of
+rpcclient to determine what name resolution services to use when
+looking up the NetBIOS name of the host being connected to.
+<p><br>The options are :"lmhosts", "host", "wins" and "bcast". They cause
+names to be resolved as follows :
+<p><br><ul>
+<p><br><li > <strong>lmhosts</strong> : Lookup an IP address in the Samba lmhosts file.
+The lmhosts file is stored in the same directory as the
+<a href="smb.conf.5.html"><strong>smb.conf</strong></a> file.
+<p><br><li > <strong>host</strong> : Do a standard host name to IP address resolution,
+using the system /etc/hosts, NIS, or DNS lookups. This method of name
+resolution is operating system depended for instance on IRIX or
+Solaris this may be controlled by the <em>/etc/nsswitch.conf</em> file).
+<p><br><li > <strong>wins</strong> : Query a name with the IP address listed in the <a href="smb.conf.5.html#winsserver"><strong>wins
+server</strong></a> parameter in the smb.conf file. If
+no WINS server has been specified this method will be ignored.
+<p><br><li > <strong>bcast</strong> : Do a broadcast on each of the known local interfaces
+listed in the <a href="smb.conf.5.html#interfaces"><strong>interfaces</strong></a> parameter
+in the smb.conf file. This is the least reliable of the name resolution
+methods as it depends on the target host being on a locally connected
+subnet. To specify a particular broadcast address the <a href="rpcclient.1.html#minusB"><strong>-B</strong></a> option
+may be used.
+<p><br></ul>
+<p><br>If this parameter is not set then the name resolve order defined
+in the <a href="smb.conf.5.html"><strong>smb.conf</strong></a> file parameter
+<a href="smb.conf.5.html#nameresolveorder">(<strong>name resolve order</strong>)</a>
+will be used.
+<p><br>The default order is lmhosts, host, wins, bcast and without this
+parameter or any entry in the <a href="smb.conf.5.html#nameresolveorder"><strong>"name resolve
+order"</strong></a> parameter of the
+<a href="smb.conf.5.html"><strong>smb.conf</strong></a> file the name resolution methods
+will be attempted in this order.
+<p><br><a name="minusi"></a>
+<li><strong><strong>-i scope</strong></strong> This specifies a NetBIOS scope that rpcclient will use
+to communicate with when generating NetBIOS names. For details on the
+use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
+are <em>very</em> rarely used, only set this parameter if you are the
+system administrator in charge of all the NetBIOS systems you
+communicate with.
+<p><br><a name="minusN"></a>
+<li><strong><strong>-N</strong></strong> If specified, this parameter suppresses the normal
+password prompt from the client to the user. This is useful when
+accessing a service that does not require a password.
+<p><br>Unless a password is specified on the command line or this parameter
+is specified, the client will request a password.
+<p><br><a name="minusn"></a>
+<li><strong><strong>-n NetBIOS name</strong></strong> By default, the client will use the local
+machine's hostname (in uppercase) as its NetBIOS name. This parameter
+allows you to override the host name and use whatever NetBIOS name you
+wish.
+<p><br><a name="minusd"></a>
+<li><strong><strong>-d debuglevel</strong></strong> debuglevel is an integer from 0 to 10, or the
+letter 'A'.
+<p><br>The default value if this parameter is not specified is zero.
+<p><br>The higher this value, the more detail will be logged to the log files
+about the activities of the client. At level 0, only critical errors
+and serious warnings will be logged. Level 1 is a reasonable level for
+day to day running - it generates a small amount of information about
+operations carried out.
+<p><br>Levels above 1 will generate considerable amounts of log data, and
+should only be used when investigating a problem. Levels above 3 are
+designed for use only by developers and generate HUGE amounts of log
+data, most of which is extremely cryptic. If debuglevel is set to the
+letter 'A', then <em>all</em> debug messages will be printed. This setting
+is for developers only (and people who <em>really</em> want to know how the
+code works internally).
+<p><br>Note that specifying this parameter here will override the <a href="smb.conf.5.html#loglevel"><strong>log
+level</strong></a> parameter in the <a href="smb.conf.5.html"><strong>smb.conf
+(5)</strong></a> file.
+<p><br><a name="minusp"></a>
+<li><strong><strong>-p port</strong></strong> This number is the TCP port number that will be used
+when making connections to the server. The standard (well-known) TCP
+port number for an SMB/CIFS server is 139, which is the default.
+<p><br><a name="minusl"></a>
+<li><strong><strong>-l logfilename</strong></strong> If specified, logfilename specifies a base
+filename into which operational data from the running client will be
+logged.
+<p><br>The default base name is specified at compile time.
+<p><br>The base name is used to generate actual log file names. For example,
+if the name specified was "log", the debug file would be
+<code>log.client</code>.
+<p><br>The log file generated is never removed by the client.
+<p><br><a name="minush"></a>
+<li><strong><strong>-h</strong></strong> Print the usage message for the client.
+<p><br><a name="minusI"></a>
+<li><strong><strong>-I IP address</strong></strong> IP address is the address of the server to
+connect to. It should be specified in standard "a.b.c.d" notation.
+<p><br>Normally the client would attempt to locate a named SMB/CIFS server by
+looking it up via the NetBIOS name resolution mechanism described
+above in the <a href="rpcclient.1.html#minusR"><strong>name resolve order</strong></a> parameter
+above. Using this parameter will force the client to assume that the
+server is on the machine with the specified IP address and the NetBIOS
+name component of the resource being connected to will be ignored.
+<p><br>There is no default for this parameter. If not supplied, it will be
+determined automatically by the client as described above.
+<p><br><a name="minusE"></a>
+<li><strong><strong>-E</strong></strong> This parameter causes the client to write messages to the
+standard error stream (stderr) rather than to the standard output
+stream.
+<p><br>By default, the client writes messages to standard output - typically
+the user's tty.
+<p><br>Note that by default, debug information is always sent to stderr.
+Debug information can instead be sent to a file, using the
+<a href="rpcclient.1.html#minusl">-l log basename</a> option.
+<p><br><a name="minusU"></a>
+<li><strong><strong>-U username</strong></strong> This specifies the user name that will be used by
+the client to make a connection, assuming your server is not a downlevel
+server that is running a protocol level that uses passwords on shares,
+not on usernames.
+<p><br>Some servers are fussy about the case of this name, and some insist
+that it must be a valid NetBIOS name.
+<p><br>If no username is supplied, it will default to an uppercase version of
+the environment variable <code>USER</code> or <code>LOGNAME</code> in that order. If no
+username is supplied and neither environment variable exists the
+username "GUEST" will be used.
+<p><br>If the <code>USER</code> environment variable contains a '%' character,
+everything after that will be treated as a password. This allows you
+to set the environment variable to be <code>USER=username%password</code> so
+that a password is not passed on the command line (where it may be
+seen by the ps command).
+<p><br>If the service you are connecting to requires a password, it can be
+supplied using the <a href="rpcclient.1.html#minusU"><strong>-U</strong></a> option, by appending a percent symbol ("%")
+then the password to username. For example, to attach to a service as
+user <code>"fred"</code> with password <code>"secret"</code>, you would specify. <br>
+<p><br><code>-U fred%secret</code> <br>
+<p><br>on the command line. Note that there are no spaces around the percent
+symbol.
+<p><br>If you specify the password as part of username then the <a href="rpcclient.1.html#minusN"><strong>-N</strong></a> option
+(suppress password prompt) is assumed.
+<p><br>If you specify the password as a parameter <em>AND</em> as part of username
+then the password as part of username will take precedence. Putting
+nothing before or nothing after the percent symbol will cause an empty
+username or an empty password to be used, respectively.
+<p><br>The password may also be specified by setting up an environment
+variable called <code>PASSWORD</code> that contains the users password. Note
+that this may be very insecure on some systems but on others allows
+users to script rpcclient commands without having a password appear in
+the command line of a process listing.
+<p><br>Note: Some servers (including OS/2 and Windows for Workgroups) insist
+on an uppercase password. Lowercase or mixed case passwords may be
+rejected by these servers.
+<p><br>Be cautious about including passwords in scripts or in the
+<code>PASSWORD</code> environment variable. Also, on many systems the command
+line of a running process may be seen via the <code>ps</code> command to be
+safe always allow rpcclient to prompt for a password and type it in
+directly.
+<p><br><a name="minust"></a>
+<li><strong><strong>-t terminal code</strong></strong> This option tells rpcclient how to interpret
+filenames coming from the remote server. Usually Asian language
+multibyte UNIX implementations use different character sets than
+SMB/CIFS servers (<em>EUC</em> instead of <em>SJIS</em> for example). Setting
+this parameter will let rpcclient convert between the UNIX filenames
+and the SMB filenames correctly. This option has not been seriously
+tested and may have some problems.
+<p><br>The terminal codes include <code>sjis</code>, <code>euc</code>, <code>jis7</code>, <code>jis8</code>,
+<code>junet</code>, <code>hex</code>, <code>cap</code>. This is not a complete list, check the
+Samba source code for the complete list.
+<p><br><a name="minusm"></a>
+<li><strong><strong>-m max protocol level</strong></strong> With the new code in Samba2.0,
+<strong>rpcclient</strong> always attempts to connect at the maximum
+protocols level the server supports. This parameter is
+preserved for backwards compatibility, but any string
+following the <strong>-m</strong> will be ignored.
+<p><br><a name="minusW"></a>
+<li><strong><strong>-W Domain</strong></strong> Override the default Domain, which is the remote server's
+Domain. This option may be needed to connect to some servers. It is also
+possible to specify the remote server name as the Domain, which will
+force the username and password to be authenticated against the remote
+server's local SAM instead of the Domain SAM.
+<p><br><a name="minusc"></a>
+<li><strong><strong>-c command string</strong></strong> command string is a semicolon separated
+list of commands to be executed instead of prompting from stdin.
+<a href="rpcclient.1.html#minusN"><strong>-N</strong></a> is implied by <strong>-c</strong>.
+<p><br>This is particularly useful in scripts, e.g. <code>-c 'lsaquery; enumusers -u'</code>.
+<p><br></ul>
+<p><br><a name="OPERATIONS"></a>
+<h2>OPERATIONS</h2>
+
+<p><br>Once the client is running, the user is presented with a prompt :
+<p><br><code>smb:\&gt;</code>
+<p><br>The prompt indicates that the client is ready and waiting to carry out
+a user command. Each command is a single word, optionally followed by
+parameters specific to that command. Command and parameters are
+space-delimited unless these notes specifically state otherwise. All
+commands are case-insensitive. Parameters to commands may or may not
+be case sensitive, depending on the command.
+<p><br>You can specify names (e.g registry keys; user or group names;
+service names) which have spaces in them by quoting the
+name with double quotes, for example "dRMON SmartAgent".
+<p><br>Parameters shown in square brackets (e.g., "[parameter]") are
+optional. If not given, the command will use suitable
+defaults. Parameters shown in angle brackets (e.g., "&lt;parameter&gt;") are
+required.
+<p><br>Note that all commands operating on the server are actually performed
+by issuing a request to the server. Thus the behavior may vary from
+server to server, depending on how the server was implemented.
+<p><br>The commands available are listed in groups relating to different services:
+<p><br><ul>
+<p><br><li><strong>Misccellaneous</strong>
+<p><br><ul>
+<p><br><a name="questionmark"></a> <li><strong><strong>? [command]</strong></strong> If "command" is specified,
+ the <strong>?</strong> command will display a brief informative message about the
+ specified command. If no command is specified, a list of available
+ commands will be displayed.
+<p><br><a name="exclaimationmark"></a> <li><strong><strong>! [shell command]</strong></strong> If "shell command"
+ is specified, the <strong>!</strong> command will execute a shell locally and run
+ the specified shell command. If no command is specified, a local shell
+ will be run.
+<p><br><a name="exit"></a> <li><strong><strong>exit</strong></strong> Terminate the connection with the server and
+ exit from the program.
+<p><br><a name="help"></a> <li><strong><strong>help [command]</strong></strong> See the <a href="rpcclient.1.html#questionmark"><strong>?</strong></a>
+ command above.
+<p><br><a name="quit"></a> <li><strong><strong>quit</strong></strong> See the <a href="rpcclient.1.html#exit"><strong>exit</strong></a> command.
+<p><br></ul>
+<p><br><li><strong>Event Log</strong>
+<p><br><ul>
+<p><br><a name="eventlog"></a> <li><strong><strong>eventlog</strong></strong>
+ list the events
+<p><br></ul>
+<p><br><li><strong>Service Control</strong>
+<p><br>These commands provide functionality similar to the Windows
+ NT Service Control Manager.
+<p><br>It is possible to use command-line completion (if you have
+ the GNU readline library) for Service names, by pressing the
+ tab key.
+<p><br><ul>
+<p><br><a name="svcenum"></a> <li><strong><strong>svcenum</strong></strong>
+ [-i] Lists Services.
+<p><br><a name="svcinfo"></a> <li><strong><strong>svcinfo</strong></strong>
+ &lt;service&gt; Service Information
+<p><br><a name="svcstart"></a> <li><strong><strong>svcstart</strong></strong>
+ &lt;service&gt; [arg 0] [arg 1] ... Start Service
+<p><br><a name="svcstop"></a> <li><strong><strong>svcstop</strong></strong>
+ &lt;service&gt; Stop Service
+<p><br></ul>
+<p><br><li><strong>Scheduler</strong>
+<p><br><ul>
+<p><br><a name="at"></a> <li><strong><strong>at</strong></strong>
+ Scheduler control (at /? for syntax)
+<p><br></ul>
+<p><br><li><strong>Registry</strong>
+<p><br>It is possible to use command-line completion (if you have
+ the GNU readline library) for registry key and value names,
+ by pressing the tab key.
+<p><br><ul>
+<p><br><a name="regenum"></a> <li><strong><strong>regenum</strong></strong>
+ &lt;keyname&gt; Registry Enumeration (keys, values)
+<p><br><a name="regdeletekey"></a> <li><strong><strong>regdeletekey</strong></strong>
+ &lt;keyname&gt; Registry Key Delete
+<p><br><a name="regcreatekey"></a> <li><strong><strong>regcreatekey</strong></strong>
+ &lt;keyname&gt; [keyclass] Registry Key Create
+<p><br><a name="shutdown"></a> <li><strong><strong>shutdown</strong></strong>
+ [-m message] [-t timeout] [-r or --reboot] Server Shutdown
+<p><br><a name="regqueryval"></a> <li><strong><strong>regqueryval</strong></strong>
+ &lt;valname&gt; Registry Value Query
+<p><br><a name="regquerykey"></a> <li><strong><strong>regquerykey</strong></strong>
+ &lt;keyname&gt; Registry Key Query
+<p><br><a name="regdeleteval"></a> <li><strong><strong>regdeleteval</strong></strong>
+ &lt;valname&gt; Registry Value Delete
+<p><br><a name="regcreateval"></a> <li><strong><strong>regcreateval</strong></strong>
+ &lt;valname&gt; &lt;valtype&gt; &lt;value&gt; Registry Key Create
+<p><br><a name="reggetsec"></a> <li><strong><strong>reggetsec</strong></strong>
+ &lt;keyname&gt; Registry Key Security
+<p><br><a name="regtestsec"></a> <li><strong><strong>regtestsec</strong></strong>
+ &lt;keyname&gt; Test Registry Key Security
+<p><br></ul>
+<p><br><li><strong>Printing</strong>
+<p><br>It is possible to use command-line completion (if you have
+ the GNU readline library) for Printer and job names, by
+ pressing the tab key.
+<p><br><ul>
+<p><br><a name="spoolenum"></a> <li><strong><strong>spoolenum</strong></strong>
+ Enumerate Printers. This experimental command lists
+ all printers available on a remote spooler service.
+<p><br><a name="spooljobs"></a> <li><strong><strong>spooljobs</strong></strong>
+ &lt;printer name&gt; Enumerate Printer Jobs. This
+ experimental command lists all jobs, and their
+ status, currently queued on a remote spooler
+ service.
+<p><br><a name="spoolopen"></a> <li><strong><strong>spoolopen</strong></strong>
+ &lt;printer name&gt; Spool Printer Open Test. Experimental.
+<p><br></ul>
+<p><br><li><strong>Server</strong>
+<p><br><ul>
+<p><br><a name="time"></a> <li><strong><strong>time</strong></strong>
+ Display remote time
+<p><br><a name="brsinfo"></a> <li><strong><strong>brsinfo</strong></strong>
+ Browser Query Info
+<p><br><a name="wksinfo"></a> <li><strong><strong>wksinfo</strong></strong>
+ Workstation Query Info
+<p><br><a name="srvinfo"></a> <li><strong><strong>srvinfo</strong></strong>
+ Server Query Info
+<p><br><a name="srvsessions"></a> <li><strong><strong>srvsessions</strong></strong>
+ List sessions on a server
+<p><br><a name="srvshares"></a> <li><strong><strong>srvshares</strong></strong>
+ List shares on a server
+<p><br><a name="srvtransports"></a> <li><strong><strong>srvtransports</strong></strong>
+ List transports on a server
+<p><br><a name="srvconnections"></a> <li><strong><strong>srvconnections</strong></strong>
+ List connections on a server
+<p><br><a name="srvfiles"></a> <li><strong><strong>srvfiles</strong></strong>
+ List files on a server
+<p><br></ul>
+<p><br><li><strong>Local Security Authority</strong>
+<p><br><ul>
+<p><br><a name="lsaquery"></a> <li><strong><strong>lsaquery</strong></strong>
+ Query Info Policy (domain member or server). Obtains
+ the SID and name of the SAM database that a server
+ is responsible for (i.e a workstation's local SAM
+ database or the PDC SAM database). Also obtains the
+ SID and name of the SAM database that a server is
+ a member of.
+<p><br><a name="lsaenumdomains"></a> <li><strong><strong>lsaenumdomains</strong></strong>
+ Enumerate Trusted Domains. Lists all Trusted and
+ Trusting Domains with which the remote PDC has
+ trust relationships established.
+<p><br><a name="lookupsids"></a> <li><strong><strong>lookupsids</strong></strong>
+ &lt;rid1 or sid1&gt; &lt;rid1 or sid2&gt; ... Resolve names from SIDs.
+ Mostly to be used by developers or for troubleshooting,
+ this command can take either Security Identifiers or Relative
+ Identifiers, and look them up in the local SAM database
+ (or look them up in a remote Trusting or Trusted PDC's SAM
+ database if there is an appropriate Trust Relationship
+ established). The result is a list of names, of the
+ format: <br>
+ <code>[TRUST_DOMAIN\]name</code>. <br>
+ the <a href="rpcclient.1.html#lsaquery"><strong>lsaquery</strong></a> command must have been
+ issued first if you wish to use lookupsids to resolve
+ RIDs. The only RIDs that will be resolved will be those
+ in the SAM database of the server to which you are connected.
+<p><br><a name="lookupnames"></a> <li><strong><strong>lookupnames</strong></strong>
+ &lt;name1&gt; &lt;name2&gt; ... Resolve SIDs from names.
+ Mostly to be used by developers or for troubleshooting,
+ this command can take names of the following format: <br>
+ <code>[DOMAIN_NAME\]name</code>. <br>
+ The names, which can be user, group or alias names, will
+ either be looked up in the local SAM database or in a remote
+ Trusting or Trusted PDC's SAM database, if there is an
+ appropriate Trust Relationship established. The optional
+ Domain name component is the name of a SAM database, which
+ can include a workstation's local SAM database or a Trusted
+ Domain.
+ Example Usage: <br>
+ <code>lookupnames WKSTANAME\Administrator "Domain Guests"</code> <br>
+<p><br><a name="querysecret"></a> <li><strong><strong>querysecret</strong></strong>
+ LSA Query Secret (developer use). This command only appears
+ to work against NT4 SP3 and below. Due to its potential
+ for misuse, it looks like Microsoft modified their
+ implementation of the LsaRetrievePrivateData call to
+ always return NT_STATUS_ACCESS_DENIED.
+<p><br></ul>
+<p><br><li><strong>NETLOGON</strong>
+<p><br><ul>
+<p><br><a name="ntlogin"></a> <li><strong><strong>ntlogin</strong></strong>
+ [username] [password] NT Domain login test. Demonstrates
+ how NT-style logins work. Mainly for developer usage,
+ it can also be used to verify that a user can log in
+ from a workstation. If you cannot ever get pam_ntdom
+ to work, try this command first.
+<p><br><a name="domtrust"></a> <li><strong><strong>domtrust</strong></strong>
+ &lt;domain&gt; NT Inter-Domain test. Demonstrates how NT-style
+ Inter-Domain Trust relationships work. Mainly for
+ developer usage, it can also be used to verify that a
+ Trust Relationship is correctly established with a
+ remote PDC.
+<p><br><a name="samsync"></a> <li><strong><strong>samsync</strong></strong>
+ SAM Synchronisation Test (experimental). This command
+ is used to manually synchronise a SAM database from a
+ remote PDC, when Samba is set up as a Backup Domain
+ Controller.
+<p><br></ul>
+<p><br><li><strong>SAM Database</strong>
+<p><br>It is possible to use command-line completion (if you have
+ the GNU readline library) for user, group, alias and domain
+ names, by pressing the tab key.
+<p><br><ul>
+<p><br><a name="lookupdomain"></a> <li><strong><strong>lookupdomain</strong></strong>
+ Obtain SID for a local domain
+<p><br><a name="enumusers"></a> <li><strong><strong>enumusers</strong></strong>
+ SAM User Database Query (experimental!)
+<p><br><a name="addgroupmem"></a> <li><strong><strong>addgroupmem</strong></strong>
+ &lt;group rid&gt; [user] [user] ... SAM Add Domain Group Member
+<p><br><a name="addaliasmem"></a> <li><strong><strong>addaliasmem</strong></strong>
+ &lt;alias rid&gt; [member sid1] [member sid2] ... SAM Add Domain Alias Member
+<p><br><a name="delgroupmem"></a> <li><strong><strong>delgroupmem</strong></strong>
+ &lt;group rid&gt; [user] [user] ... SAM Delete Domain Group Member
+<p><br><a name="delaliasmem"></a> <li><strong><strong>delaliasmem</strong></strong>
+ &lt;alias rid&gt; [member sid1] [member sid2] ... SAM Delete Domain Alias Member
+<p><br><a name="creategroup"></a> <li><strong><strong>creategroup</strong></strong>
+ SAM Create Domain Group
+<p><br><a name="createalias"></a> <li><strong><strong>createalias</strong></strong>
+ SAM Create Domain Alias
+<p><br><a name="createuser"></a> <li><strong><strong>createuser</strong></strong>
+ &lt;username&gt; SAM Create Domain User
+<p><br><a name="delgroup"></a> <li><strong><strong>delgroup</strong></strong>
+ SAM Delete Domain Group
+<p><br><a name="delalias"></a> <li><strong><strong>delalias</strong></strong>
+ SAM Delete Domain Alias
+<p><br><a name="ntpass"></a> <li><strong><strong>ntpass</strong></strong>
+ NT SAM Password Change
+<p><br><a name="samuserset2"></a> <li><strong><strong>samuserset2</strong></strong>
+ &lt;username&gt; [-s acb_bits] SAM User Set Info 2 (experimental!)
+<p><br><a name="samuserset"></a> <li><strong><strong>samuserset</strong></strong>
+ &lt;username&gt; [-p password] SAM User Set Info (experimental!)
+<p><br><a name="samuser"></a> <li><strong><strong>samuser</strong></strong>
+ &lt;username&gt; SAM User Query (experimental!)
+<p><br><a name="samgroup"></a> <li><strong><strong>samgroup</strong></strong>
+ &lt;groupname&gt; SAM Group Query (experimental!)
+<p><br><a name="samalias"></a> <li><strong><strong>samalias</strong></strong>
+ &lt;aliasname&gt; SAM Alias Query
+<p><br><a name="samaliasmem"></a> <li><strong><strong>samaliasmem</strong></strong>
+ &lt;aliasname&gt; SAM Alias Members
+<p><br><a name="samgroupmem"></a> <li><strong><strong>samgroupmem</strong></strong>
+ SAM Group Members
+<p><br><a name="samtest"></a> <li><strong><strong>samtest</strong></strong>
+ SAM User Encrypted RPC test (experimental!)
+<p><br><a name="enumaliases"></a> <li><strong><strong>enumaliases</strong></strong>
+ SAM Aliases Database Query (experimental!)
+<p><br><a name="enumdomains"></a> <li><strong><strong>enumdomains</strong></strong>
+ SAM Domains Database Query (experimental!)
+<p><br><a name="enumgroups"></a> <li><strong><strong>enumgroups</strong></strong>
+ SAM Group Database Query (experimental!)
+<p><br><a name="dominfo"></a> <li><strong><strong>dominfo</strong></strong>
+ SAM Query Domain Info
+<p><br><a name="dispinfo"></a> <li><strong><strong>dispinfo</strong></strong>
+ SAM Query Display Info
+<p><br></ul>
+<p><br></ul>
+<p><br><a name="NOTES"></a>
+<h2>NOTES</h2>
+
+<p><br>Some servers are fussy about the case of supplied usernames,
+passwords, share names (AKA service names) and machine names. If you
+fail to connect try giving all parameters in uppercase.
+<p><br>It is often necessary to use the <a href="rpcclient.1.html#minusn"><strong>-n</strong></a> option when connecting
+to some types of servers. For example OS/2 LanManager insists on a valid
+NetBIOS name being used, so you need to supply a valid name that would
+be known to the server.
+<p><br>rpcclient only works on servers that support MSRPC over SMB. This includes
+all versions of Windows NT, including the ports to Unix such as AS/U and
+AFPS. Support for MSRPC over SMB in other servers is currently rare and
+patchy, for example Samba 2.0 only supports a limited set of MSRPC commands,
+and some of those are not supported very well.
+<p><br><a name="ENVIRONMENTVARIABLES"></a>
+<h2>ENVIRONMENT VARIABLES</h2>
+
+<p><br>The variable <strong>USER</strong> may contain the username of the person using the
+client. This information is used only if the protocol level is high
+enough to support session-level passwords.
+<p><br>The variable <strong>PASSWORD</strong> may contain the password of the person using
+the client. This information is used only if the protocol level is
+high enough to support session-level passwords.
+<p><br><a name="INSTALLATION"></a>
+<h2>INSTALLATION</h2>
+
+<p><br>The location of the client program is a matter for individual system
+administrators. The following are thus suggestions only.
+<p><br>It is recommended that the rpcclient software be installed in the
+/usr/local/samba/bin or /usr/samba/bin directory, this directory
+readable by all, writeable only by root. The client program itself
+should be executable by all. The client should <em>NOT</em> be setuid or
+setgid!
+<p><br>The client log files should be put in a directory readable and
+writeable only by the user.
+<p><br>To test the client, you will need to know the name of a running
+SMB/CIFS server. It is possible to run <a href="smbd.8.html"><strong>smbd (8)</strong></a>
+an ordinary user - running that server as a daemon on a
+user-accessible port (typically any port number over 1024) would
+provide a suitable test server.
+<p><br><a name="DIAGNOSTICS"></a>
+<h2>DIAGNOSTICS</h2>
+
+<p><br>Most diagnostics issued by the client are logged in a specified log
+file. The log file name is specified at compile time, but may be
+overridden on the command line.
+<p><br>The number and nature of diagnostics available depends on the debug
+level used by the client. If you have problems, set the debug level to
+3 and peruse the log files.
+<p><br><a name="VERSION"></a>
+<h2>VERSION</h2>
+
+<p><br>This man page is correct for version 2.0 of the Samba suite.
+<p><br><a name="BUGS"></a>
+<h2>BUGS</h2>
+
+<p><br><ul>
+<li><strong>WARNING!</strong>
+The MSPRC over SMB code has been developed from examining Network traces.
+No documentation is available from the original creators (Microsoft) on
+how MSRPC over SMB works, or how the individual MSRPC services work.
+Microsoft's implementation of these services has been demonstrated (and
+reported) to be... a bit flakey in places.
+<p><br>The development of Samba's implementation of these services is <em>also</em>
+a bit rough, and as more of the services are understood, it can even result
+in versions of <a href="smbd.8.html"><strong>smbd (8)</strong></a> and rpcclient that are
+incompatible for some commands or services. Additionally, the developers
+are sending reports to Microsoft, and problems found by or reported to
+Microsoft are fixed in Service Packs, which may also result in
+incompatibilities.
+<p><br>It is therefore not guaranteed that the execution of an rpcclient command will
+work. It is also not guaranteed that the target server will continue to
+operate, i.e the execution of an MSRPC command may cause a remote service to
+fail, or even cause the remote server to fail. Usual rules apply, of course:
+the developers bear absolutely no responsibility for the use, misuse, or
+lack of use of rpcclient, by any person or persons, whether legal,
+illegal, accidental, deliberate, intentional, malicious, curious, etc.
+<p><br><li><strong>Command Completion</strong>
+Command-completion (available if you have the GNU readline library) used on
+certain commands may not operate correctly if the word being completed (such as a registry key) contains a space. Typically, the name will be completed, but
+you will have to go back and put quotes round it, yourself.
+<p><br><li><strong>SAM Database command-completion</strong>
+Command-completion (available if you have the GNU readline library) of user,
+group and alias names does not work on remote Domains, which would normally
+be specified like this: <br>
+<code>DOMAIN_name\user_name</code>. <br>
+The only names that can be completed in this fashion are the local names
+in the SAM database of the target server.
+<p><br><li><strong><a href="rpcclient.1.html#spoolenum"><strong>spoolenum</strong></a></strong>
+Due to current limitations in the rpcclient MSRPC / SMB code, and due to
+the extremely poor MSRPC implementation (by Microsoft) of the spooler
+service, if there are a large number of printers (or the names / comment
+fields associated with the printers), this command will fail. The
+limitations require further research to be carried out; we're stuck with
+the poor \PIPE\spoolss design.
+<p><br></ul>
+<p><br><a name="AUTHOR"></a>
+<h2>AUTHOR</h2>
+
+<p><br>The original Samba software and related utilities were created by
+Andrew Tridgell <a href="mailto:samba-bugs@samba.org"><em>samba-bugs@samba.org</em></a>. Samba is now developed
+by the Samba Team as an Open Source project similar to the way the
+Linux kernel is developed.
+<p><br>The original Samba man pages were written by Karl Auer. The man page
+sources were converted to YODL format (another excellent piece of Open
+Source software, available at
+<a href="ftp://ftp.icce.rug.nl/pub/unix/"><strong>ftp://ftp.icce.rug.nl/pub/unix/</strong></a>)
+and updated for the Samba2.0 release by Jeremy Allison. This man page
+was developed cut-and-paste style from the smbclient man page, by
+Luke Kenneth Casson Leighton.
+<a href="mailto:samba-bugs@samba.org"><em>samba-bugs@samba.org</em></a>.
+<p><br>See <a href="samba.7.html"><strong>samba (7)</strong></a> to find out how to get a full
+list of contributors and details on how to submit bug reports,
+comments etc.
+<p><br></body>
+</html>
diff --git a/docs/htmldocs/samba.7.html b/docs/htmldocs/samba.7.html
index f197ccfa32c..2fc86fd65af 100644
--- a/docs/htmldocs/samba.7.html
+++ b/docs/htmldocs/samba.7.html
@@ -56,6 +56,14 @@ client. This is useful for accessing SMB shares on other compatible
servers (such as Windows NT), and can also be used to allow a UNIX box
to print to a printer attached to any SMB server (such as a PC running
Windows NT).
+<p><br><li><strong><a href="rpcclient.1.html"><strong>rpcclient</strong></a></strong> <br> <br> The <a href="rpcclient.1.html"><strong>rpcclient</strong>
+(1)</a> program is a client that can 'talk' to an
+SMB/CIFS MSRPC server. Operations include things like managing a SAM
+Database (users, groups and aliases) in the same way as the Windows NT
+programs <strong>User Manager for Domains</strong> and <strong>Server Manager for Domains</strong>;
+managing a remote registry in the same way as the Windows NT programs
+<strong>REGEDT32.EXE</strong> and <strong>REGEDIT.EXE</strong>; viewing a remote event log (same
+as <strong>EVENTVWR.EXE</strong>).
<p><br><li><strong><a href="testparm.1.html"><strong>testparm</strong></a></strong> <br> <br> The <a href="testparm.1.html"><strong>testparm
(1)</strong></a> utility allows you to test your <a href="smb.conf.5.html"><strong>smb.conf
(5)</strong></a> configuration file.
diff --git a/docs/htmldocs/smb.conf.5.html b/docs/htmldocs/smb.conf.5.html
index 521c70d653e..f2f75170f80 100644
--- a/docs/htmldocs/smb.conf.5.html
+++ b/docs/htmldocs/smb.conf.5.html
@@ -204,7 +204,6 @@ would look like this:
[printers]
path = /usr/spool/public
- writeable = no
guest ok = yes
printable = yes
@@ -401,8 +400,6 @@ password.
<p><br>Here is a list of all global parameters. See the section of each
parameter for details. Note that some are synonyms.
<p><br><ul>
-<p><br><li > <a href="smb.conf.5.html#adduserscript"><strong>add user script</strong></a>
-<p><br><li > <a href="smb.conf.5.html#allowtrusteddomains"><strong>allow trusted domains</strong></a>
<p><br><li > <a href="smb.conf.5.html#announceas"><strong>announce as</strong></a>
<p><br><li > <a href="smb.conf.5.html#announceversion"><strong>announce version</strong></a>
<p><br><li > <a href="smb.conf.5.html#autoservices"><strong>auto services</strong></a>
@@ -414,24 +411,22 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#codingsystem"><strong>coding system</strong></a>
<p><br><li > <a href="smb.conf.5.html#configfile"><strong>config file</strong></a>
<p><br><li > <a href="smb.conf.5.html#deadtime"><strong>deadtime</strong></a>
-<p><br><li > <a href="smb.conf.5.html#debughirestimestamp"><strong>debug hires timestamp</strong></a>
-<p><br><li > <a href="smb.conf.5.html#debugpid"><strong>debug pid</strong></a>
<p><br><li > <a href="smb.conf.5.html#debugtimestamp"><strong>debug timestamp</strong></a>
-<p><br><li > <a href="smb.conf.5.html#debuguid"><strong>debug uid</strong></a>
<p><br><li > <a href="smb.conf.5.html#debuglevel"><strong>debuglevel</strong></a>
<p><br><li > <a href="smb.conf.5.html#default"><strong>default</strong></a>
<p><br><li > <a href="smb.conf.5.html#defaultservice"><strong>default service</strong></a>
-<p><br><li > <a href="smb.conf.5.html#deleteuserscript"><strong>delete user script</strong></a>
<p><br><li > <a href="smb.conf.5.html#dfreecommand"><strong>dfree command</strong></a>
<p><br><li > <a href="smb.conf.5.html#dnsproxy"><strong>dns proxy</strong></a>
<p><br><li > <a href="smb.conf.5.html#domainadmingroup"><strong>domain admin group</strong></a>
<p><br><li > <a href="smb.conf.5.html#domainadminusers"><strong>domain admin users</strong></a>
<p><br><li > <a href="smb.conf.5.html#domaincontroller"><strong>domain controller</strong></a>
+<p><br><li > <a href="smb.conf.5.html#domaingroupmap"><strong>domain group map</strong></a>
<p><br><li > <a href="smb.conf.5.html#domaingroups"><strong>domain groups</strong></a>
<p><br><li > <a href="smb.conf.5.html#domainguestgroup"><strong>domain guest group</strong></a>
<p><br><li > <a href="smb.conf.5.html#domainguestusers"><strong>domain guest users</strong></a>
<p><br><li > <a href="smb.conf.5.html#domainlogons"><strong>domain logons</strong></a>
<p><br><li > <a href="smb.conf.5.html#domainmaster"><strong>domain master</strong></a>
+<p><br><li > <a href="smb.conf.5.html#domainusermap"><strong>domain user map</strong></a>
<p><br><li > <a href="smb.conf.5.html#encryptpasswords"><strong>encrypt passwords</strong></a>
<p><br><li > <a href="smb.conf.5.html#getwdcache"><strong>getwd cache</strong></a>
<p><br><li > <a href="smb.conf.5.html#homedirmap"><strong>homedir map</strong></a>
@@ -439,15 +434,15 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#interfaces"><strong>interfaces</strong></a>
<p><br><li > <a href="smb.conf.5.html#keepalive"><strong>keepalive</strong></a>
<p><br><li > <a href="smb.conf.5.html#kerneloplocks"><strong>kernel oplocks</strong></a>
-<p><br><li > <a href="smb.conf.5.html#ldapfilter"><strong>ldap filter</strong></a>
+<p><br><li > <a href="smb.conf.5.html#ldapbindas"><strong>ldap bind as</strong></a>
+<p><br><li > <a href="smb.conf.5.html#ldappasswdfile"><strong>ldap passwd file</strong></a>
<p><br><li > <a href="smb.conf.5.html#ldapport"><strong>ldap port</strong></a>
-<p><br><li > <a href="smb.conf.5.html#ldaproot"><strong>ldap root</strong></a>
-<p><br><li > <a href="smb.conf.5.html#ldaprootpasswd"><strong>ldap root passwd</strong></a>
<p><br><li > <a href="smb.conf.5.html#ldapserver"><strong>ldap server</strong></a>
<p><br><li > <a href="smb.conf.5.html#ldapsuffix"><strong>ldap suffix</strong></a>
<p><br><li > <a href="smb.conf.5.html#lmannounce"><strong>lm announce</strong></a>
<p><br><li > <a href="smb.conf.5.html#lminterval"><strong>lm interval</strong></a>
<p><br><li > <a href="smb.conf.5.html#loadprinters"><strong>load printers</strong></a>
+<p><br><li > <a href="smb.conf.5.html#localgroupmap"><strong>local group map</strong></a>
<p><br><li > <a href="smb.conf.5.html#localmaster"><strong>local master</strong></a>
<p><br><li > <a href="smb.conf.5.html#lockdir"><strong>lock dir</strong></a>
<p><br><li > <a href="smb.conf.5.html#lockdirectory"><strong>lock directory</strong></a>
@@ -460,7 +455,6 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#lpqcachetime"><strong>lpq cache time</strong></a>
<p><br><li > <a href="smb.conf.5.html#machinepasswordtimeout"><strong>machine password timeout</strong></a>
<p><br><li > <a href="smb.conf.5.html#mangledstack"><strong>mangled stack</strong></a>
-<p><br><li > <a href="smb.conf.5.html#maptoguest"><strong>map to guest</strong></a>
<p><br><li > <a href="smb.conf.5.html#maxdisksize"><strong>max disk size</strong></a>
<p><br><li > <a href="smb.conf.5.html#maxlogsize"><strong>max log size</strong></a>
<p><br><li > <a href="smb.conf.5.html#maxmux"><strong>max mux</strong></a>
@@ -470,18 +464,15 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#maxwinsttl"><strong>max wins ttl</strong></a>
<p><br><li > <a href="smb.conf.5.html#maxxmit"><strong>max xmit</strong></a>
<p><br><li > <a href="smb.conf.5.html#messagecommand"><strong>message command</strong></a>
-<p><br><li > <a href="smb.conf.5.html#minpasswdlength"><strong>min passwd length</strong></a>
<p><br><li > <a href="smb.conf.5.html#minwinsttl"><strong>min wins ttl</strong></a>
<p><br><li > <a href="smb.conf.5.html#nameresolveorder"><strong>name resolve order</strong></a>
<p><br><li > <a href="smb.conf.5.html#netbiosaliases"><strong>netbios aliases</strong></a>
<p><br><li > <a href="smb.conf.5.html#netbiosname"><strong>netbios name</strong></a>
<p><br><li > <a href="smb.conf.5.html#nishomedir"><strong>nis homedir</strong></a>
-<p><br><li > <a href="smb.conf.5.html#ntaclsupport"><strong>nt acl support</strong></a>
<p><br><li > <a href="smb.conf.5.html#ntpipesupport"><strong>nt pipe support</strong></a>
<p><br><li > <a href="smb.conf.5.html#ntsmbsupport"><strong>nt smb support</strong></a>
<p><br><li > <a href="smb.conf.5.html#nullpasswords"><strong>null passwords</strong></a>
<p><br><li > <a href="smb.conf.5.html#olelockingcompatibility"><strong>ole locking compatibility</strong></a>
-<p><br><li > <a href="smb.conf.5.html#oplockbreakwaittime"><strong>oplock break wait time</strong></a>
<p><br><li > <a href="smb.conf.5.html#oslevel"><strong>os level</strong></a>
<p><br><li > <a href="smb.conf.5.html#packetsize"><strong>packet size</strong></a>
<p><br><li > <a href="smb.conf.5.html#panicaction"><strong>panic action</strong></a>
@@ -503,7 +494,6 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#readsize"><strong>read size</strong></a>
<p><br><li > <a href="smb.conf.5.html#remoteannounce"><strong>remote announce</strong></a>
<p><br><li > <a href="smb.conf.5.html#remotebrowsesync"><strong>remote browse sync</strong></a>
-<p><br><li > <a href="smb.conf.5.html#restrictanonymous"><strong>restrict anonymous</strong></a>
<p><br><li > <a href="smb.conf.5.html#root"><strong>root</strong></a>
<p><br><li > <a href="smb.conf.5.html#rootdir"><strong>root dir</strong></a>
<p><br><li > <a href="smb.conf.5.html#rootdirectory"><strong>root directory</strong></a>
@@ -545,7 +535,6 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#validchars"><strong>valid chars</strong></a>
<p><br><li > <a href="smb.conf.5.html#winsproxy"><strong>wins proxy</strong></a>
<p><br><li > <a href="smb.conf.5.html#winsserver"><strong>wins server</strong></a>
-<p><br><li > <a href="smb.conf.5.html#winshook"><strong>wins hook</strong></a>
<p><br><li > <a href="smb.conf.5.html#winssupport"><strong>wins support</strong></a>
<p><br><li > <a href="smb.conf.5.html#workgroup"><strong>workgroup</strong></a>
<p><br><li > <a href="smb.conf.5.html#writeraw"><strong>write raw</strong></a>
@@ -576,7 +565,6 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#directory"><strong>directory</strong></a>
<p><br><li > <a href="smb.conf.5.html#directorymask"><strong>directory mask</strong></a>
<p><br><li > <a href="smb.conf.5.html#directorymode"><strong>directory mode</strong></a>
-<p><br><li > <a href="smb.conf.5.html#directorysecuritymask"><strong>directory security mask</strong></a>
<p><br><li > <a href="smb.conf.5.html#dontdescend"><strong>dont descend</strong></a>
<p><br><li > <a href="smb.conf.5.html#dosfiletimeresolution"><strong>dos filetime resolution</strong></a>
<p><br><li > <a href="smb.conf.5.html#dosfiletimes"><strong>dos filetimes</strong></a>
@@ -586,9 +574,7 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#followsymlinks"><strong>follow symlinks</strong></a>
<p><br><li > <a href="smb.conf.5.html#forcecreatemode"><strong>force create mode</strong></a>
<p><br><li > <a href="smb.conf.5.html#forcedirectorymode"><strong>force directory mode</strong></a>
-<p><br><li > <a href="smb.conf.5.html#forcedirectorysecuritymode"><strong>force directory security mode</strong></a>
<p><br><li > <a href="smb.conf.5.html#forcegroup"><strong>force group</strong></a>
-<p><br><li > <a href="smb.conf.5.html#forcesecuritymode"><strong>force security mode</strong></a>
<p><br><li > <a href="smb.conf.5.html#forceuser"><strong>force user</strong></a>
<p><br><li > <a href="smb.conf.5.html#fstype"><strong>fstype</strong></a>
<p><br><li > <a href="smb.conf.5.html#group"><strong>group</strong></a>
@@ -601,7 +587,6 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#hostsdeny"><strong>hosts deny</strong></a>
<p><br><li > <a href="smb.conf.5.html#include"><strong>include</strong></a>
<p><br><li > <a href="smb.conf.5.html#invalidusers"><strong>invalid users</strong></a>
-<p><br><li > <a href="smb.conf.5.html#level2oplocks"><strong>level2 oplocks</strong></a>
<p><br><li > <a href="smb.conf.5.html#locking"><strong>locking</strong></a>
<p><br><li > <a href="smb.conf.5.html#lppausecommand"><strong>lppause command</strong></a>
<p><br><li > <a href="smb.conf.5.html#lpqcommand"><strong>lpq command</strong></a>
@@ -610,24 +595,22 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#magicoutput"><strong>magic output</strong></a>
<p><br><li > <a href="smb.conf.5.html#magicscript"><strong>magic script</strong></a>
<p><br><li > <a href="smb.conf.5.html#manglecase"><strong>mangle case</strong></a>
-<p><br><li > <a href="smb.conf.5.html#manglelocks"><strong>mangle locks</strong></a>
<p><br><li > <a href="smb.conf.5.html#mangledmap"><strong>mangled map</strong></a>
<p><br><li > <a href="smb.conf.5.html#manglednames"><strong>mangled names</strong></a>
<p><br><li > <a href="smb.conf.5.html#manglingchar"><strong>mangling char</strong></a>
<p><br><li > <a href="smb.conf.5.html#maparchive"><strong>map archive</strong></a>
<p><br><li > <a href="smb.conf.5.html#maphidden"><strong>map hidden</strong></a>
<p><br><li > <a href="smb.conf.5.html#mapsystem"><strong>map system</strong></a>
+<p><br><li > <a href="smb.conf.5.html#maptoguest"><strong>map to guest</strong></a>
<p><br><li > <a href="smb.conf.5.html#maxconnections"><strong>max connections</strong></a>
<p><br><li > <a href="smb.conf.5.html#minprintspace"><strong>min print space</strong></a>
<p><br><li > <a href="smb.conf.5.html#onlyguest"><strong>only guest</strong></a>
<p><br><li > <a href="smb.conf.5.html#onlyuser"><strong>only user</strong></a>
<p><br><li > <a href="smb.conf.5.html#oplocks"><strong>oplocks</strong></a>
-<p><br><li > <a href="smb.conf.5.html#oplockcontentionlimit"><strong>oplock contention limit</strong></a>
<p><br><li > <a href="smb.conf.5.html#path"><strong>path</strong></a>
<p><br><li > <a href="smb.conf.5.html#postexec"><strong>postexec</strong></a>
<p><br><li > <a href="smb.conf.5.html#postscript"><strong>postscript</strong></a>
<p><br><li > <a href="smb.conf.5.html#preexec"><strong>preexec</strong></a>
-<p><br><li > <a href="smb.conf.5.html#preexecclose"><strong>preexec close</strong></a>
<p><br><li > <a href="smb.conf.5.html#preservecase"><strong>preserve case</strong></a>
<p><br><li > <a href="smb.conf.5.html#printcommand"><strong>print command</strong></a>
<p><br><li > <a href="smb.conf.5.html#printok"><strong>print ok</strong></a>
@@ -645,8 +628,6 @@ parameter for details. Note that some are synonyms.
<p><br><li > <a href="smb.conf.5.html#revalidate"><strong>revalidate</strong></a>
<p><br><li > <a href="smb.conf.5.html#rootpostexec"><strong>root postexec</strong></a>
<p><br><li > <a href="smb.conf.5.html#rootpreexec"><strong>root preexec</strong></a>
-<p><br><li > <a href="smb.conf.5.html#securitymask"><strong>security mask</strong></a>
-<p><br><li > <a href="smb.conf.5.html#rootpreexecclose"><strong>root preexec close</strong></a>
<p><br><li > <a href="smb.conf.5.html#setdirectory"><strong>set directory</strong></a>
<p><br><li > <a href="smb.conf.5.html#sharemodes"><strong>share modes</strong></a>
<p><br><li > <a href="smb.conf.5.html#shortpreservecase"><strong>short preserve case</strong></a>
@@ -671,46 +652,6 @@ parameter for details. Note that some are synonyms.
<h2>EXPLANATION OF EACH PARAMETER</h2>
<p><br><ul>
-<p><br><a name="adduserscript"></a>
-<li><strong><strong>add user script (G)</strong></strong>
-<p><br>This is the full pathname to a script that will be run <em>AS ROOT</em> by
-<a href="smbd.8.html"><strong>smbd (8)</strong></a> under special circumstances decribed
-below.
-<p><br>Normally, a Samba server requires that UNIX users are created for all
-users accessing files on this server. For sites that use Windows NT
-account databases as their primary user database creating these users
-and keeping the user list in sync with the Windows NT PDC is an
-onerous task. This option allows <a href="smbd.8.html"><strong>smbd</strong></a> to create
-the required UNIX users <em>ON DEMAND</em> when a user accesses the Samba
-server.
-<p><br>In order to use this option, <a href="smbd.8.html"><strong>smbd</strong></a> must be set to
-<a href="smb.conf.5.html#securityequalserver"><strong>security=server</strong></a> or
-<a href="smb.conf.5.html#securityequaldomain"><strong>security=domain</strong></a> and <strong>"add user script"</strong>
-must be set to a full pathname for a script that will create a UNIX user
-given one argument of <strong>%u</strong>, which expands into the UNIX user name to
-create.
-<p><br>When the Windows user attempts to access the Samba server, at
-<em>"login"</em>(session setup in the SMB protocol) time,
-<a href="smbd.8.html"><strong>smbd</strong></a> contacts the <a href="smb.conf.5.html#passwordserver"><strong>password
-server</strong></a> and attempts to authenticate the given user
-with the given password. If the authentication succeeds then
-<a href="smbd.8.html"><strong>smbd</strong></a> attempts to find a UNIX user in the UNIX
-password database to map the Windows user into. If this lookup fails,
-and <strong>"add user script"</strong> is set then <a href="smbd.8.html"><strong>smbd</strong></a> will
-call the specified script <em>AS ROOT</em>, expanding any <strong>%u</strong> argument
-to be the user name to create.
-<p><br>If this script successfully creates the user then
-<a href="smbd.8.html"><strong>smbd</strong></a> will continue on as though the UNIX user
-already existed. In this way, UNIX users are dynamically created to
-match existing Windows NT accounts.
-<p><br>See also <a href="smb.conf.5.html#securityequalserver"><strong>security=server</strong></a>,
-<a href="smb.conf.5.html#securityequaldomain"><strong>security=domain</strong></a>, <a href="smb.conf.5.html#passwordserver"><strong>password
-server</strong></a>, <a href="smb.conf.5.html#deleteuserscript"><strong>delete user
-script</strong></a>.
-<p><br><strong>Default:</strong>
-<code> add user script = &lt;empty string&gt;</code>
-<p><br><strong>Example:</strong>
-<code> add user script = /usr/local/samba/bin/add_user %u</code>
<p><br><a name="adminusers"></a>
<li><strong><strong>admin users (S)</strong></strong>
<p><br>This is a list of users who will be granted administrative privileges
@@ -725,25 +666,46 @@ file permissions.
<code> admin users = jason</code>
<p><br><a name="allowhosts"></a>
<li><strong><strong>allow hosts (S)</strong></strong>
-<p><br>Synonym for <a href="smb.conf.5.html#hostsallow"><strong>hosts allow</strong></a>.
-<p><br><a name="allowtrusteddomains"></a>
-<li><strong><strong>allow trusted domains (G)</strong></strong>
-<p><br>This option only takes effect when the <a href="smb.conf.5.html#security"><strong>security</strong></a>
-option is set to <strong>server</strong> or <strong>domain</strong>. If it is set to no,
-then attempts to connect to a resource from a domain or workgroup other than
-the one which smbd is running in will fail, even if that domain
-is trusted by the remote server doing the authentication.
-<p><br>This is useful if you only want your Samba server to serve resources
-to users in the domain it is a member of. As an example, suppose that there are
-two domains DOMA and DOMB. DOMB is trusted by DOMA, which contains
-the Samba server. Under normal circumstances, a user with an account
-in DOMB can then access the resources of a UNIX account with the same
-account name on the Samba server even if they do not have an account
-in DOMA. This can make implementing a security boundary difficult.
-<p><br><strong>Default:</strong>
-<code> allow trusted domains = Yes</code>
-<p><br><strong>Example:</strong>
-<code> allow trusted domains = No</code>
+<p><br>A synonym for this parameter is <a href="smb.conf.5.html#hostsallow"><strong>'hosts allow'</strong></a>
+<p><br>This parameter is a comma, space, or tab delimited set of hosts which
+are permitted to access a service.
+<p><br>If specified in the <a href="smb.conf.5.html#global"><strong>[global]</strong></a> section then it will
+apply to all services, regardless of whether the individual service
+has a different setting.
+<p><br>You can specify the hosts by name or IP number. For example, you could
+restrict access to only the hosts on a Class C subnet with something
+like <code>"allow hosts = 150.203.5."</code>. The full syntax of the list is
+described in the man page <strong>hosts_access (5)</strong>. Note that this man
+page may not be present on your system, so a brief description will
+be given here also.
+<p><br><em>NOTE:</em> IF you wish to allow the <a href="smbpasswd.html.8"><strong>smbpasswd
+(8)</strong></a> program to be run by local users to change
+their Samba passwords using the local <a href="smbd.8.html"><strong>smbd (8)</strong></a>
+daemon, then you <em>MUST</em> ensure that the localhost is listed in your
+<strong>allow hosts</strong> list, as <a href="smbpasswd.html.8"><strong>smbpasswd (8)</strong></a> runs
+in client-server mode and is seen by the local
+<a href="smbd.8.html"><strong>smbd</strong></a> process as just another client.
+<p><br>You can also specify hosts by network/netmask pairs and by netgroup
+names if your system supports netgroups. The <em>EXCEPT</em> keyword can also
+be used to limit a wildcard list. The following examples may provide
+some help:
+<p><br><strong>Example 1</strong>: allow localhost and all IPs in 150.203.*.* except one
+<p><br><code> hosts allow = localhost, 150.203. EXCEPT 150.203.6.66</code>
+<p><br><strong>Example 2</strong>: allow localhost and hosts that match the given network/netmask
+<p><br><code> hosts allow = localhost, 150.203.15.0/255.255.255.0</code>
+<p><br><strong>Example 3</strong>: allow a localhost plus a couple of hosts
+<p><br><code> hosts allow = localhost, lapland, arvidsjaur</code>
+<p><br><strong>Example 4</strong>: allow only hosts in NIS netgroup "foonet" or localhost, but
+deny access from one particular host
+<p><br><code> hosts allow = @foonet, localhost</code>
+<code> hosts deny = pirate</code>
+<p><br>Note that access still requires suitable user-level passwords.
+<p><br>See <a href="testparm.1.html"><strong>testparm (1)</strong></a> for a way of testing your
+host access to see if it does what you expect.
+<p><br><strong>Default:</strong>
+<code> none (i.e., all hosts permitted access)</code>
+<p><br><strong>Example:</strong>
+<code> allow hosts = 150.203.5. localhost myhost.mynet.edu.au</code>
<p><br><a name="alternatepermissions"></a>
<li><strong><strong>alternate permissions (S)</strong></strong>
<p><br>This is a deprecated parameter. It no longer has any effect in Samba2.0.
@@ -755,14 +717,13 @@ regardless if the owner of the file is the currently logged on user or not.
<li><strong><strong>announce as (G)</strong></strong>
<p><br>This specifies what type of server <a href="nmbd.8.html"><strong>nmbd</strong></a> will
announce itself as, to a network neighborhood browse list. By default
-this is set to Windows NT. The valid options are : "NT", which is a
-synonym for "NT Server", "NT Server", "NT Workstation", "Win95" or
-"WfW" meaning Windows NT Server, Windows NT Workstation, Windows 95
-and Windows for Workgroups respectively. Do not change this parameter
-unless you have a specific need to stop Samba appearing as an NT server
-as this may prevent Samba servers from participating as browser servers correctly.
-<p><br><strong>Default:</strong>
-<code> announce as = NT Server</code>
+this is set to Windows NT. The valid options are : "NT", "Win95" or
+"WfW" meaning Windows NT, Windows 95 and Windows for Workgroups
+respectively. Do not change this parameter unless you have a specific
+need to stop Samba appearing as an NT server as this may prevent Samba
+servers from participating as browser servers correctly.
+<p><br><strong>Default:</strong>
+<code> announce as = NT</code>
<p><br><strong>Example</strong>
<code> announce as = Win95</code>
<p><br><a name="announceversion"></a>
@@ -826,15 +787,11 @@ will serve to packets coming in those interfaces. Note that you
should not use this parameter for machines that are serving PPP or
other intermittent or non-broadcast network interfaces as it will not
cope with non-permanent interfaces.
-<p><br>If <strong>"bind interfaces only"</strong> is set then unless the network address
-<em>127.0.0.1</em> is added to the <a href="smb.conf.5.html#interfaces"><strong>'interfaces'</strong></a> parameter
-list <a href="smbpasswd.8.html"><strong>smbpasswd</strong></a> and
-<a href="swat.8.html"><strong>swat</strong></a> may not work as expected due to the
-reasons covered below.
-<p><br>To change a users SMB password, the <a href="smbpasswd.8.html"><strong>smbpasswd</strong></a>
-by default connects to the <em>"localhost" - 127.0.0.1</em> address as an SMB
-client to issue the password change request. If <strong>"bind interfaces only"</strong>
-is set then unless the network address <em>127.0.0.1</em> is added to the
+<p><br>In addition, to change a users SMB password, the
+<a href="smbpasswd.8.html"><strong>smbpasswd</strong></a> by default connects to the
+<em>"localhost" - 127.0.0.1</em> address as an SMB client to issue the
+password change request. If <strong>"bind interfaces only"</strong> is set then
+unless the network address <em>127.0.0.1</em> is added to the
<a href="smb.conf.5.html#interfaces"><strong>'interfaces'</strong></a> parameter list then
<a href="smbpasswd.8.html"><strong>smbpasswd</strong></a> will fail to connect in it's
default mode. <a href="smbpasswd.8.html"><strong>smbpasswd</strong></a> can be forced to
@@ -842,13 +799,6 @@ use the primary IP interface of the local host by using its
<a href="smbpasswd.8.html#minusr"><strong>"-r remote machine"</strong></a> parameter, with
<strong>"remote machine"</strong> set to the IP name of the primary interface
of the local host.
-<p><br>The <a href="swat.8.html"><strong>swat</strong></a> status page tries to connect with
-<a href="smbd.8.html"><strong>smbd</strong></a> and <a href="nmbd.8.html"><strong>nmbd</strong></a> at the address
-<em>127.0.0.1</em> to determine if they are running. Not adding <em>127.0.0.1</em> will cause
-<a href="smbd.8.html"><strong>smbd</strong></a> and <a href="nmbd.8.html"><strong>nmbd</strong></a> to always show
-"not running" even if they really are. This can prevent
-<a href="swat.8.html"><strong>swat</strong></a> from starting/stopping/restarting
-<a href="smbd.8.html"><strong>smbd</strong></a> and <a href="nmbd.8.html"><strong>nmbd</strong></a>.
<p><br><strong>Default:</strong>
<code> bind interfaces only = False</code>
<p><br><strong>Example:</strong>
@@ -889,10 +839,10 @@ shares in a net view and in the browse list.
<p><br><strong>Example:</strong>
<code> browseable = No</code>
<p><br><a name="casesensitive"></a>
-<li><strong><strong>case sensitive (G)</strong></strong>
+<li><strong><strong>case sensitive (S)</strong></strong>
<p><br>See the discussion in the section <a href="smb.conf.5.html#NAMEMANGLING"><strong>NAME MANGLING</strong></a>.
<p><br><a name="casesignames"></a>
-<li><strong><strong>casesignames (G)</strong></strong>
+<li><strong><strong>casesignames (S)</strong></strong>
<p><br>Synonym for <a href="smb.conf.5.html#casesensitive"><strong>"case sensitive"</strong></a>.
<p><br><a name="changenotifytimeout"></a>
<li><strong><strong>change notify timeout (G)</strong></strong>
@@ -927,12 +877,7 @@ in order for the conversion to the UNIX character set to be done
correctly.
<p><br><li > <strong>ISO8859-5</strong> Russian Cyrillic UNIX character set. The parameter
<a href="smb.conf.5.html#clientcodepage"><strong>client code page</strong></a> <em>MUST</em> be set to code
-page 866 if the <strong>character set</strong> parameter is set to ISO8859-5
-in order for the conversion to the UNIX character set to be done
-correctly.
-<p><br><li > <strong>ISO8859-7</strong> Greek UNIX character set. The parameter
-<a href="smb.conf.5.html#clientcodepage"><strong>client code page</strong></a> <em>MUST</em> be set to code
-page 737 if the <strong>character set</strong> parameter is set to ISO8859-7
+page 866 if the <strong>character set</strong> parameter is set to ISO8859-2
in order for the conversion to the UNIX character set to be done
correctly.
<p><br><li > <strong>KOI8-R</strong> Alternate mapping for Russian Cyrillic UNIX
@@ -1103,17 +1048,6 @@ performed.
<code> deadtime = 0</code>
<p><br><strong>Example:</strong>
<code> deadtime = 15</code>
-<p><br><a name="debughirestimestamp"></a>
-<li><strong><strong>debug hires timestamp (G)</strong></strong>
-<p><br>Sometimes the timestamps in the log messages are needed with a
-resolution of higher that seconds, this boolean parameter adds
-microsecond resolution to the timestamp message header when turned on.
-<p><br>Note that the parameter <a href="smb.conf.5.html#debugtimestamp"><strong>debug timestamp</strong></a>
-must be on for this to have an effect.
-<p><br><strong>Default:</strong>
-<code> debug hires timestamp = No</code>
-<p><br><strong>Example:</strong>
-<code> debug hires timestamp = Yes</code>
<p><br><a name="debugtimestamp"></a>
<li><strong><strong>debug timestamp (G)</strong></strong>
<p><br>Samba2.0 debug log messages are timestamped by default. If you are
@@ -1124,29 +1058,6 @@ off.
<code> debug timestamp = Yes</code>
<p><br><strong>Example:</strong>
<code> debug timestamp = No</code>
-<p><br><a name="debugpid"></a>
-<li><strong><strong>debug pid (G)</strong></strong>
-<p><br>When using only one log file for more then one forked smbd-process
-there may be hard to follow which process outputs which message.
-This boolean parameter is adds the process-id to the timestamp message
-headers in the logfile when turned on.
-<p><br>Note that the parameter <a href="smb.conf.5.html#debugtimestamp"><strong>debug timestamp</strong></a>
-must be on for this to have an effect.
-<p><br><strong>Default:</strong>
-<code> debug pid = No</code>
-<p><br><strong>Example:</strong>
-<code> debug pid = Yes</code>
-<p><br><a name="debuguid"></a>
-<li><strong><strong>debug uid (G)</strong></strong>
-<p><br>Samba is sometimes run as root and sometime run as the connected
-user, this boolean parameter inserts the current euid, egid, uid
-and gid to the timestamp message headers in the log file if turned on.
-<p><br>Note that the parameter <a href="smb.conf.5.html#debugtimestamp"><strong>debug timestamp</strong></a>
-must be on for this to have an effect.
-<p><br><strong>Default:</strong>
-<code> debug uid = No</code>
-<p><br><strong>Example:</strong>
-<code> debug uid = Yes</code>
<p><br><a name="debuglevel"></a>
<li><strong><strong>debug level (G)</strong></strong>
<p><br>The value of the parameter (an integer) allows the debug level
@@ -1190,51 +1101,6 @@ interesting things.
</pre>
-<p><br><a name="deleteuserscript"></a>
-<li><strong><strong>delete user script (G)</strong></strong>
-<p><br>This is the full pathname to a script that will be run <em>AS ROOT</em> by
-<a href="smbd.8.html"><strong>smbd (8)</strong></a> under special circumstances decribed
-below.
-<p><br>Normally, a Samba server requires that UNIX users are created for all
-users accessing files on this server. For sites that use Windows NT
-account databases as their primary user database creating these users
-and keeping the user list in sync with the Windows NT PDC is an
-onerous task. This option allows <a href="smbd.8.html"><strong>smbd</strong></a> to delete
-the required UNIX users <em>ON DEMAND</em> when a user accesses the Samba
-server and the Windows NT user no longer exists.
-<p><br>In order to use this option, <a href="smbd.8.html"><strong>smbd</strong></a> must be set to
-<a href="smb.conf.5.html#securityequaldomain"><strong>security=domain</strong></a> and <strong>"delete user
-script"</strong> must be set to a full pathname for a script that will delete
-a UNIX user given one argument of <strong>%u</strong>, which expands into the UNIX
-user name to delete. <em>NOTE</em> that this is different to the
-<a href="smb.conf.5.html#adduserscript"><strong>add user script</strong></a> which will work with the
-<a href="smb.conf.5.html#securityequalserver"><strong>security=server</strong></a> option as well as
-<a href="smb.conf.5.html#securityequaldomain"><strong>security=domain</strong></a>. The reason for this
-is only when Samba is a domain member does it get the information
-on an attempted user logon that a user no longer exists. In the
-<a href="smb.conf.5.html#securityequalserver"><strong>security=server</strong></a> mode a missing user
-is treated the same as an invalid password logon attempt. Deleting
-the user in this circumstance would not be a good idea.
-<p><br>When the Windows user attempts to access the Samba server, at
-<em>"login"</em>(session setup in the SMB protocol) time,
-<a href="smbd.8.html"><strong>smbd</strong></a> contacts the <a href="smb.conf.5.html#passwordserver"><strong>password
-server</strong></a> and attempts to authenticate the given user
-with the given password. If the authentication fails with the specific
-Domain error code meaning that the user no longer exists then
-<a href="smbd.8.html"><strong>smbd</strong></a> attempts to find a UNIX user in the UNIX
-password database that matches the Windows user account. If this lookup succeeds,
-and <strong>"delete user script"</strong> is set then <a href="smbd.8.html"><strong>smbd</strong></a> will
-call the specified script <em>AS ROOT</em>, expanding any <strong>%u</strong> argument
-to be the user name to delete.
-<p><br>This script should delete the given UNIX username. In this way, UNIX
-users are dynamically deleted to match existing Windows NT accounts.
-<p><br>See also <a href="smb.conf.5.html#securityequaldomain"><strong>security=domain</strong></a>,
-<a href="smb.conf.5.html#passwordserver"><strong>password server</strong></a>, <a href="smb.conf.5.html#adduserscript"><strong>add user
-script</strong></a>.
-<p><br><strong>Default:</strong>
-<code> delete user script = &lt;empty string&gt;</code>
-<p><br><strong>Example:</strong>
-<code> delete user script = /usr/local/samba/bin/del_user %u</code>
<p><br><a name="deletereadonly"></a>
<li><strong><strong>delete readonly (S)</strong></strong>
<p><br>This parameter allows readonly files to be deleted. This is not
@@ -1269,7 +1135,14 @@ as the user has permissions to do so).
<code> delete veto files = True</code>
<p><br><a name="denyhosts"></a>
<li><strong><strong>deny hosts (S)</strong></strong>
-<p><br>Synonym for <a href="smb.conf.5.html#hostsdeny"><strong>hosts deny</strong></a>.
+<p><br>The opposite of <a href="smb.conf.5.html#allowhosts"><strong>'allow hosts'</strong></a> - hosts listed
+here are <em>NOT</em> permitted access to services unless the specific
+services have their own lists to override this one. Where the lists
+conflict, the <a href="smb.conf.5.html#allowhosts"><strong>'allow'</strong></a> list takes precedence.
+<p><br><strong>Default:</strong>
+<code> none (i.e., no hosts specifically excluded)</code>
+<p><br><strong>Example:</strong>
+<code> deny hosts = 150.203.4. badhost.mynet.edu.au</code>
<p><br><a name="dfreecommand"></a>
<li><strong><strong>dfree command (G)</strong></strong>
<p><br>The dfree command setting should only be used on systems where a
@@ -1336,8 +1209,7 @@ bits are added).
<p><br>See the <a href="smb.conf.5.html#forcedirectorymode"><strong>"force directory mode"</strong></a> parameter
to cause particular mode bits to always be set on created directories.
<p><br>See also the <a href="smb.conf.5.html#createmode"><strong>"create mode"</strong></a> parameter for masking
-mode bits on created files, and the <a href="smb.conf.5.html#directorysecuritymask"><strong>"directory security mask"</strong></a>
-parameter.
+mode bits on created files.
<p><br><strong>Default:</strong>
<code> directory mask = 0755</code>
<p><br><strong>Example:</strong>
@@ -1345,31 +1217,6 @@ parameter.
<p><br><a name="directorymode"></a>
<li><strong><strong>directory mode (S)</strong></strong>
<p><br>Synonym for <a href="smb.conf.5.html#directorymask"><strong>directory mask</strong></a>.
-<p><br><a name="directorysecuritymask"></a>
-<li><strong><strong>directory security mask (S)</strong></strong>
-<p><br>This parameter controls what UNIX permission bits can be modified
-when a Windows NT client is manipulating the UNIX permission on a
-directory using the native NT security dialog box.
-<p><br>This parameter is applied as a mask (AND'ed with) to the changed
-permission bits, thus preventing any bits not in this mask from
-being modified. Essentially, zero bits in this mask may be treated
-as a set of bits the user is not allowed to change.
-<p><br>If not set explicitly this parameter is set to the same value as the
-<a href="smb.conf.5.html#directorymask"><strong>directory mask</strong></a> parameter. To allow a user to
-modify all the user/group/world permissions on a directory, set this
-parameter to 0777.
-<p><br><em>Note</em> that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems. Administrators of
-most normal systems will probably want to set it to 0777.
-<p><br>See also the <a href="smb.conf.5.html#forcedirectorysecuritymode"><strong>force directory security
-mode</strong></a>, <a href="smb.conf.5.html#securitymask"><strong>security
-mask</strong></a>, <a href="smb.conf.5.html#forcesecuritymode"><strong>force security mode</strong></a>
-parameters.
-<p><br><strong>Default:</strong>
-<code> directory security mask = &lt;same as directory mask&gt;</code>
-<p><br><strong>Example:</strong>
-<code> directory security mask = 0777</code>
<p><br><a name="dnsproxy"></a>
<li><strong><strong>dns proxy (G)</strong></strong>
<p><br>Specifies that <a href="nmbd.8.html"><strong>nmbd</strong></a> when acting as a WINS
@@ -1388,7 +1235,7 @@ DNS name lookup requests, as doing a name lookup is a blocking action.
<p><br><a name="domainadmingroup"></a>
<strong>domain admin group (G)</strong>
<p><br>This is an <strong>EXPERIMENTAL</strong> parameter that is part of the unfinished
-Samba NT Domain Controller Code. It may be removed in a later release.
+Samba NT Domain Controller Code. It has been removed as of November 98.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list <strong>Samba-ntdom</strong> available by sending email to
@@ -1396,7 +1243,7 @@ mailing list <strong>Samba-ntdom</strong> available by sending email to
<p><br><a name="domainadminusers"></a>
<li><strong><strong>domain admin users (G)</strong></strong>
<p><br>This is an <strong>EXPERIMENTAL</strong> parameter that is part of the unfinished
-Samba NT Domain Controller Code. It may be removed in a later release.
+Samba NT Domain Controller Code. It has been removed as of November 98.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list <strong>Samba-ntdom</strong> available by sending email to
@@ -1406,10 +1253,70 @@ mailing list <strong>Samba-ntdom</strong> available by sending email to
<p><br>This is a <strong>DEPRECATED</strong> parameter. It is currently not used within
the Samba source and should be removed from all current smb.conf
files. It is left behind for compatibility reasons.
+<p><br><a name="domaingroupmap"></a>
+<li><strong><strong>domain group map (G)</strong></strong>
+<p><br>This option allows you to specify a file containing unique mappings
+of individual NT Domain Group names (in any domain) to UNIX group
+names. This allows NT domain groups to be presented correctly to
+NT users, despite the lack of native support for the NT Security model
+(based on VAX/VMS) in UNIX. The reader is advised to become familiar
+with the NT Domain system and its administration.
+<p><br>This option is used in conjunction with <a href="smb.conf.5.html#localgroupmap"><strong>'local group map'</strong></a>
+and <a href="smb.conf.5.html#domainusermap"><strong>'domain user map'</strong></a>. The use of these three
+options is trivial and often unnecessary in the case where Samba is
+not expected to interact with any other SAM databases (whether local
+workstations or Domain Controllers).
+<p><br>The map file is parsed line by line. If any line begins with a <code>'#'</code>
+or a <code>';'</code> then it is ignored. Each line should contain a single UNIX
+group name on the left then a single NT Domain Group name on the right,
+separated by a tabstop or <code>'='</code>. If either name contains spaces then
+it should be enclosed in quotes.
+The line can be either of the form:
+<p><br><code> UNIXgroupname \\DOMAIN_NAME\\DomainGroupName </code>
+<p><br>or:
+<p><br><code> UNIXgroupname DomainGroupName </code>
+<p><br>In the case where Samba is either an <strong>EXPERIMENTAL</strong> Domain Controller
+or it is a member of a domain using <a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>,
+the latter format can be used: the default Domain name is the Samba Server's
+Domain name, specified by <a href="smb.conf.5.html#workgroup"><strong>"workgroup = MYGROUP"</strong></a>.
+<p><br>Any UNIX groups that are <em>NOT</em> specified in this map file are assumed to
+be either Local or Domain Groups, depending on the role of the Samba Server.
+<p><br>In the case when Samba is an <strong>EXPERIMENTAL</strong> Domain Controller, Samba
+will present <em>ALL</em> such unspecified UNIX groups as its own NT Domain
+Groups, with the same name.
+<p><br>In the case where Samba is member of a domain using
+<a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>, Samba will check the UNIX name with
+its Domain Controller (see <a href="smb.conf.5.html#passwordserver"><strong>"password server"</strong></a>)
+as if it was an NT Domain Group. If the Domain Controller says that it is not,
+such unspecified (unmapped) UNIX groups which also are not NT Domain
+Groups are treated as Local Groups in the Samba Server's local SAM database.
+NT Administrators will recognise these as Workstation Local Groups,
+which are managed by running <strong>USRMGR.EXE</strong> and selecting a remote
+Domain named "\\WORKSTATION_NAME", or by running <strong>MUSRMGR.EXE</strong> on
+a local Workstation.
+<p><br>This may sound complicated, but it means that a Samba Server as
+either a member of a domain or as an <strong>EXPERIMENTAL</strong> Domain Controller
+will act like an NT Workstation (with a local SAM database) or an NT PDC
+(with a Domain SAM database) respectively, without the need for any of
+the map files at all. If you <strong>want</strong> to get fancy, however, you can.
+<p><br>Note that adding an entry to map an arbitrary NT group in an arbitrary
+Domain to an arbitrary UNIX group <em>REQUIRES</em> the following:
+<p><br><ul>
+<p><br><li > that the UNIX group exists on the UNIX server.
+<p><br><li > that the NT Domain Group exists in the specified NT Domain
+<p><br><li > that the UNIX Server knows about the specified Domain;
+<p><br><li > that all the UNIX users (who are expecting to access the Samba
+Server as the correct NT user and with the correct NT group permissions)
+in the UNIX group be mapped to the correct NT Domain users in the specified
+NT Domain using <a href="smb.conf.5.html#domainusermap"><strong>'domain user map'</strong></a>.
+<p><br></ul>
+<p><br>Failure to meet any of these requirements may result in either (or
+both) errors reported in the log files or (and) incorrect or missing
+access rights granted to users.
<p><br><a name="domaingroups"></a>
<li><strong><strong>domain groups (G)</strong></strong>
<p><br>This is an <strong>EXPERIMENTAL</strong> parameter that is part of the unfinished
-Samba NT Domain Controller Code. It may be removed in a later release.
+Samba NT Domain Controller Code. It has been removed as of November 98.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list <strong>Samba-ntdom</strong> available by sending email to
@@ -1417,7 +1324,7 @@ mailing list <strong>Samba-ntdom</strong> available by sending email to
<p><br><a name="domainguestgroup"></a>
<li><strong><strong>domain guest group (G)</strong></strong>
<p><br>This is an <strong>EXPERIMENTAL</strong> parameter that is part of the unfinished
-Samba NT Domain Controller Code. It may be removed in a later release.
+Samba NT Domain Controller Code. It has been removed as of November 98.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list <strong>Samba-ntdom</strong> available by sending email to
@@ -1425,7 +1332,7 @@ mailing list <strong>Samba-ntdom</strong> available by sending email to
<p><br><a name="domainguestusers"></a>
<li><strong><strong>domain guest users (G)</strong></strong>
<p><br>This is an <strong>EXPERIMENTAL</strong> parameter that is part of the unfinished
-Samba NT Domain Controller Code. It may be removed in a later release.
+Samba NT Domain Controller Code. It has been removed as of November 98.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list <strong>Samba-ntdom</strong> available by sending email to
@@ -1465,8 +1372,72 @@ if this parameter is set and <a href="nmbd.8.html"><strong>nmbd</strong></a> cla
special name for a <a href="smb.conf.5.html#workgroup"><strong>workgroup</strong></a> before a Windows NT
PDC is able to do so then cross subnet browsing will behave strangely
and may fail.
+<p><br>By default ("auto") Samba will attempt to become the domain master
+browser only if it is the Primary Domain Controller.
<p><br><strong>Default:</strong>
+<code> domain master = auto</code>
+<p><br><strong>Example:</strong>
<code> domain master = no</code>
+<p><br><a name="domainusermap"></a>
+<li><strong><strong>domain user map (G)</strong></strong>
+<p><br>This option allows you to specify a file containing unique mappings
+of individual NT Domain User names (in any domain) to UNIX user
+names. This allows NT domain users to be presented correctly to
+NT systems, despite the lack of native support for the NT Security model
+(based on VAX/VMS) in UNIX. The reader is advised to become familiar
+with the NT Domain system and its administration.
+<p><br>This option is used in conjunction with <a href="smb.conf.5.html#localgroupmap"><strong>'local group map'</strong></a>
+and <a href="smb.conf.5.html#domaingroupmap"><strong>'domain group map'</strong></a>. The use of these three
+options is trivial and often unnecessary in the case where Samba is
+not expected to interact with any other SAM databases (whether local
+workstations or Domain Controllers).
+<p><br>This option, which provides (and maintains) a one-to-one link between
+UNIX and NT users, is <em>DIFFERENT</em> from <a href="smb.conf.5.html#usernamemap"><strong>'username map'</strong></a>, which does <em>NOT</em> maintain a distinction between the
+name(s) it can map to and the name it maps.
+<p><br>The map file is parsed line by line. If any line begins with a <code>'#'</code>
+or a <code>';'</code> then the line is ignored. Each line should contain a single UNIX
+user name on the left then a single NT Domain User name on the right,
+separated by a tabstop or <code>'='</code>. If either name contains spaces then
+it should be enclosed in quotes.
+The line can be either of the form:
+<p><br><code> UNIXusername \\DOMAIN_NAME\\DomainUserName </code>
+<p><br>or:
+<p><br><code> UNIXusername DomainUserName </code>
+<p><br>In the case where Samba is either an <strong>EXPERIMENTAL</strong> Domain Controller
+or it is a member of a domain using <a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>,
+the latter format can be used: the default Domain name is the Samba Server's
+Domain name, specified by <a href="smb.conf.5.html#workgroup"><strong>"workgroup = MYGROUP"</strong></a>.
+<p><br>Any UNIX users that are <em>NOT</em> specified in this map file are assumed
+to be either Domain or Workstation Users, depending on the role of the
+Samba Server.
+<p><br>In the case when Samba is an <strong>EXPERIMENTAL</strong> Domain Controller, Samba
+will present <em>ALL</em> such unspecified UNIX users as its own NT Domain
+Users, with the same name.
+<p><br>In the case where Samba is a member of a domain using
+<a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>, Samba will check the UNIX name with
+its Domain Controller (see <a href="smb.conf.5.html#passwordserver"><strong>"password server"</strong></a>)
+as if it was an NT Domain User. If the Domain Controller says that it is not,
+such unspecified (unmapped) UNIX users which also are not NT Domain
+Users are treated as Local Users in the Samba Server's local SAM database.
+NT Administrators will recognise these as Workstation Users,
+which are managed by running <strong>USRMGR.EXE</strong> and selecting a remote
+Domain named "\\WORKSTATION_NAME", or by running <strong>MUSRMGR.EXE</strong> on
+a local Workstation.
+<p><br>This may sound complicated, but it means that a Samba Server as
+either a member of a domain or as an <strong>EXPERIMENTAL</strong> Domain Controller
+will act like an NT Workstation (with a local SAM database) or an NT PDC
+(with a Domain SAM database) respectively, without the need for any of
+the map files at all. If you <strong>want</strong> to get fancy, however, you can.
+<p><br>Note that adding an entry to map an arbitrary NT User in an arbitrary
+Domain to an arbitrary UNIX user <em>REQUIRES</em> the following:
+<p><br><ul>
+<p><br><li > that the UNIX user exists on the UNIX server.
+<p><br><li > that the NT Domain User exists in the specified NT Domain.
+<p><br><li > that the UNIX Server knows about the specified Domain.
+<p><br></ul>
+<p><br>Failure to meet any of these requirements may result in either (or
+both) errors reported in the log files or (and) incorrect or missing
+access rights granted to users.
<p><br><a name="dontdescend"></a>
<li><strong><strong>dont descend (S)</strong></strong>
<p><br>There are certain directories on some systems (e.g., the <code>/proc</code> tree
@@ -1628,31 +1599,6 @@ details on masking mode bits on created directories.
<p><br>would force all created directories to have read and execute
permissions set for 'group' and 'other' as well as the
read/write/execute bits set for the 'user'.
-<p><br><a name="forcedirectorysecuritymode"></a>
-<li><strong><strong>force directory security mode (S)</strong></strong>
-<p><br>This parameter controls what UNIX permission bits can be modified when
-a Windows NT client is manipulating the UNIX permission on a directory
-using the native NT security dialog box.
-<p><br>This parameter is applied as a mask (OR'ed with) to the changed
-permission bits, thus forcing any bits in this mask that the user may
-have modified to be on. Essentially, one bits in this mask may be
-treated as a set of bits that, when modifying security on a directory,
-the user has always set to be 'on'.
-<p><br>If not set explicitly this parameter is set to the same value as the
-<a href="smb.conf.5.html#forcedirectorymode"><strong>force directory mode</strong></a> parameter. To allow
-a user to modify all the user/group/world permissions on a directory,
-with restrictions set this parameter to 000.
-<p><br><em>Note</em> that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems. Administrators of
-most normal systems will probably want to set it to 0000.
-<p><br>See also the <a href="smb.conf.5.html#directorysecuritymask"><strong>directory security mask</strong></a>,
-<a href="smb.conf.5.html#securitymask"><strong>security mask</strong></a>, <a href="smb.conf.5.html#forcesecuritymode"><strong>force security
-mode</strong></a> parameters.
-<p><br><strong>Default:</strong>
-<code> force directory security mode = &lt;same as force directory mode&gt;</code>
-<p><br><strong>Example:</strong>
-<code> force directory security mode = 0</code>
<p><br><a name="forcegroup"></a>
<li><strong><strong>force group (S)</strong></strong>
<p><br>This specifies a UNIX group name that will be assigned as the default
@@ -1662,51 +1608,10 @@ use the named group for their permissions checking. Thus, by assigning
permissions for this group to the files and directories within this
service the Samba administrator can restrict or allow sharing of these
files.
-<p><br>In Samba 2.0.5 and above this parameter has extended functionality in the following
-way. If the group name listed here has a '+' character prepended to it
-then the current user accessing the share only has the primary group
-default assigned to this group if they are already assigned as a member
-of that group. This allows an administrator to decide that only users
-who are already in a particular group will create files with group
-ownership set to that group. This gives a finer granularity of ownership
-assignment. For example, the setting <code>force group = +sys</code> means
-that only users who are already in group sys will have their default
-primary group assigned to sys when accessing this Samba share. All
-other users will retain their ordinary primary group.
-<p><br>If the <a href="smb.conf.5.html#forceuser"><strong>"force user"</strong></a> parameter is also set the
-group specified in <strong>force group</strong> will override the primary group
-set in <a href="smb.conf.5.html#forceuser"><strong>"force user"</strong></a>.
-<p><br>See also <a href="smb.conf.5.html#forceuser"><strong>"force user"</strong></a>
<p><br><strong>Default:</strong>
<code> no forced group</code>
<p><br><strong>Example:</strong>
<code> force group = agroup</code>
-<p><br><a name="forcesecuritymode"></a>
-<li><strong><strong>force security mode (S)</strong></strong>
-<p><br>This parameter controls what UNIX permission bits can be modified when
-a Windows NT client is manipulating the UNIX permission on a file
-using the native NT security dialog box.
-<p><br>This parameter is applied as a mask (OR'ed with) to the changed
-permission bits, thus forcing any bits in this mask that the user may
-have modified to be on. Essentially, one bits in this mask may be
-treated as a set of bits that, when modifying security on a file, the
-user has always set to be 'on'.
-<p><br>If not set explicitly this parameter is set to the same value as the
-<a href="smb.conf.5.html#forcecreatemode"><strong>force create mode</strong></a> parameter. To allow
-a user to modify all the user/group/world permissions on a file,
-with no restrictions set this parameter to 000.
-<p><br><em>Note</em> that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems. Administrators of
-most normal systems will probably want to set it to 0000.
-<p><br>See also the <a href="smb.conf.5.html#forcedirectorysecuritymode"><strong>force directory security
-mode</strong></a>, <a href="smb.conf.5.html#directorysecuritymask"><strong>directory security
-mask</strong></a>, <a href="smb.conf.5.html#securitymask"><strong>security mask</strong></a>
-parameters.
-<p><br><strong>Default:</strong>
-<code> force security mode = &lt;same as force create mode&gt;</code>
-<p><br><strong>Example:</strong>
-<code> force security mode = 0</code>
<p><br><a name="forceuser"></a>
<li><strong><strong>force user (S)</strong></strong>
<p><br>This specifies a UNIX user name that will be assigned as the default
@@ -1718,11 +1623,6 @@ clients still need to connect as a valid user and supply a valid
password. Once connected, all file operations will be performed as the
<code>"forced user"</code>, no matter what username the client connected as.
<p><br>This can be very useful.
-<p><br>In Samba 2.0.5 and above this parameter also causes the primary
-group of the forced user to be used as the primary group for all
-file activity. Prior to 2.0.5 the primary group was left as the
-primary group of the connecting user (this was a bug).
-<p><br>See also <a href="smb.conf.5.html#forcegroup"><strong>"force group"</strong></a>
<p><br><strong>Default:</strong>
<code> no forced user</code>
<p><br><strong>Example:</strong>
@@ -1828,7 +1728,7 @@ files"</strong></a> and <a href="smb.conf.5.html#casesensitive"><strong>"case se
<p><br><strong>Example</strong>
<code> hide files = /.*/DesktopFolderDB/TrashFor%m/resource.frk/</code>
<p><br>The above example is based on files that the Macintosh SMB client
-(DAVE) available from <a href="http://www.thursby.com"><strong>Thursby</strong></a> creates for
+(DAVE) available from <a href="www.thursby.com"><strong>Thursby</strong></a> creates for
internal use, and also still hides all files beginning with a dot.
<p><br><a name="homedirmap"></a>
<li><strong><strong>homedir map (G)</strong></strong>
@@ -1851,57 +1751,16 @@ logons</strong></a>.
<code> homedir map = amd.homedir</code>
<p><br><a name="hostsallow"></a>
<li><strong><strong>hosts allow (S)</strong></strong>
-<p><br>A synonym for this parameter is <a href="smb.conf.5.html#allowhosts"><strong>'allow hosts'</strong></a>
-<p><br>This parameter is a comma, space, or tab delimited set of hosts which
-are permitted to access a service.
-<p><br>If specified in the <a href="smb.conf.5.html#global"><strong>[global]</strong></a> section then it will
-apply to all services, regardless of whether the individual service
-has a different setting.
-<p><br>You can specify the hosts by name or IP number. For example, you could
-restrict access to only the hosts on a Class C subnet with something
-like <code>"allow hosts = 150.203.5."</code>. The full syntax of the list is
-described in the man page <strong>hosts_access (5)</strong>. Note that this man
-page may not be present on your system, so a brief description will
-be given here also.
-<p><br>Note that the localhost address 127.0.0.1 will always be allowed
-access unless specifically denied by a "hosts deny" option.
-<p><br>You can also specify hosts by network/netmask pairs and by netgroup
-names if your system supports netgroups. The <em>EXCEPT</em> keyword can also
-be used to limit a wildcard list. The following examples may provide
-some help:
-<p><br><strong>Example 1</strong>: allow all IPs in 150.203.*.* except one
-<p><br><code> hosts allow = 150.203. EXCEPT 150.203.6.66</code>
-<p><br><strong>Example 2</strong>: allow hosts that match the given network/netmask
-<p><br><code> hosts allow = 150.203.15.0/255.255.255.0</code>
-<p><br><strong>Example 3</strong>: allow a couple of hosts
-<p><br><code> hosts allow = lapland, arvidsjaur</code>
-<p><br><strong>Example 4</strong>: allow only hosts in NIS netgroup "foonet", but
-deny access from one particular host
-<p><br><code> hosts allow = @foonet</code>
-<p><br><code> hosts deny = pirate</code>
-<p><br>Note that access still requires suitable user-level passwords.
-<p><br>See <a href="testparm.1.html"><strong>testparm (1)</strong></a> for a way of testing your
-host access to see if it does what you expect.
-<p><br><strong>Default:</strong>
-<code> none (i.e., all hosts permitted access)</code>
-<p><br><strong>Example:</strong>
-<code> allow hosts = 150.203.5. myhost.mynet.edu.au</code>
+<p><br>Synonym for <a href="smb.conf.5.html#allowhosts"><strong>allow hosts</strong></a>.
<p><br><a name="hostsdeny"></a>
<li><strong><strong>hosts deny (S)</strong></strong>
-<p><br>The opposite of <a href="smb.conf.5.html#hostsallow"><strong>'hosts allow'</strong></a> - hosts listed
-here are <em>NOT</em> permitted access to services unless the specific
-services have their own lists to override this one. Where the lists
-conflict, the <a href="smb.conf.5.html#hostsallow"><strong>'allow'</strong></a> list takes precedence.
-<p><br><strong>Default:</strong>
-<code> none (i.e., no hosts specifically excluded)</code>
-<p><br><strong>Example:</strong>
-<code> hosts deny = 150.203.4. badhost.mynet.edu.au</code>
+<p><br>Synonym for <a href="smb.conf.5.html#denyhosts"><strong>denyhosts</strong></a>.
<p><br><a name="hostsequiv"></a>
<li><strong><strong>hosts equiv (G)</strong></strong>
<p><br>If this global parameter is a non-null string, it specifies the name
of a file to read for the names of hosts and users who will be allowed
access without specifying a password.
-<p><br>This is not be confused with <a href="smb.conf.5.html#hostsallow"><strong>hosts allow</strong></a> which
+<p><br>This is not be confused with <a href="smb.conf.5.html#allowhosts"><strong>allow hosts</strong></a> which
is about hosts access to services and is more useful for guest
services. <strong>hosts equiv</strong> may be useful for NT clients which will not
supply passwords to samba.
@@ -1923,32 +1782,20 @@ is included literally, as though typed in place.
<a href="smb.conf.5.html#percentP"><strong>%P</strong></a> and <a href="smb.conf.5.html#percentS"><strong>%S</strong></a>.
<p><br><a name="interfaces"></a>
<li><strong><strong>interfaces (G)</strong></strong>
-<p><br>This option allows you to override the default network interfaces list
-that Samba will use for browsing, name registration and other NBT
-traffic. By default Samba will query the kernel for the list of all
-active interfaces and use any interfaces except 127.0.0.1 that are
-broadcast capable.
-<p><br>The option takes a list of interface strings. Each string can be in
-any of the following forms:
-<p><br><ul>
-<li > a network interface name (such as eth0). This may include
- shell-like wildcards so eth* will match any interface starting
- with the substring "eth"
-if() a IP address. In this case the netmask is determined
- from the list of interfaces obtained from the kernel
-if() a IP/mask pair.
-if() a broadcast/mask pair.
-</ul>
-<p><br>The "mask" parameters can either be a bit length (such as 24 for a C
-class network) or a full netmask in dotted decmal form.
-<p><br>The "IP" parameters above can either be a full dotted decimal IP
-address or a hostname which will be looked up via the OSes normal
-hostname resolution mechanisms.
+<p><br>This option allows you to setup multiple network interfaces, so that
+Samba can properly handle browsing on all interfaces.
+<p><br>The option takes a list of ip/netmask pairs. The netmask may either be
+a bitmask, or a bitlength.
<p><br>For example, the following line:
-<p><br><code>interfaces = eth0 192.168.2.10/24 192.168.3.10/255.255.255.0</code>
-<p><br>would configure three network interfaces corresponding to the eth0
-device and IP addresses 192.168.2.10 and 192.168.3.10. The netmasks of
-the latter two interfaces would be set to 255.255.255.0.
+<p><br><code>interfaces = 192.168.2.10/24 192.168.3.10/24</code>
+<p><br>would configure two network interfaces with IP addresses 192.168.2.10
+and 192.168.3.10. The netmasks of both interfaces would be set to
+255.255.255.0.
+<p><br>You could produce an equivalent result by using:
+<p><br><code>interfaces = 192.168.2.10/255.255.255.0 192.168.3.10/255.255.255.0</code>
+<p><br>if you prefer that format.
+<p><br>If this option is not set then Samba will attempt to find a primary
+interface, but won't attempt to configure more than one interface.
<p><br>See also <a href="smb.conf.5.html#bindinterfacesonly"><strong>"bind interfaces only"</strong></a>.
<p><br><a name="invalidusers"></a>
<li><strong><strong>invalid users (S)</strong></strong>
@@ -1986,9 +1833,9 @@ has the SO_KEEPALIVE attribute set on it (see <a href="smb.conf.5.html#socketopt
options"</strong></a>). Basically you should only use this option
if you strike difficulties.
<p><br><strong>Default:</strong>
-<code> keepalive = 0</code>
+<code> keep alive = 0</code>
<p><br><strong>Example:</strong>
-<code> keepalive = 60</code>
+<code> keep alive = 60</code>
<p><br><a name="kerneloplocks"></a>
<li><strong><strong>kernel oplocks (G)</strong></strong>
<p><br>For UNIXs that support kernel based <a href="smb.conf.5.html#oplocks"><strong>oplocks</strong></a>
@@ -2002,57 +1849,42 @@ data consistency between SMB/CIFS, NFS and local file access (and is a
<p><br>This parameter defaults to <em>"On"</em> on systems that have the support,
and <em>"off"</em> on systems that don't. You should never need to touch
this parameter.
-<p><br>See also the <a href="smb.conf.5.html#oplocks"><strong>"oplocks"</strong></a> and <a href="smb.conf.5.html#level2oplocks"><strong>"level2 oplocks"</strong></a>
-parameters.
-<p><br><a name="ldapfilter"></a>
-<li><strong><strong>ldap filter (G)</strong></strong>
+<p><br><a name="ldapbindas"></a>
+<li><strong><strong>ldap bind as (G)</strong></strong>
<p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
-password database stored on an LDAP server back-end. These options
-are only available if your version of Samba was configured with
-the <strong>--with-ldap</strong> option.
-<p><br>This parameter specifies an LDAP search filter used to search for a
-user name in the LDAP database. It must contain the string
-<a href="smb.conf.5.html#percentU"><strong>%u</strong></a> which will be replaced with the user being
-searched for.
+password database stored on an LDAP server. These options are only
+available if your version of Samba was configured with the <strong>--with-ldap</strong>
+option.
+<p><br>This parameter specifies the entity to bind to an LDAP directory as.
+Usually it should be safe to use the LDAP root account; for larger
+installations it may be preferable to restrict Samba's access. See also
+<a href="smb.conf.5.html#ldappasswdfile"><strong>ldap passwd file</strong></a>.
+<p><br><strong>Default:</strong>
+<code> none (bind anonymously)</code>
+<p><br><strong>Example:</strong>
+<code> ldap bind as = "uid=root, dc=mydomain, dc=org"</code>
+<p><br><a name="ldappasswdfile"></a>
+<li><strong><strong>ldap passwd file (G)</strong></strong>
+<p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
+password database stored on an LDAP server. These options are only
+available if your version of Samba was configured with the <strong>--with-ldap</strong>
+option.
+<p><br>This parameter specifies a file containing the password with which
+Samba should bind to an LDAP server. For obvious security reasons
+this file must be set to mode 700 or less.
<p><br><strong>Default:</strong>
-<code> empty string.</code>
+<code> none (bind anonymously)</code>
+<p><br><strong>Example:</strong>
+<code> ldap passwd file = /usr/local/samba/private/ldappasswd</code>
<p><br><a name="ldapport"></a>
<li><strong><strong>ldap port (G)</strong></strong>
<p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
-password database stored on an LDAP server back-end. These options
-are only available if your version of Samba was configured with
-the <strong>--with-ldap</strong> option.
-<p><br>This parameter specifies the TCP port number to use to contact
-the LDAP server on.
+password database stored on an LDAP server. These options are only
+available if your version of Samba was configured with the <strong>--with-ldap</strong>
+option.
+<p><br>This parameter specifies the TCP port number of the LDAP server.
<p><br><strong>Default:</strong>
<code> ldap port = 389.</code>
-<p><br><a name="ldaproot"></a>
-<li><strong><strong>ldap root (G)</strong></strong>
-<p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
-password database stored on an LDAP server back-end. These options
-are only available if your version of Samba was configured with
-the <strong>--with-ldap</strong> option.
-<p><br>This parameter specifies the entity to bind to the LDAP server
-as (essentially the LDAP username) in order to be able to perform
-queries and modifications on the LDAP database.
-<p><br>See also <a href="smb.conf.5.html#ldaprootpasswd"><strong>ldap root passwd</strong></a>.
-<p><br><strong>Default:</strong>
-<code> empty string (no user defined)</code>
-<p><br><a name="ldaprootpasswd"></a>
-<li><strong><strong>ldap root passwd (G)</strong></strong>
-<p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
-password database stored on an LDAP server back-end. These options
-are only available if your version of Samba was configured with
-the <strong>--with-ldap</strong> option.
-<p><br>This parameter specifies the password for the entity to bind to the
-LDAP server as (the password for this LDAP username) in order to be
-able to perform queries and modifications on the LDAP database.
-<p><br><em>BUGS:</em> This parameter should <em>NOT</em> be a readable parameter
-in the <strong>smb.conf</strong> file and will be removed once a correct
-storage place is found.
-<p><br>See also <a href="smb.conf.5.html#ldaproot"><strong>ldap root</strong></a>.
-<p><br><strong>Default:</strong>
-<code> empty string.</code>
<p><br><a name="ldapserver"></a>
<li><strong><strong>ldap server (G)</strong></strong>
<p><br>This parameter is part of the <em>EXPERIMENTAL</em> Samba support for a
@@ -2060,7 +1892,8 @@ password database stored on an LDAP server back-end. These options
are only available if your version of Samba was configured with
the <strong>--with-ldap</strong> option.
<p><br>This parameter specifies the DNS name of the LDAP server to use
-for SMB/CIFS authentication purposes.
+when storing and retrieving information about Samba users and
+groups.
<p><br><strong>Default:</strong>
<code> ldap server = localhost</code>
<p><br><a name="ldapsuffix"></a>
@@ -2069,42 +1902,13 @@ for SMB/CIFS authentication purposes.
password database stored on an LDAP server back-end. These options
are only available if your version of Samba was configured with
the <strong>--with-ldap</strong> option.
-<p><br>This parameter specifies the <code>"dn"</code> or LDAP <em>"distinguished name"</em>
-that tells <a href="smbd.8.html"><strong>smbd</strong></a> to start from when searching
-for an entry in the LDAP password database.
-<p><br><strong>Default:</strong>
-<code> empty string.</code>
-<p><br><a name="level2oplocks"></a>
-<li><strong><strong>level2 oplocks (S)</strong></strong>
-<p><br>This parameter (new in Samba 2.0.5) controls whether Samba supports
-level2 (read-only) oplocks on a share. In Samba 2.0.4 this parameter
-defaults to "False" as the code is new, but will default to "True"
-in a later release.
-<p><br>Level2, or read-only oplocks allow Windows NT clients that have an
-oplock on a file to downgrade from a read-write oplock to a read-only
-oplock once a second client opens the file (instead of releasing all
-oplocks on a second open, as in traditional, exclusive oplocks). This
-allows all openers of the file that support level2 oplocks to cache
-the file for read-ahead only (ie. they may not cache writes or lock
-requests) and increases performance for many acesses of files that
-are not commonly written (such as application .EXE files).
-<p><br>Once one of the clients which have a read-only oplock writes to
-the file all clients are notified (no reply is needed or waited
-for) and told to break their oplocks to "none" and delete any
-read-ahead caches.
-<p><br>It is recommended that this parameter be turned on to speed access
-to shared executables (and also to test the code :-).
-<p><br>For more discussions on level2 oplocks see the CIFS spec.
-<p><br>Currently, if <a href="smb.conf.5.html#kerneloplocks"><strong>"kernel oplocks"</strong></a> are supported
-then level2 oplocks are not granted (even if this parameter is set
-to <code>"true"</code>). Note also, the <a href="smb.conf.5.html#oplocks"><strong>"oplocks"</strong></a> parameter must
-be set to "true" on this share in order for this parameter to have any
-effect.
-<p><br>See also the <a href="smb.conf.5.html#oplocks"><strong>"oplocks"</strong></a> and <a href="smb.conf.5.html#kerneloplocks"><strong>"kernel oplocks"</strong></a> parameters.
-<p><br><strong>Default:</strong>
-<code> level2 oplocks = False</code>
-<p><br><strong>Example:</strong>
-<code> level2 oplocks = True</code>
+<p><br>This parameter specifies the node of the LDAP tree beneath which
+Samba should store its information. This parameter MUST be provided
+when using LDAP with Samba.
+<p><br><strong>Default:</strong>
+<code> none</code>
+<p><br><strong>Example:</strong>
+<code> ldap suffix = "dc=mydomain, dc=org"</code>
<p><br><a name="lmannounce"></a>
<li><strong><strong>lm announce (G)</strong></strong>
<p><br>This parameter determines if <a href="nmbd.8.html"><strong>nmbd</strong></a> will produce
@@ -2145,6 +1949,66 @@ will be loaded for browsing by default. See the
<code> load printers = yes</code>
<p><br><strong>Example:</strong>
<code> load printers = no</code>
+<p><br><a name="localgroupmap"></a>
+<li><strong><strong>local group map (G)</strong></strong>
+<p><br>This option allows you to specify a file containing unique mappings
+of individual NT Local Group names (in any domain) to UNIX group
+names. This allows NT Local groups (aliases) to be presented correctly to
+NT users, despite the lack of native support for the NT Security model
+(based on VAX/VMS) in UNIX. The reader is advised to become familiar
+with the NT Domain system and its administration.
+<p><br>This option is used in conjunction with <a href="smb.conf.5.html#domaingroupmap"><strong>'domain group map'</strong></a>
+and <a href="smb.conf.5.html#domainusermap"><strong>'domain name map'</strong></a>. The use of these three
+options is trivial and often unnecessary in the case where Samba
+is not expected to interact with any other SAM databases (whether local
+workstations or Domain Controllers).
+<p><br>The map file is parsed line by line. If any line begins with a <code>'#'</code>
+or a <code>';'</code> then it is ignored. Each line should contain a single UNIX
+group name on the left then a single NT Local Group name on the right,
+separated by a tabstop or <code>'='</code>. If either name contains spaces then
+it should be enclosed in quotes.
+The line can be either of the form:
+<p><br><code> UNIXgroupname \\DOMAIN_NAME\\LocalGroupName </code>
+<p><br>or:
+<p><br><code> UNIXgroupname LocalGroupName </code>
+<p><br>In the case where Samba is either an <strong>EXPERIMENTAL</strong> Domain Controller
+or it is a member of a domain using <a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>,
+the latter format can be used: the default Domain name is the Samba Server's
+Domain name, specified by <a href="smb.conf.5.html#workgroup"><strong>"workgroup = MYGROUP"</strong></a>.
+<p><br>Any UNIX groups that are <em>NOT</em> specified in this map file are treated
+as either Local or Domain Groups depending on the role of the Samba Server.
+<p><br>In the case when Samba is an <strong>EXPERIMENTAL</strong> Domain Controller, Samba
+will present <em>ALL</em> unspecified UNIX groups as its own NT Domain
+Groups, with the same name, and <em>NOT</em> as Local Groups.
+<p><br>In the case where Samba is member of a domain using
+<a href="smb.conf.5.html#security"><strong>"security = domain"</strong></a>, Samba will check the UNIX name with
+its Domain Controller (see <a href="smb.conf.5.html#passwordserver"><strong>"password server"</strong></a>)
+as if it was an NT Domain Group. If the Domain Controller says that it is not,
+such unspecified (unmapped) UNIX groups which also are not NT Domain
+Groups are treated as Local Groups in the Samba Server's local SAM database.
+NT Administrators will recognise these as Workstation Local Groups,
+which are managed by running <strong>USRMGR.EXE</strong> and selecting a remote
+Domain named "\\WORKSTATION_NAME", or by running <strong>MUSRMGR.EXE</strong> on
+a local Workstation.
+<p><br>This may sound complicated, but it means that a Samba Server as
+either a member of a domain or as an <strong>EXPERIMENTAL</strong> Domain Controller
+will act like an NT Workstation (with a local SAM database) or an NT PDC
+(with a Domain SAM database) respectively, without the need for any of
+the map files at all. If you <strong>want</strong> to get fancy, however, you can.
+<p><br>Note that adding an entry to map an arbitrary NT group in an arbitrary
+Domain to an arbitrary UNIX group <em>REQUIRES</em> the following:
+<p><br><ul>
+<p><br><li > that the UNIX group exists on the UNIX server.
+<p><br><li > that the NT Domain Group exists in the specified NT Domain
+<p><br><li > that the UNIX Server knows about the specified Domain;
+<p><br><li > that all the UNIX users (who are expecting to access the Samba
+Server as the correct NT user and with the correct NT group permissions)
+in the UNIX group be mapped to the correct NT Domain users in the specified
+NT Domain using <a href="smb.conf.5.html#domainusermap"><strong>'domain user map'</strong></a>.
+<p><br></ul>
+<p><br>Failure to meet any of these requirements may result in either (or
+both) errors reported in the log files or (and) incorrect or missing
+access rights granted to users.
<p><br><a name="localmaster"></a>
<li><strong><strong>local master (G)</strong></strong>
<p><br>This option allows <a href="nmbd.8.html"><strong>nmbd</strong></a> to try and become a
@@ -2444,11 +2308,6 @@ end.
<p><br><a name="manglecase"></a>
<li><strong><strong>mangle case (S)</strong></strong>
<p><br>See the section on <a href="smb.conf.5.html#NAMEMANGLING"><strong>"NAME MANGLING"</strong></a>.
-<p><br><a name="manglelocks"></a>
-<li><strong><strong>mangle locks (S)</strong></strong>
-<p><br>This option is was introduced with Samba 2.0.4 and above and has been
-removed in Samba 2.0.6 as Samba now dynamically configures such things
-on 32 bit systems.
<p><br><a name="mangledmap"></a>
<li><strong><strong>mangled map (S)</strong></strong>
<p><br>This is for those who want to directly map UNIX file names which can
@@ -2670,7 +2529,7 @@ never need to set this parameter.
<p><br><strong>Default:</strong>
<code> max mux = 50</code>
<p><br><a name="maxopenfiles"></a>
-<li><strong><strong>max open files (G)</strong></strong>
+<li><strong><strong>maxopenfiles (G)</strong></strong>
<p><br>This parameter limits the maximum number of open files that one
<a href="smbd.8.html"><strong>smbd</strong></a> file serving process may have open for
a client at any one time. The default for this parameter is set
@@ -2761,15 +2620,6 @@ job.
<code> min print space = 0</code>
<p><br><strong>Example:</strong>
<code> min print space = 2000</code>
-<p><br><a name="minpasswdlength"></a>
-<li><strong><strong>min passwd length (G)</strong></strong>
-<p><br>This option sets the minimum length in characters of a plaintext password
-than smbd will accept when performing UNIX password changing.
-<p><br>See also <a href="smb.conf.5.html#unixpasswordsync"><strong>"unix password sync"</strong></a>,
-<a href="smb.conf.5.html#passwdprogram"><strong>"passwd program"</strong></a> and <a href="smb.conf.5.html#passwdchatdebug"><strong>"passwd chat
-debug"</strong></a>.
-<p><br><strong>Default:</strong>
-<code> min passwd length = 5</code>
<p><br><a name="minwinsttl"></a>
<li><strong><strong>min wins ttl (G)</strong></strong>
<p><br>This option tells <a href="nmbd.8.html"><strong>nmbd</strong></a> when acting as a WINS
@@ -2789,15 +2639,10 @@ resolution options.
names to be resolved as follows :
<p><br><ul>
<p><br><li > <strong>lmhosts</strong> : Lookup an IP address in the Samba lmhosts file.
-If the line in lmhosts has no name type attached to the NetBIOS
-name (see the <a href="lmhosts.5.html"><strong>lmhosts (5)</strong></a> for details) then
-any name type matches for lookup.
<p><br><li > <strong>host</strong> : Do a standard host name to IP address resolution,
using the system /etc/hosts, NIS, or DNS lookups. This method of name
resolution is operating system depended for instance on IRIX or
Solaris this may be controlled by the <em>/etc/nsswitch.conf</em> file).
-Note that this method is only used if the NetBIOS name type being
-queried is the 0x20 (server) name type, otherwise it is ignored.
<p><br><li > <strong>wins</strong> : Query a name with the IP address listed in the
<a href="smb.conf.5.html#winsserver"><strong>wins server</strong></a> parameter. If no WINS server has
been specified this method will be ignored.
@@ -2864,14 +2709,6 @@ system and the Samba server with this option must also be a
<code> nis homedir = false</code>
<p><br><strong>Example:</strong>
<code> nis homedir = true</code>
-<p><br><a name="ntaclsupport"></a>
-<li><strong><strong>nt acl support (G)</strong></strong>
-<p><br>This boolean parameter controls whether <a href="smbd.8.html"><strong>smbd</strong></a>
-will attempt to map UNIX permissions into Windows NT access control lists.
-<p><br><strong>Default:</strong>
-<code> nt acl support = yes</code>
-<p><br><strong>Example:</strong>
-<code> nt acl support = no</code>
<p><br><a name="ntpipesupport"></a>
<li><strong><strong>nt pipe support (G)</strong></strong>
<p><br>This boolean parameter controls whether <a href="smbd.8.html"><strong>smbd</strong></a>
@@ -2950,47 +2787,21 @@ by the underlying operating system. This allows data synchronization between
all access to oplocked files, whether it be via Samba or NFS or a local
UNIX process. See the <a href="smb.conf.5.html#kerneloplocks"><strong>kernel oplocks</strong></a> parameter
for details.
-<p><br>See also the <a href="smb.conf.5.html#kerneloplocks"><strong>"kernel oplocks"</strong></a> and
-<a href="smb.conf.5.html#level2oplocks"><strong>"level2 oplocks"</strong></a> parameters.
<p><br><strong>Default:</strong>
<code> oplocks = True</code>
<p><br><strong>Example:</strong>
<code> oplocks = False</code>
-<p><br><a name="oplockbreakwaittime"></a>
-<li><strong><strong>oplock break wait time (G)</strong></strong>
-<p><br>This is a tuning parameter added due to bugs in both Windows 9x and WinNT.
-If Samba responds to a client too quickly when that client issues an SMB that
-can cause an oplock break request, then the client redirector can fail and
-not respond to the break request. This tuning parameter (which is set in
-milliseconds) is the amount of time Samba will wait before sending an
-oplock break request to such (broken) clients.
-<p><br><em>DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
-OPLOCK CODE</em>.
-<p><br><strong>Default:</strong>
-<code> oplock break wait time = 10</code>
-<p><br><a name="oplockcontentionlimit"></a>
-<li><strong><strong>oplock contention limit (S)</strong></strong>
-<p><br>This is a <em>very</em> advanced <a href="smbd.8.html"><strong>smbd</strong></a> tuning option to improve
-the efficiency of the granting of oplocks under multiple client contention for the same file.
-<p><br>In brief it specifies a number, which causes smbd not to grant an oplock even
-when requested if the approximate number of clients contending for an oplock on
-the same file goes over this limit. This causes <a href="smbd.8.html"><strong>smbd</strong></a> to
-behave in a similar way to Windows NT.
-<p><br><em>DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
-OPLOCK CODE</em>.
-<p><br><strong>Default:</strong>
-<code> oplock contention limit = 2</code>
<p><br><a name="oslevel"></a>
<li><strong><strong>os level (G)</strong></strong>
<p><br>This integer value controls what level Samba advertises itself as for
browse elections. The value of this parameter determines whether
<a href="nmbd.8.html"><strong>nmbd</strong></a> has a chance of becoming a local master
browser for the <a href="smb.conf.5.html#workgroup"><strong>WORKGROUP</strong></a> in the local broadcast
-area. The default is zero, which means <a href="nmbd.8.html"><strong>nmbd</strong></a> will
-lose elections to Windows machines. See BROWSING.txt in the Samba
-docs/ directory for details.
+area. Setting this to zero will cause <a href="nmbd.8.html"><strong>nmbd</strong></a> to
+always lose elections to Windows machines. See BROWSING.txt in the
+Samba docs/ directory for details.
<p><br><strong>Default:</strong>
-<code> os level = 20</code>
+<code> os level = 32</code>
<p><br><strong>Example:</strong>
<code> os level = 65 ; This will win against any NT Server</code>
<p><br><a name="packetsize"></a>
@@ -3147,18 +2958,13 @@ better restrict them with hosts allow!
<p><br>If the <a href="smb.conf.5.html#security"><strong>"security"</strong></a> parameter is set to
<strong>"domain"</strong>, then the list of machines in this option must be a list
of Primary or Backup Domain controllers for the
-<a href="smb.conf.5.html#workgroup"><strong>Domain</strong></a> or the character <code>*</code>, as the Samba server is cryptographicly
+<a href="smb.conf.5.html#workgroup"><strong>Domain</strong></a>, as the Samba server is cryptographicly
in that domain, and will use cryptographicly authenticated RPC calls
to authenticate the user logging on. The advantage of using
<a href="smb.conf.5.html#securityequaldomain"><strong>"security=domain"</strong></a> is that if you list
several hosts in the <strong>"password server"</strong> option then
<a href="smbd.8.html"><strong>smbd</strong></a> will try each in turn till it finds one
that responds. This is useful in case your primary server goes down.
-<p><br>If the <strong>"password server"</strong> option is set to the character <code>*</code>,
-then Samba will attempt to auto-locate the Primary or Backup Domain controllers
-to authenticate against by doing a query for the name <code>WORKGROUP&lt;1C&gt;</code>
-and then contacting each server returned in the list of IP addresses
-from the <a href="smb.conf.5.html#nameresolveorder"><strong>name resolution</strong></a> source.
<p><br>If the <a href="smb.conf.5.html#security"><strong>"security"</strong></a> parameter is set to
<a href="smb.conf.5.html#securityequalserver"><strong>"server"</strong></a>, then there are different
restrictions that <a href="smb.conf.5.html#securityequaldomain"><strong>"security=domain"</strong></a>
@@ -3183,8 +2989,6 @@ workstation.
<code> password server = &lt;empty string&gt;</code>
<p><br><strong>Example:</strong>
<code> password server = NT-PDC, NT-BDC1, NT-BDC2</code>
-<p><br><strong>Example:</strong>
-<code> password server = *</code>
<p><br><a name="path"></a>
<li><strong><strong>path (S)</strong></strong>
<p><br>This parameter specifies a directory to which the user of the service
@@ -3243,19 +3047,11 @@ time they log in. Maybe a message of the day? Here is an example:
</pre>
<p><br>Of course, this could get annoying after a while :-)
-<p><br>See also <a href="smb.conf.5.html#preexecclose"><strong>preexec close</strong></a> and <a href="smb.conf.5.html#postexec"><strong>postexec</strong></a>.
+<p><br>See also <a href="smb.conf.5.html#postexec"><strong>postexec</strong></a>.
<p><br><strong>Default:</strong>
<code> none (no command executed)</code>
<p><br><strong>Example:</strong>
<code> preexec = echo \"%u connected to %S from %m (%I)\" &gt;&gt; /tmp/log</code>
-<p><br><a name="preexecclose"></a>
-<li><strong><strong>preexec close (S)</strong></strong>
-<p><br>This boolean option controls whether a non-zero return code from
-<a href="smb.conf.5.html#preexec"><strong>"preexec"</strong></a> should close the service being connected to.
-<p><br><strong>Default:</strong>
-<code> preexec close = no</code>
-<p><br><strong>Example:</strong>
-<code> preexec close = yes</code>
<p><br><a name="preferredmaster"></a>
<li><strong><strong>preferred master (G)</strong></strong>
<p><br>This boolean parameter controls if <a href="nmbd.8.html"><strong>nmbd</strong></a> is a
@@ -3265,7 +3061,8 @@ force an election, and it will have a slight advantage in winning the
election. It is recommended that this parameter is used in
conjunction with <a href="smb.conf.5.html#domainmaster"><strong>"domain master = yes"</strong></a>, so
that <a href="nmbd.8.html"><strong>nmbd</strong></a> can guarantee becoming a domain
-master.
+master. Indeed the default ("auto") enables "preferred master" if
+Samba is configured as the domain master browser.
<p><br>Use this option with caution, because if there are several hosts
(whether Samba servers, Windows 95 or NT) that are preferred master
browsers on the same subnet, they will each periodically and
@@ -3274,7 +3071,7 @@ result in unnecessary broadcast traffic and reduced browsing
capabilities.
<p><br>See also <a href="smb.conf.5.html#oslevel"><strong>os level</strong></a>.
<p><br><strong>Default:</strong>
-<code> preferred master = no</code>
+<code> preferred master = auto</code>
<p><br><strong>Example:</strong>
<code> preferred master = yes</code>
<p><br><a name="preferedmaster"></a>
@@ -3442,7 +3239,7 @@ in the docs/ directory, PRINTER_DRIVER.txt.
find the printer driver files for the automatic installation of
drivers for Windows 95 machines. If Samba is set up to serve printer
drivers to Windows 95 machines, this should be set to
-<p><br><code>\\MACHINE\aPRINTER$</code>
+<p><br><code>\\MACHINE\PRINTER$</code>
<p><br>Where MACHINE is the NetBIOS name of your Samba server, and PRINTER$
is a share you set up for serving printer driver files. For more
details on setting this up see the documentation file in the docs/
@@ -3594,13 +3391,13 @@ all the data has been read from disk.
<p><br>This overlapping works best when the speeds of disk and network access
are similar, having very little effect when the speed of one is much
greater than the other.
-<p><br>The default value is 16384, but very little experimentation has been
+<p><br>The default value is 2048, but very little experimentation has been
done yet to determine the optimal value, and it is likely that the
best value will vary greatly between systems anyway. A value over
65536 is pointless and will cause you to allocate memory
unnecessarily.
<p><br><strong>Default:</strong>
-<code> read size = 16384</code>
+<code> read size = 2048</code>
<p><br><strong>Example:</strong>
<code> read size = 8192</code>
<p><br><a name="remoteannounce"></a>
@@ -3653,32 +3450,6 @@ master on it's segment.
<code> remote browse sync = &lt;empty string&gt;</code>
<p><br><strong>Example:</strong>
<code> remote browse sync = 192.168.2.255 192.168.4.255</code>
-<p><br><a name="restrictanonymous"></a>
-<li><strong><strong>restrict anonymous (G)</strong></strong>
-<p><br>This is a boolean parameter. If it is true, then anonymous access
-to the server will be restricted, namely in the case where the server
-is expecting the client to send a username, but it doesn't. Setting
-it to true will force these anonymous connections to be denied, and
-the client will be required to always supply a username and password
-when connecting. Use of this parameter is only recommened for homogenous
-NT client environments.
-<p><br>This parameter makes the use of macro expansions that rely
-on the username (%U, %G, etc) consistant. NT 4.0 likes to use
-anonymous connections when refreshing the share list, and this
-is a way to work around that.
-<p><br>When restrict anonymous is true, all anonymous connections are denied
-no matter what they are for. This can effect the ability of a machine
-to access the samba Primary Domain Controller to revalidate it's machine
-account after someone else has logged on the client interactively. The
-NT client will display a message saying that the machine's account in
-the domain doesn't exist or the password is bad. The best way to deal
-with this is to reboot NT client machines between interactive logons,
-using "Shutdown and Restart", rather than "Close all programs and logon
-as a different user".
-<p><br><strong>Default:</strong>
-<code> restrict anonymous = false</code>
-<p><br><strong>Example:</strong>
-<code> restrict anonymous = true</code>
<p><br><a name="revalidate"></a>
<li><strong><strong>revalidate (S)</strong></strong>
<p><br>Note that this option only works with
@@ -3735,13 +3506,7 @@ filesystems (such as cdroms) after a connection is closed.
<p><br>This is the same as the <a href="smb.conf.5.html#preexec"><strong>"preexec"</strong></a> parameter except
that the command is run as root. This is useful for mounting
filesystems (such as cdroms) before a connection is finalized.
-<p><br>See also <a href="smb.conf.5.html#preexec"><strong>"preexec"</strong></a>
-and <a href="smb.conf.5.html#rootpreexecclose"><strong>"root preexec close"</strong></a>.
-<p><br><a name="rootpreexecclose"></a>
-<li><strong><strong>root preexec close (S)</strong></strong>
-<p><br>This is the same as the <a href="smb.conf.5.html#preexecclose"><strong>"preexec close"</strong></a> parameter
-except that the command is run as root.
-<p><br>See also <a href="smb.conf.5.html#preexec"><strong>"preexec"</strong></a>, <a href="smb.conf.5.html#preexecclose"><strong>"preexec close"</strong></a>.
+<p><br>See also <a href="smb.conf.5.html#preexec"><strong>"preexec"</strong></a>.
<p><br><a name="security"></a>
<li><strong><strong>security (G)</strong></strong>
<p><br>This option affects how clients respond to Samba and is one of the most
@@ -3897,7 +3662,7 @@ level security without allowing the server to automatically map unknown
users into the <a href="smb.conf.5.html#guestaccount"><strong>"guest account"</strong></a>. See the
<a href="smb.conf.5.html#maptoguest"><strong>"map to guest"</strong></a> parameter for details on
doing this.
-<p><br><em>BUG:</em> There is currently a bug in the implementation of
+<p><br>e,(BUG:) There is currently a bug in the implementation of
<strong>"security=domain</strong> with respect to multi-byte character
set usernames. The communication with a Domain Controller
must be done in UNICODE and Samba currently does not widen
@@ -3913,31 +3678,6 @@ and the <a href="smb.conf.5.html#encryptpasswords"><strong>"encrypted passwords"
<code> security = USER</code>
<p><br><strong>Example:</strong>
<code> security = DOMAIN</code>
-<p><br><a name="securitymask"></a>
-<li><strong><strong>security mask (S)</strong></strong>
-<p><br>This parameter controls what UNIX permission bits can be modified
-when a Windows NT client is manipulating the UNIX permission on a
-file using the native NT security dialog box.
-<p><br>This parameter is applied as a mask (AND'ed with) to the changed
-permission bits, thus preventing any bits not in this mask from
-being modified. Essentially, zero bits in this mask may be treated
-as a set of bits the user is not allowed to change.
-<p><br>If not set explicitly this parameter is set to the same value as the
-<a href="smb.conf.5.html#createmask"><strong>create mask</strong></a> parameter. To allow a user to
-modify all the user/group/world permissions on a file, set this
-parameter to 0777.
-<p><br><em>Note</em> that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems. Administrators of
-most normal systems will probably want to set it to 0777.
-<p><br>See also the <a href="smb.conf.5.html#forcedirectorysecuritymode"><strong>force directory security
-mode</strong></a>, <a href="smb.conf.5.html#directorysecuritymask"><strong>directory security
-mask</strong></a>, <a href="smb.conf.5.html#forcesecuritymode"><strong>force security
-mode</strong></a> parameters.
-<p><br><strong>Default:</strong>
-<code> security mask = &lt;same as create mask&gt;</code>
-<p><br><strong>Example:</strong>
-<code> security mask = 0777</code>
<p><br><a name="serverstring"></a>
<li><strong><strong>server string (G)</strong></strong>
<p><br>This controls what string will show up in the printer comment box in
@@ -3986,14 +3726,12 @@ increase this parameter. Signs that this parameter is set too low are
users reporting strange problems trying to save files (locking errors)
and error messages in the smbd log looking like <code>"ERROR
smb_shm_alloc : alloc of XX bytes failed"</code>.
-<p><br>If your OS refuses the size that Samba asks for then Samba will try a
-smaller size, reducing by a factor of 0.8 until the OS accepts it.
<p><br><strong>Default:</strong>
<code> shared mem size = 1048576</code>
<p><br><strong>Example:</strong>
<code> shared mem size = 5242880 ; Set to 5mb for a large number of files.</code>
<p><br><a name="shortpreservecase"></a>
-<li><strong><strong>short preserve case (G)</strong></strong>
+<li><strong><strong>short preserve case (S)</strong></strong>
<p><br>This boolean parameter controls if new files which conform to 8.3
syntax, that is all in upper case and of suitable length, are created
upper case, or if they are forced to be the <code>"default"</code> case. This
@@ -4362,11 +4100,9 @@ set to <code>"yes"</code> in order for this parameter to have any affect.
<p><br>This parameter maps how Samba debug messages are logged onto the
system syslog logging levels. Samba debug level zero maps onto syslog
LOG_ERR, debug level one maps onto LOG_WARNING, debug level two maps
-onto LOG_NOTICE, debug level three maps onto LOG_INFO. All higher
-levels are mapped to LOG_DEBUG.
-<p><br>This paramter sets the threshold for sending messages to syslog.
-Only messages with debug level less than this value will be sent
-to syslog.
+to LOG_NOTICE, debug level three maps onto LOG_INFO. The parameter
+sets the threshold for doing the mapping, all Samba debug messages
+above this threshold are mapped to syslog LOG_DEBUG messages.
<p><br><strong>Default:</strong>
<code> syslog = 1</code>
<p><br><a name="syslogonly"></a>
@@ -4547,6 +4283,15 @@ purposes. The most common is to map usernames that users use on DOS or
Windows machines to those that the UNIX box uses. The other is to map
multiple users to a single username so that they can more easily share
files.
+<p><br>The use of this option, therefore, relates to UNIX usernames
+and not Windows (specifically NT Domain) usernames. In other words,
+once a name has been mapped using this option, the Samba server uses
+the mapped name for internal <em>AND</em> external purposes.
+<p><br>This option is <em>DIFFERENT</em> from the <a href="smb.conf.5.html#domainusermap"><strong>"domain user map"</strong></a>
+parameter, which maintains a one-to-one mapping between UNIX usernames
+and NT Domain Usernames: more specifically, the Samba server maintains
+a link between <em>BOTH</em> usernames, presenting the NT username to the
+external NT world, and using the UNIX username internally.
<p><br>The map file is parsed line by line. Each line should contain a single
UNIX username on the left then a <code>'='</code> followed by a list of
usernames on the right. The list of usernames on the right may contain
@@ -4748,9 +4493,6 @@ may be followed by the server. Links that point to areas within the
directory tree exported by the server are always allowed; this
parameter controls access only to areas that are outside the directory
tree being exported.
-<p><br>Note that setting this parameter can have a negative effect on your
-server performance due to the extra system calls that Samba has to
-do in order to perform the link checks.
<p><br><strong>Default:</strong>
<code> wide links = yes</code>
<p><br><strong>Example:</strong>
@@ -4767,7 +4509,7 @@ need to set this to <code>"yes"</code> for some older clients.
<p><br>This specifies the IP address (or DNS name: IP address for preference)
of the WINS server that <a href="nmbd.8.html"><strong>nmbd</strong></a> should register with.
If you have a WINS server on your network then you should set this to
-the WINS server's IP.
+the WINS server's IP.
<p><br>You should point this at your WINS server if you have a
multi-subnetted network.
<p><br><em>NOTE</em>. You need to set up Samba to point to a WINS server if you
@@ -4778,32 +4520,6 @@ Samba source distribution.
<code> wins server = </code>
<p><br><strong>Example:</strong>
<code> wins server = 192.9.200.1</code>
-<p><br><a name="winshook"></a>
-<li><strong><strong>wins hook (G)</strong></strong>
-<p><br>When Samba is running as a WINS server this allows you to call an
-external program for all changes to the WINS database. The primary use
-for this option is to allow the dynamic update of external name
-resolution databases such as dynamic DNS.
-<p><br>The wins hook parameter specifies the name of a script or executable
-that will be called as follows:
-<p><br>wins_hook operation name nametype ttl IP_list
-<p><br>The first argument is the operation and is one of "add", "delete",
-or "refresh". In most cases the operation can be ignored as the rest
-of the parameters provide sufficient information. Note that "refresh"
-may sometimes be called when the name has not previously been added,
-in that case it should be treated as an add.
-<p><br>The second argument is the netbios name. If the name is not a legal
-name then the wins hook is not called. Legal names contain only
-letters, digits, hyphens, underscores and periods.
-<p><br>The third argument is the netbios name type as a 2 digit hexadecimal
-number.
-<p><br>The fourth argument is the TTL (time to live) for the name in seconds.
-<p><br>The fifth and subsequent arguments are the IP addresses currently
-registered for that name. If this list is empty then the name should
-be deleted.
-<p><br>An example script that calls the BIND dynamic DNS update program
-"nsupdate" is provided in the examples directory of the Samba source
-code.
<p><br><a name="winssupport"></a>
<li><strong><strong>wins support (G)</strong></strong>
<p><br>This boolean controls if the <a href="nmbd.8.html"><strong>nmbd</strong></a> process in
@@ -4827,6 +4543,7 @@ setting.
<p><br><a name="writable"></a>
<li><strong><strong>writable (S)</strong></strong>
<p><br>Synonym for <a href="smb.conf.5.html#writeable"><strong>"writeable"</strong></a> for people who can't spell :-).
+Pronounced "ritter-bull".
<p><br><a name="writelist"></a>
<li><strong><strong>write list (S)</strong></strong>
<p><br>This is a list of users that are given read-write access to a
@@ -4870,7 +4587,6 @@ permitting), but only via spooling operations.
</pre>
-<p><br></ul>
<p><br><a name="WARNINGS"></a>
<h2>WARNINGS</h2>
diff --git a/docs/htmldocs/smbclient.1.html b/docs/htmldocs/smbclient.1.html
index a68538aa155..45823a56f9c 100644
--- a/docs/htmldocs/smbclient.1.html
+++ b/docs/htmldocs/smbclient.1.html
@@ -24,7 +24,7 @@
<p><br><a name="SYNOPSIS"></a>
<h2>SYNOPSIS</h2>
-<p><br><strong>smbclient</strong> <a href="smbclient.1.html#servicename">servicename</a> [<a href="smbclient.1.html#minuss">-s smb.conf</a>] [<a href="smbclient.1.html#minusO">-O socket options</a>][<a href="smbclient.1.html#minusR">-R name resolve order</a>] [<a href="smbclient.1.html#minusM">-M NetBIOS name</a>] [<a href="smbclient.1.html#minusi">-i scope</a>] [<a href="smbclient.1.html#minusN">-N</a>] [<a href="smbclient.1.html#minusn">-n NetBIOS name</a>] [<a href="smbclient.1.html#minusd">-d debuglevel</a>] [<a href="smbclient.1.html#minusP">-P</a>] [<a href="smbclient.1.html#minusp">-p port</a>] [<a href="smbclient.1.html#minusl">-l log basename</a>] [<a href="smbclient.1.html#minush">-h</a>] [<a href="smbclient.1.html#minusI">-I dest IP</a>] [<a href="smbclient.1.html#minusE">-E</a>] [<a href="smbclient.1.html#minusU">-U username</a>] [<a href="smbclient.1.html#minusL">-L NetBIOS name</a>] [<a href="smbclient.1.html#minust">-t terminal code</a>] [<a href="smbclient.1.html#minusm">-m max protocol</a>] [<a href="smbclient.1.html#minusb">-b buffersize</a>] [<a href="smbclient.1.html#minusW">-W workgroup</a>] [<a href="smbclient.1.html#minusT">-T&lt;c|x&gt;IXFqgbNan</a>] [<a href="smbclient.1.html#minusD">-D directory</a>] [<a href="smbclient.1.html#minusc">-c command string</a>]
+<p><br><strong>smbclient</strong> <a href="smbclient.1.html#servicename">servicename</a> [<a href="smbclient.1.html#password">password</a>] [<a href="smbclient.1.html#minuss">-s smb.conf</a>] [<a href="smbclient.1.html#minusB">-B IP addr</a>] [<a href="smbclient.1.html#minusO">-O socket options</a>][<a href="smbclient.1.html#minusR">-R name resolve order</a>] [<a href="smbclient.1.html#minusM">-M NetBIOS name</a>] [<a href="smbclient.1.html#minusi">-i scope</a>] [<a href="smbclient.1.html#minusN">-N</a>] [<a href="smbclient.1.html#minusn">-n NetBIOS name</a>] [<a href="smbclient.1.html#minusd">-d debuglevel</a>] [<a href="smbclient.1.html#minusP">-P</a>] [<a href="smbclient.1.html#minusp">-p port</a>] [<a href="smbclient.1.html#minusl">-l log basename</a>] [<a href="smbclient.1.html#minush">-h</a>] [<a href="smbclient.1.html#minusI">-I dest IP</a>] [<a href="smbclient.1.html#minusE">-E</a>] [<a href="smbclient.1.html#minusU">-U username</a>] [<a href="smbclient.1.html#minusL">-L NetBIOS name</a>] [<a href="smbclient.1.html#minust">-t terminal code</a>] [<a href="smbclient.1.html#minusm">-m max protocol</a>] [<a href="smbclient.1.html#minusW">-W workgroup</a>] [<a href="smbclient.1.html#minusT">-T&lt;c|x&gt;IXFqgbNan</a>] [<a href="smbclient.1.html#minusD">-D directory</a>] [<a href="smbclient.1.html#minusc">-c command string</a>]
<p><br><a name="DESCRIPTION"></a>
<h2>DESCRIPTION</h2>
@@ -74,6 +74,8 @@ rejected by these servers.
Samba configuration file, smb.conf. This file controls all aspects of
the Samba setup on the machine and smbclient also needs to read this
file.
+<p><br><a name="minusB"></a>
+<li><strong><strong>-B IP addr</strong></strong> The IP address to use when sending a broadcast packet.
<p><br><a name="minusO"></a>
<li><strong><strong>-O socket options</strong></strong> TCP socket options to set on the client
socket. See the <a href="smb.conf.5.html#socketoptions">socket options</a>
@@ -100,7 +102,8 @@ no WINS server has been specified this method will be ignored.
listed in the <a href="smb.conf.5.html#interfaces"><strong>interfaces</strong></a> parameter
in the smb.conf file. This is the least reliable of the name resolution
methods as it depends on the target host being on a locally connected
-subnet.
+subnet. To specify a particular broadcast address the <a href="smbclient.1.html#minusB"><strong>-B</strong></a> option
+may be used.
<p><br></ul>
<p><br>If this parameter is not set then the name resolve order defined
in the <a href="smb.conf.5.html"><strong>smb.conf</strong></a> file parameter
@@ -235,7 +238,7 @@ then the password as part of username will take precedence. Putting
nothing before or nothing after the percent symbol will cause an empty
username or an empty password to be used, respectively.
<p><br>The password may also be specified by setting up an environment
-variable called <code>PASSWD</code> that contains the users password. Note
+variable called <code>PASSWORD</code> that contains the users password. Note
that this may be very insecure on some systems but on others allows
users to script smbclient commands without having a password appear in
the command line of a process listing.
@@ -243,7 +246,7 @@ the command line of a process listing.
on an uppercase password. Lowercase or mixed case passwords may be
rejected by these servers.
<p><br>Be cautious about including passwords in scripts or in the
-<code>PASSWD</code> environment variable. Also, on many systems the command
+<code>PASSWORD</code> environment variable. Also, on many systems the command
line of a running process may be seen via the <code>ps</code> command to be
safe always allow smbclient to prompt for a password and type it in
directly.
@@ -270,11 +273,6 @@ Samba source code for the complete list.
protocols level the server supports. This parameter is
preserved for backwards compatibility, but any string
following the <strong>-m</strong> will be ignored.
-<p><br><a name="minusb"></a>
-<li><strong><strong>-b buffersize</strong></strong> This option changes the transmit/send buffer
-size when getting or putting a file from/to the server. The default
-is 65520 bytes. Setting this value smaller (to 1200 bytes) has been
-observed to speed up file transfers to and from a Win9x server.
<p><br><a name="minusW"></a>
<li><strong><strong>-W WORKGROUP</strong></strong> Override the default workgroup specified in the
<a href="smb.conf.5.html#workgroup"><strong>workgroup</strong></a> parameter of the
@@ -537,7 +535,7 @@ LANMAN2 protocol or above.
<p><br>The variable <strong>USER</strong> may contain the username of the person using the
client. This information is used only if the protocol level is high
enough to support session-level passwords.
-<p><br>The variable <strong>PASSWD</strong> may contain the password of the person using
+<p><br>The variable <strong>PASSWORD</strong> may contain the password of the person using
the client. This information is used only if the protocol level is
high enough to support session-level passwords.
<p><br><a name="INSTALLATION"></a>
diff --git a/docs/htmldocs/smbd.8.html b/docs/htmldocs/smbd.8.html
index 8230d50f47b..790c4063940 100644
--- a/docs/htmldocs/smbd.8.html
+++ b/docs/htmldocs/smbd.8.html
@@ -24,7 +24,7 @@
<p><br><a name="SYNOPSIS"></a>
<h2>SYNOPSIS</h2>
-<p><br><strong>smbd</strong> [<a href="smbd.8.html#minusD">-D</a>] [<a href="smbd.8.html#minusa">-a</a>] [<a href="smbd.8.html#minuso">-o</a>] [<a href="smbd.8.html#minusP">-P</a>] [<a href="smbd.8.html#minush">-h</a>] [<a href="smbd.8.html#minusV">-V</a>] [<a href="smbd.8.html#minusd">-d debuglevel</a>] [<a href="smbd.8.html#minusl">-l log file</a>] [<a href="smbd.8.html#minusp">-p port number</a>] [<a href="smbd.8.html#minusO">-O socket options</a>] [<a href="smbd.8.html#minuss">-s configuration file</a>] [<a href="smbd.8.html#minusi">-i scope</a>]
+<p><br><strong>smbd</strong> [<a href="smbd.8.html#minusD">-D</a>] [<a href="smbd.8.html#minusa">-a</a>] [<a href="smbd.8.html#minuso">-o</a>] [<a href="smbd.8.html#minusd">-d debuglevel</a>] [<a href="smbd.8.html#minusl">-l log file</a>] [<a href="smbd.8.html#minusp">-p port number</a>] [<a href="smbd.8.html#minusO">-O socket options</a>] [<a href="smbd.8.html#minuss">-s configuration file</a>] [<a href="smbd.8.html#minusi">-i scope</a>] [<a href="smbd.8.html#minusP">-P</a>] [<a href="smbd.8.html#minush">-h</a>]
<p><br><a name="DESCRIPTION"></a>
<h2>DESCRIPTION</h2>
@@ -75,13 +75,6 @@ append log messages to the log file. This is the default.
<li><strong><strong>-o</strong></strong> If this parameter is specified, the log files will be
overwritten when opened. By default, the log files will be appended
to.
-<p><br><a name="minusP"></a>
-<li><strong><strong>-P</strong></strong> Passive option. Causes smbd not to send any network traffic
-out. Used for debugging by the developers only.
-<p><br><a name="minush"></a>
-<li><strong><strong>-h</strong></strong> Prints the help information (usage) for <strong>smbd</strong>.
-<p><br><a name="minusV"></a>
-<li><strong><strong>-V</strong></strong> Prints the version number for <strong>smbd</strong>.
<p><br><a name="minusd"></a>
<li><strong><strong>-d debuglevel</strong></strong> debuglevel is an integer from 0 to 10.
<p><br>The default value if this parameter is not specified is zero.
@@ -140,6 +133,11 @@ use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
are <em>very</em> rarely used, only set this parameter if you are the
system administrator in charge of all the NetBIOS systems you
communicate with.
+<p><br><a name="minush"></a>
+<li><strong><strong>-h</strong></strong> Prints the help information (usage) for smbd.
+<p><br><a name="minusP"></a>
+<li><strong><strong>-P</strong></strong> Passive option. Causes smbd not to send any network traffic
+out. Used for debugging by the developers only.
<p><br></ul>
<p><br><a name="FILES"></a>
<h2>FILES</h2>
@@ -359,11 +357,16 @@ performance.
<p><br><a name="SEEALSO"></a>
<h2>SEE ALSO</h2>
-<p><br><strong>hosts_access (5)</strong>, <strong>inetd (8)</strong>, <a href="nmbd.8.html"><strong>nmbd (8)</strong></a>,
-<a href="smb.conf.5.html"><strong>smb.conf (5)</strong></a>, <a href="smbclient.1.html"><strong>smbclient
-(1)</strong></a>, <a href="testparm.1.html"><strong>testparm (1)</strong></a>,
-<a href="testprns.1.html"><strong>testprns (1)</strong></a>, and the Internet RFC's
-<strong>rfc1001.txt</strong>, <strong>rfc1002.txt</strong>. In addition the CIFS (formerly SMB)
+<p><br><strong>hosts_access (5)</strong>,
+<strong>inetd (8)</strong>,
+<a href="nmbd.8.html"><strong>nmbd (8)</strong></a>,
+<a href="smb.conf.5.html"><strong>smb.conf (5)</strong></a>,
+<a href="smbclient.1.html"><strong>smbclient (1)</strong></a>,
+<a href="testparm.1.html"><strong>testparm (1)</strong></a>,
+<a href="testprns.1.html"><strong>testprns (1)</strong></a>,
+<a href="rpcclient.1.html"><strong>rpcclient (1)</strong></a>,
+and the Internet RFC's <strong>rfc1001.txt</strong>, <strong>rfc1002.txt</strong>.
+In addition the CIFS (formerly SMB)
specification is available as a link from the Web page :
<a href="http://samba.org/cifs/">http://samba.org/cifs/</a>.
<p><br><a name="AUTHOR"></a>
diff --git a/docs/htmldocs/smbstatus.1.html b/docs/htmldocs/smbstatus.1.html
index 1cc65e81587..4a854a5c4d9 100644
--- a/docs/htmldocs/smbstatus.1.html
+++ b/docs/htmldocs/smbstatus.1.html
@@ -36,7 +36,7 @@ connections.
<p><br><ul>
<p><br><a name="minusP"></a>
-<li><strong><strong>-P</strong></strong> If samba has been compiled with the profiling option,
+<li><strong><strong>-P</strong></strong> If samba has been compiled with the profiling option,
print only the contents of the profiling shared memory area.
<p><br><a name="minusb"></a>
<li><strong><strong>-b</strong></strong> gives brief output.
diff --git a/docs/htmldocs/swat.8.html b/docs/htmldocs/swat.8.html
index 3a29f17ab5e..0d43dd494bf 100644
--- a/docs/htmldocs/swat.8.html
+++ b/docs/htmldocs/swat.8.html
@@ -20,7 +20,7 @@
<p><br><a name="NAME"></a>
<h2>NAME</h2>
- swat - Samba Web Administration Tool
+ swat - swat - Samba Web Administration Tool
<p><br><a name="SYNOPSIS"></a>
<h2>SYNOPSIS</h2>
diff --git a/docs/htmldocs/testparm.1.html b/docs/htmldocs/testparm.1.html
index 1e0396af337..00db2316266 100644
--- a/docs/htmldocs/testparm.1.html
+++ b/docs/htmldocs/testparm.1.html
@@ -24,7 +24,7 @@
<p><br><a name="SYNOPSIS"></a>
<h2>SYNOPSIS</h2>
-<p><br><strong>testparm</strong> [<a href="testparm.1.html#minuss">-s</a>] [<a href="testparm.1.html#minush">-h</a>] [<a href="testparm.1.html#minusL">-L servername</a>] [<a href="testparm.1.html#configfilename">configfilename</a>] [<a href="testparm.1.html#hostname">hostname</a> <a href="testparm.1.html#hostIP">hostIP</a>]
+<p><br><strong>testparm</strong> [<a href="testparm.1.html#minuss">-s</a>] [<a href="testparm.1.html#configfilename">configfilename</a>] [<a href="testparm.1.html#hostname">hostname</a> <a href="testparm.1.html#hostIP">hostIP</a>]
<p><br><a name="DESCRIPTION"></a>
<h2>DESCRIPTION</h2>
@@ -39,10 +39,6 @@ configuration file will be available or will operate as expected.
<p><br>If the optional host name and host IP address are specified on the
command line, this test program will run through the service entries
reporting whether the specified host has access to each service.
-<p><br>If <strong>testparm</strong> finds an error in the <a href="smb.conf.5.html"><strong>smb.conf</strong></a>
-file it returns an exit code of 1 to the calling program, else it returns
-an exit code of 0. This allows shell scripts to test the output from
-<strong>testparm</strong>.
<p><br><a name="OPTIONS"></a>
<h2>OPTIONS</h2>
@@ -51,11 +47,6 @@ an exit code of 0. This allows shell scripts to test the output from
<li><strong><strong>-s</strong></strong> Without this option, <strong>testparm</strong> will prompt for a
carriage return after printing the service names and before dumping
the service definitions.
-<p><br><a name="minush"></a>
-<li><strong><strong>-h</strong></strong> Print usage message
-<p><br><a name="minusL"></a>
-<li><strong><strong>-L servername</strong></strong> Sets the value of the %L macro to servername. This
-is useful for testing include files specified with the %L macro.
<p><br><a name="configfilename"></a>
<li><strong><strong>configfilename</strong></strong> This is the name of the configuration file to
check. If this parameter is not present then the default
diff --git a/docs/manpages/debug2html.1 b/docs/manpages/debug2html.1
new file mode 100644
index 00000000000..64b4b1d97ad
--- /dev/null
+++ b/docs/manpages/debug2html.1
@@ -0,0 +1,54 @@
+.TH DEBUG2HTML 1 "24 Feb 2000" "debug2html TNG-prealpha"
+.PP
+.SH "NAME"
+debug2html \- Samba DEBUG to HTML translation filter
+.PP
+.SH "SYNOPSIS"
+.PP
+debug2html [input-file [output-file]]
+.PP
+.SH "DESCRIPTION"
+.PP
+This program is part of the \fBSamba\fP suite\&.
+.PP
+\fBdebug2html\fP generates HTML files from Samba log files\&. Log files
+produced by \fBnmbd\fP(8) or \fBsmbd\fP(8) may then be viewed by a web
+browser\&. The output conforms to the HTML 3\&.2 specification\&.
+.PP
+The filenames specified on the command line are optional\&. If the
+output-file is ommitted, output will go to \fBstdout\fP\&. If the input-file
+is ommitted, \fBdebug2html\fP will read from \fBstdin\fP\&. The filename "-"
+can be used to indicate that input should be read from \fBstdin\fP\&. For
+example:
+.PP
+\f(CWcat /usr/local/samba/var/log\&.nmb | debug2html - nmblog\&.html\fP
+.br
+.PP
+.SH "VERSION"
+.PP
+This man page is correct for version 2\&.0 of the Samba suite\&.
+.PP
+.SH "SEE ALSO"
+.PP
+\fBnmbd\fP(8), \fBsmbd\fP(8),
+\fBsamba\fP(7)\&.
+.PP
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities were created by
+Andrew Tridgell \fIsamba-bugs@samba\&.org\fP\&. Samba is now developed
+by the Samba Team as an Open Source project similar to the way the
+Linux kernel is developed\&.
+.PP
+The original Samba man pages were written by Karl Auer\&. The man page
+sources were converted to YODL format (another excellent piece of Open
+Source software, available at
+\fBftp://ftp\&.icce\&.rug\&.nl/pub/unix/\fP)
+and updated for the Samba2\&.0 release by Jeremy Allison\&.
+\fIsamba-bugs@samba\&.org\fP\&.
+.PP
+\fBdebug2html\fP was added by Chris Hertel\&.
+.PP
+See \fBsamba\fP(7) to find out how to get a full
+list of contributors and details on how to submit bug reports,
+comments etc\&.
diff --git a/docs/manpages/lmhosts.5 b/docs/manpages/lmhosts.5
index 534c2484150..ec712a22dab 100644
--- a/docs/manpages/lmhosts.5
+++ b/docs/manpages/lmhosts.5
@@ -1,4 +1,4 @@
-.TH "lmhosts " "5" "23 Oct 1998" "Samba" "SAMBA"
+.TH LMHOSTS 5 "24 Feb 2000" "lmhosts TNG-prealpha"
.PP
.SH "NAME"
lmhosts \- The Samba NetBIOS hosts file
diff --git a/docs/manpages/make_smbcodepage.1 b/docs/manpages/make_smbcodepage.1
index 9c134201078..8c00e8cd030 100644
--- a/docs/manpages/make_smbcodepage.1
+++ b/docs/manpages/make_smbcodepage.1
@@ -1,4 +1,4 @@
-.TH "make_smbcodepage " "1" "23 Oct 1998" "Samba" "SAMBA"
+.TH MAKE_SMBCODEPAGE 1 "24 Feb 2000" "make_smbcodepage TNG-prealpha"
.PP
.SH "NAME"
make_codepage \- Construct a codepage file for Samba
diff --git a/docs/manpages/nmbd.8 b/docs/manpages/nmbd.8
index 72aeaf14a77..aec808d1325 100644
--- a/docs/manpages/nmbd.8
+++ b/docs/manpages/nmbd.8
@@ -1,4 +1,4 @@
-.TH "nmbd" "8" "23 Oct 1998" "Samba" "SAMBA"
+.TH NMBD 8 "24 Feb 2000" "nmbd TNG-prealpha"
.PP
.SH "NAME"
nmbd \- NetBIOS name server to provide NetBIOS over IP
@@ -6,7 +6,7 @@ naming services to clients
.PP
.SH "SYNOPSIS"
.PP
-\fBnmbd\fP [-D] [-a] [-o] [-h] [-V] [-H lmhosts file] [-d debuglevel] [-l log file basename] [-n primary NetBIOS name] [-p port number] [-s configuration file] [-i NetBIOS scope]
+\fBnmbd\fP [-D] [-o] [-a] [-H lmhosts file] [-d debuglevel] [-l log file basename] [-n primary NetBIOS name] [-p port number] [-s configuration file] [-i NetBIOS scope] [-h]
.PP
.SH "DESCRIPTION"
.PP
@@ -59,12 +59,6 @@ If this parameter is specified, the log files will be
overwritten when opened\&. By default, the log files will be appended
to\&.
.IP
-.IP "\fB-h\fP"
-Prints the help information (usage) for \fBnmbd\fP\&.
-.IP
-.IP "\fB-V\fP"
-Prints the version number for \fBnmbd\fP\&.
-.IP
.IP "\fB-H filename\fP"
NetBIOS lmhosts file\&.
.IP
@@ -144,6 +138,9 @@ are \fIvery\fP rarely used, only set this parameter if you are the
system administrator in charge of all the NetBIOS systems you
communicate with\&.
.IP
+.IP "\fB-h\fP"
+Prints the help information (usage) for \fBnmbd\fP\&.
+.IP
.PP
.SH "FILES"
.PP
diff --git a/docs/manpages/nmblookup.1 b/docs/manpages/nmblookup.1
index a542e6d5074..0588fb578fb 100644
--- a/docs/manpages/nmblookup.1
+++ b/docs/manpages/nmblookup.1
@@ -1,11 +1,11 @@
-.TH "nmblookup " "1" "23 Oct 1998" "Samba" "SAMBA"
+.TH NMBLOOKUP 1 "24 Feb 2000" "nmblookup TNG-prealpha"
.PP
.SH "NAME"
nmblookup \- NetBIOS over TCP/IP client used to lookup NetBIOS names
.PP
.SH "SYNOPSIS"
.PP
-\fBnmblookup\fP [-M] [-R] [-S] [-r] [-A] [-h] [-B broadcast address] [-U unicast address] [-d debuglevel] [-s smb config file] [-i NetBIOS scope] [-T] name
+\fBnmblookup\fP [-M] [-R] [-S] [-r] [-A] [-h] [-B broadcast address] [-U unicast address] [-d debuglevel] [-s smb config file] [-i NetBIOS scope] name
.PP
.SH "DESCRIPTION"
.PP
@@ -20,9 +20,8 @@ or to a particular machine\&. All queries are done over UDP\&.
.PP
.IP
.IP "\fB-M\fP"
-Searches for a master browser by looking up the
-NetBIOS name \fBname\fP with a type of 0x1d\&. If \fBname\fP
-is \f(CW"-"\fP then it does a lookup on the special name \f(CW__MSBROWSE__\fP\&.
+Searches for a master browser\&. This is done by doing a
+broadcast lookup on the special name \f(CW__MSBROWSE__\fP\&.
.IP
.IP "\fB-R\fP"
Set the recursion desired bit in the packet to do a
@@ -56,8 +55,8 @@ Print a help (usage) message\&.
.IP "\fB-B broadcast address\fP"
Send the query to the given broadcast
address\&. Without this option the default behavior of nmblookup is to
-send the query to the broadcast address of the network
-interfaces as either auto-detected or defined in the
+send the query to the broadcast address of the primary network
+interface as either auto-detected or defined in the
\fBinterfaces\fP parameter of the
\fBsmb\&.conf (5)\fP file\&.
.IP
@@ -98,12 +97,6 @@ are \fIvery\fP rarely used, only set this parameter if you are the
system administrator in charge of all the NetBIOS systems you
communicate with\&.
.IP
-.IP "\fB-T\fP"
-This causes any IP addresses found in the lookup to be
-looked up via a reverse DNS lookup into a DNS name, and printed out
-before each \f(CW"IP address NetBIOS name"\fP pair that is the normal
-output\&.
-.IP
.IP "\fBname\fP"
This is the NetBIOS name being queried\&. Depending upon
the previous options this may be a NetBIOS name or IP address\&. If a
diff --git a/docs/manpages/rpcclient.1 b/docs/manpages/rpcclient.1
new file mode 100644
index 00000000000..bbea8761fdf
--- /dev/null
+++ b/docs/manpages/rpcclient.1
@@ -0,0 +1,809 @@
+.TH RPCCLIENT 1 "24 Feb 2000" "rpcclient TNG-prealpha"
+.PP
+.SH "NAME"
+rpcclient \- utility to manage MSRPC resources on servers
+.PP
+.SH "SYNOPSIS"
+.PP
+\fBrpcclient\fP
+[password]
+-S servername
+[-U [username][%][password]]
+[-W domain]
+[-l log basename]
+[-d debuglevel]
+[-O socket options]
+[-i scope]
+[-N]
+[-n NetBIOS name]
+[-h]
+[-I dest IP]
+[-E]
+[-t terminal code]
+[-c command string]
+[-B IP addr]
+[-s smb\&.conf]
+[-m max protocol]
+.PP
+.SH "DESCRIPTION"
+.PP
+This program is part of the \fBSamba\fP suite\&.
+.PP
+\fBrpcclient\fP is a client that can \'talk\' to an SMB/CIFS MSRPC server\&.
+Operations include things like managing a SAM Database (users, groups
+and aliases) in the same way as the Windows NT programs
+\fBUser Manager for Domains\fP and \fBServer Manager for Domains\fP;
+managing a remote registry in the same way as the Windows NT programs
+\fBREGEDT32\&.EXE\fP and \fBREGEDIT\&.EXE\fP; viewing a remote event log (same
+as \fBEVENTVWR\&.EXE\fP) etc\&.
+.PP
+Typical usage is like this:
+.br
+\f(CWrpcclient -I 192\&.168\&.32\&.1 -S "*SMBSERVER" -U fred%secret -l log\fP
+.br
+.PP
+.SH "OPTIONS"
+.PP
+.IP
+.IP "\fBservername\fP"
+servername is the name of the server you want
+to use on the server\&. This should be the NetBIOS name of the SMB/CIFS
+server, which can be \fB*SMBSERVER\fP on Windows NT 4\&.0 or Samba Servers\&.
+.IP
+Note that the server name required is NOT necessarily the IP (DNS)
+host name of the server! The name required is a NetBIOS server name,
+which may or may not be the same as the IP hostname of the machine
+running the server\&. Also, remember that having a period in a NetBIOS
+name (such as an IP hostname) may cause connectivity problems on your
+network: NT tends to strip NetBIOS names from the leading period
+onwards\&.
+.IP
+The server name is looked up according to either the
+\fB-R\fP parameter to \fBrpcclient\fP or using the
+\fBname resolve order\fP
+parameter in the smb\&.conf file, allowing an administrator to change
+the order and methods by which server names are looked up\&.
+.IP
+.IP "\fBpassword\fP"
+password is the password required to access the
+specified service on the specified server\&. If this parameter is
+supplied, the \fB-N\fP option (suppress password prompt) is assumed\&.
+.IP
+There is no default password\&. If no password is supplied on the
+command line (either by using this parameter or adding a password to
+the \fB-U\fP option (see below)) and the \fB-N\fP option is not specified,
+the client will prompt for a password, even if the desired service
+does not require one\&. (If no password is required, simply press ENTER
+to provide a null password\&.)
+.IP
+Note: Some servers (including OS/2 and Windows for Workgroups) insist
+on an uppercase password\&. Lowercase or mixed case passwords may be
+rejected by these servers\&.
+.IP
+Be cautious about including passwords in scripts\&.
+.IP
+.IP "\fB-s smb\&.conf\fP"
+This parameter specifies the pathname to the
+Samba configuration file, smb\&.conf\&. This file controls all aspects of
+the Samba setup on the machine and rpcclient also needs to read this
+file\&.
+.IP
+.IP "\fB-B IP addr\fP"
+The IP address to use when sending a broadcast packet\&.
+.IP
+.IP "\fB-O socket options\fP"
+TCP socket options to set on the client
+socket\&. See the socket options
+parameter in the \fBsmb\&.conf (5)\fP manpage for
+the list of valid options\&.
+.IP
+.IP "\fB-R name resolve order\fP"
+This option allows the user of
+rpcclient to determine what name resolution services to use when
+looking up the NetBIOS name of the host being connected to\&.
+.IP
+The options are :"lmhosts", "host", "wins" and "bcast"\&. They cause
+names to be resolved as follows :
+.IP
+.IP
+.IP o
+\fBlmhosts\fP : Lookup an IP address in the Samba lmhosts file\&.
+The lmhosts file is stored in the same directory as the
+\fBsmb\&.conf\fP file\&.
+.IP
+.IP o
+\fBhost\fP : Do a standard host name to IP address resolution,
+using the system /etc/hosts, NIS, or DNS lookups\&. This method of name
+resolution is operating system depended for instance on IRIX or
+Solaris this may be controlled by the \fI/etc/nsswitch\&.conf\fP file)\&.
+.IP
+.IP o
+\fBwins\fP : Query a name with the IP address listed in the \fBwins
+server\fP parameter in the smb\&.conf file\&. If
+no WINS server has been specified this method will be ignored\&.
+.IP
+.IP o
+\fBbcast\fP : Do a broadcast on each of the known local interfaces
+listed in the \fBinterfaces\fP parameter
+in the smb\&.conf file\&. This is the least reliable of the name resolution
+methods as it depends on the target host being on a locally connected
+subnet\&. To specify a particular broadcast address the \fB-B\fP option
+may be used\&.
+.IP
+.IP
+If this parameter is not set then the name resolve order defined
+in the \fBsmb\&.conf\fP file parameter
+(\fBname resolve order\fP)
+will be used\&.
+.IP
+The default order is lmhosts, host, wins, bcast and without this
+parameter or any entry in the \fB"name resolve
+order"\fP parameter of the
+\fBsmb\&.conf\fP file the name resolution methods
+will be attempted in this order\&.
+.IP
+.IP "\fB-i scope\fP"
+This specifies a NetBIOS scope that rpcclient will use
+to communicate with when generating NetBIOS names\&. For details on the
+use of NetBIOS scopes, see rfc1001\&.txt and rfc1002\&.txt\&. NetBIOS scopes
+are \fIvery\fP rarely used, only set this parameter if you are the
+system administrator in charge of all the NetBIOS systems you
+communicate with\&.
+.IP
+.IP "\fB-N\fP"
+If specified, this parameter suppresses the normal
+password prompt from the client to the user\&. This is useful when
+accessing a service that does not require a password\&.
+.IP
+Unless a password is specified on the command line or this parameter
+is specified, the client will request a password\&.
+.IP
+.IP "\fB-n NetBIOS name\fP"
+By default, the client will use the local
+machine\'s hostname (in uppercase) as its NetBIOS name\&. This parameter
+allows you to override the host name and use whatever NetBIOS name you
+wish\&.
+.IP
+.IP "\fB-d debuglevel\fP"
+debuglevel is an integer from 0 to 10, or the
+letter \'A\'\&.
+.IP
+The default value if this parameter is not specified is zero\&.
+.IP
+The higher this value, the more detail will be logged to the log files
+about the activities of the client\&. At level 0, only critical errors
+and serious warnings will be logged\&. Level 1 is a reasonable level for
+day to day running - it generates a small amount of information about
+operations carried out\&.
+.IP
+Levels above 1 will generate considerable amounts of log data, and
+should only be used when investigating a problem\&. Levels above 3 are
+designed for use only by developers and generate HUGE amounts of log
+data, most of which is extremely cryptic\&. If debuglevel is set to the
+letter \'A\', then \fIall\fP debug messages will be printed\&. This setting
+is for developers only (and people who \fIreally\fP want to know how the
+code works internally)\&.
+.IP
+Note that specifying this parameter here will override the \fBlog
+level\fP parameter in the \fBsmb\&.conf
+(5)\fP file\&.
+.IP
+.IP "\fB-p port\fP"
+This number is the TCP port number that will be used
+when making connections to the server\&. The standard (well-known) TCP
+port number for an SMB/CIFS server is 139, which is the default\&.
+.IP
+.IP "\fB-l logfilename\fP"
+If specified, logfilename specifies a base
+filename into which operational data from the running client will be
+logged\&.
+.IP
+The default base name is specified at compile time\&.
+.IP
+The base name is used to generate actual log file names\&. For example,
+if the name specified was "log", the debug file would be
+\f(CWlog\&.client\fP\&.
+.IP
+The log file generated is never removed by the client\&.
+.IP
+.IP "\fB-h\fP"
+Print the usage message for the client\&.
+.IP
+.IP "\fB-I IP address\fP"
+IP address is the address of the server to
+connect to\&. It should be specified in standard "a\&.b\&.c\&.d" notation\&.
+.IP
+Normally the client would attempt to locate a named SMB/CIFS server by
+looking it up via the NetBIOS name resolution mechanism described
+above in the \fBname resolve order\fP parameter
+above\&. Using this parameter will force the client to assume that the
+server is on the machine with the specified IP address and the NetBIOS
+name component of the resource being connected to will be ignored\&.
+.IP
+There is no default for this parameter\&. If not supplied, it will be
+determined automatically by the client as described above\&.
+.IP
+.IP "\fB-E\fP"
+This parameter causes the client to write messages to the
+standard error stream (stderr) rather than to the standard output
+stream\&.
+.IP
+By default, the client writes messages to standard output - typically
+the user\'s tty\&.
+.IP
+Note that by default, debug information is always sent to stderr\&.
+Debug information can instead be sent to a file, using the
+-l log basename option\&.
+.IP
+.IP "\fB-U username\fP"
+This specifies the user name that will be used by
+the client to make a connection, assuming your server is not a downlevel
+server that is running a protocol level that uses passwords on shares,
+not on usernames\&.
+.IP
+Some servers are fussy about the case of this name, and some insist
+that it must be a valid NetBIOS name\&.
+.IP
+If no username is supplied, it will default to an uppercase version of
+the environment variable \f(CWUSER\fP or \f(CWLOGNAME\fP in that order\&. If no
+username is supplied and neither environment variable exists the
+username "GUEST" will be used\&.
+.IP
+If the \f(CWUSER\fP environment variable contains a \'%\' character,
+everything after that will be treated as a password\&. This allows you
+to set the environment variable to be \f(CWUSER=username%password\fP so
+that a password is not passed on the command line (where it may be
+seen by the ps command)\&.
+.IP
+If the service you are connecting to requires a password, it can be
+supplied using the \fB-U\fP option, by appending a percent symbol ("%")
+then the password to username\&. For example, to attach to a service as
+user \f(CW"fred"\fP with password \f(CW"secret"\fP, you would specify\&.
+.br
+.IP
+\f(CW-U fred%secret\fP
+.br
+.IP
+on the command line\&. Note that there are no spaces around the percent
+symbol\&.
+.IP
+If you specify the password as part of username then the \fB-N\fP option
+(suppress password prompt) is assumed\&.
+.IP
+If you specify the password as a parameter \fIAND\fP as part of username
+then the password as part of username will take precedence\&. Putting
+nothing before or nothing after the percent symbol will cause an empty
+username or an empty password to be used, respectively\&.
+.IP
+The password may also be specified by setting up an environment
+variable called \f(CWPASSWORD\fP that contains the users password\&. Note
+that this may be very insecure on some systems but on others allows
+users to script rpcclient commands without having a password appear in
+the command line of a process listing\&.
+.IP
+Note: Some servers (including OS/2 and Windows for Workgroups) insist
+on an uppercase password\&. Lowercase or mixed case passwords may be
+rejected by these servers\&.
+.IP
+Be cautious about including passwords in scripts or in the
+\f(CWPASSWORD\fP environment variable\&. Also, on many systems the command
+line of a running process may be seen via the \f(CWps\fP command to be
+safe always allow rpcclient to prompt for a password and type it in
+directly\&.
+.IP
+.IP "\fB-t terminal code\fP"
+This option tells rpcclient how to interpret
+filenames coming from the remote server\&. Usually Asian language
+multibyte UNIX implementations use different character sets than
+SMB/CIFS servers (\fIEUC\fP instead of \fISJIS\fP for example)\&. Setting
+this parameter will let rpcclient convert between the UNIX filenames
+and the SMB filenames correctly\&. This option has not been seriously
+tested and may have some problems\&.
+.IP
+The terminal codes include \f(CWsjis\fP, \f(CWeuc\fP, \f(CWjis7\fP, \f(CWjis8\fP,
+\f(CWjunet\fP, \f(CWhex\fP, \f(CWcap\fP\&. This is not a complete list, check the
+Samba source code for the complete list\&.
+.IP
+.IP "\fB-m max protocol level\fP"
+With the new code in Samba2\&.0,
+\fBrpcclient\fP always attempts to connect at the maximum
+protocols level the server supports\&. This parameter is
+preserved for backwards compatibility, but any string
+following the \fB-m\fP will be ignored\&.
+.IP
+.IP "\fB-W Domain\fP"
+Override the default Domain, which is the remote server\'s
+Domain\&. This option may be needed to connect to some servers\&. It is also
+possible to specify the remote server name as the Domain, which will
+force the username and password to be authenticated against the remote
+server\'s local SAM instead of the Domain SAM\&.
+.IP
+.IP "\fB-c command string\fP"
+command string is a semicolon separated
+list of commands to be executed instead of prompting from stdin\&.
+\fB-N\fP is implied by \fB-c\fP\&.
+.IP
+This is particularly useful in scripts, e\&.g\&. \f(CW-c \'lsaquery; enumusers -u\'\fP\&.
+.IP
+.PP
+.SH "OPERATIONS"
+.PP
+Once the client is running, the user is presented with a prompt :
+.PP
+\f(CWsmb:\e>\fP
+.PP
+The prompt indicates that the client is ready and waiting to carry out
+a user command\&. Each command is a single word, optionally followed by
+parameters specific to that command\&. Command and parameters are
+space-delimited unless these notes specifically state otherwise\&. All
+commands are case-insensitive\&. Parameters to commands may or may not
+be case sensitive, depending on the command\&.
+.PP
+You can specify names (e\&.g registry keys; user or group names;
+service names) which have spaces in them by quoting the
+name with double quotes, for example "dRMON SmartAgent"\&.
+.PP
+Parameters shown in square brackets (e\&.g\&., "[parameter]") are
+optional\&. If not given, the command will use suitable
+defaults\&. Parameters shown in angle brackets (e\&.g\&., "<parameter>") are
+required\&.
+.PP
+Note that all commands operating on the server are actually performed
+by issuing a request to the server\&. Thus the behavior may vary from
+server to server, depending on how the server was implemented\&.
+.PP
+The commands available are listed in groups relating to different services:
+.PP
+.IP
+.IP "Misccellaneous"
+.IP
+.IP
+.IP "\fB? [command]\fP"
+If "command" is specified,
+the \fB?\fP command will display a brief informative message about the
+specified command\&. If no command is specified, a list of available
+commands will be displayed\&.
+.IP
+.IP "\fB! [shell command]\fP"
+If "shell command"
+is specified, the \fB!\fP command will execute a shell locally and run
+the specified shell command\&. If no command is specified, a local shell
+will be run\&.
+.IP
+.IP "\fBexit\fP"
+Terminate the connection with the server and
+exit from the program\&.
+.IP
+.IP "\fBhelp [command]\fP"
+See the \fB?\fP
+command above\&.
+.IP
+.IP "\fBquit\fP"
+See the \fBexit\fP command\&.
+.IP
+.IP
+.IP "Event Log"
+.IP
+.IP
+.IP "\fBeventlog\fP"
+list the events
+.IP
+.IP
+.IP "Service Control"
+.IP
+These commands provide functionality similar to the Windows
+NT Service Control Manager\&.
+.IP
+It is possible to use command-line completion (if you have
+the GNU readline library) for Service names, by pressing the
+tab key\&.
+.IP
+.IP
+.IP "\fBsvcenum\fP"
+[-i] Lists Services\&.
+.IP
+.IP "\fBsvcinfo\fP"
+<service> Service Information
+.IP
+.IP "\fBsvcstart\fP"
+<service> [arg 0] [arg 1] \&.\&.\&. Start Service
+.IP
+.IP "\fBsvcstop\fP"
+<service> Stop Service
+.IP
+.IP
+.IP "Scheduler"
+.IP
+.IP
+.IP "\fBat\fP"
+Scheduler control (at /? for syntax)
+.IP
+.IP
+.IP "Registry"
+.IP
+It is possible to use command-line completion (if you have
+the GNU readline library) for registry key and value names,
+by pressing the tab key\&.
+.IP
+.IP
+.IP "\fBregenum\fP"
+<keyname> Registry Enumeration (keys, values)
+.IP
+.IP "\fBregdeletekey\fP"
+<keyname> Registry Key Delete
+.IP
+.IP "\fBregcreatekey\fP"
+<keyname> [keyclass] Registry Key Create
+.IP
+.IP "\fBshutdown\fP"
+[-m message] [-t timeout] [-r or --reboot] Server Shutdown
+.IP
+.IP "\fBregqueryval\fP"
+<valname> Registry Value Query
+.IP
+.IP "\fBregquerykey\fP"
+<keyname> Registry Key Query
+.IP
+.IP "\fBregdeleteval\fP"
+<valname> Registry Value Delete
+.IP
+.IP "\fBregcreateval\fP"
+<valname> <valtype> <value> Registry Key Create
+.IP
+.IP "\fBreggetsec\fP"
+<keyname> Registry Key Security
+.IP
+.IP "\fBregtestsec\fP"
+<keyname> Test Registry Key Security
+.IP
+.IP
+.IP "Printing"
+.IP
+It is possible to use command-line completion (if you have
+the GNU readline library) for Printer and job names, by
+pressing the tab key\&.
+.IP
+.IP
+.IP "\fBspoolenum\fP"
+Enumerate Printers\&. This experimental command lists
+all printers available on a remote spooler service\&.
+.IP
+.IP "\fBspooljobs\fP"
+<printer name> Enumerate Printer Jobs\&. This
+experimental command lists all jobs, and their
+status, currently queued on a remote spooler
+service\&.
+.IP
+.IP "\fBspoolopen\fP"
+<printer name> Spool Printer Open Test\&. Experimental\&.
+.IP
+.IP
+.IP "Server"
+.IP
+.IP
+.IP "\fBtime\fP"
+Display remote time
+.IP
+.IP "\fBbrsinfo\fP"
+Browser Query Info
+.IP
+.IP "\fBwksinfo\fP"
+Workstation Query Info
+.IP
+.IP "\fBsrvinfo\fP"
+Server Query Info
+.IP
+.IP "\fBsrvsessions\fP"
+List sessions on a server
+.IP
+.IP "\fBsrvshares\fP"
+List shares on a server
+.IP
+.IP "\fBsrvtransports\fP"
+List transports on a server
+.IP
+.IP "\fBsrvconnections\fP"
+List connections on a server
+.IP
+.IP "\fBsrvfiles\fP"
+List files on a server
+.IP
+.IP
+.IP "Local Security Authority"
+.IP
+.IP
+.IP "\fBlsaquery\fP"
+Query Info Policy (domain member or server)\&. Obtains
+the SID and name of the SAM database that a server
+is responsible for (i\&.e a workstation\'s local SAM
+database or the PDC SAM database)\&. Also obtains the
+SID and name of the SAM database that a server is
+a member of\&.
+.IP
+.IP "\fBlsaenumdomains\fP"
+Enumerate Trusted Domains\&. Lists all Trusted and
+Trusting Domains with which the remote PDC has
+trust relationships established\&.
+.IP
+.IP "\fBlookupsids\fP"
+<rid1 or sid1> <rid1 or sid2> \&.\&.\&. Resolve names from SIDs\&.
+Mostly to be used by developers or for troubleshooting,
+this command can take either Security Identifiers or Relative
+Identifiers, and look them up in the local SAM database
+(or look them up in a remote Trusting or Trusted PDC\'s SAM
+database if there is an appropriate Trust Relationship
+established)\&. The result is a list of names, of the
+format:
+.br
+\f(CW[TRUST_DOMAIN\e]name\fP\&.
+.br
+the \fBlsaquery\fP command must have been
+issued first if you wish to use lookupsids to resolve
+RIDs\&. The only RIDs that will be resolved will be those
+in the SAM database of the server to which you are connected\&.
+.IP
+.IP "\fBlookupnames\fP"
+<name1> <name2> \&.\&.\&. Resolve SIDs from names\&.
+Mostly to be used by developers or for troubleshooting,
+this command can take names of the following format:
+.br
+\f(CW[DOMAIN_NAME\e]name\fP\&.
+.br
+The names, which can be user, group or alias names, will
+either be looked up in the local SAM database or in a remote
+Trusting or Trusted PDC\'s SAM database, if there is an
+appropriate Trust Relationship established\&. The optional
+Domain name component is the name of a SAM database, which
+can include a workstation\'s local SAM database or a Trusted
+Domain\&.
+Example Usage:
+.br
+\f(CWlookupnames WKSTANAME\eAdministrator "Domain Guests"\fP
+.br
+.IP
+.IP "\fBquerysecret\fP"
+LSA Query Secret (developer use)\&. This command only appears
+to work against NT4 SP3 and below\&. Due to its potential
+for misuse, it looks like Microsoft modified their
+implementation of the LsaRetrievePrivateData call to
+always return NT_STATUS_ACCESS_DENIED\&.
+.IP
+.IP
+.IP "NETLOGON"
+.IP
+.IP
+.IP "\fBntlogin\fP"
+[username] [password] NT Domain login test\&. Demonstrates
+how NT-style logins work\&. Mainly for developer usage,
+it can also be used to verify that a user can log in
+from a workstation\&. If you cannot ever get pam_ntdom
+to work, try this command first\&.
+.IP
+.IP "\fBdomtrust\fP"
+<domain> NT Inter-Domain test\&. Demonstrates how NT-style
+Inter-Domain Trust relationships work\&. Mainly for
+developer usage, it can also be used to verify that a
+Trust Relationship is correctly established with a
+remote PDC\&.
+.IP
+.IP "\fBsamsync\fP"
+SAM Synchronisation Test (experimental)\&. This command
+is used to manually synchronise a SAM database from a
+remote PDC, when Samba is set up as a Backup Domain
+Controller\&.
+.IP
+.IP
+.IP "SAM Database"
+.IP
+It is possible to use command-line completion (if you have
+the GNU readline library) for user, group, alias and domain
+names, by pressing the tab key\&.
+.IP
+.IP
+.IP "\fBlookupdomain\fP"
+Obtain SID for a local domain
+.IP
+.IP "\fBenumusers\fP"
+SAM User Database Query (experimental!)
+.IP
+.IP "\fBaddgroupmem\fP"
+<group rid> [user] [user] \&.\&.\&. SAM Add Domain Group Member
+.IP
+.IP "\fBaddaliasmem\fP"
+<alias rid> [member sid1] [member sid2] \&.\&.\&. SAM Add Domain Alias Member
+.IP
+.IP "\fBdelgroupmem\fP"
+<group rid> [user] [user] \&.\&.\&. SAM Delete Domain Group Member
+.IP
+.IP "\fBdelaliasmem\fP"
+<alias rid> [member sid1] [member sid2] \&.\&.\&. SAM Delete Domain Alias Member
+.IP
+.IP "\fBcreategroup\fP"
+SAM Create Domain Group
+.IP
+.IP "\fBcreatealias\fP"
+SAM Create Domain Alias
+.IP
+.IP "\fBcreateuser\fP"
+<username> SAM Create Domain User
+.IP
+.IP "\fBdelgroup\fP"
+SAM Delete Domain Group
+.IP
+.IP "\fBdelalias\fP"
+SAM Delete Domain Alias
+.IP
+.IP "\fBntpass\fP"
+NT SAM Password Change
+.IP
+.IP "\fBsamuserset2\fP"
+<username> [-s acb_bits] SAM User Set Info 2 (experimental!)
+.IP
+.IP "\fBsamuserset\fP"
+<username> [-p password] SAM User Set Info (experimental!)
+.IP
+.IP "\fBsamuser\fP"
+<username> SAM User Query (experimental!)
+.IP
+.IP "\fBsamgroup\fP"
+<groupname> SAM Group Query (experimental!)
+.IP
+.IP "\fBsamalias\fP"
+<aliasname> SAM Alias Query
+.IP
+.IP "\fBsamaliasmem\fP"
+<aliasname> SAM Alias Members
+.IP
+.IP "\fBsamgroupmem\fP"
+SAM Group Members
+.IP
+.IP "\fBsamtest\fP"
+SAM User Encrypted RPC test (experimental!)
+.IP
+.IP "\fBenumaliases\fP"
+SAM Aliases Database Query (experimental!)
+.IP
+.IP "\fBenumdomains\fP"
+SAM Domains Database Query (experimental!)
+.IP
+.IP "\fBenumgroups\fP"
+SAM Group Database Query (experimental!)
+.IP
+.IP "\fBdominfo\fP"
+SAM Query Domain Info
+.IP
+.IP "\fBdispinfo\fP"
+SAM Query Display Info
+.IP
+.IP
+.PP
+.SH "NOTES"
+.PP
+Some servers are fussy about the case of supplied usernames,
+passwords, share names (AKA service names) and machine names\&. If you
+fail to connect try giving all parameters in uppercase\&.
+.PP
+It is often necessary to use the \fB-n\fP option when connecting
+to some types of servers\&. For example OS/2 LanManager insists on a valid
+NetBIOS name being used, so you need to supply a valid name that would
+be known to the server\&.
+.PP
+rpcclient only works on servers that support MSRPC over SMB\&. This includes
+all versions of Windows NT, including the ports to Unix such as AS/U and
+AFPS\&. Support for MSRPC over SMB in other servers is currently rare and
+patchy, for example Samba 2\&.0 only supports a limited set of MSRPC commands,
+and some of those are not supported very well\&.
+.PP
+.SH "ENVIRONMENT VARIABLES"
+.PP
+The variable \fBUSER\fP may contain the username of the person using the
+client\&. This information is used only if the protocol level is high
+enough to support session-level passwords\&.
+.PP
+The variable \fBPASSWORD\fP may contain the password of the person using
+the client\&. This information is used only if the protocol level is
+high enough to support session-level passwords\&.
+.PP
+.SH "INSTALLATION"
+.PP
+The location of the client program is a matter for individual system
+administrators\&. The following are thus suggestions only\&.
+.PP
+It is recommended that the rpcclient software be installed in the
+/usr/local/samba/bin or /usr/samba/bin directory, this directory
+readable by all, writeable only by root\&. The client program itself
+should be executable by all\&. The client should \fINOT\fP be setuid or
+setgid!
+.PP
+The client log files should be put in a directory readable and
+writeable only by the user\&.
+.PP
+To test the client, you will need to know the name of a running
+SMB/CIFS server\&. It is possible to run \fBsmbd (8)\fP
+an ordinary user - running that server as a daemon on a
+user-accessible port (typically any port number over 1024) would
+provide a suitable test server\&.
+.PP
+.SH "DIAGNOSTICS"
+.PP
+Most diagnostics issued by the client are logged in a specified log
+file\&. The log file name is specified at compile time, but may be
+overridden on the command line\&.
+.PP
+The number and nature of diagnostics available depends on the debug
+level used by the client\&. If you have problems, set the debug level to
+3 and peruse the log files\&.
+.PP
+.SH "VERSION"
+.PP
+This man page is correct for version 2\&.0 of the Samba suite\&.
+.PP
+.SH "BUGS"
+.PP
+.IP "WARNING!"
+The MSPRC over SMB code has been developed from examining Network traces\&.
+No documentation is available from the original creators (Microsoft) on
+how MSRPC over SMB works, or how the individual MSRPC services work\&.
+Microsoft\'s implementation of these services has been demonstrated (and
+reported) to be\&.\&.\&. a bit flakey in places\&.
+.IP
+The development of Samba\'s implementation of these services is \fIalso\fP
+a bit rough, and as more of the services are understood, it can even result
+in versions of \fBsmbd (8)\fP and rpcclient that are
+incompatible for some commands or services\&. Additionally, the developers
+are sending reports to Microsoft, and problems found by or reported to
+Microsoft are fixed in Service Packs, which may also result in
+incompatibilities\&.
+.IP
+It is therefore not guaranteed that the execution of an rpcclient command will
+work\&. It is also not guaranteed that the target server will continue to
+operate, i\&.e the execution of an MSRPC command may cause a remote service to
+fail, or even cause the remote server to fail\&. Usual rules apply, of course:
+the developers bear absolutely no responsibility for the use, misuse, or
+lack of use of rpcclient, by any person or persons, whether legal,
+illegal, accidental, deliberate, intentional, malicious, curious, etc\&.
+.IP
+.IP "Command Completion"
+Command-completion (available if you have the GNU readline library) used on
+certain commands may not operate correctly if the word being completed (such as a registry key) contains a space\&. Typically, the name will be completed, but
+you will have to go back and put quotes round it, yourself\&.
+.IP
+.IP "SAM Database command-completion"
+Command-completion (available if you have the GNU readline library) of user,
+group and alias names does not work on remote Domains, which would normally
+be specified like this:
+.br
+\f(CWDOMAIN_name\euser_name\fP\&.
+.br
+The only names that can be completed in this fashion are the local names
+in the SAM database of the target server\&.
+.IP
+.IP "\fBspoolenum\fP"
+Due to current limitations in the rpcclient MSRPC / SMB code, and due to
+the extremely poor MSRPC implementation (by Microsoft) of the spooler
+service, if there are a large number of printers (or the names / comment
+fields associated with the printers), this command will fail\&. The
+limitations require further research to be carried out; we\'re stuck with
+the poor \ePIPE\espoolss design\&.
+.IP
+.PP
+.SH "AUTHOR"
+.PP
+The original Samba software and related utilities were created by
+Andrew Tridgell \fIsamba-bugs@samba\&.org\fP\&. Samba is now developed
+by the Samba Team as an Open Source project similar to the way the
+Linux kernel is developed\&.
+.PP
+The original Samba man pages were written by Karl Auer\&. The man page
+sources were converted to YODL format (another excellent piece of Open
+Source software, available at
+\fBftp://ftp\&.icce\&.rug\&.nl/pub/unix/\fP)
+and updated for the Samba2\&.0 release by Jeremy Allison\&. This man page
+was developed cut-and-paste style from the smbclient man page, by
+Luke Kenneth Casson Leighton\&.
+\fIsamba-bugs@samba\&.org\fP\&.
+.PP
+See \fBsamba (7)\fP to find out how to get a full
+list of contributors and details on how to submit bug reports,
+comments etc\&.
+.PP
diff --git a/docs/manpages/samba.7 b/docs/manpages/samba.7
index 96975f34c26..c36e5d387fc 100644
--- a/docs/manpages/samba.7
+++ b/docs/manpages/samba.7
@@ -1,4 +1,4 @@
-.TH "Samba " "7" "23 Oct 1998" "Samba" ""
+.TH SAMBA 7 "24 Feb 2000" "samba TNG-prealpha"
.PP
.SH "NAME"
Samba \- A Windows SMB/CIFS fileserver for UNIX
@@ -50,6 +50,18 @@ servers (such as Windows NT), and can also be used to allow a UNIX box
to print to a printer attached to any SMB server (such as a PC running
Windows NT)\&.
.IP
+.IP "\fBrpcclient\fP"
+.br
+.br
+The \fBrpcclient\fP
+(1) program is a client that can \'talk\' to an
+SMB/CIFS MSRPC server\&. Operations include things like managing a SAM
+Database (users, groups and aliases) in the same way as the Windows NT
+programs \fBUser Manager for Domains\fP and \fBServer Manager for Domains\fP;
+managing a remote registry in the same way as the Windows NT programs
+\fBREGEDT32\&.EXE\fP and \fBREGEDIT\&.EXE\fP; viewing a remote event log (same
+as \fBEVENTVWR\&.EXE\fP)\&.
+.IP
.IP "\fBtestparm\fP"
.br
.br
diff --git a/docs/manpages/smb.conf.5 b/docs/manpages/smb.conf.5
index da873317697..0e88d6aac9b 100644
--- a/docs/manpages/smb.conf.5
+++ b/docs/manpages/smb.conf.5
@@ -1,4 +1,4 @@
-.TH "smb\&.conf " "5" "23 Oct 1998" "Samba" "SAMBA"
+.TH SMB.CONF 5 "24 Feb 2000" "smb.conf TNG-prealpha"
.PP
.SH "NAME"
smb\&.conf \- The configuration file for the Samba suite
@@ -242,7 +242,6 @@ would look like this:
[printers]
path = /usr/spool/public
- writeable = no
guest ok = yes
printable = yes
@@ -491,12 +490,6 @@ parameter for details\&. Note that some are synonyms\&.
.PP
.IP
.IP o
-\fBadd user script\fP
-.IP
-.IP o
-\fBallow trusted domains\fP
-.IP
-.IP o
\fBannounce as\fP
.IP
.IP o
@@ -530,18 +523,9 @@ parameter for details\&. Note that some are synonyms\&.
\fBdeadtime\fP
.IP
.IP o
-\fBdebug hires timestamp\fP
-.IP
-.IP o
-\fBdebug pid\fP
-.IP
-.IP o
\fBdebug timestamp\fP
.IP
.IP o
-\fBdebug uid\fP
-.IP
-.IP o
\fBdebuglevel\fP
.IP
.IP o
@@ -551,9 +535,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBdefault service\fP
.IP
.IP o
-\fBdelete user script\fP
-.IP
-.IP o
\fBdfree command\fP
.IP
.IP o
@@ -569,6 +550,9 @@ parameter for details\&. Note that some are synonyms\&.
\fBdomain controller\fP
.IP
.IP o
+\fBdomain group map\fP
+.IP
+.IP o
\fBdomain groups\fP
.IP
.IP o
@@ -584,6 +568,9 @@ parameter for details\&. Note that some are synonyms\&.
\fBdomain master\fP
.IP
.IP o
+\fBdomain user map\fP
+.IP
+.IP o
\fBencrypt passwords\fP
.IP
.IP o
@@ -605,16 +592,13 @@ parameter for details\&. Note that some are synonyms\&.
\fBkernel oplocks\fP
.IP
.IP o
-\fBldap filter\fP
+\fBldap bind as\fP
.IP
.IP o
-\fBldap port\fP
+\fBldap passwd file\fP
.IP
.IP o
-\fBldap root\fP
-.IP
-.IP o
-\fBldap root passwd\fP
+\fBldap port\fP
.IP
.IP o
\fBldap server\fP
@@ -632,6 +616,9 @@ parameter for details\&. Note that some are synonyms\&.
\fBload printers\fP
.IP
.IP o
+\fBlocal group map\fP
+.IP
+.IP o
\fBlocal master\fP
.IP
.IP o
@@ -668,9 +655,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBmangled stack\fP
.IP
.IP o
-\fBmap to guest\fP
-.IP
-.IP o
\fBmax disk size\fP
.IP
.IP o
@@ -698,9 +682,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBmessage command\fP
.IP
.IP o
-\fBmin passwd length\fP
-.IP
-.IP o
\fBmin wins ttl\fP
.IP
.IP o
@@ -716,9 +697,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBnis homedir\fP
.IP
.IP o
-\fBnt acl support\fP
-.IP
-.IP o
\fBnt pipe support\fP
.IP
.IP o
@@ -731,9 +709,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBole locking compatibility\fP
.IP
.IP o
-\fBoplock break wait time\fP
-.IP
-.IP o
\fBos level\fP
.IP
.IP o
@@ -797,9 +772,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBremote browse sync\fP
.IP
.IP o
-\fBrestrict anonymous\fP
-.IP
-.IP o
\fBroot\fP
.IP
.IP o
@@ -923,9 +895,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBwins server\fP
.IP
.IP o
-\fBwins hook\fP
-.IP
-.IP o
\fBwins support\fP
.IP
.IP o
@@ -1002,9 +971,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBdirectory mode\fP
.IP
.IP o
-\fBdirectory security mask\fP
-.IP
-.IP o
\fBdont descend\fP
.IP
.IP o
@@ -1032,15 +998,9 @@ parameter for details\&. Note that some are synonyms\&.
\fBforce directory mode\fP
.IP
.IP o
-\fBforce directory security mode\fP
-.IP
-.IP o
\fBforce group\fP
.IP
.IP o
-\fBforce security mode\fP
-.IP
-.IP o
\fBforce user\fP
.IP
.IP o
@@ -1077,9 +1037,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBinvalid users\fP
.IP
.IP o
-\fBlevel2 oplocks\fP
-.IP
-.IP o
\fBlocking\fP
.IP
.IP o
@@ -1104,9 +1061,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBmangle case\fP
.IP
.IP o
-\fBmangle locks\fP
-.IP
-.IP o
\fBmangled map\fP
.IP
.IP o
@@ -1125,6 +1079,9 @@ parameter for details\&. Note that some are synonyms\&.
\fBmap system\fP
.IP
.IP o
+\fBmap to guest\fP
+.IP
+.IP o
\fBmax connections\fP
.IP
.IP o
@@ -1140,9 +1097,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBoplocks\fP
.IP
.IP o
-\fBoplock contention limit\fP
-.IP
-.IP o
\fBpath\fP
.IP
.IP o
@@ -1155,9 +1109,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBpreexec\fP
.IP
.IP o
-\fBpreexec close\fP
-.IP
-.IP o
\fBpreserve case\fP
.IP
.IP o
@@ -1209,12 +1160,6 @@ parameter for details\&. Note that some are synonyms\&.
\fBroot preexec\fP
.IP
.IP o
-\fBsecurity mask\fP
-.IP
-.IP o
-\fBroot preexec close\fP
-.IP
-.IP o
\fBset directory\fP
.IP
.IP o
@@ -1275,54 +1220,6 @@ parameter for details\&. Note that some are synonyms\&.
.SH "EXPLANATION OF EACH PARAMETER"
.PP
.IP
-.IP "\fBadd user script (G)\fP"
-.IP
-This is the full pathname to a script that will be run \fIAS ROOT\fP by
-\fBsmbd (8)\fP under special circumstances decribed
-below\&.
-.IP
-Normally, a Samba server requires that UNIX users are created for all
-users accessing files on this server\&. For sites that use Windows NT
-account databases as their primary user database creating these users
-and keeping the user list in sync with the Windows NT PDC is an
-onerous task\&. This option allows \fBsmbd\fP to create
-the required UNIX users \fION DEMAND\fP when a user accesses the Samba
-server\&.
-.IP
-In order to use this option, \fBsmbd\fP must be set to
-\fBsecurity=server\fP or
-\fBsecurity=domain\fP and \fB"add user script"\fP
-must be set to a full pathname for a script that will create a UNIX user
-given one argument of \fB%u\fP, which expands into the UNIX user name to
-create\&.
-.IP
-When the Windows user attempts to access the Samba server, at
-\fI"login"\fP(session setup in the SMB protocol) time,
-\fBsmbd\fP contacts the \fBpassword
-server\fP and attempts to authenticate the given user
-with the given password\&. If the authentication succeeds then
-\fBsmbd\fP attempts to find a UNIX user in the UNIX
-password database to map the Windows user into\&. If this lookup fails,
-and \fB"add user script"\fP is set then \fBsmbd\fP will
-call the specified script \fIAS ROOT\fP, expanding any \fB%u\fP argument
-to be the user name to create\&.
-.IP
-If this script successfully creates the user then
-\fBsmbd\fP will continue on as though the UNIX user
-already existed\&. In this way, UNIX users are dynamically created to
-match existing Windows NT accounts\&.
-.IP
-See also \fBsecurity=server\fP,
-\fBsecurity=domain\fP, \fBpassword
-server\fP, \fBdelete user
-script\fP\&.
-.IP
-\fBDefault:\fP
-\f(CW add user script = <empty string>\fP
-.IP
-\fBExample:\fP
-\f(CW add user script = /usr/local/samba/bin/add_user %u\fP
-.IP
.IP "\fBadmin users (S)\fP"
.IP
This is a list of users who will be granted administrative privileges
@@ -1343,29 +1240,63 @@ file permissions\&.
.IP
.IP "\fBallow hosts (S)\fP"
.IP
-Synonym for \fBhosts allow\fP\&.
+A synonym for this parameter is \fB\'hosts allow\'\fP
+.IP
+This parameter is a comma, space, or tab delimited set of hosts which
+are permitted to access a service\&.
.IP
-.IP "\fBallow trusted domains (G)\fP"
+If specified in the \fB[global]\fP section then it will
+apply to all services, regardless of whether the individual service
+has a different setting\&.
.IP
-This option only takes effect when the \fBsecurity\fP
-option is set to \fBserver\fP or \fBdomain\fP\&. If it is set to no,
-then attempts to connect to a resource from a domain or workgroup other than
-the one which smbd is running in will fail, even if that domain
-is trusted by the remote server doing the authentication\&.
+You can specify the hosts by name or IP number\&. For example, you could
+restrict access to only the hosts on a Class C subnet with something
+like \f(CW"allow hosts = 150\&.203\&.5\&."\fP\&. The full syntax of the list is
+described in the man page \fBhosts_access (5)\fP\&. Note that this man
+page may not be present on your system, so a brief description will
+be given here also\&.
.IP
-This is useful if you only want your Samba server to serve resources
-to users in the domain it is a member of\&. As an example, suppose that there are
-two domains DOMA and DOMB\&. DOMB is trusted by DOMA, which contains
-the Samba server\&. Under normal circumstances, a user with an account
-in DOMB can then access the resources of a UNIX account with the same
-account name on the Samba server even if they do not have an account
-in DOMA\&. This can make implementing a security boundary difficult\&.
+\fINOTE:\fP IF you wish to allow the \fBsmbpasswd
+(8)\fP program to be run by local users to change
+their Samba passwords using the local \fBsmbd (8)\fP
+daemon, then you \fIMUST\fP ensure that the localhost is listed in your
+\fBallow hosts\fP list, as \fBsmbpasswd (8)\fP runs
+in client-server mode and is seen by the local
+\fBsmbd\fP process as just another client\&.
+.IP
+You can also specify hosts by network/netmask pairs and by netgroup
+names if your system supports netgroups\&. The \fIEXCEPT\fP keyword can also
+be used to limit a wildcard list\&. The following examples may provide
+some help:
+.IP
+\fBExample 1\fP: allow localhost and all IPs in 150\&.203\&.*\&.* except one
+.IP
+\f(CW hosts allow = localhost, 150\&.203\&. EXCEPT 150\&.203\&.6\&.66\fP
+.IP
+\fBExample 2\fP: allow localhost and hosts that match the given network/netmask
+.IP
+\f(CW hosts allow = localhost, 150\&.203\&.15\&.0/255\&.255\&.255\&.0\fP
+.IP
+\fBExample 3\fP: allow a localhost plus a couple of hosts
+.IP
+\f(CW hosts allow = localhost, lapland, arvidsjaur\fP
+.IP
+\fBExample 4\fP: allow only hosts in NIS netgroup "foonet" or localhost, but
+deny access from one particular host
+.IP
+\f(CW hosts allow = @foonet, localhost\fP
+\f(CW hosts deny = pirate\fP
+.IP
+Note that access still requires suitable user-level passwords\&.
+.IP
+See \fBtestparm (1)\fP for a way of testing your
+host access to see if it does what you expect\&.
.IP
\fBDefault:\fP
-\f(CW allow trusted domains = Yes\fP
+\f(CW none (i\&.e\&., all hosts permitted access)\fP
.IP
\fBExample:\fP
-\f(CW allow trusted domains = No\fP
+\f(CW allow hosts = 150\&.203\&.5\&. localhost myhost\&.mynet\&.edu\&.au\fP
.IP
.IP "\fBalternate permissions (S)\fP"
.IP
@@ -1379,15 +1310,14 @@ regardless if the owner of the file is the currently logged on user or not\&.
.IP
This specifies what type of server \fBnmbd\fP will
announce itself as, to a network neighborhood browse list\&. By default
-this is set to Windows NT\&. The valid options are : "NT", which is a
-synonym for "NT Server", "NT Server", "NT Workstation", "Win95" or
-"WfW" meaning Windows NT Server, Windows NT Workstation, Windows 95
-and Windows for Workgroups respectively\&. Do not change this parameter
-unless you have a specific need to stop Samba appearing as an NT server
-as this may prevent Samba servers from participating as browser servers correctly\&.
+this is set to Windows NT\&. The valid options are : "NT", "Win95" or
+"WfW" meaning Windows NT, Windows 95 and Windows for Workgroups
+respectively\&. Do not change this parameter unless you have a specific
+need to stop Samba appearing as an NT server as this may prevent Samba
+servers from participating as browser servers correctly\&.
.IP
\fBDefault:\fP
-\f(CW announce as = NT Server\fP
+\f(CW announce as = NT\fP
.IP
\fBExample\fP
\f(CW announce as = Win95\fP
@@ -1466,16 +1396,11 @@ should not use this parameter for machines that are serving PPP or
other intermittent or non-broadcast network interfaces as it will not
cope with non-permanent interfaces\&.
.IP
-If \fB"bind interfaces only"\fP is set then unless the network address
-\fI127\&.0\&.0\&.1\fP is added to the \fB\'interfaces\'\fP parameter
-list \fBsmbpasswd\fP and
-\fBswat\fP may not work as expected due to the
-reasons covered below\&.
-.IP
-To change a users SMB password, the \fBsmbpasswd\fP
-by default connects to the \fI"localhost" - 127\&.0\&.0\&.1\fP address as an SMB
-client to issue the password change request\&. If \fB"bind interfaces only"\fP
-is set then unless the network address \fI127\&.0\&.0\&.1\fP is added to the
+In addition, to change a users SMB password, the
+\fBsmbpasswd\fP by default connects to the
+\fI"localhost" - 127\&.0\&.0\&.1\fP address as an SMB client to issue the
+password change request\&. If \fB"bind interfaces only"\fP is set then
+unless the network address \fI127\&.0\&.0\&.1\fP is added to the
\fB\'interfaces\'\fP parameter list then
\fBsmbpasswd\fP will fail to connect in it\'s
default mode\&. \fBsmbpasswd\fP can be forced to
@@ -1484,14 +1409,6 @@ use the primary IP interface of the local host by using its
\fB"remote machine"\fP set to the IP name of the primary interface
of the local host\&.
.IP
-The \fBswat\fP status page tries to connect with
-\fBsmbd\fP and \fBnmbd\fP at the address
-\fI127\&.0\&.0\&.1\fP to determine if they are running\&. Not adding \fI127\&.0\&.0\&.1\fP will cause
-\fBsmbd\fP and \fBnmbd\fP to always show
-"not running" even if they really are\&. This can prevent
-\fBswat\fP from starting/stopping/restarting
-\fBsmbd\fP and \fBnmbd\fP\&.
-.IP
\fBDefault:\fP
\f(CW bind interfaces only = False\fP
.IP
@@ -1545,11 +1462,11 @@ shares in a net view and in the browse list\&.
\fBExample:\fP
\f(CW browseable = No\fP
.IP
-.IP "\fBcase sensitive (G)\fP"
+.IP "\fBcase sensitive (S)\fP"
.IP
See the discussion in the section \fBNAME MANGLING\fP\&.
.IP
-.IP "\fBcasesignames (G)\fP"
+.IP "\fBcasesignames (S)\fP"
.IP
Synonym for \fB"case sensitive"\fP\&.
.IP
@@ -1597,14 +1514,7 @@ correctly\&.
.IP o
\fBISO8859-5\fP Russian Cyrillic UNIX character set\&. The parameter
\fBclient code page\fP \fIMUST\fP be set to code
-page 866 if the \fBcharacter set\fP parameter is set to ISO8859-5
-in order for the conversion to the UNIX character set to be done
-correctly\&.
-.IP
-.IP o
-\fBISO8859-7\fP Greek UNIX character set\&. The parameter
-\fBclient code page\fP \fIMUST\fP be set to code
-page 737 if the \fBcharacter set\fP parameter is set to ISO8859-7
+page 866 if the \fBcharacter set\fP parameter is set to ISO8859-2
in order for the conversion to the UNIX character set to be done
correctly\&.
.IP
@@ -1856,21 +1766,6 @@ performed\&.
\fBExample:\fP
\f(CW deadtime = 15\fP
.IP
-.IP "\fBdebug hires timestamp (G)\fP"
-.IP
-Sometimes the timestamps in the log messages are needed with a
-resolution of higher that seconds, this boolean parameter adds
-microsecond resolution to the timestamp message header when turned on\&.
-.IP
-Note that the parameter \fBdebug timestamp\fP
-must be on for this to have an effect\&.
-.IP
-\fBDefault:\fP
-\f(CW debug hires timestamp = No\fP
-.IP
-\fBExample:\fP
-\f(CW debug hires timestamp = Yes\fP
-.IP
.IP "\fBdebug timestamp (G)\fP"
.IP
Samba2\&.0 debug log messages are timestamped by default\&. If you are
@@ -1884,37 +1779,6 @@ off\&.
\fBExample:\fP
\f(CW debug timestamp = No\fP
.IP
-.IP "\fBdebug pid (G)\fP"
-.IP
-When using only one log file for more then one forked smbd-process
-there may be hard to follow which process outputs which message\&.
-This boolean parameter is adds the process-id to the timestamp message
-headers in the logfile when turned on\&.
-.IP
-Note that the parameter \fBdebug timestamp\fP
-must be on for this to have an effect\&.
-.IP
-\fBDefault:\fP
-\f(CW debug pid = No\fP
-.IP
-\fBExample:\fP
-\f(CW debug pid = Yes\fP
-.IP
-.IP "\fBdebug uid (G)\fP"
-.IP
-Samba is sometimes run as root and sometime run as the connected
-user, this boolean parameter inserts the current euid, egid, uid
-and gid to the timestamp message headers in the log file if turned on\&.
-.IP
-Note that the parameter \fBdebug timestamp\fP
-must be on for this to have an effect\&.
-.IP
-\fBDefault:\fP
-\f(CW debug uid = No\fP
-.IP
-\fBExample:\fP
-\f(CW debug uid = Yes\fP
-.IP
.IP "\fBdebug level (G)\fP"
.IP
The value of the parameter (an integer) allows the debug level
@@ -1972,59 +1836,6 @@ interesting things\&.
.IP
-.IP "\fBdelete user script (G)\fP"
-.IP
-This is the full pathname to a script that will be run \fIAS ROOT\fP by
-\fBsmbd (8)\fP under special circumstances decribed
-below\&.
-.IP
-Normally, a Samba server requires that UNIX users are created for all
-users accessing files on this server\&. For sites that use Windows NT
-account databases as their primary user database creating these users
-and keeping the user list in sync with the Windows NT PDC is an
-onerous task\&. This option allows \fBsmbd\fP to delete
-the required UNIX users \fION DEMAND\fP when a user accesses the Samba
-server and the Windows NT user no longer exists\&.
-.IP
-In order to use this option, \fBsmbd\fP must be set to
-\fBsecurity=domain\fP and \fB"delete user
-script"\fP must be set to a full pathname for a script that will delete
-a UNIX user given one argument of \fB%u\fP, which expands into the UNIX
-user name to delete\&. \fINOTE\fP that this is different to the
-\fBadd user script\fP which will work with the
-\fBsecurity=server\fP option as well as
-\fBsecurity=domain\fP\&. The reason for this
-is only when Samba is a domain member does it get the information
-on an attempted user logon that a user no longer exists\&. In the
-\fBsecurity=server\fP mode a missing user
-is treated the same as an invalid password logon attempt\&. Deleting
-the user in this circumstance would not be a good idea\&.
-.IP
-When the Windows user attempts to access the Samba server, at
-\fI"login"\fP(session setup in the SMB protocol) time,
-\fBsmbd\fP contacts the \fBpassword
-server\fP and attempts to authenticate the given user
-with the given password\&. If the authentication fails with the specific
-Domain error code meaning that the user no longer exists then
-\fBsmbd\fP attempts to find a UNIX user in the UNIX
-password database that matches the Windows user account\&. If this lookup succeeds,
-and \fB"delete user script"\fP is set then \fBsmbd\fP will
-call the specified script \fIAS ROOT\fP, expanding any \fB%u\fP argument
-to be the user name to delete\&.
-.IP
-This script should delete the given UNIX username\&. In this way, UNIX
-users are dynamically deleted to match existing Windows NT accounts\&.
-.IP
-See also \fBsecurity=domain\fP,
-\fBpassword server\fP, \fBadd user
-script\fP\&.
-.IP
-\fBDefault:\fP
-\f(CW delete user script = <empty string>\fP
-.IP
-\fBExample:\fP
-\f(CW delete user script = /usr/local/samba/bin/del_user %u\fP
-.IP
.IP "\fBdelete readonly (S)\fP"
.IP
This parameter allows readonly files to be deleted\&. This is not
@@ -2069,7 +1880,16 @@ See also the \fBveto files\fP parameter\&.
.IP
.IP "\fBdeny hosts (S)\fP"
.IP
-Synonym for \fBhosts deny\fP\&.
+The opposite of \fB\'allow hosts\'\fP - hosts listed
+here are \fINOT\fP permitted access to services unless the specific
+services have their own lists to override this one\&. Where the lists
+conflict, the \fB\'allow\'\fP list takes precedence\&.
+.IP
+\fBDefault:\fP
+\f(CW none (i\&.e\&., no hosts specifically excluded)\fP
+.IP
+\fBExample:\fP
+\f(CW deny hosts = 150\&.203\&.4\&. badhost\&.mynet\&.edu\&.au\fP
.IP
.IP "\fBdfree command (G)\fP"
.IP
@@ -2160,8 +1980,7 @@ See the \fB"force directory mode"\fP parameter
to cause particular mode bits to always be set on created directories\&.
.IP
See also the \fB"create mode"\fP parameter for masking
-mode bits on created files, and the \fB"directory security mask"\fP
-parameter\&.
+mode bits on created files\&.
.IP
\fBDefault:\fP
\f(CW directory mask = 0755\fP
@@ -2173,38 +1992,6 @@ parameter\&.
.IP
Synonym for \fBdirectory mask\fP\&.
.IP
-.IP "\fBdirectory security mask (S)\fP"
-.IP
-This parameter controls what UNIX permission bits can be modified
-when a Windows NT client is manipulating the UNIX permission on a
-directory using the native NT security dialog box\&.
-.IP
-This parameter is applied as a mask (AND\'ed with) to the changed
-permission bits, thus preventing any bits not in this mask from
-being modified\&. Essentially, zero bits in this mask may be treated
-as a set of bits the user is not allowed to change\&.
-.IP
-If not set explicitly this parameter is set to the same value as the
-\fBdirectory mask\fP parameter\&. To allow a user to
-modify all the user/group/world permissions on a directory, set this
-parameter to 0777\&.
-.IP
-\fINote\fP that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems\&. Administrators of
-most normal systems will probably want to set it to 0777\&.
-.IP
-See also the \fBforce directory security
-mode\fP, \fBsecurity
-mask\fP, \fBforce security mode\fP
-parameters\&.
-.IP
-\fBDefault:\fP
-\f(CW directory security mask = <same as directory mask>\fP
-.IP
-\fBExample:\fP
-\f(CW directory security mask = 0777\fP
-.IP
.IP "\fBdns proxy (G)\fP"
.IP
Specifies that \fBnmbd\fP when acting as a WINS
@@ -2228,7 +2015,7 @@ See also the parameter \fBwins support\fP\&.
\fBdomain admin group (G)\fP
.IP
This is an \fBEXPERIMENTAL\fP parameter that is part of the unfinished
-Samba NT Domain Controller Code\&. It may be removed in a later release\&.
+Samba NT Domain Controller Code\&. It has been removed as of November 98\&.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list \fBSamba-ntdom\fP available by sending email to
@@ -2237,7 +2024,7 @@ mailing list \fBSamba-ntdom\fP available by sending email to
.IP "\fBdomain admin users (G)\fP"
.IP
This is an \fBEXPERIMENTAL\fP parameter that is part of the unfinished
-Samba NT Domain Controller Code\&. It may be removed in a later release\&.
+Samba NT Domain Controller Code\&. It has been removed as of November 98\&.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list \fBSamba-ntdom\fP available by sending email to
@@ -2249,10 +2036,91 @@ This is a \fBDEPRECATED\fP parameter\&. It is currently not used within
the Samba source and should be removed from all current smb\&.conf
files\&. It is left behind for compatibility reasons\&.
.IP
+.IP "\fBdomain group map (G)\fP"
+.IP
+This option allows you to specify a file containing unique mappings
+of individual NT Domain Group names (in any domain) to UNIX group
+names\&. This allows NT domain groups to be presented correctly to
+NT users, despite the lack of native support for the NT Security model
+(based on VAX/VMS) in UNIX\&. The reader is advised to become familiar
+with the NT Domain system and its administration\&.
+.IP
+This option is used in conjunction with \fB\'local group map\'\fP
+and \fB\'domain user map\'\fP\&. The use of these three
+options is trivial and often unnecessary in the case where Samba is
+not expected to interact with any other SAM databases (whether local
+workstations or Domain Controllers)\&.
+.IP
+The map file is parsed line by line\&. If any line begins with a \f(CW\'#\'\fP
+or a \f(CW\';\'\fP then it is ignored\&. Each line should contain a single UNIX
+group name on the left then a single NT Domain Group name on the right,
+separated by a tabstop or \f(CW\'=\'\fP\&. If either name contains spaces then
+it should be enclosed in quotes\&.
+The line can be either of the form:
+.IP
+\f(CW UNIXgroupname \e\eDOMAIN_NAME\e\eDomainGroupName \fP
+.IP
+or:
+.IP
+\f(CW UNIXgroupname DomainGroupName \fP
+.IP
+In the case where Samba is either an \fBEXPERIMENTAL\fP Domain Controller
+or it is a member of a domain using \fB"security = domain"\fP,
+the latter format can be used: the default Domain name is the Samba Server\'s
+Domain name, specified by \fB"workgroup = MYGROUP"\fP\&.
+.IP
+Any UNIX groups that are \fINOT\fP specified in this map file are assumed to
+be either Local or Domain Groups, depending on the role of the Samba Server\&.
+.IP
+In the case when Samba is an \fBEXPERIMENTAL\fP Domain Controller, Samba
+will present \fIALL\fP such unspecified UNIX groups as its own NT Domain
+Groups, with the same name\&.
+.IP
+In the case where Samba is member of a domain using
+\fB"security = domain"\fP, Samba will check the UNIX name with
+its Domain Controller (see \fB"password server"\fP)
+as if it was an NT Domain Group\&. If the Domain Controller says that it is not,
+such unspecified (unmapped) UNIX groups which also are not NT Domain
+Groups are treated as Local Groups in the Samba Server\'s local SAM database\&.
+NT Administrators will recognise these as Workstation Local Groups,
+which are managed by running \fBUSRMGR\&.EXE\fP and selecting a remote
+Domain named "\e\eWORKSTATION_NAME", or by running \fBMUSRMGR\&.EXE\fP on
+a local Workstation\&.
+.IP
+This may sound complicated, but it means that a Samba Server as
+either a member of a domain or as an \fBEXPERIMENTAL\fP Domain Controller
+will act like an NT Workstation (with a local SAM database) or an NT PDC
+(with a Domain SAM database) respectively, without the need for any of
+the map files at all\&. If you \fBwant\fP to get fancy, however, you can\&.
+.IP
+Note that adding an entry to map an arbitrary NT group in an arbitrary
+Domain to an arbitrary UNIX group \fIREQUIRES\fP the following:
+.IP
+.IP
+.IP o
+that the UNIX group exists on the UNIX server\&.
+.IP
+.IP o
+that the NT Domain Group exists in the specified NT Domain
+.IP
+.IP o
+that the UNIX Server knows about the specified Domain;
+.IP
+.IP o
+that all the UNIX users (who are expecting to access the Samba
+Server as the correct NT user and with the correct NT group permissions)
+in the UNIX group be mapped to the correct NT Domain users in the specified
+NT Domain using \fB\'domain user map\'\fP\&.
+.IP
+.IP
+Failure to meet any of these requirements may result in either (or
+both) errors reported in the log files or (and) incorrect or missing
+access rights granted to users\&.
+.IP
.IP "\fBdomain groups (G)\fP"
.IP
This is an \fBEXPERIMENTAL\fP parameter that is part of the unfinished
-Samba NT Domain Controller Code\&. It may be removed in a later release\&.
+Samba NT Domain Controller Code\&. It has been removed as of November 98\&.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list \fBSamba-ntdom\fP available by sending email to
@@ -2261,7 +2129,7 @@ mailing list \fBSamba-ntdom\fP available by sending email to
.IP "\fBdomain guest group (G)\fP"
.IP
This is an \fBEXPERIMENTAL\fP parameter that is part of the unfinished
-Samba NT Domain Controller Code\&. It may be removed in a later release\&.
+Samba NT Domain Controller Code\&. It has been removed as of November 98\&.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list \fBSamba-ntdom\fP available by sending email to
@@ -2270,7 +2138,7 @@ mailing list \fBSamba-ntdom\fP available by sending email to
.IP "\fBdomain guest users (G)\fP"
.IP
This is an \fBEXPERIMENTAL\fP parameter that is part of the unfinished
-Samba NT Domain Controller Code\&. It may be removed in a later release\&.
+Samba NT Domain Controller Code\&. It has been removed as of November 98\&.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list \fBSamba-ntdom\fP available by sending email to
@@ -2316,9 +2184,95 @@ special name for a \fBworkgroup\fP before a Windows NT
PDC is able to do so then cross subnet browsing will behave strangely
and may fail\&.
.IP
+By default ("auto") Samba will attempt to become the domain master
+browser only if it is the Primary Domain Controller\&.
+.IP
\fBDefault:\fP
+\f(CW domain master = auto\fP
+.IP
+\fBExample:\fP
\f(CW domain master = no\fP
.IP
+.IP "\fBdomain user map (G)\fP"
+.IP
+This option allows you to specify a file containing unique mappings
+of individual NT Domain User names (in any domain) to UNIX user
+names\&. This allows NT domain users to be presented correctly to
+NT systems, despite the lack of native support for the NT Security model
+(based on VAX/VMS) in UNIX\&. The reader is advised to become familiar
+with the NT Domain system and its administration\&.
+.IP
+This option is used in conjunction with \fB\'local group map\'\fP
+and \fB\'domain group map\'\fP\&. The use of these three
+options is trivial and often unnecessary in the case where Samba is
+not expected to interact with any other SAM databases (whether local
+workstations or Domain Controllers)\&.
+.IP
+This option, which provides (and maintains) a one-to-one link between
+UNIX and NT users, is \fIDIFFERENT\fP from \fB\'username map\'\fP, which does \fINOT\fP maintain a distinction between the
+name(s) it can map to and the name it maps\&.
+.IP
+The map file is parsed line by line\&. If any line begins with a \f(CW\'#\'\fP
+or a \f(CW\';\'\fP then the line is ignored\&. Each line should contain a single UNIX
+user name on the left then a single NT Domain User name on the right,
+separated by a tabstop or \f(CW\'=\'\fP\&. If either name contains spaces then
+it should be enclosed in quotes\&.
+The line can be either of the form:
+.IP
+\f(CW UNIXusername \e\eDOMAIN_NAME\e\eDomainUserName \fP
+.IP
+or:
+.IP
+\f(CW UNIXusername DomainUserName \fP
+.IP
+In the case where Samba is either an \fBEXPERIMENTAL\fP Domain Controller
+or it is a member of a domain using \fB"security = domain"\fP,
+the latter format can be used: the default Domain name is the Samba Server\'s
+Domain name, specified by \fB"workgroup = MYGROUP"\fP\&.
+.IP
+Any UNIX users that are \fINOT\fP specified in this map file are assumed
+to be either Domain or Workstation Users, depending on the role of the
+Samba Server\&.
+.IP
+In the case when Samba is an \fBEXPERIMENTAL\fP Domain Controller, Samba
+will present \fIALL\fP such unspecified UNIX users as its own NT Domain
+Users, with the same name\&.
+.IP
+In the case where Samba is a member of a domain using
+\fB"security = domain"\fP, Samba will check the UNIX name with
+its Domain Controller (see \fB"password server"\fP)
+as if it was an NT Domain User\&. If the Domain Controller says that it is not,
+such unspecified (unmapped) UNIX users which also are not NT Domain
+Users are treated as Local Users in the Samba Server\'s local SAM database\&.
+NT Administrators will recognise these as Workstation Users,
+which are managed by running \fBUSRMGR\&.EXE\fP and selecting a remote
+Domain named "\e\eWORKSTATION_NAME", or by running \fBMUSRMGR\&.EXE\fP on
+a local Workstation\&.
+.IP
+This may sound complicated, but it means that a Samba Server as
+either a member of a domain or as an \fBEXPERIMENTAL\fP Domain Controller
+will act like an NT Workstation (with a local SAM database) or an NT PDC
+(with a Domain SAM database) respectively, without the need for any of
+the map files at all\&. If you \fBwant\fP to get fancy, however, you can\&.
+.IP
+Note that adding an entry to map an arbitrary NT User in an arbitrary
+Domain to an arbitrary UNIX user \fIREQUIRES\fP the following:
+.IP
+.IP
+.IP o
+that the UNIX user exists on the UNIX server\&.
+.IP
+.IP o
+that the NT Domain User exists in the specified NT Domain\&.
+.IP
+.IP o
+that the UNIX Server knows about the specified Domain\&.
+.IP
+.IP
+Failure to meet any of these requirements may result in either (or
+both) errors reported in the log files or (and) incorrect or missing
+access rights granted to users\&.
+.IP
.IP "\fBdont descend (S)\fP"
.IP
There are certain directories on some systems (e\&.g\&., the \f(CW/proc\fP tree
@@ -2516,38 +2470,6 @@ would force all created directories to have read and execute
permissions set for \'group\' and \'other\' as well as the
read/write/execute bits set for the \'user\'\&.
.IP
-.IP "\fBforce directory security mode (S)\fP"
-.IP
-This parameter controls what UNIX permission bits can be modified when
-a Windows NT client is manipulating the UNIX permission on a directory
-using the native NT security dialog box\&.
-.IP
-This parameter is applied as a mask (OR\'ed with) to the changed
-permission bits, thus forcing any bits in this mask that the user may
-have modified to be on\&. Essentially, one bits in this mask may be
-treated as a set of bits that, when modifying security on a directory,
-the user has always set to be \'on\'\&.
-.IP
-If not set explicitly this parameter is set to the same value as the
-\fBforce directory mode\fP parameter\&. To allow
-a user to modify all the user/group/world permissions on a directory,
-with restrictions set this parameter to 000\&.
-.IP
-\fINote\fP that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems\&. Administrators of
-most normal systems will probably want to set it to 0000\&.
-.IP
-See also the \fBdirectory security mask\fP,
-\fBsecurity mask\fP, \fBforce security
-mode\fP parameters\&.
-.IP
-\fBDefault:\fP
-\f(CW force directory security mode = <same as force directory mode>\fP
-.IP
-\fBExample:\fP
-\f(CW force directory security mode = 0\fP
-.IP
.IP "\fBforce group (S)\fP"
.IP
This specifies a UNIX group name that will be assigned as the default
@@ -2558,63 +2480,12 @@ permissions for this group to the files and directories within this
service the Samba administrator can restrict or allow sharing of these
files\&.
.IP
-In Samba 2\&.0\&.5 and above this parameter has extended functionality in the following
-way\&. If the group name listed here has a \'+\' character prepended to it
-then the current user accessing the share only has the primary group
-default assigned to this group if they are already assigned as a member
-of that group\&. This allows an administrator to decide that only users
-who are already in a particular group will create files with group
-ownership set to that group\&. This gives a finer granularity of ownership
-assignment\&. For example, the setting \f(CWforce group = +sys\fP means
-that only users who are already in group sys will have their default
-primary group assigned to sys when accessing this Samba share\&. All
-other users will retain their ordinary primary group\&.
-.IP
-If the \fB"force user"\fP parameter is also set the
-group specified in \fBforce group\fP will override the primary group
-set in \fB"force user"\fP\&.
-.IP
-See also \fB"force user"\fP
-.IP
\fBDefault:\fP
\f(CW no forced group\fP
.IP
\fBExample:\fP
\f(CW force group = agroup\fP
.IP
-.IP "\fBforce security mode (S)\fP"
-.IP
-This parameter controls what UNIX permission bits can be modified when
-a Windows NT client is manipulating the UNIX permission on a file
-using the native NT security dialog box\&.
-.IP
-This parameter is applied as a mask (OR\'ed with) to the changed
-permission bits, thus forcing any bits in this mask that the user may
-have modified to be on\&. Essentially, one bits in this mask may be
-treated as a set of bits that, when modifying security on a file, the
-user has always set to be \'on\'\&.
-.IP
-If not set explicitly this parameter is set to the same value as the
-\fBforce create mode\fP parameter\&. To allow
-a user to modify all the user/group/world permissions on a file,
-with no restrictions set this parameter to 000\&.
-.IP
-\fINote\fP that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems\&. Administrators of
-most normal systems will probably want to set it to 0000\&.
-.IP
-See also the \fBforce directory security
-mode\fP, \fBdirectory security
-mask\fP, \fBsecurity mask\fP
-parameters\&.
-.IP
-\fBDefault:\fP
-\f(CW force security mode = <same as force create mode>\fP
-.IP
-\fBExample:\fP
-\f(CW force security mode = 0\fP
-.IP
.IP "\fBforce user (S)\fP"
.IP
This specifies a UNIX user name that will be assigned as the default
@@ -2629,13 +2500,6 @@ password\&. Once connected, all file operations will be performed as the
.IP
This can be very useful\&.
.IP
-In Samba 2\&.0\&.5 and above this parameter also causes the primary
-group of the forced user to be used as the primary group for all
-file activity\&. Prior to 2\&.0\&.5 the primary group was left as the
-primary group of the connecting user (this was a bug)\&.
-.IP
-See also \fB"force group"\fP
-.IP
\fBDefault:\fP
\f(CW no forced user\fP
.IP
@@ -2807,72 +2671,11 @@ logons\fP\&.
.IP
.IP "\fBhosts allow (S)\fP"
.IP
-A synonym for this parameter is \fB\'allow hosts\'\fP
-.IP
-This parameter is a comma, space, or tab delimited set of hosts which
-are permitted to access a service\&.
-.IP
-If specified in the \fB[global]\fP section then it will
-apply to all services, regardless of whether the individual service
-has a different setting\&.
-.IP
-You can specify the hosts by name or IP number\&. For example, you could
-restrict access to only the hosts on a Class C subnet with something
-like \f(CW"allow hosts = 150\&.203\&.5\&."\fP\&. The full syntax of the list is
-described in the man page \fBhosts_access (5)\fP\&. Note that this man
-page may not be present on your system, so a brief description will
-be given here also\&.
-.IP
-Note that the localhost address 127\&.0\&.0\&.1 will always be allowed
-access unless specifically denied by a "hosts deny" option\&.
-.IP
-You can also specify hosts by network/netmask pairs and by netgroup
-names if your system supports netgroups\&. The \fIEXCEPT\fP keyword can also
-be used to limit a wildcard list\&. The following examples may provide
-some help:
-.IP
-\fBExample 1\fP: allow all IPs in 150\&.203\&.*\&.* except one
-.IP
-\f(CW hosts allow = 150\&.203\&. EXCEPT 150\&.203\&.6\&.66\fP
-.IP
-\fBExample 2\fP: allow hosts that match the given network/netmask
-.IP
-\f(CW hosts allow = 150\&.203\&.15\&.0/255\&.255\&.255\&.0\fP
-.IP
-\fBExample 3\fP: allow a couple of hosts
-.IP
-\f(CW hosts allow = lapland, arvidsjaur\fP
-.IP
-\fBExample 4\fP: allow only hosts in NIS netgroup "foonet", but
-deny access from one particular host
-.IP
-\f(CW hosts allow = @foonet\fP
-.IP
-\f(CW hosts deny = pirate\fP
-.IP
-Note that access still requires suitable user-level passwords\&.
-.IP
-See \fBtestparm (1)\fP for a way of testing your
-host access to see if it does what you expect\&.
-.IP
-\fBDefault:\fP
-\f(CW none (i\&.e\&., all hosts permitted access)\fP
-.IP
-\fBExample:\fP
-\f(CW allow hosts = 150\&.203\&.5\&. myhost\&.mynet\&.edu\&.au\fP
+Synonym for \fBallow hosts\fP\&.
.IP
.IP "\fBhosts deny (S)\fP"
.IP
-The opposite of \fB\'hosts allow\'\fP - hosts listed
-here are \fINOT\fP permitted access to services unless the specific
-services have their own lists to override this one\&. Where the lists
-conflict, the \fB\'allow\'\fP list takes precedence\&.
-.IP
-\fBDefault:\fP
-\f(CW none (i\&.e\&., no hosts specifically excluded)\fP
-.IP
-\fBExample:\fP
-\f(CW hosts deny = 150\&.203\&.4\&. badhost\&.mynet\&.edu\&.au\fP
+Synonym for \fBdenyhosts\fP\&.
.IP
.IP "\fBhosts equiv (G)\fP"
.IP
@@ -2880,7 +2683,7 @@ If this global parameter is a non-null string, it specifies the name
of a file to read for the names of hosts and users who will be allowed
access without specifying a password\&.
.IP
-This is not be confused with \fBhosts allow\fP which
+This is not be confused with \fBallow hosts\fP which
is about hosts access to services and is more useful for guest
services\&. \fBhosts equiv\fP may be useful for NT clients which will not
supply passwords to samba\&.
@@ -2908,38 +2711,28 @@ It takes the standard substitutions, except \fB%u\fP,
.IP
.IP "\fBinterfaces (G)\fP"
.IP
-This option allows you to override the default network interfaces list
-that Samba will use for browsing, name registration and other NBT
-traffic\&. By default Samba will query the kernel for the list of all
-active interfaces and use any interfaces except 127\&.0\&.0\&.1 that are
-broadcast capable\&.
+This option allows you to setup multiple network interfaces, so that
+Samba can properly handle browsing on all interfaces\&.
.IP
-The option takes a list of interface strings\&. Each string can be in
-any of the following forms:
+The option takes a list of ip/netmask pairs\&. The netmask may either be
+a bitmask, or a bitlength\&.
.IP
-.IP o
-a network interface name (such as eth0)\&. This may include
-shell-like wildcards so eth* will match any interface starting
-with the substring "eth"
-if() a IP address\&. In this case the netmask is determined
-from the list of interfaces obtained from the kernel
-if() a IP/mask pair\&.
-if() a broadcast/mask pair\&.
+For example, the following line:
.IP
-The "mask" parameters can either be a bit length (such as 24 for a C
-class network) or a full netmask in dotted decmal form\&.
+\f(CWinterfaces = 192\&.168\&.2\&.10/24 192\&.168\&.3\&.10/24\fP
.IP
-The "IP" parameters above can either be a full dotted decimal IP
-address or a hostname which will be looked up via the OSes normal
-hostname resolution mechanisms\&.
+would configure two network interfaces with IP addresses 192\&.168\&.2\&.10
+and 192\&.168\&.3\&.10\&. The netmasks of both interfaces would be set to
+255\&.255\&.255\&.0\&.
.IP
-For example, the following line:
+You could produce an equivalent result by using:
+.IP
+\f(CWinterfaces = 192\&.168\&.2\&.10/255\&.255\&.255\&.0 192\&.168\&.3\&.10/255\&.255\&.255\&.0\fP
.IP
-\f(CWinterfaces = eth0 192\&.168\&.2\&.10/24 192\&.168\&.3\&.10/255\&.255\&.255\&.0\fP
+if you prefer that format\&.
.IP
-would configure three network interfaces corresponding to the eth0
-device and IP addresses 192\&.168\&.2\&.10 and 192\&.168\&.3\&.10\&. The netmasks of
-the latter two interfaces would be set to 255\&.255\&.255\&.0\&.
+If this option is not set then Samba will attempt to find a primary
+interface, but won\'t attempt to configure more than one interface\&.
.IP
See also \fB"bind interfaces only"\fP\&.
.IP
@@ -2988,10 +2781,10 @@ options"\fP)\&. Basically you should only use this option
if you strike difficulties\&.
.IP
\fBDefault:\fP
-\f(CW keepalive = 0\fP
+\f(CW keep alive = 0\fP
.IP
\fBExample:\fP
-\f(CW keepalive = 60\fP
+\f(CW keep alive = 60\fP
.IP
.IP "\fBkernel oplocks (G)\fP"
.IP
@@ -3009,72 +2802,52 @@ This parameter defaults to \fI"On"\fP on systems that have the support,
and \fI"off"\fP on systems that don\'t\&. You should never need to touch
this parameter\&.
.IP
-See also the \fB"oplocks"\fP and \fB"level2 oplocks"\fP
-parameters\&.
-.IP
-.IP "\fBldap filter (G)\fP"
+.IP "\fBldap bind as (G)\fP"
.IP
This parameter is part of the \fIEXPERIMENTAL\fP Samba support for a
-password database stored on an LDAP server back-end\&. These options
-are only available if your version of Samba was configured with
-the \fB--with-ldap\fP option\&.
+password database stored on an LDAP server\&. These options are only
+available if your version of Samba was configured with the \fB--with-ldap\fP
+option\&.
.IP
-This parameter specifies an LDAP search filter used to search for a
-user name in the LDAP database\&. It must contain the string
-\fB%u\fP which will be replaced with the user being
-searched for\&.
+This parameter specifies the entity to bind to an LDAP directory as\&.
+Usually it should be safe to use the LDAP root account; for larger
+installations it may be preferable to restrict Samba\'s access\&. See also
+\fBldap passwd file\fP\&.
.IP
\fBDefault:\fP
-\f(CW empty string\&.\fP
-.IP
-.IP "\fBldap port (G)\fP"
-.IP
-This parameter is part of the \fIEXPERIMENTAL\fP Samba support for a
-password database stored on an LDAP server back-end\&. These options
-are only available if your version of Samba was configured with
-the \fB--with-ldap\fP option\&.
-.IP
-This parameter specifies the TCP port number to use to contact
-the LDAP server on\&.
+\f(CW none (bind anonymously)\fP
.IP
-\fBDefault:\fP
-\f(CW ldap port = 389\&.\fP
+\fBExample:\fP
+\f(CW ldap bind as = "uid=root, dc=mydomain, dc=org"\fP
.IP
-.IP "\fBldap root (G)\fP"
+.IP "\fBldap passwd file (G)\fP"
.IP
This parameter is part of the \fIEXPERIMENTAL\fP Samba support for a
-password database stored on an LDAP server back-end\&. These options
-are only available if your version of Samba was configured with
-the \fB--with-ldap\fP option\&.
-.IP
-This parameter specifies the entity to bind to the LDAP server
-as (essentially the LDAP username) in order to be able to perform
-queries and modifications on the LDAP database\&.
+password database stored on an LDAP server\&. These options are only
+available if your version of Samba was configured with the \fB--with-ldap\fP
+option\&.
.IP
-See also \fBldap root passwd\fP\&.
+This parameter specifies a file containing the password with which
+Samba should bind to an LDAP server\&. For obvious security reasons
+this file must be set to mode 700 or less\&.
.IP
\fBDefault:\fP
-\f(CW empty string (no user defined)\fP
+\f(CW none (bind anonymously)\fP
.IP
-.IP "\fBldap root passwd (G)\fP"
-.IP
-This parameter is part of the \fIEXPERIMENTAL\fP Samba support for a
-password database stored on an LDAP server back-end\&. These options
-are only available if your version of Samba was configured with
-the \fB--with-ldap\fP option\&.
+\fBExample:\fP
+\f(CW ldap passwd file = /usr/local/samba/private/ldappasswd\fP
.IP
-This parameter specifies the password for the entity to bind to the
-LDAP server as (the password for this LDAP username) in order to be
-able to perform queries and modifications on the LDAP database\&.
+.IP "\fBldap port (G)\fP"
.IP
-\fIBUGS:\fP This parameter should \fINOT\fP be a readable parameter
-in the \fBsmb\&.conf\fP file and will be removed once a correct
-storage place is found\&.
+This parameter is part of the \fIEXPERIMENTAL\fP Samba support for a
+password database stored on an LDAP server\&. These options are only
+available if your version of Samba was configured with the \fB--with-ldap\fP
+option\&.
.IP
-See also \fBldap root\fP\&.
+This parameter specifies the TCP port number of the LDAP server\&.
.IP
\fBDefault:\fP
-\f(CW empty string\&.\fP
+\f(CW ldap port = 389\&.\fP
.IP
.IP "\fBldap server (G)\fP"
.IP
@@ -3084,7 +2857,8 @@ are only available if your version of Samba was configured with
the \fB--with-ldap\fP option\&.
.IP
This parameter specifies the DNS name of the LDAP server to use
-for SMB/CIFS authentication purposes\&.
+when storing and retrieving information about Samba users and
+groups\&.
.IP
\fBDefault:\fP
\f(CW ldap server = localhost\fP
@@ -3096,52 +2870,15 @@ password database stored on an LDAP server back-end\&. These options
are only available if your version of Samba was configured with
the \fB--with-ldap\fP option\&.
.IP
-This parameter specifies the \f(CW"dn"\fP or LDAP \fI"distinguished name"\fP
-that tells \fBsmbd\fP to start from when searching
-for an entry in the LDAP password database\&.
+This parameter specifies the node of the LDAP tree beneath which
+Samba should store its information\&. This parameter MUST be provided
+when using LDAP with Samba\&.
.IP
\fBDefault:\fP
-\f(CW empty string\&.\fP
-.IP
-.IP "\fBlevel2 oplocks (S)\fP"
-.IP
-This parameter (new in Samba 2\&.0\&.5) controls whether Samba supports
-level2 (read-only) oplocks on a share\&. In Samba 2\&.0\&.4 this parameter
-defaults to "False" as the code is new, but will default to "True"
-in a later release\&.
-.IP
-Level2, or read-only oplocks allow Windows NT clients that have an
-oplock on a file to downgrade from a read-write oplock to a read-only
-oplock once a second client opens the file (instead of releasing all
-oplocks on a second open, as in traditional, exclusive oplocks)\&. This
-allows all openers of the file that support level2 oplocks to cache
-the file for read-ahead only (ie\&. they may not cache writes or lock
-requests) and increases performance for many acesses of files that
-are not commonly written (such as application \&.EXE files)\&.
-.IP
-Once one of the clients which have a read-only oplock writes to
-the file all clients are notified (no reply is needed or waited
-for) and told to break their oplocks to "none" and delete any
-read-ahead caches\&.
-.IP
-It is recommended that this parameter be turned on to speed access
-to shared executables (and also to test the code :-)\&.
-.IP
-For more discussions on level2 oplocks see the CIFS spec\&.
-.IP
-Currently, if \fB"kernel oplocks"\fP are supported
-then level2 oplocks are not granted (even if this parameter is set
-to \f(CW"true"\fP)\&. Note also, the \fB"oplocks"\fP parameter must
-be set to "true" on this share in order for this parameter to have any
-effect\&.
-.IP
-See also the \fB"oplocks"\fP and \fB"kernel oplocks"\fP parameters\&.
-.IP
-\fBDefault:\fP
-\f(CW level2 oplocks = False\fP
+\f(CW none\fP
.IP
\fBExample:\fP
-\f(CW level2 oplocks = True\fP
+\f(CW ldap suffix = "dc=mydomain, dc=org"\fP
.IP
.IP "\fBlm announce (G)\fP"
.IP
@@ -3194,6 +2931,87 @@ will be loaded for browsing by default\&. See the
\fBExample:\fP
\f(CW load printers = no\fP
.IP
+.IP "\fBlocal group map (G)\fP"
+.IP
+This option allows you to specify a file containing unique mappings
+of individual NT Local Group names (in any domain) to UNIX group
+names\&. This allows NT Local groups (aliases) to be presented correctly to
+NT users, despite the lack of native support for the NT Security model
+(based on VAX/VMS) in UNIX\&. The reader is advised to become familiar
+with the NT Domain system and its administration\&.
+.IP
+This option is used in conjunction with \fB\'domain group map\'\fP
+and \fB\'domain name map\'\fP\&. The use of these three
+options is trivial and often unnecessary in the case where Samba
+is not expected to interact with any other SAM databases (whether local
+workstations or Domain Controllers)\&.
+.IP
+The map file is parsed line by line\&. If any line begins with a \f(CW\'#\'\fP
+or a \f(CW\';\'\fP then it is ignored\&. Each line should contain a single UNIX
+group name on the left then a single NT Local Group name on the right,
+separated by a tabstop or \f(CW\'=\'\fP\&. If either name contains spaces then
+it should be enclosed in quotes\&.
+The line can be either of the form:
+.IP
+\f(CW UNIXgroupname \e\eDOMAIN_NAME\e\eLocalGroupName \fP
+.IP
+or:
+.IP
+\f(CW UNIXgroupname LocalGroupName \fP
+.IP
+In the case where Samba is either an \fBEXPERIMENTAL\fP Domain Controller
+or it is a member of a domain using \fB"security = domain"\fP,
+the latter format can be used: the default Domain name is the Samba Server\'s
+Domain name, specified by \fB"workgroup = MYGROUP"\fP\&.
+.IP
+Any UNIX groups that are \fINOT\fP specified in this map file are treated
+as either Local or Domain Groups depending on the role of the Samba Server\&.
+.IP
+In the case when Samba is an \fBEXPERIMENTAL\fP Domain Controller, Samba
+will present \fIALL\fP unspecified UNIX groups as its own NT Domain
+Groups, with the same name, and \fINOT\fP as Local Groups\&.
+.IP
+In the case where Samba is member of a domain using
+\fB"security = domain"\fP, Samba will check the UNIX name with
+its Domain Controller (see \fB"password server"\fP)
+as if it was an NT Domain Group\&. If the Domain Controller says that it is not,
+such unspecified (unmapped) UNIX groups which also are not NT Domain
+Groups are treated as Local Groups in the Samba Server\'s local SAM database\&.
+NT Administrators will recognise these as Workstation Local Groups,
+which are managed by running \fBUSRMGR\&.EXE\fP and selecting a remote
+Domain named "\e\eWORKSTATION_NAME", or by running \fBMUSRMGR\&.EXE\fP on
+a local Workstation\&.
+.IP
+This may sound complicated, but it means that a Samba Server as
+either a member of a domain or as an \fBEXPERIMENTAL\fP Domain Controller
+will act like an NT Workstation (with a local SAM database) or an NT PDC
+(with a Domain SAM database) respectively, without the need for any of
+the map files at all\&. If you \fBwant\fP to get fancy, however, you can\&.
+.IP
+Note that adding an entry to map an arbitrary NT group in an arbitrary
+Domain to an arbitrary UNIX group \fIREQUIRES\fP the following:
+.IP
+.IP
+.IP o
+that the UNIX group exists on the UNIX server\&.
+.IP
+.IP o
+that the NT Domain Group exists in the specified NT Domain
+.IP
+.IP o
+that the UNIX Server knows about the specified Domain;
+.IP
+.IP o
+that all the UNIX users (who are expecting to access the Samba
+Server as the correct NT user and with the correct NT group permissions)
+in the UNIX group be mapped to the correct NT Domain users in the specified
+NT Domain using \fB\'domain user map\'\fP\&.
+.IP
+.IP
+Failure to meet any of these requirements may result in either (or
+both) errors reported in the log files or (and) incorrect or missing
+access rights granted to users\&.
+.IP
.IP "\fBlocal master (G)\fP"
.IP
This option allows \fBnmbd\fP to try and become a
@@ -3598,12 +3416,6 @@ Magic scripts are \fIEXPERIMENTAL\fP and should \fINOT\fP be relied upon\&.
.IP
See the section on \fB"NAME MANGLING"\fP\&.
.IP
-.IP "\fBmangle locks (S)\fP"
-.IP
-This option is was introduced with Samba 2\&.0\&.4 and above and has been
-removed in Samba 2\&.0\&.6 as Samba now dynamically configures such things
-on 32 bit systems\&.
-.IP
.IP "\fBmangled map (S)\fP"
.IP
This is for those who want to directly map UNIX file names which can
@@ -3896,7 +3708,7 @@ never need to set this parameter\&.
\fBDefault:\fP
\f(CW max mux = 50\fP
.IP
-.IP "\fBmax open files (G)\fP"
+.IP "\fBmaxopenfiles (G)\fP"
.IP
This parameter limits the maximum number of open files that one
\fBsmbd\fP file serving process may have open for
@@ -4025,18 +3837,6 @@ See also the \fBprinting\fP parameter\&.
\fBExample:\fP
\f(CW min print space = 2000\fP
.IP
-.IP "\fBmin passwd length (G)\fP"
-.IP
-This option sets the minimum length in characters of a plaintext password
-than smbd will accept when performing UNIX password changing\&.
-.IP
-See also \fB"unix password sync"\fP,
-\fB"passwd program"\fP and \fB"passwd chat
-debug"\fP\&.
-.IP
-\fBDefault:\fP
-\f(CW min passwd length = 5\fP
-.IP
.IP "\fBmin wins ttl (G)\fP"
.IP
This option tells \fBnmbd\fP when acting as a WINS
@@ -4061,17 +3861,12 @@ names to be resolved as follows :
.IP
.IP o
\fBlmhosts\fP : Lookup an IP address in the Samba lmhosts file\&.
-If the line in lmhosts has no name type attached to the NetBIOS
-name (see the \fBlmhosts (5)\fP for details) then
-any name type matches for lookup\&.
.IP
.IP o
\fBhost\fP : Do a standard host name to IP address resolution,
using the system /etc/hosts, NIS, or DNS lookups\&. This method of name
resolution is operating system depended for instance on IRIX or
Solaris this may be controlled by the \fI/etc/nsswitch\&.conf\fP file)\&.
-Note that this method is only used if the NetBIOS name type being
-queried is the 0x20 (server) name type, otherwise it is ignored\&.
.IP
.IP o
\fBwins\fP : Query a name with the IP address listed in the
@@ -4160,17 +3955,6 @@ system and the Samba server with this option must also be a
\fBExample:\fP
\f(CW nis homedir = true\fP
.IP
-.IP "\fBnt acl support (G)\fP"
-.IP
-This boolean parameter controls whether \fBsmbd\fP
-will attempt to map UNIX permissions into Windows NT access control lists\&.
-.IP
-\fBDefault:\fP
-\f(CW nt acl support = yes\fP
-.IP
-\fBExample:\fP
-\f(CW nt acl support = no\fP
-.IP
.IP "\fBnt pipe support (G)\fP"
.IP
This boolean parameter controls whether \fBsmbd\fP
@@ -4268,58 +4052,24 @@ all access to oplocked files, whether it be via Samba or NFS or a local
UNIX process\&. See the \fBkernel oplocks\fP parameter
for details\&.
.IP
-See also the \fB"kernel oplocks"\fP and
-\fB"level2 oplocks"\fP parameters\&.
-.IP
\fBDefault:\fP
\f(CW oplocks = True\fP
.IP
\fBExample:\fP
\f(CW oplocks = False\fP
.IP
-.IP "\fBoplock break wait time (G)\fP"
-.IP
-This is a tuning parameter added due to bugs in both Windows 9x and WinNT\&.
-If Samba responds to a client too quickly when that client issues an SMB that
-can cause an oplock break request, then the client redirector can fail and
-not respond to the break request\&. This tuning parameter (which is set in
-milliseconds) is the amount of time Samba will wait before sending an
-oplock break request to such (broken) clients\&.
-.IP
-\fIDO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
-OPLOCK CODE\fP\&.
-.IP
-\fBDefault:\fP
-\f(CW oplock break wait time = 10\fP
-.IP
-.IP "\fBoplock contention limit (S)\fP"
-.IP
-This is a \fIvery\fP advanced \fBsmbd\fP tuning option to improve
-the efficiency of the granting of oplocks under multiple client contention for the same file\&.
-.IP
-In brief it specifies a number, which causes smbd not to grant an oplock even
-when requested if the approximate number of clients contending for an oplock on
-the same file goes over this limit\&. This causes \fBsmbd\fP to
-behave in a similar way to Windows NT\&.
-.IP
-\fIDO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
-OPLOCK CODE\fP\&.
-.IP
-\fBDefault:\fP
-\f(CW oplock contention limit = 2\fP
-.IP
.IP "\fBos level (G)\fP"
.IP
This integer value controls what level Samba advertises itself as for
browse elections\&. The value of this parameter determines whether
\fBnmbd\fP has a chance of becoming a local master
browser for the \fBWORKGROUP\fP in the local broadcast
-area\&. The default is zero, which means \fBnmbd\fP will
-lose elections to Windows machines\&. See BROWSING\&.txt in the Samba
-docs/ directory for details\&.
+area\&. Setting this to zero will cause \fBnmbd\fP to
+always lose elections to Windows machines\&. See BROWSING\&.txt in the
+Samba docs/ directory for details\&.
.IP
\fBDefault:\fP
-\f(CW os level = 20\fP
+\f(CW os level = 32\fP
.IP
\fBExample:\fP
\f(CW os level = 65 ; This will win against any NT Server\fP
@@ -4526,7 +4276,7 @@ better restrict them with hosts allow!
If the \fB"security"\fP parameter is set to
\fB"domain"\fP, then the list of machines in this option must be a list
of Primary or Backup Domain controllers for the
-\fBDomain\fP or the character \f(CW*\fP, as the Samba server is cryptographicly
+\fBDomain\fP, as the Samba server is cryptographicly
in that domain, and will use cryptographicly authenticated RPC calls
to authenticate the user logging on\&. The advantage of using
\fB"security=domain"\fP is that if you list
@@ -4534,12 +4284,6 @@ several hosts in the \fB"password server"\fP option then
\fBsmbd\fP will try each in turn till it finds one
that responds\&. This is useful in case your primary server goes down\&.
.IP
-If the \fB"password server"\fP option is set to the character \f(CW*\fP,
-then Samba will attempt to auto-locate the Primary or Backup Domain controllers
-to authenticate against by doing a query for the name \f(CWWORKGROUP<1C>\fP
-and then contacting each server returned in the list of IP addresses
-from the \fBname resolution\fP source\&.
-.IP
If the \fB"security"\fP parameter is set to
\fB"server"\fP, then there are different
restrictions that \fB"security=domain"\fP
@@ -4572,9 +4316,6 @@ See also the \fB"security"\fP parameter\&.
\fBExample:\fP
\f(CW password server = NT-PDC, NT-BDC1, NT-BDC2\fP
.IP
-\fBExample:\fP
-\f(CW password server = *\fP
-.IP
.IP "\fBpath (S)\fP"
.IP
This parameter specifies a directory to which the user of the service
@@ -4656,7 +4397,7 @@ time they log in\&. Maybe a message of the day? Here is an example:
.IP
Of course, this could get annoying after a while :-)
.IP
-See also \fBpreexec close\fP and \fBpostexec\fP\&.
+See also \fBpostexec\fP\&.
.IP
\fBDefault:\fP
\f(CW none (no command executed)\fP
@@ -4664,17 +4405,6 @@ See also \fBpreexec close\fP and \fBpostexec\fP\&.
\fBExample:\fP
\f(CW preexec = echo \e"%u connected to %S from %m (%I)\e" >> /tmp/log\fP
.IP
-.IP "\fBpreexec close (S)\fP"
-.IP
-This boolean option controls whether a non-zero return code from
-\fB"preexec"\fP should close the service being connected to\&.
-.IP
-\fBDefault:\fP
-\f(CW preexec close = no\fP
-.IP
-\fBExample:\fP
-\f(CW preexec close = yes\fP
-.IP
.IP "\fBpreferred master (G)\fP"
.IP
This boolean parameter controls if \fBnmbd\fP is a
@@ -4685,7 +4415,8 @@ force an election, and it will have a slight advantage in winning the
election\&. It is recommended that this parameter is used in
conjunction with \fB"domain master = yes"\fP, so
that \fBnmbd\fP can guarantee becoming a domain
-master\&.
+master\&. Indeed the default ("auto") enables "preferred master" if
+Samba is configured as the domain master browser\&.
.IP
Use this option with caution, because if there are several hosts
(whether Samba servers, Windows 95 or NT) that are preferred master
@@ -4697,7 +4428,7 @@ capabilities\&.
See also \fBos level\fP\&.
.IP
\fBDefault:\fP
-\f(CW preferred master = no\fP
+\f(CW preferred master = auto\fP
.IP
\fBExample:\fP
\f(CW preferred master = yes\fP
@@ -4917,7 +4648,7 @@ find the printer driver files for the automatic installation of
drivers for Windows 95 machines\&. If Samba is set up to serve printer
drivers to Windows 95 machines, this should be set to
.IP
-\f(CW\e\eMACHINE\eaPRINTER$\fP
+\f(CW\e\eMACHINE\ePRINTER$\fP
.IP
Where MACHINE is the NetBIOS name of your Samba server, and PRINTER$
is a share you set up for serving printer driver files\&. For more
@@ -5128,14 +4859,14 @@ This overlapping works best when the speeds of disk and network access
are similar, having very little effect when the speed of one is much
greater than the other\&.
.IP
-The default value is 16384, but very little experimentation has been
+The default value is 2048, but very little experimentation has been
done yet to determine the optimal value, and it is likely that the
best value will vary greatly between systems anyway\&. A value over
65536 is pointless and will cause you to allocate memory
unnecessarily\&.
.IP
\fBDefault:\fP
-\f(CW read size = 16384\fP
+\f(CW read size = 2048\fP
.IP
\fBExample:\fP
\f(CW read size = 8192\fP
@@ -5207,37 +4938,6 @@ master on it\'s segment\&.
\fBExample:\fP
\f(CW remote browse sync = 192\&.168\&.2\&.255 192\&.168\&.4\&.255\fP
.IP
-.IP "\fBrestrict anonymous (G)\fP"
-.IP
-This is a boolean parameter\&. If it is true, then anonymous access
-to the server will be restricted, namely in the case where the server
-is expecting the client to send a username, but it doesn\'t\&. Setting
-it to true will force these anonymous connections to be denied, and
-the client will be required to always supply a username and password
-when connecting\&. Use of this parameter is only recommened for homogenous
-NT client environments\&.
-.IP
-This parameter makes the use of macro expansions that rely
-on the username (%U, %G, etc) consistant\&. NT 4\&.0 likes to use
-anonymous connections when refreshing the share list, and this
-is a way to work around that\&.
-.IP
-When restrict anonymous is true, all anonymous connections are denied
-no matter what they are for\&. This can effect the ability of a machine
-to access the samba Primary Domain Controller to revalidate it\'s machine
-account after someone else has logged on the client interactively\&. The
-NT client will display a message saying that the machine\'s account in
-the domain doesn\'t exist or the password is bad\&. The best way to deal
-with this is to reboot NT client machines between interactive logons,
-using "Shutdown and Restart", rather than "Close all programs and logon
-as a different user"\&.
-.IP
-\fBDefault:\fP
-\f(CW restrict anonymous = false\fP
-.IP
-\fBExample:\fP
-\f(CW restrict anonymous = true\fP
-.IP
.IP "\fBrevalidate (S)\fP"
.IP
Note that this option only works with
@@ -5308,15 +5008,7 @@ This is the same as the \fB"preexec"\fP parameter except
that the command is run as root\&. This is useful for mounting
filesystems (such as cdroms) before a connection is finalized\&.
.IP
-See also \fB"preexec"\fP
-and \fB"root preexec close"\fP\&.
-.IP
-.IP "\fBroot preexec close (S)\fP"
-.IP
-This is the same as the \fB"preexec close"\fP parameter
-except that the command is run as root\&.
-.IP
-See also \fB"preexec"\fP, \fB"preexec close"\fP\&.
+See also \fB"preexec"\fP\&.
.IP
.IP "\fBsecurity (G)\fP"
.IP
@@ -5516,7 +5208,7 @@ users into the \fB"guest account"\fP\&. See the
\fB"map to guest"\fP parameter for details on
doing this\&.
.IP
-\fIBUG:\fP There is currently a bug in the implementation of
+e,(BUG:) There is currently a bug in the implementation of
\fB"security=domain\fP with respect to multi-byte character
set usernames\&. The communication with a Domain Controller
must be done in UNICODE and Samba currently does not widen
@@ -5537,38 +5229,6 @@ and the \fB"encrypted passwords"\fP parameter\&.
\fBExample:\fP
\f(CW security = DOMAIN\fP
.IP
-.IP "\fBsecurity mask (S)\fP"
-.IP
-This parameter controls what UNIX permission bits can be modified
-when a Windows NT client is manipulating the UNIX permission on a
-file using the native NT security dialog box\&.
-.IP
-This parameter is applied as a mask (AND\'ed with) to the changed
-permission bits, thus preventing any bits not in this mask from
-being modified\&. Essentially, zero bits in this mask may be treated
-as a set of bits the user is not allowed to change\&.
-.IP
-If not set explicitly this parameter is set to the same value as the
-\fBcreate mask\fP parameter\&. To allow a user to
-modify all the user/group/world permissions on a file, set this
-parameter to 0777\&.
-.IP
-\fINote\fP that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems\&. Administrators of
-most normal systems will probably want to set it to 0777\&.
-.IP
-See also the \fBforce directory security
-mode\fP, \fBdirectory security
-mask\fP, \fBforce security
-mode\fP parameters\&.
-.IP
-\fBDefault:\fP
-\f(CW security mask = <same as create mask>\fP
-.IP
-\fBExample:\fP
-\f(CW security mask = 0777\fP
-.IP
.IP "\fBserver string (G)\fP"
.IP
This controls what string will show up in the printer comment box in
@@ -5634,16 +5294,13 @@ users reporting strange problems trying to save files (locking errors)
and error messages in the smbd log looking like \f(CW"ERROR
smb_shm_alloc : alloc of XX bytes failed"\fP\&.
.IP
-If your OS refuses the size that Samba asks for then Samba will try a
-smaller size, reducing by a factor of 0\&.8 until the OS accepts it\&.
-.IP
\fBDefault:\fP
\f(CW shared mem size = 1048576\fP
.IP
\fBExample:\fP
\f(CW shared mem size = 5242880 ; Set to 5mb for a large number of files\&.\fP
.IP
-.IP "\fBshort preserve case (G)\fP"
+.IP "\fBshort preserve case (S)\fP"
.IP
This boolean parameter controls if new files which conform to 8\&.3
syntax, that is all in upper case and of suitable length, are created
@@ -6139,12 +5796,9 @@ See also the \fB"strict sync"\fP parameter\&.
This parameter maps how Samba debug messages are logged onto the
system syslog logging levels\&. Samba debug level zero maps onto syslog
LOG_ERR, debug level one maps onto LOG_WARNING, debug level two maps
-onto LOG_NOTICE, debug level three maps onto LOG_INFO\&. All higher
-levels are mapped to LOG_DEBUG\&.
-.IP
-This paramter sets the threshold for sending messages to syslog\&.
-Only messages with debug level less than this value will be sent
-to syslog\&.
+to LOG_NOTICE, debug level three maps onto LOG_INFO\&. The parameter
+sets the threshold for doing the mapping, all Samba debug messages
+above this threshold are mapped to syslog LOG_DEBUG messages\&.
.IP
\fBDefault:\fP
\f(CW syslog = 1\fP
@@ -6377,6 +6031,17 @@ Windows machines to those that the UNIX box uses\&. The other is to map
multiple users to a single username so that they can more easily share
files\&.
.IP
+The use of this option, therefore, relates to UNIX usernames
+and not Windows (specifically NT Domain) usernames\&. In other words,
+once a name has been mapped using this option, the Samba server uses
+the mapped name for internal \fIAND\fP external purposes\&.
+.IP
+This option is \fIDIFFERENT\fP from the \fB"domain user map"\fP
+parameter, which maintains a one-to-one mapping between UNIX usernames
+and NT Domain Usernames: more specifically, the Samba server maintains
+a link between \fIBOTH\fP usernames, presenting the NT username to the
+external NT world, and using the UNIX username internally\&.
+.IP
The map file is parsed line by line\&. Each line should contain a single
UNIX username on the left then a \f(CW\'=\'\fP followed by a list of
usernames on the right\&. The list of usernames on the right may contain
@@ -6650,10 +6315,6 @@ directory tree exported by the server are always allowed; this
parameter controls access only to areas that are outside the directory
tree being exported\&.
.IP
-Note that setting this parameter can have a negative effect on your
-server performance due to the extra system calls that Samba has to
-do in order to perform the link checks\&.
-.IP
\fBDefault:\fP
\f(CW wide links = yes\fP
.IP
@@ -6674,7 +6335,7 @@ need to set this to \f(CW"yes"\fP for some older clients\&.
This specifies the IP address (or DNS name: IP address for preference)
of the WINS server that \fBnmbd\fP should register with\&.
If you have a WINS server on your network then you should set this to
-the WINS server\'s IP\&.
+the WINS server\'s IP\&.
.IP
You should point this at your WINS server if you have a
multi-subnetted network\&.
@@ -6691,41 +6352,6 @@ Samba source distribution\&.
\fBExample:\fP
\f(CW wins server = 192\&.9\&.200\&.1\fP
.IP
-.IP "\fBwins hook (G)\fP"
-.IP
-When Samba is running as a WINS server this allows you to call an
-external program for all changes to the WINS database\&. The primary use
-for this option is to allow the dynamic update of external name
-resolution databases such as dynamic DNS\&.
-.IP
-The wins hook parameter specifies the name of a script or executable
-that will be called as follows:
-.IP
-wins_hook operation name nametype ttl IP_list
-.IP
-The first argument is the operation and is one of "add", "delete",
-or "refresh"\&. In most cases the operation can be ignored as the rest
-of the parameters provide sufficient information\&. Note that "refresh"
-may sometimes be called when the name has not previously been added,
-in that case it should be treated as an add\&.
-.IP
-The second argument is the netbios name\&. If the name is not a legal
-name then the wins hook is not called\&. Legal names contain only
-letters, digits, hyphens, underscores and periods\&.
-.IP
-The third argument is the netbios name type as a 2 digit hexadecimal
-number\&.
-.IP
-The fourth argument is the TTL (time to live) for the name in seconds\&.
-.IP
-The fifth and subsequent arguments are the IP addresses currently
-registered for that name\&. If this list is empty then the name should
-be deleted\&.
-.IP
-An example script that calls the BIND dynamic DNS update program
-"nsupdate" is provided in the examples directory of the Samba source
-code\&.
-.IP
.IP "\fBwins support (G)\fP"
.IP
This boolean controls if the \fBnmbd\fP process in
@@ -6754,6 +6380,7 @@ workgroup = MYGROUP
.IP "\fBwritable (S)\fP"
.IP
Synonym for \fB"writeable"\fP for people who can\'t spell :-)\&.
+Pronounced "ritter-bull"\&.
.IP
.IP "\fBwrite list (S)\fP"
.IP
@@ -6814,52 +6441,51 @@ permitting), but only via spooling operations\&.
.IP
-.PP
.SH "WARNINGS"
-.PP
+.IP
Although the configuration file permits service names to contain
spaces, your client software may not\&. Spaces will be ignored in
comparisons anyway, so it shouldn\'t be a problem - but be aware of the
possibility\&.
-.PP
+.IP
On a similar note, many clients - especially DOS clients - limit
service names to eight characters\&. \fBSmbd\fP has no
such limitation, but attempts to connect from such clients will fail
if they truncate the service names\&. For this reason you should
probably keep your service names down to eight characters in length\&.
-.PP
+.IP
Use of the \fB[homes]\fP and \fB[printers]\fP
special sections make life for an administrator easy, but the various
combinations of default attributes can be tricky\&. Take extreme care
when designing these sections\&. In particular, ensure that the
permissions on spool directories are correct\&.
-.PP
+.IP
.SH "VERSION"
-.PP
+.IP
This man page is correct for version 2\&.0 of the Samba suite\&.
-.PP
+.IP
.SH "SEE ALSO"
-.PP
+.IP
\fBsmbd (8)\fP, \fBsmbclient (1)\fP,
\fBnmbd (8)\fP, \fBtestparm (1)\fP,
\fBtestprns (1)\fP, \fBSamba\fP,
\fBnmblookup (1)\fP, \fBsmbpasswd (5)\fP,
\fBsmbpasswd (8)\fP\&.
-.PP
+.IP
.SH "AUTHOR"
-.PP
+.IP
The original Samba software and related utilities were created by
Andrew Tridgell \fIsamba-bugs@samba\&.org\fP\&. Samba is now developed
by the Samba Team as an Open Source project similar to the way the
Linux kernel is developed\&.
-.PP
+.IP
The original Samba man pages were written by Karl Auer\&. The man page
sources were converted to YODL format (another excellent piece of Open
Source software, available at
\fBftp://ftp\&.icce\&.rug\&.nl/pub/unix/\fP)
and updated for the Samba2\&.0 release by Jeremy Allison\&.
\fIsamba-bugs@samba\&.org\fP\&.
-.PP
+.IP
See \fBsamba (7)\fP to find out how to get a full
list of contributors and details on how to submit bug reports,
comments etc\&.
diff --git a/docs/manpages/smbclient.1 b/docs/manpages/smbclient.1
index 4346629adbd..beaf3aa8d77 100644
--- a/docs/manpages/smbclient.1
+++ b/docs/manpages/smbclient.1
@@ -1,11 +1,11 @@
-.TH "smbclient " "1" "23 Oct 1998" "Samba" "SAMBA"
+.TH SMBCLIENT 1 "24 Feb 2000" "smbclient TNG-prealpha"
.PP
.SH "NAME"
smbclient \- ftp-like client to access SMB/CIFS resources on servers
.PP
.SH "SYNOPSIS"
.PP
-\fBsmbclient\fP servicename [-s smb\&.conf] [-O socket options][-R name resolve order] [-M NetBIOS name] [-i scope] [-N] [-n NetBIOS name] [-d debuglevel] [-P] [-p port] [-l log basename] [-h] [-I dest IP] [-E] [-U username] [-L NetBIOS name] [-t terminal code] [-m max protocol] [-b buffersize] [-W workgroup] [-T<c|x>IXFqgbNan] [-D directory] [-c command string]
+\fBsmbclient\fP servicename [password] [-s smb\&.conf] [-B IP addr] [-O socket options][-R name resolve order] [-M NetBIOS name] [-i scope] [-N] [-n NetBIOS name] [-d debuglevel] [-P] [-p port] [-l log basename] [-h] [-I dest IP] [-E] [-U username] [-L NetBIOS name] [-t terminal code] [-m max protocol] [-W workgroup] [-T<c|x>IXFqgbNan] [-D directory] [-c command string]
.PP
.SH "DESCRIPTION"
.PP
@@ -65,6 +65,9 @@ Samba configuration file, smb\&.conf\&. This file controls all aspects of
the Samba setup on the machine and smbclient also needs to read this
file\&.
.IP
+.IP "\fB-B IP addr\fP"
+The IP address to use when sending a broadcast packet\&.
+.IP
.IP "\fB-O socket options\fP"
TCP socket options to set on the client
socket\&. See the socket options
@@ -101,7 +104,8 @@ no WINS server has been specified this method will be ignored\&.
listed in the \fBinterfaces\fP parameter
in the smb\&.conf file\&. This is the least reliable of the name resolution
methods as it depends on the target host being on a locally connected
-subnet\&.
+subnet\&. To specify a particular broadcast address the \fB-B\fP option
+may be used\&.
.IP
.IP
If this parameter is not set then the name resolve order defined
@@ -280,7 +284,7 @@ nothing before or nothing after the percent symbol will cause an empty
username or an empty password to be used, respectively\&.
.IP
The password may also be specified by setting up an environment
-variable called \f(CWPASSWD\fP that contains the users password\&. Note
+variable called \f(CWPASSWORD\fP that contains the users password\&. Note
that this may be very insecure on some systems but on others allows
users to script smbclient commands without having a password appear in
the command line of a process listing\&.
@@ -290,7 +294,7 @@ on an uppercase password\&. Lowercase or mixed case passwords may be
rejected by these servers\&.
.IP
Be cautious about including passwords in scripts or in the
-\f(CWPASSWD\fP environment variable\&. Also, on many systems the command
+\f(CWPASSWORD\fP environment variable\&. Also, on many systems the command
line of a running process may be seen via the \f(CWps\fP command to be
safe always allow smbclient to prompt for a password and type it in
directly\&.
@@ -322,12 +326,6 @@ protocols level the server supports\&. This parameter is
preserved for backwards compatibility, but any string
following the \fB-m\fP will be ignored\&.
.IP
-.IP "\fB-b buffersize\fP"
-This option changes the transmit/send buffer
-size when getting or putting a file from/to the server\&. The default
-is 65520 bytes\&. Setting this value smaller (to 1200 bytes) has been
-observed to speed up file transfers to and from a Win9x server\&.
-.IP
.IP "\fB-W WORKGROUP\fP"
Override the default workgroup specified in the
\fBworkgroup\fP parameter of the
@@ -719,7 +717,7 @@ The variable \fBUSER\fP may contain the username of the person using the
client\&. This information is used only if the protocol level is high
enough to support session-level passwords\&.
.PP
-The variable \fBPASSWD\fP may contain the password of the person using
+The variable \fBPASSWORD\fP may contain the password of the person using
the client\&. This information is used only if the protocol level is
high enough to support session-level passwords\&.
.PP
diff --git a/docs/manpages/smbd.8 b/docs/manpages/smbd.8
index 5efd6794787..faf88cccf33 100644
--- a/docs/manpages/smbd.8
+++ b/docs/manpages/smbd.8
@@ -1,11 +1,11 @@
-.TH "smbd " "8" "23 Oct 1998" "Samba" "SAMBA"
+.TH SMBD 8 "24 Feb 2000" "smbd TNG-prealpha"
.PP
.SH "NAME"
smbd \- server to provide SMB/CIFS services to clients
.PP
.SH "SYNOPSIS"
.PP
-\fBsmbd\fP [-D] [-a] [-o] [-P] [-h] [-V] [-d debuglevel] [-l log file] [-p port number] [-O socket options] [-s configuration file] [-i scope]
+\fBsmbd\fP [-D] [-a] [-o] [-d debuglevel] [-l log file] [-p port number] [-O socket options] [-s configuration file] [-i scope] [-P] [-h]
.PP
.SH "DESCRIPTION"
.PP
@@ -65,16 +65,6 @@ If this parameter is specified, the log files will be
overwritten when opened\&. By default, the log files will be appended
to\&.
.IP
-.IP "\fB-P\fP"
-Passive option\&. Causes smbd not to send any network traffic
-out\&. Used for debugging by the developers only\&.
-.IP
-.IP "\fB-h\fP"
-Prints the help information (usage) for \fBsmbd\fP\&.
-.IP
-.IP "\fB-V\fP"
-Prints the version number for \fBsmbd\fP\&.
-.IP
.IP "\fB-d debuglevel\fP"
debuglevel is an integer from 0 to 10\&.
.IP
@@ -145,6 +135,13 @@ are \fIvery\fP rarely used, only set this parameter if you are the
system administrator in charge of all the NetBIOS systems you
communicate with\&.
.IP
+.IP "\fB-h\fP"
+Prints the help information (usage) for smbd\&.
+.IP
+.IP "\fB-P\fP"
+Passive option\&. Causes smbd not to send any network traffic
+out\&. Used for debugging by the developers only\&.
+.IP
.PP
.SH "FILES"
.PP
@@ -412,11 +409,16 @@ performance\&.
.PP
.SH "SEE ALSO"
.PP
-\fBhosts_access (5)\fP, \fBinetd (8)\fP, \fBnmbd (8)\fP,
-\fBsmb\&.conf (5)\fP, \fBsmbclient
-(1)\fP, \fBtestparm (1)\fP,
-\fBtestprns (1)\fP, and the Internet RFC\'s
-\fBrfc1001\&.txt\fP, \fBrfc1002\&.txt\fP\&. In addition the CIFS (formerly SMB)
+\fBhosts_access (5)\fP,
+\fBinetd (8)\fP,
+\fBnmbd (8)\fP,
+\fBsmb\&.conf (5)\fP,
+\fBsmbclient (1)\fP,
+\fBtestparm (1)\fP,
+\fBtestprns (1)\fP,
+\fBrpcclient (1)\fP,
+and the Internet RFC\'s \fBrfc1001\&.txt\fP, \fBrfc1002\&.txt\fP\&.
+In addition the CIFS (formerly SMB)
specification is available as a link from the Web page :
http://samba\&.org/cifs/\&.
.PP
diff --git a/docs/manpages/smbmnt.8 b/docs/manpages/smbmnt.8
index e8cc1f2cd9c..68eb727f920 100644
--- a/docs/manpages/smbmnt.8
+++ b/docs/manpages/smbmnt.8
@@ -1,37 +1,96 @@
-.TH "smbmnt " "1" "25 September 1999" "Samba" "SAMBA"
-.PP
-.SH "NAME"
-smbmnt \- helper utility for mounting SMB filesystems
-.PP
-.SH "SYNOPSIS"
-\fBsmbmnt\fP mount-point [ -s share ] [ -r ] [ -u uid ] [ -g gid ] [ -f mask ] [ -d mask ]
-.PP
-.SH "DESCRIPTION"
-.PP
-smbmnt is a helper application used by the smbmount program to do the
-actual mounting of SMB shares\&. smbmnt is meant to be installed setuid
-root so that normal users can mount their smb shares\&. It checks
-whether the user has write permissions on the mount point and then
-mounts the directory\&.
-.PP
-The smbmnt program is normally invoked by smbmount\&. It should not be
-invoked directly by users\&.
-.PP
-.IP "\fB-r\fP"
-mount the filesystem read-only
-.PP
-.IP "\fB-u uid\fP"
-specify the uid that the files will be owned by
-.PP
-.IP "\fB-g gid\fP"
-specify the gid that the files will be owned by
-.PP
-.IP "\fB-f mask\fP"
-specify the octal file mask applied
-.PP
-.IP "\fB-d mask\fP"
-specify the octal directory mask applied
-.PP
-.SH "AUTHOR"
-The maintainer of smbfs, smbmnt and smbmount is Andrew Tridgell
-\fItridge@samba\&.org\fP
+.TH SMBMNT 8 "24 Feb 2000" "smbmnt TNG-prealpha"
+.SH NAME
+smbmnt \- mount smb file system
+.SH SYNOPSIS
+.B smbmnt
+.B mount-point
+[
+.B -u
+.I uid
+] [
+.B -g
+.I gid
+] [
+.B -f
+.I file mode
+] [
+.B -d
+.I dir mode
+]
+
+.SH DESCRIPTION
+.B smbmnt
+is a helper application used by the
+.BI smbmount (8)
+program to do the actual mounting.
+.B smbmnt
+is meant to be installed setuid root so that normal users can mount
+their smb shares. It checks whether the user has write permissions
+on the mount point and then mounts the directory.
+
+The
+.B smbmnt
+program is normally invoked by a mount command to
+.BI smbmount ,
+and the command line arguments are passed directly to
+.B smbmnt.
+
+.SH OPTIONS
+.B -u
+.I uid,
+.B -g
+.I gid
+.RS 3
+A Lan Manager server does not tell us anything about the owner of a
+file, but Unix requires that each file have an owner and a group it belongs
+to. With
+.B -u
+and
+.B -g
+you can tell smbmount which id's it should assign to the files in the
+mounted directory.
+
+The defaults for these values are the current uid and gid.
+.RE
+
+.B -f
+.I file mode,
+.B -d
+.I dir mode
+.RS 3
+Like
+.B -u
+and
+.B -g,
+these options are also used to bridge differences in concepts between
+Lan Manager and Unix. Lan Manager does not know anything about file
+permissions, so
+.B smbmnt
+must be told which permissions it should assign to the mounted files
+and directories.
+
+The values must be given as octal numbers. The default values are taken
+from the current umask, where the file mode is the current umask,
+and the dir mode adds execute permissions where the file mode gives
+read permissions.
+
+Note that these permissions can differ from the rights the server
+gives to us. If you do not have write permissions on the server,
+you should choose a file mode that matches your actual permissions.
+This certainly cannot override the restrictions imposed by the server.
+
+In addition to specifying the file mode, the
+.B -f
+argument can be used to specify certain bug-fix workarounds.
+This allows bug fixes to be enabled on a per mount-point basis,
+rather than being compiled into the kernel.
+The required bug fixes are specified by prepending an (octal) value
+to the file mode.
+For information on the available bug workarounds, refer to the
+.B smbfs.txt
+file in the Linux kernel Documentation directory.
+.RE
+
+.SH SEE ALSO
+.B smbmount(8)
+
diff --git a/docs/manpages/smbmount.8 b/docs/manpages/smbmount.8
index 457a940ddba..3d1491f7fd1 100644
--- a/docs/manpages/smbmount.8
+++ b/docs/manpages/smbmount.8
@@ -1,87 +1,44 @@
-.TH "smbmount " "1" "25 September 1999" "Samba" "SAMBA"
-.PP
-.SH "NAME"
-smbmount \- mount an SMB filesystem
-.PP
-.SH "SYNOPSIS"
-\fBsmbmount\fP service mountpoint [ -o options ]
-.PP
-.SH "DESCRIPTION"
-.PP
-smbmount mounts a SMB filesystem\&. It is usually invoked as mount\&.smb
-from the mount(8) command when using the "-t smb" option\&. The kernel
-must support the smbfs filesystem\&.
-.PP
-Options to smbmount are specified as a comma separated list of
-key=value pairs\&.
-.PP
-NOTE: smbmount calls smbmnt to do the actual mount\&. You must make sure
-that smbmnt is in the path so that it can be found\&.
-.PP
-.IP "\fBusername=<arg>\fP"
-specifies the username to connect as\&. If this is
-not given then the environment variable USER is used\&. This option can
-also take the form user%password or user/workgroup or
-user/workgroup%password to allow the password and workgroup to be
-specified as part of the username\&.
-.IP
-.IP "\fBpassword=<arg>\fP"
-specifies the SMB password\&. If not given then
-smbmount will prompt for a passeword, unless the guest option is
-given\&.
-.IP
-.IP "\fBnetbiosname=<arg>\fP"
-sets the source NetBIOS name\&. It defaults to
-the local hostname\&.
-.IP
-.IP "\fBuid=<arg>\fP"
-sets the uid that files will be mounted as\&. It may be
-specified as either a username or a numeric uid\&.
-.IP
-.IP "\fBgid=<arg>\fP"
-sets the gid that files will be mounted as\&. It may be
-specified as either a groupname or a numeric gid\&.
-.IP
-.IP "\fBport=<arg>\fP"
-sets the remote SMB port number\&. The default is 139\&.
-.IP
-.IP "\fBfmask=<arg>\fP"
-sets the file mask\&. This deterines the permissions
-that remote files have in the local filesystem\&. The default is based
-on the current umask\&.
-.IP
-.IP "\fBdmask=<arg>\fP"
-sets the directory mask\&. This deterines the
-permissions that remote directories have in the local filesystem\&. The
-default is based on the current umask\&.
-.IP
-.IP "\fBdebug=<arg>\fP"
-sets the debug level\&. This is useful for tracking
-down SMB connection problems\&.
-.IP
-.IP "\fBip=<arg>\fP"
-sets the destination host or IP address\&.
-.IP
-.IP "\fBworkgroup=<arg>\fP"
-sets the workgroup on the destination
-.IP
-.IP "\fBsockopt=<arg>\fP"
-sets the TCP socket options\&. See the smb\&.conf
-"socket options" option\&.
-.IP
-.IP "\fBscope=<arg>\fP"
-sets the NetBIOS scope
-.IP
-.IP "\fBguest\fP"
-don\'t prompt for a password
-.IP
-.IP "\fBro\fP"
-mount read-only
-.IP
-.IP "\fBrw\fP"
-mount read-write
-.IP
-.PP
-.SH "AUTHOR"
-The maintainer of smbfs, smbmnt and smbmount is Andrew Tridgell
-\fItridge@samba\&.org\fP
+.TH SMBMOUNT 8 "24 Feb 2000" "smbmount TNG-prealpha"
+.SH NAME
+smbmount \- mount smb file system
+.SH SYNOPSIS
+.B smbmount
+[
+.B options
+]
+
+.SH DESCRIPTION
+.B smbmount
+is a stripped-down version of the
+.BI smbclient (1)
+program used to mount smbfs shares. It implements only the mount command,
+which then calls the
+.BI smbmnt (8)
+program to do the actual mount.
+.B smbmount
+itself accepts most of the options that
+.B smbclient
+does. See the
+.BI smbclient (1)
+manpage for details.
+
+To mount an smb file system, I suggest using the option
+.B -c
+for smbmount to pass the mount command. For example, use
+
+smbmount '\\\\server\\tmp' -c 'mount /mnt -u 123 -g 456'
+
+to mount the tmp share of server on /mnt, giving it a local uid 123
+and a local gid 456.
+
+The arguments supplied to the mount command are passed directly to the
+.B smbmnt
+utility for processing.
+Refer to the
+.BI smbmnt (8)
+manpage for details.
+
+.SH SEE ALSO
+.BI smbmnt (8),
+.BI smbclient (1)
+
diff --git a/docs/manpages/smbpasswd.5 b/docs/manpages/smbpasswd.5
index e3fbcf161ee..6fc4e783fa0 100644
--- a/docs/manpages/smbpasswd.5
+++ b/docs/manpages/smbpasswd.5
@@ -1,4 +1,4 @@
-.TH "smbpasswd " "5" "23 Oct 1998" "Samba" "SAMBA"
+.TH SMBPASSWD 5 "24 Feb 2000" "smbpasswd TNG-prealpha"
.PP
.SH "NAME"
smbpasswd \- The Samba encrypted password file
diff --git a/docs/manpages/smbpasswd.8 b/docs/manpages/smbpasswd.8
index ad502e01b12..a5fbd3f441d 100644
--- a/docs/manpages/smbpasswd.8
+++ b/docs/manpages/smbpasswd.8
@@ -1,4 +1,4 @@
-.TH "smbpasswd " "8" "23 Oct 1998" "Samba" "SAMBA"
+.TH SMBPASSWD 8 "24 Feb 2000" "smbpasswd TNG-prealpha"
.PP
.SH "NAME"
smbpasswd \- change a users SMB password
diff --git a/docs/manpages/smbrun.1 b/docs/manpages/smbrun.1
index d34b408d6bd..08f89ad30c1 100644
--- a/docs/manpages/smbrun.1
+++ b/docs/manpages/smbrun.1
@@ -1,4 +1,4 @@
-.TH "smbrun " "1" "23 Oct 1998" "Samba" "SAMBA"
+.TH SMBRUN 1 "24 Feb 2000" "smbrun TNG-prealpha"
.PP
.SH "NAME"
smbrun \- interface program between smbd and external programs
diff --git a/docs/manpages/smbstatus.1 b/docs/manpages/smbstatus.1
index 7899344d7fb..5ab7cfaade2 100644
--- a/docs/manpages/smbstatus.1
+++ b/docs/manpages/smbstatus.1
@@ -1,4 +1,4 @@
-.TH "smbstatus " "1" "23 Oct 1998" "Samba" "SAMBA"
+.TH SMBSTATUS 1 "24 Feb 2000" "smbstatus TNG-prealpha"
.PP
.SH "NAME"
smbstatus \- report on current Samba connections
@@ -18,7 +18,7 @@ connections\&.
.PP
.IP
.IP "\fB-P\fP"
-If samba has been compiled with the profiling option,
+If samba has been compiled with the profiling option,
print only the contents of the profiling shared memory area\&.
.IP
.IP "\fB-b\fP"
diff --git a/docs/manpages/smbtar.1 b/docs/manpages/smbtar.1
index 2aaa542231e..e85a1f4e633 100644
--- a/docs/manpages/smbtar.1
+++ b/docs/manpages/smbtar.1
@@ -1,4 +1,4 @@
-.TH "smbtar " "1" "23 Oct 1998" "Samba" "SAMBA"
+.TH SMBTAR 1 "24 Feb 2000" "smbtar TNG-prealpha"
.PP
.SH "NAME"
smbtar \- shell script for backing up SMB/CIFS shares directly to UNIX tape drives
diff --git a/docs/manpages/smbumount.8 b/docs/manpages/smbumount.8
index 724684a2214..017cb1dffe7 100644
--- a/docs/manpages/smbumount.8
+++ b/docs/manpages/smbumount.8
@@ -1,4 +1,4 @@
-.TH SMBUMOUNT 8 "18 May 1999" "smbumount 2.0.4"
+.TH SMBUMOUNT 8 "24 Feb 2000" "smbumount TNG-prealpha"
.SH NAME
smbumount \- umount for normal users
.SH SYNOPSIS
diff --git a/docs/manpages/swat.8 b/docs/manpages/swat.8
index 8798c0a566e..0fdc6adf23e 100644
--- a/docs/manpages/swat.8
+++ b/docs/manpages/swat.8
@@ -1,7 +1,7 @@
-.TH "swat " "8" "23 Oct 1998" "Samba" "SAMBA"
+.TH SWAT 8 "24 Feb 2000" "swat TNG-prealpha"
.PP
.SH "NAME"
-swat \- Samba Web Administration Tool
+swat \- swat - Samba Web Administration Tool
.PP
.SH "SYNOPSIS"
.PP
diff --git a/docs/manpages/testparm.1 b/docs/manpages/testparm.1
index 2d4c03a1641..3f4bba7d4d6 100644
--- a/docs/manpages/testparm.1
+++ b/docs/manpages/testparm.1
@@ -1,11 +1,11 @@
-.TH "testparm " "1" "23 Oct 1998" "Samba" "SAMBA"
+.TH TESTPARM 1 "24 Feb 2000" "testparm TNG-prealpha"
.PP
.SH "NAME"
testparm \- check an smb\&.conf configuration file for internal correctness
.PP
.SH "SYNOPSIS"
.PP
-\fBtestparm\fP [-s] [-h] [-L servername] [configfilename] [hostname hostIP]
+\fBtestparm\fP [-s] [configfilename] [hostname hostIP]
.PP
.SH "DESCRIPTION"
.PP
@@ -24,11 +24,6 @@ If the optional host name and host IP address are specified on the
command line, this test program will run through the service entries
reporting whether the specified host has access to each service\&.
.PP
-If \fBtestparm\fP finds an error in the \fBsmb\&.conf\fP
-file it returns an exit code of 1 to the calling program, else it returns
-an exit code of 0\&. This allows shell scripts to test the output from
-\fBtestparm\fP\&.
-.PP
.SH "OPTIONS"
.PP
.IP
@@ -37,13 +32,6 @@ Without this option, \fBtestparm\fP will prompt for a
carriage return after printing the service names and before dumping
the service definitions\&.
.IP
-.IP "\fB-h\fP"
-Print usage message
-.IP
-.IP "\fB-L servername\fP"
-Sets the value of the %L macro to servername\&. This
-is useful for testing include files specified with the %L macro\&.
-.IP
.IP "\fBconfigfilename\fP"
This is the name of the configuration file to
check\&. If this parameter is not present then the default
diff --git a/docs/manpages/testprns.1 b/docs/manpages/testprns.1
index bb366e329c3..aa308c3fb1c 100644
--- a/docs/manpages/testprns.1
+++ b/docs/manpages/testprns.1
@@ -1,4 +1,4 @@
-.TH "testprns " "1" "23 Oct 1998" "Samba" "SAMBA"
+.TH TESTPRNS 1 "24 Feb 2000" "testprns TNG-prealpha"
.PP
.SH "NAME"
testprns \- check printer name for validity with smbd
diff --git a/docs/samba.lsm b/docs/samba.lsm
index fa10333683a..c69add4d8ed 100644
--- a/docs/samba.lsm
+++ b/docs/samba.lsm
@@ -1,14 +1,14 @@
Begin2
Title = Samba
-Version = 1.8.0
+Version = 2.0
Desc1 = Samba is a SMB based file and print server for unix. It
Desc2 = provides access to unix file and print services from
Desc3 = SMB compatible clients such as WinNT, WfWg, OS/2
Desc4 = and Pathworks. It also includes a ftp-style unix client
Desc5 = and a netbios nameserver.
-Author = Andrew Tridgell
+Author = Samba Team
AuthorEmail = samba-bugs@samba.org
-Maintainer = Andrew Tridgell
+Maintainer = Samba Team
MaintEmail = samba-bugs@samba.org
Site1 = samba.org
Path1 = pub/samba/
@@ -18,9 +18,8 @@ Required1 = Ansi-C compiler and a TCP/IP network.
CopyPolicy1 = GNU Public License
Keywords = LanManager, SMB, Networking
Comment1 = To join the Samba mailing list send mail to
-Comment2 = listproc@listproc.anu.edu.au with a body of
+Comment2 = listproc@samba.org with a body of
Comment3 = "subscribe samba Your Name"
-Entered = October 1994
+Entered = November 1998
EnteredBy = Andrew Tridgell
End
-
diff --git a/docs/textdocs/Application_Serving.txt b/docs/textdocs/Application_Serving.txt
index be07cfe0621..fe37c6faddb 100644
--- a/docs/textdocs/Application_Serving.txt
+++ b/docs/textdocs/Application_Serving.txt
@@ -1,5 +1,5 @@
!==
-!== Application_Serving.txt for Samba release 2.0.4 18 May 1999
+!== Application_Serving.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributed: January 7, 1997
Updated: March 24, 1998
diff --git a/docs/textdocs/BROWSING-Config.txt b/docs/textdocs/BROWSING-Config.txt
index a27cf7401dc..76df7ccbab8 100644
--- a/docs/textdocs/BROWSING-Config.txt
+++ b/docs/textdocs/BROWSING-Config.txt
@@ -1,5 +1,5 @@
!==
-!== BROWSING-Config.txt for Samba release 2.0.4 18 May 1999
+!== BROWSING-Config.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Date: July 5, 1998
Contributor: John H Terpstra <jht@samba.org>
diff --git a/docs/textdocs/BROWSING.txt b/docs/textdocs/BROWSING.txt
index ae18382bd91..cdd77d5fc2c 100644
--- a/docs/textdocs/BROWSING.txt
+++ b/docs/textdocs/BROWSING.txt
@@ -1,5 +1,5 @@
!==
-!== BROWSING.txt for Samba release 2.0.4 18 May 1999
+!== BROWSING.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Author/s: Many (Thanks to Luke, Jeremy, Andrew, etc.)
Updated: July 5, 1998
diff --git a/docs/textdocs/BUGS.txt b/docs/textdocs/BUGS.txt
index 14a77f4cb44..8bca022e7f0 100644
--- a/docs/textdocs/BUGS.txt
+++ b/docs/textdocs/BUGS.txt
@@ -1,5 +1,5 @@
!==
-!== BUGS.txt for Samba release 2.0.4 18 May 1999
+!== BUGS.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Samba Team
Updated: June 27, 1997
diff --git a/docs/textdocs/CVS_ACCESS.txt b/docs/textdocs/CVS_ACCESS.txt
index c854d3fe33e..c91de15926e 100644
--- a/docs/textdocs/CVS_ACCESS.txt
+++ b/docs/textdocs/CVS_ACCESS.txt
@@ -1,5 +1,5 @@
!==
-!== CVS_ACCESS.txt for Samba release 2.0.4 18 May 1999
+!== CVS_ACCESS.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Modified from the Web pages by Jeremy Allison.
Date: 23 Dec 1997
diff --git a/docs/textdocs/DHCP-Server-Configuration.txt b/docs/textdocs/DHCP-Server-Configuration.txt
index 72afd85e594..48584816a99 100644
--- a/docs/textdocs/DHCP-Server-Configuration.txt
+++ b/docs/textdocs/DHCP-Server-Configuration.txt
@@ -1,5 +1,5 @@
!==
-!== DHCP-Server-Configuration.txt for Samba release 2.0.4 18 May 1999
+!== DHCP-Server-Configuration.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Subject: DHCP Server Configuration for SMB Clients
Date: March 1, 1998
diff --git a/docs/textdocs/DIAGNOSIS.txt b/docs/textdocs/DIAGNOSIS.txt
index ce514004643..4f27ea7f08b 100644
--- a/docs/textdocs/DIAGNOSIS.txt
+++ b/docs/textdocs/DIAGNOSIS.txt
@@ -1,8 +1,8 @@
!==
-!== DIAGNOSIS.txt for Samba release 2.0.4 18 May 1999
+!== DIAGNOSIS.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Andrew Tridgell
-Updated: November 1, 1999
+Updated: October 14, 1997
Subject: DIAGNOSING YOUR SAMBA SERVER
===========================================================================
@@ -16,6 +16,9 @@ You should do ALL the tests, in the order shown. I have tried to
carefully choose them so later tests only use capabilities verified in
the earlier tests.
+I would welcome additions to this set of tests. Please mail them to
+samba-bugs@samba.org
+
If you send me an email saying "it doesn't work" and you have not
followed this test procedure then you should not be surprised if I
ignore your email.
@@ -25,10 +28,9 @@ ASSUMPTIONS
-----------
In all of the tests I assume you have a Samba server called BIGSERVER
-and a PC called ACLIENT both in workgroup TESTGROUP. I also assume the
-PC is running windows for workgroups with a recent copy of the
-microsoft tcp/ip stack. Alternatively, your PC may be running Windows
-95 or Windows NT (Workstation or Server).
+and a PC called ACLIENT. I also assume the PC is running windows for
+workgroups with a recent copy of the microsoft tcp/ip stack. Alternatively,
+your PC may be running Windows 95 or Windows NT (Workstation or Server).
The procedure is similar for other types of clients.
@@ -42,7 +44,7 @@ smb.conf. I will assume this share is called "tmp". You can add a
read only = yes
-THESE TESTS ASSUME VERSION 2.0.6 OR LATER OF THE SAMBA SUITE. SOME
+THESE TESTS ASSUME VERSION 1.9.16 OR LATER OF THE SAMBA SUITE. SOME
COMMANDS SHOWN DID NOT EXIST IN EARLIER VERSIONS
Please pay attention to the error messages you receive. If any error message
@@ -100,7 +102,7 @@ valid. Check what your guest account is using "testparm" and
temporarily remove any "hosts allow", "hosts deny", "valid users" or
"invalid users" lines.
-If you get a "connection refused" response then the smbd server may
+If you get a "connection refused" response then the smbd server could
not be running. If you installed it in inetd.conf then you probably edited
that file incorrectly. If you installed it as a daemon then check that
it is running, and check that the netbios-ssn port is in a LISTEN
@@ -168,9 +170,6 @@ You should get the PCs IP address back. If you don't then the client
software on the PC isn't installed correctly, or isn't started, or you
got the name of the PC wrong.
-If ACLIENT doesn't resolve via DNS then use the IP address of the
-client in the above test.
-
TEST 6:
-------
@@ -200,15 +199,11 @@ not correct. (Refer to TEST 3 notes above).
TEST 7:
-------
-Run the command "smbclient //BIGSERVER/TMP". You should then be
+Run the command "smbclient '\\BIGSERVER\TMP'". You should then be
prompted for a password. You should use the password of the account
you are logged into the unix box with. If you want to test with
-another account then add the -U <accountname> option to the end of
-the command line. eg: smbclient //bigserver/tmp -Ujohndoe
-
-Note: It is possible to specify the password along with the username
-as follows:
- smbclient //bigserver/tmp -Ujohndoe%secret
+another account then add the -U <accountname> option to the command
+line.
Once you enter the password you should get the "smb>" prompt. If you
don't then look at the error message. If it says "invalid network
@@ -255,12 +250,6 @@ same fixes apply as they did for the "smbclient -L" test above. In
particular, make sure your "hosts allow" line is correct (see the man
pages)
-Also, do not overlook that fact that when the workstation requests the
-connection to the samba server it will attempt to connect using the
-name with which you logged onto your Windows machine. You need to make
-sure that an account exists on your Samba server with that exact same
-name and password.
-
If you get "specified computer is not receiving requests" or similar
it probably means that the host is not contactable via tcp services.
Check to see if the host is running tcp wrappers, and if so add an entry in
@@ -282,21 +271,8 @@ USERNAME" to the [tmp] section of smb.conf where "USERNAME" is the
username corresponding to the password you typed. If you find this
fixes things you may need the username mapping option.
-TEST 10:
---------
-
-Run the command "nmblookup -M TESTGROUP" where TESTGROUP is the name
-of the workgroup that your Samba server and Windows PCs belong to. You
-should get back the IP address of the master browser for that
-workgroup.
-If you don't then the election process has failed. Wait a minute to
-see if it is just being slow then try again. If it still fails after
-that then look at the browsing options you have set in smb.conf. Make
-sure you have "preferred master = yes" to ensure that an election is
-held at startup.
-
-TEST 11:
+TEST 10:
--------
From file manager try to browse the server. Your samba server should
diff --git a/docs/textdocs/DNIX.txt b/docs/textdocs/DNIX.txt
index f209f046182..7acf4fff717 100644
--- a/docs/textdocs/DNIX.txt
+++ b/docs/textdocs/DNIX.txt
@@ -1,5 +1,5 @@
!==
-!== DNIX.txt for Samba release 2.0.4 18 May 1999
+!== DNIX.txt for Samba release TNG-prealpha 24 Feb 2000
!==
DNIX has a problem with seteuid() and setegid(). These routines are
needed for Samba to work correctly, but they were left out of the DNIX
diff --git a/docs/textdocs/DOMAIN.txt b/docs/textdocs/DOMAIN.txt
index d16f3aa55dc..1e64b09f4cc 100644
--- a/docs/textdocs/DOMAIN.txt
+++ b/docs/textdocs/DOMAIN.txt
@@ -1,5 +1,5 @@
!==
-!== DOMAIN.txt for Samba release 2.0.4 18 May 1999
+!== DOMAIN.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Samba Team
Updated: December 4, 1998 (John H Terpstra)
diff --git a/docs/textdocs/DOMAIN_CONTROL.txt b/docs/textdocs/DOMAIN_CONTROL.txt
index dd4afa34759..f2bfcc9d094 100644
--- a/docs/textdocs/DOMAIN_CONTROL.txt
+++ b/docs/textdocs/DOMAIN_CONTROL.txt
@@ -1,5 +1,5 @@
!==
-!== DOMAIN_CONTROL.txt for Samba release 2.0.4 18 May 1999
+!== DOMAIN_CONTROL.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Initial Release: August 22, 1996
Contributor: John H Terpstra <samba-bugs@samba.org>
diff --git a/docs/textdocs/DOMAIN_MEMBER.txt b/docs/textdocs/DOMAIN_MEMBER.txt
index 53fd6d94f94..8d104dffc06 100644
--- a/docs/textdocs/DOMAIN_MEMBER.txt
+++ b/docs/textdocs/DOMAIN_MEMBER.txt
@@ -1,7 +1,10 @@
+!==
+!== DOMAIN_MEMBER.txt for Samba release TNG-prealpha 24 Feb 2000
+!==
TITLE INFORMATION: Joining an NT Domain with Samba 2.0
AUTHOR INFORMATION: Jeremy Allison, Samba Team
-DATE INFORMATION: 7th October 1999
+DATE INFORMATION: 11th November 1998
Contents
@@ -11,8 +14,7 @@ Joining an NT Domain with Samba 2.0
In order for a Samba-2 server to join an NT domain, you must first add
the NetBIOS name of the Samba server to the NT domain on the PDC using
Server Manager for Domains. This creates the machine account in the
-domain (PDC) SAM. Note that you should add the Samba server as a "Windows
-NT Workstation or Server", NOT as a Primary or backup domain controller.
+domain (PDC) SAM.
Assume you have a Samba-2 server with a NetBIOS name of SERV1 and are
joining an NT domain called DOM, which has a PDC with a NetBIOS name
@@ -76,10 +78,6 @@ workgroup = DOM
as this is the name of the domain we are joining.
-You must also have the parameter "encrypt passwords"
-set to "yes" in order for your users to authenticate to the
-NT PDC.
-
Finally, add (or modify) a:
"password server ="
@@ -94,16 +92,20 @@ each of these servers in order, so you may want to rearrange this list
in order to spread out the authentication load among domain
controllers.
-Alternatively, if you want smbd to automatically determine the
-list of Domain controllers to use for authentication, you may set this line to be :
-
-password server = *
-
-This method, which is new in Samba 2.0.6 and above, allows Samba
-to use exactly the same mechanism that NT does. This method either broadcasts or
-uses a WINS database in order to find domain controllers to
+Currently, Samba requires that a defined list of domain controllers be
+listed in this parameter in order to authenticate with domain-level
+security. NT does not use this method, and will either broadcast or
+use a WINS database in order to find domain controllers to
authenticate against.
+Originally, I considered this idea for Samba, but dropped it because
+it seemed so insecure. However several Samba-2 alpha users have
+requested that this feature be added to make Samba more NT-like, so
+I'll probably add a special name of '*' (which means: act like NT
+when looking for domain controllers) in a future release of the
+code. At present, however, you need to know where your domain
+controllers are.
+
Finally, restart your Samba daemons and get ready for clients to begin
using domain security!
diff --git a/docs/textdocs/ENCRYPTION.txt b/docs/textdocs/ENCRYPTION.txt
index 89f30b0d53a..c8b7f5ef37d 100644
--- a/docs/textdocs/ENCRYPTION.txt
+++ b/docs/textdocs/ENCRYPTION.txt
@@ -1,8 +1,8 @@
!==
-!== ENCRYPTION.txt for Samba release 2.0.5a 22 Jul 1999
+!== ENCRYPTION.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Jeremy Allison <samba-bugs@samba.org>
-Updated: April 19, 1999
+Updated: March 19, 1998
Note: Please refer to WinNT.txt also
Subject: LanManager / Samba Password Encryption.
@@ -22,7 +22,7 @@ How does it work ?
LanManager encryption is somewhat similar to UNIX password
encryption. The server uses a file containing a hashed value of a
-user's password. This is created by taking the user's plaintext
+users password. This is created by taking the users plaintext
password, capitalising it, and either truncating to 14 bytes (or
padding to 14 bytes with null bytes). This 14 byte value is used as
two 56 bit DES keys to encrypt a 'magic' eight byte value, forming a
@@ -30,7 +30,7 @@ two 56 bit DES keys to encrypt a 'magic' eight byte value, forming a
be known as the *hashed password*.
Windows NT encryption is a higher quality mechanism, consisting
-of doing an MD4 hash on a Unicode version of the user's password. This
+of doing an MD4 hash on a Unicode version of the users password. This
also produces a 16 byte hash value that is non-reversible.
When a client (LanManager, Windows for WorkGroups, Windows 95 or
@@ -51,10 +51,10 @@ In the SMB call SMBsessionsetupX (when user level security is
selected) or the call SMBtconX (when share level security is selected)
the 24 byte response is returned by the client to the Samba server.
For Windows NT protocol levels the above calculation is done on
-both hashes of the user's password and both responses are returned
+both hashes of the users password and both responses are returned
in the SMB call, giving two 24 byte values.
-The Samba server then reproduces the above calculation, using its own
+The Samba server then reproduces the above calculation, using it's own
stored value of the 16 byte hashed password (read from the smbpasswd
file - described later) and the challenge value that it kept from the
negotiate protocol reply. It then checks to see if the 24 byte value it
@@ -62,11 +62,11 @@ calculates matches the 24 byte value returned to it from the client.
If these values match exactly, then the client knew the correct
password (or the 16 byte hashed value - see security note below) and
-is thus allowed access. If not, then the client did not know the
+is this allowed access. If not then the client did not know the
correct password and is denied access.
Note that the Samba server never knows or stores the cleartext of the
-user's password - just the 16 byte hashed values derived from it. Also
+users password - just the 16 byte hashed values derived from it. Also
note that the cleartext password or 16 byte hashed values are never
transmitted over the network - thus increasing security.
@@ -79,7 +79,7 @@ typically sends clear text passwords over the nextwork when logging
in. This is bad. The SMB encryption scheme never sends the cleartext
password over the network but it does store the 16 byte hashed values
on disk. This is also bad. Why? Because the 16 byte hashed values are a
-"password equivalent". You cannot derive the user's password from them,
+"password equivalent". You cannot derive the users password from them,
but they could potentially be used in a modified client to gain access
to a server. This would require considerable technical knowledge on
behalf of the attacker but is perfectly possible. You should thus
@@ -106,7 +106,7 @@ a network sniffer cannot just record passwords going to the SMB server.
- WinNT doesn't like talking to a server that isn't using SMB
encrypted passwords. It will refuse to browse the server if the server
-is also in user level security mode. It will insist on prompting the
+is also in user level security mode. It will insist on promting the
user for the password on each connection, which is very annoying. The
only things you can do to stop this is to use SMB encryption.
@@ -135,7 +135,7 @@ The smbpasswd file.
In order for Samba to participate in the above protocol it must
be able to look up the 16 byte hashed values given a user name.
Unfortunately, as the UNIX password value is also a one way hash
-function (ie. it is impossible to retrieve the cleartext of the user's
+function (ie. it is impossible to retrieve the cleartext of the users
password given the UNIX hash of it) then a separate password file
containing this 16 byte value must be kept. To minimise problems with
these two password files, getting out of sync, the UNIX /etc/passwd and
@@ -177,11 +177,10 @@ chmod 600 smbpasswd.
The format of the smbpasswd file is
-username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[Account type]:LCT-<last-change-time>:Long name
+username:uid:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Long name:user home dir:user shell
-Although only the username, uid, XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
-[Account type] and last-change-time sections are significant and
-are looked at in the Samba code.
+Although only the username, uid, and XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+sections are significant and are looked at in the Samba code.
It is *VITALLY* important that there by 32 'X' characters between the
two ':' characters in the XXX sections - the smbpasswd and Samba code
@@ -193,7 +192,7 @@ When the password file is created all users have password entries
consisting of 32 'X' characters. By default this disallows any access
as this user. When a user has a password set, the 'X' characters change
to 32 ascii hexadecimal digits (0-9, A-F). These are an ascii
-representation of the 16 byte hashed value of a user's password.
+representation of the 16 byte hashed value of a users password.
To set a user to have no password (not recommended), edit the file
using vi, and replace the first 11 characters with the asci text
@@ -203,7 +202,7 @@ NO PASSWORD
Eg. To clear the password for user bob, his smbpasswd file entry would
look like :
-bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U ]:LCT-00000000:Bob's full name:/bobhome:/bobshell
+bob:100:NO PASSWORDXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Bob's full name:/bobhome:/bobshell
If you are allowing users to use the smbpasswd command to set their own
passwords, you may want to give users NO PASSWORD initially so they do
@@ -215,7 +214,7 @@ that user with no password. Enable this by adding the line :
null passwords = true
to the [global] section of the smb.conf file (this is why the
-above scenario is not recommended). Preferably, allocate your
+above scenario is not recommended). Preferebly, allocate your
users a default password to begin with, so you do not have
to enable this on your server.
@@ -237,16 +236,16 @@ setuid root (the new smbpasswd code enforces this restriction so
it cannot be run this way by accident).
smbpasswd now works in a client-server mode where it contacts
-the local smbd to change the user's password on its behalf. This
+the local smbd to change the users password on its behalf. This
has enormous benefits - as follows.
-1). smbpasswd no longer has to be setuid root - an enormous
+1). smbpasswd no longer has to be setuid root - an enourmous
range of potential security problems is eliminated.
2). smbpasswd now has the capability to change passwords
on Windows NT servers (this only works when the request is
sent to the NT Primary Domain Controller if you are changing
-an NT Domain user's password).
+an NT Domain users password).
To run smbpasswd as a normal user just type :
@@ -314,7 +313,7 @@ If this fails then you will find that you will need entries that look
like this:
# SMB password file.
-tridge:148:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:[U ]:LCT-00000000:Andrew Tridgell:/home/tridge:/bin/tcsh
+tridge:148:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:Andrew Tridgell:/home/tridge:/bin/tcsh
note that the uid and username fields must be right. Also, you must get
the number of X's right (there should be 32).
diff --git a/docs/textdocs/Faxing.txt b/docs/textdocs/Faxing.txt
index 426cbfcee3e..aac12ab324c 100644
--- a/docs/textdocs/Faxing.txt
+++ b/docs/textdocs/Faxing.txt
@@ -1,5 +1,5 @@
!==
-!== Faxing.txt for Samba release 2.0.4 18 May 1999
+!== Faxing.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Gerhard Zuber <zuber@berlin.snafu.de>
Date: August 5th 1997.
diff --git a/docs/textdocs/GOTCHAS.txt b/docs/textdocs/GOTCHAS.txt
index 023e33b1ce9..5b61f33b3bd 100644
--- a/docs/textdocs/GOTCHAS.txt
+++ b/docs/textdocs/GOTCHAS.txt
@@ -1,5 +1,5 @@
!==
-!== GOTCHAS.txt for Samba release 2.0.4 18 May 1999
+!== GOTCHAS.txt for Samba release TNG-prealpha 24 Feb 2000
!==
This file lists Gotchas to watch out for:
=========================================================================
diff --git a/docs/textdocs/HINTS.txt b/docs/textdocs/HINTS.txt
index 87a77dacc19..4b7c68b2244 100644
--- a/docs/textdocs/HINTS.txt
+++ b/docs/textdocs/HINTS.txt
@@ -1,5 +1,5 @@
!==
-!== HINTS.txt for Samba release 2.0.4 18 May 1999
+!== HINTS.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Many
Updated: Not for a long time!
diff --git a/docs/textdocs/LDAP.txt b/docs/textdocs/LDAP.txt
new file mode 100644
index 00000000000..f34d5ec22fe
--- /dev/null
+++ b/docs/textdocs/LDAP.txt
@@ -0,0 +1,153 @@
+!==
+!== LDAP.txt for Samba release TNG-prealpha 24 Feb 2000
+!==
+
+TITLE INFORMATION: LDAP Support in Samba
+AUTHOR INFORMATION: Matthew Chapman
+DATE INFORMATION: 29th November 1998
+
+WARNING: This is experimental code. Use at your own risk, and please report
+any bugs (after reading BUGS.txt).
+
+Contents
+
+1: What is LDAP?
+2: Why LDAP and Samba?
+3: Using LDAP with Samba
+4: Using LDAP for Unix authentication
+5: Compatibility with Active Directory
+
+1: What is LDAP?
+
+A directory is a type of hierarchical database optimised for simple query
+operations, often used for storing user information. LDAP is the
+Lightweight Directory Access Protocol, a protocol which is rapidly
+becoming the Internet standard for accessing directories.
+
+Many client applications now support LDAP (including Microsoft's Active
+Directory), and there are a number of servers available. The most popular
+implementation for Unix is from the University of Michigan; its
+homepage is at http://www.umich.edu/~dirsvcs/ldap/.
+
+Information in an LDAP tree always comes in attribute=value pairs.
+The following is an example of a Samba user entry:
+
+uid=jbloggs, dc=samba, dc=org
+objectclass=sambaAccount
+uid=jbloggs
+cn=Joe Bloggs
+description=Samba User
+uidNumber=500
+gidNumber=500
+rid=2000
+grouprid=2001
+lmPassword=46E389809F8D55BB78A48108148AD508
+ntPassword=1944CCE1AD6F80D8AEC9FC5BE77696F4
+pwdLastSet=35C11F1B
+smbHome=\\samba1\jbloggs
+homeDrive=Z
+script=logon.bat
+profile=\\samba1\jbloggs\profile
+workstations=JOE
+
+Note that the top line is a special set of attributes called a
+distinguished name which identifies the location of this entry beneath
+the directory's root node. Recent Internet standards suggest the use of
+domain-based naming using dc attributes (for instance, a microsoft.com
+directory should have a root node of dc=microsoft, dc=com), although
+this is not strictly necessary for isolated servers.
+
+There are a number of LDAP-related FAQ's on the internet, although
+generally the best source of information is the documentation for the
+individual servers.
+
+2: Why LDAP and Samba?
+
+Using an LDAP directory allows Samba to store user and group information
+more reliably and flexibly than the current combination of smbpasswd,
+smbgroup, groupdb and aliasdb with the Unix databases. If a need emerges
+for extra user information to be stored, this can easily be added without
+loss of backwards compatibility.
+
+In addition, the Samba LDAP schema is compatible with RFC2307, allowing
+Unix password database information to be stored in the same entries. This
+provides a single, consistent repository for both Unix and Windows user
+information.
+
+3: Using LDAP with Samba
+
+1 Install and configure an LDAP server if you do not already have
+one. You should read your LDAP server's documentation and set up the
+configuration file and access control as desired.
+
+2 Build Samba (latest CVS is required) with:
+
+ ./configure --with-ldap
+ make clean; make install
+
+3 Add the following options to the global section of smb.conf as
+required.
+
+o ldap suffix
+
+This parameter specifies the node of the LDAP tree beneath which
+Samba should store its information. This parameter MUST be provided
+when using LDAP with Samba.
+
+Default: none
+
+Example: ldap suffix = "dc=mydomain, dc=org"
+
+o ldap bind as
+
+This parameter specifies the entity to bind to an LDAP directory as.
+Usually it should be safe to use the LDAP root account; for larger
+installations it may be preferable to restrict Samba's access.
+
+Default: none (bind anonymously)
+
+Example: ldap bind as = "uid=root, dc=mydomain, dc=org"
+
+o ldap passwd file
+
+This parameter specifies a file containing the password with which
+Samba should bind to an LDAP server. For obvious security reasons
+this file must be set to mode 700 or less.
+
+Default: none (bind anonymously)
+
+Example: ldap passwd file = /usr/local/samba/private/ldappasswd
+
+o ldap server
+
+This parameter specifies the DNS name of the LDAP server to use
+when storing and retrieving information about Samba users and
+groups.
+
+Default: ldap server = localhost
+
+o ldap port
+
+This parameter specifies the TCP port number of the LDAP server.
+
+Default: ldap port = 389
+
+4 You should then be able to use the normal smbpasswd(8) command for
+account administration (or User Manager in the near future).
+
+4: Using LDAP for Unix authentication
+
+The Samba LDAP code was designed to utilise RFC2307-compliant directory
+entries if available. RFC2307 is a proposed standard for LDAP user
+information which has been adopted by a number of vendors. Further
+information is available at http://www.xedoc.com.au/~lukeh/ldap/.
+
+Of particular interest is Luke Howard's nameservice switch module
+(nss_ldap) and PAM module (pam_ldap) implementing this standard, providing
+LDAP-based password databases for Unix. If you are setting up a server to
+provide integrated Unix/NT services than these are worth investigating.
+
+5: Compatibility with Active Directory
+
+The current implementation is not designed to be used with Microsoft
+Active Directory, although compatibility may be added in the future.
diff --git a/docs/textdocs/MIRRORS.txt b/docs/textdocs/MIRRORS.txt
index a133f261c53..7780dff2a8f 100755
--- a/docs/textdocs/MIRRORS.txt
+++ b/docs/textdocs/MIRRORS.txt
@@ -1,5 +1,5 @@
!==
-!== MIRRORS.txt for Samba release 2.0.4 18 May 1999
+!== MIRRORS.txt for Samba release TNG-prealpha 24 Feb 2000
!==
For a list of web and ftp mirrors please see
diff --git a/docs/textdocs/Macintosh_Clients.txt b/docs/textdocs/Macintosh_Clients.txt
index 2af6e213d12..1b9f982e170 100644
--- a/docs/textdocs/Macintosh_Clients.txt
+++ b/docs/textdocs/Macintosh_Clients.txt
@@ -1,5 +1,5 @@
!==
-!== Macintosh_Clients.txt for Samba release 2.0.4 18 May 1999
+!== Macintosh_Clients.txt for Samba release TNG-prealpha 24 Feb 2000
!==
> Are there any Macintosh clients for Samba?
diff --git a/docs/textdocs/NTDOMAIN.txt b/docs/textdocs/NTDOMAIN.txt
index 8408acb979a..6a51b865b84 100644
--- a/docs/textdocs/NTDOMAIN.txt
+++ b/docs/textdocs/NTDOMAIN.txt
@@ -1,5 +1,5 @@
!==
-!== NTDOMAIN.txt for Samba release 2.0.4 18 May 1999
+!== NTDOMAIN.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Luke Kenneth Casson Leighton (samba-bugs@samba.org)
Copyright (C) 1997 Luke Kenneth Casson Leighton
diff --git a/docs/textdocs/NetBIOS.txt b/docs/textdocs/NetBIOS.txt
index 9295f5c4bdc..0fbb0fedf75 100644
--- a/docs/textdocs/NetBIOS.txt
+++ b/docs/textdocs/NetBIOS.txt
@@ -1,5 +1,5 @@
!==
-!== NetBIOS.txt for Samba release 2.0.4 18 May 1999
+!== NetBIOS.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: lkcl - samba-bugs@arvidsjaur.anu.edu.au
Copyright 1997 Luke Kenneth Casson Leighton
diff --git a/docs/textdocs/OS2-Client-HOWTO.txt b/docs/textdocs/OS2-Client-HOWTO.txt
index 4413d387eb7..dc894907aa2 100644
--- a/docs/textdocs/OS2-Client-HOWTO.txt
+++ b/docs/textdocs/OS2-Client-HOWTO.txt
@@ -1,5 +1,5 @@
!==
-!== OS2-Client-HOWTO.txt for Samba release 2.0.4 18 May 1999
+!== OS2-Client-HOWTO.txt for Samba release TNG-prealpha 24 Feb 2000
!==
diff --git a/docs/textdocs/PRINTER_DRIVER.txt b/docs/textdocs/PRINTER_DRIVER.txt
index 5bf82e0cfe4..7104d4598c7 100644
--- a/docs/textdocs/PRINTER_DRIVER.txt
+++ b/docs/textdocs/PRINTER_DRIVER.txt
@@ -1,5 +1,5 @@
!==
-!== PRINTER_DRIVER.txt for Samba release 2.0.4 18 May 1999
+!== PRINTER_DRIVER.txt for Samba release TNG-prealpha 24 Feb 2000
!==
==========================================================================
Supporting the famous PRINTER$ share
diff --git a/docs/textdocs/PROFILES.txt b/docs/textdocs/PROFILES.txt
index af9f99a0028..e9a884f21b1 100644
--- a/docs/textdocs/PROFILES.txt
+++ b/docs/textdocs/PROFILES.txt
@@ -1,5 +1,5 @@
!==
-!== PROFILES.txt for Samba release 2.0.4 18 May 1999
+!== PROFILES.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributors: Bruce Cook <BC3-AU@bigfoot.com>
Copyright (C) 1998 Bruce Cook
diff --git a/docs/textdocs/Passwords.txt b/docs/textdocs/Passwords.txt
index f86827367f0..97374bd7750 100644
--- a/docs/textdocs/Passwords.txt
+++ b/docs/textdocs/Passwords.txt
@@ -1,8 +1,8 @@
!==
-!== Passwords.txt for Samba release 2.0.4 18 May 1999
+!== Passwords.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Unknown
-Date: Updated April 19th 1999.
+Date: Unknown
Status: Current
Subject: NOTE ABOUT PASSWORDS
@@ -37,8 +37,8 @@ Unix password checking method you are using. Note that the AFS code is
only written and tested for AFS 3.3 and later.
-SECURITY = SERVER or DOMAIN
-===========================
+SECURITY = SERVER
+=================
Samba can use a remote server to do its username/password
validation. This allows you to have one central machine (for example a
diff --git a/docs/textdocs/Printing.txt b/docs/textdocs/Printing.txt
index 358eab3b602..8b614dc0f45 100644
--- a/docs/textdocs/Printing.txt
+++ b/docs/textdocs/Printing.txt
@@ -1,5 +1,5 @@
!==
-!== Printing.txt for Samba release 2.0.4 18 May 1999
+!== Printing.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Unknown <samba-bugs@samba.org>
Date: Unknown
@@ -54,7 +54,7 @@ might be:
then you print a file and look at the /tmp/tmp.print file to see what
is produced. Try printing this file with lpr. Does it work? If not
-then the problem is with your lpr system, not with Samba. Often
+then your problem with with your lpr system, not with Samba. Often
people have problems with their /etc/printcap file or permissions on
various print queues.
@@ -95,32 +95,18 @@ If the above debug tips don't help, then maybe you need to bring in
the bug gun, system tracing. See Tracing.txt in this directory.
=====================================================================
-From Caldera Inc., the following documentation has been
-contributed. Note that it contains stuff that is only relevant on some
-systems (specifically Caldera OpenLinux systems).
+From Caldera Inc., the following documentation has been contributed:
8.6 Setting up a raw SAMBA printer.
-Note: this is not a guide on setting up SAMBA. It merely addresses
-creating a printer configuration that will allow the output of regular
-(i.e. not PostScript) Windows printer drivers to print through SAMBA.
+Note: this is not a guide on setting up SAMBA. It merely addresses creating a printer configuration that will allow the output of regular (i.e. not PostScript) Windows printer drivers to print through SAMBA.
-Regular Windows printer drivers can be used to print via SAMBA, but
-you must set up a raw printer entry in "/etc/printcap" to accomplish
-this. Also, a print command will need to be specified in
-"/etc/smb.conf" that forces binary printing.
+Regular Windows printer drivers can be used to print via SAMBA, but you must set up a raw printer entry in "/etc/printcap" to accomplish this. Also, a print command will need to be specified in "/etc/smb.conf" that forces binary printing.
-The best way to start is to use printtool under X to create a new
-entry specifically for this printer. All you really need for it to do
-is create the necessary directories and set the permissions correctly,
-so don't worry about setting up a filter for a specific printer.
-Filters are not going to be used at all for this entry.
+The best way to start is to use printtool under X to create a new entry specifically for this printer. All you really need for it to do is create the necessary directories and set the permissions correctly, so don't worry about setting up a filter for a specific printer. Filters are not going to be used at all for this entry.
-Next, go into "/etc" and edit the printcap entry you just created,
-changing it to look like this (if you named it something other than
-raw, the entry name and spool directory should be changed here to
-match):
+Next, go into "/etc" and edit the printcap entry you just created, changing it to look like this (if you named it something other than raw, the entry name and spool directory should be changed here to match):
raw:\
:rw:sh: \
@@ -128,15 +114,12 @@ raw:\
:sd=/var/spool/lpd/raw: \
:fx=flp:
-When this is done and saved, edit the section of the smb.conf file
-that applies to the printer. Make sure the name of the section
-(enclosed in brackets) matches the name of the raw printer you just
-set up, then go down a line or two and add this line:
+When this is done and saved, edit the section of the smb.conf file that applies to the printer. Make sure the name of the section (enclosed in brackets) matches the name of the raw printer you just set up, then go down a line or two and add this line:
print command = lpr -b -P%p %s
-Save the file, change to "/etc/rc.d/init.d", and type the following
-commands to restart the necessary daemons:
+Save the file, change to "/etc/rc.d/init.d", and type the following commands
+to restart the necessary daemons:
./lpd stop
./lpd start
diff --git a/docs/textdocs/README.smbmount b/docs/textdocs/README.smbmount
new file mode 100644
index 00000000000..0c9d9bbe50f
--- /dev/null
+++ b/docs/textdocs/README.smbmount
@@ -0,0 +1,51 @@
+Date: February 26, 1999
+
+Subject: smbmount / smbmnt / smbumount
+=============================================================================
+
+The Samba-Team wishes to make known that the above programs are a part of
+the SMBFS software package for the Linux operating system. They are very
+definitely NOT part of Samba and are in general NOT supported by the
+Samba-Team.
+
+In repsonse to flames to comp.protocols.smb and to feedback to
+samba-bugs@samba.org we wish to place on record that the reason for which
+these programs have not received the attention that some folks expect
+from the Samba-Team is as stated above, they are NOT part of samba.
+
+Out of empathy for the Samba user base we have taken the liberty of
+including patched source code for the above "SMBFS package" utilities
+in the Samba tarball.
+
+Mike Warfield is temporary caretaker of SMBFS and may be contacted at
+mike@samba.org.
+
+In deference to the fact that these programs are NOT part of Samba
+the default binary packaging facilities included in the samba tarball
+do NOT automatically create the updates needed for the Linux 2.2.x
+kernel. If you require the updated smbmount / smbmnt / smbumount tools
+then it will be necessary to modify the samba2.spec file to include
+the --with-smbmount option to the samba "configure" script _AND_
+you will need to add these files to the appropriate locations in the "install"
+and "files" sections also. The platform specific RPM SPEC files that you
+will need to modify may be found under ~samba/packaging/"platform".
+
+The Samba-Team has considered the alternatives. These are:
+ 1) Include all SMBFS code with Samba:
+ - rejected because we do not have the resources to support it.
+ - SMBFS is specific and limited to Linux
+ 2) Just build the smbmount / smbmnt / smbumount binaries:
+ - doing this will break RPM dependencies for the SMBFS package
+ - this is not a good option either
+ 3) Encourage people to use the "smbsh" utility that is part of samba
+ and is being developed to replace the need for "SMBFS"
+ - this is portable to platforms other than Linux
+ - it allows each user to authenticate as themselves instead
+ of allowing all users to use an SMB session that is
+ authenticated as just one user.
+
+We have chosen the later and hope that our users will understand and support
+the decision that has been made.
+
+For and on behalf of the Samba-Team
+John H Terpstra
diff --git a/docs/textdocs/Recent-FAQs.txt b/docs/textdocs/Recent-FAQs.txt
index 64af51a7a80..8af2aee2283 100644
--- a/docs/textdocs/Recent-FAQs.txt
+++ b/docs/textdocs/Recent-FAQs.txt
@@ -1,5 +1,5 @@
!==
-!== Recent-FAQs.txt for Samba release 2.0.4 18 May 1999
+!== Recent-FAQs.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Samba-bugs@samba.org
Date: July 5, 1998
diff --git a/docs/textdocs/RoutedNetworks.txt b/docs/textdocs/RoutedNetworks.txt
index 35a185052fb..2d8856e37b1 100644
--- a/docs/textdocs/RoutedNetworks.txt
+++ b/docs/textdocs/RoutedNetworks.txt
@@ -1,5 +1,5 @@
!==
-!== RoutedNetworks.txt for Samba release 2.0.4 18 May 1999
+!== RoutedNetworks.txt for Samba release TNG-prealpha 24 Feb 2000
!==
#NOFNR Flag in LMHosts to Communicate Across Routers
diff --git a/docs/textdocs/SCO.txt b/docs/textdocs/SCO.txt
index d723a148890..2dc76aa49b8 100644
--- a/docs/textdocs/SCO.txt
+++ b/docs/textdocs/SCO.txt
@@ -1,5 +1,5 @@
!==
-!== SCO.txt for Samba release 2.0.4 18 May 1999
+!== SCO.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Geza Makay <makayg@math.u-szeged.hu>
Date: Unknown
diff --git a/docs/textdocs/SSLeay.txt b/docs/textdocs/SSLeay.txt
index 981e35e4ef6..6ffbcd0c159 100644
--- a/docs/textdocs/SSLeay.txt
+++ b/docs/textdocs/SSLeay.txt
@@ -1,5 +1,5 @@
!==
-!== SSLeay.txt for Samba release 2.0.4 18 May 1999
+!== SSLeay.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Christian Starkjohann <cs@obdev.at>
Date: May 29, 1998
diff --git a/docs/textdocs/Speed.txt b/docs/textdocs/Speed.txt
index b2fcd15cda4..97ca01b284a 100644
--- a/docs/textdocs/Speed.txt
+++ b/docs/textdocs/Speed.txt
@@ -1,6 +1,9 @@
!==
-!== Speed.txt for Samba release 2.0.4b 20 May 1999
+!== Speed.txt for Samba release TNG-prealpha 24 Feb 2000
!==
+Contributor: Andrew Tridgell
+Date: January 1995
+Status: Current
Subject: Samba performance issues
============================================================================
@@ -60,21 +63,6 @@ option has been left in the code for backwards compatibility reasons
but it's use is now deprecated. A short summary of what the old
code did follows.
-LEVEL2 OPLOCKS
---------------
-
-With Samba 2.0.5 a new capability - level2 (read only) oplocks is
-supported (although the option is off by default - see the smb.conf
-man page for details). Turning on level2 oplocks (on a share-by-share basis)
-by setting the parameter :
-
-level2 oplocks = true
-
-should speed concurrent access to files that are not commonly written
-to, such as application serving shares (ie. shares that contain common
-.EXE files - such as a Microsoft Office share) as it allows clients to
-read-ahread cache copies of these files.
-
Old 'fake oplocks' option - deprecated.
---------------------------------------
diff --git a/docs/textdocs/Speed2.txt b/docs/textdocs/Speed2.txt
index 057f8e6bf34..a320644a21e 100644
--- a/docs/textdocs/Speed2.txt
+++ b/docs/textdocs/Speed2.txt
@@ -1,5 +1,5 @@
!==
-!== Speed2.txt for Samba release 2.0.4 18 May 1999
+!== Speed2.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Paul Cochrane <paulc@dth.scot.nhs.uk>
Organization: Dundee Limb Fitting Centre
diff --git a/docs/textdocs/Support.txt b/docs/textdocs/Support.txt
index 192b5984801..b9e626503ea 100644
--- a/docs/textdocs/Support.txt
+++ b/docs/textdocs/Support.txt
@@ -1,8 +1,8 @@
!==
-!== Support.txt for Samba release 2.0.4 18 May 1999
+!== Support.txt for Samba release TNG-prealpha 24 Feb 2000
!==
The Samba Consultants List
==========================
This list has now moved to the support page of the
-Samba web pages at http://samba.org/samba/
+Samba web pages at http://samba.org.au/samba/
diff --git a/docs/textdocs/Tracing.txt b/docs/textdocs/Tracing.txt
index d156b34633e..5c613e2c5a3 100644
--- a/docs/textdocs/Tracing.txt
+++ b/docs/textdocs/Tracing.txt
@@ -1,5 +1,5 @@
!==
-!== Tracing.txt for Samba release 2.0.4 18 May 1999
+!== Tracing.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Andrew Tridgell <samba-bugs@samba.org>
Date: Old
diff --git a/docs/textdocs/UNIX-SMB.txt b/docs/textdocs/UNIX-SMB.txt
index 7d597af654b..bd7811bea4f 100644
--- a/docs/textdocs/UNIX-SMB.txt
+++ b/docs/textdocs/UNIX-SMB.txt
@@ -1,5 +1,5 @@
!==
-!== UNIX-SMB.txt for Samba release 2.0.4 18 May 1999
+!== UNIX-SMB.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Andrew Tridgell <samba-bugs@samba.org>
Date: April 1995
diff --git a/docs/textdocs/UNIX_INSTALL.txt b/docs/textdocs/UNIX_INSTALL.txt
index 1de821e1520..2d9c4232a64 100644
--- a/docs/textdocs/UNIX_INSTALL.txt
+++ b/docs/textdocs/UNIX_INSTALL.txt
@@ -1,5 +1,14 @@
-HOW TO INSTALL AND TEST SAMBA
-=============================
+!==
+!== UNIX_INSTALL.txt for Samba release TNG-prealpha 24 Feb 2000
+!==
+Contributor: Andrew Tridgell <samba-bugs@samba.org>
+Date: Unknown
+Status: Current
+Updated: November 13, 1998 <jra@samba.org>
+
+Subject: HOW TO INSTALL AND TEST SAMBA
+===============================================================================
+
STEP 0. Read the man pages. They contain lots of useful info that will
help to get you started. If you don't know how to read man pages then
diff --git a/docs/textdocs/UNIX_SECURITY.txt b/docs/textdocs/UNIX_SECURITY.txt
index 1a610d8e4c7..30b2fc0e3fd 100644
--- a/docs/textdocs/UNIX_SECURITY.txt
+++ b/docs/textdocs/UNIX_SECURITY.txt
@@ -1,5 +1,5 @@
!==
-!== UNIX_SECURITY.txt for Samba release 2.0.4 18 May 1999
+!== UNIX_SECURITY.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: John H Terpstra <jht@samba.org>
Date: July 5, 1998
diff --git a/docs/textdocs/Win95.txt b/docs/textdocs/Win95.txt
index 417fe012204..f7763b3139b 100644
--- a/docs/textdocs/Win95.txt
+++ b/docs/textdocs/Win95.txt
@@ -1,5 +1,5 @@
!==
-!== Win95.txt for Samba release 2.0.4 18 May 1999
+!== Win95.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Copyright (C) 1997 - Samba-Team
Contributed Date: August 20, 1997
diff --git a/docs/textdocs/WinNT.txt b/docs/textdocs/WinNT.txt
index 4894936aa9b..f7dbad771ba 100644
--- a/docs/textdocs/WinNT.txt
+++ b/docs/textdocs/WinNT.txt
@@ -1,5 +1,5 @@
!==
-!== WinNT.txt for Samba release 2.0.4 18 May 1999
+!== WinNT.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributors: Various
Password Section - Copyright (C) 1997 - John H Terpstra
diff --git a/docs/textdocs/cifsntdomain.txt b/docs/textdocs/cifsntdomain.txt
index ba6e0c46be3..afa9319a1be 100644
--- a/docs/textdocs/cifsntdomain.txt
+++ b/docs/textdocs/cifsntdomain.txt
@@ -1,5 +1,5 @@
!==
-!== cifsntdomain.txt for Samba release 2.0.4 18 May 1999
+!== cifsntdomain.txt for Samba release TNG-prealpha 24 Feb 2000
!==
NT Domain Authentication
------------------------
diff --git a/docs/textdocs/rpcclient.1.txt b/docs/textdocs/rpcclient.1.txt
new file mode 100644
index 00000000000..dfd8ed0af0c
--- /dev/null
+++ b/docs/textdocs/rpcclient.1.txt
@@ -0,0 +1,688 @@
+!==
+!== rpcclient.1.txt for Samba release TNG-prealpha 24 Feb 2000
+!==
+
+TITLE INFORMATION: rpcclient (1)
+AUTHOR INFORMATION: Samba SAMBA
+DATE INFORMATION: 23 Oct 1998
+
+NAME
+rpcclient - utility to manage MSRPC resources on servers
+
+SYNOPSIS
+
+rpcclient
+[password]
+-S servername
+[-U [username][%][password]]
+[-W domain]
+[-l log basename]
+[-d debuglevel]
+[-O socket options]
+[-i scope]
+[-N]
+[-n NetBIOS name]
+[-h]
+[-I dest IP]
+[-E]
+[-t terminal code]
+[-c command string]
+[-B IP addr]
+[-s smb.conf]
+[-m max protocol]
+
+DESCRIPTION
+
+This program is part of the Samba suite.
+
+rpcclient is a client that can 'talk' to an SMB/CIFS MSRPC server.
+Operations include things like managing a SAM Database (users, groups
+and aliases) in the same way as the Windows NT programs
+User Manager for Domains and Server Manager for Domains;
+managing a remote registry in the same way as the Windows NT programs
+REGEDT32.EXE and REGEDIT.EXE; viewing a remote event log (same
+as EVENTVWR.EXE) etc.
+
+Typical usage is like this:
+
+rpcclient -I 192.168.32.1 -S "*SMBSERVER" -U fred%secret -l log
+
+OPTIONS
+
+o servername servername is the name of the server you want
+to use on the server. This should be the NetBIOS name of the SMB/CIFS
+server, which can be *SMBSERVER on Windows NT 4.0 or Samba Servers.
+
+Note that the server name required is NOT necessarily the IP (DNS)
+host name of the server! The name required is a NetBIOS server name,
+which may or may not be the same as the IP hostname of the machine
+running the server. Also, remember that having a period in a NetBIOS
+name (such as an IP hostname) may cause connectivity problems on your
+network: NT tends to strip NetBIOS names from the leading period
+onwards.
+
+The server name is looked up according to either the
+-R parameter to rpcclient or using the
+name resolve order
+parameter in the smb.conf file, allowing an administrator to change
+the order and methods by which server names are looked up.
+
+o password password is the password required to access the
+specified service on the specified server. If this parameter is
+supplied, the -N option (suppress password prompt) is assumed.
+
+There is no default password. If no password is supplied on the
+command line (either by using this parameter or adding a password to
+the -U option (see below)) and the -N option is not specified,
+the client will prompt for a password, even if the desired service
+does not require one. (If no password is required, simply press ENTER
+to provide a null password.)
+
+Note: Some servers (including OS/2 and Windows for Workgroups) insist
+on an uppercase password. Lowercase or mixed case passwords may be
+rejected by these servers.
+
+Be cautious about including passwords in scripts.
+
+o -s smb.conf This parameter specifies the pathname to the
+Samba configuration file, smb.conf. This file controls all aspects of
+the Samba setup on the machine and rpcclient also needs to read this
+file.
+
+o -B IP addr The IP address to use when sending a broadcast packet.
+
+o -O socket options TCP socket options to set on the client
+socket. See the socket options
+parameter in the smb.conf (5) manpage for
+the list of valid options.
+
+o -R name resolve order This option allows the user of
+rpcclient to determine what name resolution services to use when
+looking up the NetBIOS name of the host being connected to.
+
+The options are :"lmhosts", "host", "wins" and "bcast". They cause
+names to be resolved as follows :
+
+o lmhosts : Lookup an IP address in the Samba lmhosts file.
+The lmhosts file is stored in the same directory as the
+smb.conf file.
+
+o host : Do a standard host name to IP address resolution,
+using the system /etc/hosts, NIS, or DNS lookups. This method of name
+resolution is operating system depended for instance on IRIX or
+Solaris this may be controlled by the /etc/nsswitch.conf file).
+
+o wins : Query a name with the IP address listed in the wins
+server parameter in the smb.conf file. If
+no WINS server has been specified this method will be ignored.
+
+o bcast : Do a broadcast on each of the known local interfaces
+listed in the interfaces parameter
+in the smb.conf file. This is the least reliable of the name resolution
+methods as it depends on the target host being on a locally connected
+subnet. To specify a particular broadcast address the -B option
+may be used.
+
+If this parameter is not set then the name resolve order defined
+in the smb.conf file parameter
+(name resolve order)
+will be used.
+
+The default order is lmhosts, host, wins, bcast and without this
+parameter or any entry in the "name resolve
+order" parameter of the
+smb.conf file the name resolution methods
+will be attempted in this order.
+
+o -i scope This specifies a NetBIOS scope that rpcclient will use
+to communicate with when generating NetBIOS names. For details on the
+use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
+are very rarely used, only set this parameter if you are the
+system administrator in charge of all the NetBIOS systems you
+communicate with.
+
+o -N If specified, this parameter suppresses the normal
+password prompt from the client to the user. This is useful when
+accessing a service that does not require a password.
+
+Unless a password is specified on the command line or this parameter
+is specified, the client will request a password.
+
+o -n NetBIOS name By default, the client will use the local
+machine's hostname (in uppercase) as its NetBIOS name. This parameter
+allows you to override the host name and use whatever NetBIOS name you
+wish.
+
+o -d debuglevel debuglevel is an integer from 0 to 10, or the
+letter 'A'.
+
+The default value if this parameter is not specified is zero.
+
+The higher this value, the more detail will be logged to the log files
+about the activities of the client. At level 0, only critical errors
+and serious warnings will be logged. Level 1 is a reasonable level for
+day to day running - it generates a small amount of information about
+operations carried out.
+
+Levels above 1 will generate considerable amounts of log data, and
+should only be used when investigating a problem. Levels above 3 are
+designed for use only by developers and generate HUGE amounts of log
+data, most of which is extremely cryptic. If debuglevel is set to the
+letter 'A', then all debug messages will be printed. This setting
+is for developers only (and people who really want to know how the
+code works internally).
+
+Note that specifying this parameter here will override the log
+level parameter in the smb.conf
+(5) file.
+
+o -p port This number is the TCP port number that will be used
+when making connections to the server. The standard (well-known) TCP
+port number for an SMB/CIFS server is 139, which is the default.
+
+o -l logfilename If specified, logfilename specifies a base
+filename into which operational data from the running client will be
+logged.
+
+The default base name is specified at compile time.
+
+The base name is used to generate actual log file names. For example,
+if the name specified was "log", the debug file would be
+log.client.
+
+The log file generated is never removed by the client.
+
+o -h Print the usage message for the client.
+
+o -I IP address IP address is the address of the server to
+connect to. It should be specified in standard "a.b.c.d" notation.
+
+Normally the client would attempt to locate a named SMB/CIFS server by
+looking it up via the NetBIOS name resolution mechanism described
+above in the name resolve order parameter
+above. Using this parameter will force the client to assume that the
+server is on the machine with the specified IP address and the NetBIOS
+name component of the resource being connected to will be ignored.
+
+There is no default for this parameter. If not supplied, it will be
+determined automatically by the client as described above.
+
+o -E This parameter causes the client to write messages to the
+standard error stream (stderr) rather than to the standard output
+stream.
+
+By default, the client writes messages to standard output - typically
+the user's tty.
+
+Note that by default, debug information is always sent to stderr.
+Debug information can instead be sent to a file, using the
+-l log basename option.
+
+o -U username This specifies the user name that will be used by
+the client to make a connection, assuming your server is not a downlevel
+server that is running a protocol level that uses passwords on shares,
+not on usernames.
+
+Some servers are fussy about the case of this name, and some insist
+that it must be a valid NetBIOS name.
+
+If no username is supplied, it will default to an uppercase version of
+the environment variable USER or LOGNAME in that order. If no
+username is supplied and neither environment variable exists the
+username "GUEST" will be used.
+
+If the USER environment variable contains a '%' character,
+everything after that will be treated as a password. This allows you
+to set the environment variable to be USER=username%password so
+that a password is not passed on the command line (where it may be
+seen by the ps command).
+
+If the service you are connecting to requires a password, it can be
+supplied using the -U option, by appending a percent symbol ("%")
+then the password to username. For example, to attach to a service as
+user "fred" with password "secret", you would specify.
+
+-U fred%secret
+
+on the command line. Note that there are no spaces around the percent
+symbol.
+
+If you specify the password as part of username then the -N option
+(suppress password prompt) is assumed.
+
+If you specify the password as a parameter AND as part of username
+then the password as part of username will take precedence. Putting
+nothing before or nothing after the percent symbol will cause an empty
+username or an empty password to be used, respectively.
+
+The password may also be specified by setting up an environment
+variable called PASSWORD that contains the users password. Note
+that this may be very insecure on some systems but on others allows
+users to script rpcclient commands without having a password appear in
+the command line of a process listing.
+
+Note: Some servers (including OS/2 and Windows for Workgroups) insist
+on an uppercase password. Lowercase or mixed case passwords may be
+rejected by these servers.
+
+Be cautious about including passwords in scripts or in the
+PASSWORD environment variable. Also, on many systems the command
+line of a running process may be seen via the ps command to be
+safe always allow rpcclient to prompt for a password and type it in
+directly.
+
+o -t terminal code This option tells rpcclient how to interpret
+filenames coming from the remote server. Usually Asian language
+multibyte UNIX implementations use different character sets than
+SMB/CIFS servers (EUC instead of SJIS for example). Setting
+this parameter will let rpcclient convert between the UNIX filenames
+and the SMB filenames correctly. This option has not been seriously
+tested and may have some problems.
+
+The terminal codes include sjis, euc, jis7, jis8,
+junet, hex, cap. This is not a complete list, check the
+Samba source code for the complete list.
+
+o -m max protocol level With the new code in Samba2.0,
+rpcclient always attempts to connect at the maximum
+protocols level the server supports. This parameter is
+preserved for backwards compatibility, but any string
+following the -m will be ignored.
+
+o -W Domain Override the default Domain, which is the remote server's
+Domain. This option may be needed to connect to some servers. It is also
+possible to specify the remote server name as the Domain, which will
+force the username and password to be authenticated against the remote
+server's local SAM instead of the Domain SAM.
+
+o -c command string command string is a semicolon separated
+list of commands to be executed instead of prompting from stdin.
+-N is implied by -c.
+
+This is particularly useful in scripts, e.g. -c 'lsaquery; enumusers -u'.
+
+OPERATIONS
+
+Once the client is running, the user is presented with a prompt :
+
+smb:\>
+
+The prompt indicates that the client is ready and waiting to carry out
+a user command. Each command is a single word, optionally followed by
+parameters specific to that command. Command and parameters are
+space-delimited unless these notes specifically state otherwise. All
+commands are case-insensitive. Parameters to commands may or may not
+be case sensitive, depending on the command.
+
+You can specify names (e.g registry keys; user or group names;
+service names) which have spaces in them by quoting the
+name with double quotes, for example "dRMON SmartAgent".
+
+Parameters shown in square brackets (e.g., "[parameter]") are
+optional. If not given, the command will use suitable
+defaults. Parameters shown in angle brackets (e.g., "<parameter>") are
+required.
+
+Note that all commands operating on the server are actually performed
+by issuing a request to the server. Thus the behavior may vary from
+server to server, depending on how the server was implemented.
+
+The commands available are listed in groups relating to different services:
+
+o Misccellaneous
+
+ o ? [command] If "command" is specified,
+ the ? command will display a brief informative message about the
+ specified command. If no command is specified, a list of available
+ commands will be displayed.
+
+ o ! [shell command] If "shell command"
+ is specified, the ! command will execute a shell locally and run
+ the specified shell command. If no command is specified, a local shell
+ will be run.
+
+ o exit Terminate the connection with the server and
+ exit from the program.
+
+ o help [command] See the ?
+ command above.
+
+ o quit See the exit command.
+
+o Event Log
+
+ o eventlog
+ list the events
+
+o Service Control
+
+ It is possible to use command-line completion (if you have
+ the GNU readline library) for Service names, by pressing the
+ tab key.
+
+ o svcenum
+ [-i] Lists Services Manager
+
+ o svcinfo
+ <service> Service Information
+
+ o svcstart
+ <service> [arg 0] [arg 1] ... Start Service
+
+ o svcstop
+ <service> Stop Service
+
+o Scheduler
+
+ o at
+ Scheduler control (at /? for syntax)
+
+o Registry
+
+ It is possible to use command-line completion (if you have
+ the GNU readline library) for registry key and value names,
+ by pressing the tab key.
+
+ o regenum
+ <keyname> Registry Enumeration (keys, values)
+
+ o regdeletekey
+ <keyname> Registry Key Delete
+
+ o regcreatekey
+ <keyname> [keyclass] Registry Key Create
+
+ o shutdown
+ [-m message] [-t timeout] [-r or --reboot] Server Shutdown
+
+ o regqueryval
+ <valname> Registry Value Query
+
+ o regquerykey
+ <keyname> Registry Key Query
+
+ o regdeleteval
+ <valname> Registry Value Delete
+
+ o regcreateval
+ <valname> <valtype> <value> Registry Key Create
+
+ o reggetsec
+ <keyname> Registry Key Security
+
+ o regtestsec
+ <keyname> Test Registry Key Security
+
+o Printing
+
+ It is possible to use command-line completion (if you have
+ the GNU readline library) for Printer and job names, by
+ pressing the tab key.
+
+ o spoolenum
+ Enumerate Printers
+
+ o spooljobs
+ <printer name> Enumerate Printer Jobs
+
+ o spoolopen
+ <printer name> Spool Printer Open Test
+
+o Server
+
+ o time
+ Display remote time
+
+ o brsinfo
+ Browser Query Info
+
+ o wksinfo
+ Workstation Query Info
+
+ o srvinfo
+ Server Query Info
+
+ o srvsessions
+ List sessions on a server
+
+ o srvshares
+ List shares on a server
+
+ o srvtransports
+ List transports on a server
+
+ o srvconnections
+ List connections on a server
+
+ o srvfiles
+ List files on a server
+
+o Local Security Authority
+
+ o lsaquery
+ Query Info Policy (domain member or server)
+
+ o lsaenumdomains
+ Enumerate Trusted Domains
+
+ o lookupsids
+ Resolve names from SIDs
+
+ o lookupnames
+ Resolve SIDs from names
+
+ o querysecret
+ LSA Query Secret (developer use)
+
+o NETLOGON
+
+ o ntlogin
+ [username] [password] NT Domain login test
+
+ o domtrust
+ <domain> NT Inter-Domain test
+
+ o samsync
+ SAM Synchronization Test (experimental)
+
+o SAM Database
+
+ It is possible to use command-line completion (if you have
+ the GNU readline library) for user, group, alias and domain
+ names, by pressing the tab key.
+
+ o lookupdomain
+ Obtain SID for a local domain
+
+ o enumusers
+ SAM User Database Query (experimental!)
+
+ o addgroupmem
+ <group rid> [user] [user] ... SAM Add Domain Group Member
+
+ o addaliasmem
+ <alias rid> [member sid1] [member sid2] ... SAM Add Domain Alias Member
+
+ o delgroupmem
+ <group rid> [user] [user] ... SAM Delete Domain Group Member
+
+ o delaliasmem
+ <alias rid> [member sid1] [member sid2] ... SAM Delete Domain Alias Member
+
+ o creategroup
+ SAM Create Domain Group
+
+ o createalias
+ SAM Create Domain Alias
+
+ o createuser
+ <username> SAM Create Domain User
+
+ o delgroup
+ SAM Delete Domain Group
+
+ o delalias
+ SAM Delete Domain Alias
+
+ o ntpass
+ NT SAM Password Change
+
+ o samuserset2
+ <username> [-s acb_bits] SAM User Set Info 2 (experimental!)
+
+ o samuserset
+ <username> [-p password] SAM User Set Info (experimental!)
+
+ o samuser
+ <username> SAM User Query (experimental!)
+
+ o samgroup
+ <groupname> SAM Group Query (experimental!)
+
+ o samalias
+ <aliasname> SAM Alias Query
+
+ o samaliasmem
+ <aliasname> SAM Alias Members
+
+ o samgroupmem
+ SAM Group Members
+
+ o samtest
+ SAM User Encrypted RPC test (experimental!)
+
+ o enumaliases
+ SAM Aliases Database Query (experimental!)
+
+ o enumdomains
+ SAM Domains Database Query (experimental!)
+
+ o enumgroups
+ SAM Group Database Query (experimental!)
+
+ o dominfo
+ SAM Query Domain Info
+
+ o dispinfo
+ SAM Query Display Info
+
+NOTES
+
+Some servers are fussy about the case of supplied usernames,
+passwords, share names (AKA service names) and machine names. If you
+fail to connect try giving all parameters in uppercase.
+
+It is often necessary to use the -n option when connecting
+to some types of servers. For example OS/2 LanManager insists on a valid
+NetBIOS name being used, so you need to supply a valid name that would
+be known to the server.
+
+rpcclient only works on servers that support MSRPC over SMB. This includes
+all versions of Windows NT, including the ports to Unix such as AS/U and
+AFPS. Support for MSRPC over SMB in other servers is currently rare and
+patchy, for example Samba 2.0 only supports a limited set of MSRPC commands,
+and some of those are not supported very well.
+
+ENVIRONMENT VARIABLES
+
+The variable USER may contain the username of the person using the
+client. This information is used only if the protocol level is high
+enough to support session-level passwords.
+
+The variable PASSWORD may contain the password of the person using
+the client. This information is used only if the protocol level is
+high enough to support session-level passwords.
+
+INSTALLATION
+
+The location of the client program is a matter for individual system
+administrators. The following are thus suggestions only.
+
+It is recommended that the rpcclient software be installed in the
+/usr/local/samba/bin or /usr/samba/bin directory, this directory
+readable by all, writeable only by root. The client program itself
+should be executable by all. The client should NOT be setuid or
+setgid!
+
+The client log files should be put in a directory readable and
+writeable only by the user.
+
+To test the client, you will need to know the name of a running
+SMB/CIFS server. It is possible to run smbd (8)
+an ordinary user - running that server as a daemon on a
+user-accessible port (typically any port number over 1024) would
+provide a suitable test server.
+
+DIAGNOSTICS
+
+Most diagnostics issued by the client are logged in a specified log
+file. The log file name is specified at compile time, but may be
+overridden on the command line.
+
+The number and nature of diagnostics available depends on the debug
+level used by the client. If you have problems, set the debug level to
+3 and peruse the log files.
+
+VERSION
+
+This man page is correct for version 2.0 of the Samba suite.
+
+BUGS
+
+o WARNING!
+The MSPRC over SMB code has been developed from examining Network traces.
+No documentation is available from the original creators (Microsoft) on
+how MSRPC over SMB works, or how the individual MSRPC services work.
+Microsoft's implementation of these services has been demonstrated (and
+reported) to be... a bit flakey in places.
+
+The development of Samba's implementation of these services is also
+a bit rough, and as more of the services are understood, it can even result
+in versions of smbd (8) and rpcclient that are
+incompatible for some commands or services. Additionally, the developers
+are sending reports to Microsoft, and problems found by or reported to
+Microsoft are fixed in Service Packs, which may also result in
+incompatibilities.
+
+It is therefore not guaranteed that the execution of an rpcclient command will
+work. It is also not guaranteed that the target server will continue to
+operate, i.e the execution of an MSRPC command may cause a remote service to
+fail, or even cause the remote server to fail. Usual rules apply, of course:
+the developers bear absolutely no responsibility for the use, misuse, or
+lack of use of rpcclient, by any person or persons, whether legal,
+illegal, accidental, deliberate, intentional, malicious, curious, etc.
+
+o Command Completion
+Command-completion (available if you have the GNU readline library) used on
+certain commands may not operate correctly if the word being completed (such as a registry key) contains a space. Typically, the name will be completed, but
+you will have to go back and put quotes round it, yourself.
+
+o SAM Database command-completion
+Command-completion (available if you have the GNU readline library) of user,
+group and alias names does not work on remote Domains, which would normally
+be specified like this:
+
+DOMAIN_name\\user_name.
+
+The only names that can be completed in this fashion are the local names
+in the SAM database of the target server.
+
+AUTHOR
+
+The original Samba software and related utilities were created by
+Andrew Tridgell samba-bugs@samba.org. Samba is now developed
+by the Samba Team as an Open Source project similar to the way the
+Linux kernel is developed.
+
+The original Samba man pages were written by Karl Auer. The man page
+sources were converted to YODL format (another excellent piece of Open
+Source software, available at
+ftp://ftp.icce.rug.nl/pub/unix/)
+and updated for the Samba2.0 release by Jeremy Allison. This man page
+was developed cut-and-paste style from the smbclient man page, by
+Luke Kenneth Casson Leighton.
+samba-bugs@samba.org.
+
+See samba (7) to find out how to get a full
+list of contributors and details on how to submit bug reports,
+comments etc.
diff --git a/docs/textdocs/security_level.txt b/docs/textdocs/security_level.txt
index 9c4680ebe11..10d014a9a25 100644
--- a/docs/textdocs/security_level.txt
+++ b/docs/textdocs/security_level.txt
@@ -1,5 +1,5 @@
!==
-!== security_level.txt for Samba release 2.0.4 18 May 1999
+!== security_level.txt for Samba release TNG-prealpha 24 Feb 2000
!==
Contributor: Andrew Tridgell
Updated: June 27, 1997
@@ -59,16 +59,16 @@ maintain multiple authentication contexts in this way (WinDD is an
example of an application that does this)
-Ok, now for share level security. In share level security the client
-authenticates itself separately for each share. It will send a
-password along with each "tree connection" (share mount). It does not
-explicitly send a username with this operation. The client is
-expecting a password to be associated with each share, independent of
-the user. This means that samba has to work out what username the
-client probably wants to use. It is never explicitly sent the
-username. Some commercial SMB servers such as NT actually associate
-passwords directly with shares in share level security, but samba
-always uses the unix authentication scheme where it is a
+Ok, now for share level security. In share level security (the default
+with samba) the client authenticates itself separately for each
+share. It will send a password along with each "tree connection"
+(share mount). It does not explicitly send a username with this
+operation. The client is expecting a password to be associated with
+each share, independent of the user. This means that samba has to work
+out what username the client probably wants to use. It is never
+explicitly sent the username. Some commercial SMB servers such as NT actually
+associate passwords directly with shares in share level security, but
+samba always uses the unix authentication scheme where it is a
username/password that is authenticated, not a "share/password".
Many clients send a "session setup" even if the server is in share
diff --git a/docs/yodldocs/DOMAIN_MEMBER.yo b/docs/yodldocs/DOMAIN_MEMBER.yo
index f52b6ab97c2..2b05c0e8148 100644
--- a/docs/yodldocs/DOMAIN_MEMBER.yo
+++ b/docs/yodldocs/DOMAIN_MEMBER.yo
@@ -1,6 +1,6 @@
mailto(samba-bugs@samba.org)
-article(Joining an NT Domain with Samba 2.0)(Jeremy Allison, Samba Team)(7th October 1999)
+article(Joining an NT Domain with Samba 2.0)(Jeremy Allison, Samba Team)(11th November 1998)
center(Joining an NT Domain with Samba 2.0)
center(-----------------------------------)
@@ -8,8 +8,7 @@ center(-----------------------------------)
In order for a Samba-2 server to join an NT domain, you must first add
the NetBIOS name of the Samba server to the NT domain on the PDC using
Server Manager for Domains. This creates the machine account in the
-domain (PDC) SAM. Note that you should add the Samba server as a "Windows
-NT Workstation or Server", em(NOT) as a Primary or backup domain controller.
+domain (PDC) SAM.
Assume you have a Samba-2 server with a NetBIOS name of tt(SERV1) and are
joining an NT domain called tt(DOM), which has a PDC with a NetBIOS name
@@ -22,7 +21,7 @@ command
tt(smbpasswd -j DOM -r DOMPDC)
as we are joining the domain DOM and the PDC for that domain (the only
-machine that has write access to the domain SAM database) is DOMPDC. If this is
+machine that has write access to the domain SAM database). If this is
successful you will see the message:
tt(smbpasswd: Joined domain DOM.)
@@ -32,8 +31,8 @@ man page for more details.
This command goes through the machine account password change
protocol, then writes the new (random) machine account password for
-this Samba server into a file in the same directory in which an
-smbpasswd file would be stored - normally :
+this Samba server into the a file in the same directory in which an
+smbpasswd file would be stored (normally :
tt(/usr/local/samba/private)
@@ -73,10 +72,6 @@ tt(workgroup = DOM)
as this is the name of the domain we are joining.
-You must also have the parameter url(bf("encrypt passwords"))(smb.conf.5.html#encryptpasswords)
-set to tt("yes") in order for your users to authenticate to the
-NT PDC.
-
Finally, add (or modify) a:
url(bf("password server ="))(smb.conf.5.html#passwordserver)
@@ -91,16 +86,20 @@ each of these servers in order, so you may want to rearrange this list
in order to spread out the authentication load among domain
controllers.
-Alternatively, if you want smbd to automatically determine the
-list of Domain controllers to use for authentication, you may set this line to be :
-
-tt(password server = *)
-
-This method, which is new in Samba 2.0.6 and above, allows Samba
-to use exactly the same mechanism that NT does. This method either broadcasts or
-uses a WINS database in order to find domain controllers to
+Currently, Samba requires that a defined list of domain controllers be
+listed in this parameter in order to authenticate with domain-level
+security. NT does not use this method, and will either broadcast or
+use a WINS database in order to find domain controllers to
authenticate against.
+Originally, I considered this idea for Samba, but dropped it because
+it seemed so insecure. However several Samba-2 alpha users have
+requested that this feature be added to make Samba more NT-like, so
+I'll probably add a special name of tt('*') (which means: act like NT
+when looking for domain controllers) in a future release of the
+code. At present, however, you need to know where your domain
+controllers are.
+
Finally, restart your Samba daemons and get ready for clients to begin
using domain security!
diff --git a/docs/yodldocs/LDAP.yo b/docs/yodldocs/LDAP.yo
new file mode 100644
index 00000000000..cf454904d33
--- /dev/null
+++ b/docs/yodldocs/LDAP.yo
@@ -0,0 +1,161 @@
+mailto(samba-bugs@samba.org)
+article(LDAP Support in Samba)(Matthew Chapman)(29th November 1998
+htmltag(p)(1) htmltag(hr)(1) htmltag(h2)(1)
+WARNING: This is experimental code. Use at your own risk, and please report
+any bugs (after reading BUGS.txt).
+htmltag(h2)(0) htmltag(br)(1)
+)
+redef(PARAGRAPH)(0)(htmlcommand(<p>
+) txtcommand(
+
+))
+
+sect(What is LDAP?)
+A directory is a type of hierarchical database optimised for simple query
+operations, often used for storing user information. LDAP is the
+Lightweight Directory Access Protocol, a protocol which is rapidly
+becoming the Internet standard for accessing directories.
+
+Many client applications now support LDAP (including Microsoft's Active
+Directory), and there are a number of servers available. The most popular
+implementation for Unix is from the em(University of Michigan); its
+homepage is at url(tt(http://www.umich.edu/~dirsvcs/ldap/))(http://www.umich.edu/~dirsvcs/ldap/).
+
+Information in an LDAP tree always comes in tt(attribute=value) pairs.
+The following is an example of a Samba user entry:
+
+verb(uid=jbloggs, dc=samba, dc=org
+objectclass=sambaAccount
+uid=jbloggs
+cn=Joe Bloggs
+description=Samba User
+uidNumber=500
+gidNumber=500
+rid=2000
+grouprid=2001
+lmPassword=46E389809F8D55BB78A48108148AD508
+ntPassword=1944CCE1AD6F80D8AEC9FC5BE77696F4
+pwdLastSet=35C11F1B
+smbHome=\\samba1\jbloggs
+homeDrive=Z
+script=logon.bat
+profile=\\samba1\jbloggs\profile
+workstations=JOE)
+
+Note that the top line is a special set of attributes called a
+em(distinguished name) which identifies the location of this entry beneath
+the directory's root node. Recent Internet standards suggest the use of
+domain-based naming using tt(dc) attributes (for instance, a microsoft.com
+directory should have a root node of tt(dc=microsoft, dc=com)), although
+this is not strictly necessary for isolated servers.
+
+There are a number of LDAP-related FAQ's on the internet, although
+generally the best source of information is the documentation for the
+individual servers.
+
+
+nl()
+sect(Why LDAP and Samba?)
+
+Using an LDAP directory allows Samba to store user and group information
+more reliably and flexibly than the current combination of smbpasswd,
+smbgroup, groupdb and aliasdb with the Unix databases. If a need emerges
+for extra user information to be stored, this can easily be added without
+loss of backwards compatibility.
+
+In addition, the Samba LDAP schema is compatible with RFC2307, allowing
+Unix password database information to be stored in the same entries. This
+provides a single, consistent repository for both Unix and Windows user
+information.
+
+
+nl()
+sect(Using LDAP with Samba)
+
+starteit()
+
+eit() Install and configure an LDAP server if you do not already have
+one. You should read your LDAP server's documentation and set up the
+configuration file and access control as desired.
+
+eit() Build Samba (latest CVS is required) with:
+
+verb( ./configure --with-ldap
+ make clean; make install)
+
+eit() Add the following options to the global section of tt(smb.conf) as
+required.
+
+startdit()
+dit(ldap suffix)
+
+This parameter specifies the node of the LDAP tree beneath which
+Samba should store its information. This parameter MUST be provided
+when using LDAP with Samba.
+
+ bf(Default:) tt(none)
+
+ bf(Example:) tt(ldap suffix = "dc=mydomain, dc=org")
+
+dit(ldap bind as)
+
+This parameter specifies the entity to bind to an LDAP directory as.
+Usually it should be safe to use the LDAP root account; for larger
+installations it may be preferable to restrict Samba's access.
+
+ bf(Default:) tt(none (bind anonymously))
+
+ bf(Example:) tt(ldap bind as = "uid=root, dc=mydomain, dc=org")
+
+dit(ldap passwd file)
+
+This parameter specifies a file containing the password with which
+Samba should bind to an LDAP server. For obvious security reasons
+this file must be set to mode 700 or less.
+
+ bf(Default:) tt(none (bind anonymously))
+
+ bf(Example:) tt(ldap passwd file = /usr/local/samba/private/ldappasswd)
+
+dit(ldap server)
+
+This parameter specifies the DNS name of the LDAP server to use
+when storing and retrieving information about Samba users and
+groups.
+
+ bf(Default:) tt(ldap server = localhost)
+
+dit(ldap port)
+
+This parameter specifies the TCP port number of the LDAP server.
+
+ bf(Default:) tt(ldap port = 389)
+
+enddit()
+
+eit() You should then be able to use the normal smbpasswd(8) command for
+account administration (or User Manager in the near future).
+
+endeit()
+
+
+nl()
+sect(Using LDAP for Unix authentication)
+
+The Samba LDAP code was designed to utilise RFC2307-compliant directory
+entries if available. RFC2307 is a proposed standard for LDAP user
+information which has been adopted by a number of vendors. Further
+information is available at url(tt(http://www.xedoc.com.au/~lukeh/ldap/))(http://www.xedoc.com.au/~lukeh/ldap).
+
+Of particular interest is Luke Howard's nameservice switch module
+(nss_ldap) and PAM module (pam_ldap) implementing this standard, providing
+LDAP-based password databases for Unix. If you are setting up a server to
+provide integrated Unix/NT services than these are worth investigating.
+
+
+nl()
+sect(Compatibility with Active Directory)
+
+The current implementation is not designed to be used with Microsoft
+Active Directory, although compatibility may be added in the future.
+
diff --git a/docs/yodldocs/debug2html.1.yo b/docs/yodldocs/debug2html.1.yo
new file mode 100644
index 00000000000..ffbd3c5b0e7
--- /dev/null
+++ b/docs/yodldocs/debug2html.1.yo
@@ -0,0 +1,62 @@
+mailto(samba-bugs@samba.org)
+
+IFDEF(html)\
+(manpage(htmlcommand(debug2html(1)))(1)(29 Dec 1998)(Samba)(SAMBA))\
+(manpage(debug2html)(1)(29 Dec 1998)(Samba)(SAMBA))
+
+label(NAME)
+manpagename(debug2html)(Samba DEBUG to HTML translation filter)
+
+label(SYNOPSIS)
+manpagesynopsis()
+
+debug2html [input-file [output-file]]
+
+label(DESCRIPTION)
+manpagedescription()
+
+This program is part of the bf(Samba) suite.
+
+bf(debug2html) generates HTML files from Samba log files. Log files
+produced by bf(nmbd)(8) or bf(smbd)(8) may then be viewed by a web
+browser. The output conforms to the HTML 3.2 specification.
+
+The filenames specified on the command line are optional. If the
+output-file is ommitted, output will go to bf(stdout). If the input-file
+is ommitted, bf(debug2html) will read from bf(stdin). The filename "-"
+can be used to indicate that input should be read from bf(stdin). For
+example:
+
+tt(cat /usr/local/samba/var/log.nmb | debug2html - nmblog.html) nl()
+
+label(VERSION)
+manpagesection(VERSION)
+
+This man page is correct for version 2.0 of the Samba suite.
+
+label(SEEALSO)
+manpageseealso()
+
+url(bf(nmbd)(8))(nmbd.8.html), url(bf(smbd)(8))(smbd.8.html),
+url(bf(samba)(7))(samba.7.html).
+
+label(AUTHOR)
+manpageauthor()
+
+The original Samba software and related utilities were created by
+Andrew Tridgell email(samba-bugs@samba.org). Samba is now developed
+by the Samba Team as an Open Source project similar to the way the
+Linux kernel is developed.
+
+The original Samba man pages were written by Karl Auer. The man page
+sources were converted to YODL format (another excellent piece of Open
+Source software, available at
+url(bf(ftp://ftp.icce.rug.nl/pub/unix/))(ftp://ftp.icce.rug.nl/pub/unix/))
+and updated for the Samba2.0 release by Jeremy Allison.
+email(samba-bugs@samba.org).
+
+bf(debug2html) was added by Chris Hertel.
+
+See url(bf(samba)(7))(samba.7.html) to find out how to get a full
+list of contributors and details on how to submit bug reports,
+comments etc.
diff --git a/docs/yodldocs/nmbd.8.yo b/docs/yodldocs/nmbd.8.yo
index d7583710ce5..bf9a5f8b78c 100644
--- a/docs/yodldocs/nmbd.8.yo
+++ b/docs/yodldocs/nmbd.8.yo
@@ -9,7 +9,7 @@ naming services to clients)
label(SYNOPSIS)
manpagesynopsis()
-bf(nmbd) [link(-D)(minusD)] [link(-a)(minusa)] [link(-o)(minuso)] [link(-h)(minush)] [link(-V)(minusV)] [link(-H lmhosts file)(minusH)] [link(-d debuglevel)(minusd)] [link(-l log file basename)(minusl)] [link(-n primary NetBIOS name)(minusn)] [link(-p port number)(minusp)] [link(-s configuration file)(minuss)]
+bf(nmbd) [link(-D)(minusD)] [link(-o)(minuso)] [link(-a)(minusa)] [link(-H lmhosts file)(minusH)] [link(-d debuglevel)(minusd)] [link(-l log file basename)(minusl)] [link(-n primary NetBIOS name)(minusn)] [link(-p port number)(minusp)] [link(-s configuration file)(minuss)] [link(-i NetBIOS scope)(minusi)] [link(-h)(minush)]
label(DESCRIPTION)
manpagedescription()
@@ -65,12 +65,6 @@ dit(bf(-o)) If this parameter is specified, the log files will be
overwritten when opened. By default, the log files will be appended
to.
-label(minush)
-dit(bf(-h)) Prints the help information (usage) for bf(nmbd).
-
-label(minusV)
-dit(bf(-V)) Prints the version number for bf(nmbd).
-
label(minusH)
dit(bf(-H filename)) NetBIOS lmhosts file.
@@ -142,6 +136,17 @@ this may be changed when Samba is autoconfigured.
The file specified contains the configuration details required by the
server. See url(bf(smb.conf (5)))(smb.conf.5.html) for more information.
+label(minusi)
+dit(bf(-i scope)) This specifies a NetBIOS scope that bf(nmbd) will use
+to communicate with when generating NetBIOS names. For details on the
+use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
+are em(very) rarely used, only set this parameter if you are the
+system administrator in charge of all the NetBIOS systems you
+communicate with.
+
+label(minush)
+dit(bf(-h)) Prints the help information (usage) for bf(nmbd).
+
endit()
label(FILES)
diff --git a/docs/yodldocs/nmblookup.1.yo b/docs/yodldocs/nmblookup.1.yo
index 80ec850be24..6293fd01e5e 100644
--- a/docs/yodldocs/nmblookup.1.yo
+++ b/docs/yodldocs/nmblookup.1.yo
@@ -8,7 +8,7 @@ manpagename(nmblookup)(NetBIOS over TCP/IP client used to lookup NetBIOS names)
label(SYNOPSIS)
manpagesynopsis()
-bf(nmblookup) [link(-M)(minusM)] [link(-R)(minusR)] [link(-S)(minusS)] [link(-r)(minusr)] [link(-A)(minusA)] [link(-h)(minush)] [link(-B broadcast address)(minusB)] [link(-U unicast address)(minusU)] [link(-d debuglevel)(minusd)] [link(-s smb config file)(minuss)] [link(-i NetBIOS scope)(minusi)] [link(-T)(minusT)] link(name)(name)
+bf(nmblookup) [link(-M)(minusM)] [link(-R)(minusR)] [link(-S)(minusS)] [link(-r)(minusr)] [link(-A)(minusA)] [link(-h)(minush)] [link(-B broadcast address)(minusB)] [link(-U unicast address)(minusU)] [link(-d debuglevel)(minusd)] [link(-s smb config file)(minuss)] [link(-i NetBIOS scope)(minusi)] link(name)(name)
label(DESCRIPTION)
manpagedescription()
@@ -26,9 +26,8 @@ manpageoptions()
startdit()
label(minusM)
-dit(bf(-M)) Searches for a master browser by looking up the
-NetBIOS name link(bf(name))(name) with a type of 0x1d. If link(bf(name))(name)
-is tt("-") then it does a lookup on the special name tt(__MSBROWSE__).
+dit(bf(-M)) Searches for a master browser. This is done by doing a
+broadcast lookup on the special name tt(__MSBROWSE__).
label(minusR)
dit(bf(-R)) Set the recursion desired bit in the packet to do a
@@ -62,8 +61,8 @@ dit(bf(-h)) Print a help (usage) message.
label(minusB)
dit(bf(-B broadcast address)) Send the query to the given broadcast
address. Without this option the default behavior of nmblookup is to
-send the query to the broadcast address of the network
-interfaces as either auto-detected or defined in the
+send the query to the broadcast address of the primary network
+interface as either auto-detected or defined in the
url(bf(interfaces))(smb.conf.5.html#interfaces) parameter of the
url(bf(smb.conf (5)))(smb.conf.5.html) file.
@@ -104,12 +103,6 @@ are em(very) rarely used, only set this parameter if you are the
system administrator in charge of all the NetBIOS systems you
communicate with.
-label(minusT)
-dit(bf(-T)) This causes any IP addresses found in the lookup to be
-looked up via a reverse DNS lookup into a DNS name, and printed out
-before each tt("IP address NetBIOS name") pair that is the normal
-output.
-
label(name)
dit(bf(name)) This is the NetBIOS name being queried. Depending upon
the previous options this may be a NetBIOS name or IP address. If a
diff --git a/docs/yodldocs/rpcclient.1.yo b/docs/yodldocs/rpcclient.1.yo
new file mode 100644
index 00000000000..88b21047422
--- /dev/null
+++ b/docs/yodldocs/rpcclient.1.yo
@@ -0,0 +1,861 @@
+mailto(samba-bugs@samba.org)
+
+manpage(rpcclient htmlcommand((1)))(1)(23 Oct 1998)(Samba)(SAMBA)
+
+label(NAME)
+manpagename(rpcclient)(utility to manage MSRPC resources on servers)
+
+label(SYNOPSIS)
+manpagesynopsis()
+
+bf(rpcclient)
+[link(password)(password)]
+link(-S servername)(servername)
+[link(-U [username][%][password])(minusU)]
+[link(-W domain)(minusW)]
+[link(-l log basename)(minusl)]
+[link(-d debuglevel)(minusd)]
+[link(-O socket options)(minusO)]
+[link(-i scope)(minusi)]
+[link(-N)(minusN)]
+[link(-n NetBIOS name)(minusn)]
+[link(-h)(minush)]
+[link(-I dest IP)(minusI)]
+[link(-E)(minusE)]
+[link(-t terminal code)(minust)]
+[link(-c command string)(minusc)]
+[link(-B IP addr)(minusB)]
+[link(-s smb.conf)(minuss)]
+[link(-m max protocol)(minusm)]
+
+label(DESCRIPTION)
+manpagedescription()
+
+This program is part of the bf(Samba) suite.
+
+bf(rpcclient) is a client that can 'talk' to an SMB/CIFS MSRPC server.
+Operations include things like managing a SAM Database (users, groups
+and aliases) in the same way as the Windows NT programs
+bf(User Manager for Domains) and bf(Server Manager for Domains);
+managing a remote registry in the same way as the Windows NT programs
+bf(REGEDT32.EXE) and bf(REGEDIT.EXE); viewing a remote event log (same
+as bf(EVENTVWR.EXE)) etc.
+
+Typical usage is like this: nl()
+tt(rpcclient -I 192.168.32.1 -S "*SMBSERVER" -U fred%secret -l log)
+nl()
+
+bf(rpcclient) is em(not) suitable for usage on single-user systems
+such as Windows 9X, as Windows 9X does not support MSRPC services.
+Therefore, if you have problems using bf(rpcclient) with Windows 9X,
+we don't want to hear about it.
+
+label(OPTIONS)
+manpageoptions()
+
+startdit()
+
+label(servername)
+dit(bf(servername)) servername is the name of the server you want
+to use on the server. This should be the NetBIOS name of the SMB/CIFS
+server, which can be bf(*SMBSERVER) on Windows NT 4.0 or Samba Servers.
+
+Note that the server name required is NOT necessarily the IP (DNS)
+host name of the server! The name required is a NetBIOS server name,
+which may or may not be the same as the IP hostname of the machine
+running the server. Also, remember that having a period in a NetBIOS
+name (such as an IP hostname) may cause connectivity problems on your
+network: NT tends to strip NetBIOS names from the leading period
+onwards.
+
+The server name is looked up according to either the
+link(bf(-R))(minusR) parameter to bf(rpcclient) or using the
+url(bf(name resolve order))(smb.conf.5.html#nameresolveorder)
+parameter in the smb.conf file, allowing an administrator to change
+the order and methods by which server names are looked up.
+
+label(password)
+dit(bf(password)) password is the password required to access the
+specified service on the specified server. If this parameter is
+supplied, the link(bf(-N))(minusN) option (suppress password prompt) is assumed.
+
+There is no default password. If no password is supplied on the
+command line (either by using this parameter or adding a password to
+the link(bf(-U))(minusU) option (see below)) and the link(bf(-N))(minusN) option is not specified,
+the client will prompt for a password, even if the desired service
+does not require one. (If no password is required, simply press ENTER
+to provide a null password.)
+
+Note: Some servers (including OS/2 and Windows for Workgroups) insist
+on an uppercase password. Lowercase or mixed case passwords may be
+rejected by these servers.
+
+Be cautious about including passwords in scripts.
+
+label(minuss)
+dit(bf(-s smb.conf)) This parameter specifies the pathname to the
+Samba configuration file, smb.conf. This file controls all aspects of
+the Samba setup on the machine and rpcclient also needs to read this
+file.
+
+label(minusB)
+dit(bf(-B IP addr)) The IP address to use when sending a broadcast packet.
+
+label(minusO)
+dit(bf(-O socket options)) TCP socket options to set on the client
+socket. See the url(socket options)(smb.conf.5.html#socketoptions)
+parameter in the url(bf(smb.conf (5)))(smb.conf.5.html) manpage for
+the list of valid options.
+
+label(minusR)
+dit(bf(-R name resolve order)) This option allows the user of
+rpcclient to determine what name resolution services to use when
+looking up the NetBIOS name of the host being connected to.
+
+The options are :"lmhosts", "host", "wins" and "bcast". They cause
+names to be resolved as follows :
+
+startit()
+
+it() bf(lmhosts) : Lookup an IP address in the Samba lmhosts file.
+The lmhosts file is stored in the same directory as the
+url(bf(smb.conf))(smb.conf.5.html) file.
+
+it() bf(host) : Do a standard host name to IP address resolution,
+using the system /etc/hosts, NIS, or DNS lookups. This method of name
+resolution is operating system depended for instance on IRIX or
+Solaris this may be controlled by the em(/etc/nsswitch.conf) file).
+
+it() bf(wins) : Query a name with the IP address listed in the url(bf(wins
+server))(smb.conf.5.html#winsserver) parameter in the smb.conf file. If
+no WINS server has been specified this method will be ignored.
+
+it() bf(bcast) : Do a broadcast on each of the known local interfaces
+listed in the url(bf(interfaces))(smb.conf.5.html#interfaces) parameter
+in the smb.conf file. This is the least reliable of the name resolution
+methods as it depends on the target host being on a locally connected
+subnet. To specify a particular broadcast address the link(bf(-B))(minusB) option
+may be used.
+
+endit()
+
+If this parameter is not set then the name resolve order defined
+in the url(bf(smb.conf))(smb.conf.5.html) file parameter
+url((bf(name resolve order)))(smb.conf.5.html#nameresolveorder)
+will be used.
+
+The default order is lmhosts, host, wins, bcast and without this
+parameter or any entry in the url(bf("name resolve
+order"))(smb.conf.5.html#nameresolveorder) parameter of the
+url(bf(smb.conf))(smb.conf.5.html) file the name resolution methods
+will be attempted in this order.
+
+label(minusi)
+dit(bf(-i scope)) This specifies a NetBIOS scope that rpcclient will use
+to communicate with when generating NetBIOS names. For details on the
+use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
+are em(very) rarely used, only set this parameter if you are the
+system administrator in charge of all the NetBIOS systems you
+communicate with.
+
+label(minusN)
+dit(bf(-N)) If specified, this parameter suppresses the normal
+password prompt from the client to the user. This is useful when
+accessing a service that does not require a password.
+
+Unless a password is specified on the command line or this parameter
+is specified, the client will request a password.
+
+label(minusn)
+dit(bf(-n NetBIOS name)) By default, the client will use the local
+machine's hostname (in uppercase) as its NetBIOS name. This parameter
+allows you to override the host name and use whatever NetBIOS name you
+wish.
+
+label(minusd)
+dit(bf(-d debuglevel)) debuglevel is an integer from 0 to 10, or the
+letter 'A'.
+
+The default value if this parameter is not specified is zero.
+
+The higher this value, the more detail will be logged to the log files
+about the activities of the client. At level 0, only critical errors
+and serious warnings will be logged. Level 1 is a reasonable level for
+day to day running - it generates a small amount of information about
+operations carried out.
+
+Levels above 1 will generate considerable amounts of log data, and
+should only be used when investigating a problem. Levels above 3 are
+designed for use only by developers and generate HUGE amounts of log
+data, most of which is extremely cryptic. If debuglevel is set to the
+letter 'A', then em(all) debug messages will be printed. This setting
+is for developers only (and people who em(really) want to know how the
+code works internally).
+
+Note that specifying this parameter here will override the url(bf(log
+level))(smb.conf.5.html#loglevel) parameter in the url(bf(smb.conf
+(5)))(smb.conf.5.html) file.
+
+label(minusp)
+dit(bf(-p port)) This number is the TCP port number that will be used
+when making connections to the server. The standard (well-known) TCP
+port number for an SMB/CIFS server is 139, which is the default.
+
+label(minusl)
+dit(bf(-l logfilename)) If specified, logfilename specifies a base
+filename into which operational data from the running client will be
+logged.
+
+The default base name is specified at compile time.
+
+The base name is used to generate actual log file names. For example,
+if the name specified was "log", the debug file would be
+tt(log.client).
+
+The log file generated is never removed by the client.
+
+label(minush)
+dit(bf(-h)) Print the usage message for the client.
+
+label(minusI)
+dit(bf(-I IP address)) IP address is the address of the server to
+connect to. It should be specified in standard "a.b.c.d" notation.
+
+Normally the client would attempt to locate a named SMB/CIFS server by
+looking it up via the NetBIOS name resolution mechanism described
+above in the link(bf(name resolve order))(minusR) parameter
+above. Using this parameter will force the client to assume that the
+server is on the machine with the specified IP address and the NetBIOS
+name component of the resource being connected to will be ignored.
+
+There is no default for this parameter. If not supplied, it will be
+determined automatically by the client as described above.
+
+label(minusE)
+dit(bf(-E)) This parameter causes the client to write messages to the
+standard error stream (stderr) rather than to the standard output
+stream.
+
+By default, the client writes messages to standard output - typically
+the user's tty.
+
+Note that by default, debug information is always sent to stderr.
+Debug information can instead be sent to a file, using the
+link(-l log basename)(minusl) option.
+
+label(minusU)
+dit(bf(-U username)) This specifies the user name that will be used by
+the client to make a connection, assuming your server is not a downlevel
+server that is running a protocol level that uses passwords on shares,
+not on usernames.
+
+Some servers are fussy about the case of this name, and some insist
+that it must be a valid NetBIOS name.
+
+If no username is supplied, it will default to an uppercase version of
+the environment variable tt(USER) or tt(LOGNAME) in that order. If no
+username is supplied and neither environment variable exists the
+username "GUEST" will be used.
+
+If the tt(USER) environment variable contains a '%' character,
+everything after that will be treated as a password. This allows you
+to set the environment variable to be tt(USER=username%password) so
+that a password is not passed on the command line (where it may be
+seen by the ps command).
+
+If the service you are connecting to requires a password, it can be
+supplied using the link(bf(-U))(minusU) option, by appending a percent symbol ("%")
+then the password to username. For example, to attach to a service as
+user tt("fred") with password tt("secret"), you would specify. nl()
+
+tt(-U fred%secret) nl()
+
+on the command line. Note that there are no spaces around the percent
+symbol.
+
+If you specify the password as part of username then the link(bf(-N))(minusN) option
+(suppress password prompt) is assumed.
+
+If you specify the password as a parameter em(AND) as part of username
+then the password as part of username will take precedence. Putting
+nothing before or nothing after the percent symbol will cause an empty
+username or an empty password to be used, respectively.
+
+The password may also be specified by setting up an environment
+variable called tt(PASSWORD) that contains the users password. Note
+that this may be very insecure on some systems but on others allows
+users to script rpcclient commands without having a password appear in
+the command line of a process listing.
+
+Note: Some servers (including OS/2 and Windows for Workgroups) insist
+on an uppercase password. Lowercase or mixed case passwords may be
+rejected by these servers.
+
+Be cautious about including passwords in scripts or in the
+tt(PASSWORD) environment variable. Also, on many systems the command
+line of a running process may be seen via the tt(ps) command to be
+safe always allow rpcclient to prompt for a password and type it in
+directly.
+
+label(minust)
+dit(bf(-t terminal code)) This option tells rpcclient how to interpret
+filenames coming from the remote server. Usually Asian language
+multibyte UNIX implementations use different character sets than
+SMB/CIFS servers (em(EUC) instead of em(SJIS) for example). Setting
+this parameter will let rpcclient convert between the UNIX filenames
+and the SMB filenames correctly. This option has not been seriously
+tested and may have some problems.
+
+The terminal codes include tt(sjis), tt(euc), tt(jis7), tt(jis8),
+tt(junet), tt(hex), tt(cap). This is not a complete list, check the
+Samba source code for the complete list.
+
+label(minusm)
+dit(bf(-m max protocol level)) With the new code in Samba2.0,
+bf(rpcclient) always attempts to connect at the maximum
+protocols level the server supports. This parameter is
+preserved for backwards compatibility, but any string
+following the bf(-m) will be ignored.
+
+label(minusW)
+dit(bf(-W Domain)) Override the default Domain, which is the remote server's
+Domain. This option may be needed to connect to some servers. It is also
+possible to specify the remote server name as the Domain, which will
+force the username and password to be authenticated against the remote
+server's local SAM instead of the Domain SAM.
+
+label(minusc)
+dit(bf(-c command string)) command string is a semicolon separated
+list of commands to be executed instead of prompting from stdin.
+link(bf(-N))(minusN) is implied by bf(-c).
+
+This is particularly useful in scripts, e.g. tt(-c 'lsaquery; enumusers -u').
+
+enddit()
+
+label(OPERATIONS)
+manpagesection(OPERATIONS)
+
+Once the client is running, the user is presented with a prompt :
+
+tt(smb:\>)
+
+The prompt indicates that the client is ready and waiting to carry out
+a user command. Each command is a single word, optionally followed by
+parameters specific to that command. Command and parameters are
+space-delimited unless these notes specifically state otherwise. All
+commands are case-insensitive. Parameters to commands may or may not
+be case sensitive, depending on the command.
+
+You can specify names (e.g registry keys; user or group names;
+service names) which have spaces in them by quoting the
+name with double quotes, for example "dRMON SmartAgent".
+
+Parameters shown in square brackets (e.g., "[parameter]") are
+optional. If not given, the command will use suitable
+defaults. Parameters shown in angle brackets (e.g., "<parameter>") are
+required.
+
+Note that all commands operating on the server are actually performed
+by issuing a request to the server. Thus the behavior may vary from
+server to server, depending on how the server was implemented.
+
+The commands available are listed in groups relating to different services:
+
+startdit()
+
+dit(Misccellaneous)
+
+ startdit()
+
+ label(questionmark) dit(bf(? [command])) If "command" is specified,
+ the bf(?) command will display a brief informative message about the
+ specified command. If no command is specified, a list of available
+ commands will be displayed.
+
+ label(exclaimationmark) dit(bf(! [shell command])) If "shell command"
+ is specified, the bf(!) command will execute a shell locally and run
+ the specified shell command. If no command is specified, a local shell
+ will be run.
+
+ label(exit) dit(bf(exit)) Terminate the connection with the server and
+ exit from the program.
+
+ label(help) dit(bf(help [command])) See the link(bf(?))(questionmark)
+ command above.
+
+ label(quit) dit(bf(quit)) See the link(bf(exit))(exit) command.
+
+ enddit()
+
+dit(Event Log)
+
+ startdit()
+
+ label(eventlog) dit(bf(eventlog))
+ list the events
+
+ enddit()
+
+dit(Service Control)
+
+ These commands provide functionality similar to the Windows
+ NT Service Control Manager.
+
+ It is possible to use command-line completion (if you have
+ the GNU readline library) for Service names, by pressing the
+ tab key.
+
+ startdit()
+
+ label(svcenum) dit(bf(svcenum))
+ [-i] Lists Services.
+
+ label(svcinfo) dit(bf(svcinfo))
+ <service> Service Information
+
+ label(svcstart) dit(bf(svcstart))
+ <service> [arg 0] [arg 1] ... Start Service
+
+ label(svcstop) dit(bf(svcstop))
+ <service> Stop Service
+
+ enddit()
+
+dit(Scheduler)
+
+ startdit()
+
+ label(at) dit(bf(at))
+ Scheduler control (at /? for syntax)
+
+ enddit()
+
+dit(Registry)
+
+ It is possible to use command-line completion (if you have
+ the GNU readline library) for registry key and value names,
+ by pressing the tab key.
+
+ startdit()
+
+ label(regenum) dit(bf(regenum))
+ <keyname> Registry Enumeration (keys, values)
+
+ label(regdeletekey) dit(bf(regdeletekey))
+ <keyname> Registry Key Delete
+
+ label(regcreatekey) dit(bf(regcreatekey))
+ <keyname> [keyclass] Registry Key Create
+
+ label(shutdown) dit(bf(shutdown))
+ [-m message] [-t timeout] [-r or --reboot] Server Shutdown
+
+ label(regqueryval) dit(bf(regqueryval))
+ <valname> Registry Value Query
+
+ label(regquerykey) dit(bf(regquerykey))
+ <keyname> Registry Key Query
+
+ label(regdeleteval) dit(bf(regdeleteval))
+ <valname> Registry Value Delete
+
+ label(regcreateval) dit(bf(regcreateval))
+ <valname> <valtype> <value> Registry Key Create
+
+ label(reggetsec) dit(bf(reggetsec))
+ <keyname> Registry Key Security
+
+ label(regtestsec) dit(bf(regtestsec))
+ <keyname> Test Registry Key Security
+
+ enddit()
+
+dit(Printing)
+
+ It is possible to use command-line completion (if you have
+ the GNU readline library) for Printer and job names, by
+ pressing the tab key.
+
+ startdit()
+
+ label(spoolenum) dit(bf(spoolenum))
+ Enumerate Printers. This experimental command lists
+ all printers available on a remote spooler service.
+
+ label(spooljobs) dit(bf(spooljobs))
+ <printer name> Enumerate Printer Jobs. This
+ experimental command lists all jobs, and their
+ status, currently queued on a remote spooler
+ service.
+
+ label(spoolopen) dit(bf(spoolopen))
+ <printer name> Spool Printer Open Test. Experimental.
+
+ enddit()
+
+dit(Server)
+
+ startdit()
+
+ label(time) dit(bf(time))
+ Display remote time
+
+ label(brsinfo) dit(bf(brsinfo))
+ Browser Query Info
+
+ label(wksinfo) dit(bf(wksinfo))
+ Workstation Query Info
+
+ label(srvinfo) dit(bf(srvinfo))
+ Server Query Info
+
+ label(srvsessions) dit(bf(srvsessions))
+ List sessions on a server
+
+ label(srvshares) dit(bf(srvshares))
+ List shares on a server
+
+ label(srvtransports) dit(bf(srvtransports))
+ List transports on a server
+
+ label(srvconnections) dit(bf(srvconnections))
+ List connections on a server
+
+ label(srvfiles) dit(bf(srvfiles))
+ List files on a server
+
+ enddit()
+
+dit(Local Security Authority)
+
+ startdit()
+
+ label(lsaquery) dit(bf(lsaquery))
+ Query Info Policy (domain member or server). Obtains
+ the SID and name of the SAM database that a server
+ is responsible for (i.e a workstation's local SAM
+ database or the PDC SAM database). Also obtains the
+ SID and name of the SAM database that a server is
+ a member of.
+
+ label(lsaenumdomains) dit(bf(lsaenumdomains))
+ Enumerate Trusted Domains. Lists all Trusted and
+ Trusting Domains with which the remote PDC has
+ trust relationships established.
+
+ label(lookupsids) dit(bf(lookupsids))
+ <rid1 or sid1> <rid1 or sid2> ... Resolve names from SIDs.
+ Mostly to be used by developers or for troubleshooting,
+ this command can take either Security Identifiers or Relative
+ Identifiers, and look them up in the local SAM database
+ (or look them up in a remote Trusting or Trusted PDC's SAM
+ database if there is an appropriate Trust Relationship
+ established). The result is a list of names, of the
+ format: nl()
+ tt([TRUST_DOMAIN\]name). nl()
+ the link(bf(lsaquery))(lsaquery) command must have been
+ issued first if you wish to use lookupsids to resolve
+ RIDs. The only RIDs that will be resolved will be those
+ in the SAM database of the server to which you are connected.
+
+ label(lookupnames) dit(bf(lookupnames))
+ <name1> <name2> ... Resolve SIDs from names.
+ Mostly to be used by developers or for troubleshooting,
+ this command can take names of the following format: nl()
+ tt([DOMAIN_NAME\]name). nl()
+ The names, which can be user, group or alias names, will
+ either be looked up in the local SAM database or in a remote
+ Trusting or Trusted PDC's SAM database, if there is an
+ appropriate Trust Relationship established. The optional
+ Domain name component is the name of a SAM database, which
+ can include a workstation's local SAM database or a Trusted
+ Domain.
+ Example Usage: nl()
+ tt(lookupnames WKSTANAME\Administrator "Domain Guests") nl()
+
+ label(querysecret) dit(bf(querysecret))
+ LSA Query Secret (developer use). This command only appears
+ to work against NT4 SP3 and below. Due to its potential
+ for misuse, it looks like Microsoft modified their
+ implementation of the LsaRetrievePrivateData call to
+ always return NT_STATUS_ACCESS_DENIED.
+
+ enddit()
+
+dit(NETLOGON)
+
+ startdit()
+
+ label(ntlogin) dit(bf(ntlogin))
+ [username] [password] NT Domain login test. Demonstrates
+ how NT-style logins work. Mainly for developer usage,
+ it can also be used to verify that a user can log in
+ from a workstation. If you cannot ever get pam_ntdom
+ to work, try this command first.
+
+ label(domtrust) dit(bf(domtrust))
+ <domain> NT Inter-Domain test. Demonstrates how NT-style
+ Inter-Domain Trust relationships work. Mainly for
+ developer usage, it can also be used to verify that a
+ Trust Relationship is correctly established with a
+ remote PDC.
+
+ label(samsync) dit(bf(samsync))
+ SAM Synchronisation Test (experimental). This command
+ is used to manually synchronise a SAM database from a
+ remote PDC, when Samba is set up as a Backup Domain
+ Controller.
+
+ enddit()
+
+dit(SAM Database)
+
+ The SAM Database holds user, group and alias information.
+ The commands listed below allow operations such as adding
+ user accounts and changing their password; listing known
+ Domains; listing user, group and alias accounts; listing the
+ members of groups and aliases; adding or removing members
+ from groups and aliases.
+
+ The commands that make changes are protected by Access Control
+ permissions on the remote server. You will therefore need to
+ be in the right NT group in order to perform certain operations.
+ If you find that a command fails with an NT_STATUS_ACCESS_DENIED
+ error and you think you should be able to perform that command,
+ talk to your Administrator: your username is probably not in the
+ correct NT alias or group (e.g Account Operators; Domain Admin).
+
+ The commands that view information usually require less
+ user privileges. However, a particular remote server may be
+ configured with better security settings, so a command that
+ succeeds on one server may not succeed on another.
+
+ It is possible to use command-line completion (if you have
+ the GNU readline library) for user, group, alias and domain
+ names, by pressing the tab key.
+
+ startdit()
+
+ label(lookupdomain) dit(bf(lookupdomain))
+ Obtain SID for a local domain
+
+ label(enumusers) dit(bf(enumusers))
+ SAM User Database Query (experimental!)
+
+ label(addgroupmem) dit(bf(addgroupmem))
+ <group rid> [user] [user] ... SAM Add Domain Group Member
+
+ label(addaliasmem) dit(bf(addaliasmem))
+ <alias rid> [member sid1] [member sid2] ... SAM Add Domain Alias Member
+
+ label(delgroupmem) dit(bf(delgroupmem))
+ <group rid> [user] [user] ... SAM Delete Domain Group Member
+
+ label(delaliasmem) dit(bf(delaliasmem))
+ <alias rid> [member sid1] [member sid2] ... SAM Delete Domain Alias Member
+
+ label(creategroup) dit(bf(creategroup))
+ SAM Create Domain Group
+
+ label(createalias) dit(bf(createalias))
+ SAM Create Domain Alias
+
+ label(createuser) dit(bf(createuser))
+ <username> SAM Create Domain User
+
+ label(delgroup) dit(bf(delgroup))
+ SAM Delete Domain Group
+
+ label(delalias) dit(bf(delalias))
+ SAM Delete Domain Alias
+
+ label(ntpass) dit(bf(ntpass))
+ NT SAM Password Change
+
+ label(samuserset2) dit(bf(samuserset2))
+ <username> [-s acb_bits] SAM User Set Info 2 (experimental!)
+
+ label(samuserset) dit(bf(samuserset))
+ <username> [-p password] SAM User Set Info (experimental!)
+
+ label(samuser) dit(bf(samuser))
+ <username> SAM User Query (experimental!)
+
+ label(samgroup) dit(bf(samgroup))
+ <groupname> SAM Group Query (experimental!)
+
+ label(samalias) dit(bf(samalias))
+ <aliasname> SAM Alias Query
+
+ label(samaliasmem) dit(bf(samaliasmem))
+ <aliasname> SAM Alias Members
+
+ label(samgroupmem) dit(bf(samgroupmem))
+ SAM Group Members
+
+ label(samtest) dit(bf(samtest))
+ SAM User Encrypted RPC test (experimental!)
+
+ label(enumaliases) dit(bf(enumaliases))
+ SAM Aliases Database Query (experimental!)
+
+ label(enumdomains) dit(bf(enumdomains))
+ SAM Domains Database Query (experimental!)
+
+ label(enumgroups) dit(bf(enumgroups))
+ SAM Group Database Query (experimental!)
+
+ label(dominfo) dit(bf(dominfo))
+ SAM Query Domain Info
+
+ label(dispinfo) dit(bf(dispinfo))
+ SAM Query Display Info
+
+ enddit()
+
+enddit()
+
+
+label(NOTES)
+manpagesection(NOTES)
+
+Some servers are fussy about the case of supplied usernames,
+passwords, share names (AKA service names) and machine names. If you
+fail to connect try giving all parameters in uppercase.
+
+It is often necessary to use the link(bf(-n))(minusn) option when connecting
+to some types of servers. For example OS/2 LanManager insists on a valid
+NetBIOS name being used, so you need to supply a valid name that would
+be known to the server.
+
+rpcclient only works on servers that support MSRPC over SMB. This includes
+all versions of Windows NT, including the ports to Unix such as AS/U and
+AFPS. Support for MSRPC over SMB in other servers is currently rare and
+patchy, for example Samba 2.0 only supports a limited set of MSRPC commands,
+and some of those are not supported very well.
+
+label(ENVIRONMENTVARIABLES)
+manpagesection(ENVIRONMENT VARIABLES)
+
+The variable bf(USER) may contain the username of the person using the
+client. This information is used only if the protocol level is high
+enough to support session-level passwords.
+
+The variable bf(PASSWORD) may contain the password of the person using
+the client. This information is used only if the protocol level is
+high enough to support session-level passwords.
+
+label(INSTALLATION)
+manpagesection(INSTALLATION)
+
+The location of the client program is a matter for individual system
+administrators. The following are thus suggestions only.
+
+It is recommended that the rpcclient software be installed in the
+/usr/local/samba/bin or /usr/samba/bin directory, this directory
+readable by all, writeable only by root. The client program itself
+should be executable by all. The client should em(NOT) be setuid or
+setgid!
+
+The client log files should be put in a directory readable and
+writeable only by the user.
+
+To test the client, you will need to know the name of a running
+SMB/CIFS server. It is possible to run url(bf(smbd (8)))(smbd.8.html)
+an ordinary user - running that server as a daemon on a
+user-accessible port (typically any port number over 1024) would
+provide a suitable test server.
+
+label(DIAGNOSTICS)
+manpagesection(DIAGNOSTICS)
+
+Most diagnostics issued by the client are logged in a specified log
+file. The log file name is specified at compile time, but may be
+overridden on the command line.
+
+The number and nature of diagnostics available depends on the debug
+level used by the client. If you have problems, set the debug level to
+3 and peruse the log files.
+
+label(VERSION)
+manpagesection(VERSION)
+
+This man page is correct for version 2.0 of the Samba suite.
+
+label(BUGS)
+manpagesection(BUGS)
+
+startdit()
+dit(WARNING!)
+The MSPRC over SMB code has been developed from examining Network traces.
+No documentation is available from the original creators (Microsoft) on
+how MSRPC over SMB works, or how the individual MSRPC services work.
+Microsoft's implementation of these services has been demonstrated (and
+reported) to be... a bit flakey in places.
+
+The development of Samba's implementation of these services is em(also)
+a bit rough, and as more of the services are understood, it can even result
+in versions of url(bf(smbd (8)))(smbd.8.html) and rpcclient that are
+backwards-incompatible for some commands or services. Additionally, the
+developers are sending reports to Microsoft, and problems found by or
+reported to Microsoft are fixed in Service Packs, which may also result in
+incompatibilities.
+
+It is therefore not guaranteed that the execution of an rpcclient command will
+work. It is also not guaranteed that the target server will continue to
+operate, i.e the execution of an MSRPC command may cause a remote service to
+fail, or even cause the remote server to fail. Usual rules apply, of course:
+the developers bear absolutely no responsibility or liability for the use,
+misuse, or lack of use of rpcclient, by any person or persons, whether legal,
+illegal, accidental, deliberate, intentional, malicious, curious, etc.
+
+This em(particularly) applies to the registry and SAM database commands.
+As you are using a command-line tool not a mouse-clicky tool, you have
+already proven yourself to be savvy, however if you don't know what you're
+doing, then em(don't do it!).
+
+dit(Command Completion)
+Command-completion (available if you have the GNU readline library) used on
+certain commands may not operate correctly if the word being completed (such as a registry key) contains a space. Typically, the name will be completed, but
+you will have to go back and put quotes round it, yourself.
+
+dit(SAM Database command-completion)
+Command-completion (available if you have the GNU readline library) of user,
+group and alias names does not work on remote Domains, which would normally
+be specified like this: nl()
+tt(DOMAIN_name\user_name). nl()
+The only names that can be completed in this fashion are the local names
+in the SAM database of the target server.
+
+dit(link(bf(spoolenum))(spoolenum))
+Due to current limitations in the rpcclient MSRPC / SMB code, and due to
+the extremely poor MSRPC implementation (by Microsoft) of the spooler
+service, if there are a large number of printers (or the names / comment
+fields associated with the printers), this command will fail. The
+limitations require further research to be carried out; we're stuck with
+the poor \PIPE\spoolss design.
+
+endit()
+
+label(AUTHOR)
+manpageauthor()
+
+The original Samba software and related utilities were created by
+Andrew Tridgell email(samba-bugs@samba.org). Samba is now developed
+by the Samba Team as an Open Source project similar to the way the
+Linux kernel is developed.
+
+The original Samba man pages were written by Karl Auer. The man page
+sources were converted to YODL format (another excellent piece of Open
+Source software, available at
+url(bf(ftp://ftp.icce.rug.nl/pub/unix/))(ftp://ftp.icce.rug.nl/pub/unix/))
+and updated for the Samba2.0 release by Jeremy Allison. This man page
+was developed cut-and-paste style from the smbclient man page, by
+Luke Kenneth Casson Leighton.
+email(samba-bugs@samba.org).
+
+See url(bf(samba (7)))(samba.7.html) to find out how to get a full
+list of contributors and details on how to submit bug reports,
+comments etc.
+
diff --git a/docs/yodldocs/samba.7.yo b/docs/yodldocs/samba.7.yo
index dc238bd0fc9..ff4ff2796b5 100644
--- a/docs/yodldocs/samba.7.yo
+++ b/docs/yodldocs/samba.7.yo
@@ -47,6 +47,15 @@ servers (such as Windows NT), and can also be used to allow a UNIX box
to print to a printer attached to any SMB server (such as a PC running
Windows NT).
+dit(url(bf(rpcclient))(rpcclient.1.html)) nl() nl() The url(bf(rpcclient)
+(1))(rpcclient.1.html) program is a client that can 'talk' to an
+SMB/CIFS MSRPC server. Operations include things like managing a SAM
+Database (users, groups and aliases) in the same way as the Windows NT
+programs bf(User Manager for Domains) and bf(Server Manager for Domains);
+managing a remote registry in the same way as the Windows NT programs
+bf(REGEDT32.EXE) and bf(REGEDIT.EXE); viewing a remote event log (same
+as bf(EVENTVWR.EXE)).
+
dit(url(bf(testparm))(testparm.1.html)) nl() nl() The url(bf(testparm
(1)))(testparm.1.html) utility allows you to test your url(bf(smb.conf
(5)))(smb.conf.5.html) configuration file.
diff --git a/docs/yodldocs/smb.conf.5.yo b/docs/yodldocs/smb.conf.5.yo
index 8aedc667fa3..05352bb883b 100644
--- a/docs/yodldocs/smb.conf.5.yo
+++ b/docs/yodldocs/smb.conf.5.yo
@@ -478,10 +478,6 @@ parameter for details. Note that some are synonyms.
startit()
-it() link(bf(add user script))(adduserscript)
-
-it() link(bf(allow trusted domains))(allowtrusteddomains)
-
it() link(bf(announce as))(announceas)
it() link(bf(announce version))(announceversion)
@@ -504,22 +500,14 @@ it() link(bf(config file))(configfile)
it() link(bf(deadtime))(deadtime)
-it() link(bf(debug hires timestamp))(debughirestimestamp)
-
-it() link(bf(debug pid))(debugpid)
-
it() link(bf(debug timestamp))(debugtimestamp)
-it() link(bf(debug uid))(debuguid)
-
it() link(bf(debuglevel))(debuglevel)
it() link(bf(default))(default)
it() link(bf(default service))(defaultservice)
-it() link(bf(delete user script))(deleteuserscript)
-
it() link(bf(dfree command))(dfreecommand)
it() link(bf(dns proxy))(dnsproxy)
@@ -530,6 +518,8 @@ it() link(bf(domain admin users))(domainadminusers)
it() link(bf(domain controller))(domaincontroller)
+it() link(bf(domain group map))(domaingroupmap)
+
it() link(bf(domain groups))(domaingroups)
it() link(bf(domain guest group))(domainguestgroup)
@@ -540,6 +530,8 @@ it() link(bf(domain logons))(domainlogons)
it() link(bf(domain master))(domainmaster)
+it() link(bf(domain user map))(domainusermap)
+
it() link(bf(encrypt passwords))(encryptpasswords)
it() link(bf(getwd cache))(getwdcache)
@@ -554,13 +546,11 @@ it() link(bf(keepalive))(keepalive)
it() link(bf(kernel oplocks))(kerneloplocks)
-it() link(bf(ldap filter))(ldapfilter)
-
-it() link(bf(ldap port))(ldapport)
+it() link(bf(ldap bind as))(ldapbindas)
-it() link(bf(ldap root))(ldaproot)
+it() link(bf(ldap passwd file))(ldappasswdfile)
-it() link(bf(ldap root passwd))(ldaprootpasswd)
+it() link(bf(ldap port))(ldapport)
it() link(bf(ldap server))(ldapserver)
@@ -572,6 +562,8 @@ it() link(bf(lm interval))(lminterval)
it() link(bf(load printers))(loadprinters)
+it() link(bf(local group map))(localgroupmap)
+
it() link(bf(local master))(localmaster)
it() link(bf(lock dir))(lockdir)
@@ -596,8 +588,6 @@ it() link(bf(machine password timeout))(machinepasswordtimeout)
it() link(bf(mangled stack))(mangledstack)
-it() link(bf(map to guest))(maptoguest)
-
it() link(bf(max disk size))(maxdisksize)
it() link(bf(max log size))(maxlogsize)
@@ -616,8 +606,6 @@ it() link(bf(max xmit))(maxxmit)
it() link(bf(message command))(messagecommand)
-it() link(bf(min passwd length))(minpasswdlength)
-
it() link(bf(min wins ttl))(minwinsttl)
it() link(bf(name resolve order))(nameresolveorder)
@@ -626,12 +614,8 @@ it() link(bf(netbios aliases))(netbiosaliases)
it() link(bf(netbios name))(netbiosname)
-it() link(bf(netbios scope))(netbiosscope)
-
it() link(bf(nis homedir))(nishomedir)
-it() link(bf(nt acl support))(ntaclsupport)
-
it() link(bf(nt pipe support))(ntpipesupport)
it() link(bf(nt smb support))(ntsmbsupport)
@@ -640,8 +624,6 @@ it() link(bf(null passwords))(nullpasswords)
it() link(bf(ole locking compatibility))(olelockingcompatibility)
-it() link(bf(oplock break wait time))(oplockbreakwaittime)
-
it() link(bf(os level))(oslevel)
it() link(bf(packet size))(packetsize)
@@ -684,8 +666,6 @@ it() link(bf(remote announce))(remoteannounce)
it() link(bf(remote browse sync))(remotebrowsesync)
-it() link(bf(restrict anonymous))(restrictanonymous)
-
it() link(bf(root))(root)
it() link(bf(root dir))(rootdir)
@@ -762,18 +742,12 @@ it() link(bf(username level))(usernamelevel)
it() link(bf(username map))(usernamemap)
-it() link(bf(utmp))(utmp)
-
-it() link(bf(utmp directory))(utmpdirectory)
-
it() link(bf(valid chars))(validchars)
it() link(bf(wins proxy))(winsproxy)
it() link(bf(wins server))(winsserver)
-it() link(bf(wins hook))(winshook)
-
it() link(bf(wins support))(winssupport)
it() link(bf(workgroup))(workgroup)
@@ -830,8 +804,6 @@ it() link(bf(directory mask))(directorymask)
it() link(bf(directory mode))(directorymode)
-it() link(bf(directory security mask))(directorysecuritymask)
-
it() link(bf(dont descend))(dontdescend)
it() link(bf(dos filetime resolution))(dosfiletimeresolution)
@@ -850,12 +822,8 @@ it() link(bf(force create mode))(forcecreatemode)
it() link(bf(force directory mode))(forcedirectorymode)
-it() link(bf(force directory security mode))(forcedirectorysecuritymode)
-
it() link(bf(force group))(forcegroup)
-it() link(bf(force security mode))(forcesecuritymode)
-
it() link(bf(force user))(forceuser)
it() link(bf(fstype))(fstype)
@@ -878,12 +846,8 @@ it() link(bf(hosts deny))(hostsdeny)
it() link(bf(include))(include)
-it() link(bf(inherit permissions))(inheritpermissions)
-
it() link(bf(invalid users))(invalidusers)
-it() link(bf(level2 oplocks))(level2oplocks)
-
it() link(bf(locking))(locking)
it() link(bf(lppause command))(lppausecommand)
@@ -900,8 +864,6 @@ it() link(bf(magic script))(magicscript)
it() link(bf(mangle case))(manglecase)
-it() link(bf(mangle locks))(manglelocks)
-
it() link(bf(mangled map))(mangledmap)
it() link(bf(mangled names))(manglednames)
@@ -914,6 +876,8 @@ it() link(bf(map hidden))(maphidden)
it() link(bf(map system))(mapsystem)
+it() link(bf(map to guest))(maptoguest)
+
it() link(bf(max connections))(maxconnections)
it() link(bf(min print space))(minprintspace)
@@ -924,8 +888,6 @@ it() link(bf(only user))(onlyuser)
it() link(bf(oplocks))(oplocks)
-it() link(bf(oplock contention limit))(oplockcontentionlimit)
-
it() link(bf(path))(path)
it() link(bf(postexec))(postexec)
@@ -934,8 +896,6 @@ it() link(bf(postscript))(postscript)
it() link(bf(preexec))(preexec)
-it() link(bf(preexec close))(preexecclose)
-
it() link(bf(preserve case))(preservecase)
it() link(bf(print command))(printcommand)
@@ -970,10 +930,6 @@ it() link(bf(root postexec))(rootpostexec)
it() link(bf(root preexec))(rootpreexec)
-it() link(bf(security mask))(securitymask)
-
-it() link(bf(root preexec close))(rootpreexecclose)
-
it() link(bf(set directory))(setdirectory)
it() link(bf(share modes))(sharemodes)
@@ -1019,55 +975,6 @@ manpagesection(EXPLANATION OF EACH PARAMETER)
startdit()
-label(adduserscript)
-dit(bf(add user script (G)))
-
-This is the full pathname to a script that will be run em(AS ROOT) by
-url(bf(smbd (8)))(smbd.8.html) under special circumstances decribed
-below.
-
-Normally, a Samba server requires that UNIX users are created for all
-users accessing files on this server. For sites that use Windows NT
-account databases as their primary user database creating these users
-and keeping the user list in sync with the Windows NT PDC is an
-onerous task. This option allows url(bf(smbd))(smbd.8.html) to create
-the required UNIX users em(ON DEMAND) when a user accesses the Samba
-server.
-
-In order to use this option, url(bf(smbd))(smbd.8.html) must be set to
-link(bf(security=server))(securityequalserver) or
-link(bf(security=domain))(securityequaldomain) and bf("add user script")
-must be set to a full pathname for a script that will create a UNIX user
-given one argument of bf(%u), which expands into the UNIX user name to
-create.
-
-When the Windows user attempts to access the Samba server, at
-em("login")(session setup in the SMB protocol) time,
-url(bf(smbd))(smbd.8.html) contacts the link(bf(password
-server))(passwordserver) and attempts to authenticate the given user
-with the given password. If the authentication succeeds then
-url(bf(smbd))(smbd.8.html) attempts to find a UNIX user in the UNIX
-password database to map the Windows user into. If this lookup fails,
-and bf("add user script") is set then url(bf(smbd))(smbd.8.html) will
-call the specified script em(AS ROOT), expanding any bf(%u) argument
-to be the user name to create.
-
-If this script successfully creates the user then
-url(bf(smbd))(smbd.8.html) will continue on as though the UNIX user
-already existed. In this way, UNIX users are dynamically created to
-match existing Windows NT accounts.
-
-See also link(bf(security=server))(securityequalserver),
-link(bf(security=domain))(securityequaldomain), link(bf(password
-server))(passwordserver), link(bf(delete user
-script))(deleteuserscript).
-
- bf(Default:)
-tt( add user script = <empty string>)
-
- bf(Example:)
-tt( add user script = /usr/local/samba/bin/add_user %u)
-
label(adminusers)
dit(bf(admin users (S)))
@@ -1088,30 +995,63 @@ tt( admin users = jason)
label(allow hosts)
dit(bf(allow hosts (S)))
-Synonym for link(bf(hosts allow))(hostsallow).
+A synonym for this parameter is link(bf('hosts allow'))(hostsallow)
-label(allowtrusteddomains)
-dit(bf(allow trusted domains (G)))
+This parameter is a comma, space, or tab delimited set of hosts which
+are permitted to access a service.
-This option only takes effect when the link(bf(security))(security)
-option is set to bf(server) or bf(domain). If it is set to no,
-then attempts to connect to a resource from a domain or workgroup other than
-the one which smbd is running in will fail, even if that domain
-is trusted by the remote server doing the authentication.
+If specified in the link(bf([global]))(global) section then it will
+apply to all services, regardless of whether the individual service
+has a different setting.
-This is useful if you only want your Samba server to serve resources
-to users in the domain it is a member of. As an example, suppose that there are
-two domains DOMA and DOMB. DOMB is trusted by DOMA, which contains
-the Samba server. Under normal circumstances, a user with an account
-in DOMB can then access the resources of a UNIX account with the same
-account name on the Samba server even if they do not have an account
-in DOMA. This can make implementing a security boundary difficult.
+You can specify the hosts by name or IP number. For example, you could
+restrict access to only the hosts on a Class C subnet with something
+like tt("allow hosts = 150.203.5."). The full syntax of the list is
+described in the man page bf(hosts_access (5)). Note that this man
+page may not be present on your system, so a brief description will
+be given here also.
+
+em(NOTE:) IF you wish to allow the url(bf(smbpasswd
+(8)))(smbpasswd.html.8) program to be run by local users to change
+their Samba passwords using the local url(bf(smbd (8)))(smbd.8.html)
+daemon, then you em(MUST) ensure that the localhost is listed in your
+bf(allow hosts) list, as url(bf(smbpasswd (8)))(smbpasswd.html.8) runs
+in client-server mode and is seen by the local
+url(bf(smbd))(smbd.8.html) process as just another client.
+
+You can also specify hosts by network/netmask pairs and by netgroup
+names if your system supports netgroups. The em(EXCEPT) keyword can also
+be used to limit a wildcard list. The following examples may provide
+some help:
+
+bf(Example 1): allow localhost and all IPs in 150.203.*.* except one
+
+tt( hosts allow = localhost, 150.203. EXCEPT 150.203.6.66)
+
+bf(Example 2): allow localhost and hosts that match the given network/netmask
+
+tt( hosts allow = localhost, 150.203.15.0/255.255.255.0)
+
+bf(Example 3): allow a localhost plus a couple of hosts
+
+tt( hosts allow = localhost, lapland, arvidsjaur)
+
+bf(Example 4): allow only hosts in NIS netgroup "foonet" or localhost, but
+deny access from one particular host
+
+tt( hosts allow = @foonet, localhost)
+tt( hosts deny = pirate)
+
+Note that access still requires suitable user-level passwords.
+
+See url(bf(testparm (1)))(testparm.1.html) for a way of testing your
+host access to see if it does what you expect.
bf(Default:)
-tt( allow trusted domains = Yes)
+tt( none (i.e., all hosts permitted access))
bf(Example:)
-tt( allow trusted domains = No)
+tt( allow hosts = 150.203.5. localhost myhost.mynet.edu.au)
label(alternatepermissions)
dit(bf(alternate permissions (S)))
@@ -1127,15 +1067,14 @@ dit(bf(announce as (G)))
This specifies what type of server url(bf(nmbd))(nmbd.8.html) will
announce itself as, to a network neighborhood browse list. By default
-this is set to Windows NT. The valid options are : "NT", which is a
-synonym for "NT Server", "NT Server", "NT Workstation", "Win95" or
-"WfW" meaning Windows NT Server, Windows NT Workstation, Windows 95
-and Windows for Workgroups respectively. Do not change this parameter
-unless you have a specific need to stop Samba appearing as an NT server
-as this may prevent Samba servers from participating as browser servers correctly.
+this is set to Windows NT. The valid options are : "NT", "Win95" or
+"WfW" meaning Windows NT, Windows 95 and Windows for Workgroups
+respectively. Do not change this parameter unless you have a specific
+need to stop Samba appearing as an NT server as this may prevent Samba
+servers from participating as browser servers correctly.
bf(Default:)
-tt( announce as = NT Server)
+tt( announce as = NT)
bf(Example)
tt( announce as = Win95)
@@ -1219,16 +1158,11 @@ should not use this parameter for machines that are serving PPP or
other intermittent or non-broadcast network interfaces as it will not
cope with non-permanent interfaces.
-If bf("bind interfaces only") is set then unless the network address
-em(127.0.0.1) is added to the link(bf('interfaces'))(interfaces) parameter
-list url(bf(smbpasswd))(smbpasswd.8.html) and
-url(bf(swat))(swat.8.html) may not work as expected due to the
-reasons covered below.
-
-To change a users SMB password, the url(bf(smbpasswd))(smbpasswd.8.html)
-by default connects to the em("localhost" - 127.0.0.1) address as an SMB
-client to issue the password change request. If bf("bind interfaces only")
-is set then unless the network address em(127.0.0.1) is added to the
+In addition, to change a users SMB password, the
+url(bf(smbpasswd))(smbpasswd.8.html) by default connects to the
+em("localhost" - 127.0.0.1) address as an SMB client to issue the
+password change request. If bf("bind interfaces only") is set then
+unless the network address em(127.0.0.1) is added to the
link(bf('interfaces'))(interfaces) parameter list then
url(bf(smbpasswd))(smbpasswd.8.html) will fail to connect in it's
default mode. url(bf(smbpasswd))(smbpasswd.8.html) can be forced to
@@ -1237,14 +1171,6 @@ url(bf("-r remote machine"))(smbpasswd.8.html#minusr) parameter, with
bf("remote machine") set to the IP name of the primary interface
of the local host.
-The url(bf(swat))(swat.8.html) status page tries to connect with
-url(bf(smbd))(smbd.8.html) and url(bf(nmbd))(nmbd.8.html) at the address
-em(127.0.0.1) to determine if they are running. Not adding em(127.0.0.1) will cause
-url(bf(smbd))(smbd.8.html) and url(bf(nmbd))(nmbd.8.html) to always show
-"not running" even if they really are. This can prevent
-url(bf(swat))(swat.8.html) from starting/stopping/restarting
-url(bf(smbd))(smbd.8.html) and url(bf(nmbd))(nmbd.8.html).
-
bf(Default:)
tt( bind interfaces only = False)
@@ -1356,13 +1282,7 @@ correctly.
it() bf(ISO8859-5) Russian Cyrillic UNIX character set. The parameter
link(bf(client code page))(clientcodepage) em(MUST) be set to code
-page 866 if the bf(character set) parameter is set to ISO8859-5
-in order for the conversion to the UNIX character set to be done
-correctly.
-
-it() bf(ISO8859-7) Greek UNIX character set. The parameter
-link(bf(client code page))(clientcodepage) em(MUST) be set to code
-page 737 if the bf(character set) parameter is set to ISO8859-7
+page 866 if the bf(character set) parameter is set to ISO8859-2
in order for the conversion to the UNIX character set to be done
correctly.
@@ -1571,7 +1491,6 @@ See also the link(bf("force create mode"))(forcecreatemode) parameter
for forcing particular mode bits to be set on created files. See also
the link(bf("directory mode"))(directorymode) parameter for masking
mode bits on created directories.
-See also the link(bf("inherit permissions"))(inheritpermissions) parameter.
bf(Default:)
tt( create mask = 0744)
@@ -1610,22 +1529,6 @@ tt( deadtime = 0)
bf(Example:)
tt( deadtime = 15)
-label(debughirestimestamp)
-dit(bf(debug hires timestamp (G)))
-
-Sometimes the timestamps in the log messages are needed with a
-resolution of higher that seconds, this boolean parameter adds
-microsecond resolution to the timestamp message header when turned on.
-
-Note that the parameter link(bf(debug timestamp))(debugtimestamp)
-must be on for this to have an effect.
-
- bf(Default:)
-tt( debug hires timestamp = No)
-
- bf(Example:)
-tt( debug hires timestamp = Yes)
-
label(debugtimestamp)
dit(bf(debug timestamp (G)))
@@ -1640,39 +1543,6 @@ tt( debug timestamp = Yes)
bf(Example:)
tt( debug timestamp = No)
-label(debugpid)
-dit(bf(debug pid (G)))
-
-When using only one log file for more then one forked smbd-process
-there may be hard to follow which process outputs which message.
-This boolean parameter is adds the process-id to the timestamp message
-headers in the logfile when turned on.
-
-Note that the parameter link(bf(debug timestamp))(debugtimestamp)
-must be on for this to have an effect.
-
- bf(Default:)
-tt( debug pid = No)
-
- bf(Example:)
-tt( debug pid = Yes)
-
-label(debuguid)
-dit(bf(debug uid (G)))
-
-Samba is sometimes run as root and sometime run as the connected
-user, this boolean parameter inserts the current euid, egid, uid
-and gid to the timestamp message headers in the log file if turned on.
-
-Note that the parameter link(bf(debug timestamp))(debugtimestamp)
-must be on for this to have an effect.
-
- bf(Default:)
-tt( debug uid = No)
-
- bf(Example:)
-tt( debug uid = Yes)
-
label(debuglevel)
dit(bf(debug level (G)))
@@ -1697,7 +1567,7 @@ dit(bf(default case (S)))
See the section on link(bf("NAME MANGLING"))(NAMEMANGLING). Also note
the link(bf("short preserve case"))(shortpreservecase) parameter.
-label(defaultservice)
+label(default service)
dit(bf(default service (G)))
This parameter specifies the name of a service which will be connected
@@ -1729,60 +1599,6 @@ verb(
path = /%S
)
-label(deleteuserscript)
-dit(bf(delete user script (G)))
-
-This is the full pathname to a script that will be run em(AS ROOT) by
-url(bf(smbd (8)))(smbd.8.html) under special circumstances decribed
-below.
-
-Normally, a Samba server requires that UNIX users are created for all
-users accessing files on this server. For sites that use Windows NT
-account databases as their primary user database creating these users
-and keeping the user list in sync with the Windows NT PDC is an
-onerous task. This option allows url(bf(smbd))(smbd.8.html) to delete
-the required UNIX users em(ON DEMAND) when a user accesses the Samba
-server and the Windows NT user no longer exists.
-
-In order to use this option, url(bf(smbd))(smbd.8.html) must be set to
-link(bf(security=domain))(securityequaldomain) and bf("delete user
-script") must be set to a full pathname for a script that will delete
-a UNIX user given one argument of bf(%u), which expands into the UNIX
-user name to delete. em(NOTE) that this is different to the
-link(bf(add user script))(adduserscript) which will work with the
-link(bf(security=server))(securityequalserver) option as well as
-link(bf(security=domain))(securityequaldomain). The reason for this
-is only when Samba is a domain member does it get the information
-on an attempted user logon that a user no longer exists. In the
-link(bf(security=server))(securityequalserver) mode a missing user
-is treated the same as an invalid password logon attempt. Deleting
-the user in this circumstance would not be a good idea.
-
-When the Windows user attempts to access the Samba server, at
-em("login")(session setup in the SMB protocol) time,
-url(bf(smbd))(smbd.8.html) contacts the link(bf(password
-server))(passwordserver) and attempts to authenticate the given user
-with the given password. If the authentication fails with the specific
-Domain error code meaning that the user no longer exists then
-url(bf(smbd))(smbd.8.html) attempts to find a UNIX user in the UNIX
-password database that matches the Windows user account. If this lookup succeeds,
-and bf("delete user script") is set then url(bf(smbd))(smbd.8.html) will
-call the specified script em(AS ROOT), expanding any bf(%u) argument
-to be the user name to delete.
-
-This script should delete the given UNIX username. In this way, UNIX
-users are dynamically deleted to match existing Windows NT accounts.
-
-See also link(bf(security=domain))(securityequaldomain),
-link(bf(password server))(passwordserver), link(bf(add user
-script))(adduserscript).
-
- bf(Default:)
-tt( delete user script = <empty string>)
-
- bf(Example:)
-tt( delete user script = /usr/local/samba/bin/del_user %u)
-
label(deletereadonly)
dit(bf(delete readonly (S)))
@@ -1830,7 +1646,16 @@ tt( delete veto files = True)
label(denyhosts)
dit(bf(deny hosts (S)))
-Synonym for link(bf(hosts deny))(hostsdeny).
+The opposite of link(bf('allow hosts'))(allowhosts) - hosts listed
+here are em(NOT) permitted access to services unless the specific
+services have their own lists to override this one. Where the lists
+conflict, the link(bf('allow'))(allowhosts) list takes precedence.
+
+ bf(Default:)
+tt( none (i.e., no hosts specifically excluded))
+
+ bf(Example:)
+tt( deny hosts = 150.203.4. badhost.mynet.edu.au)
label(dfreecommand)
dit(bf(dfree command (G)))
@@ -1912,10 +1737,7 @@ See the link(bf("force directory mode"))(forcedirectorymode) parameter
to cause particular mode bits to always be set on created directories.
See also the link(bf("create mode"))(createmode) parameter for masking
-mode bits on created files, and the link(bf("directory security mask"))(directorysecuritymask)
-parameter.
-
-See also the link(bf("inherit permissions"))(inheritpermissions) parameter.
+mode bits on created files.
bf(Default:)
tt( directory mask = 0755)
@@ -1928,39 +1750,6 @@ dit(bf(directory mode (S)))
Synonym for link(bf(directory mask))(directorymask).
-label(directorysecuritymask)
-dit(bf(directory security mask (S)))
-
-This parameter controls what UNIX permission bits can be modified
-when a Windows NT client is manipulating the UNIX permission on a
-directory using the native NT security dialog box.
-
-This parameter is applied as a mask (AND'ed with) to the changed
-permission bits, thus preventing any bits not in this mask from
-being modified. Essentially, zero bits in this mask may be treated
-as a set of bits the user is not allowed to change.
-
-If not set explicitly this parameter is set to the same value as the
-link(bf(directory mask))(directorymask) parameter. To allow a user to
-modify all the user/group/world permissions on a directory, set this
-parameter to 0777.
-
-em(Note) that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems. Administrators of
-most normal systems will probably want to set it to 0777.
-
-See also the link(bf(force directory security
-mode))(forcedirectorysecuritymode), link(bf(security
-mask))(securitymask), link(bf(force security mode))(forcesecuritymode)
-parameters.
-
- bf(Default:)
-tt( directory security mask = <same as directory mask>)
-
- bf(Example:)
-tt( directory security mask = 0777)
-
label(dnsproxy)
dit(bf(dns proxy (G)))
@@ -1986,7 +1775,7 @@ label(domainadmingroup)
bf(domain admin group (G))
This is an bf(EXPERIMENTAL) parameter that is part of the unfinished
-Samba NT Domain Controller Code. It may be removed in a later release.
+Samba NT Domain Controller Code. It has been removed as of November 98.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list bf(Samba-ntdom) available by sending email to
@@ -1996,7 +1785,7 @@ label(domainadminusers)
dit(bf(domain admin users (G)))
This is an bf(EXPERIMENTAL) parameter that is part of the unfinished
-Samba NT Domain Controller Code. It may be removed in a later release.
+Samba NT Domain Controller Code. It has been removed as of November 98.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list bf(Samba-ntdom) available by sending email to
@@ -2009,11 +1798,93 @@ This is a bf(DEPRECATED) parameter. It is currently not used within
the Samba source and should be removed from all current smb.conf
files. It is left behind for compatibility reasons.
+label(domaingroupmap)
+dit(bf(domain group map (G)))
+
+This option allows you to specify a file containing unique mappings
+of individual NT Domain Group names (in any domain) to UNIX group
+names. This allows NT domain groups to be presented correctly to
+NT users, despite the lack of native support for the NT Security model
+(based on VAX/VMS) in UNIX. The reader is advised to become familiar
+with the NT Domain system and its administration.
+
+This option is used in conjunction with link(bf('local group map'))(localgroupmap)
+and link(bf('domain user map'))(domainusermap). The use of these three
+options is trivial and often unnecessary in the case where Samba is
+not expected to interact with any other SAM databases (whether local
+workstations or Domain Controllers).
+
+
+The map file is parsed line by line. If any line begins with a tt('#')
+or a tt(';') then it is ignored. Each line should contain a single UNIX
+group name on the left then a single NT Domain Group name on the right,
+separated by a tabstop or tt('='). If either name contains spaces then
+it should be enclosed in quotes.
+The line can be either of the form:
+
+tt( UNIXgroupname \\DOMAIN_NAME\\DomainGroupName )
+
+or:
+
+tt( UNIXgroupname DomainGroupName )
+
+In the case where Samba is either an bf(EXPERIMENTAL) Domain Controller
+or it is a member of a domain using link(bf("security = domain"))(security),
+the latter format can be used: the default Domain name is the Samba Server's
+Domain name, specified by link(bf("workgroup = MYGROUP"))(workgroup).
+
+Any UNIX groups that are em(NOT) specified in this map file are assumed to
+be either Local or Domain Groups, depending on the role of the Samba Server.
+
+In the case when Samba is an bf(EXPERIMENTAL) Domain Controller, Samba
+will present em(ALL) such unspecified UNIX groups as its own NT Domain
+Groups, with the same name.
+
+In the case where Samba is member of a domain using
+link(bf("security = domain"))(security), Samba will check the UNIX name with
+its Domain Controller (see link(bf("password server"))(passwordserver))
+as if it was an NT Domain Group. If the Domain Controller says that it is not,
+such unspecified (unmapped) UNIX groups which also are not NT Domain
+Groups are treated as Local Groups in the Samba Server's local SAM database.
+NT Administrators will recognise these as Workstation Local Groups,
+which are managed by running bf(USRMGR.EXE) and selecting a remote
+Domain named "\\WORKSTATION_NAME", or by running bf(MUSRMGR.EXE) on
+a local Workstation.
+
+This may sound complicated, but it means that a Samba Server as
+either a member of a domain or as an bf(EXPERIMENTAL) Domain Controller
+will act like an NT Workstation (with a local SAM database) or an NT PDC
+(with a Domain SAM database) respectively, without the need for any of
+the map files at all. If you bf(want) to get fancy, however, you can.
+
+Note that adding an entry to map an arbitrary NT group in an arbitrary
+Domain to an arbitrary UNIX group em(REQUIRES) the following:
+
+startit()
+
+it() that the UNIX group exists on the UNIX server.
+
+it() that the NT Domain Group exists in the specified NT Domain
+
+it() that the UNIX Server knows about the specified Domain;
+
+it() that all the UNIX users (who are expecting to access the Samba
+Server as the correct NT user and with the correct NT group permissions)
+in the UNIX group be mapped to the correct NT Domain users in the specified
+NT Domain using link(bf('domain user map'))(domainusermap).
+
+endit()
+
+Failure to meet any of these requirements may result in either (or
+both) errors reported in the log files or (and) incorrect or missing
+access rights granted to users.
+
+
label(domaingroups)
dit(bf(domain groups (G)))
This is an bf(EXPERIMENTAL) parameter that is part of the unfinished
-Samba NT Domain Controller Code. It may be removed in a later release.
+Samba NT Domain Controller Code. It has been removed as of November 98.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list bf(Samba-ntdom) available by sending email to
@@ -2023,7 +1894,7 @@ label(domainguestgroup)
dit(bf(domain guest group (G)))
This is an bf(EXPERIMENTAL) parameter that is part of the unfinished
-Samba NT Domain Controller Code. It may be removed in a later release.
+Samba NT Domain Controller Code. It has been removed as of November 98.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list bf(Samba-ntdom) available by sending email to
@@ -2033,7 +1904,7 @@ label(domainguestusers)
dit(bf(domain guest users (G)))
This is an bf(EXPERIMENTAL) parameter that is part of the unfinished
-Samba NT Domain Controller Code. It may be removed in a later release.
+Samba NT Domain Controller Code. It has been removed as of November 98.
To work with the latest code builds that may have more support for
Samba NT Domain Controller functionality please subscribe to the
mailing list bf(Samba-ntdom) available by sending email to
@@ -2081,9 +1952,99 @@ special name for a link(bf(workgroup))(workgroup) before a Windows NT
PDC is able to do so then cross subnet browsing will behave strangely
and may fail.
+By default ("auto") Samba will attempt to become the domain master
+browser only if it is the Primary Domain Controller.
+
bf(Default:)
+tt( domain master = auto)
+
+ bf(Example:)
tt( domain master = no)
+
+label(domainusermap)
+dit(bf(domain user map (G)))
+
+This option allows you to specify a file containing unique mappings
+of individual NT Domain User names (in any domain) to UNIX user
+names. This allows NT domain users to be presented correctly to
+NT systems, despite the lack of native support for the NT Security model
+(based on VAX/VMS) in UNIX. The reader is advised to become familiar
+with the NT Domain system and its administration.
+
+This option is used in conjunction with link(bf('local group map'))(localgroupmap)
+and link(bf('domain group map'))(domaingroupmap). The use of these three
+options is trivial and often unnecessary in the case where Samba is
+not expected to interact with any other SAM databases (whether local
+workstations or Domain Controllers).
+
+This option, which provides (and maintains) a one-to-one link between
+UNIX and NT users, is em(DIFFERENT) from link(bf('username map'))
+(usernamemap), which does em(NOT) maintain a distinction between the
+name(s) it can map to and the name it maps.
+
+
+The map file is parsed line by line. If any line begins with a tt('#')
+or a tt(';') then the line is ignored. Each line should contain a single UNIX
+user name on the left then a single NT Domain User name on the right,
+separated by a tabstop or tt('='). If either name contains spaces then
+it should be enclosed in quotes.
+The line can be either of the form:
+
+tt( UNIXusername \\DOMAIN_NAME\\DomainUserName )
+
+or:
+
+tt( UNIXusername DomainUserName )
+
+In the case where Samba is either an bf(EXPERIMENTAL) Domain Controller
+or it is a member of a domain using link(bf("security = domain"))(security),
+the latter format can be used: the default Domain name is the Samba Server's
+Domain name, specified by link(bf("workgroup = MYGROUP"))(workgroup).
+
+Any UNIX users that are em(NOT) specified in this map file are assumed
+to be either Domain or Workstation Users, depending on the role of the
+Samba Server.
+
+In the case when Samba is an bf(EXPERIMENTAL) Domain Controller, Samba
+will present em(ALL) such unspecified UNIX users as its own NT Domain
+Users, with the same name.
+
+In the case where Samba is a member of a domain using
+link(bf("security = domain"))(security), Samba will check the UNIX name with
+its Domain Controller (see link(bf("password server"))(passwordserver))
+as if it was an NT Domain User. If the Domain Controller says that it is not,
+such unspecified (unmapped) UNIX users which also are not NT Domain
+Users are treated as Local Users in the Samba Server's local SAM database.
+NT Administrators will recognise these as Workstation Users,
+which are managed by running bf(USRMGR.EXE) and selecting a remote
+Domain named "\\WORKSTATION_NAME", or by running bf(MUSRMGR.EXE) on
+a local Workstation.
+
+This may sound complicated, but it means that a Samba Server as
+either a member of a domain or as an bf(EXPERIMENTAL) Domain Controller
+will act like an NT Workstation (with a local SAM database) or an NT PDC
+(with a Domain SAM database) respectively, without the need for any of
+the map files at all. If you bf(want) to get fancy, however, you can.
+
+Note that adding an entry to map an arbitrary NT User in an arbitrary
+Domain to an arbitrary UNIX user em(REQUIRES) the following:
+
+startit()
+
+it() that the UNIX user exists on the UNIX server.
+
+it() that the NT Domain User exists in the specified NT Domain.
+
+it() that the UNIX Server knows about the specified Domain.
+
+endit()
+
+Failure to meet any of these requirements may result in either (or
+both) errors reported in the log files or (and) incorrect or missing
+access rights granted to users.
+
+
label(dont descend)
dit(bf(dont descend (S)))
@@ -2248,17 +2209,14 @@ label(forcecreatemode)
dit(bf(force create mode (S)))
This parameter specifies a set of UNIX mode bit permissions that will
-em(*always*) be set on a file by Samba. This is done by bitwise
-'OR'ing these bits onto the mode bits of a file that is being created
-or having its permissions changed. The default for this parameter is
-(in octal) 000. The modes in this parameter are bitwise 'OR'ed onto
-the file mode after the mask set in the link(bf("create
-mask"))(createmask) parameter is applied.
+em(*always*) be set on a file created by Samba. This is done by
+bitwise 'OR'ing these bits onto the mode bits of a file that is being
+created. The default for this parameter is (in octal) 000. The modes
+in this parameter are bitwise 'OR'ed onto the file mode after the mask
+set in the link(bf("create mask"))(createmask) parameter is applied.
See also the parameter link(bf("create mask"))(createmask) for details
-on masking mode bits on files.
-
-See also the link(bf("inherit permissions"))(inheritpermissions) parameter.
+on masking mode bits on created files.
bf(Default:)
tt( force create mode = 000)
@@ -2284,8 +2242,6 @@ link(bf("directory mask"))(directorymask) is applied.
See also the parameter link(bf("directory mask"))(directorymask) for
details on masking mode bits on created directories.
-See also the link(bf("inherit permissions"))(inheritpermissions) parameter.
-
bf(Default:)
tt( force directory mode = 000)
@@ -2296,39 +2252,6 @@ would force all created directories to have read and execute
permissions set for 'group' and 'other' as well as the
read/write/execute bits set for the 'user'.
-label(forcedirectorysecuritymode)
-dit(bf(force directory security mode (S)))
-
-This parameter controls what UNIX permission bits can be modified when
-a Windows NT client is manipulating the UNIX permission on a directory
-using the native NT security dialog box.
-
-This parameter is applied as a mask (OR'ed with) to the changed
-permission bits, thus forcing any bits in this mask that the user may
-have modified to be on. Essentially, one bits in this mask may be
-treated as a set of bits that, when modifying security on a directory,
-the user has always set to be 'on'.
-
-If not set explicitly this parameter is set to the same value as the
-link(bf(force directory mode))(forcedirectorymode) parameter. To allow
-a user to modify all the user/group/world permissions on a directory,
-with restrictions set this parameter to 000.
-
-em(Note) that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems. Administrators of
-most normal systems will probably want to set it to 0000.
-
-See also the link(bf(directory security mask))(directorysecuritymask),
-link(bf(security mask))(securitymask), link(bf(force security
-mode))(forcesecuritymode) parameters.
-
- bf(Default:)
-tt( force directory security mode = <same as force directory mode>)
-
- bf(Example:)
-tt( force directory security mode = 0)
-
label(forcegroup)
dit(bf(force group (S)))
@@ -2340,64 +2263,12 @@ permissions for this group to the files and directories within this
service the Samba administrator can restrict or allow sharing of these
files.
-In Samba 2.0.5 and above this parameter has extended functionality in the following
-way. If the group name listed here has a '+' character prepended to it
-then the current user accessing the share only has the primary group
-default assigned to this group if they are already assigned as a member
-of that group. This allows an administrator to decide that only users
-who are already in a particular group will create files with group
-ownership set to that group. This gives a finer granularity of ownership
-assignment. For example, the setting tt(force group = +sys) means
-that only users who are already in group sys will have their default
-primary group assigned to sys when accessing this Samba share. All
-other users will retain their ordinary primary group.
-
-If the link(bf("force user"))(forceuser) parameter is also set the
-group specified in bf(force group) will override the primary group
-set in link(bf("force user"))(forceuser).
-
-See also link(bf("force user"))(forceuser)
-
bf(Default:)
tt( no forced group)
bf(Example:)
tt( force group = agroup)
-label(forcesecuritymode)
-dit(bf(force security mode (S)))
-
-This parameter controls what UNIX permission bits can be modified when
-a Windows NT client is manipulating the UNIX permission on a file
-using the native NT security dialog box.
-
-This parameter is applied as a mask (OR'ed with) to the changed
-permission bits, thus forcing any bits in this mask that the user may
-have modified to be on. Essentially, one bits in this mask may be
-treated as a set of bits that, when modifying security on a file, the
-user has always set to be 'on'.
-
-If not set explicitly this parameter is set to the same value as the
-link(bf(force create mode))(forcecreatemode) parameter. To allow
-a user to modify all the user/group/world permissions on a file,
-with no restrictions set this parameter to 000.
-
-em(Note) that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems. Administrators of
-most normal systems will probably want to set it to 0000.
-
-See also the link(bf(force directory security
-mode))(forcedirectorysecuritymode), link(bf(directory security
-mask))(directorysecuritymask), link(bf(security mask))(securitymask)
-parameters.
-
- bf(Default:)
-tt( force security mode = <same as force create mode>)
-
- bf(Example:)
-tt( force security mode = 0)
-
label(forceuser)
dit(bf(force user (S)))
@@ -2413,13 +2284,6 @@ tt("forced user"), no matter what username the client connected as.
This can be very useful.
-In Samba 2.0.5 and above this parameter also causes the primary
-group of the forced user to be used as the primary group for all
-file activity. Prior to 2.0.5 the primary group was left as the
-primary group of the connecting user (this was a bug).
-
-See also link(bf("force group"))(forcegroup)
-
bf(Default:)
tt( no forced user)
@@ -2563,7 +2427,7 @@ verb(
tt( hide files = /.*/DesktopFolderDB/TrashFor%m/resource.frk/)
The above example is based on files that the Macintosh SMB client
-(DAVE) available from url(bf(Thursby))(http://www.thursby.com) creates for
+(DAVE) available from url(bf(Thursby))(www.thursby.com) creates for
internal use, and also still hides all files beginning with a dot.
label(homedirmap)
@@ -2596,74 +2460,12 @@ tt( homedir map = amd.homedir)
label(hostsallow)
dit(bf(hosts allow (S)))
-A synonym for this parameter is link(bf('allow hosts'))(allowhosts)
-
-This parameter is a comma, space, or tab delimited set of hosts which
-are permitted to access a service.
-
-If specified in the link(bf([global]))(global) section then it will
-apply to all services, regardless of whether the individual service
-has a different setting.
-
-You can specify the hosts by name or IP number. For example, you could
-restrict access to only the hosts on a Class C subnet with something
-like tt("allow hosts = 150.203.5."). The full syntax of the list is
-described in the man page bf(hosts_access (5)). Note that this man
-page may not be present on your system, so a brief description will
-be given here also.
-
-Note that the localhost address 127.0.0.1 will always be allowed
-access unless specifically denied by a "hosts deny" option.
-
-You can also specify hosts by network/netmask pairs and by netgroup
-names if your system supports netgroups. The em(EXCEPT) keyword can also
-be used to limit a wildcard list. The following examples may provide
-some help:
-
-bf(Example 1): allow all IPs in 150.203.*.* except one
-
-tt( hosts allow = 150.203. EXCEPT 150.203.6.66)
-
-bf(Example 2): allow hosts that match the given network/netmask
-
-tt( hosts allow = 150.203.15.0/255.255.255.0)
-
-bf(Example 3): allow a couple of hosts
-
-tt( hosts allow = lapland, arvidsjaur)
-
-bf(Example 4): allow only hosts in NIS netgroup "foonet", but
-deny access from one particular host
-
-tt( hosts allow = @foonet)
-
-tt( hosts deny = pirate)
-
-Note that access still requires suitable user-level passwords.
-
-See url(bf(testparm (1)))(testparm.1.html) for a way of testing your
-host access to see if it does what you expect.
-
- bf(Default:)
-tt( none (i.e., all hosts permitted access))
-
- bf(Example:)
-tt( allow hosts = 150.203.5. myhost.mynet.edu.au)
-
+Synonym for link(bf(allow hosts))(allowhosts).
label(hostsdeny)
dit(bf(hosts deny (S)))
-The opposite of link(bf('hosts allow'))(hostsallow) - hosts listed
-here are em(NOT) permitted access to services unless the specific
-services have their own lists to override this one. Where the lists
-conflict, the link(bf('allow'))(hostsallow) list takes precedence.
-
- bf(Default:)
-tt( none (i.e., no hosts specifically excluded))
-
- bf(Example:)
-tt( hosts deny = 150.203.4. badhost.mynet.edu.au)
+Synonym for link(bf(denyhosts))(denyhosts).
label(hostsequiv)
dit(bf(hosts equiv (G)))
@@ -2672,7 +2474,7 @@ If this global parameter is a non-null string, it specifies the name
of a file to read for the names of hosts and users who will be allowed
access without specifying a password.
-This is not be confused with link(bf(hosts allow))(hostsallow) which
+This is not be confused with link(bf(allow hosts))(allowhosts) which
is about hosts access to services and is more useful for guest
services. bf(hosts equiv) may be useful for NT clients which will not
supply passwords to samba.
@@ -2699,78 +2501,31 @@ is included literally, as though typed in place.
It takes the standard substitutions, except link(bf(%u))(percentu),
link(bf(%P))(percentP) and link(bf(%S))(percentS).
-label(inheritpermissions)
-dit(bf(inherit permissions (S)))
-
-The permissions on new files and directories are normally governed by
-link(bf("create mask"))(createmask),
-link(bf("directory mask"))(directorymask),
-link(bf("force create mode"))(forcecreatemode) and
-link(bf("force directory mode"))(forcedirectorymode)
-but the boolean inherit permissions parameter overrides this.
-
-New directories inherit the mode of the parent directory,
-including bits such as setgid.
-
-New files inherit their read/write bits from the parent directory.
-Their execute bits continue to be determined by
-link(bf("map archive"))(maparchive),
-link(bf("map hidden"))(maphidden) and
-link(bf("map system"))(mapsystem) as usual.
-
-Note that the setuid bit is *never* set via inheritance
-(the code explicitly prohibits this).
-
-This can be particularly useful on large systems with many users,
-perhaps several thousand,
-to allow a single bf([homes]) share to be used flexibly by each user.
-
-See also link(bf("create mask"))(createmask), link(bf("directory mask"))(directorymask),
-link(bf("force create mode"))(forcecreatemode) and
-link(bf("force directory mode"))(forcedirectorymode).
-
- bf(Default)
-tt( inherit permissions = no)
-
- bf(Example)
-tt( inherit permissions = yes)
-
label(interfaces)
dit(bf(interfaces (G)))
-This option allows you to override the default network interfaces list
-that Samba will use for browsing, name registration and other NBT
-traffic. By default Samba will query the kernel for the list of all
-active interfaces and use any interfaces except 127.0.0.1 that are
-broadcast capable.
+This option allows you to setup multiple network interfaces, so that
+Samba can properly handle browsing on all interfaces.
-The option takes a list of interface strings. Each string can be in
-any of the following forms:
+The option takes a list of ip/netmask pairs. The netmask may either be
+a bitmask, or a bitlength.
-startit()
-it() a network interface name (such as eth0). This may include
- shell-like wildcards so eth* will match any interface starting
- with the substring "eth"
-it() an IP address. In this case the netmask is determined
- from the list of interfaces obtained from the kernel
-it() an IP/mask pair.
-it() a broadcast/mask pair.
-endit()
+For example, the following line:
-The "mask" parameters can either be a bit length (such as 24 for a C
-class network) or a full netmask in dotted decmal form.
+tt(interfaces = 192.168.2.10/24 192.168.3.10/24)
-The "IP" parameters above can either be a full dotted decimal IP
-address or a hostname which will be looked up via the OSes normal
-hostname resolution mechanisms.
+would configure two network interfaces with IP addresses 192.168.2.10
+and 192.168.3.10. The netmasks of both interfaces would be set to
+255.255.255.0.
-For example, the following line:
+You could produce an equivalent result by using:
-tt(interfaces = eth0 192.168.2.10/24 192.168.3.10/255.255.255.0)
+tt(interfaces = 192.168.2.10/255.255.255.0 192.168.3.10/255.255.255.0)
-would configure three network interfaces corresponding to the eth0
-device and IP addresses 192.168.2.10 and 192.168.3.10. The netmasks of
-the latter two interfaces would be set to 255.255.255.0.
+if you prefer that format.
+
+If this option is not set then Samba will attempt to find a primary
+interface, but won't attempt to configure more than one interface.
See also link(bf("bind interfaces only"))(bindinterfacesonly).
@@ -2821,10 +2576,10 @@ options"))(socketoptions)). Basically you should only use this option
if you strike difficulties.
bf(Default:)
-tt( keepalive = 0)
+tt( keep alive = 0)
bf(Example:)
-tt( keepalive = 60)
+tt( keep alive = 60)
label(kerneloplocks)
dit(bf(kernel oplocks (G)))
@@ -2843,76 +2598,55 @@ This parameter defaults to em("On") on systems that have the support,
and em("off") on systems that don't. You should never need to touch
this parameter.
-See also the link(bf("oplocks"))(oplocks) and link(bf("level2 oplocks"))(level2oplocks)
-parameters.
-
-label(ldapfilter)
-dit(bf(ldap filter (G)))
+label(ldapbindas)
+dit(bf(ldap bind as (G)))
This parameter is part of the em(EXPERIMENTAL) Samba support for a
-password database stored on an LDAP server back-end. These options
-are only available if your version of Samba was configured with
-the bf(--with-ldap) option.
+password database stored on an LDAP server. These options are only
+available if your version of Samba was configured with the bf(--with-ldap)
+option.
-This parameter specifies an LDAP search filter used to search for a
-user name in the LDAP database. It must contain the string
-link(bf(%u))(percentU) which will be replaced with the user being
-searched for.
+This parameter specifies the entity to bind to an LDAP directory as.
+Usually it should be safe to use the LDAP root account; for larger
+installations it may be preferable to restrict Samba's access. See also
+link(bf(ldap passwd file))(ldappasswdfile).
bf(Default:)
-tt( empty string.)
-
-label(ldapport)
-dit(bf(ldap port (G)))
-
-This parameter is part of the em(EXPERIMENTAL) Samba support for a
-password database stored on an LDAP server back-end. These options
-are only available if your version of Samba was configured with
-the bf(--with-ldap) option.
-
-This parameter specifies the TCP port number to use to contact
-the LDAP server on.
+tt( none (bind anonymously))
- bf(Default:)
-tt( ldap port = 389.)
+ bf(Example:)
+tt( ldap bind as = "uid=root, dc=mydomain, dc=org")
-label(ldaproot)
-dit(bf(ldap root (G)))
+label(ldappasswdfile)
+dit(bf(ldap passwd file (G)))
This parameter is part of the em(EXPERIMENTAL) Samba support for a
-password database stored on an LDAP server back-end. These options
-are only available if your version of Samba was configured with
-the bf(--with-ldap) option.
-
-This parameter specifies the entity to bind to the LDAP server
-as (essentially the LDAP username) in order to be able to perform
-queries and modifications on the LDAP database.
+password database stored on an LDAP server. These options are only
+available if your version of Samba was configured with the bf(--with-ldap)
+option.
-See also link(bf(ldap root passwd))(ldaprootpasswd).
+This parameter specifies a file containing the password with which
+Samba should bind to an LDAP server. For obvious security reasons
+this file must be set to mode 700 or less.
bf(Default:)
-tt( empty string (no user defined))
+tt( none (bind anonymously))
-label(ldaprootpasswd)
-dit(bf(ldap root passwd (G)))
-
-This parameter is part of the em(EXPERIMENTAL) Samba support for a
-password database stored on an LDAP server back-end. These options
-are only available if your version of Samba was configured with
-the bf(--with-ldap) option.
+ bf(Example:)
+tt( ldap passwd file = /usr/local/samba/private/ldappasswd)
-This parameter specifies the password for the entity to bind to the
-LDAP server as (the password for this LDAP username) in order to be
-able to perform queries and modifications on the LDAP database.
+label(ldapport)
+dit(bf(ldap port (G)))
-em(BUGS:) This parameter should em(NOT) be a readable parameter
-in the bf(smb.conf) file and will be removed once a correct
-storage place is found.
+This parameter is part of the em(EXPERIMENTAL) Samba support for a
+password database stored on an LDAP server. These options are only
+available if your version of Samba was configured with the bf(--with-ldap)
+option.
-See also link(bf(ldap root))(ldaproot).
+This parameter specifies the TCP port number of the LDAP server.
bf(Default:)
-tt( empty string.)
+tt( ldap port = 389.)
label(ldapserver)
dit(bf(ldap server (G)))
@@ -2923,7 +2657,8 @@ are only available if your version of Samba was configured with
the bf(--with-ldap) option.
This parameter specifies the DNS name of the LDAP server to use
-for SMB/CIFS authentication purposes.
+when storing and retrieving information about Samba users and
+groups.
bf(Default:)
tt( ldap server = localhost)
@@ -2936,53 +2671,15 @@ password database stored on an LDAP server back-end. These options
are only available if your version of Samba was configured with
the bf(--with-ldap) option.
-This parameter specifies the tt("dn") or LDAP em("distinguished name")
-that tells url(bf(smbd))(smbd.8.html) to start from when searching
-for an entry in the LDAP password database.
+This parameter specifies the node of the LDAP tree beneath which
+Samba should store its information. This parameter MUST be provided
+when using LDAP with Samba.
bf(Default:)
-tt( empty string.)
-
-label(level2oplocks)
-dit(bf(level2 oplocks (S)))
-
-This parameter (new in Samba 2.0.5) controls whether Samba supports
-level2 (read-only) oplocks on a share. In Samba 2.0.5 this parameter
-defaults to "False" as the code is new, but will default to "True"
-in a later release.
-
-Level2, or read-only oplocks allow Windows NT clients that have an
-oplock on a file to downgrade from a read-write oplock to a read-only
-oplock once a second client opens the file (instead of releasing all
-oplocks on a second open, as in traditional, exclusive oplocks). This
-allows all openers of the file that support level2 oplocks to cache
-the file for read-ahead only (ie. they may not cache writes or lock
-requests) and increases performance for many acesses of files that
-are not commonly written (such as application .EXE files).
-
-Once one of the clients which have a read-only oplock writes to
-the file all clients are notified (no reply is needed or waited
-for) and told to break their oplocks to "none" and delete any
-read-ahead caches.
-
-It is recommended that this parameter be turned on to speed access
-to shared executables (and also to test the code :-).
-
-For more discussions on level2 oplocks see the CIFS spec.
-
-Currently, if link(bf("kernel oplocks"))(kerneloplocks) are supported
-then level2 oplocks are not granted (even if this parameter is set
-to tt("true")). Note also, the link(bf("oplocks"))(oplocks) parameter must
-be set to "true" on this share in order for this parameter to have any
-effect.
-
-See also the link(bf("oplocks"))(oplocks) and link(bf("kernel oplocks"))(kerneloplocks) parameters.
-
- bf(Default:)
-tt( level2 oplocks = False)
+tt( none)
bf(Example:)
-tt( level2 oplocks = True)
+tt( ldap suffix = "dc=mydomain, dc=org")
label(lmannounce)
dit(bf(lm announce (G)))
@@ -3038,6 +2735,88 @@ tt( load printers = yes)
bf(Example:)
tt( load printers = no)
+label(localgroupmap)
+dit(bf(local group map (G)))
+
+This option allows you to specify a file containing unique mappings
+of individual NT Local Group names (in any domain) to UNIX group
+names. This allows NT Local groups (aliases) to be presented correctly to
+NT users, despite the lack of native support for the NT Security model
+(based on VAX/VMS) in UNIX. The reader is advised to become familiar
+with the NT Domain system and its administration.
+
+This option is used in conjunction with link(bf('domain group map'))(domaingroupmap)
+and link(bf('domain name map'))(domainusermap). The use of these three
+options is trivial and often unnecessary in the case where Samba
+is not expected to interact with any other SAM databases (whether local
+workstations or Domain Controllers).
+
+
+The map file is parsed line by line. If any line begins with a tt('#')
+or a tt(';') then it is ignored. Each line should contain a single UNIX
+group name on the left then a single NT Local Group name on the right,
+separated by a tabstop or tt('='). If either name contains spaces then
+it should be enclosed in quotes.
+The line can be either of the form:
+
+tt( UNIXgroupname \\DOMAIN_NAME\\LocalGroupName )
+
+or:
+
+tt( UNIXgroupname LocalGroupName )
+
+In the case where Samba is either an bf(EXPERIMENTAL) Domain Controller
+or it is a member of a domain using link(bf("security = domain"))(security),
+the latter format can be used: the default Domain name is the Samba Server's
+Domain name, specified by link(bf("workgroup = MYGROUP"))(workgroup).
+
+Any UNIX groups that are em(NOT) specified in this map file are treated
+as either Local or Domain Groups depending on the role of the Samba Server.
+
+In the case when Samba is an bf(EXPERIMENTAL) Domain Controller, Samba
+will present em(ALL) unspecified UNIX groups as its own NT Domain
+Groups, with the same name, and em(NOT) as Local Groups.
+
+In the case where Samba is member of a domain using
+link(bf("security = domain"))(security), Samba will check the UNIX name with
+its Domain Controller (see link(bf("password server"))(passwordserver))
+as if it was an NT Domain Group. If the Domain Controller says that it is not,
+such unspecified (unmapped) UNIX groups which also are not NT Domain
+Groups are treated as Local Groups in the Samba Server's local SAM database.
+NT Administrators will recognise these as Workstation Local Groups,
+which are managed by running bf(USRMGR.EXE) and selecting a remote
+Domain named "\\WORKSTATION_NAME", or by running bf(MUSRMGR.EXE) on
+a local Workstation.
+
+This may sound complicated, but it means that a Samba Server as
+either a member of a domain or as an bf(EXPERIMENTAL) Domain Controller
+will act like an NT Workstation (with a local SAM database) or an NT PDC
+(with a Domain SAM database) respectively, without the need for any of
+the map files at all. If you bf(want) to get fancy, however, you can.
+
+Note that adding an entry to map an arbitrary NT group in an arbitrary
+Domain to an arbitrary UNIX group em(REQUIRES) the following:
+
+startit()
+
+it() that the UNIX group exists on the UNIX server.
+
+it() that the NT Domain Group exists in the specified NT Domain
+
+it() that the UNIX Server knows about the specified Domain;
+
+it() that all the UNIX users (who are expecting to access the Samba
+Server as the correct NT user and with the correct NT group permissions)
+in the UNIX group be mapped to the correct NT Domain users in the specified
+NT Domain using link(bf('domain user map'))(domainusermap).
+
+endit()
+
+Failure to meet any of these requirements may result in either (or
+both) errors reported in the log files or (and) incorrect or missing
+access rights granted to users.
+
+
label(localmaster)
dit(bf(local master (G)))
@@ -3461,13 +3240,6 @@ dit(bf(mangle case (S)))
See the section on link(bf("NAME MANGLING"))(NAMEMANGLING).
-label(manglelocks)
-dit(bf(mangle locks (S)))
-
-This option is was introduced with Samba 2.0.4 and above and has been
-removed in Samba 2.0.6 as Samba now dynamically configures such things
-on 32 bit systems.
-
label(mangledmap)
dit(bf(mangled map (S)))
@@ -3770,7 +3542,7 @@ never need to set this parameter.
tt( max mux = 50)
label(maxopenfiles)
-dit(bf(max open files (G)))
+dit(bf(maxopenfiles (G)))
This parameter limits the maximum number of open files that one
url(bf(smbd))(smbd.8.html) file serving process may have open for
@@ -3904,20 +3676,6 @@ tt( min print space = 0)
bf(Example:)
tt( min print space = 2000)
-label(minpasswdlength)
-dit(bf(min passwd length (G)))
-
-This option sets the minimum length in characters of a plaintext password
-than smbd will accept when performing UNIX password changing.
-
-See also link(bf("unix password sync"))(unixpasswordsync),
-link(bf("passwd program"))(passwdprogram) and link(bf("passwd chat
-debug"))(passwdchatdebug).
-
- bf(Default:)
-tt( min passwd length = 5)
-
-
label(minwinsttl)
dit(bf(min wins ttl (G)))
@@ -3945,16 +3703,11 @@ names to be resolved as follows :
startit()
it() bf(lmhosts) : Lookup an IP address in the Samba lmhosts file.
-If the line in lmhosts has no name type attached to the NetBIOS
-name (see the url(bf(lmhosts (5)))(lmhosts.5.html) for details) then
-any name type matches for lookup.
it() bf(host) : Do a standard host name to IP address resolution,
using the system /etc/hosts, NIS, or DNS lookups. This method of name
resolution is operating system depended for instance on IRIX or
Solaris this may be controlled by the em(/etc/nsswitch.conf) file).
-Note that this method is only used if the NetBIOS name type being
-queried is the 0x20 (server) name type, otherwise it is ignored.
it() bf(wins) : Query a name with the IP address listed in the
link(bf(wins server))(winsserver) parameter. If no WINS server has
@@ -4013,12 +3766,6 @@ tt( Machine DNS name.)
bf(Example:)
tt( netbios name = MYNAME)
-label(netbiosscope)
-dit(bf(netbios scope (G)))
-
-This sets the NetBIOS scope that Samba will operate under. This should
-not be set unless every machine on your LAN also sets this value.
-
label(nishomedir)
dit(bf(nis homedir (G)))
@@ -4051,18 +3798,6 @@ tt( nis homedir = false)
bf(Example:)
tt( nis homedir = true)
-label(ntaclsupport)
-dit(bf(nt acl support (G)))
-
-This boolean parameter controls whether url(bf(smbd))(smbd.8.html)
-will attempt to map UNIX permissions into Windows NT access control lists.
-
- bf(Default:)
-tt( nt acl support = yes)
-
- bf(Example:)
-tt( nt acl support = no)
-
label(ntpipesupport)
dit(bf(nt pipe support (G)))
@@ -4167,48 +3902,12 @@ all access to oplocked files, whether it be via Samba or NFS or a local
UNIX process. See the link(bf(kernel oplocks))(kerneloplocks) parameter
for details.
-See also the link(bf("kernel oplocks"))(kerneloplocks) and
-link(bf("level2 oplocks"))(level2oplocks) parameters.
-
bf(Default:)
tt( oplocks = True)
bf(Example:)
tt( oplocks = False)
-label(oplockbreakwaittime)
-dit(bf(oplock break wait time (G)))
-
-This is a tuning parameter added due to bugs in both Windows 9x and WinNT.
-If Samba responds to a client too quickly when that client issues an SMB that
-can cause an oplock break request, then the client redirector can fail and
-not respond to the break request. This tuning parameter (which is set in
-milliseconds) is the amount of time Samba will wait before sending an
-oplock break request to such (broken) clients.
-
-em(DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
-OPLOCK CODE).
-
- bf(Default:)
-tt( oplock break wait time = 10)
-
-label(oplockcontentionlimit)
-dit(bf(oplock contention limit (S)))
-
-This is a em(very) advanced url(bf(smbd))(smbd.8.html) tuning option to improve
-the efficiency of the granting of oplocks under multiple client contention for the same file.
-
-In brief it specifies a number, which causes smbd not to grant an oplock even
-when requested if the approximate number of clients contending for an oplock on
-the same file goes over this limit. This causes url(bf(smbd))(smbd.8.html) to
-behave in a similar way to Windows NT.
-
-em(DO NOT CHANGE THIS PARAMETER UNLESS YOU HAVE READ AND UNDERSTOOD THE SAMBA
-OPLOCK CODE).
-
- bf(Default:)
-tt( oplock contention limit = 2)
-
label(oslevel)
dit(bf(os level (G)))
@@ -4216,12 +3915,12 @@ This integer value controls what level Samba advertises itself as for
browse elections. The value of this parameter determines whether
url(bf(nmbd))(nmbd.8.html) has a chance of becoming a local master
browser for the link(bf(WORKGROUP))(workgroup) in the local broadcast
-area. The default is zero, which means url(bf(nmbd))(nmbd.8.html) will
-lose elections to Windows machines. See BROWSING.txt in the Samba
-docs/ directory for details.
+area. Setting this to zero will cause url(bf(nmbd))(nmbd.8.html) to
+always lose elections to Windows machines. See BROWSING.txt in the
+Samba docs/ directory for details.
bf(Default:)
-tt( os level = 20)
+tt( os level = 32)
bf(Example:)
tt( os level = 65 ; This will win against any NT Server)
@@ -4424,7 +4123,7 @@ better restrict them with hosts allow!
If the link(bf("security"))(security) parameter is set to
bf("domain"), then the list of machines in this option must be a list
of Primary or Backup Domain controllers for the
-link(bf(Domain))(workgroup) or the character tt(*), as the Samba server is cryptographicly
+link(bf(Domain))(workgroup), as the Samba server is cryptographicly
in that domain, and will use cryptographicly authenticated RPC calls
to authenticate the user logging on. The advantage of using
link(bf("security=domain"))(securityequaldomain) is that if you list
@@ -4432,12 +4131,6 @@ several hosts in the bf("password server") option then
url(bf(smbd))(smbd.8.html) will try each in turn till it finds one
that responds. This is useful in case your primary server goes down.
-If the bf("password server") option is set to the character tt(*),
-then Samba will attempt to auto-locate the Primary or Backup Domain controllers
-to authenticate against by doing a query for the name tt(WORKGROUP<1C>)
-and then contacting each server returned in the list of IP addresses
-from the link(bf(name resolution))(nameresolveorder) source.
-
If the link(bf("security"))(security) parameter is set to
link(bf("server"))(securityequalserver), then there are different
restrictions that link(bf("security=domain"))(securityequaldomain)
@@ -4470,9 +4163,6 @@ tt( password server = <empty string>)
bf(Example:)
tt( password server = NT-PDC, NT-BDC1, NT-BDC2)
- bf(Example:)
-tt( password server = *)
-
label(path)
dit(bf(path (S)))
@@ -4553,7 +4243,7 @@ verb(
Of course, this could get annoying after a while :-)
-See also link(bf(preexec close))(preexecclose) and link(bf(postexec))(postexec).
+See also link(bf(postexec))(postexec).
bf(Default:)
tt( none (no command executed))
@@ -4561,18 +4251,6 @@ tt( none (no command executed))
bf(Example:)
tt( preexec = echo \"%u connected to %S from %m (%I)\" >> /tmp/log)
-label(preexecclose)
-dit(bf(preexec close (S)))
-
-This boolean option controls whether a non-zero return code from
-link(bf("preexec"))(preexec) should close the service being connected to.
-
- bf(Default:)
-tt( preexec close = no)
-
- bf(Example:)
-tt( preexec close = yes)
-
label(preferredmaster)
dit(bf(preferred master (G)))
@@ -4584,7 +4262,8 @@ force an election, and it will have a slight advantage in winning the
election. It is recommended that this parameter is used in
conjunction with link(bf("domain master = yes"))(domainmaster), so
that url(bf(nmbd))(nmbd.8.html) can guarantee becoming a domain
-master.
+master. Indeed the default ("auto") enables "preferred master" if
+Samba is configured as the domain master browser.
Use this option with caution, because if there are several hosts
(whether Samba servers, Windows 95 or NT) that are preferred master
@@ -4596,7 +4275,7 @@ capabilities.
See also link(bf(os level))(oslevel).
bf(Default:)
-tt( preferred master = no)
+tt( preferred master = auto)
bf(Example:)
tt( preferred master = yes)
@@ -4635,11 +4314,16 @@ command you specify should remove the spool file when it has been
processed, otherwise you will need to manually remove old spool files.
The print command is simply a text string. It will be used verbatim,
-with two exceptions: All occurrences of tt("%s") and tt("%f") will be
-replaced by the appropriate spool file name, and all occurrences of
-tt("%p") will be replaced by the appropriate printer name. The spool
-file name is generated automatically by the server, the printer name
-is discussed below.
+with two exceptions: All occurrences of tt("%s") will be replaced by
+the appropriate spool file name, and all occurrences of tt("%p") will
+be replaced by the appropriate printer name. The spool file name is
+generated automatically by the server, the printer name is discussed
+below.
+
+The full path name will be used for the filename if tt("%s") is not
+preceded by a tt('/'). If you don't like this (it can stuff up some
+lpq output) then use tt("%f") instead. Any occurrences of tt("%f") get
+replaced by the spool filename without the full path at the front.
The print command em(MUST) contain at least one occurrence of tt("%s")
or tt("%f") - the tt("%p") is optional. At the time a job is
@@ -5037,14 +4721,14 @@ This overlapping works best when the speeds of disk and network access
are similar, having very little effect when the speed of one is much
greater than the other.
-The default value is 16384, but very little experimentation has been
+The default value is 2048, but very little experimentation has been
done yet to determine the optimal value, and it is likely that the
best value will vary greatly between systems anyway. A value over
65536 is pointless and will cause you to allocate memory
unnecessarily.
bf(Default:)
-tt( read size = 16384)
+tt( read size = 2048)
bf(Example:)
tt( read size = 8192)
@@ -5118,39 +4802,6 @@ tt( remote browse sync = <empty string>)
bf(Example:)
tt( remote browse sync = 192.168.2.255 192.168.4.255)
-
-label(restrict anonymous)
-dit(bf(restrict anonymous (G)))
-
-This is a boolean parameter. If it is true, then anonymous access
-to the server will be restricted, namely in the case where the server
-is expecting the client to send a username, but it doesn't. Setting
-it to true will force these anonymous connections to be denied, and
-the client will be required to always supply a username and password
-when connecting. Use of this parameter is only recommened for homogenous
-NT client environments.
-
-This parameter makes the use of macro expansions that rely
-on the username (%U, %G, etc) consistant. NT 4.0 likes to use
-anonymous connections when refreshing the share list, and this
-is a way to work around that.
-
-When restrict anonymous is true, all anonymous connections are denied
-no matter what they are for. This can effect the ability of a machine
-to access the samba Primary Domain Controller to revalidate it's machine
-account after someone else has logged on the client interactively. The
-NT client will display a message saying that the machine's account in
-the domain doesn't exist or the password is bad. The best way to deal
-with this is to reboot NT client machines between interactive logons,
-using "Shutdown and Restart", rather than "Close all programs and logon
-as a different user".
-
- bf(Default:)
-tt( restrict anonymous = false)
-
- bf(Example:)
-tt( restrict anonymous = true)
-
label(revalidate)
dit(bf(revalidate (S)))
@@ -5227,16 +4878,7 @@ This is the same as the link(bf("preexec"))(preexec) parameter except
that the command is run as root. This is useful for mounting
filesystems (such as cdroms) before a connection is finalized.
-See also link(bf("preexec"))(preexec)
-and link(bf("root preexec close"))(rootpreexecclose).
-
-label(rootpreexecclose)
-dit(bf(root preexec close (S)))
-
-This is the same as the link(bf("preexec close"))(preexecclose) parameter
-except that the command is run as root.
-
-See also link(bf("preexec"))(preexec), link(bf("preexec close"))(preexecclose).
+See also link(bf("preexec"))(preexec).
label(security)
dit(bf(security (G)))
@@ -5437,7 +5079,7 @@ users into the link(bf("guest account"))(guestaccount). See the
link(bf("map to guest"))(maptoguest) parameter for details on
doing this.
-em(BUG:) There is currently a bug in the implementation of
+e,(BUG:) There is currently a bug in the implementation of
bf("security=domain) with respect to multi-byte character
set usernames. The communication with a Domain Controller
must be done in UNICODE and Samba currently does not widen
@@ -5459,40 +5101,6 @@ tt( security = USER)
bf(Example:)
tt( security = DOMAIN)
-label(securitymask)
-dit(bf(security mask (S)))
-
-This parameter controls what UNIX permission bits can be modified
-when a Windows NT client is manipulating the UNIX permission on a
-file using the native NT security dialog box.
-
-This parameter is applied as a mask (AND'ed with) to the changed
-permission bits, thus preventing any bits not in this mask from
-being modified. Essentially, zero bits in this mask may be treated
-as a set of bits the user is not allowed to change.
-
-If not set explicitly this parameter is set to the same value as the
-link(bf(create mask))(createmask) parameter. To allow a user to
-modify all the user/group/world permissions on a file, set this
-parameter to 0777.
-
-em(Note) that users who can access the Samba server through other
-means can easily bypass this restriction, so it is primarily
-useful for standalone "appliance" systems. Administrators of
-most normal systems will probably want to set it to 0777.
-
-See also the link(bf(force directory security
-mode))(forcedirectorysecuritymode), link(bf(directory security
-mask))(directorysecuritymask), link(bf(force security
-mode))(forcesecuritymode) parameters.
-
- bf(Default:)
-tt( security mask = <same as create mask>)
-
- bf(Example:)
-tt( security mask = 0777)
-
-
label(serverstring)
dit(bf(server string (G)))
@@ -5562,9 +5170,6 @@ users reporting strange problems trying to save files (locking errors)
and error messages in the smbd log looking like tt("ERROR
smb_shm_alloc : alloc of XX bytes failed").
-If your OS refuses the size that Samba asks for then Samba will try a
-smaller size, reducing by a factor of 0.8 until the OS accepts it.
-
bf(Default:)
tt( shared mem size = 1048576)
@@ -6086,12 +5691,9 @@ dit(bf(syslog (G)))
This parameter maps how Samba debug messages are logged onto the
system syslog logging levels. Samba debug level zero maps onto syslog
LOG_ERR, debug level one maps onto LOG_WARNING, debug level two maps
-onto LOG_NOTICE, debug level three maps onto LOG_INFO. All higher
-levels are mapped to LOG_DEBUG.
-
-This paramter sets the threshold for sending messages to syslog.
-Only messages with debug level less than this value will be sent
-to syslog.
+to LOG_NOTICE, debug level three maps onto LOG_INFO. The parameter
+sets the threshold for doing the mapping, all Samba debug messages
+above this threshold are mapped to syslog LOG_DEBUG messages.
bf(Default:)
tt( syslog = 1)
@@ -6331,6 +5933,17 @@ Windows machines to those that the UNIX box uses. The other is to map
multiple users to a single username so that they can more easily share
files.
+The use of this option, therefore, relates to UNIX usernames
+and not Windows (specifically NT Domain) usernames. In other words,
+once a name has been mapped using this option, the Samba server uses
+the mapped name for internal em(AND) external purposes.
+
+This option is em(DIFFERENT) from the link(bf("domain user map"))(domainusermap)
+parameter, which maintains a one-to-one mapping between UNIX usernames
+and NT Domain Usernames: more specifically, the Samba server maintains
+a link between em(BOTH) usernames, presenting the NT username to the
+external NT world, and using the UNIX username internally.
+
The map file is parsed line by line. Each line should contain a single
UNIX username on the left then a tt('=') followed by a list of
usernames on the right. The list of usernames on the right may contain
@@ -6406,41 +6019,8 @@ tt( no username map)
bf(Example:)
tt( username map = /usr/local/samba/lib/users.map)
-label(utmp)
-dit(bf(utmp (G)))
-
-This boolean parameter is only available if Samba has been configured and compiled
-with the option tt(--with-utmp). If set to True then Samba will attempt
-to add utmp or utmpx records (depending on the UNIX system) whenever a
-connection is made to a Samba server. Sites may use this to record the
-user connecting to a Samba share.
-
-See also the link(bf("utmp directory"))(utmpdirectory) parameter.
-
- bf(Default:)
-tt(utmp = False)
-
- bf(Example:)
-tt(utmp = True)
-
-label(utmpdirectory)
-dit(bf(utmp directory(G)))
-
-This parameter is only available if Samba has been configured and compiled
-with the option tt(--with-utmp). It specifies a directory pathname that is
-used to store the utmp or utmpx files (depending on the UNIX system) that
-record user connections to a Samba server. See also the link(bf("utmp"))(utmp)
-parameter. By default this is not set, meaning the system will use whatever
-utmp file the native system is set to use (usually /var/run/utmp on Linux).
-
- bf(Default:)
-tt(no utmp directory)
-
- bf(Example:)
-tt(utmp directory = /var/adm/)
-
label(validchars)
-dit(bf(valid chars (G)))
+dit(bf(valid chars (S)))
The option allows you to specify additional characters that should be
considered valid by the server in filenames. This is particularly
@@ -6614,10 +6194,6 @@ directory tree exported by the server are always allowed; this
parameter controls access only to areas that are outside the directory
tree being exported.
-Note that setting this parameter can have a negative effect on your
-server performance due to the extra system calls that Samba has to
-do in order to perform the link checks.
-
bf(Default:)
tt( wide links = yes)
@@ -6640,7 +6216,7 @@ dit(bf(wins server (G)))
This specifies the IP address (or DNS name: IP address for preference)
of the WINS server that url(bf(nmbd))(nmbd.8.html) should register with.
If you have a WINS server on your network then you should set this to
-the WINS server's IP.
+the WINS server's IP.
You should point this at your WINS server if you have a
multi-subnetted network.
@@ -6657,42 +6233,6 @@ tt( wins server = )
bf(Example:)
tt( wins server = 192.9.200.1)
-label(winshook)
-dit(bf(wins hook (G)))
-
-When Samba is running as a WINS server this allows you to call an
-external program for all changes to the WINS database. The primary use
-for this option is to allow the dynamic update of external name
-resolution databases such as dynamic DNS.
-
-The wins hook parameter specifies the name of a script or executable
-that will be called as follows:
-
- wins_hook operation name nametype ttl IP_list
-
-The first argument is the operation and is one of "add", "delete",
-or "refresh". In most cases the operation can be ignored as the rest
-of the parameters provide sufficient information. Note that "refresh"
-may sometimes be called when the name has not previously been added,
-in that case it should be treated as an add.
-
-The second argument is the netbios name. If the name is not a legal
-name then the wins hook is not called. Legal names contain only
-letters, digits, hyphens, underscores and periods.
-
-The third argument is the netbios name type as a 2 digit hexadecimal
-number.
-
-The fourth argument is the TTL (time to live) for the name in seconds.
-
-The fifth and subsequent arguments are the IP addresses currently
-registered for that name. If this list is empty then the name should
-be deleted.
-
-An example script that calls the BIND dynamic DNS update program
-"nsupdate" is provided in the examples directory of the Samba source
-code.
-
label(winssupport)
dit(bf(wins support (G)))
@@ -6724,6 +6264,7 @@ label(writable)
dit(bf(writable (S)))
Synonym for link(bf("writeable"))(writeable) for people who can't spell :-).
+Pronounced "ritter-bull".
label(writelist)
dit(bf(write list (S)))
@@ -6782,8 +6323,6 @@ verb(
write ok = yes
)
-endit()
-
label(WARNINGS)
manpagesection(WARNINGS)
diff --git a/docs/yodldocs/smbclient.1.yo b/docs/yodldocs/smbclient.1.yo
index a2d14209b99..327e47c7a2b 100644
--- a/docs/yodldocs/smbclient.1.yo
+++ b/docs/yodldocs/smbclient.1.yo
@@ -8,7 +8,7 @@ manpagename(smbclient)(ftp-like client to access SMB/CIFS resources on servers)
label(SYNOPSIS)
manpagesynopsis()
-bf(smbclient) link(servicename)(servicename) [link(-s smb.conf)(minuss)] [link(-O socket options)(minusO)][link(-R name resolve order)(minusR)] [link(-M NetBIOS name)(minusM)] [link(-i scope)(minusi)] [link(-N)(minusN)] [link(-n NetBIOS name)(minusn)] [link(-d debuglevel)(minusd)] [link(-P)(minusP)] [link(-p port)(minusp)] [link(-l log basename)(minusl)] [link(-h)(minush)] [link(-I dest IP)(minusI)] [link(-E)(minusE)] [link(-U username)(minusU)] [link(-L NetBIOS name)(minusL)] [link(-t terminal code)(minust)] [link(-m max protocol)(minusm)] [link(-b buffersize)(minusb)] [link(-W workgroup)(minusW)] [link(-T<c|x>IXFqgbNan)(minusT)] [link(-D directory)(minusD)] [link(-c command string)(minusc)]
+bf(smbclient) link(servicename)(servicename) [link(password)(password)] [link(-s smb.conf)(minuss)] [link(-B IP addr)(minusB)] [link(-O socket options)(minusO)][link(-R name resolve order)(minusR)] [link(-M NetBIOS name)(minusM)] [link(-i scope)(minusi)] [link(-N)(minusN)] [link(-n NetBIOS name)(minusn)] [link(-d debuglevel)(minusd)] [link(-P)(minusP)] [link(-p port)(minusp)] [link(-l log basename)(minusl)] [link(-h)(minush)] [link(-I dest IP)(minusI)] [link(-E)(minusE)] [link(-U username)(minusU)] [link(-L NetBIOS name)(minusL)] [link(-t terminal code)(minust)] [link(-m max protocol)(minusm)] [link(-W workgroup)(minusW)] [link(-T<c|x>IXFqgbNan)(minusT)] [link(-D directory)(minusD)] [link(-c command string)(minusc)]
label(DESCRIPTION)
manpagedescription()
@@ -71,6 +71,9 @@ Samba configuration file, smb.conf. This file controls all aspects of
the Samba setup on the machine and smbclient also needs to read this
file.
+label(minusB)
+dit(bf(-B IP addr)) The IP address to use when sending a broadcast packet.
+
label(minusO)
dit(bf(-O socket options)) TCP socket options to set on the client
socket. See the url(socket options)(smb.conf.5.html#socketoptions)
@@ -104,7 +107,8 @@ it() bf(bcast) : Do a broadcast on each of the known local interfaces
listed in the url(bf(interfaces))(smb.conf.5.html#interfaces) parameter
in the smb.conf file. This is the least reliable of the name resolution
methods as it depends on the target host being on a locally connected
-subnet.
+subnet. To specify a particular broadcast address the link(bf(-B))(minusB) option
+may be used.
endit()
@@ -282,7 +286,7 @@ nothing before or nothing after the percent symbol will cause an empty
username or an empty password to be used, respectively.
The password may also be specified by setting up an environment
-variable called tt(PASSWD) that contains the users password. Note
+variable called tt(PASSWORD) that contains the users password. Note
that this may be very insecure on some systems but on others allows
users to script smbclient commands without having a password appear in
the command line of a process listing.
@@ -292,7 +296,7 @@ on an uppercase password. Lowercase or mixed case passwords may be
rejected by these servers.
Be cautious about including passwords in scripts or in the
-tt(PASSWD) environment variable. Also, on many systems the command
+tt(PASSWORD) environment variable. Also, on many systems the command
line of a running process may be seen via the tt(ps) command to be
safe always allow smbclient to prompt for a password and type it in
directly.
@@ -324,12 +328,6 @@ protocols level the server supports. This parameter is
preserved for backwards compatibility, but any string
following the bf(-m) will be ignored.
-label(minusb)
-dit(bf(-b buffersize)) This option changes the transmit/send buffer
-size when getting or putting a file from/to the server. The default
-is 65520 bytes. Setting this value smaller (to 1200 bytes) has been
-observed to speed up file transfers to and from a Win9x server.
-
label(minusW)
dit(bf(-W WORKGROUP)) Override the default workgroup specified in the
url(bf(workgroup))(smb.conf.5.html#workgroup) parameter of the
@@ -685,7 +683,7 @@ The variable bf(USER) may contain the username of the person using the
client. This information is used only if the protocol level is high
enough to support session-level passwords.
-The variable bf(PASSWD) may contain the password of the person using
+The variable bf(PASSWORD) may contain the password of the person using
the client. This information is used only if the protocol level is
high enough to support session-level passwords.
diff --git a/docs/yodldocs/smbd.8.yo b/docs/yodldocs/smbd.8.yo
index 1a3b9db475e..b0ed9a6cff1 100644
--- a/docs/yodldocs/smbd.8.yo
+++ b/docs/yodldocs/smbd.8.yo
@@ -8,7 +8,7 @@ manpagename(smbd)(server to provide SMB/CIFS services to clients)
label(SYNOPSIS)
manpagesynopsis()
-bf(smbd) [link(-D)(minusD)] [link(-a)(minusa)] [link(-o)(minuso)] [link(-P)(minusP)] [link(-h)(minush)] [link(-V)(minusV)] [link(-d debuglevel)(minusd)] [link(-l log file)(minusl)] [link(-p port number)(minusp)] [link(-O socket options)(minusO)] [link(-s configuration file)(minuss)]
+bf(smbd) [link(-D)(minusD)] [link(-a)(minusa)] [link(-o)(minuso)] [link(-d debuglevel)(minusd)] [link(-l log file)(minusl)] [link(-p port number)(minusp)] [link(-O socket options)(minusO)] [link(-s configuration file)(minuss)] [link(-i scope)(minusi)] [link(-P)(minusP)] [link(-h)(minush)]
label(DESCRIPTION)
manpagedescription()
@@ -71,16 +71,6 @@ dit(bf(-o)) If this parameter is specified, the log files will be
overwritten when opened. By default, the log files will be appended
to.
-label(minusP)
-dit(bf(-P)) Passive option. Causes smbd not to send any network traffic
-out. Used for debugging by the developers only.
-
-label(minush)
-dit(bf(-h)) Prints the help information (usage) for bf(smbd).
-
-label(minusV)
-dit(bf(-V)) Prints the version number for bf(smbd).
-
label(minusd)
dit(bf(-d debuglevel)) debuglevel is an integer from 0 to 10.
@@ -144,6 +134,21 @@ of all the services that the server is to provide. See bf(smb.conf
(5)) for more information.
The default configuration file name is determined at compile time.
+label(minusi)
+dit(bf(-i scope)) This specifies a NetBIOS scope that the server will use
+to communicate with when generating NetBIOS names. For details on the
+use of NetBIOS scopes, see rfc1001.txt and rfc1002.txt. NetBIOS scopes
+are em(very) rarely used, only set this parameter if you are the
+system administrator in charge of all the NetBIOS systems you
+communicate with.
+
+label(minush)
+dit(bf(-h)) Prints the help information (usage) for smbd.
+
+label(minusP)
+dit(bf(-P)) Passive option. Causes smbd not to send any network traffic
+out. Used for debugging by the developers only.
+
endit()
label(FILES)
@@ -416,11 +421,16 @@ performance.
label(SEEALSO)
manpageseealso()
-bf(hosts_access (5)), bf(inetd (8)), url(bf(nmbd (8)))(nmbd.8.html),
-url(bf(smb.conf (5)))(smb.conf.5.html), url(bf(smbclient
-(1)))(smbclient.1.html), url(bf(testparm (1)))(testparm.1.html),
-url(bf(testprns (1)))(testprns.1.html), and the Internet RFC's
-bf(rfc1001.txt), bf(rfc1002.txt). In addition the CIFS (formerly SMB)
+bf(hosts_access (5)),
+bf(inetd (8)),
+url(bf(nmbd (8)))(nmbd.8.html),
+url(bf(smb.conf (5)))(smb.conf.5.html),
+url(bf(smbclient (1)))(smbclient.1.html),
+url(bf(testparm (1)))(testparm.1.html),
+url(bf(testprns (1)))(testprns.1.html),
+url(bf(rpcclient (1)))(rpcclient.1.html),
+and the Internet RFC's bf(rfc1001.txt), bf(rfc1002.txt).
+In addition the CIFS (formerly SMB)
specification is available as a link from the Web page :
url(http://samba.org/cifs/)(http://samba.org/cifs/).
diff --git a/docs/yodldocs/smbstatus.1.yo b/docs/yodldocs/smbstatus.1.yo
index f412a00a151..0d88bc7ef55 100644
--- a/docs/yodldocs/smbstatus.1.yo
+++ b/docs/yodldocs/smbstatus.1.yo
@@ -24,7 +24,7 @@ manpageoptions()
startdit()
label(minusP)
-dit(bf(-P)) If samba has been compiled with the profiling option,
+dit(bf(-P)) If samba has been compiled with the profiling option,
print only the contents of the profiling shared memory area.
label(minusb)
diff --git a/docs/yodldocs/swat.8.yo b/docs/yodldocs/swat.8.yo
index 145a9198797..5059e3f47c6 100644
--- a/docs/yodldocs/swat.8.yo
+++ b/docs/yodldocs/swat.8.yo
@@ -3,7 +3,7 @@ mailto(samba-bugs@samba.org)
manpage(swat htmlcommand((8)))(8)(23 Oct 1998)(Samba)(SAMBA)
label(NAME)
-manpagename(swat)(Samba Web Administration Tool)
+manpagename(swat)(swat - Samba Web Administration Tool)
label(SYNOPSIS)
manpagesynopsis()
diff --git a/docs/yodldocs/testparm.1.yo b/docs/yodldocs/testparm.1.yo
index 35ebce9a982..2c8e414bcd8 100644
--- a/docs/yodldocs/testparm.1.yo
+++ b/docs/yodldocs/testparm.1.yo
@@ -8,7 +8,7 @@ manpagename(testparm)(check an smb.conf configuration file for internal correctn
label(SYNOPSIS)
manpagesynopsis()
-bf(testparm) [link(-s)(minuss)] [link(-h)(minush)] [link(-L servername)(minusL)] [link(configfilename)(configfilename)] [link(hostname)(hostname) link(hostIP)(hostIP)]
+bf(testparm) [link(-s)(minuss)] [link(configfilename)(configfilename)] [link(hostname)(hostname) link(hostIP)(hostIP)]
label(DESCRIPTION)
manpagedescription()
@@ -28,11 +28,6 @@ If the optional host name and host IP address are specified on the
command line, this test program will run through the service entries
reporting whether the specified host has access to each service.
-If bf(testparm) finds an error in the url(bf(smb.conf))(smb.conf.5.html)
-file it returns an exit code of 1 to the calling program, else it returns
-an exit code of 0. This allows shell scripts to test the output from
-bf(testparm).
-
label(OPTIONS)
manpageoptions()
@@ -43,13 +38,6 @@ dit(bf(-s)) Without this option, bf(testparm) will prompt for a
carriage return after printing the service names and before dumping
the service definitions.
-label(minush)
-dit(bf(-h)) Print usage message
-
-label(minusL)
-dit(bf(-L servername)) Sets the value of the %L macro to servername. This
-is useful for testing include files specified with the %L macro.
-
label(configfilename)
dit(bf(configfilename)) This is the name of the configuration file to
check. If this parameter is not present then the default
diff --git a/examples/autofs/auto.a b/examples/autofs/auto.a
index 0fa8f4efc30..fc293f5391d 100644
--- a/examples/autofs/auto.a
+++ b/examples/autofs/auto.a
@@ -9,7 +9,10 @@ valepp -fstype=nfs,rsize=8192,wsize=8192 valepp:/
galaun -fstype=nfs,rsize=8192,wsize=8192 galaun:/
# smb-servers
-supra_andreas -fstype=smb,username=andreas,password=foo ://supra/aheinrich
-supra_cspiel -fstype=smb,username=cspiel ://supra/cspiel
-phonon_andreas -fstype=smb,username=andreas ://phonon/andreas
-helium_cspiel -fstype=smb,username=cspiel ://helium/cspiel
+supra_andreas -fstype=smb,uuname=andreas supra:/aheinrich
+supra_cspiel -fstype=smb,uuname=cspiel supra:/cspiel
+phonon_andreas -fstype=smb,uuname=andreas,fmod=3700 phonon:/andreas
+helium_cspiel -fstype=smb,uuname=cspiel,fmod=3700 helium:/cspiel
+
+#supra_jaz -fstype=smb,user,fmod=644,dmod=755 supra:/f
+
diff --git a/examples/autofs/mount-smb.doc b/examples/autofs/mount-smb.doc
new file mode 100644
index 00000000000..7eee74fce0d
--- /dev/null
+++ b/examples/autofs/mount-smb.doc
@@ -0,0 +1,65 @@
+Date: Tue, 07 Apr 1998
+Contributor: Christoph L. Spiel <Christoph_Spiel@physik.tu-muenchen.de>
+Organization: Munich Institute of Technology, Institute E10
+Subject: WISHES:LINUX:smbmount
+===============================================================================
+Machine Arch: i386
+Machine OS: linux
+Kernel: 2.1.85
+Samba Version: Version 1.9.18p3
+Mount Version: 2.7i
+Autofs Version: 0.3.14
+
+
+Hi SAMBA developers!
+
+I have written a shell script that marries smbmount and mount
+on a Linux-machine with a 2.1.55+ kernel (i.e., a newer developper
+kernel. Especially it makes smbmount compatible
+with autofs! Now, You (when root :-) can say
+ mount -t smb /win-machine/my-share /mntpt
+Concerning the management of the user/password-pairs I have already
+made a step in the right direction, but there is still a lot of
+brain-work to do :-(
+
+The primary problem with the Win passwords
+is that they are under user-control, and not under admin-control
+as the Linux passwords are. Therfore, I give every SAMBA user
+a
+ ~/smb-pass
+file where she can manage her usernames and passwords herself.
+The fundamental mount-tables /etc/fstab and /etc/auto.* only
+list the mount-point and the respective options. The user´s
+password file is adressed via the uuname=<user_name>-option.
+
+An important "side-effect" is that the password file need not to
+be word-readable. In fact my script tests for user-only rights of
+this file to close this potential security-hole.
+
+The script mount.smb has to be installed in /sbin and given mode 755.
+No suid is necessary! I attached an automount table that is currently
+in use on my machine. A user´s password file looks like this:
+
+$ cat ~/smb-pass
+supra:/cspiel cspiel secret
+helium:/c cspiel sesame
+^ ^ ^
+| | +- password
+| +- username
++- share-name as in fundamental mount-table.
+
+It would be nice, if someone else tests my script. Maybe, You have
+already found a better solution than mine. If You find it useful,
+I would be glad to donate it to the SAMBA-project.
+
+BUGS:
+(1) There is no documentation yet. (Yes, I consider this a bug!)
+(2) When used with autofs the automounter overruns mount.smb.
+ This means when accessing an automounted share for the 1st time
+ You may get an empty directory. Retrying several times will
+ cause the mount to complete successfully.
+
+
+Best,
+ Christoph Spiel
+
diff --git a/examples/autofs/mount.smb b/examples/autofs/mount.smb
new file mode 100644
index 00000000000..76f1a596e35
--- /dev/null
+++ b/examples/autofs/mount.smb
@@ -0,0 +1,441 @@
+#!/bin/sh -x
+
+
+# name: mount.smb -- interface between mount and smbmount
+# author: Ch. L. Spiel (cspiel@physik.tu-muenchen.de)
+# $Id: mount.smb,v 1.1 1998/04/13 12:31:10 jht Exp $
+
+# bash version: 1.14.7(1)
+# mount version: 2.7i
+# smbmount version: 1.9.18p3
+
+
+myname=`basename $0`
+passwd_filename="smb-pass" # name of user smb-password file
+lock_file="/var/lock/$myname"
+log_file="/tmp/mount.smb.log"
+
+PATH=/usr/local/samba/bin:/usr/bin:/bin
+
+# check for an existing lock-file quickly(!)
+if [ -e "$lock_file" ]; then
+ # exit, but don´t touch lock-file
+ exit 0
+fi
+# set up new lock-file
+echo > $lock_file
+
+# initialise log-file
+echo "logging of $myname started at `date`" > $log_file
+chmod --silent 600 $log_file
+echo "called with: $@" >> $log_file
+exec >> $log_file 2>&1
+
+
+
+# set default and initial values
+verbose=false # be silent
+fake=false # really do the mount
+fmode="-f 600" # default file mode
+dmode="-d 700" # default dir mode
+
+#uid="-u `id | sed 's/^uid=\([0-9]*\).*$/\1/'`"
+uid="-u 0"
+#gid="-g `id | sed 's/^.*gid=\([0-9]*\).*$/\1/'`"
+gid="-g 0"
+
+
+#
+# functions
+#
+
+# exitproc(int exit_code)
+function exit_proc
+{
+ if [ -n "$lock_file" ]; then
+ # remove current lock-file
+ rm "$lock_file"
+ fi
+ # update log-file
+ echo "" >> $log_file
+ echo "$myname´s return value is $1." >> $log_file
+ echo "logging of $myname ended at `date`." >> $log_file
+ # done.
+ exit $1
+}
+
+
+# split_arg(arg)
+# arg ::= id '=' val
+# set id and val on return
+function split_arg
+{
+ id="$1"
+ val="$2"
+ extra="$3"
+} # end of split_arg
+
+
+# split_passwdline(uline)
+function split_passwdline
+{
+ user_name=$1
+ real_password=$2
+ user_id=$3
+ group_id=$4
+ full_name=$5
+ home_dir=$6
+ shell_name=$7
+}
+
+
+# get_homedir(username)
+function get_homedir
+{
+ local temp_ifs
+
+ temp_ifs="$IFS"
+ uline=`grep "^$1" /etc/passwd`
+ if [ -z "$uline" ]; then
+ echo "$myname: unknown user \"$1\""
+ exit_proc 1
+ fi
+ IFS=":"
+ split_passwdline $uline
+ if [ -z "$home_dir" ]; then
+ echo "$myname: user \"$1\" has no home directory"
+ exit_proc 1
+ fi
+ echo "$home_dir"
+ IFS="$temp_ifs"
+}
+
+
+# get_uid(username)
+function get_uid
+{
+ local temp_ifs
+
+ temp_ifs="$IFS"
+ uline=`grep "^$1" /etc/passwd`
+ if [ -z "$uline" ]; then
+ echo "$myname: unknown user \"$1\""
+ exit_proc 1
+ fi
+ IFS=":"
+ split_passwdline $uline
+ echo "$user_id"
+ IFS="$temp_ifs"
+}
+
+
+# get_gid(username)
+function get_gid
+{
+ local temp_ifs
+
+ temp_ifs="$IFS"
+ uline=`grep "^$1" /etc/passwd`
+ if [ -z "$uline" ]; then
+ echo "$myname: unknown user \"$1\""
+ exit_proc 1
+ fi
+ IFS=":"
+ split_passwdline $uline
+ echo "$group_id"
+ IFS="$temp_ifs"
+}
+
+
+# read_passwd_file(sharename)
+function read_passwd_file
+{
+ local pwd_filename pwd_entry temp_ifs share_name fmod
+
+ pwd_filename=`get_homedir $uuname`/$passwd_filename
+ # use uid and gid of user´s /etc/password entry
+ uid="-u `get_uid $uuname`"
+ gid="-g `get_gid $uuname`"
+ # check existence of password file
+ if [ ! -f "$pwd_filename" -o ! -r "$pwd_filename" ]; then
+ echo "$myname: cannot read from user password file \"$pwd_filename\""
+ exit_proc 1
+ fi
+ # check file permissions
+ for f in $pwd_filename{,~,%,.BAK,.bak,.new,.old,.orig,.sav}; do
+ if [ ! -f $f ]; then continue; fi
+ /bin/ls -l $f | grep -q -- "^-r\(w\|-\)------"
+ if [ $? = 1 ]; then
+ echo "$myname: Found security hole: mode of file \"$f\""
+ echo "$myname: Password file must have permission 400 or 600."
+ echo "$myname: Please fix the file´s mode."
+ exit_proc 1
+ fi
+ done
+
+ share_name="$1" # sharename in smb-format!
+ pwd_entry=`grep -v '^#' "$pwd_filename" | grep -i "^$share_name"`
+ if [ -z "$pwd_entry" ]; then
+ # try uni*-like sharename
+ share_name=`echo $share_name | sed -e 's,^//,,' -e 's,/,:/,'`
+ pwd_entry=`grep -v '^#' "$pwd_filename" | grep -i "^$share_name"`
+ fi
+ if [ -z "$pwd_entry" ]; then
+ # sharename was not found in user´s password file
+ echo "$myname: cannot authentify share named \"$1\" via file \"$pwd_filename\""
+ exit_proc 1
+ fi
+
+ # pwd_entry has the form:
+ # sharename username password
+ temp_ifs="$IFS"
+ IFS=" " # <tab> and <space>
+ split_arg $pwd_entry
+ options="$options -U $val"
+ password="$extra"
+ IFS="$temp_ifs"
+}
+
+
+# process_options(opt1, opt2, ..., optN)
+function process_options
+{
+ local temp_ifs
+
+ for j; do
+ temp_ifs="$IFS" # save current internal-field separator
+ IFS="=" # set new separator
+ split_arg $j # split argument into identifier and value
+ IFS="$temp_ifs" # reset old separator
+ case "$id" in
+ port)
+ options="$options -p $val"
+ ;;
+ debug)
+ options="$options -d $val"
+ ;;
+ log)
+ options="$options -l $val"
+ ;;
+ nbname)
+ options="$options -n $val"
+ ;;
+ nopwd)
+ options="$options -N"
+ ;;
+ maxproto)
+ options="$options -m $val"
+ ;;
+ ip)
+ options="$options -I $val"
+ ;;
+ uname)
+ options="$options -U $val"
+ ;;
+ wrkgrp)
+ options="$options -W $val"
+ ;;
+ term)
+ options="$options -t $val"
+ ;;
+ sdir)
+ options="$options -D $val"
+ ;;
+ pwd)
+ # DO NOT USE THIS OPTION! It is a severe scurity hole.
+ password="$val"
+ ;;
+ uuname)
+ # consult user´s smb-password file
+ uuname="$val" # uni* user name
+ read_passwd_file "$server_service"
+ ;;
+
+ # ignored options
+ async)
+ # do nothing
+ ;;
+ atime)
+ # do nothing
+ ;;
+ auto)
+ # do nothing
+ ;;
+ defaults)
+ # do nothing
+ ;;
+ dev)
+ # do nothing
+ ;;
+ exec)
+ # do nothing
+ ;;
+ noatime)
+ # do nothing
+ ;;
+ noauto)
+ # do nothing
+ ;;
+ nodev)
+ # do nothing
+ ;;
+ noexec)
+ # do nothing
+ ;;
+ nosuid)
+ # do nothing
+ ;;
+ nouser)
+ # do nothing
+ ;;
+ ro)
+ # do nothing
+ ;;
+ rw)
+ # do nothing
+ ;;
+ suid)
+ # do nothing
+ ;;
+ sync)
+ # do nothing
+ ;;
+ user)
+ # do nothing
+ ;;
+
+ # fs options
+ fmod)
+ fmode="-f $val"
+ ;;
+ dmod)
+ dmode="-d $val"
+ ;;
+ uid)
+ uid="-u $val"
+ ;;
+ gid)
+ gid="-g $val"
+ ;;
+
+ # fallthrough
+ *)
+ echo "$myname: unrecognized option $id"
+ exit_proc 1
+ ;;
+ esac
+ done
+} # end of split_options
+
+
+
+#
+# main
+#
+
+
+
+if [ "$verbose" != "false" ]; then
+ # show how we have been called
+ echo "$myname: $*"
+fi
+
+# some checks of the input parameters
+if [ "$#" -lt 2 ]; then
+ echo "$myname: need at least service and mountpoint"
+ exit_proc 1
+fi
+
+if `echo "$2" | grep -vq "^/"`; then
+ echo "$myname: mount point must be an absolut path"
+ exit_proc 1
+fi
+
+
+# copy arguments
+if `echo "$1" | grep -q ":/"`; then
+ # non--standard format, i.e., server:/service
+ server_service=`echo "//$1" | sed -e "sx:/x/x"`
+else
+ # standard format, i.e, //server/service
+ server_service="$1"
+fi
+mntpt="$2"
+
+# copy options
+shift 2 # skip arguments: //server/service and /mnt-point
+for i; do
+ case "$i" in
+ -f | --fake)
+ fake=true
+ ;;
+ -h | --help)
+ echo "usage: mount.smb service [password] mountpoint [options]"
+ exit_proc 0
+ ;;
+ -v | --verbose)
+ verbose=true
+ ;;
+ -V | --version)
+ echo "$myname: mount.smb-0.1.0"
+ exit_proc 0
+ ;;
+ -o)
+ shift # skip leading -o
+ temp_ifs="$IFS" # save current internal-field separator
+ IFS="," # set new separator
+ process_options $*
+ IFS="$temp_ifs" # reset old separator
+ break # mount places options at the end -> we are done
+ ;;
+ *)
+ echo "$myname: unrecognized option $i"
+ exit_proc 1
+ ;;
+ esac
+ shift
+done
+IFS=' '
+
+
+#
+# be careful...
+#
+
+
+# nmblookup server: is node up and running?
+srv=`echo $server_service | sed 's,^//\(.*\)/.*$,\1,'` # server´s name
+nmblookup "$srv" | grep -q "failed to find name"
+if [ "$?" = 0 ]; then
+ echo "$myname: failed to find server \"$srv\"."
+ exit_proc 1
+fi
+
+
+#
+# perform mount
+#
+
+
+fs_options="$fmode $dmode $uid $gid" # all options concerning the mounted fs
+if [ "$verbose" = "true" ]; then
+ # display what we would do. Do not show the password, only show "xxx".
+ echo -n "smbmount $server_service "
+ if [ -n "$password" ]; then # password is set
+ echo -n "xxx " # ... but we don´t show it ;-)
+ fi
+ echo "-c \"mount $mntpt $fs_options\" $options"
+#else
+ # supress further messages
+# exec > /dev/null 2>&1
+#:
+fi
+
+if [ "$fake" != "true" ]; then
+ smbmount $server_service $password -c "mount $mntpt $fs_options" $options
+ echo "smbmount´s exit code was $?."
+fi
+
+# clean up and exit
+exit_proc 0
+
diff --git a/examples/printer-accounting/hp5-redir b/examples/printer-accounting/hp5-redir
index ea1299068a3..98c2b72edd2 100644
--- a/examples/printer-accounting/hp5-redir
+++ b/examples/printer-accounting/hp5-redir
@@ -1,5 +1,8 @@
#!/usr/bin/perl
#
+# $Source: /data/src/mirror/cvs/samba/examples/printer-accounting/hp5-redir,v $
+# $Id: hp5-redir,v 1.1 1996/07/23 03:30:56 samba-bugs Exp $
+#
# 0 == stdin == docuement
# 1 == stdout == printer
# 2 == stderr == logging
diff --git a/examples/printer-accounting/lp-acct b/examples/printer-accounting/lp-acct
index 91a3def08f8..3fe45f877fd 100644
--- a/examples/printer-accounting/lp-acct
+++ b/examples/printer-accounting/lp-acct
@@ -1,5 +1,8 @@
#!/usr/bin/perl
#
+# $Source: /data/src/mirror/cvs/samba/examples/printer-accounting/lp-acct,v $
+# $Id: lp-acct,v 1.1 1996/07/23 03:30:56 samba-bugs Exp $
+#
# 0 == stdin == docuement
# 1 == stdout == printer
# 2 == stderr == logging
diff --git a/examples/printing/smbprint b/examples/printing/smbprint
index 5a00a2a8aa8..9d19c26decd 100755
--- a/examples/printing/smbprint
+++ b/examples/printing/smbprint
@@ -87,7 +87,7 @@ echo "server $server, service $service" >> $logfile
(
# NOTE You may wish to add the line `echo translate' if you want automatic
# CR/LF translation when printing.
- if [ $TRANS -eq 1 ]; then
+ if [ $TRANS ]; then
echo translate
fi
echo "print -"
diff --git a/examples/rpcclient/README b/examples/rpcclient/README
new file mode 100644
index 00000000000..bdff5821a75
--- /dev/null
+++ b/examples/rpcclient/README
@@ -0,0 +1,11 @@
+This directory contains example programs and scripts that have been written by
+Samba rpcclient administrators and users. You may, or may not, find
+some of them useful. They have been submitted here for use at your own
+risk, and no responsibility is accepted for their use or mis-use.
+
+Program Author Purpose
+------- ------ -------
+
+ntsd.c David Bannon. Pings several workstations and shuts them down.
+ Used by David in a lab environment to kick students
+ off workstations from a cron job.
diff --git a/examples/rpcclient/nettime b/examples/rpcclient/nettime
new file mode 100644
index 00000000000..7af2c123818
--- /dev/null
+++ b/examples/rpcclient/nettime
@@ -0,0 +1,23 @@
+#/bin/bash
+# nettime, a WIN NT 'net time' command "equivalent"
+# please send hints and comments to csanson@etn.fr
+# (this is only a test purpose script for rpcclient from samba 2.1)
+
+RPCCLIENT=/usr/bin/rpcclient
+DATEBIN=/bin/date
+AWKBIN=/bin/awk
+
+if [ $# -lt 1 -o $# -gt 2 ]; then
+ echo "Usage: `basename $0` NTServer [-set]" 1>&2
+ exit 1
+fi
+
+RPCTIME=$($RPCCLIENT $DESTIP -S $1 -U% -c 'time;quit' |head -1| $AWKBIN '{print $3" "$4" "$5" "$6" "$7}')
+
+if [ "$2" = "-set" ]
+then
+ $DATEBIN --set "$RPCTIME" 1>/dev/null 2>/dev/null
+ echo "OK, system date set to:"
+fi
+ echo $RPCTIME
+
diff --git a/examples/rpcclient/ntsd.c b/examples/rpcclient/ntsd.c
new file mode 100644
index 00000000000..37976edaa5e
--- /dev/null
+++ b/examples/rpcclient/ntsd.c
@@ -0,0 +1,259 @@
+/* This is an experiemental programme to shutdown a group of NTws in a
+ Samba domain via rpcclient.
+
+ Copyright (c) David Bannon 1999
+ David Bannon, D.Bannon@latrobe.edu.au, 4th November, 1999
+
+ Full permission is granted to use this code (for what that is worth) in
+ any way you wish, strictly at your own risk.
+
+ I use it from a cron a job to close a computer lab down at 5:00 pm.
+
+ It has some serious security implications, make sure you understand
+ them before using this code !
+
+ If you find a way to make this 'power down' a machine that is set up to
+ do power down correctly please let me know !!
+
+ Machines to be shutdown must be members of a samba (or NT) domain.
+ You are going to have to offer your domain admin user name/password
+ (see below).
+
+ As you probably don't want your domain admin password appearing in the
+ crontab file or popping up in a 'ps' list, it can be encrypted and the
+ programme will tell you what it should look like. i.e :
+
+ [root@bclab shutdown]# ./ntsd -e
+ Domain Admin User name :dbannon
+ Domain Admin Password
+ Use the string between [] after a -p : [1HCeTcXqOfo7R[hg]
+ [root@bclab shutdown]#
+
+ Now a crontab entry would look like this :
+
+ 00 17 * * 1-5 /usr/local/sbin/ntsd -p'1HCeTcXqOfo7R[hg' -a
+
+ The -p indicates passwd (actually user name and password) and the
+ -a says shutdown all machines. Note that the password string must
+ have inverted commas around it so the shell does not try and expand
+ any special charachers that it is likely to contain.
+
+ Security Alert !!
+ The encryption is pretty weak and its reversable ! Change the key
+ strings, compile and change the key strings again ! You don't need
+ to remember the key but if you leave the unchanged source around
+ someone may use it to reverse the encryption. The Keys are in lumps
+ to stop someone doing a 'cat ntsd' and seeing the key string.
+ (yeah, I know its not very clever, but they should not be able to
+ read the binary or your crontab anyway)
+
+ Ping
+ I ping the target machines before trying to shut them down, you
+ dont't need to, just let rpcclient time out. If you want to ping
+ first (because its nicer !) you need :
+ 1. First element of IP name should be the netbios name. (makes sense)
+ 2. If the server you will run the cron job from does not have the
+ same default domain name as machines being shutdown then you will
+ need to define USE_DOMAIN and put in appropriate ip domain info.
+ This code does ping, get busy with vi if you don't want to.
+
+ Machine Names
+ For this system to be practical, the machine names must be in some
+ sort of sequence, ie bclab1, bclab2, bclab3, not more creative like
+ grumpy, dopey, sneezy. See the code in main() to see how the names
+ are built.
+
+ Configuration
+
+ Machine Names
+ If you have used a naming scheme like mine then you may need to
+ change only LASTMACHINE and PREFIX, otherwise look at main().
+
+ Binary locations.
+ We need to find the rpcclient and ping binaries. The values below
+ are typical. Better check first.
+
+ Compile
+ Known to compile cleanly on linux (RH5.0 - RH6.1) and DEC 4.0. Does
+ not do anything fancy so should compile on most systems easily
+ enough.
+
+ Install
+ Rename the binary (ie ntsd) and put it somewhere safe. It should
+ be rwx root only. Comes up with basic help if run without command
+ line switch, prompts for admin user name and password if used
+ without the -p switch.
+ (Typically)Put entry in your crontab (crontab -e) and watch the
+ fun. Remember, it does not keep them shutdown, try an entry every
+ 5 minutes for a while (or until door is locked).
+*/
+
+
+#include<stdio.h>
+#include<stdlib.h>
+#include<unistd.h>
+#include<pwd.h>
+
+#define PING "/bin/ping"
+#define RPCCLIENT "/usr/local/samba/bin/rpcclient"
+
+
+#define LASTMACHINE 14 /* ie, scans bclab1 through to bclab14 */
+#define PREFIX "bclab"
+
+/* #define USE_DOMAIN Only if you need full ip name to ping machines */
+
+#ifdef USE_DOMAIN
+#define DOMAIN ".biochem.latrobe.edu.au" /* required by ping, possibly.
+ */
+#endif
+
+#define KEY1 "Please"
+#define KEY2 "don't leave"
+#define KEY3 "this"
+#define KEY4 "as it is"
+#define KEY5 "here"
+#define KEY6 "silly."
+
+
+int Shutdown(char *machine, char *PassWord) {
+ char Buff[128], *Ptr;
+ int Res;
+ /* printf("Shutting down %s\n", machine); */
+ sprintf(Buff, "/bin/ping -c 1 -q %s > /dev/null", machine);
+ Res = system(Buff);
+ if (Res == 0) { /* its turned on */
+ Ptr = machine;
+ /* first 'word' in ip name = netbios name, get rid of rest */
+ while (*++Ptr != 0) if (*Ptr == '.') *Ptr = 0;
+ printf("Shutting down %s\n", machine);
+ sprintf(Buff, "%s -c shutdown -U%s -S %s", RPCCLIENT, PassWord,
+machine);
+ system(Buff);
+ }
+}
+
+int Usage(char *prog) {
+ printf("Programme to shutdown NTs in domain.\n");
+ printf("Normally called from cron (using encrypted passwd, see -e and
+-p).\n");
+ printf("Usage \n");
+ printf(" -a shutdown all machines %s1 to %s%d. \n",
+ PREFIX, PREFIX, LASTMACHINE);
+ printf(" -m machine shutdown [machine] (might need full ip
+name).\n");
+ printf(" -e tell me my encrypted name and password to
+use with -p.\n");
+ printf(" -p'pw_string' use encrypted name & password as given by
+-e.\n");
+ printf(" You must have single inverted commas around
+the pw string !");
+ printf(" -h help, give this message.\n");
+ printf("Typical cron line : 00 17 * * 1-5 /usr/local/sbin/ntsd
+-p1HCeTcXqOfo7R[hg -a\n");
+ printf(" David Bannon,
+Nov 1999\n");
+ exit(0);
+}
+
+int GetPassWord(char *Passwd) {
+ char *ptr, *p;
+ char User[128];
+ printf("Domain Admin User name :");
+ fgets(User, 127, stdin);
+ if (strlen(User) < 3) {
+ printf("Short user name, exiting.\n");
+ exit(1);
+ }
+ p = User;
+ while (*p != '\n') p++; /* get rid of newline */
+ *p = 0;
+ ptr = getpass("Domain Admin Password ");
+ if (strlen(ptr) < 3) {
+ printf("Short password, exiting.\n");
+ exit(1);
+ }
+ strcpy(Passwd, User); /* do this with sprintf */
+ strcat(Passwd, "%");
+ strcat(Passwd, ptr);
+ *ptr = 0; /* clean up system buffer */
+ return 0;
+}
+
+int Encrypt(char *InPass) {
+ char Pass[128], Enc[128];
+ int Temp;
+ char *Hash;
+ int Offset = 0;
+ Hash = malloc(256);
+ /* so it a bit harder than just 'cat ntsd' */
+ sprintf(Hash, "%s%s%s%s%s%s", KEY4, KEY3, KEY2, KEY5, KEY1, KEY6);
+ if (InPass == 0) {
+ GetPassWord(Pass); /* may not return */
+ while (*(Pass + Offset) != 0) {
+ Temp = *(Pass + Offset) + *(Hash + Offset) - ' ';
+ if (Temp > '~') Temp = Temp - 95;
+ *(Pass+Offset++) = Temp;
+ }
+ printf("Use the string between [] after a -p : ['%s']\n", Pass);
+ exit(0);
+ } else {
+ while (*(InPass + Offset) != 0) {
+ Temp = *(InPass + Offset) - *(Hash + Offset) + ' ';
+ if (Temp < ' ') Temp = Temp + 95;
+ *(InPass+Offset++) = Temp;
+ }
+ }
+ free(Hash);
+ return 0;
+}
+
+int main(int argc, char **argv) {
+ extern char *optarg;
+ extern int optind;
+ int Ch;
+ static char *prog_name;
+ int MachineNo = 0, AllMachines = 0;
+ char Machine[128], PassWord[128];
+ uid_t UID = getuid();
+ prog_name = argv[0];
+ if (UID != 0) {
+ printf("Sorry, this programme can only be run as root.\n");
+ exit(1);
+ }
+ *Machine = 0;
+ *PassWord = 0;
+ if (argc < 2) Usage(prog_name);
+ while ((Ch = getopt(argc, argv, "haem:p:")) != EOF) {
+ switch(Ch) {
+ case 'e': Encrypt(NULL); break; /* Does not return */
+ case 'a': AllMachines = 1; break;
+ case 'm': strcpy(Machine, optarg); break;
+ case 'p': strcpy(PassWord, optarg); break;
+ case 'h': Usage(prog_name);
+ default: Usage(prog_name);
+ }
+ }
+ if (*PassWord == 0) GetPassWord(PassWord); /* may not return */
+ else Encrypt(PassWord);
+ if (*Machine != 0) {
+ Shutdown(Machine, PassWord);
+ exit(0);
+ }
+ /* printf("exit for safety = %s.\n", PassWord);
+exit(0); */
+ while (++MachineNo < LASTMACHINE+1) {
+ pid_t Proc;
+#ifdef USE_DOMAIN
+ sprintf(Machine, "%s%d%s", PREFIX, MachineNo, DOMAIN);
+#else
+ sprintf(Machine, "%s%d", PREFIX, MachineNo);
+#endif
+ Proc = fork();
+ if (Proc == 0) { /* in child process */
+ Shutdown(Machine, PassWord);
+ exit(0);
+ }
+ }
+ printf("Shutdowns initiated.\n");
+}
diff --git a/examples/validchars/validchr.com b/examples/validchars/validchr.com
index a5dbb39bedf..ce159568369 100644
--- a/examples/validchars/validchr.com
+++ b/examples/validchars/validchr.com
Binary files differ
diff --git a/packaging/Caldera/README b/packaging/Caldera/README
new file mode 100644
index 00000000000..ec6806645c5
--- /dev/null
+++ b/packaging/Caldera/README
@@ -0,0 +1,11 @@
+Preparation Date: Mon November 16 1998
+Preparer: John H Terpstra <jht@samba.org>
+
+Instructions: Preparing Samba Packages for Caldera OpenLinux 1.2
+==================================================================
+
+We provide support only for current versions of Caldera OpenLinux.
+
+To produce the RPMS simply type:
+ sh makerpms.sh
+
diff --git a/packaging/Caldera/findsmb b/packaging/Caldera/findsmb
new file mode 100644
index 00000000000..986c2481779
--- /dev/null
+++ b/packaging/Caldera/findsmb
@@ -0,0 +1,141 @@
+#!/usr/bin/perl
+#
+# Prints info on all smb responding machines on a subnet.
+# This script needs to be run on a machine without nmbd running and be
+# run as root to get correct info from WIN95 clients.
+#
+# syntax:
+# findsmb [subnet broadcast address]
+#
+# with no agrument it will list machines on the current subnet
+#
+# There will be a "+" in front of the workgroup name for machines that are
+# local master browsers for that workgroup. There will be an "*" in front
+# of the workgroup name for machines that are the domain master browser for
+# that workgroup.
+#
+
+$SAMBABIN = "/usr/bin";
+
+for ($i = 0; $i < 2; $i++) { # test for -d option and broadcast address
+ $_ = shift;
+ if (m/-d|-D/) {
+ $DEBUG = 1;
+ } else {
+ if ($_) {
+ $BCAST = "-B $_";
+ }
+ }
+}
+
+sub ipsort # do numeric sort on last field of IP address
+{
+ @t1 = split(/\./,$a);
+ @t2 = split(/\./,$b);
+ @t1[3] <=> @t2[3];
+}
+
+# look for all machines that respond to a name lookup
+
+open(NMBLOOKUP,"$SAMBABIN/nmblookup $BCAST '*'|") ||
+ die("Can't run nmblookup '*'.\n");
+
+# get rid of all lines that are not a response IP address,
+# strip everything but IP address and sort by last field in address
+
+@ipaddrs = sort ipsort grep(s/ \*<00>.*$//,<NMBLOOKUP>);
+
+# print header info
+
+print "\nIP ADDR NETBIOS NAME WORKGROUP/OS/VERSION $BCAST\n";
+print "---------------------------------------------------------------------\n";
+
+foreach $ip (@ipaddrs) # loop through each IP address found
+{
+ $ip =~ s/\n//; # strip newline from IP address
+
+# find the netbios names registered by each machine
+
+ open(NMBLOOKUP,"$SAMBABIN/nmblookup -r -A $ip|") ||
+ die("Can't get nmb name list.\n");
+ @nmblookup = <NMBLOOKUP>;
+ close NMBLOOKUP;
+
+# get the first <00> name
+
+ @name = grep(/<00>/,@nmblookup);
+ $_ = @name[0];
+ if ($_) { # we have a netbios name
+ if (/GROUP/) { # is it a group name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown nis name";
+ }
+ } else {
+ /(\S+)/;
+ $name = $1;
+ }
+
+# do an smbclient command on the netbios name.
+
+ open(SMB,"$SAMBABIN/smbclient -N -L $name -I $ip -U% |") ||
+ die("Can't do smbclient command.\n");
+ @smb = <SMB>;
+ close SMB;
+
+ if ($DEBUG) { # if -d flag print results of nmblookup and smbclient
+ print "===============================================================\n";
+ print @nmblookup;
+ print @smb;
+ }
+
+# look for the OS= string
+
+ @info = grep(/OS=/,@smb);
+ $_ = @info[0];
+ if ($_) { # we found response
+ s/Domain=|OS=|Server=|\n//g; # strip out descriptions to make line shorter
+
+ } else { # no OS= string in response (WIN95 client)
+
+# for WIN95 clients get workgroup name from nmblookup response
+ @name = grep(/<00> - <GROUP>/,@nmblookup);
+ $_ = @name[0];
+ if ($_) {
+ /(\S+)/;
+ $_ = "[$1]";
+ } else {
+ $_ = "Unknown Workgroup";
+ }
+ }
+
+# see if machine registered a local master browser name
+ if (grep(/<1d>/,@nmblookup)) {
+ $master = '+'; # indicate local master browser
+ if (grep(/<1b>/,@nmblookup)) { # how about domain master browser?
+ $master = '*'; # indicate domain master browser
+ }
+ } else {
+ $master = ' '; # not a browse master
+ }
+
+# line up info in 3 columns
+
+ print "$ip".' 'x(16-length($ip))."$name".' 'x(14-length($name))."$master"."$_\n";
+
+ } else { # no netbios name found
+# try getting the host name
+ ($name, $aliases, $type, $length, @addresses) =
+ gethostbyaddr(pack('C4',split('\.',$ip)),2);
+ if (! $name) { # could not get name
+ $name = "unknown nis name";
+ }
+ if ($DEBUG) { # if -d flag print results of nmblookup
+ print "===============================================================\n";
+ print @nmblookup;
+ }
+ print "$ip".' 'x(16-length($ip))."$name\n";
+ }
+}
+
diff --git a/packaging/Caldera/makefile-path.patch b/packaging/Caldera/makefile-path.patch
new file mode 100644
index 00000000000..5fddb7cbfb4
--- /dev/null
+++ b/packaging/Caldera/makefile-path.patch
@@ -0,0 +1,44 @@
+diff -uNr samba-PVERSION/source/Makefile.in samba-kgc/source/Makefile.in
+--- samba-PVERSION/source/Makefile.in Wed Dec 2 14:35:18 1998
++++ samba-kgc/source/Makefile.in Wed Dec 2 15:06:02 1998
+@@ -27,7 +27,7 @@
+ # the previous releases of Samba
+ SBINDIR = @bindir@
+ LIBDIR = @libdir@
+-VARDIR = $(BASEDIR)/var
++VARDIR = /var
+ MANDIR = @mandir@
+
+ # The permissions to give the executables
+@@ -36,23 +36,23 @@
+ # set these to where to find various files
+ # These can be overridden by command line switches (see smbd(8))
+ # or in smb.conf (see smb.conf(5))
+-SMBLOGFILE = $(VARDIR)/log.smb
+-NMBLOGFILE = $(VARDIR)/log.nmb
++SMBLOGFILE = $(VARDIR)/log/samba/log.smb
++NMBLOGFILE = $(VARDIR)/log/samba/log.nmb
+ CONFIGFILE = $(LIBDIR)/smb.conf
+ LMHOSTSFILE = $(LIBDIR)/lmhosts
+ DRIVERFILE = $(LIBDIR)/printers.def
+ PASSWD_PROGRAM = /bin/passwd
+-SMB_PASSWD_FILE = $(BASEDIR)/private/smbpasswd
+-SMB_PASSGRP_FILE = $(BASEDIR)/private/smbpassgrp
+-SMB_GROUP_FILE = $(BASEDIR)/private/smbgroup
+-SMB_ALIAS_FILE = $(BASEDIR)/private/smbalias
++SMB_PASSWD_FILE = $(LIBDIR)/smbpasswd
++SMB_PASSGRP_FILE = $(LIBDIR)/smbpassgrp
++SMB_GROUP_FILE = $(LIBDIR)/smbgroup
++SMB_ALIAS_FILE = $(LIBDIR)/smbalias
+ SMB_PASSWD_PROGRAM = $(BINDIR)/smbpasswd
+
+ # This is where SWAT images and help files go
+-SWATDIR = $(BASEDIR)/swat
++SWATDIR = $(BASEDIR)/share/swat
+
+ # the directory where lock files go
+-LOCKDIR = $(VARDIR)/locks
++LOCKDIR = $(VARDIR)/lock/samba
+
+ # The directory where code page definition files go
+ CODEPAGEDIR = $(LIBDIR)/codepages
diff --git a/packaging/Caldera/makerpms.sh.tmpl b/packaging/Caldera/makerpms.sh.tmpl
new file mode 100644
index 00000000000..fa69370dff0
--- /dev/null
+++ b/packaging/Caldera/makerpms.sh.tmpl
@@ -0,0 +1,14 @@
+#!/bin/sh
+# Copyright (C) John H Terpstra 1998
+#
+RPMDIR=`rpm --showrc | awk '/^rpmdir/ { print $3}'`
+SPECDIR=`rpm --showrc | awk '/^specdir/ { print $3}'`
+SRCDIR=`rpm --showrc | awk '/^sourcedir/ { print $3}'`
+
+( cd ../../.. ; tar czvf ${SRCDIR}/samba-PVERSION.tar.gz samba-PVERSION )
+cp -a *.spec $SPECDIR
+cp -a *.patch smb.* samba.log $SRCDIR
+cd $SRCDIR
+chown -R root.root samba-PVERSION
+cd $SPECDIR
+rpm -ba -v samba2.spec
diff --git a/packaging/Caldera/samba.log b/packaging/Caldera/samba.log
new file mode 100644
index 00000000000..c5f2a5b45bc
--- /dev/null
+++ b/packaging/Caldera/samba.log
@@ -0,0 +1,11 @@
+/var/log/samba/log.nmb {
+ postrotate
+ /usr/bin/killall -HUP nmbd
+ endrotate
+}
+
+/var/log/samba/log.smb {
+ postrotate
+ /usr/bin/killall -HUP smbd
+ endrotate
+}
diff --git a/packaging/Caldera/samba.pamd b/packaging/Caldera/samba.pamd
new file mode 100644
index 00000000000..f38e70184af
--- /dev/null
+++ b/packaging/Caldera/samba.pamd
@@ -0,0 +1,2 @@
+auth required /lib/security/pam_pwdb.so nullok shadow
+account required /lib/security/pam_pwdb.so
diff --git a/packaging/Caldera/samba2.spec.tmpl b/packaging/Caldera/samba2.spec.tmpl
new file mode 100644
index 00000000000..84fe3dcd3b0
--- /dev/null
+++ b/packaging/Caldera/samba2.spec.tmpl
@@ -0,0 +1,282 @@
+Summary: Samba SMB client and server
+Name: samba
+Version: PVERSION
+Release: PRELEASE
+Copyright: GNU GPL version 2
+Group: Networking
+Source: ftp://samba.org/pub/samba/samba-PVERSION.tar.gz
+Patch: makefile-path.patch
+Patch1: smbw.patch
+Packager: John H Terpstra [Samba-Team] <jht@samba.org>
+BuildRoot: /var/tmp/samba
+
+%description
+Samba provides an SMB server which can be used to provide
+network services to SMB (sometimes called "Lan Manager")
+clients, including various versions of MS Windows, OS/2,
+and other Linux machines. Samba also provides some SMB
+clients, which complement the built-in SMB filesystem
+in Linux. Samba uses NetBIOS over TCP/IP (NetBT) protocols
+and does NOT need NetBEUI (Microsoft Raw NetBIOS frame)
+protocol.
+
+Samba-2 features an almost working NT Domain Control
+capability and includes the new SWAT (Samba Web Administration
+Tool) that allows samba's smb.conf file to be remotely managed
+using your favourite web browser. For the time being this is
+being enabled on TCP port 901 via inetd.
+
+Please refer to the WHATSNEW.txt document for fixup information.
+This binary release includes encrypted password support.
+Please read the smb.conf file and ENCRYPTION.txt in the
+docs directory for implementation details.
+
+%changelog
+* Mon Nov 16 1998 John H Terpstra <jht@samba.org>
+ - Ported to Cadera OpenLinux
+
+%prep
+%setup
+%patch -p1
+%patch1 -p1
+
+%build
+cd source
+./configure --prefix=/usr --libdir=/etc
+make all
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT/etc/codepages/src
+mkdir -p $RPM_BUILD_ROOT/etc/{logrotate.d,pam.d}
+mkdir -p $RPM_BUILD_ROOT/etc/rc.d/{init.d,rc0.d,rc1.d,rc2.d,rc3.d,rc5.d,rc6.d}
+mkdir -p $RPM_BUILD_ROOT/home/samba
+mkdir -p $RPM_BUILD_ROOT/usr/{bin,sbin}
+mkdir -p $RPM_BUILD_ROOT/usr/share/swat/{images,help,include}
+mkdir -p $RPM_BUILD_ROOT/usr/man/{man1,man5,man7,man8}
+mkdir -p $RPM_BUILD_ROOT/var/lock/samba
+mkdir -p $RPM_BUILD_ROOT/var/log/samba
+mkdir -p $RPM_BUILD_ROOT/var/spool/samba
+
+# Install standard binary files
+for i in nmblookup smbclient smbpasswd smbrun smbstatus testparm testprns \
+ make_smbcodepage make_printerdef rpcclient
+do
+install -m755 -s source/bin/$i $RPM_BUILD_ROOT/usr/bin
+done
+for i in addtosmbpass mksmbpasswd.sh smbtar
+do
+install -m755 source/script/$i $RPM_BUILD_ROOT/usr/bin
+done
+
+# Install secure binary files
+for i in smbd nmbd swat
+do
+install -m755 -s source/bin/$i $RPM_BUILD_ROOT/usr/sbin
+done
+
+# Install level 1 man pages
+for i in smbclient.1 smbrun.1 smbstatus.1 smbtar.1 testparm.1 testprns.1 make_smbcodepage.1 nmblookup.1
+do
+install -m644 docs/manpages/$i $RPM_BUILD_ROOT/usr/man/man1
+done
+
+# Install codepage source files
+for i in 437 737 850 852 861 866 932 936 949 950
+do
+install -m644 source/codepages/codepage_def.$i $RPM_BUILD_ROOT/etc/codepages/src
+done
+
+# Install SWAT helper files
+for i in swat/help/*.html docs/htmldocs/*.html
+do
+install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/help
+done
+for i in swat/images/*.gif
+do
+install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/images
+done
+for i in swat/include/*.html
+do
+install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/include
+done
+
+# Install the miscellany
+install -m644 swat/README $RPM_BUILD_ROOT/usr/share/swat
+install -m644 docs/manpages/smb.conf.5 $RPM_BUILD_ROOT/usr/man/man5
+install -m644 docs/manpages/lmhosts.5 $RPM_BUILD_ROOT/usr/man/man5
+install -m644 docs/manpages/smbpasswd.5 $RPM_BUILD_ROOT/usr/man/man5
+install -m644 docs/manpages/samba.7 $RPM_BUILD_ROOT/usr/man/man7
+install -m644 docs/manpages/smbd.8 $RPM_BUILD_ROOT/usr/man/man8
+install -m644 docs/manpages/nmbd.8 $RPM_BUILD_ROOT/usr/man/man8
+install -m644 docs/manpages/swat.8 $RPM_BUILD_ROOT/usr/man/man8
+install -m644 docs/manpages/smbpasswd.8 $RPM_BUILD_ROOT/usr/man/man8
+install -m644 packaging/RedHat/smb.conf $RPM_BUILD_ROOT/etc/smb.conf
+install -m644 packaging/RedHat/smbusers $RPM_BUILD_ROOT/etc/smbusers
+install -m755 packaging/RedHat/smbprint $RPM_BUILD_ROOT/usr/bin
+install -m755 packaging/RedHat/findsmb $RPM_BUILD_ROOT/usr/bin
+install -m755 packaging/RedHat/smbadduser $RPM_BUILD_ROOT/usr/bin
+install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT/etc/rc.d/init.d/smb
+install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT/usr/sbin/samba
+install -m644 packaging/RedHat/samba.pamd $RPM_BUILD_ROOT/etc/pam.d/samba
+install -m644 packaging/RedHat/samba.log $RPM_BUILD_ROOT/etc/logrotate.d/samba
+echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/etc/lmhosts
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post
+/sbin/chkconfig --add smb
+
+# Build codepage load files
+for i in 437 737 850 852 861 866 932 936 949 950
+do
+/usr/bin/make_smbcodepage c $i /etc/codepages/src/codepage_def.$i /etc/codepages/codepage.$i
+done
+
+# Add swat entry to /etc/services if not already there
+if !( grep ^[:space:]*swat /etc/services > /dev/null ) then
+ echo 'swat 901/tcp # Add swat service used via inetd' >> /etc/services
+fi
+
+# Add swat entry to /etc/inetd.conf if needed
+if !( grep ^[:space:]*swat /etc/inetd.conf > /dev/null ) then
+ echo 'swat stream tcp nowait.400 root /usr/sbin/swat swat' >> /etc/inetd.conf
+killall -1 inetd || :
+fi
+
+%preun
+if [ $1 = 0 ] ; then
+ /sbin/chkconfig --del smb
+
+ for n in /etc/codepages/*; do
+ if [ $n != /etc/codepages/src ]; then
+ rm -rf $n
+ fi
+ done
+ # We want to remove the browse.dat and wins.dat files so they can not interfer with a new version of samba!
+ if [ -e /var/lock/samba/browse.dat ]; then
+ rm -f /var/lock/samba/browse.dat
+ fi
+ if [ -e /var/lock/samba/wins.dat ]; then
+ rm -f /var/lock/samba/wins.dat
+ fi
+fi
+
+%postun
+# Only delete remnants of samba if this is the final deletion.
+if [ $1 != 0 ] ; then
+ exit 0
+
+ if [ -x /etc/pam.d/samba ]; then
+ rm -f /etc/pam.d/samba
+ fi
+ if [ -e /var/log/samba ]; then
+ rm -rf /var/log/samba
+ fi
+ if [ -e /var/lock/samba ]; then
+ rm -rf /var/lock/samba
+ fi
+
+ # Remove swat entries from /etc/inetd.conf and /etc/services
+ cd /etc
+ tmpfile=/etc/tmp.$$
+ sed -e '/^[:space:]*swat.*$/d' /etc/inetd.conf > $tmpfile
+ mv $tmpfile inetd.conf
+ sed -e '/^[:space:]*swat.*$/d' /etc/services > $tmpfile
+ mv $tmpfile services
+fi
+
+%files
+%doc README COPYING Manifest Read-Manifest-Now
+%doc WHATSNEW.txt Roadmap
+%doc docs
+%doc swat/README
+%doc examples
+%attr(-,root,root) /usr/sbin/smbd
+%attr(-,root,root) /usr/sbin/nmbd
+%attr(-,root,root) /usr/sbin/swat
+%attr(0750,root,root) /usr/sbin/samba
+%attr(-,root,root) /usr/bin/addtosmbpass
+%attr(-,root,root) /usr/bin/mksmbpasswd.sh
+%attr(-,root,root) /usr/bin/smbclient
+%attr(-,root,root) /usr/bin/rpcclient
+%attr(-,root,root) /usr/bin/testparm
+%attr(-,root,root) /usr/bin/testprns
+%attr(-,root,root) /usr/bin/smbrun
+%attr(-,root,root) /usr/bin/findsmb
+%attr(-,root,root) /usr/bin/smbstatus
+%attr(-,root,root) /usr/bin/nmblookup
+%attr(-,root,root) /usr/bin/make_smbcodepage
+%attr(-,root,root) /usr/bin/make_printerdef
+%attr(-,root,root) /usr/bin/smbpasswd
+%attr(-,root,root) /usr/bin/smbtar
+%attr(-,root,root) /usr/bin/smbprint
+%attr(-,root,root) /usr/bin/smbadduser
+%attr(-,root,root) /usr/share/swat/help/welcome.html
+%attr(-,root,root) /usr/share/swat/help/DOMAIN_MEMBER.html
+%attr(-,root,root) /usr/share/swat/help/lmhosts.5.html
+%attr(-,root,root) /usr/share/swat/help/make_smbcodepage.1.html
+%attr(-,root,root) /usr/share/swat/help/nmbd.8.html
+%attr(-,root,root) /usr/share/swat/help/nmblookup.1.html
+%attr(-,root,root) /usr/share/swat/help/samba.7.html
+%attr(-,root,root) /usr/share/swat/help/smb.conf.5.html
+%attr(-,root,root) /usr/share/swat/help/smbclient.1.html
+%attr(-,root,root) /usr/share/swat/help/smbd.8.html
+%attr(-,root,root) /usr/share/swat/help/smbpasswd.5.html
+%attr(-,root,root) /usr/share/swat/help/smbpasswd.8.html
+%attr(-,root,root) /usr/share/swat/help/smbrun.1.html
+%attr(-,root,root) /usr/share/swat/help/smbstatus.1.html
+%attr(-,root,root) /usr/share/swat/help/smbtar.1.html
+%attr(-,root,root) /usr/share/swat/help/swat.8.html
+%attr(-,root,root) /usr/share/swat/help/testparm.1.html
+%attr(-,root,root) /usr/share/swat/help/testprns.1.html
+%attr(-,root,root) /usr/share/swat/images/globals.gif
+%attr(-,root,root) /usr/share/swat/images/home.gif
+%attr(-,root,root) /usr/share/swat/images/passwd.gif
+%attr(-,root,root) /usr/share/swat/images/printers.gif
+%attr(-,root,root) /usr/share/swat/images/shares.gif
+%attr(-,root,root) /usr/share/swat/images/samba.gif
+%attr(-,root,root) /usr/share/swat/images/status.gif
+%attr(-,root,root) /usr/share/swat/images/viewconfig.gif
+%attr(-,root,root) /usr/share/swat/include/header.html
+%attr(-,root,root) /usr/share/swat/include/footer.html
+%attr(-,root,root) %config(noreplace) /etc/lmhosts
+%attr(-,root,root) %config(noreplace) /etc/smb.conf
+%attr(-,root,root) %config(noreplace) /etc/smbusers
+%attr(-,root,root) /etc/rc.d/init.d/smb
+%attr(-,root,root) /etc/logrotate.d/samba
+%attr(-,root,root) /etc/pam.d/samba
+%attr(-,root,root) /etc/codepages/src/codepage_def.437
+%attr(-,root,root) /etc/codepages/src/codepage_def.737
+%attr(-,root,root) /etc/codepages/src/codepage_def.850
+%attr(-,root,root) /etc/codepages/src/codepage_def.852
+%attr(-,root,root) /etc/codepages/src/codepage_def.861
+%attr(-,root,root) /etc/codepages/src/codepage_def.866
+%attr(-,root,root) /etc/codepages/src/codepage_def.932
+%attr(-,root,root) /etc/codepages/src/codepage_def.936
+%attr(-,root,root) /etc/codepages/src/codepage_def.949
+%attr(-,root,root) /etc/codepages/src/codepage_def.950
+%attr(-,root,root) /usr/man/man1/smbstatus.1
+%attr(-,root,root) /usr/man/man1/smbclient.1
+%attr(-,root,root) /usr/man/man1/make_smbcodepage.1
+%attr(-,root,root) /usr/man/man1/smbrun.1
+%attr(-,root,root) /usr/man/man1/smbtar.1
+%attr(-,root,root) /usr/man/man1/testparm.1
+%attr(-,root,root) /usr/man/man1/testprns.1
+%attr(-,root,root) /usr/man/man1/nmblookup.1
+%attr(-,root,root) /usr/man/man5/smb.conf.5
+%attr(-,root,root) /usr/man/man5/lmhosts.5
+%attr(-,root,root) /usr/man/man5/smbpasswd.5
+%attr(-,root,root) /usr/man/man7/samba.7
+%attr(-,root,root) /usr/man/man8/smbd.8
+%attr(-,root,root) /usr/man/man8/nmbd.8
+%attr(-,root,root) /usr/man/man8/smbpasswd.8
+%attr(-,root,root) /usr/man/man8/swat.8
+%attr(-,root,nobody) %dir /home/samba
+%attr(-,root,root) %dir /etc/codepages
+%attr(-,root,root) %dir /etc/codepages/src
+%attr(-,root,root) %dir /var/lock/samba
+%attr(-,root,root) %dir /var/log/samba
+%attr(1777,root,root) %dir /var/spool/samba
diff --git a/packaging/Caldera/smb.conf b/packaging/Caldera/smb.conf
new file mode 100644
index 00000000000..bd9a8e15bcc
--- /dev/null
+++ b/packaging/Caldera/smb.conf
@@ -0,0 +1,291 @@
+# This is the main Samba configuration file. You should read the
+# smb.conf(5) manual page in order to understand the options listed
+# here. Samba has a huge number of configurable options (perhaps too
+# many!) most of which are not shown in this example
+#
+# Any line which starts with a ; (semi-colon) or a # (hash)
+# is a comment and is ignored. In this example we will use a #
+# for commentry and a ; for parts of the config file that you
+# may wish to enable
+#
+# NOTE: Whenever you modify this file you should run the command "testparm"
+# to check that you have not many any basic syntactic errors.
+#
+#======================= Global Settings =====================================
+[global]
+
+# workgroup = NT-Domain-Name or Workgroup-Name
+ workgroup = MYGROUP
+
+# server string is the equivalent of the NT Description field
+ server string = Samba Server
+
+# This option is important for security. It allows you to restrict
+# connections to machines which are on your local network. The
+# following example restricts access to two C class networks and
+# the "loopback" interface. For more examples of the syntax see
+# the smb.conf man page
+; hosts allow = 192.168.1. 192.168.2. 127.
+
+# if you want to automatically load your printer list rather
+# than setting them up individually then you'll need this
+ printcap name = /etc/printcap
+ load printers = yes
+
+# It should not be necessary to spell out the print system type unless
+# yours is non-standard. Currently supported print systems include:
+# bsd, sysv, plp, lprng, aix, hpux, qnx
+; printing = bsd
+
+# Uncomment this if you want a guest account, you must add this to /etc/passwd
+# otherwise the user "nobody" is used
+; guest account = pcguest
+
+# this tells Samba to use a separate log file for each machine
+# that connects
+ log file = /var/log/samba/log.%m
+
+# Put a capping on the size of the log files (in Kb).
+ max log size = 50
+
+# Security mode. Most people will want user level security. See
+# security_level.txt for details.
+ security = user
+# Use password server option only with security = server
+; password server = <NT-Server-Name>
+
+# Password Level allows matching of _n_ characters of the password for
+# all combinations of upper and lower case.
+; password level = 8
+; username level = 8
+
+# You may wish to use password encryption. Please read
+# ENCRYPTION.txt, Win95.txt and WinNT.txt in the Samba documentation.
+# Do not enable this option unless you have read those documents
+; encrypt passwords = yes
+; smb passwd file = /etc/smbpasswd
+
+# The following are needed to allow password changing from Windows to
+# update the Linux sytsem password also.
+# NOTE: Use these with 'encrypt passwords' and 'smb passwd file' above.
+# NOTE2: You do NOT need these to allow workstations to change only
+# the encrypted SMB passwords. They allow the Unix password
+# to be kept in sync with the SMB password.
+; unix password sync = Yes
+; passwd program = /usr/bin/passwd %u
+; passwd chat = *New*UNIX*password* %n\n *ReType*new*UNIX*password* %n\n *passwd:*all*authentication*tokens*updated*successfully*
+
+# Unix users can map to different SMB User names
+; username map = /etc/smbusers
+
+# Using the following line enables you to customise your configuration
+# on a per machine basis. The %m gets replaced with the netbios name
+# of the machine that is connecting
+; include = /etc/smb.conf.%m
+
+# Most people will find that this option gives better performance.
+# See speed.txt and the manual pages for details
+ socket options = TCP_NODELAY
+
+# Configure Samba to use multiple interfaces
+# If you have multiple network interfaces then you must list them
+# here. See the man page for details.
+; interfaces = 192.168.12.2/24 192.168.13.2/24
+
+# Configure remote browse list synchronisation here
+# request announcement to, or browse list sync from:
+# a specific host or from / to a whole subnet (see below)
+; remote browse sync = 192.168.3.25 192.168.5.255
+# Cause this host to announce itself to local subnets here
+; remote announce = 192.168.1.255 192.168.2.44
+
+# Browser Control Options:
+# set local master to no if you don't want Samba to become a master
+# browser on your network. Otherwise the normal election rules apply
+; local master = no
+
+# OS Level determines the precedence of this server in master browser
+# elections. The default value should be reasonable
+; os level = 33
+
+# Domain Master specifies Samba to be the Domain Master Browser. This
+# allows Samba to collate browse lists between subnets. Don't use this
+# if you already have a Windows NT domain controller doing this job
+; domain master = yes
+
+# Preferred Master causes Samba to force a local browser election on startup
+# and gives it a slightly higher chance of winning the election
+; preferred master = yes
+
+# Use only if you have an NT server on your network that has been
+# configured at install time to be a primary domain controller.
+; domain controller = <NT-Domain-Controller-SMBName>
+
+# Enable this if you want Samba to be a domain logon server for
+# Windows95 workstations.
+; domain logons = yes
+
+# if you enable domain logons then you may want a per-machine or
+# per user logon script
+# run a specific logon batch file per workstation (machine)
+; logon script = %m.bat
+# run a specific logon batch file per username
+; logon script = %U.bat
+
+# Where to store roving profiles (only for Win95 and WinNT)
+# %L substitutes for this servers netbios name, %U is username
+# You must uncomment the [Profiles] share below
+; logon path = \\%L\Profiles\%U
+
+# All NetBIOS names must be resolved to IP Addresses
+# 'Name Resolve Order' allows the named resolution mechanism to be specified
+# the default order is "host lmhosts wins bcast". "host" means use the unix
+# system gethostbyname() function call that will use either /etc/hosts OR
+# DNS or NIS depending on the settings of /etc/host.config, /etc/nsswitch.conf
+# and the /etc/resolv.conf file. "host" therefore is system configuration
+# dependant. This parameter is most often of use to prevent DNS lookups
+# in order to resolve NetBIOS names to IP Addresses. Use with care!
+# The example below excludes use of name resolution for machines that are NOT
+# on the local network segment
+# - OR - are not deliberately to be known via lmhosts or via WINS.
+; name resolve order = wins lmhosts bcast
+
+# Windows Internet Name Serving Support Section:
+# WINS Support - Tells the NMBD component of Samba to enable it's WINS Server
+; wins support = yes
+
+# WINS Server - Tells the NMBD components of Samba to be a WINS Client
+# Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
+; wins server = w.x.y.z
+
+# WINS Proxy - Tells Samba to answer name resolution queries on
+# behalf of a non WINS capable client, for this to work there must be
+# at least one WINS Server on the network. The default is NO.
+; wins proxy = yes
+
+# DNS Proxy - tells Samba whether or not to try to resolve NetBIOS names
+# via DNS nslookups. The built-in default for versions 1.9.17 is yes,
+# this has been changed in version 1.9.18 to no.
+ dns proxy = no
+
+# Case Preservation can be handy - system default is _no_
+# NOTE: These can be set on a per share basis
+; preserve case = no
+; short preserve case = no
+# Default case is normally upper case for all DOS files
+; default case = lower
+# Be very careful with case sensitivity - it can break things!
+; case sensitive = no
+
+#============================ Share Definitions ==============================
+[homes]
+ comment = Home Directories
+ browseable = no
+ writable = yes
+
+# Un-comment the following and create the netlogon directory for Domain Logons
+; [netlogon]
+; comment = Network Logon Service
+; path = /home/netlogon
+; guest ok = yes
+; writable = no
+; share modes = no
+
+
+# Un-comment the following to provide a specific roving profile share
+# the default is to use the user's home directory
+;[Profiles]
+; path = /home/profiles
+; browseable = no
+; guest ok = yes
+
+
+# NOTE: If you have a BSD-style print system there is no need to
+# specifically define each individual printer
+[printers]
+ comment = All Printers
+ path = /var/spool/samba
+ browseable = no
+# Set public = yes to allow user 'guest account' to print
+ guest ok = no
+ writable = no
+ printable = yes
+
+# This one is useful for people to share files
+;[tmp]
+; comment = Temporary file space
+; path = /tmp
+; read only = no
+; public = yes
+
+# A publicly accessible directory, but read only, except for people in
+# the "staff" group
+;[public]
+; comment = Public Stuff
+; path = /home/samba
+; public = yes
+; writable = yes
+; printable = no
+; write list = @staff
+
+# Other examples.
+#
+# A private printer, usable only by fred. Spool data will be placed in fred's
+# home directory. Note that fred must have write access to the spool directory,
+# wherever it is.
+;[fredsprn]
+; comment = Fred's Printer
+; valid users = fred
+; path = /homes/fred
+; printer = freds_printer
+; public = no
+; writable = no
+; printable = yes
+
+# A private directory, usable only by fred. Note that fred requires write
+# access to the directory.
+;[fredsdir]
+; comment = Fred's Service
+; path = /usr/somewhere/private
+; valid users = fred
+; public = no
+; writable = yes
+; printable = no
+
+# a service which has a different directory for each machine that connects
+# this allows you to tailor configurations to incoming machines. You could
+# also use the %u option to tailor it by user name.
+# The %m gets replaced with the machine name that is connecting.
+;[pchome]
+; comment = PC Directories
+; path = /usr/pc/%m
+; public = no
+; writable = yes
+
+# A publicly accessible directory, read/write to all users. Note that all files
+# created in the directory by users will be owned by the default user, so
+# any user with access can delete any other user's files. Obviously this
+# directory must be writable by the default user. Another user could of course
+# be specified, in which case all files would be owned by that user instead.
+;[public]
+; path = /usr/somewhere/else/public
+; public = yes
+; only guest = yes
+; writable = yes
+; printable = no
+
+# The following two entries demonstrate how to share a directory so that two
+# users can place files there that will be owned by the specific users. In this
+# setup, the directory should be writable by both users and should have the
+# sticky bit set on it to prevent abuse. Obviously this could be extended to
+# as many users as required.
+;[myshare]
+; comment = Mary's and Fred's stuff
+; path = /usr/somewhere/shared
+; valid users = mary fred
+; public = no
+; writable = yes
+; printable = no
+; create mask = 0765
+
+
diff --git a/packaging/Caldera/smb.init b/packaging/Caldera/smb.init
new file mode 100755
index 00000000000..828c19b069d
--- /dev/null
+++ b/packaging/Caldera/smb.init
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# description: Starts and stops the Samba smbd and nmbd daemons \
+# used to provide SMB network services.
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+# Source networking configuration.
+. /etc/sysconfig/network
+
+# Check that networking is up.
+[ ${NETWORKING} = "no" ] && exit 0
+
+# Check that smb.conf exists.
+[ -f /etc/smb.conf ] || exit 0
+
+# See how we were called.
+case "$1" in
+ start)
+ echo -n "Starting SMB services: "
+ smbd -D
+ nmbd -D
+ echo
+ touch /var/lock/subsys/smb
+ ;;
+ stop)
+ echo -n "Shutting down SMB services: "
+ killproc smbd
+ killproc nmbd
+ rm -f /var/lock/subsys/smb
+ echo ""
+ ;;
+ status)
+ status smbd
+ status nmbd
+ ;;
+ restart)
+ echo -n "Restarting SMB services: "
+ $0 stop
+ $0 start
+ echo "done."
+ ;;
+ *)
+ echo "Usage: smb {start|stop|restart|status}"
+ exit 1
+esac
+
diff --git a/packaging/Caldera/smbadduser b/packaging/Caldera/smbadduser
new file mode 100755
index 00000000000..2f38bf28f1a
--- /dev/null
+++ b/packaging/Caldera/smbadduser
@@ -0,0 +1,73 @@
+#!/bin/csh
+#
+# smbadduser - Written by Mike Zakharoff
+#
+unalias *
+set path = ($path)
+
+set smbpasswd = /etc/smbpasswd
+set user_map = /etc/smbusers
+#
+# Set to site specific passwd command
+#
+set passwd = "cat /etc/passwd"
+#set passwd = "niscat passwd.org_dir"
+#set passwd = "ypcat passwd"
+
+set line = "----------------------------------------------------------"
+if ($#argv == 0) then
+ echo $line
+ echo "Written: Mike Zakharoff email: michael.j.zakharoff@boeing.com"
+ echo ""
+ echo " 1) Updates $smbpasswd"
+ echo " 2) Updates $user_map"
+ echo " 3) Executes smbpasswd for each new user"
+ echo ""
+ echo "smbadduser unixid:ntid unixid:ntid ..."
+ echo ""
+ echo "Example: smbadduser zak:zakharoffm johns:smithj"
+ echo $line
+ exit 1
+endif
+
+touch $smbpasswd $user_map
+set new = ()
+foreach one ($argv)
+ echo $one | grep ':' >& /dev/null
+ if ($status != 0) then
+ echo "ERROR: Must use unixid:ntid like -> zak:zakharoffm"
+ continue
+ endif
+ set unix = `echo $one | awk -F: '{print $1}'`
+ set ntid = `echo $one | awk -F: '{print $2}'`
+
+ set usr = `eval $passwd | awk -F: '$1==USR {print $1}' USR=$unix`
+ if ($#usr != 1) then
+ echo "ERROR: $unix Not in passwd database SKIPPING..."
+ continue
+ endif
+ set tmp = `cat $smbpasswd | awk -F: '$1==USR {print $1}' USR=$unix`
+ if ($#tmp != 0) then
+ echo "ERROR: $unix is already in $smbpasswd SKIPPING..."
+ continue
+ endif
+
+ echo "Adding: $unix to $smbpasswd"
+ eval $passwd | \
+ awk -F: '$1==USR { \
+ printf( "%s:%s:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:%s:%s:%s\n", $1, $3, $5, $6, $7) }' USR=$unix >> $smbpasswd
+ if ($unix != $ntid) then
+ echo "Adding: {$unix = $ntid} to $user_map"
+ echo "$unix = $ntid" >> $user_map
+ endif
+ set new = ($new $unix)
+end
+
+#
+# Enter password for new users
+#
+foreach one ($new)
+ echo $line
+ echo "ENTER password for $one"
+ smbpasswd $one
+end
diff --git a/packaging/Caldera/smbprint b/packaging/Caldera/smbprint
new file mode 100755
index 00000000000..ec083eede62
--- /dev/null
+++ b/packaging/Caldera/smbprint
@@ -0,0 +1,77 @@
+#!/bin/sh
+
+# This script is an input filter for printcap printing on a unix machine. It
+# uses the smbclient program to print the file to the specified smb-based
+# server and service.
+# For example you could have a printcap entry like this
+#
+# smb:lp=/dev/null:sd=/usr/spool/smb:sh:if=/usr/local/samba/smbprint
+#
+# which would create a unix printer called "smb" that will print via this
+# script. You will need to create the spool directory /usr/spool/smb with
+# appropriate permissions and ownerships for your system.
+
+# Set these to the server and service you wish to print to
+# In this example I have a WfWg PC called "lapland" that has a printer
+# exported called "printer" with no password.
+
+#
+# Script further altered by hamiltom@ecnz.co.nz (Michael Hamilton)
+# so that the server, service, and password can be read from
+# a /var/spool/lpd/PRINTNAME/.config file.
+#
+# In order for this to work the /etc/printcap entry must include an
+# accounting file (af=...):
+#
+# cdcolour:\
+# :cm=CD IBM Colorjet on 6th:\
+# :sd=/var/spool/lpd/cdcolour:\
+# :af=/var/spool/lpd/cdcolour/acct:\
+# :if=/usr/local/etc/smbprint:\
+# :mx=0:\
+# :lp=/dev/null:
+#
+# The /usr/var/spool/lpd/PRINTNAME/.config file should contain:
+# server=PC_SERVER
+# service=PR_SHARENAME
+# password="password"
+#
+# E.g.
+# server=PAULS_PC
+# service=CJET_371
+# password=""
+
+#
+# Debugging log file, change to /dev/null if you like.
+#
+# logfile=/tmp/smb-print.log
+logfile=/dev/null
+
+
+#
+# The last parameter to the filter is the accounting file name.
+# Extract the directory name from the file name.
+# Concat this with /.config to get the config file.
+#
+eval acct_file=\${$#}
+spool_dir=`dirname $acct_file`
+config_file=$spool_dir/.config
+
+# Should read the following variables set in the config file:
+# server
+# service
+# password
+eval `cat $config_file`
+
+#
+# Some debugging help, change the >> to > if you want to same space.
+#
+echo "server $server, service $service" >> $logfile
+
+(
+# NOTE You may wish to add the line `echo translate' if you want automatic
+# CR/LF translation when printing.
+# echo translate
+ echo "print -"
+ cat
+) | /usr/bin/smbclient "\\\\$server\\$service" $password -U $server -N -P >> $logfile
diff --git a/packaging/Caldera/smbusers b/packaging/Caldera/smbusers
new file mode 100644
index 00000000000..ae3389f53f8
--- /dev/null
+++ b/packaging/Caldera/smbusers
@@ -0,0 +1,3 @@
+# Unix_name = SMB_name1 SMB_name2 ...
+root = administrator admin
+nobody = guest pcguest smbguest
diff --git a/packaging/Caldera/smbw.patch b/packaging/Caldera/smbw.patch
new file mode 100644
index 00000000000..0abbfdf73f6
--- /dev/null
+++ b/packaging/Caldera/smbw.patch
@@ -0,0 +1,10 @@
+--- samba-2.0.0/source/smbwrapper/smbsh.in.orig Mon Oct 5 22:37:01 1998
++++ samba-2.0.0/source/smbwrapper/smbsh.in Mon Oct 5 22:37:51 1998
+@@ -1,6 +1,6 @@
+ #! /bin/sh
+
+-SMBW_LIBDIR=${SMBW_LIBDIR-@builddir@/smbwrapper}
++SMBW_LIBDIR=${SMBW_LIBDIR-/usr/bin}
+
+ if [ ! -f ${SMBW_LIBDIR}/smbwrapper.so ]; then
+ echo You need to set LIBDIR in smbsh
diff --git a/packaging/Digital/package-prep b/packaging/Digital/package-prep
index 2daee8b69ef..a1d3827553c 100755
--- a/packaging/Digital/package-prep
+++ b/packaging/Digital/package-prep
@@ -1,10 +1,10 @@
tar xvf skeleton.tar
-NOWDIR=`pwd`;
( cd /usr/local;
- if [ -x man ]; then mv man man.orig; fi
- if [ -x samba ]; then mv samba samba.orig; fi
- ln -sf $NOWDIR/usr/local/man man;
- ln -sf $NOWDIR/usr/local/samba samba; )
+ mv man man.orig;
+ mv samba samba.orig;
+ DIRNOW=`pwd1`;
+ ln -sf $NOWDIR/usr/local/man man;
+ ln -sf $NOWDIR/usr/local/samba samba; )
gunzip samba-2.0.0.tar.gz
tar xvf samba-2.0.0.tar
cd samba-2.0.0/source
@@ -24,7 +24,7 @@ tar cvf samba-2.0.0.tar samba-2.0.0
rm -rf samba-2.0.0
rm -rf usr var
cd ..
-find samba-2.0.0 -print | cpio -o > samba-2.0.0-OSF1-v4.0-beta5.cpio
-gzip samba-2.0.0-OSF1-v4.0-beta5.cpio
+find samba-2.0.0 -print | cpio -o > samba-2.0.0-OSF1-v4.0-alpha.cpio
+gzip samba-2.0.0-OSF1-v4.0-alpha.cpio
cd samba-2.0.0
-tar xvf install.tar
+tar xcf install.tar
diff --git a/packaging/Digital/samba.init b/packaging/Digital/samba.init
index 6a742440890..c1d605cda06 100755
--- a/packaging/Digital/samba.init
+++ b/packaging/Digital/samba.init
@@ -19,8 +19,8 @@ case "$1" in
'start')
echo "Starting Samba"
- /usr/local/samba/bin/smbd
- /usr/local/samba/bin/nmbd
+ /usr/local/samba/sbin/smbd
+ /usr/local/samba/sbin/nmbd
echo "Done."
;;
'stop')
diff --git a/packaging/Example/package-prep b/packaging/Example/package-prep
index e8f5089a865..5e5834a6d3c 100755
--- a/packaging/Example/package-prep
+++ b/packaging/Example/package-prep
@@ -7,7 +7,7 @@ tar xvf skeleton.tar
( cd /usr/local;
mv man man.orig;
mv samba samba.orig;
- NOWDIR=`pwd`;
+ DIRNOW=`pwd1`;
ln -sf $NOWDIR/usr/local/man man;
ln -sf $NOWDIR/usr/local/samba samba; )
@@ -32,8 +32,9 @@ tar cvf install.tar usr var
# Clean up original sources preserving all configured files
# Note: This will allow installers to check build options
-cd samba-X.X.X/source
-rm -f ../source/bin/*
+cd samba-X.X.X/source/bin
+rm -f *
+cd ..
make clean
cd ../..
tar cvf samba-X.X.X.tar samba-X.X.X
diff --git a/packaging/PHT/TurboLinux/makefile-path.patch b/packaging/PHT/TurboLinux/makefile-path.patch
index 88d5222e09a..5fddb7cbfb4 100644
--- a/packaging/PHT/TurboLinux/makefile-path.patch
+++ b/packaging/PHT/TurboLinux/makefile-path.patch
@@ -1,12 +1,44 @@
---- samba-2.0.1/source/Makefile.in.orig Tue Dec 1 22:32:20 1998
-+++ samba-2.0.1/source/Makefile.in Wed Dec 2 17:11:33 1998
-@@ -25,9 +25,9 @@
- BINDIR = @bindir@
- # we don't use sbindir because we want full compatibility with
+diff -uNr samba-PVERSION/source/Makefile.in samba-kgc/source/Makefile.in
+--- samba-PVERSION/source/Makefile.in Wed Dec 2 14:35:18 1998
++++ samba-kgc/source/Makefile.in Wed Dec 2 15:06:02 1998
+@@ -27,7 +27,7 @@
# the previous releases of Samba
--SBINDIR = @bindir@
-+SBINDIR = @sbindir@
+ SBINDIR = @bindir@
LIBDIR = @libdir@
--VARDIR = @localstatedir@
-+VARDIR = /var/log/samba
+-VARDIR = $(BASEDIR)/var
++VARDIR = /var
MANDIR = @mandir@
+
+ # The permissions to give the executables
+@@ -36,23 +36,23 @@
+ # set these to where to find various files
+ # These can be overridden by command line switches (see smbd(8))
+ # or in smb.conf (see smb.conf(5))
+-SMBLOGFILE = $(VARDIR)/log.smb
+-NMBLOGFILE = $(VARDIR)/log.nmb
++SMBLOGFILE = $(VARDIR)/log/samba/log.smb
++NMBLOGFILE = $(VARDIR)/log/samba/log.nmb
+ CONFIGFILE = $(LIBDIR)/smb.conf
+ LMHOSTSFILE = $(LIBDIR)/lmhosts
+ DRIVERFILE = $(LIBDIR)/printers.def
+ PASSWD_PROGRAM = /bin/passwd
+-SMB_PASSWD_FILE = $(BASEDIR)/private/smbpasswd
+-SMB_PASSGRP_FILE = $(BASEDIR)/private/smbpassgrp
+-SMB_GROUP_FILE = $(BASEDIR)/private/smbgroup
+-SMB_ALIAS_FILE = $(BASEDIR)/private/smbalias
++SMB_PASSWD_FILE = $(LIBDIR)/smbpasswd
++SMB_PASSGRP_FILE = $(LIBDIR)/smbpassgrp
++SMB_GROUP_FILE = $(LIBDIR)/smbgroup
++SMB_ALIAS_FILE = $(LIBDIR)/smbalias
+ SMB_PASSWD_PROGRAM = $(BINDIR)/smbpasswd
+
+ # This is where SWAT images and help files go
+-SWATDIR = $(BASEDIR)/swat
++SWATDIR = $(BASEDIR)/share/swat
+
+ # the directory where lock files go
+-LOCKDIR = $(VARDIR)/locks
++LOCKDIR = $(VARDIR)/lock/samba
+
+ # The directory where code page definition files go
+ CODEPAGEDIR = $(LIBDIR)/codepages
diff --git a/packaging/PHT/TurboLinux/smb.conf b/packaging/PHT/TurboLinux/smb.conf
index e07d15c93ef..bd9a8e15bcc 100644
--- a/packaging/PHT/TurboLinux/smb.conf
+++ b/packaging/PHT/TurboLinux/smb.conf
@@ -85,7 +85,7 @@
# Most people will find that this option gives better performance.
# See speed.txt and the manual pages for details
- socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
+ socket options = TCP_NODELAY
# Configure Samba to use multiple interfaces
# If you have multiple network interfaces then you must list them
diff --git a/packaging/RedHat/makefile-path.patch b/packaging/RedHat/makefile-path.patch
index 88d5222e09a..af2031abaf3 100644
--- a/packaging/RedHat/makefile-path.patch
+++ b/packaging/RedHat/makefile-path.patch
@@ -1,12 +1,46 @@
---- samba-2.0.1/source/Makefile.in.orig Tue Dec 1 22:32:20 1998
-+++ samba-2.0.1/source/Makefile.in Wed Dec 2 17:11:33 1998
-@@ -25,9 +25,9 @@
- BINDIR = @bindir@
- # we don't use sbindir because we want full compatibility with
+diff -uNr samba-orig/source/Makefile.in samba/source/Makefile.in
+--- samba-orig/source/Makefile.in Tue Jan 19 19:51:09 2000
++++ samba/source/Makefile.in Wed Jan 20 02:04:50 2000
+@@ -27,7 +27,7 @@
# the previous releases of Samba
--SBINDIR = @bindir@
-+SBINDIR = @sbindir@
+ SBINDIR = @bindir@
LIBDIR = @libdir@
--VARDIR = @localstatedir@
-+VARDIR = /var/log/samba
+-VARDIR = $(BASEDIR)/var
++VARDIR = /var
MANDIR = @mandir@
+
+ # The permissions to give the executables
+@@ -37,25 +37,25 @@
+ # These can be overridden by command line switches (see smbd(8))
+ # or in smb.conf (see smb.conf(5))
+ LOGFILEBASE = $(VARDIR)
+-SMBLOGFILE = $(LOGFILEBASE)/log.smb
+-NMBLOGFILE = $(LOGFILEBASE)/log.nmb
++SMBLOGFILE = $(LOGFILEBASE)/log/samba/log.smb
++NMBLOGFILE = $(LOGFILEBASE)/log/samba/log.nmb
+ CONFIGFILE = $(LIBDIR)/smb.conf
+ LMHOSTSFILE = $(LIBDIR)/lmhosts
+ DRIVERFILE = $(LIBDIR)/printers.def
+ FORMSFILE = $(LIBDIR)/ntforms.def
+ NTDRIVERSDIR = $(LIBDIR)
+ PASSWD_PROGRAM = /bin/passwd
+-SMB_PASSWD_FILE = $(BASEDIR)/private/smbpasswd
+-SMB_PASSGRP_FILE = $(BASEDIR)/private/smbpassgrp
+-SMB_GROUP_FILE = $(BASEDIR)/private/smbgroup
+-SMB_ALIAS_FILE = $(BASEDIR)/private/smbalias
++SMB_PASSWD_FILE = $(LIBDIR)/smbpasswd
++SMB_PASSGRP_FILE = $(LIBDIR)/smbpassgrp
++SMB_GROUP_FILE = $(LIBDIR)/smbgroup
++SMB_ALIAS_FILE = $(LIBDIR)/smbalias
+ SMB_PASSWD_PROGRAM = $(BINDIR)/smbpasswd
+
+ # This is where SWAT images and help files go
+-SWATDIR = $(BASEDIR)/swat
++SWATDIR = $(BASEDIR)/share/swat
+
+ # the directory where lock files go
+-LOCKDIR = $(VARDIR)/locks
++LOCKDIR = $(VARDIR)/lock/samba
+
+ # The directory where code page definition files go
+ CODEPAGEDIR = $(LIBDIR)/codepages
diff --git a/packaging/RedHat/makerpms.sh.tmpl b/packaging/RedHat/makerpms.sh.tmpl
index 1767176a1fe..fa69370dff0 100644
--- a/packaging/RedHat/makerpms.sh.tmpl
+++ b/packaging/RedHat/makerpms.sh.tmpl
@@ -1,47 +1,14 @@
#!/bin/sh
# Copyright (C) John H Terpstra 1998
-# Updated for RPM 3 by Jochen Wiedmann, joe@ispsoft.de
#
-USERID=`id -u`
-GRPID=`id -g`
+RPMDIR=`rpm --showrc | awk '/^rpmdir/ { print $3}'`
+SPECDIR=`rpm --showrc | awk '/^specdir/ { print $3}'`
+SRCDIR=`rpm --showrc | awk '/^sourcedir/ { print $3}'`
-rpm3var () {
- echo "rpm3var start $1" >>/tmp/log
- var=`rpm --showrc \
- | awk "/-[0-9]+[:=][[:blank:]]+$1[[:blank:]]/ {print \\$3}"`
- echo "var=$var" >>/tmp/log
- while test -n "`echo $var | egrep '%{[_a-zA-Z]+}'`"; do
- v=`echo $var | sed 's/.*%{\([_a-zA-Z]\+\)}.*/\1/'`
- echo "Loop: v=$v" >>/tmp/log
- w="`rpm3var $v`"
- var=`echo $var | sed "s,%{\\([_a-zA-Z]\\+\\)},$w,g"`
- echo "Loop: var=$var" >>/tmp/log
- done
- echo "rpm3var stop $1 $var" >>/tmp/log
- echo $var
-}
-
-case `rpm --version | awk '{print $3}'` in
- 2.*)
- RPMDIR=`rpm --showrc | awk '/^rpmdir/ { print $3}'`
- SPECDIR=`rpm --showrc | awk '/^specdir/ { print $3}'`
- SRCDIR=`rpm --showrc | awk '/^sourcedir/ { print $3}'`
- ;;
- 3.*)
- RPMDIR=`rpm3var _rpmdir`
- SPECDIR=`rpm3var _specdir`
- SRCDIR=`rpm3var _sourcedir`
- ;;
- *)
- echo "Unknown RPM version: `rpm --version`"
- exit 1
- ;;
-esac
-
-( cd ../../.. ; chown -R ${USERID}.${GRPID} ${SRCDIR}/samba-PVERSION )
( cd ../../.. ; tar czvf ${SRCDIR}/samba-PVERSION.tar.gz samba-PVERSION )
-
cp -a *.spec $SPECDIR
cp -a *.patch smb.* samba.log $SRCDIR
+cd $SRCDIR
+chown -R root.root samba-PVERSION
cd $SPECDIR
rpm -ba -v samba2.spec
diff --git a/packaging/RedHat/samba.log b/packaging/RedHat/samba.log
index c8ab3852e27..c5f2a5b45bc 100644
--- a/packaging/RedHat/samba.log
+++ b/packaging/RedHat/samba.log
@@ -1,11 +1,11 @@
/var/log/samba/log.nmb {
postrotate
/usr/bin/killall -HUP nmbd
- endscript
+ endrotate
}
/var/log/samba/log.smb {
postrotate
/usr/bin/killall -HUP smbd
- endscript
+ endrotate
}
diff --git a/packaging/RedHat/samba2.spec.tmpl b/packaging/RedHat/samba2.spec.tmpl
index 92ea52527b2..c7d665c672d 100644
--- a/packaging/RedHat/samba2.spec.tmpl
+++ b/packaging/RedHat/samba2.spec.tmpl
@@ -11,7 +11,6 @@ Packager: John H Terpstra [Samba-Team] <jht@samba.org>
Requires: pam >= 0.64
Prereq: chkconfig fileutils
BuildRoot: /var/tmp/samba
-Prefix: /usr
%description
Samba provides an SMB server which can be used to provide
@@ -39,25 +38,6 @@ for Shadow passwords. Do NOT recompile with the SHADOW_PWD option
enabled. Red Hat Linux has built in support for quotas in PAM.
%changelog
-* Sat Nov 29 1999 Matthew Vanecek <mev0003@unt.edu>
- - Added a Prefix and changed "/usr" to "%{prefix}"
-
-* Sat Nov 11 1999 Tridge <tridge@linuxcare.com>
- - changed from mount.smb to mount.smbfs
-
-* Sat Oct 9 1999 Tridge <tridge@linuxcare.com>
- - removed smbwrapper
- - added smbmnt and smbmount
-
-* Sun Apr 25 1999 John H Terpstra <jht@samba.org>
- - added smbsh.1 man page
-
-* Fri Mar 26 1999 Andrew Tridgell <tridge@samba.org>
- - added --with-pam as pam is no longer used by default
-
-* Sat Jan 27 1999 Jeremy Allison <jra@samba.org>
- - Removed smbrun binary and tidied up some loose ends
-
* Sun Oct 25 1998 John H Terpstra <jht@samba.org>
- Added parameters to /config to ensure smb.conf, lmhosts,
and smbusers never gets over-written.
@@ -95,7 +75,7 @@ enabled. Red Hat Linux has built in support for quotas in PAM.
- Updated spec file
- Included new codepage.936
-* Sat Mar 20 1998 John H Terpstra <jht@samba.org>
+* Sat Mar 20 1998 John H Terpstra <jht@samba.anu.edu/au>
- Added swat facility
* Sat Jan 24 1998 John H Terpstra <jht@samba.org>
@@ -117,8 +97,8 @@ enabled. Red Hat Linux has built in support for quotas in PAM.
%build
cd source
-./configure --prefix=%{prefix} --libdir=/etc --with-lockdir=/var/lock/samba --with-privatedir=/etc --with-swatdir=%{prefix}/share/swat --with-smbmount --with-automount --with-quotas --with-pam
-make all
+./configure --prefix=/usr --libdir=/etc --with-smbwrapper
+make all smbwrapper
%install
rm -rf $RPM_BUILD_ROOT
@@ -127,38 +107,34 @@ mkdir -p $RPM_BUILD_ROOT/etc/codepages/src
mkdir -p $RPM_BUILD_ROOT/etc/{logrotate.d,pam.d}
mkdir -p $RPM_BUILD_ROOT/etc/rc.d/{init.d,rc0.d,rc1.d,rc2.d,rc3.d,rc5.d,rc6.d}
mkdir -p $RPM_BUILD_ROOT/home/samba
-mkdir -p $RPM_BUILD_ROOT%{prefix}/{bin,sbin}
-mkdir -p $RPM_BUILD_ROOT/sbin
-mkdir -p $RPM_BUILD_ROOT%{prefix}/share/swat/{images,help,include}
-mkdir -p $RPM_BUILD_ROOT%{prefix}/man/{man1,man5,man7,man8}
+mkdir -p $RPM_BUILD_ROOT/usr/{bin,sbin}
+mkdir -p $RPM_BUILD_ROOT/usr/share/swat/{images,help,include}
+mkdir -p $RPM_BUILD_ROOT/usr/man/{man1,man5,man7,man8}
mkdir -p $RPM_BUILD_ROOT/var/lock/samba
mkdir -p $RPM_BUILD_ROOT/var/log/samba
mkdir -p $RPM_BUILD_ROOT/var/spool/samba
# Install standard binary files
-for i in nmblookup smbclient smbspool smbpasswd smbstatus testparm testprns \
- make_smbcodepage make_printerdef rpcclient
+for i in nmblookup smbclient smbpasswd smbrun smbstatus testparm testprns \
+ make_smbcodepage make_printerdef rpcclient smbsh smbwrapper.so
do
-install -m755 -s source/bin/$i $RPM_BUILD_ROOT%{prefix}/bin
+install -m755 -s source/bin/$i $RPM_BUILD_ROOT/usr/bin
done
for i in addtosmbpass mksmbpasswd.sh smbtar
do
-install -m755 source/script/$i $RPM_BUILD_ROOT%{prefix}/bin
+install -m755 source/script/$i $RPM_BUILD_ROOT/usr/bin
done
# Install secure binary files
-for i in smbd nmbd swat smbmount smbmnt smbumount
+for i in smbd nmbd swat
do
-install -m755 -s source/bin/$i $RPM_BUILD_ROOT%{prefix}/sbin
+install -m755 -s source/bin/$i $RPM_BUILD_ROOT/usr/sbin
done
-# we need a symlink for mount to recognise the smb filesystem type
-ln -sf %{prefix}/sbin/smbmount $RPM_BUILD_ROOT/sbin/mount.smbfs
-
# Install level 1 man pages
for i in smbclient.1 smbrun.1 smbstatus.1 smbtar.1 testparm.1 testprns.1 make_smbcodepage.1 nmblookup.1
do
-install -m644 docs/manpages/$i $RPM_BUILD_ROOT%{prefix}/man/man1
+install -m644 docs/manpages/$i $RPM_BUILD_ROOT/usr/man/man1
done
# Install codepage source files
@@ -170,37 +146,34 @@ done
# Install SWAT helper files
for i in swat/help/*.html docs/htmldocs/*.html
do
-install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/help
+install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/help
done
for i in swat/images/*.gif
do
-install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/images
+install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/images
done
for i in swat/include/*.html
do
-install -m644 $i $RPM_BUILD_ROOT%{prefix}/share/swat/include
+install -m644 $i $RPM_BUILD_ROOT/usr/share/swat/include
done
# Install the miscellany
-install -m644 swat/README $RPM_BUILD_ROOT%{prefix}/share/swat
-install -m644 docs/manpages/smb.conf.5 $RPM_BUILD_ROOT%{prefix}/man/man5
-install -m644 docs/manpages/lmhosts.5 $RPM_BUILD_ROOT%{prefix}/man/man5
-install -m644 docs/manpages/smbpasswd.5 $RPM_BUILD_ROOT%{prefix}/man/man5
-install -m644 docs/manpages/samba.7 $RPM_BUILD_ROOT%{prefix}/man/man7
-install -m644 docs/manpages/smbd.8 $RPM_BUILD_ROOT%{prefix}/man/man8
-install -m644 docs/manpages/nmbd.8 $RPM_BUILD_ROOT%{prefix}/man/man8
-install -m644 docs/manpages/swat.8 $RPM_BUILD_ROOT%{prefix}/man/man8
-install -m644 docs/manpages/smbmnt.8 $RPM_BUILD_ROOT%{prefix}/man/man8
-install -m644 docs/manpages/smbmount.8 $RPM_BUILD_ROOT%{prefix}/man/man8
-install -m644 docs/manpages/smbpasswd.8 $RPM_BUILD_ROOT%{prefix}/man/man8
-install -m644 docs/manpages/smbspool.8 $RPM_BUILD_ROOT%{prefix}/man/man8
+install -m644 swat/README $RPM_BUILD_ROOT/usr/share/swat
+install -m644 docs/manpages/smb.conf.5 $RPM_BUILD_ROOT/usr/man/man5
+install -m644 docs/manpages/lmhosts.5 $RPM_BUILD_ROOT/usr/man/man5
+install -m644 docs/manpages/smbpasswd.5 $RPM_BUILD_ROOT/usr/man/man5
+install -m644 docs/manpages/samba.7 $RPM_BUILD_ROOT/usr/man/man7
+install -m644 docs/manpages/smbd.8 $RPM_BUILD_ROOT/usr/man/man8
+install -m644 docs/manpages/nmbd.8 $RPM_BUILD_ROOT/usr/man/man8
+install -m644 docs/manpages/swat.8 $RPM_BUILD_ROOT/usr/man/man8
+install -m644 docs/manpages/smbpasswd.8 $RPM_BUILD_ROOT/usr/man/man8
install -m644 packaging/RedHat/smb.conf $RPM_BUILD_ROOT/etc/smb.conf
install -m644 packaging/RedHat/smbusers $RPM_BUILD_ROOT/etc/smbusers
-install -m755 packaging/RedHat/smbprint $RPM_BUILD_ROOT%{prefix}/bin
-install -m755 packaging/RedHat/findsmb $RPM_BUILD_ROOT%{prefix}/bin
-install -m755 packaging/RedHat/smbadduser $RPM_BUILD_ROOT%{prefix}/bin
+install -m755 packaging/RedHat/smbprint $RPM_BUILD_ROOT/usr/bin
+install -m755 packaging/RedHat/findsmb $RPM_BUILD_ROOT/usr/bin
+install -m755 packaging/RedHat/smbadduser $RPM_BUILD_ROOT/usr/bin
install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT/etc/rc.d/init.d/smb
-install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT%{prefix}/sbin/samba
+install -m755 packaging/RedHat/smb.init $RPM_BUILD_ROOT/usr/sbin/samba
install -m644 packaging/RedHat/samba.pamd $RPM_BUILD_ROOT/etc/pam.d/samba
install -m644 packaging/RedHat/samba.log $RPM_BUILD_ROOT/etc/logrotate.d/samba
echo 127.0.0.1 localhost > $RPM_BUILD_ROOT/etc/lmhosts
@@ -214,7 +187,7 @@ rm -rf $RPM_BUILD_ROOT
# Build codepage load files
for i in 437 737 850 852 861 866 932 936 949 950
do
-%{prefix}/bin/make_smbcodepage c $i /etc/codepages/src/codepage_def.$i /etc/codepages/codepage.$i
+/usr/bin/make_smbcodepage c $i /etc/codepages/src/codepage_def.$i /etc/codepages/codepage.$i
done
# Add swat entry to /etc/services if not already there
@@ -224,7 +197,7 @@ fi
# Add swat entry to /etc/inetd.conf if needed
if !( grep ^[:space:]*swat /etc/inetd.conf > /dev/null ) then
- echo 'swat stream tcp nowait.400 root %{prefix}/sbin/swat swat' >> /etc/inetd.conf
+ echo 'swat stream tcp nowait.400 root /usr/sbin/swat swat' >> /etc/inetd.conf
killall -1 inetd || :
fi
@@ -248,7 +221,9 @@ fi
%postun
# Only delete remnants of samba if this is the final deletion.
-if [ $1 = 0 ] ; then
+if [ $1 != 0 ] ; then
+ exit 0
+
if [ -x /etc/pam.d/samba ]; then
rm -f /etc/pam.d/samba
fi
@@ -280,60 +255,56 @@ fi
%doc docs
%doc swat/README
%doc examples
-%attr(-,root,root) %{prefix}/sbin/smbd
-%attr(-,root,root) %{prefix}/sbin/nmbd
-%attr(-,root,root) %{prefix}/sbin/swat
-%attr(-,root,root) %{prefix}/sbin/smbmnt
-%attr(-,root,root) %{prefix}/sbin/smbmount
-%attr(-,root,root) %{prefix}/sbin/smbumount
-%attr(-,root,root) /sbin/mount.smbfs
-%attr(0750,root,root) %{prefix}/sbin/samba
-%attr(-,root,root) %{prefix}/bin/addtosmbpass
-%attr(-,root,root) %{prefix}/bin/mksmbpasswd.sh
-%attr(-,root,root) %{prefix}/bin/smbclient
-%attr(-,root,root) %{prefix}/bin/smbspool
-%attr(-,root,root) %{prefix}/bin/rpcclient
-%attr(-,root,root) %{prefix}/bin/testparm
-%attr(-,root,root) %{prefix}/bin/testprns
-%attr(-,root,root) %{prefix}/bin/findsmb
-%attr(-,root,root) %{prefix}/bin/smbstatus
-%attr(-,root,root) %{prefix}/bin/nmblookup
-%attr(-,root,root) %{prefix}/bin/make_smbcodepage
-%attr(-,root,root) %{prefix}/bin/make_printerdef
-%attr(-,root,root) %{prefix}/bin/smbpasswd
-%attr(-,root,root) %{prefix}/bin/smbtar
-%attr(-,root,root) %{prefix}/bin/smbprint
-%attr(-,root,root) %{prefix}/bin/smbadduser
-%attr(-,root,root) %{prefix}/share/swat/help/welcome.html
-%attr(-,root,root) %{prefix}/share/swat/help/DOMAIN_MEMBER.html
-%attr(-,root,root) %{prefix}/share/swat/help/NT_Security.html
-%attr(-,root,root) %{prefix}/share/swat/help/lmhosts.5.html
-%attr(-,root,root) %{prefix}/share/swat/help/make_smbcodepage.1.html
-%attr(-,root,root) %{prefix}/share/swat/help/nmbd.8.html
-%attr(-,root,root) %{prefix}/share/swat/help/nmblookup.1.html
-%attr(-,root,root) %{prefix}/share/swat/help/samba.7.html
-%attr(-,root,root) %{prefix}/share/swat/help/smb.conf.5.html
-%attr(-,root,root) %{prefix}/share/swat/help/smbclient.1.html
-%attr(-,root,root) %{prefix}/share/swat/help/smbspool.8.html
-%attr(-,root,root) %{prefix}/share/swat/help/smbd.8.html
-%attr(-,root,root) %{prefix}/share/swat/help/smbpasswd.5.html
-%attr(-,root,root) %{prefix}/share/swat/help/smbpasswd.8.html
-%attr(-,root,root) %{prefix}/share/swat/help/smbrun.1.html
-%attr(-,root,root) %{prefix}/share/swat/help/smbstatus.1.html
-%attr(-,root,root) %{prefix}/share/swat/help/smbtar.1.html
-%attr(-,root,root) %{prefix}/share/swat/help/swat.8.html
-%attr(-,root,root) %{prefix}/share/swat/help/testparm.1.html
-%attr(-,root,root) %{prefix}/share/swat/help/testprns.1.html
-%attr(-,root,root) %{prefix}/share/swat/images/globals.gif
-%attr(-,root,root) %{prefix}/share/swat/images/home.gif
-%attr(-,root,root) %{prefix}/share/swat/images/passwd.gif
-%attr(-,root,root) %{prefix}/share/swat/images/printers.gif
-%attr(-,root,root) %{prefix}/share/swat/images/shares.gif
-%attr(-,root,root) %{prefix}/share/swat/images/samba.gif
-%attr(-,root,root) %{prefix}/share/swat/images/status.gif
-%attr(-,root,root) %{prefix}/share/swat/images/viewconfig.gif
-%attr(-,root,root) %{prefix}/share/swat/include/header.html
-%attr(-,root,root) %{prefix}/share/swat/include/footer.html
+%attr(-,root,root) /usr/sbin/smbd
+%attr(-,root,root) /usr/sbin/nmbd
+%attr(-,root,root) /usr/sbin/swat
+%attr(0750,root,root) /usr/sbin/samba
+%attr(-,root,root) /usr/bin/addtosmbpass
+%attr(-,root,root) /usr/bin/mksmbpasswd.sh
+%attr(-,root,root) /usr/bin/smbclient
+%attr(-,root,root) /usr/bin/rpcclient
+%attr(-,root,root) /usr/bin/testparm
+%attr(-,root,root) /usr/bin/testprns
+%attr(-,root,root) /usr/bin/smbrun
+%attr(-,root,root) /usr/bin/findsmb
+%attr(-,root,root) /usr/bin/smbstatus
+%attr(-,root,root) /usr/bin/nmblookup
+%attr(-,root,root) /usr/bin/make_smbcodepage
+%attr(-,root,root) /usr/bin/make_printerdef
+%attr(-,root,root) /usr/bin/smbpasswd
+%attr(-,root,root) /usr/bin/smbtar
+%attr(-,root,root) /usr/bin/smbprint
+%attr(-,root,root) /usr/bin/smbadduser
+%attr(0755,root,root) /usr/bin/smbsh
+%attr(0755,root,root) /usr/bin/smbwrapper.so
+%attr(-,root,root) /usr/share/swat/help/welcome.html
+%attr(-,root,root) /usr/share/swat/help/DOMAIN_MEMBER.html
+%attr(-,root,root) /usr/share/swat/help/lmhosts.5.html
+%attr(-,root,root) /usr/share/swat/help/make_smbcodepage.1.html
+%attr(-,root,root) /usr/share/swat/help/nmbd.8.html
+%attr(-,root,root) /usr/share/swat/help/nmblookup.1.html
+%attr(-,root,root) /usr/share/swat/help/samba.7.html
+%attr(-,root,root) /usr/share/swat/help/smb.conf.5.html
+%attr(-,root,root) /usr/share/swat/help/smbclient.1.html
+%attr(-,root,root) /usr/share/swat/help/smbd.8.html
+%attr(-,root,root) /usr/share/swat/help/smbpasswd.5.html
+%attr(-,root,root) /usr/share/swat/help/smbpasswd.8.html
+%attr(-,root,root) /usr/share/swat/help/smbrun.1.html
+%attr(-,root,root) /usr/share/swat/help/smbstatus.1.html
+%attr(-,root,root) /usr/share/swat/help/smbtar.1.html
+%attr(-,root,root) /usr/share/swat/help/swat.8.html
+%attr(-,root,root) /usr/share/swat/help/testparm.1.html
+%attr(-,root,root) /usr/share/swat/help/testprns.1.html
+%attr(-,root,root) /usr/share/swat/images/globals.gif
+%attr(-,root,root) /usr/share/swat/images/home.gif
+%attr(-,root,root) /usr/share/swat/images/passwd.gif
+%attr(-,root,root) /usr/share/swat/images/printers.gif
+%attr(-,root,root) /usr/share/swat/images/shares.gif
+%attr(-,root,root) /usr/share/swat/images/samba.gif
+%attr(-,root,root) /usr/share/swat/images/status.gif
+%attr(-,root,root) /usr/share/swat/images/viewconfig.gif
+%attr(-,root,root) /usr/share/swat/include/header.html
+%attr(-,root,root) /usr/share/swat/include/footer.html
%attr(-,root,root) %config(noreplace) /etc/lmhosts
%attr(-,root,root) %config(noreplace) /etc/smb.conf
%attr(-,root,root) %config(noreplace) /etc/smbusers
@@ -350,25 +321,22 @@ fi
%attr(-,root,root) /etc/codepages/src/codepage_def.936
%attr(-,root,root) /etc/codepages/src/codepage_def.949
%attr(-,root,root) /etc/codepages/src/codepage_def.950
-%attr(-,root,root) %{prefix}/man/man1/smbstatus.1
-%attr(-,root,root) %{prefix}/man/man1/smbclient.1
-%attr(-,root,root) %{prefix}/man/man1/make_smbcodepage.1
-%attr(-,root,root) %{prefix}/man/man1/smbrun.1
-%attr(-,root,root) %{prefix}/man/man1/smbtar.1
-%attr(-,root,root) %{prefix}/man/man1/testparm.1
-%attr(-,root,root) %{prefix}/man/man1/testprns.1
-%attr(-,root,root) %{prefix}/man/man1/nmblookup.1
-%attr(-,root,root) %{prefix}/man/man5/smb.conf.5
-%attr(-,root,root) %{prefix}/man/man5/lmhosts.5
-%attr(-,root,root) %{prefix}/man/man5/smbpasswd.5
-%attr(-,root,root) %{prefix}/man/man7/samba.7
-%attr(-,root,root) %{prefix}/man/man8/smbd.8
-%attr(-,root,root) %{prefix}/man/man8/nmbd.8
-%attr(-,root,root) %{prefix}/man/man8/smbpasswd.8
-%attr(-,root,root) %{prefix}/man/man8/swat.8
-%attr(-,root,root) %{prefix}/man/man8/smbmnt.8
-%attr(-,root,root) %{prefix}/man/man8/smbmount.8
-%attr(-,root,root) %{prefix}/man/man8/smbspool.8
+%attr(-,root,root) /usr/man/man1/smbstatus.1
+%attr(-,root,root) /usr/man/man1/smbclient.1
+%attr(-,root,root) /usr/man/man1/make_smbcodepage.1
+%attr(-,root,root) /usr/man/man1/smbrun.1
+%attr(-,root,root) /usr/man/man1/smbtar.1
+%attr(-,root,root) /usr/man/man1/testparm.1
+%attr(-,root,root) /usr/man/man1/testprns.1
+%attr(-,root,root) /usr/man/man1/nmblookup.1
+%attr(-,root,root) /usr/man/man5/smb.conf.5
+%attr(-,root,root) /usr/man/man5/lmhosts.5
+%attr(-,root,root) /usr/man/man5/smbpasswd.5
+%attr(-,root,root) /usr/man/man7/samba.7
+%attr(-,root,root) /usr/man/man8/smbd.8
+%attr(-,root,root) /usr/man/man8/nmbd.8
+%attr(-,root,root) /usr/man/man8/smbpasswd.8
+%attr(-,root,root) /usr/man/man8/swat.8
%attr(-,root,nobody) %dir /home/samba
%attr(-,root,root) %dir /etc/codepages
%attr(-,root,root) %dir /etc/codepages/src
diff --git a/packaging/RedHat/smb.conf b/packaging/RedHat/smb.conf
index e07d15c93ef..bd9a8e15bcc 100644
--- a/packaging/RedHat/smb.conf
+++ b/packaging/RedHat/smb.conf
@@ -85,7 +85,7 @@
# Most people will find that this option gives better performance.
# See speed.txt and the manual pages for details
- socket options = TCP_NODELAY SO_RCVBUF=8192 SO_SNDBUF=8192
+ socket options = TCP_NODELAY
# Configure Samba to use multiple interfaces
# If you have multiple network interfaces then you must list them
diff --git a/packaging/SGI/idb.pl b/packaging/SGI/idb.pl
index a7f3c574a74..cc446272731 100755
--- a/packaging/SGI/idb.pl
+++ b/packaging/SGI/idb.pl
@@ -10,15 +10,6 @@ $curdir = $ENV{"PWD"};
open(IGNORES,"../../source/.cvsignore") || die "Unable to open .cvsignore file\n";
while (<IGNORES>) {
chop;
- next if /cvs\.log/;
- $ignores{$_}++;
-}
-close IGNORES;
-
-# We don't want the files listed in .cvsignore in the source/include tree
-open(IGNORES,"../../source/include/.cvsignore") || die "Unable to open include/.cvsignore file\n";
-while (<IGNORES>) {
- chop;
$ignores{$_}++;
}
close IGNORES;
@@ -41,7 +32,6 @@ if (@sprogs) {
}
if (@progs) {
@progs[0] =~ s/^.*\=//;
- @progs[0] =~ s/\$\(\S+\)\s//g;
@progs = split(' ',@progs[0]);
}
if (@mprogs) {
@@ -58,7 +48,6 @@ if (@progs2) {
}
if (@scripts) {
@scripts[0] =~ s/^.*\=//;
- @scripts[0] =~ s/\$\(srcdir\)\///g;
@scripts = split(' ',@scripts[0]);
}
if (@codepage) {
@@ -188,7 +177,7 @@ while (@sorted) {
print IDB "d 0755 root sys usr/samba/src/$nextfile $nextfile samba.src.samba\n";
}
else {
- if (grep((/\.sh$/ | /configure$/ | /configure\.developer/ | /config\.guess/ | /config\.sub/ | /\.pl$/ | /mkman$/),$nextfile)) {
+ if (grep((/\.sh$/ | /\.pl$/ | /mkman$/),$nextfile)) {
print IDB "f 0755 root sys usr/samba/src/$nextfile $nextfile samba.src.samba\n";
}
else {
@@ -221,7 +210,7 @@ while (@catman) {
$nextfile = shift @catman;
($file = $nextfile) =~ s/^packaging\/SGI\/catman\///;
($dirnum = $file) =~ s/^[\D]*//;
- $dirnum =~ s/\.z//;
+ $dirnum =~ s/\.Z//;
if ($dirnum ne $olddirnum) {
print IDB "d 0755 root sys usr/share/catman/u_man/cat$dirnum packaging/SGI samba.man.manpages\n";
$olddirnum = $dirnum;
diff --git a/packaging/SGI/inst.msg b/packaging/SGI/inst.msg
index 248e990c4a5..c613a09d018 100755
--- a/packaging/SGI/inst.msg
+++ b/packaging/SGI/inst.msg
@@ -2,7 +2,7 @@
echo
echo
-echo Samba has been installed on your system.
+echo Samba for IRIX has been installed on your system.
echo
echo Your /etc/services and /etc/inetd.conf files have
echo been modified to automatically start the
diff --git a/packaging/SGI/mkman b/packaging/SGI/mkman
index a39ed9fdd0c..4de437d0ad8 100755
--- a/packaging/SGI/mkman
+++ b/packaging/SGI/mkman
@@ -9,10 +9,7 @@ FILES="*.?"
cd ../../docs/manpages
for FILE in $FILES ; do
- if [ "$FILE" = "smbmnt.8" ]; then continue; fi;
- if [ "$FILE" = "smbmount.8" -o "$FILE" = "smbumount.8" ]; then continue; fi;
- if [ "$FILE" = "smbrun.1" ]; then continue; fi;
neqn $FILE | tbl | nroff -man > ../../packaging/SGI/catman/`basename $FILE`
- pack -f ../../packaging/SGI/catman/`basename $FILE`
+ compress -f ../../packaging/SGI/catman/`basename $FILE`
done
cd ../../packaging/SGI
diff --git a/packaging/SGI/mkrelease.sh b/packaging/SGI/mkrelease.sh
index 19aa642aadd..cfe9c1f6b86 100755
--- a/packaging/SGI/mkrelease.sh
+++ b/packaging/SGI/mkrelease.sh
@@ -14,7 +14,6 @@
doclean=""
SGI_ABI=-n32
-ISA=-mips3
CC=cc
if [ ! -f ../../source/Makefile ]; then
@@ -26,7 +25,6 @@ if [ "$1" = "clean" ]; then
shift
elif [ "$1" = "5" ]; then
SGI_ABI=-32
- ISA=""
shift
fi
@@ -37,11 +35,10 @@ if [ "$1" = "clean" ]; then
shift
elif [ "$1" = "5" ]; then
SGI_ABI=-32
- ISA=""
shift
fi
-export SGI_ABI ISA CC
+export SGI_ABI CC
if [ "$doclean" = "clean" ]; then
cd ../../source
@@ -67,6 +64,11 @@ fi
cd ../../source
if [ "$doclean" = "clean" ]; then
echo Create SGI specific Makefile
+ chmod +x configure
+ chmod +x configure.developer
+ chmod +x config.guess
+ chmod +x config.status
+ chmod +x config.sub
./configure --prefix=/usr/samba --mandir=/usr/share/catman --with-smbwrapper
errstat=$?
if [ $errstat -ne 0 ]; then
diff --git a/packaging/SGI/sambalp b/packaging/SGI/sambalp
index 61e62215c91..fd0cef8f933 100644
--- a/packaging/SGI/sambalp
+++ b/packaging/SGI/sambalp
@@ -146,12 +146,5 @@ if ($PSFIX) { # are we running a "psfix"?
system("$lpcommand $file");
}
-if ($file =~ m(^/)) {
- # $file is a fully specified path
- # Remove the file only if it lives in a directory ending in /tmp.
- unlink($file) if ($file =~ m(/tmp/[^/]+$));
-} else {
- # $file is NOT a fully specified path
- # Remove the file only if current directory ends in /tmp.
- unlink($file) if (`pwd` =~ m(/tmp$));
-}
+# Remove the file only if it lives in /usr/tmp, /tmp, or /var/tmp.
+unlink($file) if $file =~ m=^(/(usr|var))?/tmp=;
diff --git a/packaging/SGI/smb.conf b/packaging/SGI/smb.conf
index 68187ee2886..9a154f8f9b5 100644
--- a/packaging/SGI/smb.conf
+++ b/packaging/SGI/smb.conf
@@ -76,16 +76,6 @@
preserve case = yes
short preserve case = yes
-; These are the settings required for IRIX password sync
- passwd program = /usr/bin/passwd %u
- passwd chat = *ew*password:* %n\n *e-enter*new*password:* %n\n
-
-; Uncomment the following if you wish to use encrypted passwords.
-; encrypt passwords = yes
-
-; Uncomment the following if you wish to sync unix and smbpasswd
-; unix password sync = yes
-
[homes]
comment = Home Directories
browseable = no
diff --git a/packaging/SGI/spec.pl b/packaging/SGI/spec.pl
index 4541eb04ec3..3bd643eef6e 100755
--- a/packaging/SGI/spec.pl
+++ b/packaging/SGI/spec.pl
@@ -22,10 +22,6 @@ elsif (/-HEAD/) {
$_ =~ s/-HEAD/.01/;
$_ .= '.99';
}
-elsif (/pre-/) {
- $_ =~ s/pre-//;
- $_ .= '.00';
-}
elsif (/p/) {
$_ =~ s/p/./;
$_ .= '.00';
diff --git a/packaging/Solaris/pkg-specs/Packaging.script b/packaging/Solaris/pkg-specs/Packaging.script
new file mode 100644
index 00000000000..6f182c33e52
--- /dev/null
+++ b/packaging/Solaris/pkg-specs/Packaging.script
@@ -0,0 +1,5 @@
+#!/bin/sh
+./mkprototype
+pkgmk -o -d /tmp -b `pwd` -f ./prototype
+cd /tmp
+pkgtrans . samba.pkg samba
diff --git a/packaging/Solaris/pkg-specs/mkprototype b/packaging/Solaris/pkg-specs/mkprototype
new file mode 100644
index 00000000000..5ca0746beea
--- /dev/null
+++ b/packaging/Solaris/pkg-specs/mkprototype
@@ -0,0 +1,31 @@
+#!/bin/sh
+# this creates prototype files
+pkgproto * > prototype
+nawk 'BEGIN { print "# d directory"
+ print "# e a file to be edited upon installation or removal"
+ print "# f a standard executable or data file"
+ print "# i installation script or information file"
+ print "# l linked file"
+ print "# s symbolic link"
+ print "# v volatile file (one whose contents are expected to
+change)"
+ print "#" }
+/ pkginfo / { print "i pkginfo" ; next }
+/ postinstall / { print "i postinstall" ; next }
+/ postremove / { print "i postremove" ; next }
+/d none usr / { print "d none usr ? ? ?" ; next }
+/d none usr\/local / { print "d none usr/local ? ? ?" ; next }
+/d none etc / { print "d none etc ? ? ?" ; next }
+/f none etc\// { $1 = "v" }
+/d none opt / { print "d none opt ? ? ?" ; next }
+/d none var / { print "d none var ? ? ?" ; next }
+/none prototype / { next }
+/none mkprototype / { next }
+/ src[ \/]/ { next }
+/^[dfv]/ { $5 = "bin"
+ $6 = "bin"
+ print
+ next }
+{ print }' prototype >/tmp/prototype.$$
+mv /tmp/prototype.$$ prototype
+
diff --git a/packaging/Solaris/pkg-specs/pkginfo b/packaging/Solaris/pkg-specs/pkginfo
index d195f177e90..ab06b3fffab 100644
--- a/packaging/Solaris/pkg-specs/pkginfo
+++ b/packaging/Solaris/pkg-specs/pkginfo
@@ -1,12 +1,12 @@
+PSTAMP=Mon Sep 29 17:26:14 BST 1997
PKG=samba
NAME=SMB based file/printer sharing
+VERSION=1.9.17p2,REV=1
ARCH=sparc
-VERSION=2.0.6
CATEGORY=system
-VENDOR=Samba Group
+VENDOR=samba group
DESC=File and printer sharing for NT workstations
-HOTLINE=Please contact your local UNIX support group
-EMAIL=samba@samba.org
CLASSES=none
-BASEDIR=/usr/local
INTONLY=1
+HOTLINE=Please contact your local UNIX support group
+BASEDIR=/
diff --git a/packaging/Solaris/pkg-specs/postinstall b/packaging/Solaris/pkg-specs/postinstall
new file mode 100644
index 00000000000..0fbe9da10b5
--- /dev/null
+++ b/packaging/Solaris/pkg-specs/postinstall
@@ -0,0 +1,37 @@
+#!/bin/sh
+# install samba
+
+nawk '/^netbios-[ns]*[ ]/ {next}
+{print}
+END { print "netbios-ssn 139/tcp"
+ print "netbios-ns 137/udp # samba service" }' \
+ ${PKG_INSTALL_ROOT}/etc/inet/services > /tmp/services.$$ && \
+ mv -f /tmp/services.$$ ${PKG_INSTALL_ROOT}/etc/inet/services &&
+\
+ chmod 644 ${PKG_INSTALL_ROOT}/etc/inet/services && \
+ echo "Updated ${PKG_INSTALL_ROOT}/etc/inet/services"
+
+nawk '/samba.*mbd[ ]/ { next }
+{print}
+END { print "# samba connections are handled by smbd and nmbd"
+ print "netbios-ssn stream tcp nowait root /opt/samba/bin/smbd
+smbd"
+ print "netbios-ns dgram udp wait root /opt/samba/bin/nmbd nmbd" }'
+\
+ ${PKG_INSTALL_ROOT}/etc/inet/inetd.conf > /tmp/inetd.conf.$$ &&
+\
+ mv -f /tmp/inetd.conf.$$ ${PKG_INSTALL_ROOT}/etc/inet/inetd.conf
+&& \
+ chmod 644 ${PKG_INSTALL_ROOT}/etc/inet/inetd.conf && \
+ echo "Updated ${PKG_INSTALL_ROOT}/etc/inet/inetd.conf"
+
+echo "Installed samba service into ${PKG_INSTALL_ROOT:-/}"
+
+inetpid=`/bin/ps -ef | awk '/ \/usr\/sbin\/inetd / { print $2 } '`
+if [ "X$inetpid" = "X" ]; then
+ echo "inetd not running"
+else
+ echo "Restarting inetd($inetpid)"
+ kill -HUP $inetpid
+fi
+
diff --git a/packaging/Solaris/pkg-specs/postremove b/packaging/Solaris/pkg-specs/postremove
new file mode 100644
index 00000000000..7f7a5c1f8e4
--- /dev/null
+++ b/packaging/Solaris/pkg-specs/postremove
@@ -0,0 +1,30 @@
+#!/bin/sh
+# remove samba
+
+nawk '/^netbios-[ns]*[ ]/ {next}
+{print} ' \
+ ${PKG_INSTALL_ROOT}/etc/inet/services > /tmp/services.$$ && \
+ mv -f /tmp/services.$$ ${PKG_INSTALL_ROOT}/etc/inet/services &&
+\
+ chmod 644 ${PKG_INSTALL_ROOT}/etc/inet/services && \
+ echo "Updated ${PKG_INSTALL_ROOT}/etc/inet/services"
+
+nawk '/samba.*mbd[ ]/ { next }
+{print} ' \
+ ${PKG_INSTALL_ROOT}/etc/inet/inetd.conf > /tmp/inetd.conf.$$ &&
+\
+ mv -f /tmp/inetd.conf.$$ ${PKG_INSTALL_ROOT}/etc/inet/inetd.conf
+&& \
+ chmod 644 ${PKG_INSTALL_ROOT}/etc/inet/inetd.conf && \
+ echo "Updated ${PKG_INSTALL_ROOT}/etc/inet/inetd.conf"
+
+echo "Removed samba service from ${PKG_INSTALL_ROOT:-/}"
+
+inetpid=`/bin/ps -ef | awk '/ \/usr\/sbin\/inetd / { print $2 } '`
+if [ "X$inetpid" = "X" ]; then
+ echo "inetd not running"
+else
+ echo "Restarting inetd($inetpid)"
+ kill -HUP $inetpid
+fi
+
diff --git a/packaging/SuSE/5.2/samba.spec b/packaging/SuSE/5.2/samba.spec
index 5f20875c9ea..637af1781e1 100644
--- a/packaging/SuSE/5.2/samba.spec
+++ b/packaging/SuSE/5.2/samba.spec
@@ -67,6 +67,7 @@ fi
/usr/bin/smbclient
/usr/bin/smbmount
/usr/bin/smbpasswd
+/usr/bin/smbrun
/usr/bin/smbstatus
/usr/bin/smbtar
/usr/bin/smbumount
@@ -108,6 +109,8 @@ Samba includes the following programs (in summary):
* smbd, the SMB server. This handles actual connections from clients.
* nmbd, the Netbios name server, which helps clients locate servers.
* smbclient, the Unix-hosted client program.
+* smbrun, a little 'glue' program to help the server run external
+programs.
* testprns, a program to test server access to printers.
* testparm, a program to test the Samba configuration file for correctness.
* smb.conf, the Samba configuration file.
diff --git a/source/.cvsignore b/source/.cvsignore
index 247b980fa8d..30ba04b6d01 100644
--- a/source/.cvsignore
+++ b/source/.cvsignore
@@ -6,3 +6,4 @@ config.log
config.status
cvs.log
so_locations
+libtool
diff --git a/source/Makefile.in b/source/Makefile.in
index 584fec0b612..395df94e3c1 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -6,6 +6,7 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
mandir=@mandir@
+DESTDIR=
LIBS=@LIBS@
CC=@CC@
@@ -13,12 +14,18 @@ CFLAGS=@CFLAGS@
CPPFLAGS=@CPPFLAGS@
LDFLAGS=@LDFLAGS@
AWK=@AWK@
+LIBTOOL=@LIBTOOL@ --quiet
+LIBTOOL_DEPS=@LIBTOOL_DEPS@
+LINK=$(LIBTOOL) --mode=link $(CC) $(FLAGS) $(LDFLAGS)
+INSTALL = @INSTALL@
INSTALLCMD=@INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
VPATH=@srcdir@
srcdir=@srcdir@
builddir=@builddir@
+top_builddir=.
SHELL=/bin/sh
BASEDIR= @prefix@
@@ -27,8 +34,10 @@ BINDIR = @bindir@
# the previous releases of Samba
SBINDIR = @bindir@
LIBDIR = @libdir@
-VARDIR = @localstatedir@
+VARDIR = $(BASEDIR)/var
MANDIR = @mandir@
+SYSCONFDIR = @sysconfdir@
+PRIVATEDIR = $(BASEDIR)/private
# The permissions to give the executables
INSTALLPERMS = 0755
@@ -36,30 +45,33 @@ INSTALLPERMS = 0755
# set these to where to find various files
# These can be overridden by command line switches (see smbd(8))
# or in smb.conf (see smb.conf(5))
-SMBLOGFILE = $(VARDIR)/log.smb
-NMBLOGFILE = $(VARDIR)/log.nmb
+LOGFILEBASE = $(VARDIR)
+SMBLOGFILE = $(LOGFILEBASE)/log.smb
+NMBLOGFILE = $(LOGFILEBASE)/log.nmb
CONFIGFILE = $(LIBDIR)/smb.conf
LMHOSTSFILE = $(LIBDIR)/lmhosts
DRIVERFILE = $(LIBDIR)/printers.def
-NTDRIVERSDIR = $(LIBDIR)/ntprinters
-FORMSFILE = $(NTDRIVERSDIR)/ntforms.def
+FORMSFILE = $(LIBDIR)/ntforms.def
+NTDRIVERSDIR = $(LIBDIR)
PASSWD_PROGRAM = /bin/passwd
-# This is where smbpasswd et al go
-PRIVATEDIR = @privatedir@
-
-SMB_PASSWD_FILE = $(PRIVATEDIR)/smbpasswd
+SMB_PASSWD_FILE = $(BASEDIR)/private/smbpasswd
+SAM_DIR = $(BASEDIR)/sam
+SMB_PASSGRP_FILE = $(BASEDIR)/private/smbpassgrp
+SMB_GROUP_FILE = $(BASEDIR)/private/smbgroup
+SMB_ALIAS_FILE = $(BASEDIR)/private/smbalias
+SMB_PASSWD_PROGRAM = $(BINDIR)/smbpasswd
# This is where SWAT images and help files go
-SWATDIR = @swatdir@
+SWATDIR = $(BASEDIR)/swat
# the directory where lock files go
-LOCKDIR = @lockdir@
+LOCKDIR = $(VARDIR)/locks
# The directory where code page definition files go
CODEPAGEDIR = $(LIBDIR)/codepages
# The current codepage definition list.
-CODEPAGELIST= 437 737 850 852 861 932 866 949 950 936 1251 ISO8859-1 ISO8859-2 ISO8859-5 ISO8859-7 KOI-R
+CODEPAGELIST= 437 737 850 852 861 932 866 949 950 936
# where you are going to have the smbrun binary. This defaults to the
# install directory. This binary is needed for correct printing
@@ -69,22 +81,41 @@ CODEPAGELIST= 437 737 850 852 861 932 866 949 950 936 1251 ISO8859-1 ISO8859-2 I
SMBRUN = $(BINDIR)/smbrun
-PASSWD_FLAGS = -DPASSWD_PROGRAM=\"$(PASSWD_PROGRAM)\" -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\"
-FLAGS1 = $(CFLAGS) -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper $(CPPFLAGS) -DSMBLOGFILE=\"$(SMBLOGFILE)\" -DNMBLOGFILE=\"$(NMBLOGFILE)\"
+PASSWD_FLAGS = \
+ -DPASSWD_PROGRAM=\"$(PASSWD_PROGRAM)\" \
+ -DSMB_PASSWD_PROGRAM=\"$(SMB_PASSWD_PROGRAM)\" \
+ -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \
+ -DSAM_DIR=\"$(SAM_DIR)\" \
+ -DSMB_PASSGRP_FILE=\"$(SMB_PASSGRP_FILE)\" \
+ -DSMB_GROUP_FILE=\"$(SMB_GROUP_FILE)\" \
+ -DSMB_ALIAS_FILE=\"$(SMB_ALIAS_FILE)\"
+
+FLAGS1 = $(CFLAGS) \
+ -Iinclude -I$(srcdir)/include \
+ -I$(srcdir)/ubiqx \
+ -I$(srcdir)/smbwrapper \
+ $(CPPFLAGS) \
+ -DLOGFILEBASE=\"$(LOGFILEBASE)\" \
+ -DSMBLOGFILE=\"$(SMBLOGFILE)\" \
+ -DNMBLOGFILE=\"$(NMBLOGFILE)\"
+
FLAGS2 = -DCONFIGFILE=\"$(CONFIGFILE)\" -DLMHOSTSFILE=\"$(LMHOSTSFILE)\"
FLAGS3 = -DSWATDIR=\"$(SWATDIR)\" -DSBINDIR=\"$(SBINDIR)\" -DLOCKDIR=\"$(LOCKDIR)\" -DSMBRUN=\"$(SMBRUN)\" -DCODEPAGEDIR=\"$(CODEPAGEDIR)\"
FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\" -DFORMSFILE=\"$(FORMSFILE)\" -DNTDRIVERSDIR=\"$(NTDRIVERSDIR)\"
FLAGS5 = $(FLAGS1) $(FLAGS2) $(FLAGS3) $(FLAGS4) -DHAVE_INCLUDES_H
-FLAGS = $(ISA) $(FLAGS5) $(PASSWD_FLAGS)
-FLAGS32 = $(ISA32) $(FLAGS5) $(PASSWD_FLAGS)
+FLAGS = $(FLAGS5) $(PASSWD_FLAGS)
-SPROGS = bin/smbd bin/nmbd bin/swat
-PROGS1 = bin/smbclient bin/smbspool bin/testparm bin/testprns bin/smbstatus @RUNPROG@
-PROGS2 = bin/rpcclient bin/smbpasswd bin/make_smbcodepage bin/make_unicodemap @WRAP@ @WRAP32@
-MPROGS = @MPROGS@
-PROGS = $(PROGS1) $(PROGS2) $(MPROGS) bin/nmblookup bin/make_printerdef
+SPROGS = bin/smbd bin/lsarpcd bin/svcctld bin/spoolssd bin/samrd \
+ bin/srvsvcd bin/wkssvcd bin/browserd bin/netlogond bin/winregd \
+ bin/nmbd bin/swat
+PROGS1 = bin/smbclient bin/testparm bin/testprns bin/smbrun bin/smbstatus
+PROGS2 = bin/rpcclient bin/smbpasswd bin/make_smbcodepage bin/debug2html
+PROGS3 = bin/regedit bin/samedit bin/svccontrol bin/cmdat bin/spoolss
+PROGS4 = @WRAP@ @WRAP32@
+#MPROGS = @MPROGS@
+PROGS = $(PROGS1) $(PROGS2) $(PROGS3) $(PROGS4) $(MPROGS) bin/nmblookup bin/make_printerdef
-SCRIPTS = $(srcdir)/script/smbtar $(srcdir)/script/addtosmbpass $(srcdir)/script/convert_smbpasswd
+SCRIPTS = script/smbtar script/addtosmbpass script/convert_smbpasswd
QUOTAOBJS=@QUOTAOBJS@
@@ -92,78 +123,301 @@ QUOTAOBJS=@QUOTAOBJS@
# object file lists
######################################################################
-LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
- lib/getsmbpass.o lib/interface.o lib/kanji.o lib/md4.o \
- lib/interfaces.o lib/pidfile.o lib/replace.o \
- lib/signal.o lib/slprintf.o lib/system.o lib/doscalls.o lib/time.o \
- lib/ufc.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \
- lib/bitmap.o lib/crc32.o lib/snprintf.o \
- lib/util_array.o lib/util_str.o lib/util_sid.o \
- lib/util_unistr.o lib/util_file.o \
- lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o lib/fnmatch.o \
- tdb/tdb.o lib/talloc.o lib/hash.o
+SAMBALIB = bin/libsamba.la
+UBIQXLIB = bin/libubiqx.la
+SMBLIB = bin/libsmb.la
+NMBLIB = bin/libnmb.la
+MSRPCLIB = bin/libmsrpc.la
+SMBPWLIB = bin/libsmbpw.la
+SAMRPASSLIB = bin/libsamrpass.la
+SAMRTDBLIB = bin/libsamrtdb.la
+SAMRNT5LDAPLIB = bin/libsamrnt5ldap.la
+LIBSURS = bin/libsurs.la
+
+SAM_PWDB_LIB = @SAM_PWDB_LIB@
+
+SAMBA_LIBS = $(MSRPCLIB) $(SMBLIB) $(NMBLIB) $(SAMBALIB)
+
+SHARED_LIBS = $(SAMBA_LIBS) $(SMBPWLIB) $(UBIQXLIB) \
+ $(SAM_PWDB_LIB) $(LIBSURS)
+
+LIBSTATUS_OBJ = lib/util_status.o
+
+LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
+ lib/getsmbpass.o lib/interface.o lib/kanji.o \
+ lib/md4.o \
+ lib/netmask.o lib/pidfile.o lib/replace.o \
+ lib/signal.o lib/slprintf.o lib/system.o lib/doscalls.o \
+ lib/time.o lib/ufc.o lib/util.o lib/genrand.o \
+ lib/username.o \
+ lib/access.o lib/smbrun.o \
+ lib/bitmap.o lib/util_sid.o lib/snprintf.o \
+ lib/util_str.o lib/util_unistr.o \
+ lib/util_file.o \
+ lib/util_sock.o lib/util_sec.o lib/util_array.o \
+ lib/vagent.o \
+ tdb/tdb.o
+
+STUB_UID_OBJ = lib/stub_uid.o
UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
- ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o ubiqx/debugparse.o
+ ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o
PARAM_OBJ = param/loadparm.o param/params.o
-LIBSMB_OBJ = libsmb/clientgen.o libsmb/namequery.o libsmb/nmblib.o \
+LIBSAMBA_OBJ = $(PARAM_OBJ) $(LIB_OBJ)
+
+LIBNMB_OBJ = libsmb/namequery.o libsmb/nmblib.o
+
+LIBSMB_OBJ = libsmb/clientgen.o \
libsmb/nterr.o libsmb/smbdes.o libsmb/smbencrypt.o \
- libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \
- libsmb/passchange.o libsmb/unexpected.o
-
-RPC_SERVER_OBJ = rpc_server/srv_lsa.o \
- rpc_server/srv_lsa_hnd.o rpc_server/srv_netlog.o \
- rpc_server/srv_pipe_hnd.o rpc_server/srv_reg.o \
- rpc_server/srv_samr.o rpc_server/srv_srvsvc.o \
- rpc_server/srv_util.o rpc_server/srv_wkssvc.o \
- rpc_server/srv_pipe_srv.o rpc_server/srv_pipe.o \
- rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o
-
-RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_misc.o \
- rpc_parse/parse_net.o rpc_parse/parse_prs.o \
- rpc_parse/parse_reg.o rpc_parse/parse_rpc.o \
- rpc_parse/parse_samr.o rpc_parse/parse_srv.o \
- rpc_parse/parse_wks.o rpc_parse/parse_sec.o \
- rpc_parse/parse_spoolss.o
+ libsmb/smberr.o libsmb/credentials.o \
+ libsmb/pwd_cache.o \
+ lib/crc32.o lib/md5.o lib/hmacmd5.o \
+ lib/util_hnd.o \
+ rpc_parse/parse_creds.o \
+ rpc_parse/parse_net.o \
+ rpc_parse/parse_ntlmssp.o rpc_parse/parse_prs.o \
+ rpc_parse/parse_vuid.o \
+ lib/vuser.o lib/vuser_db.o \
+ rpc_parse/parse_misc.o
+
+RPC_SRVUTIL_OBJ = rpc_server/srv_pipe_srv.o \
+ rpc_server/srv_pipe_noauth.o
+
+RPC_SERVER_OBJ = \
+ rpc_server/srv_pipe_hnd.o \
+ rpc_server/srv_pipe.o
+
+RPC_PARSE_OBJ1 = rpc_parse/parse_lsa.o \
+ rpc_parse/parse_reg.o \
+ rpc_parse/parse_samr.o \
+ rpc_parse/parse_srv.o \
+ rpc_parse/parse_wks.o \
+ rpc_parse/parse_svc.o \
+ rpc_parse/parse_at.o \
+ rpc_parse/parse_spoolss.o \
+ rpc_parse/parse_eventlog.o \
+ rpc_parse/parse_brs.o
+
+RPC_PARSE_OBJ2 = rpc_parse/parse_rpc.o \
+ rpc_parse/parse_netsec.o \
+ rpc_parse/parse_sec.o \
+ lib/msrpc-client.o
+
+# lib/msrpc_use.o
+# lib/msrpc-agent.o
+
+RPC_PARSE_OBJ = $(RPC_PARSE_OBJ1) $(RPC_PARSE_OBJ2)
RPC_CLIENT_OBJ = \
rpc_client/cli_login.o \
rpc_client/cli_netlogon.o \
+ rpc_client/cli_reg.o \
rpc_client/cli_pipe.o \
+ rpc_client/cli_pipe_ntlmssp.o \
+ rpc_client/cli_pipe_netsec.o \
+ rpc_client/cli_pipe_noauth.o \
+ rpc_client/cli_connect.o \
+ rpc_client/cli_use.o \
+ rpc_client/ncalrpc_l_use.o \
+ rpc_client/ncacn_np_use.o \
+ rpc_client/cli_spoolss.o \
rpc_client/cli_lsarpc.o \
rpc_client/cli_wkssvc.o \
+ rpc_client/cli_brs.o \
rpc_client/cli_srvsvc.o \
- rpc_client/cli_reg.o \
- rpc_client/cli_samr.o
+ rpc_client/cli_svcctl.o \
+ rpc_client/cli_samr.o \
+ rpc_client/msrpc_samr.o \
+ rpc_client/msrpc_netlogon.o \
+ rpc_client/msrpc_lsarpc.o \
+ rpc_client/cli_atsvc.o \
+ rpc_client/cli_eventlog.o
+LOCKING_OBJ = locking/locking.o
-LOCKING_OBJ = locking/locking.o locking/brlock.o
+GROUPDB_OBJ = groupdb/groupdb.o groupdb/aliasdb.o groupdb/builtindb.o \
+ groupdb/groupfile.o groupdb/aliasfile.o \
+ groupdb/groupunix.o groupdb/aliasunix.o groupdb/builtinunix.o \
+ groupdb/groupldap.o groupdb/aliasldap.o groupdb/builtinldap.o \
+ groupdb/groupnt5ldap.o groupdb/aliasnt5ldap.o groupdb/builtinnt5ldap.o \
+ passdb/passgrp.o passdb/smbpassgroup.o \
+ passdb/smbpassgroupunix.o passdb/passgrpldap.o passdb/passgrpnt5ldap.o
-PASSDB_OBJ = passdb/passdb.o passdb/smbpassfile.o passdb/smbpass.o \
- passdb/pass_check.o passdb/ldap.o passdb/nispass.o passdb/smbpasschange.o
+SAMPASSDB_OBJ = passdb/sampassdb.o passdb/sampass.o passdb/sampassldap.o passdb/mysqlsampass.o passdb/sampassnt5ldap.o
+
+UNIXPASSDB_OBJ = passdb/pass_check.o
+
+PASSDB_OBJ = passdb/passdb.o passdb/smbpass.o \
+ passdb/ldap.o passdb/ldapdb.o passdb/nt5ldap.o passdb/nispass.o \
+ passdb/smbpasschange.o passdb/mysqlpass.o passdb/smbpassnt5ldap.o \
+ lib/util_pwdb.o lib/domain_namemap.o
+
+SIDDB_OBJ = lib/sids.o lib/util_seaccess.o
PROFILE_OBJ = profile/profile.o
-SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
+SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/connection.o \
+ lib/set_uid.o \
smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o smbd/fileio.o \
- smbd/ipc.o smbd/mangle.o smbd/negprot.o \
+ smbd/ipc.o smbd/lanman.o smbd/mangle.o smbd/negprot.o \
smbd/message.o smbd/nttrans.o smbd/pipes.o smbd/predict.o \
- smbd/$(QUOTAOBJS) smbd/reply.o smbd/trans2.o smbd/uid.o \
+ smbd/$(QUOTAOBJS) smbd/reply.o smbd/ssl.o smbd/trans2.o \
+ smbd/uid.o \
smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o smbd/blocking.o \
- smbd/vfs.o smbd/vfs-wrap.o \
- lib/msrpc-client.o lib/msrpc_use.o \
- rpc_parse/parse_creds.o \
- smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o printing/nt_printing.o
+ smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o smbd/vfs.o \
+ smbd/vfs-wrap.o smbd/dfs.o \
+ smbd/challenge.o \
+ lib/util_pwdb.o
+
+PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o
+
+MSRPCD_OBJ = msrpc/msrpcd.o \
+ msrpc/msrpcd_process.o \
+ lib/set_vuid.o \
+ lib/set_uid.o
+
+BROWSERD_OBJ1 = browserd/browserd.o \
+ rpc_server/srv_brs.o
+
+WKSSVCD_OBJ1 = wkssvcd/wkssvcd.o \
+ rpc_server/srv_wkssvc.o \
+ wkssvcd/srv_wkssvc_nt.o
+
+SRVSVCD_OBJ1 = srvsvcd/srvsvcd.o \
+ srvsvcd/srv_srvsvc_nt.o \
+ rpc_server/srv_srvsvc.o
+
+WINREGD_OBJ1 = winregd/winregd.o \
+ winregd/srv_reg_nt.o \
+ rpc_server/srv_reg.o
+
+NETLOGOND_OBJ1 = netlogond/netlogond.o \
+ netlogond/creds_db.o \
+ netlogond/srv_netlogon_nt.o \
+ rpc_server/srv_netlog.o \
+ rpc_server/srv_pipe_netsec.o \
+ lib/passcheck.o
+
+SAMRTDBLIB_OBJ = lib/util_pwdb.o lib/domain_namemap.o \
+ samrd/srv_samr_tdb_init.o \
+ samrd/srv_samr_dom_tdb.o \
+ samrd/srv_samr_sam_tdb.o \
+ samrd/srv_samr_usr_tdb.o \
+ samrd/srv_samr_grp_tdb.o \
+ samrd/srv_samr_als_tdb.o \
+ samrd/srv_samr_tdb.o
+
+SAMRNT5LDAPLIB_OBJ = lib/util_pwdb.o lib/domain_namemap.o \
+ samrd/srv_samr_usr_nt5ldap.o \
+ samrd/srv_samr_dom_nt5ldap.o \
+ samrd/srv_samr_nt5ldap.o
+# samrd/srv_samr_sam_nt5ldap.o \
+# samrd/srv_samr_grp_nt5ldap.o \
+# samrd/srv_samr_als_nt5ldap.o \
+
+SAMRPASSLIB_OBJ = rpc_server/srv_lookup.o \
+ samrd/srv_samr_passdb.o \
+ smbd/chgpasswd.o
+
+SAMRD_OBJ1 = samrd/samrd.o \
+ rpc_server/srv_pipe_ntlmssp.o \
+ rpc_server/srv_samr.o
+
+SVCCTLD_OBJ1 = svcctld/svcctld.o \
+ svcctld/srv_svcctl_nt.o \
+ rpc_server/srv_svcctl.o
+
+LSARPCD_OBJ1 = lsarpcd/lsarpcd.o \
+ lsarpcd/srv_lsa.o \
+ lsarpcd/secret_db.o \
+ lsarpcd/srv_lsa_samdb.o
+
+SPOOLSSD_OBJ1 = spoolssd/spoolssd.o \
+ rpc_server/srv_spoolss.o \
+ spoolssd/srv_spoolss_nt.o \
+ printing/nt_printing.o
+
+SMBD_OBJ = $(SMBD_OBJ1) $(UNIXPASSDB_OBJ) \
+ $(RPC_SERVER_OBJ) \
+ lib/domain_namemap.o \
+ $(LOCKING_OBJ) \
+ $(SIDDB_OBJ) \
+ $(LIBSTATUS_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ)
+
+SMBD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB) $(LIBSURS)
+
+SRVSVCD_OBJ = $(MSRPCD_OBJ) $(SRVSVCD_OBJ1) \
+ $(RPC_SRVUTIL_OBJ) \
+ $(LOCKING_OBJ) $(PROFILE_OBJ) \
+ $(SIDDB_OBJ) \
+ $(LIBSTATUS_OBJ)
+
+WKSSVCD_OBJ = $(MSRPCD_OBJ) $(WKSSVCD_OBJ1) \
+ $(RPC_SRVUTIL_OBJ) \
+ $(SIDDB_OBJ) \
+ $(LOCKING_OBJ) $(PROFILE_OBJ)
+
+BROWSERD_OBJ = $(MSRPCD_OBJ) $(BROWSERD_OBJ1) \
+ $(RPC_SRVUTIL_OBJ) \
+ $(SIDDB_OBJ) \
+ $(LOCKING_OBJ) $(PROFILE_OBJ)
+
+WINREGD_OBJ = $(MSRPCD_OBJ) $(WINREGD_OBJ1) \
+ $(RPC_SRVUTIL_OBJ) \
+ $(SIDDB_OBJ) \
+ $(LOCKING_OBJ) $(PROFILE_OBJ)
+
+SVCCTLD_OBJ = $(MSRPCD_OBJ) $(SVCCTLD_OBJ1) \
+ $(RPC_SRVUTIL_OBJ) \
+ $(SIDDB_OBJ) \
+ $(LOCKING_OBJ) $(PROFILE_OBJ)
+
+LSARPCD_OBJ = $(MSRPCD_OBJ) $(LSARPCD_OBJ1) \
+ $(RPC_SRVUTIL_OBJ) \
+ $(SIDDB_OBJ) $(LOCKING_OBJ) \
+ $(PROFILE_OBJ)
+LSARPCD_LIBS = $(SAMBA_LIBS)
+
+SPOOLSSD_OBJ = $(MSRPCD_OBJ) $(SPOOLSSD_OBJ1) \
+ $(PRINTING_OBJ) \
+ $(SIDDB_OBJ) \
+ $(RPC_SRVUTIL_OBJ) \
+ $(LOCKING_OBJ) $(PROFILE_OBJ)
+
+NETLOGOND_OBJ = $(MSRPCD_OBJ) $(NETLOGOND_OBJ1) \
+ $(RPC_SRVUTIL_OBJ) \
+ $(LOCKING_OBJ) \
+ $(SIDDB_OBJ) \
+ $(UNIXPASSDB_OBJ) $(LIBSTATUS_OBJ) $(PROFILE_OBJ)
+
+NETLOGOND_LIBS = $(SAMBA_LIBS) $(UBIQXLIB) $(SAM_PWDB_LIB) $(LIBSURS)
+
+NETLOGONPASSD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB) $(SAMRPASSLIB) $(SMBPWLIB) \
+ $(LIBSURS)
+
+NETLOGONTDBD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB) $(SAMRTDBLIB) $(LIBSURS)
+
+NETLOGONNT5LDAPD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB) $(SAMRNT5LDAPLIB) $(LIBSURS)
+
+SAMRD_OBJ = $(MSRPCD_OBJ) $(SAMRD_OBJ1) \
+ $(RPC_SRVUTIL_OBJ) \
+ $(LOCKING_OBJ) \
+ $(SIDDB_OBJ) \
+ $(PROFILE_OBJ)
+
+LIBSURS_OBJ = lib/surs.o lib/sursalgdomonly.o \
+ lib/sursalgnt5ldap.o \
+ lib/surstdb.o
+
+SAMRD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB) $(SAM_PWDB_LIB) $(LIBSURS)
-PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o \
- printing/print_cups.o
+SAMRPASSD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB) $(SAMRPASSLIB) $(SMBPWLIB)
-SMBD_OBJ = $(SMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
- $(RPC_SERVER_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) \
- $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
+SAMRTDBD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB) $(SAMRTDBLIB)
+SAMRNT5LDAPD_LIBS = $(SAMBA_LIBS) $(UBIQXLIB) $(SAMRNT5LDAPLIB)
NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_become_lmb.o nmbd/nmbd_browserdb.o \
@@ -178,103 +432,271 @@ NMBD_OBJ1 = nmbd/asyncdns.o nmbd/nmbd.o nmbd/nmbd_become_dmb.o \
nmbd/nmbd_subnetdb.o nmbd/nmbd_winsproxy.o nmbd/nmbd_winsserver.o \
nmbd/nmbd_workgroupdb.o nmbd/nmbd_synclists.o
-NMBD_OBJ = $(NMBD_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) \
- $(LIB_OBJ)
+NMBD_OBJ = $(NMBD_OBJ1)
+NMBD_LIBS = $(SMBLIB) $(NMBLIB) $(SAMBALIB) $(UBIQXLIB)
SWAT_OBJ = web/cgi.o web/diagnose.o web/startstop.o web/statuspage.o \
- web/swat.o $(LIBSMB_OBJ) $(LOCKING_OBJ) \
- $(PARAM_OBJ) $(PASSDB_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) \
- $(UBIQX_OBJ) $(LIB_OBJ) $(PRINTING_OBJ)
+ web/swat.o libsmb/passchange.o $(LOCKING_OBJ) \
+ rpc_server/srv_lookup.o \
+ $(SIDDB_OBJ) \
+ $(UNIXPASSDB_OBJ) \
+ $(STUB_UID_OBJ)
+
+SWAT_LIBS = $(SAMBA_LIBS) $(SMBPWLIB) $(UBIQXLIB) $(LIBSURS)
+
+SMBRUN_OBJ = utils/smbrun.o
+
+SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o
+
+MAKE_SMBCODEPAGE_OBJ = utils/make_smbcodepage.o
+
+MAKE_PRINTERDEF_OBJ = utils/make_printerdef.o
+
+STATUS_OBJ = utils/status.o $(LIBSTATUS_OBJ) $(LOCKING_OBJ) \
+ $(PROFILE_OBJ) $(STUB_UID_OBJ)
+
+TESTPARM_OBJ = utils/testparm.o
+
+TESTPRNS_OBJ = utils/testprns.o printing/pcap.o printing/print_svid.o
+
+SMBPASSWD_OBJ = utils/smbpasswd.o libsmb/passchange.o \
+ rpc_server/srv_lookup.o \
+ rpc_client/cli_netlogon_sync.o \
+ $(SIDDB_OBJ) $(STUB_UID_OBJ)
+
+SMBPASSWD_LIBS = $(SAMBA_LIBS) $(SMBPWLIB) $(UBIQXLIB) $(LIBSURS)
+
+REGEDIT_OBJ = lib/cmd_interp.o \
+ rpcclient/regedit.o \
+ rpcclient/regedit_cmds.o \
+ rpcclient/display_reg.o \
+ rpcclient/display_sec.o \
+ rpcclient/cmd_reg.o \
+ $(STUB_UID_OBJ)
+REGEDIT_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
+
+SVCCLIENT_OBJ = lib/cmd_interp.o \
+ rpcclient/svcctrl.o \
+ rpcclient/svcctrl_cmds.o \
+ rpcclient/display_svc.o \
+ rpcclient/cmd_svcctl.o \
+ $(SIDDB_OBJ) \
+ $(STUB_UID_OBJ)
+SVCCLIENT_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
+
+SAMCLIENT_OBJ = lib/cmd_interp.o \
+ rpcclient/samedit.o \
+ rpcclient/samedit_cmds.o \
+ rpcclient/netlogon_cmds.o \
+ rpcclient/display_sam.o \
+ rpcclient/display_sec.o \
+ rpcclient/display_sync.o \
+ rpcclient/cmd_samr.o \
+ rpcclient/cmd_netlogon.o \
+ $(SIDDB_OBJ) \
+ $(STUB_UID_OBJ)
+SAMCLIENT_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
+
+CMDCLIENT_OBJ = lib/cmd_interp.o \
+ rpcclient/cmdat.o \
+ rpcclient/cmdat_cmds.o \
+ rpcclient/display_at.o \
+ rpcclient/cmd_atsvc.o \
+ $(SIDDB_OBJ) \
+ $(STUB_UID_OBJ)
+CMDCLIENT_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
+
+NETCLIENT_OBJ = lib/cmd_interp.o \
+ rpcclient/net.o \
+ rpcclient/net_cmds.o \
+ rpcclient/display_srv.o \
+ rpcclient/cmd_wkssvc.o \
+ rpcclient/cmd_brs.o \
+ rpcclient/cmd_srvsvc.o \
+ $(SIDDB_OBJ) \
+ $(STUB_UID_OBJ)
+NETCLIENT_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
+
+EVTCLIENT_OBJ = lib/cmd_interp.o \
+ rpcclient/eventlog.o \
+ rpcclient/eventlog_cmds.o \
+ rpcclient/display_event.o \
+ rpcclient/cmd_eventlog.o \
+ $(SIDDB_OBJ) \
+ $(STUB_UID_OBJ)
+EVTCLIENT_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
+
+LSACLIENT_OBJ = lib/cmd_interp.o \
+ rpcclient/lsa.o \
+ rpcclient/lsa_cmds.o \
+ rpcclient/cmd_lsarpc.o \
+ $(SIDDB_OBJ) \
+ $(STUB_UID_OBJ)
+LSACLIENT_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
+
+RPCTORTURE_OBJ = lib/cmd_interp.o \
+ utils/rpctorture.o \
+ rpcclient/net_cmds.o \
+ rpcclient/display_event.o \
+ rpcclient/display_srv.o \
+ rpcclient/display_sync.o \
+ rpcclient/cmd_wkssvc.o \
+ rpcclient/cmd_brs.o \
+ rpcclient/cmd_srvsvc.o \
+ rpcclient/cmd_netlogon.o \
+ $(SIDDB_OBJ) \
+ $(STUB_UID_OBJ)
+RPCTORTURE_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
+
+SPOOLCLIENT_OBJ = lib/cmd_interp.o \
+ rpcclient/spoolss.o \
+ rpcclient/spoolss_cmds.o \
+ rpcclient/display_spool.o \
+ rpcclient/cmd_spoolss.o \
+ $(SIDDB_OBJ) \
+ $(STUB_UID_OBJ)
+SPOOLCLIENT_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
+
+RPCCLIENT_OBJ = lib/cmd_interp.o \
+ rpcclient/rpcclient.o \
+ rpcclient/svcctrl_cmds.o \
+ rpcclient/samedit_cmds.o \
+ rpcclient/regedit_cmds.o \
+ rpcclient/lsa_cmds.o \
+ rpcclient/net_cmds.o \
+ rpcclient/eventlog_cmds.o \
+ rpcclient/netlogon_cmds.o \
+ rpcclient/cmdat_cmds.o \
+ rpcclient/spoolss_cmds.o \
+ rpcclient/display_at.o \
+ rpcclient/display_event.o \
+ rpcclient/display_reg.o \
+ rpcclient/display_sam.o \
+ rpcclient/display_sec.o \
+ rpcclient/display_spool.o \
+ rpcclient/display_srv.o \
+ rpcclient/display_svc.o \
+ rpcclient/display_sync.o \
+ rpcclient/cmd_lsarpc.o \
+ rpcclient/cmd_wkssvc.o \
+ rpcclient/cmd_brs.o \
+ rpcclient/cmd_samr.o \
+ rpcclient/cmd_reg.o \
+ rpcclient/cmd_srvsvc.o \
+ rpcclient/cmd_svcctl.o \
+ rpcclient/cmd_netlogon.o \
+ rpcclient/cmd_atsvc.o \
+ rpcclient/cmd_spoolss.o \
+ rpcclient/cmd_eventlog.o \
+ $(SIDDB_OBJ) \
+ $(STUB_UID_OBJ)
+RPCCLIENT_LIBS = $(SAMBA_LIBS) $(UBIQXLIB)
-SMBRUN_OBJ = utils/smbrun.o lib/util_sec.o
+SMBWRAPPER_OBJ = smbwrapper/smbw.o smbwrapper/wrapped.o \
+ smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \
+ smbwrapper/realcalls.o smbwrapper/shared.o
-SMBSH_OBJ = smbwrapper/smbsh.o smbwrapper/shared.o \
- $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
+CLIENT_OBJ = client/client.o client/clitar.o
+CLIENT_LIBS = $(SMBLIB) $(NMBLIB) $(SAMBALIB)
-MAKE_SMBCODEPAGE_OBJ = utils/make_smbcodepage.o $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_OBJ)
+MOUNT_OBJ = client/smbmount.o client/clientutil.o \
+ $(RPC_PARSE_OBJ2)
-MAKE_UNICODEMAP_OBJ = utils/make_unicodemap.o $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_OBJ)
+MNT_OBJ = client/smbmnt.o \
+ $(RPC_PARSE_OBJ2)
-MAKE_PRINTERDEF_OBJ = utils/make_printerdef.o $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_OBJ)
+UMOUNT_OBJ = client/smbumount.o \
+ $(RPC_PARSE_OBJ2)
-STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
+NMB_AGENT_OBJ = utils/nmb-agent.o \
+ $(RPC_PARSE_OBJ2)
-TESTPARM_OBJ = utils/testparm.o \
- $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
+NMBLOOKUP_OBJ = utils/nmblookup.o
-TESTPRNS_OBJ = utils/testprns.o $(PARAM_OBJ) $(PRINTING_OBJ) $(UBIQX_OBJ) \
- $(LIB_OBJ)
+#$(RPC_PARSE_OBJ2)
-SMBPASSWD_OBJ = utils/smbpasswd.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(PASSDB_OBJ) \
- $(UBIQX_OBJ) $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(LIB_OBJ)
+DEBUG2HTML_OBJ = utils/debug2html.o
-RPCCLIENT_OBJ = rpcclient/rpcclient.o \
- rpcclient/display.o \
- rpcclient/cmd_lsarpc.o \
- rpcclient/cmd_wkssvc.o \
- rpcclient/cmd_samr.o \
- rpcclient/cmd_reg.o \
- rpcclient/cmd_srvsvc.o \
- rpcclient/cmd_netlogon.o \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
- $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ)
+SMB_AGENT_OBJ = utils/smb-agent.o \
+ $(RPC_PARSE_OBJ2) rpc_client/cli_use.o
-SMBWRAPPER_OBJ = smbwrapper/smbw.o smbwrapper/wrapped.o \
- smbwrapper/smbw_dir.o smbwrapper/smbw_stat.o \
- smbwrapper/realcalls.o smbwrapper/shared.o \
- $(LIBSMB_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_OBJ)
+SMB_CLIENT_OBJ = smb-client.o
-CLIENT_OBJ = client/client.o client/clitar.o \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
+SMBTORTURE_OBJ = utils/torture.o
-CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
+SMBFILTER_OBJ = utils/smbfilter.o \
+ rpc_parse/parse_creds.o \
+ rpc_parse/parse_ntlmssp.o rpc_parse/parse_prs.o \
+ rpc_parse/parse_misc.o
-MOUNT_OBJ = client/smbmount.o \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
+PROTO_OBJ = $(LIB_OBJ) $(LIBNMB_OBJ) $(PARAM_OBJ) \
+ $(MSRPCD_OBJ) $(SVCCTLD_OBJ1) $(WINREGD_OBJ1) \
+ $(SAMRD_OBJ1) \
+ $(SAMRTDBLIB_OBJ) \
+ $(SAMRNT5LDAPLIB_OBJ) \
+ $(LIBSURS_OBJ) \
+ $(SAMRPASSLIB_OBJ) \
+ $(SAMRTDBD_OBJ1) \
+ $(SAMRNT5LDAPD_OBJ1) \
+ $(SRVSVCD_OBJ1) $(WKSSVCD_OBJ1) $(BROWSERD_OBJ1) \
+ $(SPOOLSSD_OBJ1) $(NETLOGOND_OBJ1) \
+ $(LSARPCD_OBJ1) $(SMBD_OBJ) $(NMBD_OBJ) \
+ $(SWAT_OBJ) $(CLIENT_OBJ) \
+ $(REGEDIT_OBJ) $(SVCCLIENT_OBJ) \
+ $(SAMCLIENT_OBJ) $(RPCCLIENT_OBJ) \
+ $(RPCTORTURE_OBJ) $(SPOOLCLIENT_OBJ) \
+ $(CMDCLIENT_OBJ) $(LSACLIENT_OBJ) \
+ $(EVTCLIENT_OBJ) $(NETCLIENT_OBJ) \
+ $(LIBSMB_OBJ) $(SMBWRAPPER_OBJ) \
+ $(GROUPDB_OBJ) $(PASSDB_OBJ) $(SAMPASSDB_OBJ) \
+ $(SMBPASSWD_OBJ) $(SIDDB_OBJ) \
+ $(RPC_SRVUTIL_OBJ) \
+ $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ2)
-MNT_OBJ = client/smbmnt.o \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
+SMBWRAPPERPICOBJS = $(SMBWRAPPER_OBJ:.o=.po)
+SMBWRAPPERPICOBJS32 = $(SMBWRAPPER_OBJ:.o=.po32)
-UMOUNT_OBJ = client/smbumount.o \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
+LIBSURS_LTOBJS = $(LIBSURS_OBJ:.o=.lo)
-NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) \
- $(LIBSMB_OBJ) $(LIB_OBJ)
+LIBSAMRTDB_LTOBJS = $(SAMRTDBLIB_OBJ:.o=.lo)
-SMBTORTURE_OBJ = utils/torture.o utils/nbio.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_OBJ)
+LIBSAMRPASS_LTOBJS = $(SAMRPASSLIB_OBJ:.o=.lo)
-MASKTEST_OBJ = utils/masktest.o smbd/mangle.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_OBJ)
+LIBSAMRNT5LDAP_LTOBJS = $(SAMRNT5LDAPLIB_OBJ:.o=.lo)
-RPCTORTURE_OBJ = utils/rpctorture.o \
- rpcclient/display.o \
- rpcclient/cmd_lsarpc.o \
- rpcclient/cmd_wkssvc.o \
- rpcclient/cmd_samr.o \
- rpcclient/cmd_srvsvc.o \
- rpcclient/cmd_netlogon.o \
- $(PARAM_OBJ) $(LIBSMB_OBJ) $(UBIQX_OBJ) $(LIB_OBJ) \
- $(RPC_CLIENT_OBJ) $(RPC_PARSE_OBJ) $(PASSDB_OBJ)
+LIBSMBPW_LTOBJS = $(GROUPDB_OBJ:.o=.lo) $(SAMPASSDB_OBJ:.o=.lo) \
+ $(PASSDB_OBJ:.o=.lo)
-DEBUG2HTML_OBJ = utils/debug2html.o ubiqx/debugparse.o
+LIBUBIQX_LTOBJS = $(UBIQX_OBJ:.o=.lo)
-SMBFILTER_OBJ = utils/smbfilter.o $(LIBSMB_OBJ) $(PARAM_OBJ) \
- $(UBIQX_OBJ) $(LIB_OBJ)
+LIBSAMBA_LTOBJS = $(LIBSAMBA_OBJ:.o=.lo)
-PROTO_OBJ = $(SMBD_OBJ) $(NMBD_OBJ) $(SWAT_OBJ) $(CLIENT_OBJ) \
- $(RPCCLIENT_OBJ) $(SMBWRAPPER_OBJ) $(SMBTORTURE_OBJ)
+LIBNMB_LTOBJS = $(LIBNMB_OBJ:.o=.lo)
-NSS_OBJ_0 = nsswitch/wins.o $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) $(LIB_OBJ) $(NSSWINS_OBJ)
-NSS_OBJ = $(NSS_OBJ_0:.o=.po)
+LIBSMB_LTOBJS = $(LIBSMB_OBJ:.o=.lo)
-PICOBJS = $(SMBWRAPPER_OBJ:.o=.po)
-PICOBJS32 = $(SMBWRAPPER_OBJ:.o=.po32)
+LIBMSRPC_LTOBJS = $(RPC_CLIENT_OBJ:.o=.lo) $(RPC_PARSE_OBJ:.o=.lo)
+
+WINBINDD_OBJ = nsswitch/winbindd.o nsswitch/winbindd_user.o \
+nsswitch/winbindd_group.o nsswitch/winbindd_surs.o \
+rpc_client/cli_lsarpc.o rpc_parse/parse_lsa.o \
+rpc_client/cli_connect.o rpc_client/cli_use.o rpc_client/cli_samr.o \
+rpc_parse/parse_samr.o rpc_client/cli_pipe.o rpc_parse/parse_rpc.o \
+lib/msrpc-client.o rpc_client/cli_pipe_noauth.o $(STUB_UID_OBJ) \
+rpc_client/cli_netlogon.o rpc_client/msrpc_samr.o \
+rpc_client/cli_pipe_ntlmssp.o lib/msrpc_use.o \
+rpc_parse/parse_sec.o lib/set_vuid.o \
+rpc_client/ncalrpc_l_use.o rpc_client/ncacn_np_use.o \
+$(LIBNMB_OBJ) $(PARAM_OBJ) $(UBIQX_OBJ) $(LIBSMB_OBJ) $(LIB_OBJ) \
+$(NSSWINS_OBJ) $(SIDDB_OBJ) $(LIBSURS_OBJ)
+
+#msrpc/msrpcd.o browserd/browserd.o \
+#locking/locking.o msrpc/msrpcd_process.o rpc_server/srv_brs.o \
+#rpc_server/srv_pipe_srv.o rpc_parse/parse_brs.o rpc_server/srv_pipe_noauth.o \
+
+NSS_OBJ_O = nsswitch/ntdom.o
+
+NSS_OBJ = $(NSS_OBJ_O:.o=.po)
######################################################################
# now the rules...
@@ -282,24 +704,41 @@ PICOBJS32 = $(SMBWRAPPER_OBJ:.o=.po32)
all : CHECK $(SPROGS) $(PROGS)
-smbwrapper : CHECK bin/smbsh bin/smbwrapper.@SHLIBEXT@ @WRAP32@
+libsurs : CHECK $(LIBSURS)
-smbtorture : CHECK bin/smbtorture
+libsamrpass : CHECK $(SAMRPASSLIB)
-masktest : CHECK bin/masktest
+libsamrtdb : CHECK $(SAMRTDBLIB)
-rpctorture : CHECK bin/rpctorture
+libsamrnt5ldap : CHECK $(SAMRNT5LDAPLIB)
+
+libnmb : CHECK $(NMBLIB)
+
+libsmb : CHECK $(SMBLIB)
-debug2html : CHECK bin/debug2html
+libsmbpw : CHECK $(SMBPWLIB)
+
+libmsrpc : CHECK $(MSRPCLIB)
+
+libsamba : CHECK $(SAMBALIB)
+
+libubiqx : CHECK $(UBIQXLIB)
+
+smbwrapper : CHECK bin/smbsh bin/smbwrapper.so @WRAP32@
+
+smbtorture : CHECK bin/smbtorture
+
+rpctorture : CHECK bin/rpctorture
smbfilter : CHECK bin/smbfilter
+nsswitch: CHECK nsswitch/ntdom.so bin/winbindd
+
.SUFFIXES:
-.SUFFIXES: .c .o .po .po32
+.SUFFIXES: .c .o .lo .po .po32
CHECK:
@echo "Using FLAGS = $(FLAGS)"
- @echo "Using FLAGS32 = $(FLAGS32)"
@echo "Using LIBS = $(LIBS)"
MAKEDIR = || exec false; \
@@ -322,11 +761,25 @@ MAKEDIR = || exec false; \
@echo Compiling $*.c
@$(CC) -I. -I$(srcdir) $(FLAGS) -c $< \
-o $@ @MAINT@ -Wp,-MD,.deps/$@
-@BROKEN_CC@ -mv `echo $@ | sed 's%^.*/%%g'` $@
@MAINT@ @sed 's|^'`echo $@ | sed 's,.*/,,'`':|$@:|' \
@MAINT@ <.deps/$@ >.deps/$@d && \
@MAINT@ rm -f .deps/$@ && : >.deps/.stamp
+# This is for libtool
+.c.lo: @MAINT@ .deps/.dummy
+ @if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
+ dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
+@MAINT@ @if (: >> .deps/$@ || : > .deps/$@) >/dev/null 2>&1; then :; \
+@MAINT@ else dir=.deps/`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` \
+@MAINT@ $(MAKEDIR); fi; rm -f .deps/$@ .deps/$@d
+ @echo Compiling $< with libtool
+ @$(LIBTOOL) --mode=compile \
+ $(CC) -I. -I$(srcdir) $(FLAGS) -c $< \
+ -o $@ @MAINT@ -Wp,-MD,.deps/$@
+@MAINT@ @sed 's|^.*'`echo $* | sed 's,.*/,,'`'.*:|$@:|' \
+@MAINT@ <.deps/$@ >.deps/$@d && \
+@MAINT@ rm -f .deps/$@ && : >.deps/.stamp
+
.c.po: @MAINT@ .deps/.dummy
@if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
@@ -336,7 +789,6 @@ MAKEDIR = || exec false; \
@echo Compiling $*.c with @PICFLAG@
@$(CC) -I. -I$(srcdir) $(FLAGS) @PICFLAG@ -c $< \
-o $*.po.o @MAINT@ -Wp,-MD,.deps/$@
-@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po$$%.o%'` $@.o
@MAINT@ @sed 's|^'`echo $*\.po\.o | sed 's,.*/,,'`':|$@:|' \
@MAINT@ <.deps/$@ >.deps/$@d && \
@MAINT@ rm -f .deps/$@ && : >.deps/.stamp
@@ -350,9 +802,8 @@ MAKEDIR = || exec false; \
@MAINT@ else dir=.deps/`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` \
@MAINT@ $(MAKEDIR); fi; rm -f .deps/$@ .deps/$@d
@echo Compiling $*.c with @PICFLAG@ and -32
- @$(CC) -32 -I. -I$(srcdir) $(FLAGS32) @PICFLAG@ -c $< \
+ @$(CC) -32 -I. -I$(srcdir) $(FLAGS) @PICFLAG@ -c $< \
-o $*.po32.o @MAINT@ -Wp,-MD,.deps/$@
-@BROKEN_CC@ -mv `echo $@ | sed -e 's%^.*/%%g' -e 's%\.po32$$%.o%'` $@.o
@MAINT@ @sed 's|^'`echo $*.po32.o | sed 's,.*/,,'`':|$@:|' \
@MAINT@ <.deps/$@ >.deps/$@d && \
@MAINT@ rm -f .deps/$@ && : >.deps/.stamp
@@ -363,131 +814,290 @@ bin/.dummy:
dir=bin $(MAKEDIR); fi
@: >> $@ || : > $@ # what a fancy emoticon!
-bin/smbd: $(SMBD_OBJ) bin/.dummy
+bin/libsurs.la: $(LIBSURS_LTOBJS) bin/.dummy
+ @echo Linking shared library $@
+ @$(LINK) -o $@ -rpath $(LIBDIR) -version-info 0:1:0 \
+ $(LIBSURS_LTOBJS)
+
+bin/libmsrpc.la: $(LIBMSRPC_LTOBJS) bin/.dummy
+ @echo Linking shared library $@
+ @$(LINK) -o $@ -rpath $(LIBDIR) -version-info 0:1:0 \
+ $(LIBMSRPC_LTOBJS)
+
+bin/libnmb.la: $(LIBNMB_LTOBJS) bin/.dummy
+ @echo Linking shared library $@
+ @$(LINK) -o $@ -rpath $(LIBDIR) -version-info 0:1:0 \
+ $(LIBNMB_LTOBJS)
+
+bin/libsmbpw.la: $(LIBSMBPW_LTOBJS) bin/.dummy
+ @echo Linking shared library $@
+ @$(LINK) -o $@ -rpath $(LIBDIR) -version-info 0:1:0 \
+ $(LIBSMBPW_LTOBJS)
+
+bin/libsmb.la: $(LIBSMB_LTOBJS) bin/.dummy
+ @echo Linking shared library $@
+ @$(LINK) -o $@ -rpath $(LIBDIR) -version-info 0:1:0 \
+ $(LIBSMB_LTOBJS)
+
+bin/libubiqx.la: $(LIBUBIQX_LTOBJS) bin/.dummy
+ @echo Linking shared library $@
+ @$(LINK) -o $@ -rpath $(LIBDIR) -version-info 0:1:0 \
+ $(LIBUBIQX_LTOBJS)
+
+bin/libsamba.la: $(LIBSAMBA_LTOBJS) bin/.dummy
+ @echo Linking shared library $@
+ @$(LINK) -o $@ -rpath $(LIBDIR) -version-info 0:1:0 \
+ $(LIBSAMBA_LTOBJS)
+
+bin/libsamrpass.la: $(LIBSAMRPASS_LTOBJS) bin/.dummy
+ @echo Linking shared library $@
+ @$(LINK) -o $@ -rpath $(LIBDIR) -version-info 0:1:0 \
+ $(LIBSAMRPASS_LTOBJS)
+
+bin/libsamrnt5ldap.la: $(LIBSAMRNT5LDAP_LTOBJS) bin/.dummy
+ @echo Linking shared library $@
+ @$(LINK) -o $@ -rpath $(LIBDIR) -version-info 0:1:0 \
+ $(LIBSAMRNT5LDAP_LTOBJS)
+
+bin/libsamrtdb.la: $(LIBSAMRTDB_LTOBJS) bin/.dummy
+ @echo Linking shared library $@
+ @$(LINK) -o $@ -rpath $(LIBDIR) -version-info 0:1:0 \
+ $(LIBSAMRTDB_LTOBJS)
+
+bin/smbd: $(SMBD_LIBS) $(SMBD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(SMBD_OBJ) $(SMBD_LIBS) $(LIBS)
+
+bin/svcctld: $(SAMBA_LIBS) $(SVCCTLD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(SVCCTLD_OBJ) $(SAMBA_LIBS) $(LIBS)
+
+bin/lsarpcd: $(LSARPCD_LIBS) $(LSARPCD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(LSARPCD_OBJ) $(LSARPCD_LIBS) $(LIBS)
+
+bin/spoolssd: $(SAMBA_LIBS) $(SPOOLSSD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(SPOOLSSD_OBJ) $(SAMBA_LIBS) $(LIBS)
+
+bin/srvsvcd: $(SAMBA_LIBS) $(SRVSVCD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(SRVSVCD_OBJ) $(SAMBA_LIBS) $(LIBS)
+
+bin/wkssvcd: $(SAMBA_LIBS) $(WKSSVCD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(WKSSVCD_OBJ) $(SAMBA_LIBS) $(LIBS)
+
+bin/browserd: $(SAMBA_LIBS) $(BROWSERD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(BROWSERD_OBJ) $(SAMBA_LIBS) $(LIBS)
+
+bin/winregd: $(SAMBA_LIBS) $(WINREGD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(WINREGD_OBJ) $(SAMBA_LIBS) $(LIBS)
+
+bin/netlogond: $(NETLOGOND_LIBS) $(NETLOGOND_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(NETLOGOND_OBJ) $(NETLOGOND_LIBS) $(LIBS)
+
+bin/netlogonpassd: $(NETLOGONPASSD_LIBS) $(NETLOGOND_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(NETLOGOND_OBJ) $(NETLOGONPASSD_LIBS) $(LIBS)
+
+bin/netlogontdbd: $(NETLOGONTDBD_LIBS) $(NETLOGOND_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(NETLOGOND_OBJ) $(NETLOGONTDBD_LIBS) $(LIBS)
+
+bin/netlogonnt5ldapd: $(NETLOGONNT5LDAPD_LIBS) $(NETLOGOND_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(NETLOGOND_OBJ) $(NETLOGONNT5LDAPD_LIBS) $(LIBS)
+
+bin/samrd: $(SAMRD_LIBS) $(SAMRD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(SAMRD_OBJ) $(SAMRD_LIBS) $(LIBS)
+
+bin/samrpassd: $(SAMRPASSD_LIBS) $(SAMRD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(SAMRD_OBJ) $(SAMRPASSD_LIBS) $(LIBS)
+
+bin/samrtdbd: $(SAMRTDBD_LIBS) $(SAMRD_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(SAMRD_OBJ) $(SAMRTDBD_LIBS) $(LIBS)
-bin/nmbd: $(NMBD_OBJ) bin/.dummy
+bin/samrnt5ldapd: $(SAMRNT5LDAPD_LIBS) $(SAMRD_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NMBD_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(SAMRD_OBJ) $(SAMRNT5LDAPD_LIBS) $(LIBS)
-bin/swat: $(SWAT_OBJ) bin/.dummy
+bin/nmbd: $(NMBD_LIBS) $(NMBD_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SWAT_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(NMBD_OBJ) $(NMBD_LIBS) $(LIBS)
+
+bin/swat: $(SWAT_LIBS) $(SWAT_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(SWAT_OBJ) $(SWAT_LIBS) $(LIBS)
bin/smbrun: $(SMBRUN_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBRUN_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(SMBRUN_OBJ) $(LIBS)
-bin/rpcclient: $(RPCCLIENT_OBJ) bin/.dummy
+bin/regedit: $(REGEDIT_LIBS) $(REGEDIT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(RPCCLIENT_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(REGEDIT_OBJ) $(REGEDIT_LIBS) $(LIBS)
-bin/smbclient: $(CLIENT_OBJ) bin/.dummy
+bin/svccontrol: $(SVCCLIENT_LIBS) $(SVCCLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CLIENT_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(SVCCLIENT_OBJ) $(SVCCLIENT_LIBS) $(LIBS)
-bin/smbspool: $(CUPS_OBJ) bin/.dummy
+bin/samedit: $(SAMCLIENT_LIBS) $(SAMCLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(CUPS_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(SAMCLIENT_OBJ) $(SAMCLIENT_LIBS) $(LIBS)
-bin/smbmount: $(MOUNT_OBJ) bin/.dummy
+bin/cmdat: $(CMDCLIENT_LIBS) $(CMDCLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MOUNT_OBJ) $(LIBS)
+ @$(LINK) -o $@ $(CMDCLIENT_OBJ) $(CMDCLIENT_LIBS) $(LIBS)
-bin/smbmnt: $(MNT_OBJ) bin/.dummy
+bin/eventlog: $(EVTCLIENT_LIBS) $(EVTCLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MNT_OBJ) $(LIBS)
+ @$(LINK) -o $@ $(EVTCLIENT_OBJ) $(EVTCLIENT_LIBS) $(LIBS)
-bin/smbumount: $(UMOUNT_OBJ) bin/.dummy
+bin/net: $(NETCLIENT_LIBS) $(NETCLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(UMOUNT_OBJ) $(LIBS)
+ @$(LINK) -o $@ $(NETCLIENT_OBJ) $(NETCLIENT_LIBS) $(LIBS)
-bin/testparm: $(TESTPARM_OBJ) bin/.dummy
+bin/lsa: $(LSACLIENT_LIBS) $(LSACLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(TESTPARM_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(LSACLIENT_OBJ) $(LSACLIENT_LIBS) $(LIBS)
-bin/testprns: $(TESTPRNS_OBJ) bin/.dummy
+bin/rpctorture: $(RPCTORTURE_LIBS) $(RPCTORTURE_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(TESTPRNS_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(RPCTORTURE_OBJ) $(RPCTORTURE_LIBS) $(LIBS)
-bin/smbstatus: $(STATUS_OBJ) bin/.dummy
+bin/spoolss: $(SPOOLCLIENT_LIBS) $(SPOOLCLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(SPOOLCLIENT_OBJ) $(SPOOLCLIENT_LIBS) $(LIBS)
-bin/smbpasswd: $(SMBPASSWD_OBJ) bin/.dummy
+bin/rpcclient: $(RPCCLIENT_LIBS) $(RPCCLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(RPCCLIENT_OBJ) $(RPCCLIENT_LIBS) $(LIBS)
-bin/make_smbcodepage: $(MAKE_SMBCODEPAGE_OBJ) bin/.dummy
+bin/smbclient: $(CLIENT_LIBS) $(CLIENT_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MAKE_SMBCODEPAGE_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(CLIENT_OBJ) $(CLIENT_LIBS) $(LIBS)
+
+#bin/smbmount: $(SMBLIB) $(SAMBALIB) $(NMBLIB) $(MOUNT_OBJ) bin/.dummy
+# @echo Linking $@
+# @$(LINK) -o $@ $(MOUNT_OBJ) $(SAMBALIB) $(SMBLIB) $(NMBLIB) $(LIBS)
+
+#bin/smbmnt: $(SMBLIB) $(SAMBALIB) $(NMBLIB) $(MNT_OBJ) bin/.dummy
+# @echo Linking $@
+# @$(LINK) -o $@ $(MNT_OBJ) $(SMBLIB) $(SAMBALIB) $(NMBLIB) $(LIBS)
-bin/make_unicodemap: $(MAKE_UNICODEMAP_OBJ) bin/.dummy
+#bin/smbumount: $(SMBLIB) $(SAMBALIB) $(NMBLIB) $(UMOUNT_OBJ) bin/.dummy
+# @echo Linking $@
+# @$(LINK) -o $@ $(UMOUNT_OBJ) $(SMBLIB) $(SAMBALIB) $(NMBLIB) $(LIBS)
+
+bin/testparm: $(SAMBALIB) $(TESTPARM_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MAKE_UNICODEMAP_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(TESTPARM_OBJ) $(SAMBALIB) $(LIBS)
-bin/nmblookup: $(NMBLOOKUP_OBJ) bin/.dummy
+bin/testprns: $(SAMBALIB) $(TESTPRNS_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(NMBLOOKUP_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(TESTPRNS_OBJ) $(SAMBALIB) $(LIBS)
-bin/make_printerdef: $(MAKE_PRINTERDEF_OBJ) bin/.dummy
+bin/smbstatus: $(SAMBALIB) $(STATUS_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MAKE_PRINTERDEF_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(STATUS_OBJ) $(SAMBALIB) $(LIBS)
-bin/smbtorture: $(SMBTORTURE_OBJ) bin/.dummy
+bin/smbpasswd: $(SMBPASSWD_LIBS) $(SMBPASSWD_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBTORTURE_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(SMBPASSWD_OBJ) $(SMBPASSWD_LIBS) $(LIBS)
-bin/masktest: $(MASKTEST_OBJ) bin/.dummy
+bin/make_smbcodepage: $(SAMBALIB) $(MAKE_SMBCODEPAGE_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(MASKTEST_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(MAKE_SMBCODEPAGE_OBJ) $(SAMBALIB) $(LIBS)
-bin/rpctorture: $(RPCTORTURE_OBJ) bin/.dummy
+bin/nmblookup: $(SAMBALIB) $(NMBLIB) $(NMBLOOKUP_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(RPCTORTURE_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(NMBLOOKUP_OBJ) $(NMBLIB) $(SAMBALIB) $(LIBS)
-bin/debug2html: $(DEBUG2HTML_OBJ) bin/.dummy
+bin/make_printerdef: $(SAMBALIB) $(MAKE_PRINTERDEF_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(DEBUG2HTML_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(MAKE_PRINTERDEF_OBJ) $(SAMBALIB) $(LIBS)
-bin/smbfilter: $(SMBFILTER_OBJ) bin/.dummy
+bin/smbtorture: $(SAMBA_LIBS) $(SMBTORTURE_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBFILTER_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(SMBTORTURE_OBJ) $(SAMBA_LIBS) $(LIBS)
-bin/smbwrapper.@SHLIBEXT@: $(PICOBJS)
- @echo Linking shared library $@
- @$(LD) @LDSHFLAGS@ -o $@ $(PICOBJS) $(LIBS)
+bin/smb-client: $(SMB_CLIENT_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(SMB_CLIENT_OBJ) $(LIBS)
-bin/smbwrapper.32.@SHLIBEXT@: $(PICOBJS32)
- @echo Linking shared library $@
- @$(LD) -32 @LDSHFLAGS@ -o $@ $(PICOBJS32) $(LIBS)
+bin/nmb-agent: $(SAMBALIB) $(SMBLIB) $(NMBLIB) $(NMB_AGENT_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(NMB_AGENT_OBJ) $(SAMBALIB) $(SMBLIB) $(NMBLIB) $(LIBS)
+
+bin/smb-agent: $(SMBLIB) $(SAMBALIB) $(NMBLIB) $(SMB_AGENT_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(SMB_AGENT_OBJ) $(SMBLIB) $(SAMBALIB) $(NMBLIB) $(LIBS)
-bin/smbsh: $(SMBSH_OBJ) bin/.dummy
+bin/smbfilter: $(SAMBA_LIBS) $(SMBFILTER_OBJ) bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) -o $@ $(SMBSH_OBJ) $(LDFLAGS) $(LIBS)
+ @$(LINK) -o $@ $(SMBFILTER_OBJ) $(SAMBA_LIBS) $(LIBS)
+
+bin/debug2html: $(SAMBALIB) $(DEBUG2HTML_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(DEBUG2HTML_OBJ) $(SAMBALIB) $(LIBS)
+
+bin/smbwrapper.so: $(SMBWRAPPERPICOBJS)
+ @echo Linking smbwrapper shared library $@
+ @$(LD) @LDSHFLAGS@ -o $@ $(SMBWRAPPERPICOBJS) $(LIBS)
+
+bin/smbwrapper.32.so: $(SMBWRAPPERPICOBJS32)
+ @echo Linking smbwrapper shared library $@
+ @$(LD) -32 @LDSHFLAGS@ -o $@ $(SMBWRAPPERPICOBJS32) $(LIBS)
-nsswitch/libnss_wins.so: $(NSS_OBJ)
+bin/smbsh: $(SAMBALIB) $(SMBSH_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(SMBSH_OBJ) $(SAMBALIB) $(LIBS)
+
+bin/winbindd: $(WINBINDD_OBJ) bin/.dummy
+ @echo Linking $@
+ @$(LINK) -o $@ $(WINBINDD_OBJ) $(LIBS)
+
+nsswitch/ntdom.so: $(NSS_OBJ)
@echo "Linking $@"
@$(LD) @LDSHFLAGS@ -o $@ $(NSS_OBJ) -lc
-nsswitch: nsswitch/libnss_wins.so
-
-install: installbin installman installscripts installcp installswat
+install: installdirs \
+ install-libs installbin install-sbin \
+ installman installscripts installcp installswat
installdirs:
- $(SHELL) $(srcdir)/install-sh -d -m $(INSTALLPERMS) \
- $(BASEDIR) $(SBINDIR) $(BINDIR) $(LIBDIR) $(VARDIR) $(CODEPAGEDIR)
+ @for p in $(BASEDIR) $(SBINDIR) $(BINDIR) $(LIBDIR) $(VARDIR) \
+ $(CODEPAGEDIR); do \
+ $(SHELL) $(srcdir)/install-sh -d -m $(INSTALLPERMS) $(DESTDIR)$$p; \
+ done
-installservers: all installdirs
- @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(BASEDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(SPROGS)
+install-libs: $(SHARED_LIBS) installdirs
+ @list='$(SHARED_LIBS)'; for p in $$list; do \
+ echo Installing $$p in $(LIBDIR) using libtool; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(LIBDIR); \
+ done
installbin: all installdirs
- @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(BASEDIR) $(SBINDIR) $(LIBDIR) $(VARDIR) $(SPROGS)
- @$(SHELL) $(srcdir)/script/installbin.sh $(INSTALLPERMS) $(BASEDIR) $(BINDIR) $(LIBDIR) $(VARDIR) $(PROGS)
+ @list='$(PROGS)'; for p in $$list; do \
+ echo Installing $$p in $(BINDIR) using libtool; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(BINDIR); \
+ done
+
+install-sbin: all installdirs
+ @list='$(SPROGS)'; for p in $$list; do \
+ echo Installing $$p in $(SBINDIR) using libtool; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(SBINDIR); \
+ done
installscripts: installdirs
- @$(SHELL) $(srcdir)/script/installscripts.sh $(INSTALLPERMS) $(BINDIR) $(SCRIPTS)
+ @$(SHELL) $(srcdir)/script/installscripts.sh $(INSTALLPERMS) $(BINDIR) $(patsubst %,$(srcdir)/%,$(SCRIPTS))
installcp: installdirs
@$(SHELL) $(srcdir)/script/installcp.sh $(srcdir) $(LIBDIR) $(CODEPAGEDIR) $(BINDIR) $(CODEPAGELIST)
@@ -519,29 +1129,53 @@ uninstallcp:
@$(SHELL) $(srcdir)/script/uninstallcp.sh $(CODEPAGEDIR) $(CODEPAGELIST)
clean:
- -rm -f core */*~ *~ */*.o */*.po */*.po32 */*.@SHLIBEXT@
+ -rm -f core */*~ *~ */*.o */*.po */*.po32 */*.lo */*.so
+
+proto: libsmb_proto rpc_client_proto rpc_parse_proto winbindd_proto \
+ all_other_proto_for_now
-proto:
+all_other_proto_for_now:
@echo rebuilding include/proto.h
@cd $(srcdir) && $(AWK) -f script/mkproto.awk `echo $(PROTO_OBJ) | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort -u | egrep -v 'ubiqx/|wrapped'` > include/proto.h
+winbindd_proto:
+ @echo rebuilding include/winbindd_proto.h
+ @cd $(srcdir) && $(AWK) -v headername=_WINBINDD_PROTO_H_ \
+ -f script/mkproto.awk `echo $(WINBINDD_OBJ) | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort -u | egrep -v 'ubiqx/|wrapped'` > include/winbindd_proto.h
+
+libsmb_proto:
+ @echo rebuilding include/libsmb_proto.h
+ @cd $(srcdir) && $(AWK) -v headername=_LIB_SMB_PROTO_H_ \
+ -f script/mkproto.awk `echo $(LIBSMB_OBJ) | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort -u | egrep -v 'ubiqx/|wrapped'` > include/lib_smb_proto.h
+
+rpc_parse_proto:
+ @echo rebuilding include/rpc_parse_proto.h
+ @cd $(srcdir) && $(AWK) -v headername=_RPC_PARSE_PROTO_H_ \
+ -f script/mkproto.awk `echo $(RPC_PARSE_OBJ) | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort -u | egrep -v 'ubiqx/|wrapped'` > include/rpc_parse_proto.h
+
+rpc_client_proto:
+ @echo rebuilding include/rpc_client_proto.h
+ @cd $(srcdir) && $(AWK) -v headername=_RPC_CLIENT_PROTO_H_ \
+ -f script/mkproto.awk `echo $(RPC_CLIENT_OBJ) | tr ' ' '\n' | sed -e 's/\.o/\.c/g' | sort -u | egrep -v 'ubiqx/|wrapped'` > include/rpc_client_proto.h
+
etags:
- etags `find . -name "*.[ch]" | grep -v /CVS/`
+ etags `find . -name "*.[ch]"`
ctags:
- ctags `find . -name "*.[ch]" | grep -v /CVS/`
+ ctags `find . -name "*.[ch]"`
realclean: clean
-rm -f config.log $(PROGS) $(SPROGS) bin/.dummy
- -rmdir bin
+ -rm -rf bin
distclean: realclean
-rm -f include/config.h include/stamp-h Makefile
-rm -f config.status config.cache so_locations
+ -rm -f libtool
-rm -rf .deps
#
-# This target is for documenation updators. It regenerates
+# This target is for documentation updaters. It regenerates
# the man pages and HTML docs from the YODL source files.
# In order for this target to work YODL must be installed
# and working on your system. JRA.
@@ -556,6 +1190,11 @@ finddead:
nm */*.o |grep 'T ' | awk '{print $$3}' | sort -u > nmfns.txt
comm -13 nmused.txt nmfns.txt
+finddeadsmbd:
+ nm $(SMBD_OBJ) |grep 'U ' | awk '{print $$2}' | sort -u > nmusedsmbd.txt
+ nm $(SMBD_OBJ) |grep 'T ' | awk '{print $$3}' | sort -u > nmfnssmbd.txt
+ comm -13 nmusedsmbd.txt nmfnssmbd.txt
+
# Rules for maintainers (--enable-maintainer-mode)
AUTOCONF=@AUTOCONF@
AUTOHEADER=@AUTOHEADER@
@@ -571,6 +1210,11 @@ Makefile: $(srcdir)/Makefile.in config.status \
include/stamp-h # just to ensure that config.h is up-to-date
CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+# So something depends on libtool, so it gets rebuild, if needed
+$(SHARED_LIBS): libtool
+
# note that nothing depends on config.h, so will probably be rebuilt
# only when explicitly requested, unless dependency tracking is enabled
include/config.h: include/stamp-h
diff --git a/source/README b/source/README
new file mode 100644
index 00000000000..77902359a58
--- /dev/null
+++ b/source/README
@@ -0,0 +1,75 @@
+Samba, The Next Generation.
+Sun Jan 2nd 2000.
+lkcl, samba team.
+
+if you got this far, you probably obtained samba using cvs. well done.
+in order to maintain it, you will need to use cvs update, but occasionally
+this will fail, and you will need to delete your cvs tree and start again.
+instructions, in case it was a while since you last did that, are at
+http://samba.org/cvs.html. remember to use SAMBA_TNG as the tag name.
+
+there is also a FAQ, maintained by Lars Kneschke <lars@kneschke.de>, at
+http://www.kneschke.de/projekte/samba_tng.
+
+basic compilation and usage instructions. the following are executed at
+the unix prompt, if you hadn't already guessed.
+
+./configure
+make
+[make install]
+
+to run samba, you will need:
+
+bin/smbd
+bin/nmbd
+
+if you are using any nt clients, running the following will change the
+behaviour of the nt clients towards samba, which will improve the nt
+clients' reliability and performance:
+
+bin/srvsvcd
+bin/wkssvcd
+
+if you intend to operate samba with "encrypt passwords = yes",
+"update encrypted = yes" or "migrate passwords = yes", you will
+also need:
+
+bin/lsarpcd
+bin/samrd
+bin/netlogond
+bin/winregd
+
+you will also need to add your own samba server as a trust account.
+one way to do this, in the usual manner, is:
+
+bin/smbpasswd -a -m your_samba_server_name
+
+if you need NT-style printing:
+
+bin/spoolssd
+
+if you want to be able to start/stop services remotely (yes, dammit,
+you can only do this as root, you think i'm stupid????), you will need,
+as well as your own rc.services script in /usr/local/samba/bin:
+
+bin/svcctld
+
+
+i _really_ like this daemon architecture stuff. if ever there's a problem,
+or you want to upgrade one component, just kill the relevant daemon,
+NOT smbd and NOT any of the other services, and restart it. i think
+that's just great :)
+
+
+Sun Jan 2nd 2000 (later on)
+
+i liked the daemon architecture so much i decided to add it to cvs main,
+or what is affectionately known as the SAMBA-3 tree. what i added was
+code that, instead of _always_ redirecting to the daemon architecture
+like in SAMBA_TNG, samba cvs main _attempts_ to redirect to the daemon
+architecture. if this fails, it will fall back to using the internal
+msrpc code.
+
+so, if you want to use smbd file-services in cvs main, which are much better,
+then simply run cvs main's smbd daemon instead of SAMBA_TNG's.
+
diff --git a/source/acconfig.h b/source/acconfig.h
index 4bf614c04f3..55fd87425e5 100644
--- a/source/acconfig.h
+++ b/source/acconfig.h
@@ -1,4 +1,3 @@
-#undef HAVE_VOLATILE
#undef HAVE_BROKEN_READDIR
#undef HAVE_ERRNO_DECL
#undef HAVE_LONGLONG
@@ -6,14 +5,12 @@
#undef HAVE_REMSH
#undef HAVE_UNSIGNED_CHAR
#undef HAVE_UTIMBUF
-#undef HAVE_SIG_ATOMIC_T_TYPE
#undef ssize_t
#undef ino_t
#undef ssize_t
#undef loff_t
#undef offset_t
#undef aclent_t
-#undef wchar_t
#undef HAVE_CONNECT
#undef HAVE_SHORT_INO_T
#undef WITH_SMBWRAPPER
@@ -25,22 +22,19 @@
#undef AIX
#undef BSD
#undef IRIX
-#undef IRIX6
#undef HPUX
#undef QNX
#undef SCO
#undef OSF1
#undef NEXT2
-#undef RELIANTUNIX
#undef HAVE_SHARED_MMAP
-#undef HAVE_MMAP
#undef HAVE_SYSV_IPC
#undef HAVE_FCNTL_LOCK
#undef HAVE_FTRUNCATE_EXTEND
-#undef FTRUNCATE_NEEDS_ROOT
#undef HAVE_TRAPDOOR_UID
#undef HAVE_ROOT
#undef HAVE_UNION_SEMUN
+#undef HAVE_NETMASK_IFCONF
#undef HAVE_GETTIMEOFDAY_TZ
#undef HAVE_SOCK_SIN_LEN
#undef STAT_READ_FILSYS
@@ -51,36 +45,38 @@
#undef STAT_STATFS4
#undef STAT_STATVFS
#undef STAT_STATVFS64
-#undef HAVE_IFACE_AIX
-#undef HAVE_IFACE_IFCONF
-#undef HAVE_IFACE_IFREQ
+#undef HAVE_NETMASK_IFREQ
+#undef HAVE_NETMASK_AIX
#undef HAVE_CRYPT
#undef HAVE_PUTPRPWNAM
#undef HAVE_SET_AUTH_PARAMETERS
+#undef WITH_MMAP
#undef WITH_SYSLOG
#undef WITH_PROFILE
#undef WITH_SSL
#undef WITH_LDAP
+#undef WITH_TDBSURS
#undef WITH_NISPLUS
-#undef WITH_PAM
#undef WITH_NISPLUS_HOME
#undef WITH_AUTOMOUNT
#undef WITH_SMBMOUNT
+#undef HAVE_PAM_AUTHENTICATE
#undef HAVE_BROKEN_GETGROUPS
#undef REPLACE_GETPASS
#undef REPLACE_INET_NTOA
#undef HAVE_FILE_MACRO
#undef HAVE_FUNCTION_MACRO
#undef HAVE_SETRESUID_DECL
+#undef HAVE_CRYPT_DECL
#undef HAVE_SETRESUID
#undef WITH_NETATALK
-#undef WITH_UTMP
#undef HAVE_INO64_T
#undef HAVE_STRUCT_FLOCK64
#undef SIZEOF_INO_T
#undef SIZEOF_OFF_T
#undef STAT_STATVFS64
#undef HAVE_LIBREADLINE
+#undef HAVE_READLINE_FCF_PROTO
#undef HAVE_KERNEL_OPLOCKS
#undef HAVE_IRIX_SPECIFIC_CAPABILITIES
#undef HAVE_INT16_FROM_RPC_RPC_H
@@ -88,32 +84,23 @@
#undef HAVE_INT32_FROM_RPC_RPC_H
#undef HAVE_UINT32_FROM_RPC_RPC_H
#undef KRB4_AUTH
-#undef KRB5_AUTH
#undef SEEKDIR_RETURNS_VOID
#undef HAVE_DIRENT_D_OFF
#undef HAVE_GETSPNAM
#undef HAVE_BIGCRYPT
#undef HAVE_GETPRPWNAM
-#undef HAVE_FSTAT64
-#undef HAVE_LSTAT64
-#undef HAVE_STAT64
-#undef HAVE_SETRESGID
-#undef HAVE_SETRESGID_DECL
-#undef HAVE_SHADOW_H
-#undef HAVE_MEMSET
-#undef HAVE_STRCASECMP
-#undef HAVE_STRUCT_DIRENT64
-#undef HAVE_TRUNCATED_SALT
-#undef BROKEN_NISPLUS_INCLUDE_FILES
-#undef HAVE_RPC_AUTH_ERROR_CONFLICT
-#undef HAVE_EXPLICIT_LARGEFILE_SUPPORT
-#undef USE_BOTH_CRYPT_CALLS
-#undef HAVE_BROKEN_FCNTL64_LOCKS
-#undef HAVE_FNMATCH
+
+#undef WITH_LIBMSRPC
+#undef WITH_LIBNMB
+#undef WITH_LIBSAMBA
+#undef WITH_LIBSMB
+#undef WITH_LIBSURS
+#undef WITH_LIBSMBPW
+#undef WITH_LIBUBIQX
+
#undef USE_SETEUID
#undef USE_SETRESUID
#undef USE_SETREUID
#undef USE_SETUIDX
-#undef HAVE_LIBDL
-#undef NEED_SGI_SEMUN_HACK
-#undef SYSCONF_SC_NGROUPS_MAX
+
+#undef WITH_NT5LDAP
diff --git a/source/aclocal.m4 b/source/aclocal.m4
index 45ee7b23ade..d037c29ed30 100644
--- a/source/aclocal.m4
+++ b/source/aclocal.m4
@@ -73,3 +73,434 @@ AC_DEFUN(AC_LIBTESTFUNC,
;;
esac
])
+
+## libtool.m4 - Configure libtool for the target system. -*-Shell-script-*-
+## Copyright (C) 1996-1999 Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program 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
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+ [ --disable-libtool-lock avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$lt_target" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$lt_target" in
+*-*-beos* | *-*-cygwin*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, main, LIBM="-lm")
+ ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case "$enable_ltdl_convenience" in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, main,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ INCLTDL=
+ fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
diff --git a/source/architecture.doc b/source/architecture.doc
index eb29792bea0..58a46895941 100644
--- a/source/architecture.doc
+++ b/source/architecture.doc
@@ -7,7 +7,7 @@ Quickly scrabbled together from odd bits of mail and memory. Please update.
This document gives a general overview of how Samba works
internally. The Samba Team has tried to come up with a model which is
the best possible compromise between elegance, portability, security
-and the constraints imposed by the very messy SMB and CIFS
+and the constraints imposed by the very message SMB and CIFS
protocol.
It also tries to answer some of the frequently asked questions such as:
@@ -132,3 +132,8 @@ Samba Design and Security
Why Isn't nmbd Multiple Daemons?
--------------------------------
+DCE/RPC
+-------
+
+NT administration is basically DCE/RPC function calls. The entire
+NT architecture is based on DCE/RPC over SMB.
diff --git a/source/auth/pass_check.c b/source/auth/pass_check.c
index 11ce0d754e8..d89ef2e6c9d 100644
--- a/source/auth/pass_check.c
+++ b/source/auth/pass_check.c
@@ -32,7 +32,7 @@ static char this_salt[100]="";
static char this_crypted[100]="";
-#ifdef WITH_PAM
+#ifdef HAVE_PAM
/*******************************************************************
check on PAM authentication
********************************************************************/
@@ -136,10 +136,6 @@ static BOOL pam_auth(char *user,char *password)
#ifdef WITH_AFS
-
-#include <afs/stds.h>
-#include <afs/kautils.h>
-
/*******************************************************************
check on AFS authentication
********************************************************************/
@@ -162,7 +158,6 @@ static BOOL afs_auth(char *user,char *password)
&reason) == 0) {
return(True);
}
- DEBUG(1,("AFS authentication for \"%s\" failed (%s)\n", user, reason));
return(False);
}
#endif
@@ -170,9 +165,6 @@ static BOOL afs_auth(char *user,char *password)
#ifdef WITH_DFS
-#include <dce/dce_error.h>
-#include <dce/sec_login.h>
-
/*****************************************************************
This new version of the DFS_AUTH code was donated by Karsten Muuss
<muuss@or.uni-bonn.de>. It fixes the following problems with the
@@ -203,7 +195,6 @@ static BOOL dfs_auth(char *user,char *password)
sec_passwd_rec_t passwd_rec;
sec_login_auth_src_t auth_src = sec_login_auth_src_network;
unsigned char dce_errstr[dce_c_error_string_len];
- gid_t egid;
if (dcelogin_atmost_once) return(False);
@@ -331,16 +322,14 @@ static BOOL dfs_auth(char *user,char *password)
* back to being root on error though. JRA.
*/
- egid = getegid();
-
- if (set_effective_gid(pw->pw_gid) != 0) {
+ if (setregid(-1, pw->pw_gid) != 0) {
DEBUG(0,("Can't set egid to %d (%s)\n",
pw->pw_gid, strerror(errno)));
return False;
}
- if (set_effective_uid(pw->pw_uid) != 0) {
- set_effective_gid(egid);
+ if (setreuid(-1, pw->pw_uid) != 0) {
+ setgid(0);
DEBUG(0,("Can't set euid to %d (%s)\n",
pw->pw_uid, strerror(errno)));
return False;
@@ -351,17 +340,24 @@ static BOOL dfs_auth(char *user,char *password)
&my_dce_sec_context,
&err) == 0) {
dce_error_inq_text(err, dce_errstr, &err2);
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE Setup Identity for %s failed: %s\n",
user,dce_errstr));
- goto err;
+ return(False);
}
sec_login_get_pwent(my_dce_sec_context,
(sec_login_passwd_t*)&pw, &err);
if (err != error_status_ok ) {
dce_error_inq_text(err, dce_errstr, &err2);
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr));
- goto err;
+
+ return(False);
}
passwd_rec.version_number = sec_passwd_c_version_none;
@@ -374,16 +370,24 @@ static BOOL dfs_auth(char *user,char *password)
&auth_src, &err);
if (err != error_status_ok ) {
dce_error_inq_text(err, dce_errstr, &err2);
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE Identity Validation failed for principal %s: %s\n",
user,dce_errstr));
- goto err;
+
+ return(False);
}
sec_login_certify_identity(my_dce_sec_context, &err);
if (err != error_status_ok) {
dce_error_inq_text(err, dce_errstr, &err2);
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE certify identity failed: %s\n", dce_errstr));
- goto err;
+
+ return(False);
}
if (auth_src != sec_login_auth_src_network) {
@@ -397,7 +401,10 @@ static BOOL dfs_auth(char *user,char *password)
user,dce_errstr));
sec_login_purge_context(&my_dce_sec_context, &err);
- goto err;
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
+ return(False);
}
sec_login_get_pwent(my_dce_sec_context,
@@ -405,7 +412,11 @@ static BOOL dfs_auth(char *user,char *password)
if (err != error_status_ok) {
dce_error_inq_text(err, dce_errstr, &err2);
DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr));
- goto err;
+
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
+ return(False);
}
DEBUG(0,("DCE login succeeded for principal %s on pid %d\n",
@@ -423,24 +434,21 @@ static BOOL dfs_auth(char *user,char *password)
sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);
if (err != error_status_ok) {
dce_error_inq_text(err, dce_errstr, &err2);
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE can't get expiration. %s\n", dce_errstr));
- goto err;
+
+ return(False);
}
- set_effective_uid(0);
- set_effective_gid(0);
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE context expires: %s",asctime(localtime(&expire_time))));
dcelogin_atmost_once = 1;
return (True);
-
-err:
-
- /* Go back to root, JRA. */
- set_effective_uid(0);
- set_effective_gid(egid);
- return(False);
}
void dfs_unlogin(void)
@@ -459,9 +467,6 @@ void dfs_unlogin(void)
#endif
#ifdef KRB5_AUTH
-
-#include <krb5.h>
-
/*******************************************************************
check on Kerberos authentication
********************************************************************/
@@ -609,7 +614,6 @@ static char *osf1_bigcrypt(char *password,char *salt1)
StrnCpy(salt,salt1,2);
StrnCpy(result,salt1,2);
- result[2]='\0';
for (i=0; i<parts;i++) {
p1 = crypt(p2,salt);
@@ -676,7 +680,7 @@ core of password checking routine
static BOOL password_check(char *password)
{
-#ifdef WITH_PAM
+#ifdef HAVE_PAM
/* This falls through if the password check fails
- if HAVE_CRYPT is not defined this causes an error msg
saying Warning - no crypt available
@@ -687,23 +691,23 @@ static BOOL password_check(char *password)
Hence we make a direct return to avoid a second chance!!!
*/
return (pam_auth(this_user,password));
-#endif /* WITH_PAM */
+#endif
#ifdef WITH_AFS
if (afs_auth(this_user,password)) return(True);
-#endif /* WITH_AFS */
+#endif
#ifdef WITH_DFS
if (dfs_auth(this_user,password)) return(True);
-#endif /* WITH_DFS */
+#endif
#ifdef KRB5_AUTH
if (krb5_auth(this_user,password)) return(True);
-#endif /* KRB5_AUTH */
+#endif
#ifdef KRB4_AUTH
if (krb4_auth(this_user,password)) return(True);
-#endif /* KRB4_AUTH */
+#endif
#ifdef OSF1_ENH_SEC
{
@@ -714,42 +718,26 @@ static BOOL password_check(char *password)
}
return ret;
}
-#endif /* OSF1_ENH_SEC */
+#endif
#ifdef ULTRIX_AUTH
return (strcmp((char *)crypt16(password, this_salt ),this_crypted) == 0);
-#endif /* ULTRIX_AUTH */
+#endif
#ifdef LINUX_BIGCRYPT
return(linux_bigcrypt(password,this_salt,this_crypted));
-#endif /* LINUX_BIGCRYPT */
-
-#if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
-
- /*
- * Some systems have bigcrypt in the C library but might not
- * actually use it for the password hashes (HPUX 10.20) is
- * a noteable example. So we try bigcrypt first, followed
- * by crypt.
- */
-
- if(strcmp(bigcrypt(password,this_salt),this_crypted) == 0)
- return True;
- else
- return (strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
-#else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
+#endif
#ifdef HAVE_BIGCRYPT
return(strcmp(bigcrypt(password,this_salt),this_crypted) == 0);
-#endif /* HAVE_BIGCRYPT */
+#endif
#ifndef HAVE_CRYPT
DEBUG(1,("Warning - no crypt available\n"));
return(False);
-#else /* HAVE_CRYPT */
+#else
return(strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
-#endif /* HAVE_CRYPT */
-#endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
+#endif
}
@@ -760,112 +748,61 @@ the function pointer fn() points to a function to call when a successful
match is found and is used to update the encrypted password file
return True on correct match, False otherwise
****************************************************************************/
-BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
- BOOL (*fn)(char *, char *))
+BOOL pass_check(const char *_user, const char *_password,
+ int pwlen, const struct passwd *pwd,
+ BOOL (*fn)(const char *, const char *))
{
pstring pass2;
int level = lp_passwordlevel();
- struct passwd *pass;
+ const struct passwd *pass;
+ fstring password;
+ fstring user;
- if (password) password[pwlen] = 0;
+ fstrcpy(user, _user);
#if DEBUG_PASSWORD
- DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password));
+ DEBUG(100,("checking user=[%s] pass=",user));
+ dump_data(100, password, strlen(password));
#endif
- if (!password) {
- return(False);
- }
-
- if (((!*password) || (!pwlen)) && !lp_null_passwords()) {
+ if (!_password)
+ {
return(False);
}
- if (pwd && !user) {
- pass = (struct passwd *) pwd;
- user = pass->pw_name;
- } else {
- pass = Get_Pwnam(user,True);
- }
-
+ pwlen = MIN(sizeof(password)-1, pwlen);
+ memset(password, 0, sizeof(password));
+ memcpy(password, _password, pwlen);
- DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen));
-
- if (!pass) {
- DEBUG(3,("Couldn't find user %s\n",user));
+ if (((!*password) || (!pwlen)) && !lp_null_passwords()) {
return(False);
}
-#ifdef HAVE_GETSPNAM
+ if (pwd != NULL && _user == NULL)
{
- struct spwd *spass;
-
- /* many shadow systems require you to be root to get
- the password, in most cases this should already be
- the case when this function is called, except
- perhaps for IPC password changing requests */
-
- spass = getspnam(pass->pw_name);
- if (spass && spass->sp_pwdp) {
- pstrcpy(pass->pw_passwd,spass->sp_pwdp);
- }
+ pass = (const struct passwd *) pwd;
+ fstrcpy(user, pass->pw_name);
}
-#elif defined(IA_UINFO)
+ else
{
- /* Need to get password with SVR4.2's ia_ functions
- instead of get{sp,pw}ent functions. Required by
- UnixWare 2.x, tested on version
- 2.1. (tangent@cyberport.com) */
- uinfo_t uinfo;
- if (ia_openinfo(pass->pw_name, &uinfo) != -1) {
- ia_get_logpwd(uinfo, &(pass->pw_passwd));
- }
+ pass = Get_Pwnam(user,True);
}
-#endif
-#ifdef HAVE_GETPRPWNAM
- {
- struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
- if (pr_pw && pr_pw->ufld.fd_encrypt)
- pstrcpy(pass->pw_passwd,pr_pw->ufld.fd_encrypt);
- }
-#endif
-#ifdef OSF1_ENH_SEC
- {
- struct pr_passwd *mypasswd;
- DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n",
- user));
- mypasswd = getprpwnam (user);
- if (mypasswd) {
- fstrcpy(pass->pw_name,mypasswd->ufld.fd_name);
- fstrcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt);
- } else {
- DEBUG(5,("OSF1_ENH_SEC: No entry for user %s in protected database !\n",
- user));
- }
- }
-#endif
+ DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen));
-#ifdef ULTRIX_AUTH
+ if (pass == NULL)
{
- AUTHORIZATION *ap = getauthuid(pass->pw_uid);
- if (ap) {
- fstrcpy(pass->pw_passwd, ap->a_password);
- endauthent();
- }
+ DEBUG(3,("Couldn't find user %s\n",user));
+ return(False);
}
-#endif
/* extract relevant info */
fstrcpy(this_user,pass->pw_name);
fstrcpy(this_salt,pass->pw_passwd);
-
-#if defined(HAVE_TRUNCATED_SALT)
/* crypt on some platforms (HPUX in particular)
won't work with more than 2 salt characters. */
this_salt[2] = 0;
-#endif
fstrcpy(this_crypted,pass->pw_passwd);
diff --git a/source/bin/.cvsignore b/source/bin/.cvsignore
deleted file mode 100644
index 619587e7b83..00000000000
--- a/source/bin/.cvsignore
+++ /dev/null
@@ -1,15 +0,0 @@
-make_printerdef
-make_smbcodepage
-make_unicodemap
-nmbd
-nmblookup
-rpcclient
-smbclient
-smbd
-smbpasswd
-smbspool
-smbstatus
-swat
-testparm
-testprns
-.dummy
diff --git a/source/browserd/browserd.c b/source/browserd/browserd.c
new file mode 100644
index 00000000000..5ea85a59ba8
--- /dev/null
+++ b/source/browserd/browserd.c
@@ -0,0 +1,142 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+fstring pipe_name;
+
+pstring servicesf = CONFIGFILE;
+extern pstring debugf;
+extern BOOL append_log;
+
+/*****************************************************************************
+ initialise srv_auth_fns array
+ *****************************************************************************/
+static void auth_init(rpcsrv_struct *l)
+{
+}
+
+/*************************************************************************
+ initialise an msrpc service
+ *************************************************************************/
+static void service_init(char* service_name)
+{
+ add_msrpc_command_processor( pipe_name, service_name, api_brs_rpc );
+ generate_wellknown_sids();
+}
+
+/****************************************************************************
+ reload the services file
+ **************************************************************************/
+static BOOL reload_msrpc(BOOL test)
+{
+ BOOL ret;
+
+ if (lp_loaded()) {
+ pstring fname;
+ pstrcpy(fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
+ reopen_logs();
+
+ if (test && !lp_file_list_changed())
+ return(True);
+
+ lp_killunused(NULL);
+
+ ret = lp_load(servicesf,False,False,True);
+
+ /* perhaps the config filename is now set */
+ if (!test)
+ reload_msrpc(True);
+
+ reopen_logs();
+
+ load_interfaces();
+
+ return(ret);
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+static int main_init(int argc,char *argv[])
+{
+#ifdef HAVE_SET_AUTH_PARAMETERS
+ set_auth_parameters(argc,argv);
+#endif
+
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ append_log = True;
+
+ TimeInit();
+
+ setup_logging(argv[0],False);
+ fstrcpy(pipe_name, "browser");
+ slprintf(debugf, sizeof(debugf), "%s/log.%s", LOGFILEBASE, pipe_name);
+
+ return 0;
+}
+
+static msrpc_service_fns fn_table =
+{
+ auth_init,
+ service_init,
+ reload_msrpc,
+ main_init,
+ NULL
+};
+
+msrpc_service_fns *get_service_fns(void)
+{
+ return &fn_table;
+}
+
+/*******************************************************************
+ create_brs_info_100
+ ********************************************************************/
+static void create_brs_info_100(BRS_INFO_100 *inf)
+{
+ make_brs_info_100(inf);
+}
+
+/*******************************************************************
+ _brs_query_info
+
+ only supports info level 100 at the moment.
+
+ ********************************************************************/
+uint32 _brs_query_info( const UNISTR2 *srv_name, uint16 switch_value,
+ void *id)
+{
+ create_brs_info_100(id);
+
+ return 0x0;
+}
diff --git a/source/browserd/srv_browserd_nt.c b/source/browserd/srv_browserd_nt.c
new file mode 100644
index 00000000000..2da6404169d
--- /dev/null
+++ b/source/browserd/srv_browserd_nt.c
@@ -0,0 +1,53 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Sean Millichamp 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+/*******************************************************************
+ create_brs_info_100
+ ********************************************************************/
+static void create_brs_info_100(BRS_INFO_100 *inf)
+{
+ make_brs_info_100(inf);
+}
+
+/*******************************************************************
+ _brs_query_info
+
+ only supports info level 100 at the moment.
+
+ ********************************************************************/
+uint32 _brs_query_info( const UNISTR2 *srv_name, uint16 switch_value,
+ void *id)
+{
+ switch (switch_value)
+ {
+ case 100:
+ {
+ create_brs_info_100(id);
+ return NT_STATUS_NOPROBLEMO;
+ }
+ }
+ return NT_STATUS_INVALID_INFO_CLASS;
+}
diff --git a/source/client/client.c b/source/client/client.c
index ea029d4df7f..114e27d6e21 100644
--- a/source/client/client.c
+++ b/source/client/client.c
@@ -35,13 +35,14 @@ pstring cd_path = "";
static pstring service;
static pstring desthost;
extern pstring global_myname;
+extern pstring myhostname;
static pstring password;
static pstring username;
static pstring workgroup;
static char *cmdstr;
static BOOL got_pass;
-static int io_bufsize = 65520;
extern struct in_addr ipzero;
+extern pstring scope;
static int name_type = 0x20;
@@ -104,6 +105,10 @@ static double dir_total;
#define USENMB
+#define CNV_LANG(s) dos_to_unix(s,False)
+#define CNV_INPUT(s) unix_to_dos(s,True)
+
+
/****************************************************************************
write to a local file with CR/LF->LF translation if appropriate. return the
number taken from the buffer. This may not equal the number written.
@@ -144,16 +149,18 @@ static int readfile(char *b, int size, int n, FILE *f)
return(fread(b,size,n,f));
i = 0;
- while (i < (n - 1) && (i < BUFFER_SIZE)) {
+ while (i < n) {
if ((c = getc(f)) == EOF) {
break;
}
if (c == '\n') { /* change all LFs to CR/LF */
b[i++] = '\r';
+ n++;
}
- b[i++] = c;
+ if(i < n)
+ b[i++] = c;
}
return(i);
@@ -190,13 +197,6 @@ static void send_message(void)
msg[l] = c;
}
- /*
- * The message is in UNIX codepage format. Convert to
- * DOS before sending.
- */
-
- unix_to_dos(msg, True);
-
if (!cli_message_text(cli, msg, l, grp_id)) {
printf("SMBsendtxt failed (%s)\n",cli_errstr(cli));
return;
@@ -239,8 +239,8 @@ show cd/pwd
****************************************************************************/
static void cmd_pwd(void)
{
- DEBUG(0,("Current directory is %s",service));
- DEBUG(0,("%s\n",cur_dir));
+ DEBUG(0,("Current directory is %s",CNV_LANG(service)));
+ DEBUG(0,("%s\n",CNV_LANG(cur_dir)));
}
@@ -290,7 +290,7 @@ static void cmd_cd(void)
if (next_token(NULL,buf,NULL,sizeof(buf)))
do_cd(buf);
else
- DEBUG(0,("Current directory is %s\n",cur_dir));
+ DEBUG(0,("Current directory is %s\n",CNV_LANG(cur_dir)));
}
@@ -327,8 +327,8 @@ static void display_finfo(file_info *finfo)
{
if (do_this_one(finfo)) {
time_t t = finfo->mtime; /* the time is assumed to be passed as GMT */
- DEBUG(0,(" %-30s%7.7s %8.0f %s",
- finfo->name,
+ DEBUG(0,(" %-30s%7.7s%8.0f %s",
+ CNV_LANG(finfo->name),
attrib_string(finfo->mode),
(double)finfo->size,
asctime(LocalTime(&t))));
@@ -349,128 +349,10 @@ static void do_du(file_info *finfo)
static BOOL do_list_recurse;
static BOOL do_list_dirs;
-static char *do_list_queue = 0;
-static long do_list_queue_size = 0;
-static long do_list_queue_start = 0;
-static long do_list_queue_end = 0;
+static int do_list_attr;
static void (*do_list_fn)(file_info *);
/****************************************************************************
-functions for do_list_queue
- ****************************************************************************/
-
-/*
- * The do_list_queue is a NUL-separated list of strings stored in a
- * char*. Since this is a FIFO, we keep track of the beginning and
- * ending locations of the data in the queue. When we overflow, we
- * double the size of the char*. When the start of the data passes
- * the midpoint, we move everything back. This is logically more
- * complex than a linked list, but easier from a memory management
- * angle. In any memory error condition, do_list_queue is reset.
- * Functions check to ensure that do_list_queue is non-NULL before
- * accessing it.
- */
-static void reset_do_list_queue(void)
-{
- if (do_list_queue)
- {
- free(do_list_queue);
- }
- do_list_queue = 0;
- do_list_queue_size = 0;
- do_list_queue_start = 0;
- do_list_queue_end = 0;
-}
-
-static void init_do_list_queue(void)
-{
- reset_do_list_queue();
- do_list_queue_size = 1024;
- do_list_queue = malloc(do_list_queue_size);
- if (do_list_queue == 0) {
- DEBUG(0,("malloc fail for size %d\n",
- (int)do_list_queue_size));
- reset_do_list_queue();
- } else {
- memset(do_list_queue, 0, do_list_queue_size);
- }
-}
-
-static void adjust_do_list_queue(void)
-{
- /*
- * If the starting point of the queue is more than half way through,
- * move everything toward the beginning.
- */
- if (do_list_queue && (do_list_queue_start == do_list_queue_end))
- {
- DEBUG(4,("do_list_queue is empty\n"));
- do_list_queue_start = do_list_queue_end = 0;
- *do_list_queue = '\0';
- }
- else if (do_list_queue_start > (do_list_queue_size / 2))
- {
- DEBUG(4,("sliding do_list_queue backward\n"));
- memmove(do_list_queue,
- do_list_queue + do_list_queue_start,
- do_list_queue_end - do_list_queue_start);
- do_list_queue_end -= do_list_queue_start;
- do_list_queue_start = 0;
- }
-
-}
-
-static void add_to_do_list_queue(const char* entry)
-{
- long new_end = do_list_queue_end + ((long)strlen(entry)) + 1;
- while (new_end > do_list_queue_size)
- {
- do_list_queue_size *= 2;
- DEBUG(4,("enlarging do_list_queue to %d\n",
- (int)do_list_queue_size));
- do_list_queue = Realloc(do_list_queue, do_list_queue_size);
- if (! do_list_queue) {
- DEBUG(0,("failure enlarging do_list_queue to %d bytes\n",
- (int)do_list_queue_size));
- reset_do_list_queue();
- }
- else
- {
- memset(do_list_queue + do_list_queue_size / 2,
- 0, do_list_queue_size / 2);
- }
- }
- if (do_list_queue)
- {
- pstrcpy(do_list_queue + do_list_queue_end, entry);
- do_list_queue_end = new_end;
- DEBUG(4,("added %s to do_list_queue (start=%d, end=%d)\n",
- entry, (int)do_list_queue_start, (int)do_list_queue_end));
- }
-}
-
-static char *do_list_queue_head(void)
-{
- return do_list_queue + do_list_queue_start;
-}
-
-static void remove_do_list_queue_head(void)
-{
- if (do_list_queue_end > do_list_queue_start)
- {
- do_list_queue_start += strlen(do_list_queue_head()) + 1;
- adjust_do_list_queue();
- DEBUG(4,("removed head of do_list_queue (start=%d, end=%d)\n",
- (int)do_list_queue_start, (int)do_list_queue_end));
- }
-}
-
-static int do_list_queue_empty(void)
-{
- return (! (do_list_queue && *do_list_queue));
-}
-
-/****************************************************************************
a helper for do_list
****************************************************************************/
static void do_list_helper(file_info *f, const char *mask)
@@ -490,8 +372,11 @@ static void do_list_helper(file_info *f, const char *mask)
if (!p) return;
p[1] = 0;
pstrcat(mask2, f->name);
+ if (do_list_fn == display_finfo) {
+ DEBUG(0,("\n%s\n",CNV_LANG(mask2)));
+ }
pstrcat(mask2,"\\*");
- add_to_do_list_queue(mask2);
+ do_list(mask2, do_list_attr, do_list_fn, True, True);
}
return;
}
@@ -507,68 +392,12 @@ a wrapper around cli_list that adds recursion
****************************************************************************/
void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs)
{
- static int in_do_list = 0;
-
- if (in_do_list && rec)
- {
- fprintf(stderr, "INTERNAL ERROR: do_list called recursively when the recursive flag is true\n");
- exit(1);
- }
-
- in_do_list = 1;
-
do_list_recurse = rec;
do_list_dirs = dirs;
do_list_fn = fn;
+ do_list_attr = attribute;
- if (rec)
- {
- init_do_list_queue();
- add_to_do_list_queue(mask);
-
- while (! do_list_queue_empty())
- {
- /*
- * Need to copy head so that it doesn't become
- * invalid inside the call to cli_list. This
- * would happen if the list were expanded
- * during the call.
- * Fix from E. Jay Berkenbilt (ejb@ql.org)
- */
- pstring head;
- pstrcpy(head, do_list_queue_head());
- cli_list(cli, head, attribute, do_list_helper);
- remove_do_list_queue_head();
- if ((! do_list_queue_empty()) && (fn == display_finfo))
- {
- char* next_file = do_list_queue_head();
- char* save_ch = 0;
- if ((strlen(next_file) >= 2) &&
- (next_file[strlen(next_file) - 1] == '*') &&
- (next_file[strlen(next_file) - 2] == '\\'))
- {
- save_ch = next_file +
- strlen(next_file) - 2;
- *save_ch = '\0';
- }
- DEBUG(0,("\n%s\n",next_file));
- if (save_ch)
- {
- *save_ch = '\\';
- }
- }
- }
- }
- else
- {
- if (cli_list(cli, mask, attribute, do_list_helper) == -1)
- {
- DEBUG(0, ("%s listing %s\n", cli_errstr(cli), mask));
- }
- }
-
- in_do_list = 0;
- reset_do_list_queue();
+ cli_list(cli, mask, attribute, do_list_helper);
}
/****************************************************************************
@@ -647,7 +476,7 @@ static void do_get(char *rname,char *lname)
BOOL newhandle = False;
char *data;
struct timeval tp_start;
- int read_size = io_bufsize;
+ int read_size = 65520;
uint16 attr;
size_t size;
off_t nread = 0;
@@ -661,7 +490,7 @@ static void do_get(char *rname,char *lname)
fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
if (fnum == -1) {
- DEBUG(0,("%s opening remote file %s\n",cli_errstr(cli),rname));
+ DEBUG(0,("%s opening remote file %s\n",cli_errstr(cli),CNV_LANG(rname)));
return;
}
@@ -688,14 +517,10 @@ static void do_get(char *rname,char *lname)
DEBUG(2,("getting file %s of size %.0f as %s ",
lname, (double)size, lname));
- if(!(data = (char *)malloc(read_size))) {
- DEBUG(0,("malloc fail for size %d\n", read_size));
- cli_close(cli, fnum);
- return;
- }
+ data = (char *)malloc(read_size);
while (1) {
- int n = cli_read(cli, fnum, data, nread, read_size);
+ int n = cli_read(cli, fnum, data, nread, read_size, True);
if (n <= 0) break;
@@ -706,13 +531,6 @@ static void do_get(char *rname,char *lname)
nread += n;
}
-
- if (nread < size) {
- DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n",
- rname, (long)nread));
- }
-
- free(data);
if (!cli_close(cli, fnum)) {
DEBUG(0,("Error %s closing remote file\n",cli_errstr(cli)));
@@ -737,7 +555,7 @@ static void do_get(char *rname,char *lname)
get_total_time_ms += this_time;
get_total_size += nread;
- DEBUG(2,("(%3.1f kb/s) (average %3.1f kb/s)\n",
+ DEBUG(2,("(%g kb/s) (average %g kb/s)\n",
nread / (1.024*this_time + 1.0e-4),
get_total_size / (1.024*get_total_time_ms)));
}
@@ -791,10 +609,10 @@ static void do_mget(file_info *finfo)
if (finfo->mode & aDIR)
slprintf(quest,sizeof(pstring)-1,
- "Get directory %s? ",finfo->name);
+ "Get directory %s? ",CNV_LANG(finfo->name));
else
slprintf(quest,sizeof(pstring)-1,
- "Get file %s? ",finfo->name);
+ "Get file %s? ",CNV_LANG(finfo->name));
if (prompt && !yesno(quest)) return;
@@ -817,13 +635,13 @@ static void do_mget(file_info *finfo)
if (!dos_directory_exist(finfo->name,NULL) &&
dos_mkdir(finfo->name,0777) != 0) {
- DEBUG(0,("failed to create directory %s\n",finfo->name));
+ DEBUG(0,("failed to create directory %s\n",CNV_LANG(finfo->name)));
pstrcpy(cur_dir,saved_curdir);
return;
}
if (dos_chdir(finfo->name) != 0) {
- DEBUG(0,("failed to chdir to directory %s\n",finfo->name));
+ DEBUG(0,("failed to chdir to directory %s\n",CNV_LANG(finfo->name)));
pstrcpy(cur_dir,saved_curdir);
return;
}
@@ -916,7 +734,7 @@ static BOOL do_mkdir(char *name)
{
if (!cli_mkdir(cli, name)) {
DEBUG(0,("%s making remote directory %s\n",
- cli_errstr(cli),name));
+ cli_errstr(cli),CNV_LANG(name)));
return(False);
}
@@ -925,7 +743,7 @@ static BOOL do_mkdir(char *name)
/****************************************************************************
- Exit client.
+make a directory of name "name"
****************************************************************************/
static void cmd_quit(void)
{
@@ -983,15 +801,15 @@ static void do_put(char *rname,char *lname)
FILE *f;
int nread=0;
char *buf=NULL;
- int maxwrite=io_bufsize;
+ int maxwrite=65520;
struct timeval tp_start;
GetTimeOfDay(&tp_start);
- fnum = cli_open(cli, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
+ fnum = cli_open(cli, rname, O_WRONLY|O_CREAT|O_TRUNC, DENY_NONE);
if (fnum == -1) {
- DEBUG(0,("%s opening remote file %s\n",cli_errstr(cli),rname));
+ DEBUG(0,("%s opening remote file %s\n",cli_errstr(cli),CNV_LANG(rname)));
return;
}
@@ -1011,7 +829,7 @@ static void do_put(char *rname,char *lname)
DEBUG(1,("putting file %s as %s ",lname,
- rname));
+ CNV_LANG(rname)));
buf = (char *)malloc(maxwrite);
while (!feof(f)) {
@@ -1019,14 +837,11 @@ static void do_put(char *rname,char *lname)
int ret;
if ((n = readfile(buf,1,n,f)) < 1) {
- if((n == 0) && feof(f))
- break; /* Empty local file. */
-
- DEBUG(0,("Error reading local file: %s\n", strerror(errno) ));
+ DEBUG(0,("Error reading local file\n"));
break;
}
- ret = cli_write(cli, fnum, 0, buf, nread, n);
+ ret = cli_write(cli, fnum, 0, buf, nread, n, 0);
if (n != ret) {
DEBUG(0,("Error writing file: %s\n", cli_errstr(cli)));
@@ -1037,7 +852,7 @@ static void do_put(char *rname,char *lname)
}
if (!cli_close(cli, fnum)) {
- DEBUG(0,("%s closing remote file %s\n",cli_errstr(cli),rname));
+ DEBUG(0,("%s closing remote file %s\n",cli_errstr(cli),CNV_LANG(rname)));
fclose(f);
if (buf) free(buf);
return;
@@ -1058,7 +873,7 @@ static void do_put(char *rname,char *lname)
put_total_time_ms += this_time;
put_total_size += nread;
- DEBUG(1,("(%3.1f kb/s) (average %3.1f kb/s)\n",
+ DEBUG(1,("(%g kb/s) (average %g kb/s)\n",
nread / (1.024*this_time + 1.0e-4),
put_total_size / (1.024*put_total_time_ms)));
}
@@ -1309,7 +1124,7 @@ static void do_del(file_info *finfo)
return;
if (!cli_unlink(cli, mask)) {
- DEBUG(0,("%s deleting remote file %s\n",cli_errstr(cli),mask));
+ DEBUG(0,("%s deleting remote file %s\n",cli_errstr(cli),CNV_LANG(mask)));
}
}
@@ -1336,24 +1151,6 @@ static void cmd_del(void)
do_list(mask, attribute,do_del,False,False);
}
-/****************************************************************************
-****************************************************************************/
-static void cmd_open(void)
-{
- pstring mask;
- fstring buf;
-
- pstrcpy(mask,cur_dir);
-
- if (!next_token(NULL,buf,NULL,sizeof(buf))) {
- DEBUG(0,("del <filename>\n"));
- return;
- }
- pstrcat(mask,buf);
-
- cli_open(cli, mask, O_RDWR, DENY_ALL);
-}
-
/****************************************************************************
remove a directory
@@ -1373,7 +1170,7 @@ static void cmd_rmdir(void)
if (!cli_rmdir(cli, mask)) {
DEBUG(0,("%s removing remote directory file %s\n",
- cli_errstr(cli),mask));
+ cli_errstr(cli),CNV_LANG(mask)));
}
}
@@ -1535,7 +1332,6 @@ list a share name
static void browse_fn(const char *name, uint32 m, const char *comment)
{
fstring typestr;
-
*typestr=0;
switch (m)
@@ -1560,15 +1356,10 @@ try and browse available connections on a host
****************************************************************************/
static BOOL browse_host(BOOL sort)
{
- int ret;
-
printf("\n\tSharename Type Comment\n");
printf("\t--------- ---- -------\n");
- if((ret = cli_RNetShareEnum(cli, browse_fn)) == -1)
- printf("Error returning browse list: %s\n", cli_errstr(cli));
-
- return (ret != -1);
+ return cli_RNetShareEnum(cli, browse_fn);
}
/****************************************************************************
@@ -1584,40 +1375,18 @@ try and browse available connections on a host
****************************************************************************/
static BOOL list_servers(char *wk_grp)
{
- if (!cli->server_domain) return False;
-
printf("\n\tServer Comment\n");
printf("\t--------- -------\n");
- cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_ALL, server_fn);
+ cli_NetServerEnum(cli, workgroup, SV_TYPE_ALL, server_fn);
printf("\n\tWorkgroup Master\n");
printf("\t--------- -------\n");
- cli_NetServerEnum(cli, cli->server_domain, SV_TYPE_DOMAIN_ENUM, server_fn);
+ cli_NetServerEnum(cli, workgroup, SV_TYPE_DOMAIN_ENUM, server_fn);
return True;
}
-#if defined(HAVE_LIBREADLINE)
-# if defined(HAVE_READLINE_HISTORY_H) || defined(HAVE_HISTORY_H)
-/****************************************************************************
-history
-****************************************************************************/
-static void cmd_history(void)
-{
- HIST_ENTRY **hlist;
- register int i;
-
- hlist = history_list (); /* Get pointer to history list */
-
- if (hlist) /* If list not empty */
- {
- for (i = 0; hlist[i]; i++) /* then display it */
- DEBUG(0, ("%d: %s\n", i, hlist[i]->line));
- }
-}
-# endif
-#endif
/* Some constants for completing filename arguments */
@@ -1648,7 +1417,6 @@ struct
{"more",cmd_more,"<remote name> view a remote file with your pager",{COMPL_REMOTE,COMPL_NONE}},
{"mask",cmd_select,"<mask> mask all filenames against this",{COMPL_REMOTE,COMPL_NONE}},
{"del",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
- {"open",cmd_open,"<mask> open a file",{COMPL_REMOTE,COMPL_NONE}},
{"rm",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
{"mkdir",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
{"md",cmd_mkdir,"<directory> make a directory",{COMPL_NONE,COMPL_NONE}},
@@ -1674,9 +1442,6 @@ struct
{"setmode",cmd_setmode,"filename <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}},
{"help",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
{"?",cmd_help,"[command] give help on a command",{COMPL_NONE,COMPL_NONE}},
-#ifdef HAVE_LIBREADLINE
- {"history",cmd_history,"displays the command history",{COMPL_NONE,COMPL_NONE}},
-#endif
{"!",NULL,"run a shell command on the local system",{COMPL_NONE,COMPL_NONE}},
{"",NULL,NULL,{COMPL_NONE,COMPL_NONE}}
};
@@ -1734,7 +1499,6 @@ static void cmd_help(void)
}
}
-#ifndef HAVE_LIBREADLINE
/****************************************************************************
wait for keyboard activity, swallowing network packets
****************************************************************************/
@@ -1750,7 +1514,7 @@ static void wait_keyboard(void)
timeout.tv_sec = 20;
timeout.tv_usec = 0;
- sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,&timeout);
+ sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,NULL, &timeout);
if (FD_ISSET(fileno(stdin),&fds))
return;
@@ -1765,7 +1529,6 @@ static void wait_keyboard(void)
cli_chkpath(cli, "\\");
}
}
-#endif
/****************************************************************************
process a -c command string
@@ -1791,6 +1554,9 @@ static void process_command_string(char *cmd)
cmd = p + 1;
}
+ /* input language code to internal one */
+ CNV_INPUT (line);
+
/* and get the first part of the command */
ptr = line;
if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
@@ -1798,65 +1564,233 @@ static void process_command_string(char *cmd)
if ((i = process_tok(tok)) >= 0) {
commands[i].fn();
} else if (i == -2) {
- DEBUG(0,("%s: command abbreviation ambiguous\n",tok));
+ DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
} else {
- DEBUG(0,("%s: command not found\n",tok));
+ DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
}
}
}
+#ifdef HAVE_LIBREADLINE
+
+/****************************************************************************
+GNU readline completion functions
+****************************************************************************/
+
+/* Argh. This is where it gets ugly. We really need to be able to
+ pass back from the do_list() iterator function. */
+
+static int compl_state;
+static char *compl_text;
+static pstring result;
+
+/* Iterator function for do_list() */
+
+static void complete_process_file(file_info *f)
+{
+ /* Do we have a partial match? */
+
+ if ((compl_state >= 0) && (strncmp(compl_text, f->name,
+ strlen(compl_text)) == 0)) {
+
+ /* Return filename if we have made enough matches */
+
+ if (compl_state == 0) {
+ pstrcpy(result, f->name);
+ compl_state = -1;
+
+ return;
+ }
+ compl_state--;
+ }
+}
+
+/* Complete a remote file */
+
+static char *complete_remote_file(char *text, int state)
+{
+ int attribute = aDIR | aSYSTEM | aHIDDEN;
+ pstring mask;
+
+ /* Create dir mask */
+
+ pstrcpy(mask, cur_dir);
+ pstrcat(mask, "*");
+
+ /* Initialise static vars for filename match */
+
+ compl_text = text;
+ compl_state = state;
+ result[0] = '\0';
+
+ /* Iterate over all files in directory */
+
+ do_list(mask, attribute, complete_process_file, False, True);
+
+ /* Return matched filename */
+
+ if (result[0] != '\0') {
+ return strdup(result); /* Readline will dispose of strings */
+ } else {
+ return NULL;
+ }
+}
+
+/* Complete a smbclient command */
+
+static char *complete_cmd(char *text, int state)
+{
+ static int cmd_index;
+ char *name;
+
+ /* Initialise */
+
+ if (state == 0) {
+ cmd_index = 0;
+ }
+
+ /* Return the next name which partially matches the list of commands */
+
+ while (strlen(name = commands[cmd_index++].name) > 0) {
+ if (strncmp(name, text, strlen(text)) == 0) {
+ return strdup(name);
+ }
+ }
+
+ return NULL;
+}
+
+/* Main completion function for smbclient. Work out which word we are
+ trying to complete and call the appropriate helper function -
+ complete_cmd() if we are completing smbclient commands,
+ comlete_remote_file() if we are completing a file on the remote end,
+ filename_completion_function() builtin to GNU readline for local
+ files. */
+
+static char **completion_fn(char *text, int start, int end)
+{
+ int i, num_words, cmd_index;
+ char lastch = ' ';
+
+ /* If we are at the start of a word, we are completing a smbclient
+ command. */
+
+ if (start == 0) {
+ return completion_matches(text, complete_cmd);
+ }
+
+ /* Count # of words in command */
+
+ num_words = 0;
+ for (i = 0; i <= end; i++) {
+ if ((rl_line_buffer[i] != ' ') && (lastch == ' '))
+ num_words++;
+ lastch = rl_line_buffer[i];
+ }
+
+ if (rl_line_buffer[end] == ' ')
+ num_words++;
+
+ /* Work out which command we are completing for */
+
+ for (cmd_index = 0; strcmp(commands[cmd_index].name, "") != 0;
+ cmd_index++) {
+
+ /* Check each command in array */
+
+ if (strncmp(rl_line_buffer, commands[cmd_index].name,
+ strlen(commands[cmd_index].name)) == 0) {
+
+ /* Call appropriate completion function */
+
+ if ((num_words == 2) || (num_words == 3)) {
+ switch (commands[cmd_index].compl_args[num_words - 2]) {
+
+ case COMPL_REMOTE:
+ return completion_matches(text, complete_remote_file);
+ break;
+
+ case COMPL_LOCAL:
+ return completion_matches(text, filename_completion_function);
+ break;
+
+ default:
+ /* An invalid completion type */
+ break;
+ }
+ }
+
+ /* We're either completing an argument > 3 or found an invalid
+ completion type. Either way do nothing about it. */
+
+ break;
+ }
+ }
+
+ return NULL;
+}
+
+/* To avoid filename completion being activated when no valid
+ completions are found, we assign this stub completion function
+ to the rl_completion_entry_function variable. */
+
+static char *complete_cmd_null(char *text, int state)
+{
+ return NULL;
+}
+
+#endif /* HAVE_LIBREADLINE */
+
/****************************************************************************
process commands on stdin
****************************************************************************/
static void process_stdin(void)
{
pstring line;
- char *ptr;
-
#ifdef HAVE_LIBREADLINE
-/* Minimal readline support, 29Jun1999, s.xenitellis@rhbnc.ac.uk */
-#ifdef PROMPTSIZE
-#undef PROMPTSIZE
-#endif
-#define PROMPTSIZE 2048
- char prompt_str[PROMPTSIZE]; /* This holds the buffer "smb: \dir1\> " */
-
- char *temp; /* Gets the buffer from readline() */
- temp = (char *)NULL;
+ pstring promptline;
#endif
+ char *ptr;
+
while (!feof(stdin)) {
fstring tok;
int i;
-#ifdef HAVE_LIBREADLINE
- if ( temp != (char *)NULL )
- {
- free( temp ); /* Free memory allocated every time by readline() */
- temp = (char *)NULL;
- }
- snprintf( prompt_str, PROMPTSIZE - 1, "smb: %s> ", cur_dir );
-
- temp = readline( prompt_str ); /* We read the line here */
-
- if ( !temp )
- break; /* EOF occured */
+#ifndef HAVE_LIBREADLINE
- if ( *temp ) /* If non-empty line, save to history */
- add_history (temp);
-
- strncpy( line, temp, 1023 ); /* Maximum size of (pstring)line. Null is guarranteed. */
-#else
/* display a prompt */
- DEBUG(0,("smb: %s> ", cur_dir));
+ DEBUG(0,("smb: %s> ", CNV_LANG(cur_dir)));
dbgflush( );
-
+
wait_keyboard();
/* and get a response */
if (!fgets(line,1000,stdin))
break;
-#endif
+#else /* !HAVE_LIBREADLINE */
+
+ /* Read input using GNU Readline */
+
+ slprintf(promptline, sizeof(promptline) - 1, "smb: %s> ",
+ CNV_LANG(cur_dir));
+
+ if (!readline(promptline))
+ break;
+
+ /* Copy read line to samba buffer */
+
+ pstrcpy(line, rl_line_buffer);
+ pstrcat(line, "\n");
+
+ /* Add line to history */
+
+ if (strlen(line) > 0)
+ add_history(line);
+#endif
+ /* input language code to internal one */
+ CNV_INPUT (line);
+
/* special case - first char is ! */
if (*line == '!') {
system(line + 1);
@@ -1870,9 +1804,9 @@ static void process_stdin(void)
if ((i = process_tok(tok)) >= 0) {
commands[i].fn();
} else if (i == -2) {
- DEBUG(0,("%s: command abbreviation ambiguous\n",tok));
+ DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
} else {
- DEBUG(0,("%s: command not found\n",tok));
+ DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
}
}
}
@@ -1881,15 +1815,22 @@ static void process_stdin(void)
/*****************************************************
return a connection to a server
*******************************************************/
-struct cli_state *do_connect(char *server, char *share)
+struct cli_state *do_connect(char *server, char *share, int smb_port)
{
- struct cli_state *c;
- struct nmb_name called, calling;
+ struct cli_state *smb_cli;
+ struct nmb_name called, calling, stupid_smbserver_called;
char *server_n;
struct in_addr ip;
extern struct in_addr ipzero;
- if (*share == '\\') {
+ if ((smb_cli=cli_initialise(NULL)) == NULL)
+ {
+ DEBUG(1,("cli_initialise failed\n"));
+ return NULL;
+ }
+
+ if (*share == '\\')
+ {
server = share+2;
share = strchr(server,'\\');
if (!share) return NULL;
@@ -1901,88 +1842,54 @@ struct cli_state *do_connect(char *server, char *share)
ip = ipzero;
- make_nmb_name(&calling, global_myname, 0x0);
- make_nmb_name(&called , server, name_type);
+ make_nmb_name(&calling, global_myname, 0x0, "");
+ make_nmb_name(&called , server, name_type, "");
+ make_nmb_name(&stupid_smbserver_called , "*SMBSERVER", 0x20, scope);
+
+ fstrcpy(smb_cli->usr.user_name, username);
+ fstrcpy(smb_cli->usr.domain, workgroup);
- again:
ip = ipzero;
if (have_ip) ip = dest_ip;
- /* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) == 0) ||
- !cli_connect(c, server_n, &ip)) {
- DEBUG(0,("Connection to %s failed\n", server_n));
+ if (cli_set_port(smb_cli, smb_port) == 0)
+ {
return NULL;
}
- if (!cli_session_request(c, &calling, &called)) {
- char *p;
- DEBUG(0,("session request to %s failed (%s)\n",
- called.name, cli_errstr(c)));
- cli_shutdown(c);
- if ((p=strchr(called.name, '.'))) {
- *p = 0;
- goto again;
- }
- if (strcmp(called.name, "*SMBSERVER")) {
- make_nmb_name(&called , "*SMBSERVER", 0x20);
- goto again;
+ /* set the password cache info */
+ if (got_pass)
+ {
+ if (password[0] == 0)
+ {
+ pwd_set_nullpwd(&(smb_cli->usr.pwd));
}
- return NULL;
- }
-
- DEBUG(4,(" session request ok\n"));
-
- if (!cli_negprot(c)) {
- DEBUG(0,("protocol negotiation failed\n"));
- cli_shutdown(c);
- return NULL;
- }
-
- if (!got_pass) {
- char *pass = getpass("Password: ");
- if (pass) {
- pstrcpy(password, pass);
+ else
+ {
+ /* generate 16 byte hashes */
+ pwd_make_lm_nt_16(&(smb_cli->usr.pwd), password);
}
}
-
- if (!cli_session_setup(c, username,
- password, strlen(password),
- password, strlen(password),
- workgroup)) {
- /* if a password was not supplied then try again with a null username */
- if (password[0] || !username[0] ||
- !cli_session_setup(c, "", "", 0, "", 0, workgroup)) {
- DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
- return NULL;
- }
- DEBUG(0,("Anonymous login successful\n"));
+ else
+ {
+ pwd_read(&(smb_cli->usr.pwd), "Password:", True);
}
- /*
- * These next two lines are needed to emulate
- * old client behaviour for people who have
- * scripts based on client output.
- * QUESTION ? Do we want to have a 'client compatibility
- * mode to turn these on/off ? JRA.
- */
+ /* paranoia: destroy the local copy of the password */
+ bzero(password, sizeof(password));
- if (*c->server_domain || *c->server_os || *c->server_type)
- DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
- c->server_domain,c->server_os,c->server_type));
-
- DEBUG(4,(" session setup ok\n"));
+ smb_cli->use_ntlmv2 = lp_client_ntlmv2();
- if (!cli_send_tconX(c, share, "?????",
- password, strlen(password)+1)) {
- DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
- cli_shutdown(c);
+ if (!cli_establish_connection(smb_cli, server, &ip, &calling, &called,
+ share, "?????", False, True) &&
+ !cli_establish_connection(smb_cli, server, &ip,
+ &calling, &stupid_smbserver_called,
+ share, "?????", False, True))
+ {
return NULL;
}
-
- DEBUG(4,(" tconx ok\n"));
-
- return c;
+
+ return smb_cli;
}
@@ -1991,7 +1898,7 @@ struct cli_state *do_connect(char *server, char *share)
****************************************************************************/
static BOOL process(char *base_directory)
{
- cli = do_connect(desthost, service);
+ cli = do_connect(desthost, service, port);
if (!cli) {
return(False);
}
@@ -2013,10 +1920,11 @@ usage on the program
****************************************************************************/
static void usage(char *pname)
{
- DEBUG(0,("Usage: %s service <password> [options]", pname));
+ DEBUG(0,("Usage: %s service <password> ", pname));
DEBUG(0,("\nVersion %s\n",VERSION));
DEBUG(0,("\t-s smb.conf pathname to smb.conf file\n"));
+ DEBUG(0,("\t-B IP addr broadcast IP address to use\n"));
DEBUG(0,("\t-O socket_options socket options to use\n"));
DEBUG(0,("\t-R name resolve order use these name resolution services only\n"));
DEBUG(0,("\t-M host send a winpopup message to the host\n"));
@@ -2038,7 +1946,6 @@ static void usage(char *pname)
DEBUG(0,("\t-T<c|x>IXFqgbNan command line tar\n"));
DEBUG(0,("\t-D directory start from directory\n"));
DEBUG(0,("\t-c command string execute semicolon separated commands\n"));
- DEBUG(0,("\t-b xmit/send buffer changes the transmit/send buffer (default: 65520)\n"));
DEBUG(0,("\n"));
}
@@ -2106,9 +2013,9 @@ static void get_password_file(void)
/****************************************************************************
handle a -L query
****************************************************************************/
-static int do_host_query(char *query_host)
+static int do_host_query(char *query_host, int smb_port)
{
- cli = do_connect(query_host, "IPC$");
+ cli = do_connect(query_host, "IPC$", smb_port);
if (!cli)
return 1;
@@ -2124,10 +2031,10 @@ static int do_host_query(char *query_host)
/****************************************************************************
handle a tar operation
****************************************************************************/
-static int do_tar_op(char *base_directory)
+static int do_tar_op(int smb_port, char *base_directory)
{
int ret;
- cli = do_connect(desthost, service);
+ cli = do_connect(desthost, service, smb_port);
if (!cli)
return 1;
@@ -2152,8 +2059,8 @@ static int do_message_op(void)
ip = ipzero;
- make_nmb_name(&calling, global_myname, 0x0);
- make_nmb_name(&called , desthost, name_type);
+ make_nmb_name(&calling, global_myname, 0x0, "");
+ make_nmb_name(&called , desthost, name_type, "");
ip = ipzero;
if (have_ip) ip = dest_ip;
@@ -2189,6 +2096,7 @@ static int do_message_op(void)
extern int optind;
pstring query_host;
BOOL message = False;
+ BOOL explicit_user = False;
extern char tar_type;
static pstring servicesf = CONFIGFILE;
pstring term_code;
@@ -2208,39 +2116,15 @@ static int do_message_op(void)
DEBUGLEVEL = 2;
-#ifdef HAVE_LIBREADLINE
- /* Allow conditional parsing of the ~/.inputrc file. */
- rl_readline_name = "smbclient";
-#endif
setup_logging(pname,True);
- /*
- * If the -E option is given, be careful not to clobber stdout
- * before processing the options. 28.Feb.99, richard@hacom.nl.
- * Also pre-parse the -s option to get the service file name.
- */
-
- for (opt = 1; opt < argc; opt++) {
- if (strcmp(argv[opt], "-E") == 0)
- dbf = stderr;
- else if(strncmp(argv[opt], "-s", 2) == 0) {
- if(argv[opt][2] != '\0')
- pstrcpy(servicesf, &argv[opt][2]);
- else if(argv[opt+1] != NULL) {
- /*
- * At least one more arg left.
- */
- pstrcpy(servicesf, argv[opt+1]);
- } else {
- usage(pname);
- exit(1);
- }
- }
- }
-
TimeInit();
charset_initialise();
+ if(!get_myname(myhostname,NULL)) {
+ DEBUG(0,("Failed to get my hostname.\n"));
+ }
+
in_client = True; /* Make sure that we tell lp_load we are */
if (!lp_load(servicesf,True,False,False)) {
@@ -2249,6 +2133,8 @@ static int do_message_op(void)
codepage_initialise(lp_client_code_page());
+ interpret_coding_system(term_code);
+
#ifdef WITH_SSL
sslutil_init(0);
#endif
@@ -2323,11 +2209,14 @@ static int do_message_op(void)
}
while ((opt =
- getopt(argc, argv,"s:O:R:M:i:Nn:d:Pp:l:hI:EU:L:t:m:W:T:D:c:b:")) != EOF) {
+ getopt(argc, argv,"s:B:O:R:M:i:Nn:d:Pp:l:hI:EU:L:t:m:W:T:D:c:")) != EOF) {
switch (opt) {
case 's':
pstrcpy(servicesf, optarg);
break;
+ case 'B':
+ iface_set_default(NULL,optarg,NULL);
+ break;
case 'O':
pstrcpy(user_socket_options,optarg);
break;
@@ -2340,11 +2229,7 @@ static int do_message_op(void)
message = True;
break;
case 'i':
- {
- extern pstring global_scope;
- pstrcpy(global_scope,optarg);
- strupper(global_scope);
- }
+ pstrcpy(scope,optarg);
break;
case 'N':
got_pass = True;
@@ -2385,6 +2270,7 @@ static int do_message_op(void)
case 'U':
{
char *lp;
+ explicit_user = True;
pstrcpy(username,optarg);
if ((lp=strchr(username,'%'))) {
*lp = 0;
@@ -2395,10 +2281,9 @@ static int do_message_op(void)
}
break;
case 'L':
- p = optarg;
- while(*p == '\\' || *p == '/')
- p++;
- pstrcpy(query_host,p);
+ pstrcpy(query_host,optarg);
+ if(!explicit_user)
+ *username = '\0';
break;
case 't':
pstrcpy(term_code, optarg);
@@ -2422,32 +2307,40 @@ static int do_message_op(void)
cmdstr = optarg;
got_pass = True;
break;
- case 'b':
- io_bufsize = MAX(1, atoi(optarg));
- break;
default:
usage(pname);
exit(1);
}
}
- get_myname((*global_myname)?NULL:global_myname);
+ get_myname((*global_myname)?NULL:global_myname,NULL);
if(*new_name_resolve_order)
lp_set_name_resolve_order(new_name_resolve_order);
- if (*term_code)
- interpret_coding_system(term_code);
-
if (!tar_type && !*query_host && !*service && !message) {
usage(pname);
exit(1);
}
+#ifdef HAVE_LIBREADLINE
+
+ /* Initialise GNU Readline */
+
+ rl_readline_name = "smbclient";
+ rl_attempted_completion_function = completion_fn;
+ rl_completion_entry_function = (Function *)complete_cmd_null;
+
+ /* Initialise history list */
+
+ using_history();
+
+#endif /* HAVE_LIBREADLINE */
+
DEBUG( 3, ( "Client started (version %s).\n", VERSION ) );
if (tar_type) {
- return do_tar_op(base_directory);
+ return do_tar_op(port, base_directory);
}
if ((p=strchr(query_host,'#'))) {
@@ -2457,7 +2350,7 @@ static int do_message_op(void)
}
if (*query_host) {
- return do_host_query(query_host);
+ return do_host_query(query_host, port);
}
if (message) {
@@ -2465,8 +2358,10 @@ static int do_message_op(void)
}
if (!process(base_directory)) {
+ close_sockets();
return(1);
}
+ close_sockets();
return(0);
}
diff --git a/source/client/clientutil.c b/source/client/clientutil.c
new file mode 100644
index 00000000000..efa836dede5
--- /dev/null
+++ b/source/client/clientutil.c
@@ -0,0 +1,975 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define NO_SYSLOG
+
+#include "includes.h"
+
+#ifndef REGISTER
+#define REGISTER 0
+#endif
+
+pstring service="";
+pstring desthost="";
+extern pstring global_myname;
+pstring password = "";
+pstring smb_login_passwd = "";
+pstring username="";
+pstring workgroup=WORKGROUP;
+BOOL got_pass = False;
+BOOL no_pass = False;
+BOOL connect_as_printer = False;
+BOOL connect_as_ipc = False;
+
+char cryptkey[8];
+BOOL doencrypt=False;
+
+extern pstring user_socket_options;
+
+/* 30 second timeout on most commands */
+#define CLIENT_TIMEOUT (30*1000)
+#define SHORT_TIMEOUT (5*1000)
+
+int name_type = 0x20;
+
+int max_protocol = PROTOCOL_NT1;
+
+BOOL readbraw_supported = False;
+BOOL writebraw_supported = False;
+
+extern int DEBUGLEVEL;
+
+uint16 cnum = 0;
+uint16 pid = 0;
+uint16 vuid = 0;
+uint16 mid = 0;
+
+int max_xmit = BUFFER_SIZE;
+
+BOOL have_ip = False;
+
+extern struct in_addr dest_ip;
+
+extern int Protocol;
+
+extern int Client;
+
+
+/****************************************************************************
+setup basics in a outgoing packet
+****************************************************************************/
+void cli_setup_pkt(char *outbuf)
+{
+ SSVAL(outbuf,smb_pid,pid);
+ SSVAL(outbuf,smb_uid,vuid);
+ SSVAL(outbuf,smb_mid,mid);
+ if (Protocol > PROTOCOL_COREPLUS)
+ {
+ SCVAL(outbuf,smb_flg,0x8);
+ SSVAL(outbuf,smb_flg2,0x1);
+ }
+}
+
+/****************************************************************************
+call a remote api
+****************************************************************************/
+BOOL cli_call_api(char *pipe_name, int pipe_name_len,
+ int prcnt,int drcnt, int srcnt,
+ int mprcnt,int mdrcnt,
+ int *rprcnt,int *rdrcnt,
+ char *param,char *data, uint16 *setup,
+ char **rparam,char **rdata)
+{
+ static char *inbuf=NULL;
+ static char *outbuf=NULL;
+
+ if (!inbuf) inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+ if (!outbuf) outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+
+ if(!inbuf || !outbuf) {
+ DEBUG(0,("cli_call_api: malloc fail.\n"));
+ return False;
+ }
+
+ if (pipe_name_len == 0) pipe_name_len = strlen(pipe_name);
+
+ cli_send_trans_request(outbuf,SMBtrans,pipe_name, pipe_name_len, 0,0,
+ data, param, setup,
+ drcnt, prcnt, srcnt,
+ mdrcnt, mprcnt, 0);
+
+ return (cli_receive_trans_response(inbuf,SMBtrans,
+ rdrcnt,rprcnt,
+ rdata,rparam));
+}
+
+
+/****************************************************************************
+ receive a SMB trans or trans2 response allocating the necessary memory
+ ****************************************************************************/
+BOOL cli_receive_trans_response(char *inbuf,int trans,
+ int *data_len,int *param_len,
+ char **data,char **param)
+{
+ int total_data=0;
+ int total_param=0;
+ int this_data,this_param;
+
+ *data_len = *param_len = 0;
+
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ show_msg(inbuf);
+
+ /* sanity check */
+ if (CVAL(inbuf,smb_com) != trans)
+ {
+ DEBUG(0,("Expected %s response, got command 0x%02x\n",
+ trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
+ return(False);
+ }
+ if (CVAL(inbuf,smb_rcls) != 0)
+ return(False);
+
+ /* parse out the lengths */
+ total_data = SVAL(inbuf,smb_tdrcnt);
+ total_param = SVAL(inbuf,smb_tprcnt);
+
+ /* allocate it */
+ *data = Realloc(*data,total_data);
+ *param = Realloc(*param,total_param);
+
+ if((total_data && !data) || (total_param && !param)) {
+ DEBUG(0,("cli_receive_trans_response: Realloc fail !\n"));
+ return(False);
+ }
+
+ while (1)
+ {
+ this_data = SVAL(inbuf,smb_drcnt);
+ this_param = SVAL(inbuf,smb_prcnt);
+ if (this_data)
+ memcpy(*data + SVAL(inbuf,smb_drdisp),
+ smb_base(inbuf) + SVAL(inbuf,smb_droff),
+ this_data);
+ if (this_param)
+ memcpy(*param + SVAL(inbuf,smb_prdisp),
+ smb_base(inbuf) + SVAL(inbuf,smb_proff),
+ this_param);
+ *data_len += this_data;
+ *param_len += this_param;
+
+ /* parse out the total lengths again - they can shrink! */
+ total_data = SVAL(inbuf,smb_tdrcnt);
+ total_param = SVAL(inbuf,smb_tprcnt);
+
+ if (total_data <= *data_len && total_param <= *param_len)
+ break;
+
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+ show_msg(inbuf);
+
+ /* sanity check */
+ if (CVAL(inbuf,smb_com) != trans)
+ {
+ DEBUG(0,("Expected %s response, got command 0x%02x\n",
+ trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(inbuf,smb_com)));
+ return(False);
+ }
+ if (CVAL(inbuf,smb_rcls) != 0)
+ return(False);
+ }
+
+ return(True);
+}
+
+
+
+/****************************************************************************
+ send a SMB trans or trans2 request
+ ****************************************************************************/
+BOOL cli_send_trans_request(char *outbuf,int trans,
+ char *name,int namelen, int fid,int flags,
+ char *data,char *param,uint16 *setup,
+ int ldata,int lparam,int lsetup,
+ int mdata,int mparam,int msetup)
+{
+ int i;
+ int this_ldata,this_lparam;
+ int tot_data=0,tot_param=0;
+ char *outdata,*outparam;
+ pstring inbuf;
+ char *p;
+
+ this_lparam = MIN(lparam,max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */
+ this_ldata = MIN(ldata,max_xmit - (500+lsetup*SIZEOFWORD+this_lparam));
+
+ bzero(outbuf,smb_size);
+ set_message(outbuf,14+lsetup,0,True);
+ CVAL(outbuf,smb_com) = trans;
+ SSVAL(outbuf,smb_tid,cnum);
+ cli_setup_pkt(outbuf);
+
+ outparam = smb_buf(outbuf)+(trans==SMBtrans ? namelen+1 : 3);
+ outdata = outparam+this_lparam;
+
+ /* primary request */
+ SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
+ SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
+ SSVAL(outbuf,smb_mprcnt,mparam); /* mprcnt */
+ SSVAL(outbuf,smb_mdrcnt,mdata); /* mdrcnt */
+ SCVAL(outbuf,smb_msrcnt,msetup); /* msrcnt */
+ SSVAL(outbuf,smb_flags,flags); /* flags */
+ SIVAL(outbuf,smb_timeout,0); /* timeout */
+ SSVAL(outbuf,smb_pscnt,this_lparam); /* pscnt */
+ SSVAL(outbuf,smb_psoff,smb_offset(outparam,outbuf)); /* psoff */
+ SSVAL(outbuf,smb_dscnt,this_ldata); /* dscnt */
+ SSVAL(outbuf,smb_dsoff,smb_offset(outdata,outbuf)); /* dsoff */
+ SCVAL(outbuf,smb_suwcnt,lsetup); /* suwcnt */
+ for (i=0;i<lsetup;i++) /* setup[] */
+ SSVAL(outbuf,smb_setup+i*SIZEOFWORD,setup[i]);
+ p = smb_buf(outbuf);
+ if (trans==SMBtrans)
+ memcpy(p,name, namelen+1); /* name[] */
+ else
+ {
+ *p++ = 0; /* put in a null smb_name */
+ *p++ = 'D'; *p++ = ' '; /* this was added because OS/2 does it */
+ }
+ if (this_lparam) /* param[] */
+ memcpy(outparam,param,this_lparam);
+ if (this_ldata) /* data[] */
+ memcpy(outdata,data,this_ldata);
+ set_message(outbuf,14+lsetup, /* wcnt, bcc */
+ PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
+
+ show_msg(outbuf);
+ send_smb(Client,outbuf);
+
+ if (this_ldata < ldata || this_lparam < lparam)
+ {
+ /* receive interim response */
+ if (!client_receive_smb(Client,inbuf,SHORT_TIMEOUT) || CVAL(inbuf,smb_rcls) != 0)
+ {
+ DEBUG(0,("%s request failed (%s)\n",
+ trans==SMBtrans?"SMBtrans":"SMBtrans2", smb_errstr(inbuf)));
+ return(False);
+ }
+
+ tot_data = this_ldata;
+ tot_param = this_lparam;
+
+ while (tot_data < ldata || tot_param < lparam)
+ {
+ this_lparam = MIN(lparam-tot_param,max_xmit - 500); /* hack */
+ this_ldata = MIN(ldata-tot_data,max_xmit - (500+this_lparam));
+
+ set_message(outbuf,trans==SMBtrans?8:9,0,True);
+ CVAL(outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2;
+
+ outparam = smb_buf(outbuf);
+ outdata = outparam+this_lparam;
+
+ /* secondary request */
+ SSVAL(outbuf,smb_tpscnt,lparam); /* tpscnt */
+ SSVAL(outbuf,smb_tdscnt,ldata); /* tdscnt */
+ SSVAL(outbuf,smb_spscnt,this_lparam); /* pscnt */
+ SSVAL(outbuf,smb_spsoff,smb_offset(outparam,outbuf)); /* psoff */
+ SSVAL(outbuf,smb_spsdisp,tot_param); /* psdisp */
+ SSVAL(outbuf,smb_sdscnt,this_ldata); /* dscnt */
+ SSVAL(outbuf,smb_sdsoff,smb_offset(outdata,outbuf)); /* dsoff */
+ SSVAL(outbuf,smb_sdsdisp,tot_data); /* dsdisp */
+ if (trans==SMBtrans2)
+ SSVAL(outbuf,smb_sfid,fid); /* fid */
+ if (this_lparam) /* param[] */
+ memcpy(outparam,param,this_lparam);
+ if (this_ldata) /* data[] */
+ memcpy(outdata,data,this_ldata);
+ set_message(outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
+ PTR_DIFF(outdata+this_ldata,smb_buf(outbuf)),False);
+
+ show_msg(outbuf);
+ send_smb(Client,outbuf);
+
+ tot_data += this_ldata;
+ tot_param += this_lparam;
+ }
+ }
+
+ return(True);
+}
+
+
+/****************************************************************************
+send a session request
+****************************************************************************/
+BOOL cli_send_session_request(char *inbuf,char *outbuf)
+{
+ fstring dest;
+ char *p;
+ int len = 4;
+ /* send a session request (RFC 8002) */
+
+ fstrcpy(dest,desthost);
+ p = strchr(dest,'.');
+ if (p) *p = 0;
+
+ /* put in the destination name */
+ p = outbuf+len;
+ name_mangle(dest,p,name_type); /* 0x20 is the SMB server NetBIOS type. */
+ len += name_len(p);
+
+ /* and my name */
+ p = outbuf+len;
+ name_mangle(global_myname,p,0);
+ len += name_len(p);
+
+ /* setup the packet length */
+ _smb_setlen(outbuf,len);
+ CVAL(outbuf,0) = 0x81;
+
+#ifdef WITH_SSL
+retry:
+#endif /* WITH_SSL */
+
+ send_smb(Client,outbuf);
+ DEBUG(5,("Sent session request\n"));
+
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+
+ if (CVAL(inbuf,0) == 0x84) /* C. Hoch 9/14/95 Start */
+ {
+ /* For information, here is the response structure.
+ * We do the byte-twiddling to for portability.
+ struct RetargetResponse{
+ unsigned char type;
+ unsigned char flags;
+ int16 length;
+ int32 ip_addr;
+ int16 port;
+ };
+ */
+ extern int Client;
+ int port = (CVAL(inbuf,8)<<8)+CVAL(inbuf,9);
+ /* SESSION RETARGET */
+ putip((char *)&dest_ip,inbuf+4);
+
+ close_sockets();
+ Client = open_socket_out(SOCK_STREAM, &dest_ip, port, LONG_CONNECT_TIMEOUT);
+ if (Client == -1)
+ return False;
+
+ DEBUG(3,("Retargeted\n"));
+
+ set_socket_options(Client,user_socket_options);
+
+ /* Try again */
+ return cli_send_session_request(inbuf,outbuf);
+ } /* C. Hoch 9/14/95 End */
+
+#ifdef WITH_SSL
+ if(CVAL(inbuf,0) == 0x83 && CVAL(inbuf,4) == 0x8e) { /* use ssl */
+ fprintf(stderr, "Making secure connection\n");
+ if(!sslutil_fd_is_ssl(Client)){
+ if(sslutil_connect(Client) == 0)
+ goto retry;
+ }
+ }
+#endif
+
+ if (CVAL(inbuf,0) != 0x82)
+ {
+ int ecode = CVAL(inbuf,4);
+ DEBUG(0,("Session request failed (%d,%d) with myname=%s destname=%s\n",
+ CVAL(inbuf,0),ecode,global_myname,desthost));
+ switch (ecode)
+ {
+ case 0x80:
+ DEBUG(0,("Not listening on called name\n"));
+ DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
+ DEBUG(0,("You may find the -I option useful for this\n"));
+ break;
+ case 0x81:
+ DEBUG(0,("Not listening for calling name\n"));
+ DEBUG(0,("Try to connect as another name (instead of %s)\n",global_myname));
+ DEBUG(0,("You may find the -n option useful for this\n"));
+ break;
+ case 0x82:
+ DEBUG(0,("Called name not present\n"));
+ DEBUG(0,("Try to connect to another name (instead of %s)\n",desthost));
+ DEBUG(0,("You may find the -I option useful for this\n"));
+ break;
+ case 0x83:
+ DEBUG(0,("Called name present, but insufficient resources\n"));
+ DEBUG(0,("Perhaps you should try again later?\n"));
+ break;
+ default:
+ DEBUG(0,("Unspecified error 0x%X\n",ecode));
+ DEBUG(0,("Your server software is being unfriendly\n"));
+ break;
+ }
+ return(False);
+ }
+ return(True);
+}
+
+static struct {
+ int prot;
+ char *name;
+} prots[] = {
+ {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"},
+ {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"},
+ {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"},
+ {PROTOCOL_LANMAN1,"LANMAN1.0"},
+ {PROTOCOL_LANMAN2,"LM1.2X002"},
+ {PROTOCOL_LANMAN2,"Samba"},
+ {PROTOCOL_NT1,"NT LM 0.12"},
+ {PROTOCOL_NT1,"NT LANMAN 1.0"},
+ {-1,NULL}
+};
+
+
+/****************************************************************************
+send a login command.
+****************************************************************************/
+BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup, struct connection_options *options)
+{
+ BOOL was_null = (!inbuf && !outbuf);
+ time_t servertime = 0;
+ extern int serverzone;
+ int crypt_len=0;
+ char *pass = NULL;
+ uchar enc_ntpass[24];
+ int ntpasslen = 0;
+ pstring dev;
+ char *p;
+ int numprots;
+ int tries=0;
+ struct connection_options opt;
+
+ bzero(&opt, sizeof(opt));
+
+ if (was_null)
+ {
+ inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+ outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+
+ if(!inbuf || !outbuf) {
+ DEBUG(0,("cli_send_login: malloc fail !\n"));
+ return False;
+ }
+ }
+
+ if (strstr(service,"IPC$")) connect_as_ipc = True;
+
+ pstrcpy(dev,"A:");
+ if (connect_as_printer)
+ pstrcpy(dev,"LPT1:");
+ if (connect_as_ipc)
+ pstrcpy(dev,"IPC");
+
+
+ if (start_session && !cli_send_session_request(inbuf,outbuf))
+ {
+ if (was_null)
+ {
+ free(inbuf);
+ free(outbuf);
+ }
+ return(False);
+ }
+
+ bzero(outbuf,smb_size);
+
+ /* setup the protocol strings */
+ {
+ int plength;
+
+ for (plength=0,numprots=0;
+ prots[numprots].name && prots[numprots].prot<=max_protocol;
+ numprots++)
+ plength += strlen(prots[numprots].name)+2;
+
+ set_message(outbuf,0,plength,True);
+
+ p = smb_buf(outbuf);
+ for (numprots=0;
+ prots[numprots].name && prots[numprots].prot<=max_protocol;
+ numprots++)
+ {
+ *p++ = 2;
+ pstrcpy(p,prots[numprots].name);
+ p += strlen(p) + 1;
+ }
+ }
+
+ CVAL(outbuf,smb_com) = SMBnegprot;
+ cli_setup_pkt(outbuf);
+
+ CVAL(smb_buf(outbuf),0) = 2;
+
+ send_smb(Client,outbuf);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+
+ show_msg(inbuf);
+
+ if (CVAL(inbuf,smb_rcls) != 0 || ((int)SVAL(inbuf,smb_vwv0) >= numprots))
+ {
+ DEBUG(0,("SMBnegprot failed. myname=%s destname=%s - %s \n",
+ global_myname,desthost,smb_errstr(inbuf)));
+ if (was_null)
+ {
+ free(inbuf);
+ free(outbuf);
+ }
+ return(False);
+ }
+
+ opt.protocol = Protocol = prots[SVAL(inbuf,smb_vwv0)].prot;
+
+
+ if (Protocol < PROTOCOL_LANMAN1) {
+ /* no extra params */
+ } else if (Protocol < PROTOCOL_NT1) {
+ opt.sec_mode = SVAL(inbuf,smb_vwv1);
+ opt.max_xmit = max_xmit = SVAL(inbuf,smb_vwv2);
+ opt.sesskey = IVAL(inbuf,smb_vwv6);
+ opt.serverzone = serverzone = SVALS(inbuf,smb_vwv10)*60;
+ /* this time is converted to GMT by make_unix_date */
+ servertime = make_unix_date(inbuf+smb_vwv8);
+ if (Protocol >= PROTOCOL_COREPLUS) {
+ opt.rawmode = SVAL(inbuf,smb_vwv5);
+ readbraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x1) != 0);
+ writebraw_supported = ((SVAL(inbuf,smb_vwv5) & 0x2) != 0);
+ }
+ crypt_len = smb_buflen(inbuf);
+ memcpy(cryptkey,smb_buf(inbuf),8);
+ DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv3)));
+ opt.max_vcs = SVAL(inbuf,smb_vwv4);
+ DEBUG(3,("max vcs %d\n",opt.max_vcs));
+ DEBUG(3,("max blk %d\n",SVAL(inbuf,smb_vwv5)));
+ } else {
+ /* NT protocol */
+ opt.sec_mode = CVAL(inbuf,smb_vwv1);
+ opt.max_xmit = max_xmit = IVAL(inbuf,smb_vwv3+1);
+ opt.sesskey = IVAL(inbuf,smb_vwv7+1);
+ opt.serverzone = SVALS(inbuf,smb_vwv15+1)*60;
+ /* this time arrives in real GMT */
+ servertime = interpret_long_date(inbuf+smb_vwv11+1);
+ crypt_len = CVAL(inbuf,smb_vwv16+1);
+ memcpy(cryptkey,smb_buf(inbuf),8);
+ if (IVAL(inbuf,smb_vwv9+1) & 1)
+ readbraw_supported = writebraw_supported = True;
+ DEBUG(3,("max mux %d\n",SVAL(inbuf,smb_vwv1+1)));
+ opt.max_vcs = SVAL(inbuf,smb_vwv2+1);
+ DEBUG(3,("max vcs %d\n",opt.max_vcs));
+ DEBUG(3,("max raw %d\n",IVAL(inbuf,smb_vwv5+1)));
+ DEBUG(3,("capabilities 0x%x\n",IVAL(inbuf,smb_vwv9+1)));
+ }
+
+ DEBUG(3,("Sec mode %d\n",SVAL(inbuf,smb_vwv1)));
+ DEBUG(3,("max xmt %d\n",max_xmit));
+ DEBUG(3,("Got %d byte crypt key\n",crypt_len));
+ DEBUG(3,("Chose protocol [%s]\n",prots[SVAL(inbuf,smb_vwv0)].name));
+
+ doencrypt = ((opt.sec_mode & 2) != 0);
+
+ if (servertime) {
+ static BOOL done_time = False;
+ if (!done_time) {
+ DEBUG(1,("Server time is %sTimezone is UTC%+02.1f\n",
+ asctime(LocalTime(&servertime)),
+ -(double)(serverzone/3600.0)));
+ done_time = True;
+ }
+ }
+
+ get_pass:
+
+ if (got_pass)
+ pass = password;
+ else
+ pass = (char *)getpass("Password: ");
+
+ if(!pass)
+ pass = "";
+
+ pstrcpy(smb_login_passwd, pass);
+
+ /* use a blank username for the 2nd try with a blank password */
+ if (tries++ && !*pass)
+ *username = 0;
+
+ if (Protocol >= PROTOCOL_LANMAN1 && use_setup)
+ {
+ fstring pword;
+ int passlen = strlen(pass)+1;
+ fstrcpy(pword,pass);
+
+ if (doencrypt && *pass)
+ {
+ DEBUG(3,("Using encrypted passwords\n"));
+ passlen = 24;
+ SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword);
+ ntpasslen = 24;
+ SMBNTencrypt((uchar *)pass,(uchar *)cryptkey,enc_ntpass);
+ }
+
+ /* if in share level security then don't send a password now */
+ if (!(opt.sec_mode & 1)) {fstrcpy(pword, "");passlen=1;}
+
+ /* send a session setup command */
+ bzero(outbuf,smb_size);
+
+ if (Protocol < PROTOCOL_NT1)
+ {
+ set_message(outbuf,10,1 + strlen(username) + passlen,True);
+ CVAL(outbuf,smb_com) = SMBsesssetupX;
+ cli_setup_pkt(outbuf);
+
+ CVAL(outbuf,smb_vwv0) = 0xFF;
+ SSVAL(outbuf,smb_vwv2,max_xmit);
+ SSVAL(outbuf,smb_vwv3,2);
+ SSVAL(outbuf,smb_vwv4,opt.max_vcs-1);
+ SIVAL(outbuf,smb_vwv5,opt.sesskey);
+ SSVAL(outbuf,smb_vwv7,passlen);
+ p = smb_buf(outbuf);
+ memcpy(p,pword,passlen);
+ p += passlen;
+ pstrcpy(p,username);
+ }
+ else
+ {
+ if (!doencrypt) passlen--;
+ /* for Win95 */
+ set_message(outbuf,13,0,True);
+ CVAL(outbuf,smb_com) = SMBsesssetupX;
+ cli_setup_pkt(outbuf);
+
+ CVAL(outbuf,smb_vwv0) = 0xFF;
+ SSVAL(outbuf,smb_vwv2,BUFFER_SIZE);
+ SSVAL(outbuf,smb_vwv3,2);
+ SSVAL(outbuf,smb_vwv4,getpid());
+ SIVAL(outbuf,smb_vwv5,opt.sesskey);
+ SSVAL(outbuf,smb_vwv7,passlen);
+ SSVAL(outbuf,smb_vwv8,doencrypt ? ntpasslen : 0);
+ p = smb_buf(outbuf);
+ memcpy(p,pword,passlen); p += SVAL(outbuf,smb_vwv7);
+ if(doencrypt)
+ memcpy(p,enc_ntpass,ntpasslen); p += SVAL(outbuf,smb_vwv8);
+ pstrcpy(p,username);p = skip_string(p,1);
+ pstrcpy(p,workgroup);p = skip_string(p,1);
+ pstrcpy(p,"Unix");p = skip_string(p,1);
+ pstrcpy(p,"Samba");p = skip_string(p,1);
+ set_message(outbuf,13,PTR_DIFF(p,smb_buf(outbuf)),False);
+ }
+
+ send_smb(Client,outbuf);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+
+ show_msg(inbuf);
+
+ if (CVAL(inbuf,smb_rcls) != 0)
+ {
+ if (! *pass &&
+ ((CVAL(inbuf,smb_rcls) == ERRDOS &&
+ SVAL(inbuf,smb_err) == ERRnoaccess) ||
+ (CVAL(inbuf,smb_rcls) == ERRSRV &&
+ SVAL(inbuf,smb_err) == ERRbadpw)))
+ {
+ got_pass = False;
+ DEBUG(3,("resending login\n"));
+ if (! no_pass)
+ goto get_pass;
+ }
+
+ DEBUG(0,("Session setup failed for username=%s myname=%s destname=%s %s\n",
+ username,global_myname,desthost,smb_errstr(inbuf)));
+ DEBUG(0,("You might find the -U, -W or -n options useful\n"));
+ DEBUG(0,("Sometimes you have to use `-n USERNAME' (particularly with OS/2)\n"));
+ DEBUG(0,("Some servers also insist on uppercase-only passwords\n"));
+ if (was_null)
+ {
+ free(inbuf);
+ free(outbuf);
+ }
+ return(False);
+ }
+
+ if (Protocol >= PROTOCOL_NT1)
+ {
+ char *domain,*os,*lanman;
+ p = smb_buf(inbuf);
+ os = p;
+ lanman = skip_string(os,1);
+ domain = skip_string(lanman,1);
+ if (*domain || *os || *lanman)
+ DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",domain,os,lanman));
+ }
+
+ /* use the returned uid from now on */
+ if (SVAL(inbuf,smb_uid) != vuid)
+ DEBUG(3,("Server gave us a UID of %d. We gave %d\n",
+ SVAL(inbuf,smb_uid),(int)vuid));
+ opt.server_vuid = vuid = SVAL(inbuf,smb_uid);
+ }
+
+ if (opt.sec_mode & 1) {
+ if (SVAL(inbuf, smb_vwv2) & 1)
+ DEBUG(1,("connected as guest "));
+ DEBUG(1,("security=user\n"));
+ } else {
+ DEBUG(1,("security=share\n"));
+ }
+
+ /* now we've got a connection - send a tcon message */
+ bzero(outbuf,smb_size);
+
+ if (strncmp(service,"\\\\",2) != 0)
+ {
+ DEBUG(0,("\nWarning: Your service name doesn't start with \\\\. This is probably incorrect.\n"));
+ DEBUG(0,("Perhaps try replacing each \\ with \\\\ on the command line?\n\n"));
+ }
+
+
+ again2:
+
+ {
+ int passlen = strlen(pass)+1;
+ fstring pword;
+ fstrcpy(pword,pass);
+
+ if (doencrypt && *pass) {
+ passlen=24;
+ SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword);
+ }
+
+ /* if in user level security then don't send a password now */
+ if ((opt.sec_mode & 1)) {
+ fstrcpy(pword, ""); passlen=1;
+ }
+
+ if (Protocol <= PROTOCOL_COREPLUS) {
+ set_message(outbuf,0,6 + strlen(service) + passlen + strlen(dev),True);
+ CVAL(outbuf,smb_com) = SMBtcon;
+ cli_setup_pkt(outbuf);
+
+ p = smb_buf(outbuf);
+ *p++ = 0x04;
+ pstrcpy(p, service);
+ p = skip_string(p,1);
+ *p++ = 0x04;
+ memcpy(p,pword,passlen);
+ p += passlen;
+ *p++ = 0x04;
+ pstrcpy(p, dev);
+ }
+ else {
+ set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True);
+ CVAL(outbuf,smb_com) = SMBtconX;
+ cli_setup_pkt(outbuf);
+
+ SSVAL(outbuf,smb_vwv0,0xFF);
+ SSVAL(outbuf,smb_vwv3,passlen);
+
+ p = smb_buf(outbuf);
+ memcpy(p,pword,passlen);
+ p += passlen;
+ pstrcpy(p,service);
+ p = skip_string(p,1);
+ pstrcpy(p,dev);
+ }
+ }
+
+ send_smb(Client,outbuf);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+
+ /* trying again with a blank password */
+ if (CVAL(inbuf,smb_rcls) != 0 &&
+ (int)strlen(pass) > 0 &&
+ !doencrypt &&
+ Protocol >= PROTOCOL_LANMAN1)
+ {
+ DEBUG(2,("first SMBtconX failed, trying again. %s\n",smb_errstr(inbuf)));
+ pstrcpy(pass,"");
+ goto again2;
+ }
+
+ if (CVAL(inbuf,smb_rcls) != 0)
+ {
+ DEBUG(0,("SMBtconX failed. %s\n",smb_errstr(inbuf)));
+ DEBUG(0,("Perhaps you are using the wrong sharename, username or password?\n"));
+ DEBUG(0,("Some servers insist that these be in uppercase\n"));
+ if (was_null)
+ {
+ free(inbuf);
+ free(outbuf);
+ }
+ return(False);
+ }
+
+
+ if (Protocol <= PROTOCOL_COREPLUS) {
+ max_xmit = SVAL(inbuf,smb_vwv0);
+
+ cnum = SVAL(inbuf,smb_vwv1);
+ }
+ else {
+ max_xmit = MIN(max_xmit,BUFFER_SIZE-4);
+ if (max_xmit <= 0)
+ max_xmit = BUFFER_SIZE - 4;
+
+ cnum = SVAL(inbuf,smb_tid);
+ }
+ opt.max_xmit = max_xmit;
+ opt.tid = cnum;
+
+ DEBUG(3,("Connected with cnum=%d max_xmit=%d\n",cnum,max_xmit));
+
+ if (was_null)
+ {
+ free(inbuf);
+ free(outbuf);
+ }
+
+ if (options != NULL)
+ {
+ *options = opt;
+ }
+
+ return True;
+}
+
+
+/****************************************************************************
+send a logout command
+****************************************************************************/
+void cli_send_logout(char *dum_in, char *dum_out)
+{
+ pstring inbuf,outbuf;
+
+ DEBUG(5,("cli_send_logout\n"));
+
+ bzero(outbuf,smb_size);
+ set_message(outbuf,0,0,True);
+ CVAL(outbuf,smb_com) = SMBtdis;
+ SSVAL(outbuf,smb_tid,cnum);
+ cli_setup_pkt(outbuf);
+
+ send_smb(Client,outbuf);
+ client_receive_smb(Client,inbuf,SHORT_TIMEOUT);
+
+ if (CVAL(inbuf,smb_rcls) != 0)
+ {
+ DEBUG(0,("SMBtdis failed %s\n",smb_errstr(inbuf)));
+ }
+
+
+#ifdef STATS
+ stats_report();
+#endif
+ exit(0);
+}
+
+
+/****************************************************************************
+open the client sockets
+****************************************************************************/
+BOOL cli_open_sockets(int port )
+{
+ static int last_port;
+ char *host;
+ pstring service2;
+ extern int Client;
+
+ if (port == 0) port=last_port;
+ last_port=port;
+
+ strupper(service);
+
+ if (*desthost)
+ {
+ host = desthost;
+ }
+ else
+ {
+ pstrcpy(service2,service);
+ host = strtok(service2,"\\/");
+ if (!host) {
+ DEBUG(0,("Badly formed host name\n"));
+ return(False);
+ }
+ pstrcpy(desthost,host);
+ }
+
+ if (!(*global_myname)) {
+ get_myname(global_myname,NULL);
+ }
+ strupper(global_myname);
+
+ DEBUG(3,("Opening sockets\n"));
+
+ if (!have_ip)
+ {
+ if(!resolve_name( host, &dest_ip, 0x20))
+ {
+ DEBUG(0,("cli_open_sockets: Unknown host %s.\n",host));
+ return False;
+ }
+ }
+
+ Client = open_socket_out(SOCK_STREAM, &dest_ip, port, LONG_CONNECT_TIMEOUT);
+ if (Client == -1)
+ return False;
+
+ DEBUG(3,("Connected\n"));
+
+ set_socket_options(Client,user_socket_options);
+
+ return True;
+}
+
+/****************************************************************************
+close and open the connection again
+****************************************************************************/
+BOOL cli_reopen_connection(char *inbuf,char *outbuf)
+{
+ static int open_count=0;
+
+ open_count++;
+
+ if (open_count>5) return(False);
+
+ DEBUG(1,("Trying to re-open connection\n"));
+
+ set_message(outbuf,0,0,True);
+ SCVAL(outbuf,smb_com,SMBtdis);
+ SSVAL(outbuf,smb_tid,cnum);
+ cli_setup_pkt(outbuf);
+
+ send_smb(Client,outbuf);
+ client_receive_smb(Client,inbuf,SHORT_TIMEOUT);
+
+ close_sockets();
+ if (!cli_open_sockets(0)) return(False);
+
+ return(cli_send_login(inbuf,outbuf,True,True,NULL));
+}
+
diff --git a/source/client/clitar.c b/source/client/clitar.c
index d71eff1c9e2..ee1f97835c0 100644
--- a/source/client/clitar.c
+++ b/source/client/clitar.c
@@ -193,7 +193,7 @@ static void writetarheader(int f, char *aname, int size, time_t mtime,
memset(b, 0, l+TBLOCK+100);
fixtarname(b, aname, l);
i = strlen(b)+1;
- DEBUG(5, ("File name in tar file: %s, size=%d, \n", b, (int)strlen(b)));
+ DEBUG(5, ("File name in tar file: %s, size=%i, \n", b, strlen(b)));
dotarbuf(f, b, TBLOCK*(((i-1)/TBLOCK)+1));
free(b);
}
@@ -427,8 +427,8 @@ static void fixtarname(char *tptr, char *fp, int l)
*tptr++='.';
while (l > 0) {
- int skip = get_character_len(*fp);
- if(skip != 0) {
+ int skip;
+ if((skip = skip_multibyte_char( *fp)) != 0) {
if (skip == 2) {
*tptr++ = *fp++;
*tptr++ = *fp++;
@@ -659,7 +659,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
{
DEBUG(3,("skipping file %s of size %d bytes\n",
finfo.name,
- (int)finfo.size));
+ finfo.size));
shallitime=0;
ttarf+=finfo.size + TBLOCK - (finfo.size % TBLOCK);
ntarf++;
@@ -712,7 +712,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
{
DEBUG(3,("getting file %s of size %d bytes as a tar file %s",
finfo.name,
- (int)finfo.size,
+ finfo.size,
lname));
/* write a tar header, don't bother with mode - just set to 100644 */
@@ -722,7 +722,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
DEBUG(3,("nread=%d\n",nread));
- datalen = cli_read(cli, fnum, data, nread, read_size);
+ datalen = cli_read(cli, fnum, data, nread, read_size, True);
if (datalen == -1) {
DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli)));
@@ -747,7 +747,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
/* pad tar file with zero's if we couldn't get entire file */
if (nread < finfo.size) {
- DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n", (int)finfo.size, (int)nread));
+ DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n", finfo.size, nread));
if (padit(data, sizeof(data), finfo.size - nread))
DEBUG(0,("Error writing tar file - %s\n", strerror(errno)));
}
@@ -781,7 +781,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
if (tar_noisy)
{
DEBUG(0, ("%10d (%7.1f kb/s) %s\n",
- (int)finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
+ finfo.size, finfo.size / MAX(0.001, (1.024*this_time)),
finfo.name));
}
@@ -806,7 +806,7 @@ static void do_tar(file_info *finfo)
if (!tar_excl && clipn) {
pstring exclaim;
- DEBUG(5, ("Excl: strlen(cur_dir) = %d\n", (int)strlen(cur_dir)));
+ DEBUG(5, ("Excl: strlen(cur_dir) = %i\n", strlen(cur_dir)));
safe_strcpy(exclaim, cur_dir, sizeof(pstring));
*(exclaim+strlen(exclaim)-1)='\0';
@@ -834,7 +834,7 @@ static void do_tar(file_info *finfo)
safe_strcpy(saved_curdir, cur_dir, sizeof(saved_curdir));
- DEBUG(5, ("Sizeof(cur_dir)=%d, strlen(cur_dir)=%d, strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", (int)sizeof(cur_dir), (int)strlen(cur_dir), (int)strlen(finfo->name), finfo->name, cur_dir));
+ DEBUG(5, ("Sizeof(cur_dir)=%i, strlen(cur_dir)=%i, strlen(finfo->name)=%i\nname=%s,cur_dir=%s\n", sizeof(cur_dir), strlen(cur_dir), strlen(finfo->name), finfo->name, cur_dir));
safe_strcat(cur_dir,finfo->name, sizeof(cur_dir));
safe_strcat(cur_dir,"\\", sizeof(cur_dir));
@@ -885,8 +885,8 @@ static void unfixtarname(char *tptr, char *fp, int l, BOOL first)
}
while (l > 0) {
- int skip = get_character_len(*fp);
- if(skip != 0) {
+ int skip;
+ if(( skip = skip_multibyte_char( *fp )) != 0) {
if (skip == 2) {
*tptr++ = *fp++;
*tptr++ = *fp++;
@@ -923,27 +923,14 @@ static int next_block(char *ltarbuf, char **bufferp, int bufsiz)
DEBUG(5, ("Reading more data into ltarbuf ...\n"));
- /*
- * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>
- * Fixes bug where read can return short if coming from
- * a pipe.
- */
+ total = 0;
- bufread = read(tarhandle, ltarbuf, bufsiz);
- total = bufread;
+ for (bufread = read(tarhandle, ltarbuf, bufsiz); total < bufsiz; total += bufread) {
- while (total < bufsiz) {
- if (bufread < 0) { /* An error, return false */
- return (total > 0 ? -2 : bufread);
- }
- if (bufread == 0) {
- if (total <= 0) {
- return -2;
- }
- break;
+ if (bufread <= 0) { /* An error, return false */
+ return (total > 0 ? -2 : bufread);
}
- bufread = read(tarhandle, &ltarbuf[total], bufsiz - total);
- total += bufread;
+
}
DEBUG(5, ("Total bytes read ... %i\n", total));
@@ -981,27 +968,24 @@ static int skip_file(int skipsize)
return(True);
}
-/*************************************************************
- Get a file from the tar file and store it.
- When this is called, tarbuf already contains the first
- file block. This is a bit broken & needs fixing.
-**************************************************************/
-
+/* We get a file from the tar file and store it */
static int get_file(file_info2 finfo)
{
+ int fsize = finfo.size;
int fnum = -1, pos = 0, dsize = 0, rsize = 0, bpos = 0;
- DEBUG(5, ("get_file: file: %s, size %i\n", finfo.name, (int)finfo.size));
+ DEBUG(5, ("get_file: file: %s, size %i\n", finfo.name, fsize));
if (ensurepath(finfo.name) &&
- (fnum=cli_open(cli, finfo.name, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) == -1) {
+ (fnum=cli_open(cli, finfo.name, O_WRONLY|O_CREAT|O_TRUNC, DENY_NONE)) == -1)
+ {
DEBUG(0, ("abandoning restore\n"));
return(False);
- }
+ }
/* read the blocks from the tar file and write to the remote file */
- rsize = finfo.size; /* This is how much to write */
+ rsize = fsize; /* This is how much to write */
while (rsize > 0) {
@@ -1011,7 +995,7 @@ static int get_file(file_info2 finfo)
dsize = MIN(dsize, rsize); /* Should be only what is left */
DEBUG(5, ("writing %i bytes, bpos = %i ...\n", dsize, bpos));
- if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize) != dsize) {
+ if (cli_write(cli, fnum, 0, buffer_p + bpos, pos, dsize, dsize) != dsize) {
DEBUG(0, ("Error writing remote file\n"));
return 0;
}
@@ -1039,23 +1023,17 @@ static int get_file(file_info2 finfo)
}
- /*
- * Bugfix from Bob Boehmer <boehmer@worldnet.att.net>.
- * If the file being extracted is an exact multiple of
- * TBLOCK bytes then we don't want to extract the next
- * block from the tarfile here, as it will be done in
- * the caller of get_file().
- */
-
- while (((rsize != 0) && (dsize >= TBLOCK)) ||
- ((rsize == 0) && (dsize > TBLOCK))) {
+ while (dsize >= TBLOCK) {
if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
+
DEBUG(0, ("Empty file, short tar file, or read error: %s\n", strerror(errno)));
return False;
+
}
dsize -= TBLOCK;
+
}
bpos = dsize;
@@ -1082,7 +1060,7 @@ static int get_file(file_info2 finfo)
ntarf++;
- DEBUG(0, ("restore tar file %s of size %d bytes\n", finfo.name, (int)finfo.size));
+ DEBUG(0, ("restore tar file %s of size %d bytes\n", finfo.name, finfo.size));
return(True);
}
@@ -1093,7 +1071,7 @@ static int get_file(file_info2 finfo)
static int get_dir(file_info2 finfo)
{
- DEBUG(0, ("restore directory %s\n", finfo.name));
+ DEBUG(5, ("Creating directory: %s\n", finfo.name));
if (!ensurepath(finfo.name)) {
@@ -1101,8 +1079,6 @@ static int get_dir(file_info2 finfo)
return(False);
}
-
- ntarf++;
return(True);
}
@@ -1118,12 +1094,12 @@ static char * get_longfilename(file_info2 finfo)
BOOL first = True;
DEBUG(5, ("Restoring a long file name: %s\n", finfo.name));
- DEBUG(5, ("Len = %d\n", (int)finfo.size));
+ DEBUG(5, ("Len = %i\n", finfo.size));
if (longname == NULL) {
DEBUG(0, ("could not allocate buffer of size %d for longname\n",
- (int)(finfo.size + strlen(cur_dir) + 2)));
+ finfo.size + strlen(cur_dir) + 2));
return(NULL);
}
@@ -1205,7 +1181,7 @@ static void do_tarput(void)
return;
case 0: /* chksum is zero - looks like an EOF */
- DEBUG(0, ("tar: restored %d files and directories\n", ntarf));
+ DEBUG(0, ("total of %d tar files restored to share\n", ntarf));
return; /* Hmmm, bad here ... */
default:
@@ -1253,14 +1229,10 @@ static void do_tarput(void)
case '0': /* Should use symbolic names--FIXME */
- /*
- * Skip to the next block first, so we can get the file, FIXME, should
- * be in get_file ...
- * The 'finfo.size != 0' fix is from Bob Boehmer <boehmer@worldnet.att.net>
- * Fixes bug where file size in tarfile is zero.
- */
+ /* Skip to the next block first, so we can get the file, FIXME, should
+ be in get_file ... */
- if ((finfo.size != 0) && next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
+ if (next_block(tarbuf, &buffer_p, tbufsiz) <=0) {
DEBUG(0, ("Short file, bailing out...\n"));
return;
}
@@ -1514,7 +1486,7 @@ int process_tar(void)
close(tarhandle);
free(tarbuf);
- DEBUG(0, ("tar: dumped %d files and directories\n", ntarf));
+ DEBUG(0, ("tar: dumped %d tar files\n", ntarf));
DEBUG(0, ("Total bytes written: %.0f\n", (double)ttarf));
break;
}
diff --git a/source/client/smbmnt.c b/source/client/smbmnt.c
index b7e30c3967f..fa3cacb8640 100644
--- a/source/client/smbmnt.c
+++ b/source/client/smbmnt.c
@@ -1,8 +1,7 @@
/*
- * smbmnt.c
+ * smbmount.c
*
* Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke
- * extensively modified by Tridge
*
*/
@@ -24,24 +23,27 @@
#include <linux/fs.h>
#endif
-static uid_t mount_uid;
-static gid_t mount_gid;
-static int mount_ro;
-static unsigned mount_fmask;
-static unsigned mount_dmask;
-static int user_mount;
+static char *progname;
+
+
+static void
+usage(void)
+{
+ printf("usage: %s mount-point [options]\n", progname);
+ printf("Try `%s -h' for more information\n", progname);
+}
static void
help(void)
{
printf("\n");
- printf("usage: smbmnt mount-point [options]\n");
- printf("-s share share name on server\n"
- "-r mount read-only\n"
- "-u uid mount as uid\n"
- "-g gid mount as gid\n"
- "-f mask permission mask for files\n"
- "-d mask permission mask for directories\n"
+ printf("usage: %s mount-point [options]\n", progname);
+ printf("-u uid uid the mounted files get\n"
+ "-g gid gid the mounted files get\n"
+ "-f mode permission the files get (octal notation)\n"
+ "-d mode permission the dirs get (octal notation)\n"
+ "-P pid connection handler's pid\n\n"
+ "-s share share name on server\n\n"
"-h print this help text\n");
}
@@ -49,32 +51,55 @@ static int
parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share)
{
int opt;
+ struct passwd *pwd;
+ struct group *grp;
- while ((opt = getopt (argc, argv, "s:u:g:rf:d:")) != EOF)
+ while ((opt = getopt (argc, argv, "u:g:f:d:s:")) != EOF)
{
switch (opt)
{
- case 's':
- *share = optarg;
- break;
case 'u':
- if (!user_mount) {
- mount_uid = strtol(optarg, NULL, 0);
- }
+ if (isdigit(optarg[0]))
+ {
+ data->uid = atoi(optarg);
+ }
+ else
+ {
+ pwd = getpwnam(optarg);
+ if (pwd == NULL)
+ {
+ fprintf(stderr, "Unknown user: %s\n",
+ optarg);
+ return 1;
+ }
+ data->uid = pwd->pw_uid;
+ }
break;
case 'g':
- if (!user_mount) {
- mount_gid = strtol(optarg, NULL, 0);
- }
- break;
- case 'r':
- mount_ro = 1;
+ if (isdigit(optarg[0]))
+ {
+ data->gid = atoi(optarg);
+ }
+ else
+ {
+ grp = getgrnam(optarg);
+ if (grp == NULL)
+ {
+ fprintf(stderr, "Unknown group: %s\n",
+ optarg);
+ return 1;
+ }
+ data->gid = grp->gr_gid;
+ }
break;
case 'f':
- mount_fmask = strtol(optarg, NULL, 8);
+ data->file_mode = strtol(optarg, NULL, 8);
break;
case 'd':
- mount_dmask = strtol(optarg, NULL, 8);
+ data->dir_mode = strtol(optarg, NULL, 8);
+ break;
+ case 's':
+ *share = optarg;
break;
default:
return -1;
@@ -89,39 +114,32 @@ fullpath(const char *p)
{
char path[MAXPATHLEN];
- if (strlen(p) > MAXPATHLEN-1) {
+ if (strlen(p) > MAXPATHLEN-1)
+ {
return NULL;
}
- if (realpath(p, path) == NULL) {
- fprintf(stderr,"Failed to find real path for mount point\n");
- exit(1);
+ if (realpath(p, path) == NULL)
+ {
+ return strdup(p);
}
return strdup(path);
}
-/* Check whether user is allowed to mount on the specified mount point. If it's
- OK then we change into that directory - this prevents race conditions */
-static int mount_ok(char *mount_point)
+/* Check whether user is allowed to mount on the specified mount point */
+static int
+mount_ok(SMB_STRUCT_STAT *st)
{
- SMB_STRUCT_STAT st;
-
- if (chdir(mount_point) != 0) {
- return -1;
- }
-
- if (sys_stat(".", &st) != 0) {
- return -1;
- }
-
- if (!S_ISDIR(st.st_mode)) {
+ if (!S_ISDIR(st->st_mode))
+ {
errno = ENOTDIR;
return -1;
}
-
- if ((getuid() != 0) &&
- ((getuid() != st.st_uid) ||
- ((st.st_mode & S_IRWXU) != S_IRWXU))) {
+
+ if ( (getuid() != 0)
+ && ( (getuid() != st->st_uid)
+ || ((st->st_mode & S_IRWXU) != S_IRWXU)))
+ {
errno = EPERM;
return -1;
}
@@ -129,48 +147,53 @@ static int mount_ok(char *mount_point)
return 0;
}
- int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
{
char *mount_point, *share_name = NULL;
FILE *mtab;
- int fd;
+ int fd, um;
unsigned int flags;
struct smb_mount_data data;
+ SMB_STRUCT_STAT st;
struct mntent ment;
- memset(&data, 0, sizeof(struct smb_mount_data));
+ progname = argv[0];
- if (argc < 2) {
- help();
- exit(1);
- }
+ memset(&data, 0, sizeof(struct smb_mount_data));
- if (argv[1][0] == '-') {
+ if ( (argc == 2)
+ && (argv[1][0] == '-')
+ && (argv[1][1] == 'h')
+ && (argv[1][2] == '\0'))
+ {
help();
- exit(1);
- }
-
- if (getuid() != 0) {
- user_mount = 1;
+ return 0;
}
if (geteuid() != 0) {
- fprintf(stderr, "smbmnt must be installed suid root for direct user mounts (%d,%d)\n", getuid(), geteuid());
+ fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
- mount_uid = getuid();
- mount_gid = getgid();
- mount_fmask = umask(0);
- umask(mount_fmask);
- mount_fmask = ~mount_fmask;
+ if (argc < 2)
+ {
+ usage();
+ return 1;
+ }
- mount_point = fullpath(argv[1]);
+ mount_point = argv[1];
argv += 1;
argc -= 1;
- if (mount_ok(mount_point) != 0) {
+ if (sys_stat(mount_point, &st) == -1) {
+ fprintf(stderr, "could not find mount point %s: %s\n",
+ mount_point, strerror(errno));
+ exit(1);
+ }
+
+ if (mount_ok(&st) != 0) {
fprintf(stderr, "cannot mount on %s: %s\n",
mount_point, strerror(errno));
exit(1);
@@ -181,17 +204,19 @@ static int mount_ok(char *mount_point)
/* getuid() gives us the real uid, who may umount the fs */
data.mounted_uid = getuid();
+ data.uid = getuid();
+ data.gid = getgid();
+ um = umask(0);
+ umask(um);
+ data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & ~um;
+ data.dir_mode = 0;
+
if (parse_args(argc, argv, &data, &share_name) != 0) {
- help();
+ usage();
return -1;
}
- data.uid = mount_uid;
- data.gid = mount_gid;
- data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_fmask;
- data.dir_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_dmask;
-
- if (mount_dmask == 0) {
+ if (data.dir_mode == 0) {
data.dir_mode = data.file_mode;
if ((data.dir_mode & S_IRUSR) != 0)
data.dir_mode |= S_IXUSR;
@@ -203,23 +228,15 @@ static int mount_ok(char *mount_point)
flags = MS_MGC_VAL;
- if (mount_ro) flags |= MS_RDONLY;
-
- if (mount(share_name, ".", "smbfs", flags, (char *)&data) < 0)
+ if (mount(share_name, mount_point, "smbfs", flags, (char *)&data) < 0)
{
- switch (errno) {
- case ENODEV:
- fprintf(stderr, "ERROR: smbfs filesystem not supported by the kernel\n");
- break;
- default:
- perror("mount error");
- }
- fprintf(stderr, "Please refer to the smbmnt(8) manual page\n");
+ perror("mount error");
+ printf("Please refer to the smbmnt(8) manual page\n");
return -1;
}
ment.mnt_fsname = share_name ? share_name : "none";
- ment.mnt_dir = mount_point;
+ ment.mnt_dir = fullpath(mount_point);
ment.mnt_type = "smbfs";
ment.mnt_opts = "";
ment.mnt_freq = 0;
diff --git a/source/client/smbmount.c b/source/client/smbmount.c
index 18af824c1fd..3fad6674fb8 100644
--- a/source/client/smbmount.c
+++ b/source/client/smbmount.c
@@ -1,8 +1,8 @@
/*
Unix SMB/Netbios implementation.
- Version 2.0.
- SMBFS mount program
- Copyright (C) Andrew Tridgell 1999
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,62 +21,193 @@
#define NO_SYSLOG
+#include <linux/version.h>
+#define LVERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
+#if LINUX_VERSION_CODE < LVERSION(2,1,70)
+#error this code will only compile on versions of linux after 2.1.70
+#endif
+
#include "includes.h"
#include <mntent.h>
+
#include <asm/types.h>
#include <linux/smb_fs.h>
+static struct smb_conn_opt conn_options;
-/* Uncomment this to allow debug the mount.smb daemon */
+#ifndef REGISTER
+#define REGISTER 0
+#endif
+
+/* Uncomment this to allow debug the smbmount daemon */
/* WARNING! This option is incompatible with autofs/automount because
it does not close the stdout pipe back to the automount
process, which automount depends on. This will cause automount
to hang! Use with caution! */
-/* #define SMBFS_DEBUG 1 */
-
+/* #define SMBFS_DEBUG 1 */
+
+pstring cur_dir = "\\";
+pstring cd_path = "";
+extern pstring service;
+extern pstring desthost;
+extern pstring global_myname;
+extern pstring myhostname;
+extern pstring password;
+extern pstring smb_login_passwd;
+extern pstring username;
+extern pstring workgroup;
+char *cmdstr="";
+extern BOOL got_pass;
+extern BOOL connect_as_printer;
+extern BOOL connect_as_ipc;
extern struct in_addr ipzero;
-extern int DEBUGLEVEL;
-extern BOOL in_client;
+extern BOOL doencrypt;
+
extern pstring user_socket_options;
-static pstring my_netbios_name;
-static pstring password;
-static pstring username;
-static pstring workgroup;
-static pstring mpoint;
-static pstring service;
-
-static struct in_addr dest_ip;
-static BOOL have_ip;
-static int smb_port = 139;
-static BOOL got_pass;
-static uid_t mount_uid;
-static gid_t mount_gid;
-static int mount_ro;
-static unsigned mount_fmask;
-static unsigned mount_dmask;
-
-static void usage(void);
-
-static void exit_parent(int sig)
+/* 30 second timeout on most commands */
+#define CLIENT_TIMEOUT (30*1000)
+#define SHORT_TIMEOUT (5*1000)
+
+/* value for unused fid field in trans2 secondary request */
+#define FID_UNUSED (0xFFFF)
+
+extern int name_type;
+
+extern int max_protocol;
+int port = SMB_PORT;
+
+time_t newer_than = 0;
+int archive_level = 0;
+
+extern pstring debugf;
+extern int DEBUGLEVEL;
+
+BOOL translation = False;
+
+extern uint16 cnum;
+extern uint16 mid;
+extern uint16 pid;
+extern uint16 vuid;
+
+extern BOOL have_ip;
+extern int max_xmit;
+
+/* clitar bits insert */
+extern int blocksize;
+extern BOOL tar_inc;
+extern BOOL tar_reset;
+/* clitar bits end */
+
+
+mode_t myumask = 0755;
+
+extern pstring scope;
+
+BOOL prompt = True;
+
+int printmode = 1;
+
+BOOL recurse = False;
+BOOL lowercase = False;
+
+struct in_addr dest_ip;
+
+#define SEPARATORS " \t\n\r"
+
+BOOL abort_mget = True;
+
+extern int Protocol;
+
+extern BOOL readbraw_supported ;
+extern BOOL writebraw_supported;
+
+pstring fileselection = "";
+
+extern file_info def_finfo;
+
+/* timing globals */
+int get_total_size = 0;
+int get_total_time_ms = 0;
+int put_total_size = 0;
+int put_total_time_ms = 0;
+
+/* totals globals */
+int dir_total = 0;
+
+extern int Client;
+
+#define USENMB
+
+#define CNV_LANG(s) dos_to_unix(s,False)
+#define CNV_INPUT(s) unix_to_dos(s,True)
+
+/****************************************************************************
+check for existance of a dir
+****************************************************************************/
+static BOOL chkpath(char *path,BOOL report)
+{
+ fstring path2;
+ pstring inbuf,outbuf;
+ char *p;
+
+ fstrcpy(path2,path);
+ trim_string(path2,NULL,"\\");
+ if (!*path2) *path2 = '\\';
+
+ memset(outbuf,'\0',smb_size);
+ set_message(outbuf,0,4 + strlen(path2),True);
+ SCVAL(outbuf,smb_com,SMBchkpth);
+ SSVAL(outbuf,smb_tid,cnum);
+ cli_setup_pkt(outbuf);
+
+ p = smb_buf(outbuf);
+ *p++ = 4;
+ fstrcpy(p,path2);
+
+#if 0
+ {
+ /* this little bit of code can be used to extract NT error codes.
+ Just feed a bunch of "cd foo" commands to smbclient then watch
+ in netmon (tridge) */
+ static int code=0;
+ SIVAL(outbuf, smb_rcls, code | 0xC0000000);
+ SSVAL(outbuf, smb_flg2, SVAL(outbuf, smb_flg2) | (1<<14));
+ code++;
+ }
+#endif
+
+ send_smb(Client,outbuf);
+ client_receive_smb(Client,inbuf,CLIENT_TIMEOUT);
+
+ if (report && CVAL(inbuf,smb_rcls) != 0)
+ DEBUG(2,("chkpath: %s\n",smb_errstr(inbuf)));
+
+ return(CVAL(inbuf,smb_rcls) == 0);
+}
+
+static void
+exit_parent( int sig )
{
/* parent simply exits when child says go... */
exit(0);
}
-static void daemonize(void)
+static void
+daemonize(void)
{
int j, status;
pid_t child_pid;
signal( SIGTERM, exit_parent );
- if ((child_pid = fork()) < 0) {
- fprintf(stderr,"could not fork\n");
+ if ((child_pid = fork()) < 0)
+ {
+ DEBUG(0, ("could not fork\n"));
}
-
- if (child_pid > 0) {
+ if (child_pid > 0)
+ {
while( 1 ) {
j = waitpid( child_pid, &status, 0 );
if( j < 0 ) {
@@ -90,127 +221,84 @@ static void daemonize(void)
/* If we get here - the child exited with some error status */
exit(status);
}
+ /* Programmers Note:
+ Danger Will Robinson! Danger!
+ There use to be a call to setsid() here. This does no
+ harm to normal mount operations, but it broke automounting.
+ The setsid call has been moved to just before the child
+ sends the SIGTERM to the parent. All of our deadly embrace
+ conditions with autofs will have been cleared by then...
+ -mhw-
+ */
signal( SIGTERM, SIG_DFL );
chdir("/");
}
-static void close_our_files(int client_fd)
+static void
+close_our_files(void)
{
int i;
- for (i = 0; i < 256; i++) {
- if (i == client_fd) continue;
+ for (i = 0; i < NR_OPEN; i++) {
+ if (i == Client) {
+ continue;
+ }
close(i);
}
}
-static void usr1_handler(int x)
+static void
+usr1_handler(int x)
{
return;
}
-
-/*****************************************************
-return a connection to a server
-*******************************************************/
-static struct cli_state *do_connection(char *service)
+/*
+ * Send a login and store the connection options. This is a separate
+ * function to keep clientutil.c independent of linux kernel changes.
+ */
+static BOOL mount_send_login(char *inbuf, char *outbuf)
{
- struct cli_state *c;
- struct nmb_name called, calling;
- char *server_n;
- struct in_addr ip;
- extern struct in_addr ipzero;
- pstring server;
- char *share;
-
- if (service[0] != '\\' || service[1] != '\\') {
- usage();
- exit(1);
- }
-
- pstrcpy(server, service+2);
- share = strchr(server,'\\');
- if (!share) {
- usage();
- exit(1);
- }
- *share = 0;
- share++;
-
- server_n = server;
-
- ip = ipzero;
-
- make_nmb_name(&calling, my_netbios_name, 0x0);
- make_nmb_name(&called , server, 0x20);
-
- again:
- ip = ipzero;
- if (have_ip) ip = dest_ip;
-
- /* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || (cli_set_port(c, smb_port) == 0) ||
- !cli_connect(c, server_n, &ip)) {
- fprintf(stderr,"Connection to %s failed\n", server_n);
- return NULL;
- }
-
- if (!cli_session_request(c, &calling, &called)) {
- fprintf(stderr, "session request to %s failed\n", called.name);
- cli_shutdown(c);
- if (strcmp(called.name, "*SMBSERVER")) {
- make_nmb_name(&called , "*SMBSERVER", 0x20);
- goto again;
- }
- return NULL;
- }
-
- DEBUG(4,(" session request ok\n"));
-
- if (!cli_negprot(c)) {
- fprintf(stderr, "protocol negotiation failed\n");
- cli_shutdown(c);
- return NULL;
- }
-
- if (!got_pass) {
- char *pass = getpass("Password: ");
- if (pass) {
- pstrcpy(password, pass);
- }
- }
-
- if (!cli_session_setup(c, username,
- password, strlen(password),
- password, strlen(password),
- workgroup)) {
- fprintf(stderr, "session setup failed: %s\n", cli_errstr(c));
- return NULL;
- }
-
- DEBUG(4,(" session setup ok\n"));
-
- if (!cli_send_tconX(c, share, "?????",
- password, strlen(password)+1)) {
- fprintf(stderr,"tree connect failed: %s\n", cli_errstr(c));
- cli_shutdown(c);
- return NULL;
- }
-
- DEBUG(4,(" tconx ok\n"));
-
- got_pass = True;
+ struct connection_options opt;
+ int res = cli_send_login(inbuf, outbuf, True, True, &opt);
+
+ if (!res)
+ return res;
+
+ if( !got_pass ) {
+ /* Ok... If we got this thing connected and got_pass is false,
+ that means that the client util prompted for a password and
+ got a good one... We need to cache this in password and set
+ got_pass for future retries. We don't want to prompt for the
+ $#@$#$ password everytime the network blinks!
+ */
- return c;
+ pstrcpy(password,smb_login_passwd);
+ got_pass = True;
+ }
+ conn_options.protocol = opt.protocol;
+ conn_options.case_handling = CASE_LOWER;
+ conn_options.max_xmit = opt.max_xmit;
+ conn_options.server_uid = opt.server_vuid;
+ conn_options.tid = opt.tid;
+ conn_options.secmode = opt.sec_mode;
+ conn_options.maxmux = opt.max_mux;
+ conn_options.maxvcs = opt.max_vcs;
+ conn_options.rawmode = opt.rawmode;
+ conn_options.sesskey = opt.sesskey;
+ conn_options.maxraw = opt.maxraw;
+ conn_options.capabilities = opt.capabilities;
+ conn_options.serverzone = opt.serverzone;
+
+ return True;
}
-
/****************************************************************************
unmount smbfs (this is a bailout routine to clean up if a reconnect fails)
Code blatently stolen from smbumount.c
-mhw-
****************************************************************************/
-static void smb_umount(char *mount_point)
+static void smb_umount( char *mount_point )
{
int fd;
struct mntent *mnt;
@@ -226,29 +314,29 @@ static void smb_umount(char *mount_point)
the lights to exit anyways...
*/
if (umount(mount_point) != 0) {
- fprintf(stderr, "Could not umount %s: %s\n",
- mount_point, strerror(errno));
+ DEBUG(0, ("Could not umount %s: %s\n",
+ mount_point, strerror(errno)));
return;
}
- if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) {
- fprintf(stderr, "Can't get "MOUNTED"~ lock file");
+ if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
+ {
+ DEBUG(0, ("Can't get "MOUNTED"~ lock file"));
return;
}
-
close(fd);
if ((mtab = setmntent(MOUNTED, "r")) == NULL) {
- fprintf(stderr, "Can't open " MOUNTED ": %s\n",
- strerror(errno));
+ DEBUG(0, ("Can't open " MOUNTED ": %s\n",
+ strerror(errno)));
return;
}
#define MOUNTED_TMP MOUNTED".tmp"
if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) {
- fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n",
- strerror(errno));
+ DEBUG(0, ("Can't open " MOUNTED_TMP ": %s\n",
+ strerror(errno)));
endmntent(mtab);
return;
}
@@ -262,23 +350,26 @@ static void smb_umount(char *mount_point)
endmntent(mtab);
if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
- fprintf(stderr, "Error changing mode of %s: %s\n",
- MOUNTED_TMP, strerror(errno));
+ DEBUG(0, ("Error changing mode of %s: %s\n",
+ MOUNTED_TMP, strerror(errno)));
return;
}
endmntent(new_mtab);
if (rename(MOUNTED_TMP, MOUNTED) < 0) {
- fprintf(stderr, "Cannot rename %s to %s: %s\n",
- MOUNTED, MOUNTED_TMP, strerror(errno));
+ DEBUG(0, ("Cannot rename %s to %s: %s\n",
+ MOUNTED, MOUNTED_TMP, strerror(errno)));
return;
}
- if (unlink(MOUNTED"~") == -1) {
- fprintf(stderr, "Can't remove "MOUNTED"~");
+ if (unlink(MOUNTED"~") == -1)
+ {
+ DEBUG(0, ("Can't remove "MOUNTED"~"));
return;
}
+
+ return;
}
@@ -288,174 +379,136 @@ static void smb_umount(char *mount_point)
* not exit after open_sockets() or send_login() errors,
* as the smbfs mount would then have no way to recover.
*/
-static void send_fs_socket(char *service, char *mount_point, struct cli_state *c)
+static void
+send_fs_socket(char *mount_point, char *inbuf, char *outbuf)
{
int fd, closed = 0, res = 1;
- pid_t parentpid = getppid();
- struct smb_conn_opt conn_options;
- memset(&conn_options, 0, sizeof(conn_options));
+ pid_t parentpid = getppid();
- while (1) {
- if ((fd = open(mount_point, O_RDONLY)) < 0) {
- fprintf(stderr, "mount.smbfs: can't open %s\n", mount_point);
+ while (1)
+ {
+ if ((fd = open(mount_point, O_RDONLY)) < 0)
+ {
+ DEBUG(0, ("smbmount: can't open %s\n", mount_point));
break;
}
- conn_options.fd = c->fd;
- conn_options.protocol = c->protocol;
- conn_options.case_handling = SMB_CASE_DEFAULT;
- conn_options.max_xmit = c->max_xmit;
- conn_options.server_uid = c->vuid;
- conn_options.tid = c->cnum;
- conn_options.secmode = c->sec_mode;
- conn_options.rawmode = 0;
- conn_options.sesskey = c->sesskey;
- conn_options.maxraw = 0;
- conn_options.capabilities = c->capabilities;
- conn_options.serverzone = c->serverzone/60;
-
+ /*
+ * Call the ioctl even if we couldn't get a socket ...
+ * there's no point in making smbfs wait for a timeout.
+ */
+ conn_options.fd = -1;
+ if (res)
+ conn_options.fd = Client;
res = ioctl(fd, SMB_IOC_NEWCONN, &conn_options);
- if (res != 0) {
- fprintf(stderr, "mount.smbfs: ioctl failed, res=%d\n", res);
- break;
+ if (res != 0)
+ {
+ DEBUG(0, ("smbmount: ioctl failed, res=%d\n", res));
}
- if (parentpid) {
+ if( parentpid ) {
/* Ok... We are going to kill the parent. Now
is the time to break the process group... */
setsid();
/* Send a signal to the parent to terminate */
- kill(parentpid, SIGTERM);
+ kill( parentpid, SIGTERM );
parentpid = 0;
}
+ close_sockets();
close(fd);
-
+ /*
+ * Close all open files if we haven't done so yet.
+ */
#ifndef SMBFS_DEBUG
- /* Close all open files if we haven't done so yet. */
- if (!closed) {
- extern FILE *dbf;
+ if (!closed)
+ {
closed = 1;
- dbf = NULL;
- close_our_files(c?c->fd:-1);
+ close_our_files();
}
#endif
- /* Wait for a signal from smbfs ... */
+ /*
+ * Wait for a signal from smbfs ...
+ */
CatchSignal(SIGUSR1, &usr1_handler);
pause();
-#ifdef SMBFS_DEBUG
- DEBUG(2,("mount.smbfs: got signal, getting new socket\n"));
-#endif
- c = do_connection(service);
- }
+ DEBUG(0, ("smbmount: got signal, getting new socket\n"));
- smb_umount(mount_point);
- DEBUG(2,("mount.smbfs: exit\n"));
- exit(1);
-}
+ res = cli_open_sockets(port);
+ if (!res)
+ {
+ DEBUG(0, ("smbmount: can't open sockets\n"));
+ continue;
+ }
-/*********************************************************
-a strdup with exit
-**********************************************************/
-static char *xstrdup(char *s)
-{
- s = strdup(s);
- if (!s) {
- fprintf(stderr,"out of memory\n");
- exit(1);
+ res = mount_send_login(inbuf, outbuf);
+ if (!res)
+ {
+ DEBUG(0, ("smbmount: login failed\n"));
+ break;
+ }
}
- return s;
+ smb_umount( mount_point );
+ DEBUG(0, ("smbmount: exit\n"));
+ exit(1);
}
-
/****************************************************************************
mount smbfs
****************************************************************************/
-static void init_mount(void)
+static void cmd_mount(char *inbuf,char *outbuf)
{
+ pstring mpoint;
+ pstring share_name;
+ pstring mount_command;
+ fstring buf;
+ int retval;
char mount_point[MAXPATHLEN+1];
- pstring tmp;
- pstring svc2;
- struct cli_state *c;
- char *args[20];
- int i, status;
-
- if (realpath(mpoint, mount_point) == NULL) {
- fprintf(stderr, "Could not resolve mount point %s\n", mpoint);
+
+ if (!next_token(NULL, mpoint, NULL, sizeof(mpoint)))
+ {
+ DEBUG(0,("You must supply a mount point\n"));
return;
}
+ memset(mount_point, 0, sizeof(mount_point));
- c = do_connection(service);
- if (!c) {
- fprintf(stderr,"SMB connection failed\n");
- exit(1);
+ if (realpath(mpoint, mount_point) == NULL)
+ {
+ DEBUG(0, ("Could not resolve mount point\n"));
+ return;
}
/*
- Set up to return as a daemon child and wait in the parent
- until the child say it's ready...
- */
- daemonize();
-
- pstrcpy(svc2, service);
- string_replace(svc2, '\\','/');
- string_replace(svc2, ' ','_');
-
- memset(args, 0, sizeof(args[0])*20);
-
- i=0;
- args[i++] = "smbmnt";
+ * Build the service name to report on the Unix side,
+ * converting '\' to '/' and ' ' to '_'.
+ */
+ pstrcpy(share_name, service);
+ string_replace(share_name, '\\', '/');
+ string_replace(share_name, ' ', '_');
- args[i++] = mount_point;
- args[i++] = "-s";
- args[i++] = svc2;
+ slprintf(mount_command, sizeof(mount_command)-1,"smbmnt %s -s %s", mount_point, share_name);
- if (mount_ro) {
- args[i++] = "-r";
- }
- if (mount_uid) {
- slprintf(tmp, sizeof(tmp), "%d", mount_uid);
- args[i++] = "-u";
- args[i++] = xstrdup(tmp);
- }
- if (mount_gid) {
- slprintf(tmp, sizeof(tmp), "%d", mount_gid);
- args[i++] = "-g";
- args[i++] = xstrdup(tmp);
- }
- if (mount_fmask) {
- slprintf(tmp, sizeof(tmp), "0%o", mount_fmask);
- args[i++] = "-f";
- args[i++] = xstrdup(tmp);
- }
- if (mount_dmask) {
- slprintf(tmp, sizeof(tmp), "0%o", mount_dmask);
- args[i++] = "-d";
- args[i++] = xstrdup(tmp);
+ while(next_token(NULL, buf, NULL, sizeof(buf)))
+ {
+ pstrcat(mount_command, " ");
+ pstrcat(mount_command, buf);
}
- if (fork() == 0) {
- if (file_exist(BINDIR "/smbmnt", NULL)) {
- execv(BINDIR "/smbmnt", args);
- fprintf(stderr,"execv of %s failed. Error was %s.", BINDIR "/smbmnt", strerror(errno));
- } else {
- execvp("smbmnt", args);
- fprintf(stderr,"execvp of smbmnt failed. Error was %s.", strerror(errno) );
- }
- exit(1);
- }
+ DEBUG(3, ("mount command: %s\n", mount_command));
- if (waitpid(-1, &status, 0) == -1) {
- fprintf(stderr,"waitpid failed: Error was %s", strerror(errno) );
- /* FIXME: do some proper error handling */
- exit(1);
- }
+ /*
+ Set up to return as a daemon child and wait in the parent
+ until the child say it's ready...
+ */
+ daemonize();
- if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
- fprintf(stderr,"smbmnt failed: %d\n", WEXITSTATUS(status));
+ if ((retval = system(mount_command)) != 0)
+ {
+ DEBUG(0,("mount failed\n"));
+ exit(1);
}
/* Ok... This is the rubicon for that mount point... At any point
@@ -463,158 +516,241 @@ static void init_mount(void)
for any reason, we will have to unmount the mount point. There
is no exit from the next call...
*/
- send_fs_socket(service, mount_point, c);
+ send_fs_socket(mount_point, inbuf, outbuf);
}
+/* This defines the commands supported by this client */
+struct
+{
+ char *name;
+ void (*fn)();
+ char *description;
+} commands[] =
+{
+ {"mount", cmd_mount, "<mount-point options> mount an smbfs file system"},
+ {"",NULL,NULL}
+};
+
+
+/*******************************************************************
+ lookup a command string in the list of commands, including
+ abbreviations
+ ******************************************************************/
+static int process_tok(fstring tok)
+{
+ int i = 0, matches = 0;
+ int cmd=0;
+ int tok_len = strlen(tok);
+
+ while (commands[i].fn != NULL)
+ {
+ if (strequal(commands[i].name,tok))
+ {
+ matches = 1;
+ cmd = i;
+ break;
+ }
+ else if (strnequal(commands[i].name, tok, tok_len))
+ {
+ matches++;
+ cmd = i;
+ }
+ i++;
+ }
+
+ if (matches == 0)
+ return(-1);
+ else if (matches == 1)
+ return(cmd);
+ else
+ return(-2);
+}
+
/****************************************************************************
-usage on the program
+help
****************************************************************************/
-static void usage(void)
+void cmd_help(char *dum_in, char *dum_out)
{
- printf("Usage: mount.smbfs service mountpoint [-o options,...]\n");
-
- printf("Version %s\n\n",VERSION);
-
- printf(
-"Options:
- username=<arg> SMB username
- password=<arg> SMB password
- netbiosname=<arg> source NetBIOS name
- uid=<arg> mount uid or username
- gid=<arg> mount gid or groupname
- port=<arg> remote SMB port number
- fmask=<arg> file umask
- dmask=<arg> directory umask
- debug=<arg> debug level
- ip=<arg> destination host or IP address
- workgroup=<arg> workgroup on destination
- sockopt=<arg> TCP socket options
- scope=<arg> NetBIOS scope
- guest don't prompt for a password
- ro mount read-only
- rw mount read-write
-
-This command is designed to be run from within /bin/mount by giving
-the option '-t smbfs'. For example:
- mount -t smbfs -o username=tridge,password=foobar //fjall/test /data/test
-");
+ int i=0,j;
+ fstring buf;
+
+ if (next_token(NULL,buf,NULL,sizeof(buf)))
+ {
+ if ((i = process_tok(buf)) >= 0)
+ DEBUG(0,("HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description));
+ }
+ else
+ while (commands[i].description)
+ {
+ for (j=0; commands[i].description && (j<5); j++) {
+ DEBUG(0,("%-15s",commands[i].name));
+ i++;
+ }
+ DEBUG(0,("\n"));
+ }
}
-
/****************************************************************************
- Argument parsing for mount.smbfs interface
- mount will call us like this:
- mount.smbfs device mountpoint -o <options>
-
- <options> is never empty, containing at least rw or ro
- ****************************************************************************/
-static void parse_mount_smb(int argc, char **argv)
+wait for keyboard activity, swallowing network packets
+****************************************************************************/
+static void wait_keyboard(char *buffer)
{
- int opt;
- char *opts;
- char *opteq;
- extern char *optarg;
- int val;
- extern pstring global_scope;
-
- if (argc < 2 || argv[1][0] == '-') {
- usage();
- exit(1);
- }
-
- pstrcpy(service, argv[1]);
- pstrcpy(mpoint, argv[2]);
+ fd_set fds;
+ int selrtn;
+ struct timeval timeout;
+
+ while (1)
+ {
+ extern int Client;
+ FD_ZERO(&fds);
+ FD_SET(Client,&fds);
+ FD_SET(fileno(stdin),&fds);
+
+ timeout.tv_sec = 20;
+ timeout.tv_usec = 0;
+ selrtn = sys_select(MAX(Client,fileno(stdin))+1,&fds,NULL, &timeout);
+
+ if (FD_ISSET(fileno(stdin),&fds))
+ return;
+
+ /* We deliberately use receive_smb instead of
+ client_receive_smb as we want to receive
+ session keepalives and then drop them here.
+ */
+ if (FD_ISSET(Client,&fds))
+ receive_smb(Client,buffer,0);
+
+ chkpath("\\",False);
+ }
+}
- /* Convert any '/' characters in the service name to
- '\' characters */
- string_replace(service, '/','\\');
- argc -= 2;
- argv += 2;
- opt = getopt(argc, argv, "o:");
- if(opt != 'o') {
- return;
- }
+/****************************************************************************
+ process commands from the client
+****************************************************************************/
+static BOOL process(char *base_directory)
+{
+ extern FILE *dbf;
+ pstring line;
+ char *cmd;
- /*
- * option parsing from nfsmount.c (util-linux-2.9u)
- */
- for (opts = strtok(optarg, ","); opts; opts = strtok(NULL, ",")) {
- DEBUG(3, ("opts: %s\n", opts));
- if ((opteq = strchr(opts, '='))) {
- val = atoi(opteq + 1);
- *opteq = '\0';
-
- if (!strcmp(opts, "username") ||
- !strcmp(opts, "logon")) {
- char *lp;
- pstrcpy(username,opteq+1);
- if ((lp=strchr(username,'%'))) {
- *lp = 0;
- pstrcpy(password,lp+1);
- got_pass = True;
- memset(strchr(opteq+1,'%')+1,'X',strlen(password));
- }
- if ((lp=strchr(username,'/'))) {
- *lp = 0;
- pstrcpy(workgroup,lp+1);
- }
- } else if(!strcmp(opts, "passwd") ||
- !strcmp(opts, "password")) {
- pstrcpy(password,opteq+1);
- got_pass = True;
- memset(opteq+1,'X',strlen(password));
- } else if(!strcmp(opts, "netbiosname")) {
- pstrcpy(my_netbios_name,opteq+1);
- } else if(!strcmp(opts, "uid")) {
- mount_uid = nametouid(opteq+1);
- } else if(!strcmp(opts, "gid")) {
- mount_gid = nametogid(opteq+1);
- } else if(!strcmp(opts, "port")) {
- smb_port = val;
- } else if(!strcmp(opts, "fmask")) {
- mount_fmask = strtol(opteq+1, NULL, 8);
- } else if(!strcmp(opts, "dmask")) {
- mount_dmask = strtol(opteq+1, NULL, 8);
- } else if(!strcmp(opts, "debug")) {
- DEBUGLEVEL = val;
- } else if(!strcmp(opts, "ip")) {
- dest_ip = *interpret_addr2(opteq+1);
- if (zero_ip(dest_ip)) {
- fprintf(stderr,"Can't resolve address %s\n", opteq+1);
- exit(1);
- }
- have_ip = True;
- } else if(!strcmp(opts, "workgroup")) {
- pstrcpy(workgroup,opteq+1);
- } else if(!strcmp(opts, "sockopt")) {
- pstrcpy(user_socket_options,opteq+1);
- } else if(!strcmp(opts, "scope")) {
- pstrcpy(global_scope,opteq+1);
- } else {
- usage();
- exit(1);
- }
- } else {
- val = 1;
- if(!strcmp(opts, "nocaps")) {
- fprintf(stderr, "Unhandled option: %s\n", opteq+1);
- exit(1);
- } else if(!strcmp(opts, "guest")) {
- got_pass = True;
- } else if(!strcmp(opts, "rw")) {
- mount_ro = 0;
- } else if(!strcmp(opts, "ro")) {
- mount_ro = 1;
- }
- }
- }
+ char *InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+ char *OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if (!*service) {
- usage();
- exit(1);
- }
+ if ((InBuffer == NULL) || (OutBuffer == NULL))
+ return(False);
+
+ memset(OutBuffer,'\0',smb_size);
+
+ if (!mount_send_login(InBuffer,OutBuffer))
+ return(False);
+
+ cmd = cmdstr;
+ if (cmd[0] != '\0') while (cmd[0] != '\0')
+ {
+ char *p;
+ fstring tok;
+ int i;
+
+ if ((p = strchr(cmd, ';')) == 0)
+ {
+ strncpy(line, cmd, 999);
+ line[1000] = '\0';
+ cmd += strlen(cmd);
+ }
+ else
+ {
+ if (p - cmd > 999) p = cmd + 999;
+ strncpy(line, cmd, p - cmd);
+ line[p - cmd] = '\0';
+ cmd = p + 1;
+ }
+
+ /* input language code to internal one */
+ CNV_INPUT (line);
+
+ /* and get the first part of the command */
+ {
+ char *ptr = line;
+ if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
+ }
+
+ if ((i = process_tok(tok)) >= 0)
+ commands[i].fn(InBuffer,OutBuffer);
+ else if (i == -2)
+ DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
+ else
+ DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
+ }
+ else while (!feof(stdin))
+ {
+ fstring tok;
+ int i;
+
+ memset(OutBuffer,'\0',smb_size);
+
+ /* display a prompt */
+ DEBUG(0,("smb: %s> ", CNV_LANG(cur_dir)));
+ dbgflush();
+
+ wait_keyboard(InBuffer);
+
+ /* and get a response */
+ if (!fgets(line,1000,stdin))
+ break;
+
+ /* input language code to internal one */
+ CNV_INPUT (line);
+
+ /* special case - first char is ! */
+ if (*line == '!')
+ {
+ system(line + 1);
+ continue;
+ }
+
+ /* and get the first part of the command */
+ {
+ char *ptr = line;
+ if (!next_token(&ptr,tok,NULL,sizeof(tok))) continue;
+ }
+
+ if ((i = process_tok(tok)) >= 0)
+ commands[i].fn(InBuffer,OutBuffer);
+ else if (i == -2)
+ DEBUG(0,("%s: command abbreviation ambiguous\n",CNV_LANG(tok)));
+ else
+ DEBUG(0,("%s: command not found\n",CNV_LANG(tok)));
+ }
+
+ cli_send_logout(InBuffer,OutBuffer);
+ return(True);
+}
+
+/****************************************************************************
+usage on the program
+****************************************************************************/
+static void usage(char *pname)
+{
+ DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ",
+ pname));
+
+ DEBUG(0,("\nVersion %s\n",VERSION));
+ DEBUG(0,("\t-p port connect to the specified port\n"));
+ DEBUG(0,("\t-d debuglevel set the debuglevel\n"));
+ DEBUG(0,("\t-l log basename. Basename for log/debug files\n"));
+ DEBUG(0,("\t-n netbios name. Use this name as my netbios name\n"));
+ DEBUG(0,("\t-N don't ask for a password\n"));
+ DEBUG(0,("\t-m max protocol set the max protocol level\n"));
+ DEBUG(0,("\t-I dest IP use this IP to connect to\n"));
+ DEBUG(0,("\t-E write messages to stderr instead of stdout\n"));
+ DEBUG(0,("\t-U username set the network username\n"));
+ DEBUG(0,("\t-W workgroup set the workgroup name\n"));
+ DEBUG(0,("\t-c command string execute semicolon separated commands\n"));
+ DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n"));
+ DEBUG(0,("\t-D directory start from directory\n"));
+ DEBUG(0,("\n"));
}
/****************************************************************************
@@ -622,59 +758,229 @@ static void parse_mount_smb(int argc, char **argv)
****************************************************************************/
int main(int argc,char *argv[])
{
- extern char *optarg;
- extern int optind;
- static pstring servicesf = CONFIGFILE;
- char *p;
-
- DEBUGLEVEL = 1;
-
- setup_logging("mount.smbfs",True);
-
- TimeInit();
- charset_initialise();
-
- in_client = True; /* Make sure that we tell lp_load we are */
+ fstring base_directory;
+ char *pname = argv[0];
+ int opt;
+ extern FILE *dbf;
+ extern char *optarg;
+ extern int optind;
+ pstring query_host;
+ BOOL nt_domain_logon = False;
+ static pstring servicesf = CONFIGFILE;
+ pstring term_code;
+ char *p;
+
+#ifdef KANJI
+ pstrcpy(term_code, KANJI);
+#else /* KANJI */
+ *term_code = 0;
+#endif /* KANJI */
+
+ *query_host = 0;
+ *base_directory = 0;
+
+ DEBUGLEVEL = 2;
+
+ setup_logging(pname,True);
+
+ TimeInit();
+ charset_initialise();
+
+ pid = (uint16)getpid();
+ vuid = (uint16)getuid();
+ mid = pid + 100;
+ myumask = umask(0);
+ umask(myumask);
+
+ if (getenv("USER"))
+ {
+ pstrcpy(username,getenv("USER"));
+
+ /* modification to support userid%passwd syntax in the USER var
+ 25.Aug.97, jdblair@uab.edu */
+
+ if ((p=strchr(username,'%')))
+ {
+ *p = 0;
+ pstrcpy(password,p+1);
+ got_pass = True;
+ memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
+ }
+ strupper(username);
+ }
+
+ /* modification to support PASSWD environmental var
+ 25.Aug.97, jdblair@uab.edu */
+
+ if (getenv("PASSWD"))
+ pstrcpy(password,getenv("PASSWD"));
+
+ if (*username == 0 && getenv("LOGNAME"))
+ {
+ pstrcpy(username,getenv("LOGNAME"));
+ strupper(username);
+ }
+
+ if (argc < 2)
+ {
+ usage(pname);
+ exit(1);
+ }
+
+ if (*argv[1] != '-')
+ {
+
+ pstrcpy(service, argv[1]);
+ /* Convert any '/' characters in the service name to '\' characters */
+ string_replace( service, '/','\\');
+ argc--;
+ argv++;
+
+ if (count_chars(service,'\\') < 3)
+ {
+ usage(pname);
+ printf("\n%s: Not enough '\\' characters in service\n",service);
+ exit(1);
+ }
+
+ if (argc > 1 && (*argv[1] != '-'))
+ {
+ got_pass = True;
+ pstrcpy(password,argv[1]);
+ memset(argv[1],'X',strlen(argv[1]));
+ argc--;
+ argv++;
+ }
+ }
+
+ while ((opt =
+ getopt(argc, argv,"s:B:O:M:S:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
+ switch (opt)
+ {
+ case 'm':
+ max_protocol = interpret_protocol(optarg,max_protocol);
+ break;
+ case 'O':
+ pstrcpy(user_socket_options,optarg);
+ break;
+ case 'S':
+ pstrcpy(desthost,optarg);
+ strupper(desthost);
+ nt_domain_logon = True;
+ break;
+ case 'B':
+ iface_set_default(NULL,optarg,NULL);
+ break;
+ case 'D':
+ pstrcpy(base_directory,optarg);
+ break;
+ case 'i':
+ pstrcpy(scope,optarg);
+ break;
+ case 'U':
+ {
+ char *lp;
+ pstrcpy(username,optarg);
+ if ((lp=strchr(username,'%')))
+ {
+ *lp = 0;
+ pstrcpy(password,lp+1);
+ got_pass = True;
+ memset(strchr(optarg,'%')+1,'X',strlen(password));
+ }
+ }
+
+ break;
+ case 'W':
+ pstrcpy(workgroup,optarg);
+ break;
+ case 'E':
+ dbf = stderr;
+ break;
+ case 'I':
+ {
+ dest_ip = *interpret_addr2(optarg);
+ if (zero_ip(dest_ip)) exit(1);
+ have_ip = True;
+ }
+ break;
+ case 'n':
+ pstrcpy(global_myname,optarg);
+ break;
+ case 'N':
+ got_pass = True;
+ break;
+ case 'd':
+ if (*optarg == 'A')
+ DEBUGLEVEL = 10000;
+ else
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ case 'l':
+ slprintf(debugf,sizeof(debugf)-1,"%s.client",optarg);
+ break;
+ case 'p':
+ port = atoi(optarg);
+ break;
+ case 'c':
+ cmdstr = optarg;
+ got_pass = True;
+ break;
+ case 'h':
+ usage(pname);
+ exit(0);
+ break;
+ case 's':
+ pstrcpy(servicesf, optarg);
+ break;
+ case 't':
+ pstrcpy(term_code, optarg);
+ break;
+ default:
+ usage(pname);
+ exit(1);
+ }
- if (getenv("USER")) {
- pstrcpy(username,getenv("USER"));
+ if (!*query_host && !*service)
+ {
+ usage(pname);
+ exit(1);
+ }
- if ((p=strchr(username,'%'))) {
- *p = 0;
- pstrcpy(password,p+1);
- got_pass = True;
- }
- }
- if (getenv("PASSWD")) {
- pstrcpy(password,getenv("PASSWD"));
- }
+ DEBUG( 3, ( "Client started (version %s)\n", VERSION ) );
- if (*username == 0 && getenv("LOGNAME")) {
- pstrcpy(username,getenv("LOGNAME"));
- }
+ if(!get_myname(myhostname,NULL))
+ {
+ DEBUG(0,("Failed to get my hostname.\n"));
+ }
- parse_mount_smb(argc, argv);
+ if (!lp_load(servicesf,True,False,False)) {
+ fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
+ }
- DEBUG(3,("mount.smbfs started (version %s)\n", VERSION));
+ codepage_initialise(lp_client_code_page());
- if (!lp_load(servicesf,True,False,False)) {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n",
- servicesf);
- }
+ interpret_coding_system(term_code);
- codepage_initialise(lp_client_code_page());
+ if (*workgroup == 0)
+ pstrcpy(workgroup,lp_workgroup());
- if (*workgroup == 0) {
- pstrcpy(workgroup,lp_workgroup());
- }
+ load_interfaces();
+ get_myname((*global_myname)?NULL:global_myname,NULL);
+ strupper(global_myname);
- load_interfaces();
- if (!*my_netbios_name) {
- pstrcpy(my_netbios_name, myhostname());
+ if (cli_open_sockets(port))
+ {
+ if (!process(base_directory))
+ {
+ close_sockets();
+ return(1);
}
- strupper(my_netbios_name);
+ close_sockets();
+ }
+ else
+ return(1);
- init_mount();
- return 0;
+ return(0);
}
diff --git a/source/client/smbspool.c b/source/client/smbspool.c
deleted file mode 100644
index 8150787fcb0..00000000000
--- a/source/client/smbspool.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 2.0.
- SMB backend for the Common UNIX Printing System ("CUPS")
- Copyright 1999 by Easy Software Products
- Copyright Andrew Tridgell 1994-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define NO_SYSLOG
-
-#include "includes.h"
-
-/*
- * Globals...
- */
-
-extern BOOL in_client; /* Boolean for client library */
-extern struct in_addr ipzero; /* Any address */
-
-
-/*
- * Local functions...
- */
-
-static struct cli_state *smb_connect(char *, char *, char *, char *, char *);
-static int smb_print(struct cli_state *, char *, FILE *);
-
-
-/*
- * 'main()' - Main entry for SMB backend.
- */
-
- int /* O - Exit status */
- main(int argc, /* I - Number of command-line arguments */
- char *argv[]) /* I - Command-line arguments */
-{
- int i; /* Looping var */
- int copies; /* Number of copies */
- char uri[1024], /* URI */
- *sep, /* Pointer to separator */
- *username, /* Username */
- *password, /* Password */
- *workgroup, /* Workgroup */
- *server, /* Server name */
- *printer; /* Printer name */
- FILE *fp; /* File to print */
- int status; /* Status of LPD job */
- struct cli_state *cli; /* SMB interface */
-
- /* we expect the URI in argv[0]. Detect the case where it is in argv[1] and cope */
- if (argc > 2 && strncmp(argv[0],"smb://", 6) && !strncmp(argv[1],"smb://", 6)) {
- argv++;
- argc--;
- }
-
-
- if (argc < 6 || argc > 7)
- {
- fprintf(stderr, "Usage: %s [DEVICE_URI] job-id user title copies options [file]\n",
- argv[0]);
- fputs(" The DEVICE_URI environment variable can also contain the\n", stderr);
- fputs(" destination printer:\n", stderr);
- fputs("\n", stderr);
- fputs(" smb://[username:password@][workgroup/]server/printer\n", stderr);
- return (1);
- }
-
- /*
- * If we have 7 arguments, print the file named on the command-line.
- * Otherwise, print data from stdin...
- */
-
- if (argc == 6)
- {
- /*
- * Print from Copy stdin to a temporary file...
- */
-
- fp = stdin;
- copies = 1;
- }
- else if ((fp = fopen(argv[6], "rb")) == NULL)
- {
- perror("ERROR: Unable to open print file");
- return (1);
- }
- else
- copies = atoi(argv[4]);
-
- /*
- * Fine the URI...
- */
-
- if (strncmp(argv[0], "smb://", 6) == 0)
- strncpy(uri, argv[0], sizeof(uri) - 1);
- else if (getenv("DEVICE_URI") != NULL)
- strncpy(uri, getenv("DEVICE_URI"), sizeof(uri) - 1);
- else
- {
- fputs("ERROR: No device URI found in argv[0] or DEVICE_URI environment variable!\n", stderr);
- return (1);
- }
-
- uri[sizeof(uri) - 1] = '\0';
-
- /*
- * Extract the destination from the URI...
- */
-
- if ((sep = strrchr(uri, '@')) != NULL)
- {
- username = uri + 6;
- *sep++ = '\0';
-
- server = sep;
-
- /*
- * Extract password as needed...
- */
-
- if ((password = strchr(username, ':')) != NULL)
- *password++ = '\0';
- else
- password = "";
- }
- else
- {
- username = "";
- password = "";
- server = uri + 6;
- }
-
- if ((sep = strchr(server, '/')) == NULL)
- {
- fputs("ERROR: Bad URI - need printer name!\n", stderr);
- return (1);
- }
-
- *sep++ = '\0';
- printer = sep;
-
- if ((sep = strchr(printer, '/')) != NULL)
- {
- /*
- * Convert to smb://[username:password@]workgroup/server/printer...
- */
-
- *sep++ = '\0';
-
- workgroup = server;
- server = printer;
- printer = sep;
- }
- else
- workgroup = NULL;
-
- /*
- * Setup the SAMBA server state...
- */
-
- setup_logging("smbspool", True);
-
- TimeInit();
- charset_initialise();
-
- in_client = True; /* Make sure that we tell lp_load we are */
-
- if (!lp_load(CONFIGFILE, True, False, False))
- {
- fprintf(stderr, "ERROR: Can't load %s - run testparm to debug it\n", CONFIGFILE);
- return (1);
- }
-
- if (workgroup == NULL)
- workgroup = lp_workgroup();
-
- codepage_initialise(lp_client_code_page());
-
- load_interfaces();
-
- if ((cli = smb_connect(workgroup, server, printer, username, password)) == NULL)
- {
- perror("ERROR: Unable to connect to SAMBA host");
- return (1);
- }
-
- /*
- * Queue the job...
- */
-
- for (i = 0; i < copies; i ++)
- if ((status = smb_print(cli, argv[3] /* title */, fp)) != 0)
- break;
-
- cli_shutdown(cli);
-
- /*
- * Return the queue status...
- */
-
- return (status);
-}
-
-
-/*
- * 'smb_connect()' - Return a connection to a server.
- */
-
-static struct cli_state * /* O - SMB connection */
-smb_connect(char *workgroup, /* I - Workgroup */
- char *server, /* I - Server */
- char *share, /* I - Printer */
- char *username, /* I - Username */
- char *password) /* I - Password */
-{
- struct cli_state *c; /* New connection */
- struct nmb_name called, /* NMB name of server */
- calling; /* NMB name of client */
- struct in_addr ip; /* IP address of server */
- pstring myname; /* Client name */
-
-
- /*
- * Get the names and addresses of the client and server...
- */
-
- get_myname(myname);
-
- ip = ipzero;
-
- make_nmb_name(&calling, myname, 0x0);
- make_nmb_name(&called, server, 0x20);
-
- /*
- * Open a new connection to the SMB server...
- */
-
- if ((c = cli_initialise(NULL)) == NULL)
- {
- fputs("ERROR: cli_initialize() failed...\n", stderr);
- return (NULL);
- }
-
- if (!cli_set_port(c, SMB_PORT))
- {
- fputs("ERROR: cli_set_port() failed...\n", stderr);
- return (NULL);
- }
-
- if (!cli_connect(c, server, &ip))
- {
- fputs("ERROR: cli_connect() failed...\n", stderr);
- return (NULL);
- }
-
- if (!cli_session_request(c, &calling, &called))
- {
- fputs("ERROR: cli_session_request() failed...\n", stderr);
- return (NULL);
- }
-
- if (!cli_negprot(c))
- {
- fputs("ERROR: SMB protocol negotiation failed\n", stderr);
- cli_shutdown(c);
- return (NULL);
- }
-
- /*
- * Do password stuff...
- */
-
- if (!cli_session_setup(c, username,
- password, strlen(password),
- password, strlen(password),
- workgroup))
- {
- fprintf(stderr, "ERROR: SMB session setup failed: %s\n", cli_errstr(c));
- return (NULL);
- }
-
- if (!cli_send_tconX(c, share, "?????",
- password, strlen(password)+1))
- {
- fprintf(stderr, "ERROR: SMB tree connect failed: %s\n", cli_errstr(c));
- cli_shutdown(c);
- return (NULL);
- }
-
- /*
- * Return the new connection...
- */
-
- return (c);
-}
-
-
-/*
- * 'smb_print()' - Queue a job for printing using the SMB protocol.
- */
-
-static int /* O - 0 = success, non-0 = failure */
-smb_print(struct cli_state *cli, /* I - SMB connection */
- char *title, /* I - Title/job name */
- FILE *fp) /* I - File to print */
-{
- int fnum; /* File number */
- int nbytes, /* Number of bytes read */
- tbytes; /* Total bytes read */
- char buffer[8192]; /* Buffer for copy */
-
-
- /*
- * Open the printer device...
- */
-
- if ((fnum = cli_open(cli, title, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE)) == -1)
- {
- fprintf(stderr, "ERROR: %s opening remote file %s\n",
- cli_errstr(cli), title);
- return (1);
- }
-
- /*
- * Copy the file to the printer...
- */
-
- if (fp != stdin)
- rewind(fp);
-
- tbytes = 0;
-
- while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
- {
- if (cli_write(cli, fnum, 0, buffer, tbytes, nbytes) != nbytes)
- {
- fprintf(stderr, "ERROR: Error writing file: %s\n", cli_errstr(cli));
- break;
- }
-
- tbytes += nbytes;
- }
-
- if (!cli_close(cli, fnum))
- {
- fprintf(stderr, "ERROR: %s closing remote file %s\n",
- cli_errstr(cli), title);
- return (1);
- }
- else
- return (0);
-}
diff --git a/source/client/smbumount.c b/source/client/smbumount.c
index dacf4ab67d0..bc8999d765e 100644
--- a/source/client/smbumount.c
+++ b/source/client/smbumount.c
@@ -23,24 +23,20 @@
#undef SMB_IOC_GETMOUNTUID
#define SMB_IOC_GETMOUNTUID _IOR('u', 1, __kernel_uid_t)
-#ifndef O_NOFOLLOW
-#define O_NOFOLLOW 0400000
-#endif
+static char *progname;
static void
usage(void)
{
- printf("usage: smbumount mountpoint\n");
+ printf("usage: %s mount-point\n", progname);
}
static int
umount_ok(const char *mount_point)
{
- /* we set O_NOFOLLOW to prevent users playing games with symlinks to
- umount filesystems they don't own */
- int fid = open(mount_point, O_RDONLY|O_NOFOLLOW, 0);
+ int fid = open(mount_point, O_RDONLY, 0);
__kernel_uid_t mount_uid;
-
+
if (fid == -1) {
fprintf(stderr, "Could not open %s: %s\n",
mount_point, strerror(errno));
@@ -53,7 +49,7 @@ umount_ok(const char *mount_point)
return -1;
}
- if ((getuid() != 0)
+ if ( (getuid() != 0)
&& (mount_uid != getuid())) {
fprintf(stderr, "You are not allowed to umount %s\n",
mount_point);
@@ -67,14 +63,15 @@ umount_ok(const char *mount_point)
/* Make a canonical pathname from PATH. Returns a freshly malloced string.
It is up the *caller* to ensure that the PATH is sensible. i.e.
canonicalize ("/dev/fd0/.") returns "/dev/fd0" even though ``/dev/fd0/.''
- is not a legal pathname for ``/dev/fd0'' Anything we cannot parse
+ is not a legal pathname for ``/dev/fd0.'' Anything we cannot parse
we return unmodified. */
-static char *
+char *
canonicalize (char *path)
{
char *canonical = malloc (PATH_MAX + 1);
- if (strlen(path) > PATH_MAX) {
+ if (strlen(path) > PATH_MAX)
+ {
fprintf(stderr, "Mount point string too long\n");
return NULL;
}
@@ -94,18 +91,22 @@ int
main(int argc, char *argv[])
{
int fd;
+
char* mount_point;
+
struct mntent *mnt;
FILE* mtab;
FILE* new_mtab;
+ progname = argv[0];
+
if (argc != 2) {
usage();
exit(1);
}
if (geteuid() != 0) {
- fprintf(stderr, "smbumount must be installed suid root\n");
+ fprintf(stderr, "%s must be installed suid root\n", progname);
exit(1);
}
diff --git a/source/codepages/codepage_def.852 b/source/codepages/codepage_def.852
index 76f6f7de4a6..ed1423428ca 100644
--- a/source/codepages/codepage_def.852
+++ b/source/codepages/codepage_def.852
@@ -61,4 +61,3 @@
0xEE 0xDD True True
0xFB 0xEB True True
0xFD 0xFC True True
- 0xFF 0xFF True True
diff --git a/source/codepages/codepage_def.932 b/source/codepages/codepage_def.932
index 5d636ae420a..8d9ff631fba 100644
--- a/source/codepages/codepage_def.932
+++ b/source/codepages/codepage_def.932
@@ -21,3 +21,4 @@
# The columns are :
# lower upper map upper to lower map lower to upper
#
+# This file is intentionaly empty - no mappings are done. \ No newline at end of file
diff --git a/source/config.guess b/source/config.guess
index 695867b068e..e1b58717080 100755
--- a/source/config.guess
+++ b/source/config.guess
@@ -1,6 +1,7 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999
+# Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -23,6 +24,7 @@
# Written by Per Bothner <bothner@cygnus.com>.
# The master version of this file is at the FSF in /home/gd/gnu/lib.
+# Please send patches to <autoconf-patches@gnu.org>.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
@@ -35,6 +37,20 @@
# (but try to keep the structure clean).
#
+# Use $HOST_CC if defined. $CC may point to a cross-compiler
+if test x"$CC_FOR_BUILD" = x; then
+ if test x"$HOST_CC" != x; then
+ CC_FOR_BUILD="$HOST_CC"
+ else
+ if test x"$CC" != x; then
+ CC_FOR_BUILD="$CC"
+ else
+ CC_FOR_BUILD=cc
+ fi
+ fi
+fi
+
+
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 8/24/94.)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
@@ -46,20 +62,66 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- news*:NEWS-OS:6.*:*)
- echo mips-sony-newsos6
- exit 0 ;;
alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'`
+ cat <<EOF >$dummy.s
+ .globl main
+ .ent main
+main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
exit 0 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
@@ -71,23 +133,60 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;;
amiga:OpenBSD:*:*)
- echo m68k-cbm-openbsd${UNAME_RELEASE}
- exit 0 ;;
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
- Pyramid*:OSx*:*:*)
+ arm32:NetBSD:*:*)
+ echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit 0 ;;
- sun4*:SunOS:5.*:*)
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
i86pc:SunOS:5.*:*)
- echo i386-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -107,23 +206,79 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
atari*:NetBSD:*:*)
echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0 ;;
atari*:OpenBSD:*:*)
- echo m68k-atari-openbsd${UNAME_RELEASE}
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:OpenBSD:*:*)
- echo m68k-sun-openbsd${UNAME_RELEASE}
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
- echo m68k-apple-openbsd${UNAME_RELEASE}
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ macppc:NetBSD:*:*)
+ echo powerpc-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
exit 0 ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
@@ -131,10 +286,34 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
- mips:*:4*:UMIPS)
- echo mips-mips-riscos4sysv
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
- mips:*:5*:RISCos)
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy \
+ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
@@ -152,15 +331,18 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
- -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
echo m88k-dg-dgux${UNAME_RELEASE}
- else
+ else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
fi
- else echo i586-dg-dgux${UNAME_RELEASE}
- fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
@@ -178,15 +360,15 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit 0 ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i[34]86:AIX:*:*)
+ i?86:AIX:*:*)
echo i386-ibm-aix
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- sed 's/^ //' << EOF >dummy.c
+ sed 's/^ //' << EOF >$dummy.c
#include <sys/systemcfg.h>
main()
@@ -197,8 +379,8 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit(0);
}
EOF
- ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
@@ -207,7 +389,8 @@ EOF
fi
exit 0 ;;
*:AIX:*:4)
- if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
@@ -226,7 +409,7 @@ EOF
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0 ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
@@ -240,18 +423,50 @@ EOF
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0 ;;
- 9000/[3478]??:HP-UX:*:*)
+ 9000/[34678]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;;
- 9000/8?? ) HP_ARCH=hppa1.0 ;;
+ 9000/[678][0-9][0-9])
+ sed 's/^ //' << EOF >$dummy.c
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+ rm -f $dummy.c $dummy
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
- sed 's/^ //' << EOF >dummy.c
+ sed 's/^ //' << EOF >$dummy.c
#include <unistd.h>
int
main ()
@@ -276,8 +491,8 @@ EOF
exit (0);
}
EOF
- ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
@@ -286,15 +501,28 @@ EOF
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
+ *9??*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
+ hppa*:OpenBSD:*:*)
+ echo hppa-unknown-openbsd
+ exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
@@ -313,126 +541,332 @@ EOF
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
- CRAY*T3E:*:*:*)
- echo t3e-cray-unicos_mk
- exit 0 ;;
CRAY*X-MP:*:*:*)
echo xmp-cray-unicos
exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE}
exit 0 ;;
- CRAY*C90:*:*:*)
- echo c90-cray-unicos${UNAME_RELEASE}
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
exit 0 ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE}
exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alpha-cray-unicosmk${UNAME_RELEASE}
+ exit 0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;;
- hp3[0-9][05]:OpenBSD:*:*)
- echo m68k-hp-openbsd${UNAME_RELEASE}
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | i?86:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
- i[34]86:BSD/386:*:* | *:BSD/OS:*:*)
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
+ if test -x /usr/bin/objformat; then
+ if test "elf" = "`/usr/bin/objformat`"; then
+ echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
+ exit 0
+ fi
+ fi
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
*:NetBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'`
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
- *:QNX:*:4*)
- echo i386-qnx-qnx4
- exit 0 ;;
i*:CYGWIN*:*)
- echo i386-unknown-cygwin32
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i386-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
exit 0 ;;
p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin32
+ echo powerpcle-unknown-cygwin
exit 0 ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
*:GNU:*:*)
- echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
+
# The BFD linker knows what the default object file format is, so
- # first see if it will tell us.
- ld_help_string=`ld --help 2>&1`
- if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i[345]86"; then
- echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
- elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86linux"; then
- echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
- elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i[345]86coff"; then
- echo "${UNAME_MACHINE}-unknown-linuxcoff" ; exit 0
- elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
- echo "${UNAME_MACHINE}-unknown-linux" ; exit 0
- elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
- echo "${UNAME_MACHINE}-unknown-linuxaout" ; exit 0
- elif test "${UNAME_MACHINE}" = "alpha" ; then
- echo alpha-unknown-linux ; exit 0
- else
- # Either a pre-BFD a.out linker (linuxoldld) or one that does not give us
- # useful --help. Gcc wants to distinguish between linuxoldld and linuxaout.
- test ! -d /usr/lib/ldscripts/. \
- && echo "${UNAME_MACHINE}-unknown-linuxoldld" && exit 0
- # Determine whether the default compiler is a.out or elf
- cat >dummy.c <<EOF
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ ld_help_string=`cd /; ld --help 2>&1`
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ *ia64)
+ echo "${UNAME_MACHINE}-unknown-linux"
+ exit 0
+ ;;
+ i?86linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0
+ ;;
+ i?86coff)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0
+ ;;
+ sparclinux)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+ exit 0
+ ;;
+ armlinux)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+ exit 0
+ ;;
+ elf32arm*)
+ echo "${UNAME_MACHINE}-unknown-linux-gnu"
+ exit 0
+ ;;
+ armelf_linux*)
+ echo "${UNAME_MACHINE}-unknown-linux-gnu"
+ exit 0
+ ;;
+ m68klinux)
+ echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
+ exit 0
+ ;;
+ elf32ppc)
+ # Determine Lib Version
+ cat >$dummy.c <<EOF
+#include <features.h>
+#if defined(__GLIBC__)
+extern char __libc_version[];
+extern char __libc_release[];
+#endif
main(argc, argv)
-int argc;
-char *argv[];
+ int argc;
+ char *argv[];
{
+#if defined(__GLIBC__)
+ printf("%s %s\n", __libc_version, __libc_release);
+#else
+ printf("unkown\n");
+#endif
+ return 0;
+}
+EOF
+ LIBC=""
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy | grep 1\.99 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.c $dummy
+ echo powerpc-unknown-linux-gnu${LIBC}
+ exit 0
+ ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ sed 's/^ //' <<EOF >$dummy.s
+ .globl main
+ .ent main
+ main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ LIBC=""
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./$dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+
+ objdump --private-headers $dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >$dummy.c <<EOF
+#ifdef __cplusplus
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ else
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
#ifdef __ELF__
- printf ("%s-unknown-linux\n", argv[1]);
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
#else
- printf ("%s-unknown-linuxaout\n", argv[1]);
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
#endif
return 0;
}
EOF
- ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
- rm -f dummy.c dummy
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
fi ;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
# are messed up and put the nodename in both sysname and nodename.
- i[34]86:DYNIX/ptx:4*:*)
+ i?86:DYNIX/ptx:4*:*)
echo i386-sequent-sysv4
exit 0 ;;
- i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*)
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i?86:*:5:7*)
+ # Fixed at (any) Pentium or better
+ UNAME_MACHINE=i586
+ if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
+ echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
else
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi
exit 0 ;;
- i[34]86:*:3.2:*)
+ i?86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
- echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
+ (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
- echo ${UNAME_MACHINE}-unknown-sysv32
+ echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
- *:UnixWare:*:*)
- echo ${UNAME_MACHINE}-UnixWare-sysv${UNAME_RELEASE}
- exit 0 ;;
+ pc:*:*:*)
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
Intel:Mach:3*:*)
- echo i386-unknown-mach3
+ echo i386-pc-mach3
exit 0 ;;
paragon:*:*:*)
echo i860-intel-osf1
@@ -448,30 +882,39 @@ EOF
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
- M680[234]0:*:R3V[567]*:*)
+ M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
- 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
- uname -p 2>/dev/null | grep 86 >/dev/null \
- && echo i486-ncr-sysv4.3 && exit 0
- uname -p 2>/dev/null | grep entium >/dev/null \
- && echo i586-ncr-sysv4.3 && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- uname -p 2>/dev/null | grep 86 >/dev/null \
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4 && exit 0 ;;
- m680[234]0:LynxOS:2.[23]*:*)
- echo m68k-lynx-lynxos${UNAME_RELEASE}
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
- i[34]86:LynxOS:2.[23]*:*)
- echo i386-lynx-lynxos${UNAME_RELEASE}
+ i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
- TSUNAMI:LynxOS:2.[23]*:*)
- echo sparc-lynx-lynxos${UNAME_RELEASE}
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
- rs6000:LynxOS:2.[23]*:*)
- echo rs6000-lynx-lynxos${UNAME_RELEASE}
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
@@ -484,25 +927,62 @@ EOF
echo ns32k-sni-sysv
fi
exit 0 ;;
- *:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
- R3000:*System_V*:*:*)
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-qnx-qnx${UNAME_VERSION}
+ exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-cat >dummy.c <<EOF
+cat >$dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
@@ -540,7 +1020,10 @@ main ()
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3");
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
@@ -557,7 +1040,7 @@ main ()
#endif
#if defined (__386BSD__)
- printf ("i386-unknown-bsd\n"); exit (0);
+ printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
@@ -600,8 +1083,8 @@ main ()
}
EOF
-${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
-rm -f dummy.c dummy
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
# Apollos put the system type in the environment.
diff --git a/source/config.sub b/source/config.sub
index ccbdb0257d2..28426bb8fa0 100755
--- a/source/config.sub
+++ b/source/config.sub
@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
-# Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+# Copyright (C) 1991, 92-97, 1998, 1999 Free Software Foundation, Inc.
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
+# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -41,6 +41,8 @@
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
if [ x$1 = x ]
@@ -62,11 +64,21 @@ case $1 in
;;
esac
-# Separate what the user gave into CPU-COMPANY and OS (if any).
-basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-if [ $basic_machine != $1 ]
-then os=`echo $1 | sed 's/.*-/-/'`
-else os=; fi
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
@@ -81,52 +93,56 @@ case $os in
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp )
- os=
- basic_machine=$1
- ;;
- -sim | -cisco | -oki | -wec | -winbond ) # CYGNUS LOCAL
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
os=
basic_machine=$1
;;
- -apple*) # CYGNUS LOCAL
+ -sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
;;
- -scout) # CYGNUS LOCAL
+ -scout)
;;
- -wrs) # CYGNUS LOCAL
- os=vxworks
+ -wrs)
+ os=-vxworks
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
-sco4)
os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
@@ -137,50 +153,70 @@ case $os in
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
- tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm | armeb \
- | armel | pyramid \
- | tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
- | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
- | powerpc | powerpcle | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
- | pdp11 | mips64el | mips64orion | mips64orionel \
- | sparc | sparc8 | supersparc | microsparc | ultrasparc)
+ tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+ | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
+ | 580 | i960 | h8300 \
+ | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
+ | alpha | alphaev[4-7] | alphaev56 | alphapca5[67] \
+ | we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
+ | 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
+ | mips64orion | mips64orionel | mipstx39 | mipstx39el \
+ | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
+ | mips64vr5000 | miprs64vr5000el | mcore \
+ | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
+ | thumb | d10v | fr30)
basic_machine=$basic_machine-unknown
;;
- m88110 | m680[012346]0 | m683?2 | m68360 | z8k | v70 | h8500 | w65) # CYGNUS LOCAL
- basic_machine=$basic_machine-unknown
- ;;
- mips64vr4300 | mips64vr4300el) # CYGNUS LOCAL jsmith
- basic_machine=$basic_machine-unknown
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[34567]86)
+ basic_machine=$basic_machine-pc
+ ;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
- vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
- | sparc-* | ns32k-* | fx80-* | arm-* | arme[lb]-* | c[123]* \
- | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
- | none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
- | hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
- | pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
- | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* \
- | mips64-* | mipsel-* | mips64el-* | mips64orion-* \
- | mips64orionel-* | sparc8-* | supersparc-* | microsparc-* | ultrasparc-*)
- ;;
- m88110-* | m680[012346]0-* | m683?2-* | m68360-* | z8k-* | h8500-*) # CYGNUS LOCAL
- ;;
- mips64vr4300-* | mips64vr4300el-*) # CYGNUS LOCAL jsmith
+ # FIXME: clean up the formatting here.
+ vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
+ | xmp-* | ymp-* \
+ | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* | hppa2.0n-* \
+ | alpha-* | alphaev[4-7]-* | alphaev56-* | alphapca5[67]-* \
+ | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
+ | clipper-* | orion-* \
+ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+ | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
+ | mipstx39-* | mipstx39el-* | mcore-* \
+ | f301-* | armv*-* | t3e-* \
+ | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
+ | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* )
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
- 386bsd) # CYGNUS LOCAL
+ 386bsd)
basic_machine=i386-unknown
os=-bsd
;;
@@ -190,11 +226,11 @@ case $basic_machine in
3b*)
basic_machine=we32k-att
;;
- a29khif) # CYGNUS LOCAL
+ a29khif)
basic_machine=a29k-amd
os=-udi
;;
- adobe68k) # CYGNUS LOCAL
+ adobe68k)
basic_machine=m68010-adobe
os=-scout
;;
@@ -215,9 +251,9 @@ case $basic_machine in
amiga | amiga-*)
basic_machine=m68k-cbm
;;
- amigados)
+ amigaos | amigados)
basic_machine=m68k-cbm
- os=-amigados
+ os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-cbm
@@ -227,26 +263,18 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-sysv
;;
- apollo68bsd) # CYGNUS LOCAL
+ apollo68bsd)
basic_machine=m68k-apollo
os=-bsd
;;
- arm | armel | armeb)
- basic_machine=arm-arm
- os=-aout
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
- [ctj]90-cray)
- basic_machine=c90-cray
- os=-unicos
- ;;
- t3e-cray)
- basic_machine=t3e-cray
- os=-unicos_mk
- ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -275,6 +303,10 @@ case $basic_machine in
basic_machine=cray2-cray
os=-unicos
;;
+ [ctj]90-cray)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
crds | unos)
basic_machine=m68k-crds
;;
@@ -311,7 +343,7 @@ case $basic_machine in
encore | umax | mmax)
basic_machine=ns32k-encore
;;
- es1800 | OSE68k | ose68k | ose | OSE) # CYGNUS LOCAL
+ es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
os=-ose
;;
@@ -333,11 +365,11 @@ case $basic_machine in
basic_machine=h8300-hitachi
os=-hms
;;
- h8300xray) # CYGNUS LOCAL
+ h8300xray)
basic_machine=h8300-hitachi
os=-xray
;;
- h8500hms) # CYGNUS LOCAL
+ h8500hms)
basic_machine=h8500-hitachi
os=-hms
;;
@@ -356,71 +388,85 @@ case $basic_machine in
basic_machine=m68k-hp
os=-hpux
;;
- w89k-*) # CYGNUS LOCAL
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- op50n-*) # CYGNUS LOCAL
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- op60c-*) # CYGNUS LOCAL
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- hppro) # CYGNUS LOCAL
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
- hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
- hppaosf) # CYGNUS LOCAL
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
basic_machine=hppa1.1-hp
os=-osf
;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
- os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i[3456]86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[34567]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
- i[3456]86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[34567]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
- i[3456]86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[34567]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
- i[3456]86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[34567]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
- i386mach) # CYGNUS LOCAL
+ i386mach)
basic_machine=i386-mach
os=-mach
;;
- i386-vsta | vsta) # CYGNUS LOCAL
+ i386-vsta | vsta)
basic_machine=i386-unknown
os=-vsta
;;
- i386-go32 | go32) # CYGNUS LOCAL
+ i386-go32 | go32)
basic_machine=i386-unknown
os=-go32
;;
+ i386-mingw32 | mingw32)
+ basic_machine=i386-unknown
+ os=-mingw32
+ ;;
+ i386-qnx | qnx)
+ basic_machine=i386-qnx
+ ;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
@@ -449,28 +495,48 @@ case $basic_machine in
miniframe)
basic_machine=m68000-convergent
;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
- monitor) # CYGNUS LOCAL
+ monitor)
basic_machine=m68k-rom68k
os=-coff
;;
- msdos) # CYGNUS LOCAL
- basic_machine=i386-unknown
+ msdos)
+ basic_machine=i386-unknown
os=-msdos
;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
netbsd386)
- basic_machine=i386-unknown # CYGNUS LOCAL
+ basic_machine=i386-unknown
os=-netbsd
;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
@@ -483,7 +549,7 @@ case $basic_machine in
basic_machine=mips-sony
os=-newsos
;;
- necv70) # CYGNUS LOCAL
+ necv70)
basic_machine=v70-nec
os=-sysv
;;
@@ -512,14 +578,22 @@ case $basic_machine in
basic_machine=i960-intel
os=-nindy
;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
np1)
basic_machine=np1-gould
;;
- OSE68000 | ose68000) # CYGNUS LOCAL
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
;;
- os68k) # CYGNUS LOCAL
+ os68k)
basic_machine=m68k-none
os=-os68k
;;
@@ -540,25 +614,23 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
- pentium | p5)
- basic_machine=i586-intel
+ pentium | p5 | k5 | k6 | nexen)
+ basic_machine=i586-pc
;;
- pentiumpro | p6)
- basic_machine=i686-intel
+ pentiumpro | p6 | 6x86)
+ basic_machine=i686-pc
;;
- pentium-* | p5-*)
+ pentiumii | pentium2)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexen-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
- pentiumpro-* | p6-*)
+ pentiumpro-* | p6-* | 6x86-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
- k5)
- # We don't have specific support for AMD's K5 yet, so just call it a Pentium
- basic_machine=i586-amd
- ;;
- nexgen)
- # We don't have specific support for Nexgen yet, so just call it a Pentium
- basic_machine=i586-nexgen
+ pentiumii-* | pentium2-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
@@ -578,7 +650,7 @@ case $basic_machine in
ps2)
basic_machine=i386-ibm
;;
- rom68k) # CYGNUS LOCAL
+ rom68k)
basic_machine=m68k-rom68k
os=-coff
;;
@@ -588,7 +660,7 @@ case $basic_machine in
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
- sa29200) # CYGNUS LOCAL
+ sa29200)
basic_machine=a29k-amd
os=-udi
;;
@@ -599,24 +671,10 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
- sparclite-wrs) # CYGNUS LOCAL
+ sparclite-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
- sparcfrw) # CYGNUS LOCAL
- basic_machine=sparcfrw-sun
- os=-sunos4
- ;;
- sparcfrwcompat) # CYGNUS LOCAL
- basic_machine=sparcfrwcompat-sun
- os=-sunos4
- ;;
- sparclitefrw) # CYGNUS LOCAL
- basic_machine=sparclitefrw-fujitsu
- ;;
- sparclitefrwcompat) # CYGNUS LOCAL
- basic_machine=sparclitefrwcompat-fujitsu
- ;;
sps7)
basic_machine=m68k-bull
os=-sysv2
@@ -624,10 +682,10 @@ case $basic_machine in
spur)
basic_machine=spur-unknown
;;
- st2000) # CYGNUS LOCAL
+ st2000)
basic_machine=m68k-tandem
;;
- stratus) # CYGNUS LOCAL
+ stratus)
basic_machine=i860-stratus
os=-sysv4
;;
@@ -675,6 +733,16 @@ case $basic_machine in
basic_machine=i386-sequent
os=-dynix
;;
+ t3e)
+ basic_machine=t3e-cray
+ os=-unicos
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
tower | tower-32)
basic_machine=m68k-ncr
;;
@@ -686,7 +754,7 @@ case $basic_machine in
basic_machine=a29k-nyu
os=-sym1
;;
- v810 | necv810) # CYGNUS LOCAL
+ v810 | necv810)
basic_machine=v810-nec
os=-none
;;
@@ -698,6 +766,9 @@ case $basic_machine in
basic_machine=vax-dec
os=-vms
;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
@@ -706,13 +777,17 @@ case $basic_machine in
basic_machine=m68k-wrs
os=-vxworks
;;
- vxworks29k) # CYGNUS LOCAL
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*) # CYGNUS LOCAL
- basic_machine=w65-wdc
- os=-none
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
;;
xmp)
basic_machine=xmp-cray
@@ -721,7 +796,7 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
- z8k-*-coff) # CYGNUS LOCAL
+ z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
@@ -732,17 +807,21 @@ case $basic_machine in
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
- w89k) # CYGNUS LOCAL
+ w89k)
basic_machine=hppa1.1-winbond
;;
- op50n) # CYGNUS LOCAL
+ op50n)
basic_machine=hppa1.1-oki
;;
- op60c) # CYGNUS LOCAL
+ op60c)
basic_machine=hppa1.1-oki
;;
mips)
- basic_machine=mips-mips
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
;;
romp)
basic_machine=romp-ibm
@@ -759,7 +838,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sparc)
+ sparc | sparcv9)
basic_machine=sparc-sun
;;
cydra)
@@ -771,12 +850,16 @@ case $basic_machine in
orion105)
basic_machine=clipper-highlevel
;;
- mac | mpw | mac-mpw) # CYGNUS LOCAL
+ mac | mpw | mac-mpw)
basic_machine=m68k-apple
;;
- pmac | pmac-mpw) # CYGNUS LOCAL
+ pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
@@ -800,6 +883,8 @@ esac
if [ x"$os" != x"" ]
then
case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
@@ -807,42 +892,54 @@ case $os in
-solaris)
os=-solaris2
;;
- -unixware* | svr4*)
+ -svr4*)
os=-sysv4
;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
-gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux|'`
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
- # Each alternative must end in a *, to match a version number.
+ # Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -lites* | -minix* | -genix* | -ultrix* | -irix* \
- | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[3456]* \
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigados* | -msdos* | -moss* | -newsos* | -unicos* | -aos* \
- | -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
- | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -netbsd* | -freebsd* | -openbsd* \
- | -riscix* | -lites* \
- | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta | -udi \
- | -eabi* | -ieee*)
- ;;
- # CYGNUS LOCAL
- -go32 | -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -proelf | -os9* \
- | -macos* | -mpw* | -magic* | -pe* | -win32)
- ;;
- -mac*) # CYGNUS LOCAL
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -rhapsody* | -opened* | -openstep* | -oskit*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mon960* | -lnews*)
+ ;;
+ -mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
+ -opened*)
+ os=-openedition
+ ;;
-osfrose*)
os=-osfrose
;;
@@ -858,12 +955,15 @@ case $os in
-acis*)
os=-aos
;;
- -386bsd) # CYGNUS LOCAL
+ -386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
+ -ns2 )
+ os=-nextstep2
+ ;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
@@ -877,6 +977,9 @@ case $os in
-oss*)
os=-sysv3
;;
+ -qnx)
+ os=-qnx4
+ ;;
-svr4)
os=-sysv4
;;
@@ -889,15 +992,18 @@ case $os in
# This must come after -sysvr4.
-sysv*)
;;
- -ose*) # CYGNUS LOCAL
+ -ose*)
os=-ose
;;
- -es1800*) # CYGNUS LOCAL
+ -es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
+ -*mint | -*MiNT)
+ os=-mint
+ ;;
-none)
;;
*)
@@ -923,6 +1029,12 @@ case $basic_machine in
*-acorn)
os=-riscix1.2
;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
pdp11-*)
os=-none
;;
@@ -941,10 +1053,13 @@ case $basic_machine in
# default.
# os=-sunos4
;;
- m68*-cisco) # CYGNUS LOCAL
+ m68*-cisco)
os=-aout
;;
- mips*-cisco) # CYGNUS LOCAL
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
os=-elf
;;
*-tti) # must be before sparc entry or we get the wrong os.
@@ -953,16 +1068,19 @@ case $basic_machine in
sparc-* | *-sun)
os=-sunos4.1.1
;;
+ *-be)
+ os=-beos
+ ;;
*-ibm)
os=-aix
;;
- *-wec) # CYGNUS LOCAL
+ *-wec)
os=-proelf
;;
- *-winbond) # CYGNUS LOCAL
+ *-winbond)
os=-proelf
;;
- *-oki) # CYGNUS LOCAL
+ *-oki)
os=-proelf
;;
*-hp)
@@ -975,7 +1093,7 @@ case $basic_machine in
os=-sysv
;;
*-cbm)
- os=-amigados
+ os=-amigaos
;;
*-dg)
os=-dgux
@@ -989,6 +1107,9 @@ case $basic_machine in
m88k-omron*)
os=-luna
;;
+ *-next )
+ os=-nextstep
+ ;;
*-sequent)
os=-ptx
;;
@@ -1022,15 +1143,21 @@ case $basic_machine in
*-masscomp)
os=-rtu
;;
- *-rom68k) # CYGNUS LOCAL
+ f301-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
os=-coff
;;
- *-*bug) # CYGNUS LOCAL
+ *-*bug)
os=-coff
;;
- *-apple) # CYGNUS LOCAL
+ *-apple)
os=-macos
;;
+ *-atari*)
+ os=-mint
+ ;;
*)
os=-none
;;
@@ -1049,18 +1176,18 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
- -bosx*) # CYGNUS LOCAL
- vendor=bull
- ;;
- -lynxos*)
- vendor=lynx
- ;;
-aix*)
vendor=ibm
;;
+ -beos*)
+ vendor=be
+ ;;
-hpux*)
vendor=hp
;;
+ -mpeix*)
+ vendor=hp
+ ;;
-hiux*)
vendor=hitachi
;;
@@ -1076,21 +1203,27 @@ case $basic_machine in
-genix*)
vendor=ns
;;
- -mvs*)
+ -mvs* | -opened*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
- -vxworks*)
+ -vxsim* | -vxworks*)
vendor=wrs
;;
- -hms*) # CYGNUS LOCAL
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
vendor=hitachi
;;
- -mpw* | -macos*) # CYGNUS LOCAL
+ -mpw* | -macos*)
vendor=apple
;;
+ -*mint | -*MiNT)
+ vendor=atari
+ ;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
diff --git a/source/configure b/source/configure
index 63c87c508d4..3f175083ff6 100755
--- a/source/configure
+++ b/source/configure
@@ -1,7 +1,7 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.12
+# Generated automatically using autoconf version 2.13
# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
@@ -15,6 +15,40 @@ ac_default_prefix=/usr/local/samba
ac_help="$ac_help
--enable-maintainer-mode enable some make rules for maintainers"
ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=no]"
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --disable-libtool-lock avoid locking (might break parallel builds)"
+ac_help="$ac_help
+ --with-sam-pwdb={passdb,tdb,nt5ldap}
+ which password-database to use (passdb)"
+ac_help="$ac_help
+ --with-libmsrpc Include libmsrpc support (default)
+ --without-libmsrpc Don't include libmsrpc support "
+ac_help="$ac_help
+ --with-libubiqx Include SMB libubiqx support (default)
+ --without-libubiqx Don't include SMB libubiqx support "
+ac_help="$ac_help
+ --with-libsamba Include SMB libsamba support (default)
+ --without-libsamba Don't include SMB libsamba support "
+ac_help="$ac_help
+ --with-libnmb Include NMB libnmb support (default)
+ --without-libnmb Don't include NMB libnmb support "
+ac_help="$ac_help
+ --with-libsurs Include SMB libsurs support (default)
+ --without-libsurs Don't include SMB libsurs support "
+ac_help="$ac_help
+ --with-libsmbpw Include SMB libsmbpw support (default)
+ --without-libsmbpw Don't include SMB libsmbpw support "
+ac_help="$ac_help
+ --with-libsmb Include SMB libsmb support (default)
+ --without-libsmb Don't include SMB libsmb support "
+ac_help="$ac_help
--with-smbwrapper Include SMB wrapper support
--without-smbwrapper Don't include SMB wrapper support (default)"
ac_help="$ac_help
@@ -25,10 +59,7 @@ ac_help="$ac_help
--without-dfs Don't include DFS support (default)"
ac_help="$ac_help
--with-krb4=base-dir Include Kerberos IV support
- --without-krb4 Don't include Kerbers IV support (default)"
-ac_help="$ac_help
- --with-krb5=base-dir Include Kerberos 5 support
- --without-krb5 Don't include Kerbers 5 support (default)"
+ --without-krb4 Don't include Kerberos IV support (default)"
ac_help="$ac_help
--with-automount Include AUTOMOUNT support
--without-automount Don't include AUTOMOUNT support (default)"
@@ -36,12 +67,18 @@ ac_help="$ac_help
--with-smbmount Include SMBMOUNT (Linux only) support
--without-smbmount Don't include SMBMOUNT support (default)"
ac_help="$ac_help
- --with-pam Include PAM password database support
- --without-pam Don't include PAM password database support (default)"
+ --with-surstdb Use SURS tdb database
+ --without-surstdb Don't use SURS tdb database (default)"
ac_help="$ac_help
--with-ldap Include LDAP support
--without-ldap Don't include LDAP support (default)"
ac_help="$ac_help
+ --with-nt5ldap Include NT5 LDAP support
+ --without-nt5ldap Don't include NT5 LDAP support (default)"
+ac_help="$ac_help
+ --with-nt5ldap Include NT5 LDAP support
+ --without-nt5ldap Don't include NT5 LDAP support (default)"
+ac_help="$ac_help
--with-nisplus Include NISPLUS password database support
--without-nisplus Don't include NISPLUS password database support (default)"
ac_help="$ac_help
@@ -49,8 +86,10 @@ ac_help="$ac_help
--without-nisplus-home Don't include NISPLUS_HOME support (default)"
ac_help="$ac_help
--with-ssl Include SSL support
- --without-ssl Don't include SSL support (default)
- --with-sslinc=DIR Where the SSL includes are (defaults to /usr/local/ssl)"
+ --without-ssl Don't include SSL support (default)"
+ac_help="$ac_help
+ --with-mmap Include experimental MMAP support
+ --without-mmap Don't include MMAP support (default)"
ac_help="$ac_help
--with-syslog Include experimental SYSLOG support
--without-syslog Don't include SYSLOG support (default)"
@@ -63,15 +102,6 @@ ac_help="$ac_help
ac_help="$ac_help
--with-quotas Include experimental disk-quota support
--without-quotas Don't include experimental disk-quota support (default)"
-ac_help="$ac_help
- --with-utmp Include experimental utmp accounting
- --without-utmp Don't include experimental utmp accounting (default)"
-ac_help="$ac_help
- --with-privatedir=DIR Where to put smbpasswd ($ac_default_prefix/private)"
-ac_help="$ac_help
- --with-lockdir=DIR Where to put lock files ($ac_default_prefix/var/locks)"
-ac_help="$ac_help
- --with-swatdir=DIR Where to put SWAT files ($ac_default_prefix/swat)"
# Initialize some variables set by options.
# The variables have the same names as the options, with
@@ -110,6 +140,7 @@ mandir='${prefix}/man'
# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
# Maximum number of lines to put in a shell here document.
ac_max_here_lines=12
@@ -393,7 +424,7 @@ EOF
verbose=yes ;;
-version | --version | --versio | --versi | --vers)
- echo "configure generated by autoconf version 2.12"
+ echo "configure generated by autoconf version 2.13"
exit 0 ;;
-with-* | --with-*)
@@ -563,9 +594,11 @@ ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
+ac_exeext=
+ac_objext=o
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
# Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
@@ -593,21 +626,34 @@ fi
+
+
+
+
+
+
+
+
+
+
+
+
# compile with optimisation and without debugging by default
CFLAGS=${CFLAGS-"-O"}
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:603: checking for $ac_word" >&5
+echo "configure:648: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_CC="gcc"
@@ -628,16 +674,17 @@ if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:632: checking for $ac_word" >&5
+echo "configure:678: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
ac_prog_rejected=no
- for ac_dir in $PATH; do
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
@@ -672,25 +719,61 @@ else
echo "$ac_t""no" 1>&6
fi
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:729: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:680: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:761: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross
-cat > conftest.$ac_ext <<EOF
-#line 690 "configure"
+cat > conftest.$ac_ext << EOF
+
+#line 772 "configure"
#include "confdefs.h"
+
main(){return(0);}
EOF
-if { (eval echo configure:694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:777: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
ac_cv_prog_cc_works=yes
# If we can't run a trivial program, we are probably using a cross compiler.
if (./conftest; exit) 2>/dev/null; then
@@ -704,18 +787,24 @@ else
ac_cv_prog_cc_works=no
fi
rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
if test $ac_cv_prog_cc_works = no; then
{ echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:714: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:803: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
cross_compiling=$ac_cv_prog_cc_cross
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:719: checking whether we are using GNU C" >&5
+echo "configure:808: checking whether we are using GNU C" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -724,7 +813,7 @@ else
yes;
#endif
EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:728: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:817: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
ac_cv_prog_gcc=yes
else
ac_cv_prog_gcc=no
@@ -735,11 +824,15 @@ echo "$ac_t""$ac_cv_prog_gcc" 1>&6
if test $ac_cv_prog_gcc = yes; then
GCC=yes
- ac_test_CFLAGS="${CFLAGS+set}"
- ac_save_CFLAGS="$CFLAGS"
- CFLAGS=
- echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:743: checking whether ${CC-cc} accepts -g" >&5
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:836: checking whether ${CC-cc} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -754,16 +847,20 @@ rm -f conftest*
fi
echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
- if test "$ac_test_CFLAGS" = set; then
- CFLAGS="$ac_save_CFLAGS"
- elif test $ac_cv_prog_cc_g = yes; then
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
CFLAGS="-g -O2"
else
- CFLAGS="-O2"
+ CFLAGS="-g"
fi
else
- GCC=
- test "${CFLAGS+set}" = set || CFLAGS="-g"
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
fi
ac_aux_dir=
@@ -792,28 +889,30 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:800: checking for a BSD compatible install" >&5
+echo "configure:898: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:"
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
for ac_dir in $PATH; do
# Account for people who put trailing slashes in PATH elements.
case "$ac_dir/" in
/|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
- for ac_prog in ginstall installbsd scoinst install; do
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
if test -f $ac_dir/$ac_prog; then
if test $ac_prog = install &&
grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
- # OSF/1 installbsd also uses dspmsg, but is usable.
:
else
ac_cv_path_install="$ac_dir/$ac_prog -c"
@@ -843,6 +942,8 @@ echo "$ac_t""$INSTALL" 1>&6
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
for ac_prog in mawk gawk nawk awk
@@ -850,15 +951,16 @@ do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:854: checking for $ac_word" >&5
+echo "configure:955: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$AWK"; then
ac_cv_prog_AWK="$AWK" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_AWK="$ac_prog"
@@ -879,101 +981,6 @@ test -n "$AWK" && break
done
-if test "x$CC" != xcc; then
- echo $ac_n "checking whether $CC and cc understand -c and -o together""... $ac_c" 1>&6
-echo "configure:885: checking whether $CC and cc understand -c and -o together" >&5
-else
- echo $ac_n "checking whether cc understands -c and -o together""... $ac_c" 1>&6
-echo "configure:888: checking whether cc understands -c and -o together" >&5
-fi
-set dummy $CC; ac_cc="`echo $2 |
- sed -e 's/[^a-zA-Z0-9_]/_/g' -e 's/^[0-9]/_/'`"
-if eval "test \"`echo '$''{'ac_cv_prog_cc_${ac_cc}_c_o'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- echo 'foo(){}' > conftest.c
-# Make sure it works both with $CC and with simple cc.
-# We do the test twice because some compilers refuse to overwrite an
-# existing .o file with -o, though they will create one.
-ac_try='${CC-cc} -c conftest.c -o conftest.o 1>&5'
-if { (eval echo configure:900: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
- test -f conftest.o && { (eval echo configure:901: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
-then
- eval ac_cv_prog_cc_${ac_cc}_c_o=yes
- if test "x$CC" != xcc; then
- # Test first that cc exists at all.
- if { ac_try='cc -c conftest.c 1>&5'; { (eval echo configure:906: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
- ac_try='cc -c conftest.c -o conftest.o 1>&5'
- if { (eval echo configure:908: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } &&
- test -f conftest.o && { (eval echo configure:909: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; };
- then
- # cc works too.
- :
- else
- # cc exists but doesn't like -o.
- eval ac_cv_prog_cc_${ac_cc}_c_o=no
- fi
- fi
- fi
-else
- eval ac_cv_prog_cc_${ac_cc}_c_o=no
-fi
-rm -f conftest*
-
-fi
-if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = yes"; then
- echo "$ac_t""yes" 1>&6
-else
- echo "$ac_t""no" 1>&6
- cat >> confdefs.h <<\EOF
-#define NO_MINUS_C_MINUS_O 1
-EOF
-
-fi
-
-if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
- BROKEN_CC=
-else
- BROKEN_CC=#
-fi
-
-
-echo $ac_n "checking that the C compiler understands volatile""... $ac_c" 1>&6
-echo "configure:943: checking that the C compiler understands volatile" >&5
-if eval "test \"`echo '$''{'samba_cv_volatile'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- cat > conftest.$ac_ext <<EOF
-#line 949 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-int main() {
-volatile int i = 0
-; return 0; }
-EOF
-if { (eval echo configure:956: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- samba_cv_volatile=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- samba_cv_volatile=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$samba_cv_volatile" 1>&6
-if test x"$samba_cv_volatile" = x"yes"; then
- cat >> confdefs.h <<\EOF
-#define HAVE_VOLATILE 1
-EOF
-
-fi
-
-
-
# Do some error checking and defaulting for the host and target type.
# The inputs are:
@@ -997,33 +1004,33 @@ esac
# Make sure we can run config.sub.
-if $ac_config_sub sun4 >/dev/null 2>&1; then :
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi
echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:1006: checking host system type" >&5
+echo "configure:1013: checking host system type" >&5
host_alias=$host
case "$host_alias" in
NONE)
case $nonopt in
NONE)
- if host_alias=`$ac_config_guess`; then :
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
fi ;;
*) host_alias=$nonopt ;;
esac ;;
esac
-host=`$ac_config_sub $host_alias`
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 1>&6
echo $ac_n "checking target system type""... $ac_c" 1>&6
-echo "configure:1027: checking target system type" >&5
+echo "configure:1034: checking target system type" >&5
target_alias=$target
case "$target_alias" in
@@ -1034,14 +1041,14 @@ NONE)
esac ;;
esac
-target=`$ac_config_sub $target_alias`
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$target" 1>&6
echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:1045: checking build system type" >&5
+echo "configure:1052: checking build system type" >&5
build_alias=$build
case "$build_alias" in
@@ -1052,7 +1059,7 @@ NONE)
esac ;;
esac
-build=`$ac_config_sub $build_alias`
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
@@ -1066,7 +1073,7 @@ test "$host_alias" != "$target_alias" &&
echo $ac_n "checking config.cache system type""... $ac_c" 1>&6
-echo "configure:1070: checking config.cache system type" >&5
+echo "configure:1077: checking config.cache system type" >&5
if { test x"${ac_cv_host_system_type+set}" = x"set" &&
test x"$ac_cv_host_system_type" != x"$host"; } ||
{ test x"${ac_cv_build_system_type+set}" = x"set" &&
@@ -1096,7 +1103,7 @@ fi
# Extract the first word of "autoconf", so it can be a program name with args.
set dummy autoconf; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1100: checking for $ac_word" >&5
+echo "configure:1107: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_AUTOCONF'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1104,9 +1111,13 @@ else
/*)
ac_cv_path_AUTOCONF="$AUTOCONF" # Let the user override the test with a path.
;;
+ ?:/*)
+ ac_cv_path_AUTOCONF="$AUTOCONF" # Let the user override the test with a dos path.
+ ;;
*)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_path_AUTOCONF="$ac_dir/$ac_word"
@@ -1129,7 +1140,7 @@ fi
# Extract the first word of "autoheader", so it can be a program name with args.
set dummy autoheader; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1133: checking for $ac_word" >&5
+echo "configure:1144: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_AUTOHEADER'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1137,9 +1148,13 @@ else
/*)
ac_cv_path_AUTOHEADER="$AUTOHEADER" # Let the user override the test with a path.
;;
+ ?:/*)
+ ac_cv_path_AUTOHEADER="$AUTOHEADER" # Let the user override the test with a dos path.
+ ;;
*)
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_path_AUTOHEADER="$ac_dir/$ac_word"
@@ -1169,7 +1184,7 @@ case "$host_os" in
# Try to work out if this is the native HPUX compiler that uses the -Ae flag.
*hpux*)
echo $ac_n "checking whether ${CC-cc} accepts -Ae""... $ac_c" 1>&6
-echo "configure:1173: checking whether ${CC-cc} accepts -Ae" >&5
+echo "configure:1188: checking whether ${CC-cc} accepts -Ae" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_Ae'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -1187,178 +1202,160 @@ echo "$ac_t""$ac_cv_prog_cc_Ae" 1>&6
if test $ac_cv_prog_cc_Ae = yes; then
CPPFLAGS="$CPPFLAGS -Ae"
fi
-#
-# Defines needed for HPUX support.
-# HPUX has bigcrypt but (sometimes?) doesn't use it for
-# password hashing - hence the USE_BOTH_CRYPT_CALLS define.
-#
- case `uname -r` in
- *9*|*10*)
- CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE"
- cat >> confdefs.h <<\EOF
-#define USE_BOTH_CRYPT_CALLS 1
-EOF
-
- ;;
- *11*)
- CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_LARGEFILE64_SOURCE"
- cat >> confdefs.h <<\EOF
-#define USE_BOTH_CRYPT_CALLS 1
-EOF
-
- ;;
- esac
;;
#
-# AIX4.x doesn't even admit to having large
+# AIX4.x is *so* broken. It doesn't even admit to having large
# files *at all* unless the -D_LARGE_FILE or -D_LARGE_FILE_API flags are set.
#
*aix4*)
- echo "$ac_t""enabling large file support" 1>&6
CPPFLAGS="$CPPFLAGS -D_LARGE_FILES"
;;
#
-# Defines needed for Solaris 2.6/2.7 aka 7.0 to make it admit
-# to the existance of large files..
-# Note that -D_LARGEFILE64_SOURCE is different from the Sun
-# recommendations on large file support, however it makes the
-# compile work using gcc 2.7 and 2.8, whereas using the Sun
-# recommendation makes the compile fail on gcc2.7. JRA.
+# Irix needs standards.h to detect netinet
#
- *solaris*)
- case `uname -r` in
- 5.6*|5.7*)
- echo "$ac_t""enabling large file support" 1>&6
- if test "$ac_cv_prog_gcc" = yes; then
- ${CC-cc} -v >conftest.c 2>&1
- ac_cv_gcc_compiler_version_number=`grep 'gcc version' conftest.c`
- rm -fr conftest.c
- case "$ac_cv_gcc_compiler_version_number" in
- *"gcc version 2.6"*|*"gcc version 2.7"*)
- CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE"
- ;;
- *)
- CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
- ;;
- esac
- else
- CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
- fi
- ;;
- esac
- ;;
-#
-# Tests needed for SINIX large file support.
-#
- *sysv4*)
- if test $host = mips-sni-sysv4 ; then
- echo $ac_n "checking for LFS support""... $ac_c" 1>&6
-echo "configure:1257: checking for LFS support" >&5
- old_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS"
- if test "$cross_compiling" = yes; then
- SINIX_LFS_SUPPORT=cross
+ *irix*)
+ echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1219: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
cat > conftest.$ac_ext <<EOF
-#line 1264 "configure"
+#line 1234 "configure"
#include "confdefs.h"
-
-#include <unistd.h>
-main () {
-#if _LFS64_LARGEFILE == 1
-exit(0);
-#else
-exit(1);
-#endif
-}
+#include <assert.h>
+Syntax Error
EOF
-if { (eval echo configure:1276: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- SINIX_LFS_SUPPORT=yes
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1240: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
else
+ echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
- rm -fr conftest*
- SINIX_LFS_SUPPORT=no
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1251 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1257: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1268 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1274: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
fi
-rm -fr conftest*
+rm -f conftest*
fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
- CPPFLAGS="$old_CPPFLAGS"
- if test x$SINIX_LFS_SUPPORT = xyes ; then
- CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS"
- CFLAGS="`getconf LFS64_CFLAGS` $CFLAGS"
- LDFLAGS="`getconf LFS64_LDFLAGS` $LDFLAGS"
- LIBS="`getconf LFS64_LIBS` $LIBS"
- fi
- echo "$ac_t""$SINIX_LFS_SUPPORT" 1>&6
- fi
- ;;
-
-#
-# Tests needed for glibc 2.1 large file support.
-#
- *linux*)
- echo "$ac_t""disabling large file support for glibc2.1 on Linux" 1>&6
- ;;
- *hurd*)
- echo $ac_n "checking for LFS support""... $ac_c" 1>&6
-echo "configure:1307: checking for LFS support" >&5
- old_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS"
- if test "$cross_compiling" = yes; then
- GLIBC_LFS_SUPPORT=cross
+for ac_hdr in standards.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1302: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1314 "configure"
+#line 1307 "configure"
#include "confdefs.h"
-
-#include <unistd.h>
-main () {
-#if _LFS64_LARGEFILE == 1
-exit(0);
-#else
-exit(1);
-#endif
-}
+#include <$ac_hdr>
EOF
-if { (eval echo configure:1326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- GLIBC_LFS_SUPPORT=yes
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1312: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
else
+ echo "$ac_err" >&5
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
- rm -fr conftest*
- GLIBC_LFS_SUPPORT=no
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
fi
-rm -fr conftest*
+rm -f conftest*
fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ cat >> confdefs.h <<EOF
+#include <standards.h>
+EOF
- CPPFLAGS="$old_CPPFLAGS"
- if test x$GLIBC_LFS_SUPPORT = xyes ; then
- CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS"
- fi
- echo "$ac_t""$GLIBC_LFS_SUPPORT" 1>&6
- ;;
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+ ;;
esac
echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:1348: checking for inline" >&5
+echo "configure:1345: checking for inline" >&5
if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
cat > conftest.$ac_ext <<EOF
-#line 1355 "configure"
+#line 1352 "configure"
#include "confdefs.h"
int main() {
} $ac_kw foo() {
; return 0; }
EOF
-if { (eval echo configure:1362: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1359: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
else
@@ -1383,74 +1380,13 @@ EOF
;;
esac
-echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1388: checking how to run the C preprocessor" >&5
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
-if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- # This must be in double quotes, not single quotes, because CPP may get
- # substituted into the Makefile and "${CC-cc}" will confuse make.
- CPP="${CC-cc} -E"
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp.
- cat > conftest.$ac_ext <<EOF
-#line 1403 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1409: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP="${CC-cc} -E -traditional-cpp"
- cat > conftest.$ac_ext <<EOF
-#line 1420 "configure"
-#include "confdefs.h"
-#include <assert.h>
-Syntax Error
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1426: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- :
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- CPP=/lib/cpp
-fi
-rm -f conftest*
-fi
-rm -f conftest*
- ac_cv_prog_CPP="$CPP"
-fi
- CPP="$ac_cv_prog_CPP"
-else
- ac_cv_prog_CPP="$CPP"
-fi
-echo "$ac_t""$CPP" 1>&6
-
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1449: checking for ANSI C header files" >&5
+echo "configure:1385: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1454 "configure"
+#line 1390 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
@@ -1458,8 +1394,8 @@ else
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1462: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1398: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
ac_cv_header_stdc=yes
@@ -1475,7 +1411,7 @@ rm -f conftest*
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1479 "configure"
+#line 1415 "configure"
#include "confdefs.h"
#include <string.h>
EOF
@@ -1493,7 +1429,7 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
-#line 1497 "configure"
+#line 1433 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
@@ -1514,7 +1450,7 @@ if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 1518 "configure"
+#line 1454 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1525,7 +1461,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }
EOF
-if { (eval echo configure:1529: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1465: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
:
else
@@ -1553,12 +1489,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:1557: checking for $ac_hdr that defines DIR" >&5
+echo "configure:1493: checking for $ac_hdr that defines DIR" >&5
if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1562 "configure"
+#line 1498 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_hdr>
@@ -1566,7 +1502,7 @@ int main() {
DIR *dirp = 0;
; return 0; }
EOF
-if { (eval echo configure:1570: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1506: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_header_dirent_$ac_safe=yes"
else
@@ -1591,7 +1527,7 @@ done
# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
if test $ac_header_dirent = dirent.h; then
echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:1595: checking for opendir in -ldir" >&5
+echo "configure:1531: checking for opendir in -ldir" >&5
ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1599,7 +1535,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldir $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1603 "configure"
+#line 1539 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1610,7 +1546,7 @@ int main() {
opendir()
; return 0; }
EOF
-if { (eval echo configure:1614: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1550: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1632,7 +1568,7 @@ fi
else
echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:1636: checking for opendir in -lx" >&5
+echo "configure:1572: checking for opendir in -lx" >&5
ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -1640,7 +1576,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lx $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1644 "configure"
+#line 1580 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -1651,7 +1587,7 @@ int main() {
opendir()
; return 0; }
EOF
-if { (eval echo configure:1655: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1591: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -1674,12 +1610,12 @@ fi
fi
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:1678: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1614: checking whether time.h and sys/time.h may both be included" >&5
if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1683 "configure"
+#line 1619 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
@@ -1688,7 +1624,7 @@ int main() {
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:1692: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1628: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
@@ -1709,12 +1645,12 @@ EOF
fi
echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1713: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1649: checking for sys/wait.h that is POSIX.1 compatible" >&5
if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1718 "configure"
+#line 1654 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
@@ -1730,7 +1666,7 @@ wait (&s);
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
-if { (eval echo configure:1734: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1670: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_sys_wait_h=yes
else
@@ -1750,22 +1686,22 @@ EOF
fi
-for ac_hdr in arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h
+for ac_hdr in sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1758: checking for $ac_hdr" >&5
+echo "configure:1694: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1763 "configure"
+#line 1699 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1768: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1704: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -1790,22 +1726,22 @@ else
fi
done
-for ac_hdr in unistd.h utime.h grp.h sys/id.h limits.h memory.h net/if.h
+for ac_hdr in sys/param.h ctype.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1798: checking for $ac_hdr" >&5
+echo "configure:1734: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1803 "configure"
+#line 1739 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1808: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1744: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -1830,22 +1766,22 @@ else
fi
done
-for ac_hdr in compat.h rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h
+for ac_hdr in unistd.h utime.h grp.h sys/id.h limits.h memory.h net/route.h net/if.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1838: checking for $ac_hdr" >&5
+echo "configure:1774: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1843 "configure"
+#line 1779 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1848: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1784: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -1870,22 +1806,22 @@ else
fi
done
-for ac_hdr in sys/param.h ctype.h sys/un.h sys/wait.h sys/resource.h sys/ioctl.h sys/mode.h
+for ac_hdr in compat.h rpc/rpc.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h sys/param.h ctype.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1878: checking for $ac_hdr" >&5
+echo "configure:1814: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1883 "configure"
+#line 1819 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1888: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1824: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -1910,22 +1846,22 @@ else
fi
done
-for ac_hdr in sys/mman.h sys/filio.h sys/priv.h string.h strings.h stdlib.h sys/socket.h
+for ac_hdr in sys/wait.h sys/resource.h sys/ioctl.h sys/mode.h sys/mman.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1918: checking for $ac_hdr" >&5
+echo "configure:1854: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1923 "configure"
+#line 1859 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1928: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1864: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -1950,22 +1886,22 @@ else
fi
done
-for ac_hdr in sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h
+for ac_hdr in sys/filio.h string.h strings.h stdlib.h sys/socket.h sys/un.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1958: checking for $ac_hdr" >&5
+echo "configure:1894: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 1963 "configure"
+#line 1899 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1968: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1904: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -1990,22 +1926,22 @@ else
fi
done
-for ac_hdr in sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h
+for ac_hdr in sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1998: checking for $ac_hdr" >&5
+echo "configure:1934: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2003 "configure"
+#line 1939 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2008: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1944: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -2030,54 +1966,22 @@ else
fi
done
-#
-# HPUX has a bug in that including shadow.h causes a re-definition of MAXINT.
-# This causes configure to fail to detect it. Check for shadow separately on HPUX.
-#
-case "$host_os" in
- *hpux*)
- cat > conftest.$ac_ext <<EOF
-#line 2041 "configure"
-#include "confdefs.h"
-#include <shadow.h>
-int main() {
-struct spwd testme
-; return 0; }
-EOF
-if { (eval echo configure:2048: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- ac_cv_header_shadow_h=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- ac_cv_header_shadow_h=no
-fi
-rm -f conftest*
- if test x"$ac_cv_header_shadow_h" = x"yes"; then
- cat >> confdefs.h <<\EOF
-#define HAVE_SHADOW_H 1
-EOF
-
- fi
- ;;
-esac
-for ac_hdr in shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h
+for ac_hdr in sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2070: checking for $ac_hdr" >&5
+echo "configure:1974: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2075 "configure"
+#line 1979 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2080: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:1984: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -2102,22 +2006,22 @@ else
fi
done
-for ac_hdr in sys/security.h security/pam_appl.h
+for ac_hdr in shadow.h netinet/tcp.h sys/security.h security/pam_appl.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2110: checking for $ac_hdr" >&5
+echo "configure:2014: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2115 "configure"
+#line 2019 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2120: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:2024: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -2146,18 +2050,18 @@ for ac_hdr in stropts.h poll.h readline.h history.h readline/readline.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2150: checking for $ac_hdr" >&5
+echo "configure:2054: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2155 "configure"
+#line 2059 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2160: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:2064: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -2186,18 +2090,18 @@ for ac_hdr in readline/history.h sys/capability.h syscall.h sys/syscall.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2190: checking for $ac_hdr" >&5
+echo "configure:2094: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2195 "configure"
+#line 2099 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2200: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:2104: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -2222,64 +2126,22 @@ else
fi
done
-for ac_hdr in sys/acl.h sys/cdefs.h glob.h
+for ac_hdr in sys/acl.h sys/cdefs.h glob.h mysql.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2230: checking for $ac_hdr" >&5
+echo "configure:2134: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2235 "configure"
+#line 2139 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2240: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
-if test -z "$ac_err"; then
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=yes"
-else
- echo "$ac_err" >&5
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_header_$ac_safe=no"
-fi
-rm -f conftest*
-fi
-if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-
-# For experimental utmp support
-for ac_hdr in utmp.h utmpx.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2272: checking for $ac_hdr" >&5
-if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 2277 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
-EOF
-ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2282: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
-ac_err=`grep -v '^ *+' conftest.out`
+{ (eval echo configure:2144: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
eval "ac_cv_header_$ac_safe=yes"
@@ -2306,7 +2168,7 @@ done
echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:2310: checking size of int" >&5
+echo "configure:2172: checking size of int" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2314,7 +2176,7 @@ else
ac_cv_sizeof_int=cross
else
cat > conftest.$ac_ext <<EOF
-#line 2318 "configure"
+#line 2180 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -2325,7 +2187,7 @@ main()
exit(0);
}
EOF
-if { (eval echo configure:2329: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2191: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_int=`cat conftestval`
else
@@ -2345,7 +2207,7 @@ EOF
echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:2349: checking size of long" >&5
+echo "configure:2211: checking size of long" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2353,7 +2215,7 @@ else
ac_cv_sizeof_long=cross
else
cat > conftest.$ac_ext <<EOF
-#line 2357 "configure"
+#line 2219 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -2364,7 +2226,7 @@ main()
exit(0);
}
EOF
-if { (eval echo configure:2368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_long=`cat conftestval`
else
@@ -2384,7 +2246,7 @@ EOF
echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:2388: checking size of short" >&5
+echo "configure:2250: checking size of short" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -2392,7 +2254,7 @@ else
ac_cv_sizeof_short=cross
else
cat > conftest.$ac_ext <<EOF
-#line 2396 "configure"
+#line 2258 "configure"
#include "confdefs.h"
#include <stdio.h>
main()
@@ -2403,7 +2265,7 @@ main()
exit(0);
}
EOF
-if { (eval echo configure:2407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_sizeof_short=`cat conftestval`
else
@@ -2424,12 +2286,12 @@ EOF
echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2428: checking for working const" >&5
+echo "configure:2290: checking for working const" >&5
if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2433 "configure"
+#line 2295 "configure"
#include "confdefs.h"
int main() {
@@ -2478,7 +2340,7 @@ ccp = (char const *const *) p;
; return 0; }
EOF
-if { (eval echo configure:2482: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2344: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_const=yes
else
@@ -2499,21 +2361,21 @@ EOF
fi
echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:2503: checking for inline" >&5
+echo "configure:2365: checking for inline" >&5
if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
cat > conftest.$ac_ext <<EOF
-#line 2510 "configure"
+#line 2372 "configure"
#include "confdefs.h"
int main() {
} $ac_kw foo() {
; return 0; }
EOF
-if { (eval echo configure:2517: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2379: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_inline=$ac_kw; break
else
@@ -2539,14 +2401,14 @@ EOF
esac
echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:2543: checking whether byte ordering is bigendian" >&5
+echo "configure:2405: checking whether byte ordering is bigendian" >&5
if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_bigendian=unknown
# See if sys/param.h defines the BYTE_ORDER macro.
cat > conftest.$ac_ext <<EOF
-#line 2550 "configure"
+#line 2412 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
@@ -2557,11 +2419,11 @@ int main() {
#endif
; return 0; }
EOF
-if { (eval echo configure:2561: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2423: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
# It does; now see whether it defined to BIG_ENDIAN or not.
cat > conftest.$ac_ext <<EOF
-#line 2565 "configure"
+#line 2427 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
@@ -2572,7 +2434,7 @@ int main() {
#endif
; return 0; }
EOF
-if { (eval echo configure:2576: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2438: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_bigendian=yes
else
@@ -2592,7 +2454,7 @@ if test "$cross_compiling" = yes; then
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 2596 "configure"
+#line 2458 "configure"
#include "confdefs.h"
main () {
/* Are we little or big endian? From Harbison&Steele. */
@@ -2605,7 +2467,7 @@ main () {
exit (u.c[sizeof (long) - 1] == 1);
}
EOF
-if { (eval echo configure:2609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_c_bigendian=no
else
@@ -2629,14 +2491,14 @@ EOF
fi
echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
-echo "configure:2633: checking whether char is unsigned" >&5
+echo "configure:2495: checking whether char is unsigned" >&5
if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$GCC" = yes; then
# GCC predefines this symbol on systems where it applies.
cat > conftest.$ac_ext <<EOF
-#line 2640 "configure"
+#line 2502 "configure"
#include "confdefs.h"
#ifdef __CHAR_UNSIGNED__
yes
@@ -2658,7 +2520,7 @@ if test "$cross_compiling" = yes; then
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 2662 "configure"
+#line 2524 "configure"
#include "confdefs.h"
/* volatile prevents gcc2 from optimizing the test away on sparcs. */
#if !defined(__STDC__) || __STDC__ != 1
@@ -2668,7 +2530,7 @@ main() {
volatile char c = 255; exit(c < 0);
}
EOF
-if { (eval echo configure:2672: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2534: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_c_char_unsigned=yes
else
@@ -2692,13 +2554,424 @@ EOF
fi
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=no
+fi
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2630: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:2669: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:2693: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:2696: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:2731: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:2747: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:2783: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$lt_target" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 2832 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:2833: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:2854: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2859 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:2697: checking return type of signal handlers" >&5
+echo "configure:2970: checking return type of signal handlers" >&5
if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2702 "configure"
+#line 2975 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <signal.h>
@@ -2715,7 +2988,7 @@ int main() {
int i;
; return 0; }
EOF
-if { (eval echo configure:2719: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2992: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_type_signal=void
else
@@ -2734,12 +3007,12 @@ EOF
echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:2738: checking for uid_t in sys/types.h" >&5
+echo "configure:3011: checking for uid_t in sys/types.h" >&5
if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2743 "configure"
+#line 3016 "configure"
#include "confdefs.h"
#include <sys/types.h>
EOF
@@ -2768,12 +3041,12 @@ EOF
fi
echo $ac_n "checking for mode_t""... $ac_c" 1>&6
-echo "configure:2772: checking for mode_t" >&5
+echo "configure:3045: checking for mode_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2777 "configure"
+#line 3050 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -2782,7 +3055,7 @@ else
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ egrep "(^|[^a-zA-Z_0-9])mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_mode_t=yes
else
@@ -2801,12 +3074,12 @@ EOF
fi
echo $ac_n "checking for off_t""... $ac_c" 1>&6
-echo "configure:2805: checking for off_t" >&5
+echo "configure:3078: checking for off_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2810 "configure"
+#line 3083 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -2815,7 +3088,7 @@ else
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_off_t=yes
else
@@ -2834,12 +3107,12 @@ EOF
fi
echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:2838: checking for size_t" >&5
+echo "configure:3111: checking for size_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2843 "configure"
+#line 3116 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -2848,7 +3121,7 @@ else
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_size_t=yes
else
@@ -2867,12 +3140,12 @@ EOF
fi
echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:2871: checking for pid_t" >&5
+echo "configure:3144: checking for pid_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2876 "configure"
+#line 3149 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -2881,7 +3154,7 @@ else
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_pid_t=yes
else
@@ -2900,12 +3173,12 @@ EOF
fi
echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
-echo "configure:2904: checking for st_rdev in struct stat" >&5
+echo "configure:3177: checking for st_rdev in struct stat" >&5
if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2909 "configure"
+#line 3182 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
@@ -2913,7 +3186,7 @@ int main() {
struct stat s; s.st_rdev;
; return 0; }
EOF
-if { (eval echo configure:2917: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3190: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_st_rdev=yes
else
@@ -2934,12 +3207,12 @@ EOF
fi
echo $ac_n "checking for d_off in dirent""... $ac_c" 1>&6
-echo "configure:2938: checking for d_off in dirent" >&5
+echo "configure:3211: checking for d_off in dirent" >&5
if eval "test \"`echo '$''{'ac_cv_dirent_d_off'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2943 "configure"
+#line 3216 "configure"
#include "confdefs.h"
#include <unistd.h>
@@ -2949,7 +3222,7 @@ int main() {
struct dirent d; d.d_off;
; return 0; }
EOF
-if { (eval echo configure:2953: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3226: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_dirent_d_off=yes
else
@@ -2970,12 +3243,12 @@ EOF
fi
echo $ac_n "checking for ino_t""... $ac_c" 1>&6
-echo "configure:2974: checking for ino_t" >&5
+echo "configure:3247: checking for ino_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_ino_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2979 "configure"
+#line 3252 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -2984,7 +3257,7 @@ else
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "ino_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ egrep "(^|[^a-zA-Z_0-9])ino_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_ino_t=yes
else
@@ -3003,12 +3276,12 @@ EOF
fi
echo $ac_n "checking for loff_t""... $ac_c" 1>&6
-echo "configure:3007: checking for loff_t" >&5
+echo "configure:3280: checking for loff_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_loff_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3012 "configure"
+#line 3285 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3017,7 +3290,7 @@ else
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "loff_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ egrep "(^|[^a-zA-Z_0-9])loff_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_loff_t=yes
else
@@ -3036,12 +3309,12 @@ EOF
fi
echo $ac_n "checking for offset_t""... $ac_c" 1>&6
-echo "configure:3040: checking for offset_t" >&5
+echo "configure:3313: checking for offset_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_offset_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3045 "configure"
+#line 3318 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3050,7 +3323,7 @@ else
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "offset_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ egrep "(^|[^a-zA-Z_0-9])offset_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_offset_t=yes
else
@@ -3069,12 +3342,12 @@ EOF
fi
echo $ac_n "checking for ssize_t""... $ac_c" 1>&6
-echo "configure:3073: checking for ssize_t" >&5
+echo "configure:3346: checking for ssize_t" >&5
if eval "test \"`echo '$''{'ac_cv_type_ssize_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3078 "configure"
+#line 3351 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if STDC_HEADERS
@@ -3083,7 +3356,7 @@ else
#endif
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "ssize_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ egrep "(^|[^a-zA-Z_0-9])ssize_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
rm -rf conftest*
ac_cv_type_ssize_t=yes
else
@@ -3101,197 +3374,29 @@ EOF
fi
-echo $ac_n "checking for wchar_t""... $ac_c" 1>&6
-echo "configure:3106: checking for wchar_t" >&5
-if eval "test \"`echo '$''{'ac_cv_type_wchar_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3111 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-EOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- egrep "wchar_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
- rm -rf conftest*
- ac_cv_type_wchar_t=yes
-else
- rm -rf conftest*
- ac_cv_type_wchar_t=no
-fi
-rm -f conftest*
-
-fi
-echo "$ac_t""$ac_cv_type_wchar_t" 1>&6
-if test $ac_cv_type_wchar_t = no; then
- cat >> confdefs.h <<\EOF
-#define wchar_t unsigned short
-EOF
-
-fi
-
-
-# we need libcups for CUPS support...
-echo $ac_n "checking for httpConnect in -lcups""... $ac_c" 1>&6
-echo "configure:3141: checking for httpConnect in -lcups" >&5
-ac_lib_var=`echo cups'_'httpConnect | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lcups $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 3149 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char httpConnect();
-
-int main() {
-httpConnect()
-; return 0; }
-EOF
-if { (eval echo configure:3160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo cups | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lcups $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-# we need libdl for PAM and the new VFS code
-echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:3190: checking for dlopen in -ldl" >&5
-ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-ldl $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 3198 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char dlopen();
-
-int main() {
-dlopen()
-; return 0; }
-EOF
-if { (eval echo configure:3209: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- LIBS="$LIBS -ldl";
- cat >> confdefs.h <<\EOF
-#define HAVE_LIBDL 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-
-echo $ac_n "checking for sig_atomic_t type""... $ac_c" 1>&6
-echo "configure:3235: checking for sig_atomic_t type" >&5
-if eval "test \"`echo '$''{'samba_cv_sig_atomic_t'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- cat > conftest.$ac_ext <<EOF
-#line 3241 "configure"
-#include "confdefs.h"
-
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-#include <signal.h>
-int main() {
-sig_atomic_t i = 0
-; return 0; }
-EOF
-if { (eval echo configure:3254: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- samba_cv_sig_atomic_t=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- samba_cv_sig_atomic_t=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$samba_cv_sig_atomic_t" 1>&6
-if test x"$samba_cv_sig_atomic_t" = x"yes"; then
- cat >> confdefs.h <<\EOF
-#define HAVE_SIG_ATOMIC_T_TYPE 1
-EOF
-
-fi
echo $ac_n "checking for errno in errno.h""... $ac_c" 1>&6
-echo "configure:3275: checking for errno in errno.h" >&5
+echo "configure:3380: checking for errno in errno.h" >&5
if eval "test \"`echo '$''{'samba_cv_errno'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3281 "configure"
+#line 3386 "configure"
#include "confdefs.h"
#include <errno.h>
int main() {
int i = errno
; return 0; }
EOF
-if { (eval echo configure:3288: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3393: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_errno=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
- samba_cv_have_errno=no
+ samba_cv_have_errno_decl=no
fi
rm -f conftest*
fi
@@ -3306,20 +3411,20 @@ fi
# stupid glibc has the functions but no declaration. grrrr.
echo $ac_n "checking for setresuid declaration""... $ac_c" 1>&6
-echo "configure:3310: checking for setresuid declaration" >&5
+echo "configure:3415: checking for setresuid declaration" >&5
if eval "test \"`echo '$''{'samba_cv_have_setresuid_decl'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3316 "configure"
+#line 3421 "configure"
#include "confdefs.h"
#include <unistd.h>
int main() {
int i = (int)setresuid
; return 0; }
EOF
-if { (eval echo configure:3323: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3428: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_have_setresuid_decl=yes
else
@@ -3340,36 +3445,36 @@ EOF
fi
# stupid glibc has the functions but no declaration. grrrr.
-echo $ac_n "checking for setresgid declaration""... $ac_c" 1>&6
-echo "configure:3345: checking for setresgid declaration" >&5
-if eval "test \"`echo '$''{'samba_cv_have_setresgid_decl'+set}'`\" = set"; then
+echo $ac_n "checking for crypt declaration""... $ac_c" 1>&6
+echo "configure:3450: checking for crypt declaration" >&5
+if eval "test \"`echo '$''{'samba_cv_have_crypt_decl'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3351 "configure"
+#line 3456 "configure"
#include "confdefs.h"
#include <unistd.h>
int main() {
-int i = (int)setresgid
+int i = (int)crypt
; return 0; }
EOF
-if { (eval echo configure:3358: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3463: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
- samba_cv_have_setresgid_decl=yes
+ samba_cv_have_crypt_decl=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -rf conftest*
- samba_cv_have_setresgid_decl=no
+ samba_cv_have_crypt_decl=no
fi
rm -f conftest*
fi
-echo "$ac_t""$samba_cv_have_setresgid_decl" 1>&6
-if test x"$samba_cv_have_setresgid_decl" = x"yes"; then
+echo "$ac_t""$samba_cv_have_crypt_decl" 1>&6
+if test x"$samba_cv_have_crypt_decl" = x"yes"; then
cat >> confdefs.h <<\EOF
-#define HAVE_SETRESGID_DECL 1
+#define HAVE_CRYPT_DECL 1
EOF
fi
@@ -3377,7 +3482,7 @@ fi
# and glibc has setresuid under linux but the function does
# nothing until kernel 2.1.44! very dumb.
echo $ac_n "checking for real setresuid""... $ac_c" 1>&6
-echo "configure:3381: checking for real setresuid" >&5
+echo "configure:3486: checking for real setresuid" >&5
if eval "test \"`echo '$''{'samba_cv_have_setresuid'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3386,12 +3491,12 @@ else
samba_cv_have_setresuid=cross
else
cat > conftest.$ac_ext <<EOF
-#line 3390 "configure"
+#line 3495 "configure"
#include "confdefs.h"
#include <errno.h>
main() { setresuid(1,1,1); setresuid(2,2,2); exit(errno==EPERM?0:1);}
EOF
-if { (eval echo configure:3395: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3500: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_have_setresuid=yes
else
@@ -3413,48 +3518,8 @@ EOF
fi
-# Do the same check for setresguid...
-#
-echo $ac_n "checking for real setresgid""... $ac_c" 1>&6
-echo "configure:3420: checking for real setresgid" >&5
-if eval "test \"`echo '$''{'samba_cv_have_setresgid'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
- if test "$cross_compiling" = yes; then
- samba_cv_have_setresgid=cross
-else
- cat > conftest.$ac_ext <<EOF
-#line 3429 "configure"
-#include "confdefs.h"
-#include <unistd.h>
-#include <errno.h>
-main() { errno = 0; setresgid(1,1,1); exit(errno != 0 ? (errno==EPERM ? 0 : 1) : 0);}
-EOF
-if { (eval echo configure:3435: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- samba_cv_have_setresgid=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- samba_cv_have_setresgid=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$samba_cv_have_setresgid" 1>&6
-if test x"$samba_cv_have_setresgid" = x"yes"; then
- cat >> confdefs.h <<\EOF
-#define HAVE_SETRESGID 1
-EOF
-
-fi
-
echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
-echo "configure:3458: checking for 8-bit clean memcmp" >&5
+echo "configure:3523: checking for 8-bit clean memcmp" >&5
if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3462,7 +3527,7 @@ else
ac_cv_func_memcmp_clean=no
else
cat > conftest.$ac_ext <<EOF
-#line 3466 "configure"
+#line 3531 "configure"
#include "confdefs.h"
main()
@@ -3472,7 +3537,7 @@ main()
}
EOF
-if { (eval echo configure:3476: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3541: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_memcmp_clean=yes
else
@@ -3487,7 +3552,7 @@ fi
fi
echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
-test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.o"
+test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
###############################################
@@ -3495,12 +3560,12 @@ test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.o"
for ac_func in crypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3499: checking for $ac_func" >&5
+echo "configure:3564: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3504 "configure"
+#line 3569 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3523,7 +3588,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3527: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3592: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -3549,7 +3614,7 @@ done
if test x"$ac_cv_func_crypt" = x"no"; then
echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:3553: checking for crypt in -lcrypt" >&5
+echo "configure:3618: checking for crypt in -lcrypt" >&5
ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3557,7 +3622,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lcrypt $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3561 "configure"
+#line 3626 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3568,7 +3633,7 @@ int main() {
crypt()
; return 0; }
EOF
-if { (eval echo configure:3572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3637: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3596,11 +3661,256 @@ fi
###############################################
-# test for where we get readline() from
+# test for where we get pam_authenticate() from
+# might need libdl for this to work
+if test "$ac_cv_header_security_pam_appl_h" = "yes"; then
+ echo $ac_n "checking for main in -ldl""... $ac_c" 1>&6
+echo "configure:3669: checking for main in -ldl" >&5
+ac_lib_var=`echo dl'_'main | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3677 "configure"
+#include "confdefs.h"
+
+int main() {
+main()
+; return 0; }
+EOF
+if { (eval echo configure:3684: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo dl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-ldl $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+for ac_func in pam_authenticate
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3715: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3720 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3743: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+if test x"$ac_cv_func_pam_authenticate" = x"no"; then
+ echo $ac_n "checking for pam_authenticate in -lpam""... $ac_c" 1>&6
+echo "configure:3769: checking for pam_authenticate in -lpam" >&5
+ac_lib_var=`echo pam'_'pam_authenticate | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lpam $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3777 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char pam_authenticate();
+
+int main() {
+pam_authenticate()
+; return 0; }
+EOF
+if { (eval echo configure:3788: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lpam"
+ cat >> confdefs.h <<\EOF
+#define HAVE_PAM_AUTHENTICATE 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+###############################################
+# readline requires some curses routines
if test "$ac_cv_header_readline_h" = "yes" ||
test "$ac_cv_header_readline_readline_h" = "yes"; then
+ for ac_func in tputs
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:3821: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 3826 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:3849: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ echo $ac_n "checking for tputs in -lcurses""... $ac_c" 1>&6
+echo "configure:3874: checking for tputs in -lcurses" >&5
+ac_lib_var=`echo curses'_'tputs | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcurses $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3882 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char tputs();
+
+int main() {
+tputs()
+; return 0; }
+EOF
+if { (eval echo configure:3893: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lcurses"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6
-echo "configure:3604: checking for readline in -lreadline" >&5
+echo "configure:3914: checking for readline in -lreadline" >&5
ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3608,7 +3918,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lreadline $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3612 "configure"
+#line 3922 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3619,7 +3929,7 @@ int main() {
readline()
; return 0; }
EOF
-if { (eval echo configure:3623: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:3933: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3646,8 +3956,45 @@ else
echo "$ac_t""no" 1>&6
fi
+ echo $ac_n "checking for filename_completion_function proto""... $ac_c" 1>&6
+echo "configure:3961: checking for filename_completion_function proto" >&5
+if eval "test \"`echo '$''{'samba_cv_have_fcf_proto'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ cat > conftest.$ac_ext <<EOF
+#line 3967 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+#ifdef HAVE_READLINE_H
+#include <readline.h>
+#else
+#include <readline/readline.h>
+#endif
+int main() {
+filename_completion_function
+; return 0; }
+EOF
+if { (eval echo configure:3979: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ samba_cv_have_fcf_proto=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ samba_cv_have_fcf_proto=no
fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$samba_cv_have_fcf_proto" 1>&6
+ if test x"$samba_cv_have_fcf_proto" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_READLINE_FCF_PROTO 1
+EOF
+ fi
+fi
# The following test taken from the cvs sources
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
@@ -3658,12 +4005,12 @@ fi
for ac_func in connect
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3662: checking for $ac_func" >&5
+echo "configure:4009: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3667 "configure"
+#line 4014 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3686,7 +4033,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3690: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4037: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -3714,7 +4061,7 @@ if test x"$ac_cv_func_connect" = x"no"; then
case "$LIBS" in
*-lnsl*) ;;
*) echo $ac_n "checking for printf in -lnsl_s""... $ac_c" 1>&6
-echo "configure:3718: checking for printf in -lnsl_s" >&5
+echo "configure:4065: checking for printf in -lnsl_s" >&5
ac_lib_var=`echo nsl_s'_'printf | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3722,7 +4069,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl_s $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3726 "configure"
+#line 4073 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3733,7 +4080,7 @@ int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:3737: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4084: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3764,7 +4111,7 @@ fi
case "$LIBS" in
*-lnsl*) ;;
*) echo $ac_n "checking for printf in -lnsl""... $ac_c" 1>&6
-echo "configure:3768: checking for printf in -lnsl" >&5
+echo "configure:4115: checking for printf in -lnsl" >&5
ac_lib_var=`echo nsl'_'printf | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3772,7 +4119,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lnsl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3776 "configure"
+#line 4123 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3783,7 +4130,7 @@ int main() {
printf()
; return 0; }
EOF
-if { (eval echo configure:3787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3814,7 +4161,7 @@ fi
case "$LIBS" in
*-lsocket*) ;;
*) echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
-echo "configure:3818: checking for connect in -lsocket" >&5
+echo "configure:4165: checking for connect in -lsocket" >&5
ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3822,7 +4169,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsocket $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3826 "configure"
+#line 4173 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3833,7 +4180,7 @@ int main() {
connect()
; return 0; }
EOF
-if { (eval echo configure:3837: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4184: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3864,7 +4211,7 @@ fi
case "$LIBS" in
*-linet*) ;;
*) echo $ac_n "checking for connect in -linet""... $ac_c" 1>&6
-echo "configure:3868: checking for connect in -linet" >&5
+echo "configure:4215: checking for connect in -linet" >&5
ac_lib_var=`echo inet'_'connect | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3872,7 +4219,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-linet $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3876 "configure"
+#line 4223 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3883,7 +4230,7 @@ int main() {
connect()
; return 0; }
EOF
-if { (eval echo configure:3887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3922,77 +4269,16 @@ EOF
fi
fi
-# Check if we have execl, if not we need to compile smbrun.
-for ac_func in execl
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3930: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 3935 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:3958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
-if test x"$ac_cv_func_execl" = x"no"; then
- RUNPROG="bin/smbrun"
-else
- RUNPROG=""
-fi
for ac_func in waitpid getcwd strdup strtoul strerror chown chmod chroot
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3991: checking for $ac_func" >&5
+echo "configure:4277: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3996 "configure"
+#line 4282 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4015,7 +4301,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4019: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4305: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4039,15 +4325,15 @@ else
fi
done
-for ac_func in fstat strchr utime utimes getrlimit fsync bzero memset
+for ac_func in fstat strchr utime utimes getrlimit fsync execl bzero memset
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4046: checking for $ac_func" >&5
+echo "configure:4332: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4051 "configure"
+#line 4337 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4070,7 +4356,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4360: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4097,12 +4383,12 @@ done
for ac_func in memmove vsnprintf snprintf setsid glob strpbrk pipe crypt16 getauthuid
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4101: checking for $ac_func" >&5
+echo "configure:4387: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4106 "configure"
+#line 4392 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4125,7 +4411,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4415: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4152,12 +4438,12 @@ done
for ac_func in strftime sigprocmask sigblock sigaction innetgr setnetgrent getnetgrent endnetgrent
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4156: checking for $ac_func" >&5
+echo "configure:4442: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4161 "configure"
+#line 4447 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4180,7 +4466,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4184: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4470: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4204,15 +4490,15 @@ else
fi
done
-for ac_func in initgroups select rdchk getgrnam getgrent pathconf
+for ac_func in initgroups select rdchk getgrnam pathconf
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4211: checking for $ac_func" >&5
+echo "configure:4497: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4216 "configure"
+#line 4502 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4235,7 +4521,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4525: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4259,15 +4545,15 @@ else
fi
done
-for ac_func in setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate stat64 fstat64
+for ac_func in setuidx setgroups mktime rename ftruncate stat64 fstat64 lstat64 fopen64
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4266: checking for $ac_func" >&5
+echo "configure:4552: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4271 "configure"
+#line 4557 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4290,7 +4576,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4294: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4580: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4314,15 +4600,15 @@ else
fi
done
-for ac_func in lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64
+for ac_func in atexit grantpt dup2 lseek64 ftruncate64
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4321: checking for $ac_func" >&5
+echo "configure:4607: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4326 "configure"
+#line 4612 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4345,7 +4631,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4349: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4635: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4369,15 +4655,15 @@ else
fi
done
-for ac_func in fseek64 fseeko64 ftell64 ftello64 setluid yp_get_default_domain getpwanam
+for ac_func in fseek64 ftell64 setluid yp_get_default_domain getpwanam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4376: checking for $ac_func" >&5
+echo "configure:4662: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4381 "configure"
+#line 4667 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4400,7 +4686,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4404: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4690: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4424,15 +4710,15 @@ else
fi
done
-for ac_func in srandom random srand rand setenv usleep mmap64 strcasecmp fcvt fcvtl
+for ac_func in srandom random srand rand setenv mmap64
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4431: checking for $ac_func" >&5
+echo "configure:4717: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4436 "configure"
+#line 4722 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4455,7 +4741,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4479,17 +4765,16 @@ else
fi
done
-
# syscall() is needed for smbwrapper.
for ac_func in syscall
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4488: checking for $ac_func" >&5
+echo "configure:4773: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4493 "configure"
+#line 4778 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4512,7 +4797,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4801: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4540,12 +4825,12 @@ done
for ac_func in _dup _dup2 _opendir _readdir _seekdir _telldir _closedir
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4544: checking for $ac_func" >&5
+echo "configure:4829: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4549 "configure"
+#line 4834 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4568,7 +4853,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4857: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4595,12 +4880,12 @@ done
for ac_func in __dup __dup2 __opendir __readdir __seekdir __telldir __closedir
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4599: checking for $ac_func" >&5
+echo "configure:4884: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4604 "configure"
+#line 4889 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4623,7 +4908,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4912: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4650,12 +4935,12 @@ done
for ac_func in __getcwd _getcwd
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4654: checking for $ac_func" >&5
+echo "configure:4939: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4659 "configure"
+#line 4944 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4678,7 +4963,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:4967: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4705,12 +4990,12 @@ done
for ac_func in __xstat __fxstat __lxstat
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4709: checking for $ac_func" >&5
+echo "configure:4994: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4714 "configure"
+#line 4999 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4733,7 +5018,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4737: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4760,12 +5045,12 @@ done
for ac_func in _stat _lstat _fstat __stat __lstat __fstat
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4764: checking for $ac_func" >&5
+echo "configure:5049: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4769 "configure"
+#line 5054 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4788,7 +5073,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4792: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5077: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4815,12 +5100,12 @@ done
for ac_func in _acl __acl _facl __facl _open __open _chdir __chdir
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4819: checking for $ac_func" >&5
+echo "configure:5104: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4824 "configure"
+#line 5109 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4843,7 +5128,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4847: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4870,12 +5155,12 @@ done
for ac_func in _close __close _fchdir __fchdir _fcntl __fcntl
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4874: checking for $ac_func" >&5
+echo "configure:5159: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4879 "configure"
+#line 5164 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4898,7 +5183,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5187: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4925,12 +5210,12 @@ done
for ac_func in getdents _getdents __getdents _lseek __lseek _read __read
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4929: checking for $ac_func" >&5
+echo "configure:5214: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4934 "configure"
+#line 5219 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4953,7 +5238,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5242: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4980,12 +5265,12 @@ done
for ac_func in _write __write _fork __fork
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4984: checking for $ac_func" >&5
+echo "configure:5269: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4989 "configure"
+#line 5274 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5008,7 +5293,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5297: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5035,12 +5320,12 @@ done
for ac_func in _stat64 __stat64 _fstat64 __fstat64 _lstat64 __lstat64
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5039: checking for $ac_func" >&5
+echo "configure:5324: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5044 "configure"
+#line 5329 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5063,7 +5348,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5067: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5090,12 +5375,12 @@ done
for ac_func in __sys_llseek llseek _llseek __llseek readdir64 _readdir64 __readdir64
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5094: checking for $ac_func" >&5
+echo "configure:5379: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5099 "configure"
+#line 5384 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5118,7 +5403,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5122: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5145,12 +5430,12 @@ done
for ac_func in pread _pread __pread pread64 _pread64 __pread64
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5149: checking for $ac_func" >&5
+echo "configure:5434: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5154 "configure"
+#line 5439 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5173,7 +5458,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5177: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5200,12 +5485,12 @@ done
for ac_func in pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5204: checking for $ac_func" >&5
+echo "configure:5489: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5209 "configure"
+#line 5494 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5228,7 +5513,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5232: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5517: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5255,12 +5540,12 @@ done
for ac_func in open64 _open64 __open64 creat64
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5259: checking for $ac_func" >&5
+echo "configure:5544: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5264 "configure"
+#line 5549 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5283,7 +5568,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5572: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5309,162 +5594,6 @@ done
#
-# stat64 family may need <sys/stat.h> on some systems, notably ReliantUNIX
-#
-
-if test x$ac_cv_func_stat64 = xno ; then
- echo $ac_n "checking for stat64 in <sys/stat.h>""... $ac_c" 1>&6
-echo "configure:5318: checking for stat64 in <sys/stat.h>" >&5
- cat > conftest.$ac_ext <<EOF
-#line 5320 "configure"
-#include "confdefs.h"
-
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <sys/stat.h>
-
-int main() {
-struct stat64 st64; exit(stat64(".",&st64));
-; return 0; }
-EOF
-if { (eval echo configure:5332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- ac_cv_func_stat64=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- echo "$ac_t""$ac_cv_func_stat64" 1>&6
- if test x$ac_cv_func_stat64 = xyes ; then
- cat >> confdefs.h <<\EOF
-#define HAVE_STAT64 1
-EOF
-
- fi
-fi
-
-if test x$ac_cv_func_lstat64 = xno ; then
- echo $ac_n "checking for lstat64 in <sys/stat.h>""... $ac_c" 1>&6
-echo "configure:5351: checking for lstat64 in <sys/stat.h>" >&5
- cat > conftest.$ac_ext <<EOF
-#line 5353 "configure"
-#include "confdefs.h"
-
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <sys/stat.h>
-
-int main() {
-struct stat64 st64; exit(lstat64(".",&st64));
-; return 0; }
-EOF
-if { (eval echo configure:5365: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- ac_cv_func_lstat64=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- echo "$ac_t""$ac_cv_func_lstat64" 1>&6
- if test x$ac_cv_func_lstat64 = xyes ; then
- cat >> confdefs.h <<\EOF
-#define HAVE_LSTAT64 1
-EOF
-
- fi
-fi
-
-if test x$ac_cv_func_fstat64 = xno ; then
- echo $ac_n "checking for fstat64 in <sys/stat.h>""... $ac_c" 1>&6
-echo "configure:5384: checking for fstat64 in <sys/stat.h>" >&5
- cat > conftest.$ac_ext <<EOF
-#line 5386 "configure"
-#include "confdefs.h"
-
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <sys/stat.h>
-
-int main() {
-struct stat64 st64; exit(fstat64(0,&st64));
-; return 0; }
-EOF
-if { (eval echo configure:5398: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- ac_cv_func_fstat64=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
-fi
-rm -f conftest*
- echo "$ac_t""$ac_cv_func_fstat64" 1>&6
- if test x$ac_cv_func_fstat64 = xyes ; then
- cat >> confdefs.h <<\EOF
-#define HAVE_FSTAT64 1
-EOF
-
- fi
-fi
-
-#
-# If no strcasecmp, check for it in some known places
-# It is in -lresolv on ReliantUNIX and UnixWare
-# -lresolve *must* follow -lnsl for name resolution to work properly
-#
-
-if test x$ac_cv_func_strcasecmp = xno ; then
- echo $ac_n "checking for strcasecmp in -lresolv""... $ac_c" 1>&6
-echo "configure:5423: checking for strcasecmp in -lresolv" >&5
-ac_lib_var=`echo resolv'_'strcasecmp | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lresolv $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 5431 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char strcasecmp();
-
-int main() {
-strcasecmp()
-; return 0; }
-EOF
-if { (eval echo configure:5442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- LIBS="$LIBS -lresolv"
- cat >> confdefs.h <<\EOF
-#define HAVE_STRCASECMP 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
-fi
-
-#
# Check for the functions putprpwnam, set_auth_parameters,
# getspnam, bigcrypt and getprpwnam in -lsec and -lsecurity
# Needed for OSF1 and HPUX.
@@ -5474,12 +5603,12 @@ case "$LIBS" in
*-lsecurity*) for ac_func in putprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5478: checking for $ac_func" >&5
+echo "configure:5607: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5483 "configure"
+#line 5612 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5502,7 +5631,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5506: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5635: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5527,7 +5656,7 @@ fi
done
;;
*) echo $ac_n "checking for putprpwnam in -lsecurity""... $ac_c" 1>&6
-echo "configure:5531: checking for putprpwnam in -lsecurity" >&5
+echo "configure:5660: checking for putprpwnam in -lsecurity" >&5
ac_lib_var=`echo security'_'putprpwnam | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -5535,7 +5664,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsecurity $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 5539 "configure"
+#line 5668 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -5546,7 +5675,7 @@ int main() {
putprpwnam()
; return 0; }
EOF
-if { (eval echo configure:5550: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5679: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -5576,12 +5705,12 @@ fi
for ac_func in putprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5580: checking for $ac_func" >&5
+echo "configure:5709: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5585 "configure"
+#line 5714 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5604,7 +5733,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5608: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5737: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5635,12 +5764,12 @@ case "$LIBS" in
*-lsec*) for ac_func in putprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5639: checking for $ac_func" >&5
+echo "configure:5768: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5644 "configure"
+#line 5773 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5663,7 +5792,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5667: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5796: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5688,7 +5817,7 @@ fi
done
;;
*) echo $ac_n "checking for putprpwnam in -lsec""... $ac_c" 1>&6
-echo "configure:5692: checking for putprpwnam in -lsec" >&5
+echo "configure:5821: checking for putprpwnam in -lsec" >&5
ac_lib_var=`echo sec'_'putprpwnam | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -5696,7 +5825,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 5700 "configure"
+#line 5829 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -5707,7 +5836,7 @@ int main() {
putprpwnam()
; return 0; }
EOF
-if { (eval echo configure:5711: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5840: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -5737,12 +5866,12 @@ fi
for ac_func in putprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5741: checking for $ac_func" >&5
+echo "configure:5870: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5746 "configure"
+#line 5875 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5765,7 +5894,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5769: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5898: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5797,12 +5926,12 @@ case "$LIBS" in
*-lsecurity*) for ac_func in set_auth_parameters
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5801: checking for $ac_func" >&5
+echo "configure:5930: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5806 "configure"
+#line 5935 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5825,7 +5954,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5829: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:5958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5850,7 +5979,7 @@ fi
done
;;
*) echo $ac_n "checking for set_auth_parameters in -lsecurity""... $ac_c" 1>&6
-echo "configure:5854: checking for set_auth_parameters in -lsecurity" >&5
+echo "configure:5983: checking for set_auth_parameters in -lsecurity" >&5
ac_lib_var=`echo security'_'set_auth_parameters | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -5858,7 +5987,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsecurity $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 5862 "configure"
+#line 5991 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -5869,7 +5998,7 @@ int main() {
set_auth_parameters()
; return 0; }
EOF
-if { (eval echo configure:5873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6002: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -5899,12 +6028,12 @@ fi
for ac_func in set_auth_parameters
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5903: checking for $ac_func" >&5
+echo "configure:6032: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5908 "configure"
+#line 6037 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5927,7 +6056,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5931: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -5958,12 +6087,12 @@ case "$LIBS" in
*-lsec*) for ac_func in set_auth_parameters
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:5962: checking for $ac_func" >&5
+echo "configure:6091: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5967 "configure"
+#line 6096 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -5986,7 +6115,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5990: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6119: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6011,7 +6140,7 @@ fi
done
;;
*) echo $ac_n "checking for set_auth_parameters in -lsec""... $ac_c" 1>&6
-echo "configure:6015: checking for set_auth_parameters in -lsec" >&5
+echo "configure:6144: checking for set_auth_parameters in -lsec" >&5
ac_lib_var=`echo sec'_'set_auth_parameters | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -6019,7 +6148,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6023 "configure"
+#line 6152 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6030,7 +6159,7 @@ int main() {
set_auth_parameters()
; return 0; }
EOF
-if { (eval echo configure:6034: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6163: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -6060,175 +6189,12 @@ fi
for ac_func in set_auth_parameters
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6064: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 6069 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:6092: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
-
- ;;
- esac
-
-
-# UnixWare 7.x has its getspnam in -lgen
-case "$LIBS" in
- *-lgen*) for ac_func in getspnam
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6125: checking for $ac_func" >&5
-if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- cat > conftest.$ac_ext <<EOF
-#line 6130 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func(); below. */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-$ac_func();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:6153: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_func_$ac_func=no"
-fi
-rm -f conftest*
-fi
-
-if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_func 1
-EOF
-
-else
- echo "$ac_t""no" 1>&6
-fi
-done
- ;;
- *) echo $ac_n "checking for getspnam in -lgen""... $ac_c" 1>&6
-echo "configure:6178: checking for getspnam in -lgen" >&5
-ac_lib_var=`echo gen'_'getspnam | sed 'y%./+-%__p_%'`
-if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
- ac_save_LIBS="$LIBS"
-LIBS="-lgen $LIBS"
-cat > conftest.$ac_ext <<EOF
-#line 6186 "configure"
-#include "confdefs.h"
-/* Override any gcc2 internal prototype to avoid an error. */
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char getspnam();
-
-int main() {
-getspnam()
-; return 0; }
-EOF
-if { (eval echo configure:6197: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=yes"
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- eval "ac_cv_lib_$ac_lib_var=no"
-fi
-rm -f conftest*
-LIBS="$ac_save_LIBS"
-
-fi
-if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
- echo "$ac_t""yes" 1>&6
- ac_tr_lib=HAVE_LIB`echo gen | sed -e 's/[^a-zA-Z0-9_]/_/g' \
- -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
- cat >> confdefs.h <<EOF
-#define $ac_tr_lib 1
-EOF
-
- LIBS="-lgen $LIBS"
-
-else
- echo "$ac_t""no" 1>&6
-fi
-
- for ac_func in getspnam
-do
-echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6227: checking for $ac_func" >&5
+echo "configure:6193: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6232 "configure"
+#line 6198 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6251,7 +6217,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6255: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6221: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6283,12 +6249,12 @@ case "$LIBS" in
*-lsecurity*) for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6287: checking for $ac_func" >&5
+echo "configure:6253: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6292 "configure"
+#line 6258 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6311,7 +6277,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6281: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6336,7 +6302,7 @@ fi
done
;;
*) echo $ac_n "checking for getspnam in -lsecurity""... $ac_c" 1>&6
-echo "configure:6340: checking for getspnam in -lsecurity" >&5
+echo "configure:6306: checking for getspnam in -lsecurity" >&5
ac_lib_var=`echo security'_'getspnam | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -6344,7 +6310,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsecurity $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6348 "configure"
+#line 6314 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6355,7 +6321,7 @@ int main() {
getspnam()
; return 0; }
EOF
-if { (eval echo configure:6359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6325: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -6385,12 +6351,12 @@ fi
for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6389: checking for $ac_func" >&5
+echo "configure:6355: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6394 "configure"
+#line 6360 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6413,7 +6379,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6417: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6383: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6444,12 +6410,12 @@ case "$LIBS" in
*-lsec*) for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6448: checking for $ac_func" >&5
+echo "configure:6414: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6453 "configure"
+#line 6419 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6472,7 +6438,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6476: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6497,7 +6463,7 @@ fi
done
;;
*) echo $ac_n "checking for getspnam in -lsec""... $ac_c" 1>&6
-echo "configure:6501: checking for getspnam in -lsec" >&5
+echo "configure:6467: checking for getspnam in -lsec" >&5
ac_lib_var=`echo sec'_'getspnam | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -6505,7 +6471,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6509 "configure"
+#line 6475 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6516,7 +6482,7 @@ int main() {
getspnam()
; return 0; }
EOF
-if { (eval echo configure:6520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6486: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -6546,12 +6512,12 @@ fi
for ac_func in getspnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6550: checking for $ac_func" >&5
+echo "configure:6516: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6555 "configure"
+#line 6521 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6574,7 +6540,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6578: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6544: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6606,12 +6572,12 @@ case "$LIBS" in
*-lsecurity*) for ac_func in bigcrypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6610: checking for $ac_func" >&5
+echo "configure:6576: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6615 "configure"
+#line 6581 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6634,7 +6600,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6638: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6604: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6659,7 +6625,7 @@ fi
done
;;
*) echo $ac_n "checking for bigcrypt in -lsecurity""... $ac_c" 1>&6
-echo "configure:6663: checking for bigcrypt in -lsecurity" >&5
+echo "configure:6629: checking for bigcrypt in -lsecurity" >&5
ac_lib_var=`echo security'_'bigcrypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -6667,7 +6633,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsecurity $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6671 "configure"
+#line 6637 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6678,7 +6644,7 @@ int main() {
bigcrypt()
; return 0; }
EOF
-if { (eval echo configure:6682: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -6708,12 +6674,12 @@ fi
for ac_func in bigcrypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6712: checking for $ac_func" >&5
+echo "configure:6678: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6717 "configure"
+#line 6683 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6736,7 +6702,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6706: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6767,12 +6733,12 @@ case "$LIBS" in
*-lsec*) for ac_func in bigcrypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6771: checking for $ac_func" >&5
+echo "configure:6737: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6776 "configure"
+#line 6742 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6795,7 +6761,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6799: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6765: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6820,7 +6786,7 @@ fi
done
;;
*) echo $ac_n "checking for bigcrypt in -lsec""... $ac_c" 1>&6
-echo "configure:6824: checking for bigcrypt in -lsec" >&5
+echo "configure:6790: checking for bigcrypt in -lsec" >&5
ac_lib_var=`echo sec'_'bigcrypt | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -6828,7 +6794,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6832 "configure"
+#line 6798 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -6839,7 +6805,7 @@ int main() {
bigcrypt()
; return 0; }
EOF
-if { (eval echo configure:6843: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6809: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -6869,12 +6835,12 @@ fi
for ac_func in bigcrypt
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6873: checking for $ac_func" >&5
+echo "configure:6839: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6878 "configure"
+#line 6844 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6897,7 +6863,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6901: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6929,12 +6895,12 @@ case "$LIBS" in
*-lsecurity*) for ac_func in getprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:6933: checking for $ac_func" >&5
+echo "configure:6899: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6938 "configure"
+#line 6904 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6957,7 +6923,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:6961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6927: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -6982,7 +6948,7 @@ fi
done
;;
*) echo $ac_n "checking for getprpwnam in -lsecurity""... $ac_c" 1>&6
-echo "configure:6986: checking for getprpwnam in -lsecurity" >&5
+echo "configure:6952: checking for getprpwnam in -lsecurity" >&5
ac_lib_var=`echo security'_'getprpwnam | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -6990,7 +6956,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsecurity $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 6994 "configure"
+#line 6960 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7001,7 +6967,7 @@ int main() {
getprpwnam()
; return 0; }
EOF
-if { (eval echo configure:7005: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:6971: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -7031,12 +6997,12 @@ fi
for ac_func in getprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7035: checking for $ac_func" >&5
+echo "configure:7001: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7040 "configure"
+#line 7006 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7059,7 +7025,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7063: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7029: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -7090,12 +7056,12 @@ case "$LIBS" in
*-lsec*) for ac_func in getprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7094: checking for $ac_func" >&5
+echo "configure:7060: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7099 "configure"
+#line 7065 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7118,7 +7084,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7122: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7088: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -7143,7 +7109,7 @@ fi
done
;;
*) echo $ac_n "checking for getprpwnam in -lsec""... $ac_c" 1>&6
-echo "configure:7147: checking for getprpwnam in -lsec" >&5
+echo "configure:7113: checking for getprpwnam in -lsec" >&5
ac_lib_var=`echo sec'_'getprpwnam | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -7151,7 +7117,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsec $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 7155 "configure"
+#line 7121 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -7162,7 +7128,7 @@ int main() {
getprpwnam()
; return 0; }
EOF
-if { (eval echo configure:7166: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -7192,12 +7158,12 @@ fi
for ac_func in getprpwnam
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7196: checking for $ac_func" >&5
+echo "configure:7162: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7201 "configure"
+#line 7167 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7220,7 +7186,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:7224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7190: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -7255,8 +7221,6 @@ done
# these are the defaults, good for lots of systems
HOST_OS="$host_os"
LDSHFLAGS="-shared"
-PICFLAG=""
-SHLIBEXT="so"
# and these are for particular systems
case "$host_os" in
@@ -7282,14 +7246,14 @@ EOF
#define IRIX 1
EOF
- case "$host_os" in
- *irix6*) cat >> confdefs.h <<\EOF
-#define IRIX6 1
-EOF
-
- ;;
- esac
ATTEMPT_WRAP32_BUILD=yes
+ ATTEMPT_LIBSMB32_BUILD=yes
+ ATTEMPT_LIBSURS32_BUILD=yes
+ ATTEMPT_LIBSMBPW32_BUILD=yes
+ ATTEMPT_LIBNMB32_BUILD=yes
+ ATTEMPT_LIBSAMBA32_BUILD=yes
+ ATTEMPT_LIBUBIQX32_BUILD=yes
+ ATTEMPT_LIBMSRPC32_BUILD=yes
;;
*aix*) cat >> confdefs.h <<\EOF
#define AIX 1
@@ -7298,14 +7262,7 @@ EOF
*hpux*) cat >> confdefs.h <<\EOF
#define HPUX 1
EOF
-
- SHLIBEXT="sl"
- # Use special PIC flags for the native HP-UX compiler.
- if test $ac_cv_prog_cc_Ae = yes; then
- LDSHFLAGS="-b"
- PICFLAG="+z"
- fi
- ;;
+;;
*qnx*) cat >> confdefs.h <<\EOF
#define QNX 1
EOF
@@ -7325,15 +7282,16 @@ EOF
*dgux*) # Extract the first word of "groff", so it can be a program name with args.
set dummy groff; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:7329: checking for $ac_word" >&5
+echo "configure:7286: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_ROFF'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test -n "$ROFF"; then
ac_cv_prog_ROFF="$ROFF" # Let the user override the test.
else
- IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
- for ac_dir in $PATH; do
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
test -z "$ac_dir" && ac_dir=.
if test -f $ac_dir/$ac_word; then
ac_cv_prog_ROFF="groff -etpsR -Tascii -man"
@@ -7350,36 +7308,59 @@ else
echo "$ac_t""no" 1>&6
fi
;;
- *sysv4*)
- case "$host" in
- *-univel-*) if test "$GCC" != yes ; then
- cat >> confdefs.h <<\EOF
-#define HAVE_MEMSET 1
-EOF
+ *sysv4.2*) echo $ac_n "checking for strcasecmp in -lresolv""... $ac_c" 1>&6
+echo "configure:7313: checking for strcasecmp in -lresolv" >&5
+ac_lib_var=`echo resolv'_'strcasecmp | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lresolv $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 7321 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strcasecmp();
- fi
- LDSHFLAGS="-G"
- ;;
- *mips-sni-sysv4*) cat >> confdefs.h <<\EOF
-#define RELIANTUNIX 1
+int main() {
+strcasecmp()
+; return 0; }
EOF
-;;
- esac
- ;;
- *sysv5*)
- if test "$GCC" != yes ; then
- cat >> confdefs.h <<\EOF
-#define HAVE_MEMSET 1
+if { (eval echo configure:7332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
EOF
- fi
- LDSHFLAGS="-G"
- ;;
+ LIBS="-lresolv $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+;;
esac
# try to work out how to produce pic code with this compiler
+PICFLAG=""
echo $ac_n "checking whether ${CC-cc} accepts -fpic""... $ac_c" 1>&6
-echo "configure:7383: checking whether ${CC-cc} accepts -fpic" >&5
+echo "configure:7364: checking whether ${CC-cc} accepts -fpic" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_fpic'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7395,11 +7376,11 @@ fi
echo "$ac_t""$ac_cv_prog_cc_fpic" 1>&6
if test $ac_cv_prog_cc_fpic = yes; then
- PICFLAG="-fpic";
+ PICFLAG="-fpic";
fi
if test x$PICFLAG = x; then
echo $ac_n "checking whether ${CC-cc} accepts -Kpic""... $ac_c" 1>&6
-echo "configure:7403: checking whether ${CC-cc} accepts -Kpic" >&5
+echo "configure:7384: checking whether ${CC-cc} accepts -Kpic" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_Kpic'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7416,11 +7397,11 @@ fi
echo "$ac_t""$ac_cv_prog_cc_Kpic" 1>&6
if test $ac_cv_prog_cc_Kpic = yes; then
PICFLAG="-Kpic";
- fi
+ fi
fi
if test x$PICFLAG = x; then
echo $ac_n "checking whether ${CC-cc} accepts -KPIC""... $ac_c" 1>&6
-echo "configure:7424: checking whether ${CC-cc} accepts -KPIC" >&5
+echo "configure:7405: checking whether ${CC-cc} accepts -KPIC" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cc_KPIC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7437,13 +7418,13 @@ fi
echo "$ac_t""$ac_cv_prog_cc_KPIC" 1>&6
if test $ac_cv_prog_cc_KPIC = yes; then
PICFLAG="-KPIC";
- fi
+ fi
fi
################
echo $ac_n "checking for long long""... $ac_c" 1>&6
-echo "configure:7447: checking for long long" >&5
+echo "configure:7428: checking for long long" >&5
if eval "test \"`echo '$''{'samba_cv_have_longlong'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7452,12 +7433,12 @@ if test "$cross_compiling" = yes; then
samba_cv_have_longlong=cross
else
cat > conftest.$ac_ext <<EOF
-#line 7456 "configure"
+#line 7437 "configure"
#include "confdefs.h"
#include <stdio.h>
main() { long long x = 1000000; x *= x; exit(((x/1000000) == 1000000)? 0: 1); }
EOF
-if { (eval echo configure:7461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_have_longlong=yes
else
@@ -7480,7 +7461,7 @@ EOF
fi
echo $ac_n "checking for 64 bit off_t""... $ac_c" 1>&6
-echo "configure:7484: checking for 64 bit off_t" >&5
+echo "configure:7465: checking for 64 bit off_t" >&5
if eval "test \"`echo '$''{'samba_cv_SIZEOF_OFF_T'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7489,13 +7470,13 @@ if test "$cross_compiling" = yes; then
samba_cv_SIZEOF_OFF_T=cross
else
cat > conftest.$ac_ext <<EOF
-#line 7493 "configure"
+#line 7474 "configure"
#include "confdefs.h"
#include <stdio.h>
#include <sys/stat.h>
main() { exit((sizeof(off_t) == 8) ? 0 : 1); }
EOF
-if { (eval echo configure:7499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7480: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_SIZEOF_OFF_T=yes
else
@@ -7518,7 +7499,7 @@ EOF
fi
echo $ac_n "checking for off64_t""... $ac_c" 1>&6
-echo "configure:7522: checking for off64_t" >&5
+echo "configure:7503: checking for off64_t" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_OFF64_T'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7527,17 +7508,13 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_OFF64_T=cross
else
cat > conftest.$ac_ext <<EOF
-#line 7531 "configure"
+#line 7512 "configure"
#include "confdefs.h"
-
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
#include <stdio.h>
#include <sys/stat.h>
main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }
EOF
-if { (eval echo configure:7541: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7518: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_OFF64_T=yes
else
@@ -7560,7 +7537,7 @@ EOF
fi
echo $ac_n "checking for 64 bit ino_t""... $ac_c" 1>&6
-echo "configure:7564: checking for 64 bit ino_t" >&5
+echo "configure:7541: checking for 64 bit ino_t" >&5
if eval "test \"`echo '$''{'samba_cv_SIZEOF_INO_T'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7569,13 +7546,13 @@ if test "$cross_compiling" = yes; then
samba_cv_SIZEOF_INO_T=cross
else
cat > conftest.$ac_ext <<EOF
-#line 7573 "configure"
+#line 7550 "configure"
#include "confdefs.h"
#include <stdio.h>
#include <sys/stat.h>
main() { exit((sizeof(ino_t) == 8) ? 0 : 1); }
EOF
-if { (eval echo configure:7579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7556: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_SIZEOF_INO_T=yes
else
@@ -7598,7 +7575,7 @@ EOF
fi
echo $ac_n "checking for ino64_t""... $ac_c" 1>&6
-echo "configure:7602: checking for ino64_t" >&5
+echo "configure:7579: checking for ino64_t" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_INO64_T'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7607,17 +7584,13 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_INO64_T=cross
else
cat > conftest.$ac_ext <<EOF
-#line 7611 "configure"
+#line 7588 "configure"
#include "confdefs.h"
-
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
#include <stdio.h>
#include <sys/stat.h>
main() { struct stat64 st; ino64_t s; if (sizeof(ino_t) == sizeof(ino64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }
EOF
-if { (eval echo configure:7621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7594: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_INO64_T=yes
else
@@ -7639,47 +7612,8 @@ EOF
fi
-echo $ac_n "checking for struct dirent64""... $ac_c" 1>&6
-echo "configure:7644: checking for struct dirent64" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_STRUCT_DIRENT64'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
-cat > conftest.$ac_ext <<EOF
-#line 7650 "configure"
-#include "confdefs.h"
-
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <sys/types.h>
-#include <dirent.h>
-int main() {
-struct dirent64 de;
-; return 0; }
-EOF
-if { (eval echo configure:7662: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- samba_cv_HAVE_STRUCT_DIRENT64=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- samba_cv_HAVE_STRUCT_DIRENT64=no
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$samba_cv_HAVE_STRUCT_DIRENT64" 1>&6
-if test x"$samba_cv_HAVE_STRUCT_DIRENT64" = x"yes"; then
- cat >> confdefs.h <<\EOF
-#define HAVE_STRUCT_DIRENT64 1
-EOF
-
-fi
-
echo $ac_n "checking for union semun""... $ac_c" 1>&6
-echo "configure:7683: checking for union semun" >&5
+echo "configure:7617: checking for union semun" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_UNION_SEMUN'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7688,7 +7622,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_UNION_SEMUN=cross
else
cat > conftest.$ac_ext <<EOF
-#line 7692 "configure"
+#line 7626 "configure"
#include "confdefs.h"
#include <sys/types.h>
@@ -7696,7 +7630,7 @@ else
#include <sys/sem.h>
main() { union semun ss; exit(0); }
EOF
-if { (eval echo configure:7700: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7634: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_UNION_SEMUN=yes
else
@@ -7719,7 +7653,7 @@ EOF
fi
echo $ac_n "checking for unsigned char""... $ac_c" 1>&6
-echo "configure:7723: checking for unsigned char" >&5
+echo "configure:7657: checking for unsigned char" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_UNSIGNED_CHAR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7728,12 +7662,12 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_UNSIGNED_CHAR=cross
else
cat > conftest.$ac_ext <<EOF
-#line 7732 "configure"
+#line 7666 "configure"
#include "confdefs.h"
#include <stdio.h>
main() { char c; c=250; exit((c > 0)?0:1); }
EOF
-if { (eval echo configure:7737: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_UNSIGNED_CHAR=yes
else
@@ -7756,13 +7690,13 @@ EOF
fi
echo $ac_n "checking for sin_len in sock""... $ac_c" 1>&6
-echo "configure:7760: checking for sin_len in sock" >&5
+echo "configure:7694: checking for sin_len in sock" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_SOCK_SIN_LEN'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7766 "configure"
+#line 7700 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/socket.h>
@@ -7771,7 +7705,7 @@ int main() {
struct sockaddr_in sock; sock.sin_len = sizeof(sock);
; return 0; }
EOF
-if { (eval echo configure:7775: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7709: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_SOCK_SIN_LEN=yes
else
@@ -7792,13 +7726,13 @@ EOF
fi
echo $ac_n "checking whether seekdir returns void""... $ac_c" 1>&6
-echo "configure:7796: checking whether seekdir returns void" >&5
+echo "configure:7730: checking whether seekdir returns void" >&5
if eval "test \"`echo '$''{'samba_cv_SEEKDIR_RETURNS_VOID'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7802 "configure"
+#line 7736 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <dirent.h>
@@ -7807,7 +7741,7 @@ int main() {
return 0;
; return 0; }
EOF
-if { (eval echo configure:7811: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7745: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_SEEKDIR_RETURNS_VOID=yes
else
@@ -7828,20 +7762,20 @@ EOF
fi
echo $ac_n "checking for __FILE__ macro""... $ac_c" 1>&6
-echo "configure:7832: checking for __FILE__ macro" >&5
+echo "configure:7766: checking for __FILE__ macro" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_FILE_MACRO'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7838 "configure"
+#line 7772 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
printf("%s\n", __FILE__);
; return 0; }
EOF
-if { (eval echo configure:7845: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7779: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_FILE_MACRO=yes
else
@@ -7862,20 +7796,20 @@ EOF
fi
echo $ac_n "checking for __FUNCTION__ macro""... $ac_c" 1>&6
-echo "configure:7866: checking for __FUNCTION__ macro" >&5
+echo "configure:7800: checking for __FUNCTION__ macro" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_FUNCTION_MACRO'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7872 "configure"
+#line 7806 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
printf("%s\n", __FUNCTION__);
; return 0; }
EOF
-if { (eval echo configure:7879: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7813: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_FUNCTION_MACRO=yes
else
@@ -7896,7 +7830,7 @@ EOF
fi
echo $ac_n "checking if gettimeofday takes tz argument""... $ac_c" 1>&6
-echo "configure:7900: checking if gettimeofday takes tz argument" >&5
+echo "configure:7834: checking if gettimeofday takes tz argument" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_GETTIMEOFDAY_TZ'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7905,14 +7839,14 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_GETTIMEOFDAY_TZ=cross
else
cat > conftest.$ac_ext <<EOF
-#line 7909 "configure"
+#line 7843 "configure"
#include "confdefs.h"
#include <sys/time.h>
#include <unistd.h>
main() { struct timeval tv; exit(gettimeofday(&tv, NULL));}
EOF
-if { (eval echo configure:7916: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7850: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_GETTIMEOFDAY_TZ=yes
else
@@ -7936,7 +7870,7 @@ fi
echo $ac_n "checking for broken readdir""... $ac_c" 1>&6
-echo "configure:7940: checking for broken readdir" >&5
+echo "configure:7874: checking for broken readdir" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_READDIR'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -7945,7 +7879,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_BROKEN_READDIR=cross
else
cat > conftest.$ac_ext <<EOF
-#line 7949 "configure"
+#line 7883 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <dirent.h>
@@ -7953,7 +7887,7 @@ main() { struct dirent *di; DIR *d = opendir("."); di = readdir(d);
if (di && di->d_name[-2] == '.' && di->d_name[-1] == 0 &&
di->d_name[0] == 0) exit(0); exit(1);}
EOF
-if { (eval echo configure:7957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:7891: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_BROKEN_READDIR=yes
else
@@ -7976,13 +7910,13 @@ EOF
fi
echo $ac_n "checking for utimbuf""... $ac_c" 1>&6
-echo "configure:7980: checking for utimbuf" >&5
+echo "configure:7914: checking for utimbuf" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_UTIMBUF'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7986 "configure"
+#line 7920 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <utime.h>
@@ -7990,7 +7924,7 @@ int main() {
struct utimbuf tbuf; tbuf.actime = 0; tbuf.modtime = 1; exit(utime("foo.c",&tbuf));
; return 0; }
EOF
-if { (eval echo configure:7994: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7928: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UTIMBUF=yes
else
@@ -8011,13 +7945,13 @@ EOF
fi
echo $ac_n "checking for kernel oplock type definitions""... $ac_c" 1>&6
-echo "configure:8015: checking for kernel oplock type definitions" >&5
+echo "configure:7949: checking for kernel oplock type definitions" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_KERNEL_OPLOCKS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 8021 "configure"
+#line 7955 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <fcntl.h>
@@ -8025,7 +7959,7 @@ int main() {
oplock_stat_t t; t.os_state = OP_REVOKE; t.os_dev = 1; t.os_ino = 1;
; return 0; }
EOF
-if { (eval echo configure:8029: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:7963: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_KERNEL_OPLOCKS=yes
else
@@ -8046,7 +7980,7 @@ EOF
fi
echo $ac_n "checking for irix specific capabilities""... $ac_c" 1>&6
-echo "configure:8050: checking for irix specific capabilities" >&5
+echo "configure:7984: checking for irix specific capabilities" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8055,7 +7989,7 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8059 "configure"
+#line 7993 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/capability.h>
@@ -8070,7 +8004,7 @@ main() {
}
EOF
-if { (eval echo configure:8074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_IRIX_SPECIFIC_CAPABILITIES=yes
else
@@ -8098,13 +8032,13 @@ fi
#
echo $ac_n "checking for int16 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:8102: checking for int16 typedef included by rpc/rpc.h" >&5
+echo "configure:8036: checking for int16 typedef included by rpc/rpc.h" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_INT16_FROM_RPC_RPC_H'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 8108 "configure"
+#line 8042 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if defined(HAVE_RPC_RPC_H)
@@ -8114,7 +8048,7 @@ int main() {
int16 testvar;
; return 0; }
EOF
-if { (eval echo configure:8118: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8052: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_INT16_FROM_RPC_RPC_H=yes
else
@@ -8135,13 +8069,13 @@ EOF
fi
echo $ac_n "checking for uint16 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:8139: checking for uint16 typedef included by rpc/rpc.h" >&5
+echo "configure:8073: checking for uint16 typedef included by rpc/rpc.h" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_UINT16_FROM_RPC_RPC_H'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 8145 "configure"
+#line 8079 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if defined(HAVE_RPC_RPC_H)
@@ -8151,7 +8085,7 @@ int main() {
uint16 testvar;
; return 0; }
EOF
-if { (eval echo configure:8155: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8089: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UINT16_FROM_RPC_RPC_H=yes
else
@@ -8172,13 +8106,13 @@ EOF
fi
echo $ac_n "checking for int32 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:8176: checking for int32 typedef included by rpc/rpc.h" >&5
+echo "configure:8110: checking for int32 typedef included by rpc/rpc.h" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_INT32_FROM_RPC_RPC_H'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 8182 "configure"
+#line 8116 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if defined(HAVE_RPC_RPC_H)
@@ -8188,7 +8122,7 @@ int main() {
int32 testvar;
; return 0; }
EOF
-if { (eval echo configure:8192: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8126: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_INT32_FROM_RPC_RPC_H=yes
else
@@ -8209,13 +8143,13 @@ EOF
fi
echo $ac_n "checking for uint32 typedef included by rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:8213: checking for uint32 typedef included by rpc/rpc.h" >&5
+echo "configure:8147: checking for uint32 typedef included by rpc/rpc.h" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_UINT32_FROM_RPC_RPC_H'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 8219 "configure"
+#line 8153 "configure"
#include "confdefs.h"
#include <sys/types.h>
#if defined(HAVE_RPC_RPC_H)
@@ -8225,7 +8159,7 @@ int main() {
uint32 testvar;
; return 0; }
EOF
-if { (eval echo configure:8229: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8163: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_HAVE_UINT32_FROM_RPC_RPC_H=yes
else
@@ -8245,59 +8179,17 @@ EOF
fi
-
-echo $ac_n "checking for conflicting AUTH_ERROR define in rpc/rpc.h""... $ac_c" 1>&6
-echo "configure:8251: checking for conflicting AUTH_ERROR define in rpc/rpc.h" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
-cat > conftest.$ac_ext <<EOF
-#line 8257 "configure"
-#include "confdefs.h"
-#include <sys/types.h>
-#ifdef HAVE_SYS_SECURITY_H
-#include <sys/security.h>
-#include <prot.h>
-#endif /* HAVE_SYS_SECURITY_H */
-#if defined(HAVE_RPC_RPC_H)
-#include <rpc/rpc.h>
-#endif
-int main() {
-int testvar;
-; return 0; }
-EOF
-if { (eval echo configure:8271: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=no
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=yes
-fi
-rm -f conftest*
-fi
-
-echo "$ac_t""$samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT" 1>&6
-if test x"$samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT" = x"yes"; then
- cat >> confdefs.h <<\EOF
-#define HAVE_RPC_AUTH_ERROR_CONFLICT 1
-EOF
-
-fi
-
echo $ac_n "checking for test routines""... $ac_c" 1>&6
-echo "configure:8292: checking for test routines" >&5
+echo "configure:8184: checking for test routines" >&5
if test "$cross_compiling" = yes; then
echo "configure: warning: cannot run when cross-compiling" 1>&2
else
cat > conftest.$ac_ext <<EOF
-#line 8297 "configure"
+#line 8189 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/trivial.c"
EOF
-if { (eval echo configure:8301: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8193: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
echo "$ac_t""yes" 1>&6
else
@@ -8311,7 +8203,7 @@ fi
echo $ac_n "checking for ftruncate extend""... $ac_c" 1>&6
-echo "configure:8315: checking for ftruncate extend" >&5
+echo "configure:8207: checking for ftruncate extend" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_FTRUNCATE_EXTEND'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8320,11 +8212,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_FTRUNCATE_EXTEND=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8324 "configure"
+#line 8216 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/ftruncate.c"
EOF
-if { (eval echo configure:8328: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_FTRUNCATE_EXTEND=yes
else
@@ -8347,7 +8239,7 @@ EOF
fi
echo $ac_n "checking for broken getgroups""... $ac_c" 1>&6
-echo "configure:8351: checking for broken getgroups" >&5
+echo "configure:8243: checking for broken getgroups" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_GETGROUPS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8356,11 +8248,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_BROKEN_GETGROUPS=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8360 "configure"
+#line 8252 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/getgroups.c"
EOF
-if { (eval echo configure:8364: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8256: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_BROKEN_GETGROUPS=yes
else
@@ -8383,15 +8275,15 @@ EOF
fi
echo $ac_n "checking whether getpass should be replaced""... $ac_c" 1>&6
-echo "configure:8387: checking whether getpass should be replaced" >&5
+echo "configure:8279: checking whether getpass should be replaced" >&5
if eval "test \"`echo '$''{'samba_cv_REPLACE_GETPASS'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/smbwrapper"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/include -I${srcdir-.}/ubiqx"
cat > conftest.$ac_ext <<EOF
-#line 8395 "configure"
+#line 8287 "configure"
#include "confdefs.h"
#define REPLACE_GETPASS 1
@@ -8404,7 +8296,7 @@ int main() {
; return 0; }
EOF
-if { (eval echo configure:8408: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8300: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
samba_cv_REPLACE_GETPASS=yes
else
@@ -8426,45 +8318,8 @@ EOF
fi
-echo $ac_n "checking for working fnmatch""... $ac_c" 1>&6
-echo "configure:8431: checking for working fnmatch" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_FNMATCH'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
-if test "$cross_compiling" = yes; then
- samba_cv_HAVE_FNMATCH=cross
-else
- cat > conftest.$ac_ext <<EOF
-#line 8440 "configure"
-#include "confdefs.h"
-#include <fnmatch.h>
-main() { exit(fnmatch("*.o", "x.o", FNM_PATHNAME) == 0? 0: 1); }
-EOF
-if { (eval echo configure:8445: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- samba_cv_HAVE_FNMATCH=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- samba_cv_HAVE_FNMATCH=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$samba_cv_HAVE_FNMATCH" 1>&6
-if test x"$samba_cv_HAVE_FNMATCH" = x"yes"; then
- cat >> confdefs.h <<\EOF
-#define HAVE_FNMATCH 1
-EOF
-
-fi
-
echo $ac_n "checking for broken inet_ntoa""... $ac_c" 1>&6
-echo "configure:8468: checking for broken inet_ntoa" >&5
+echo "configure:8323: checking for broken inet_ntoa" >&5
if eval "test \"`echo '$''{'samba_cv_REPLACE_INET_NTOA'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8473,21 +8328,19 @@ if test "$cross_compiling" = yes; then
samba_cv_REPLACE_INET_NTOA=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8477 "configure"
+#line 8332 "configure"
#include "confdefs.h"
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
-#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
-#endif
main() { struct in_addr ip; ip.s_addr = 0x12345678;
if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); }
exit(1);}
EOF
-if { (eval echo configure:8491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8344: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_REPLACE_INET_NTOA=yes
else
@@ -8509,215 +8362,208 @@ EOF
fi
-echo $ac_n "checking for sysconf(_SC_NGROUPS_MAX)""... $ac_c" 1>&6
-echo "configure:8514: checking for sysconf(_SC_NGROUPS_MAX)" >&5
-if eval "test \"`echo '$''{'samba_cv_SYSCONF_SC_NGROUPS_MAX'+set}'`\" = set"; then
+echo $ac_n "checking for root""... $ac_c" 1>&6
+echo "configure:8367: checking for root" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_ROOT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
- samba_cv_SYSCONF_SC_NGROUPS_MAX=cross
+ samba_cv_HAVE_ROOT=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8523 "configure"
+#line 8376 "configure"
#include "confdefs.h"
-#include <unistd.h>
-main() { exit(sysconf(_SC_NGROUPS_MAX) == -1 ? 1 : 0); }
+main() { exit(getuid() != 0); }
EOF
-if { (eval echo configure:8528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8380: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
- samba_cv_SYSCONF_SC_NGROUPS_MAX=yes
+ samba_cv_HAVE_ROOT=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
- samba_cv_SYSCONF_SC_NGROUPS_MAX=no
+ samba_cv_HAVE_ROOT=no
fi
rm -fr conftest*
fi
fi
-echo "$ac_t""$samba_cv_SYSCONF_SC_NGROUPS_MAX" 1>&6
-if test x"$samba_cv_SYSCONF_SC_NGROUPS_MAX" = x"yes"; then
+echo "$ac_t""$samba_cv_HAVE_ROOT" 1>&6
+if test x"$samba_cv_HAVE_ROOT" = x"yes"; then
cat >> confdefs.h <<\EOF
-#define SYSCONF_SC_NGROUPS_MAX 1
+#define HAVE_ROOT 1
EOF
+else
+ echo "configure: warning: running as non-root will disable some tests" 1>&2
fi
-echo $ac_n "checking for root""... $ac_c" 1>&6
-echo "configure:8551: checking for root" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_ROOT'+set}'`\" = set"; then
+netmask=no;
+echo $ac_n "checking for netmask ifconf""... $ac_c" 1>&6
+echo "configure:8406: checking for netmask ifconf" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_NETMASK_IFCONF'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
- samba_cv_HAVE_ROOT=cross
+ samba_cv_HAVE_NETMASK_IFCONF=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8560 "configure"
+#line 8415 "configure"
#include "confdefs.h"
-main() { exit(getuid() != 0); }
+
+#define HAVE_NETMASK_IFCONF 1
+#define AUTOCONF 1
+#include "${srcdir-.}/lib/netmask.c"
EOF
-if { (eval echo configure:8564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8422: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
- samba_cv_HAVE_ROOT=yes
+ samba_cv_HAVE_NETMASK_IFCONF=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
- samba_cv_HAVE_ROOT=no
+ samba_cv_HAVE_NETMASK_IFCONF=no
fi
rm -fr conftest*
fi
fi
-echo "$ac_t""$samba_cv_HAVE_ROOT" 1>&6
-if test x"$samba_cv_HAVE_ROOT" = x"yes"; then
- cat >> confdefs.h <<\EOF
-#define HAVE_ROOT 1
+echo "$ac_t""$samba_cv_HAVE_NETMASK_IFCONF" 1>&6
+if test x"$samba_cv_HAVE_NETMASK_IFCONF" = x"yes"; then
+ netmask=yes;cat >> confdefs.h <<\EOF
+#define HAVE_NETMASK_IFCONF 1
EOF
-else
- echo "configure: warning: running as non-root will disable some tests" 1>&2
fi
-##################
-# look for a method of finding the list of network interfaces
-iface=no;
-echo $ac_n "checking for iface AIX""... $ac_c" 1>&6
-echo "configure:8592: checking for iface AIX" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_AIX'+set}'`\" = set"; then
+if test $netmask = no; then
+echo $ac_n "checking for netmask ifreq""... $ac_c" 1>&6
+echo "configure:8446: checking for netmask ifreq" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_NETMASK_IFREQ'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
- samba_cv_HAVE_IFACE_AIX=cross
+ samba_cv_HAVE_NETMASK_IFREQ=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8601 "configure"
+#line 8455 "configure"
#include "confdefs.h"
-#define HAVE_IFACE_AIX 1
-#define AUTOCONF_TEST 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/interfaces.c"
+#define HAVE_NETMASK_IFREQ 1
+#define AUTOCONF 1
+#include "${srcdir-.}/lib/netmask.c"
EOF
-if { (eval echo configure:8609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8462: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
- samba_cv_HAVE_IFACE_AIX=yes
+ samba_cv_HAVE_NETMASK_IFREQ=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
- samba_cv_HAVE_IFACE_AIX=no
+ samba_cv_HAVE_NETMASK_IFREQ=no
fi
rm -fr conftest*
fi
fi
-echo "$ac_t""$samba_cv_HAVE_IFACE_AIX" 1>&6
-if test x"$samba_cv_HAVE_IFACE_AIX" = x"yes"; then
- iface=yes;cat >> confdefs.h <<\EOF
-#define HAVE_IFACE_AIX 1
+echo "$ac_t""$samba_cv_HAVE_NETMASK_IFREQ" 1>&6
+if test x"$samba_cv_HAVE_NETMASK_IFREQ" = x"yes"; then
+ netmask=yes;cat >> confdefs.h <<\EOF
+#define HAVE_NETMASK_IFREQ 1
EOF
fi
+fi
-if test $iface = no; then
-echo $ac_n "checking for iface ifconf""... $ac_c" 1>&6
-echo "configure:8633: checking for iface ifconf" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_IFCONF'+set}'`\" = set"; then
+if test $netmask = no; then
+echo $ac_n "checking for netmask AIX""... $ac_c" 1>&6
+echo "configure:8487: checking for netmask AIX" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_NETMASK_AIX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
- samba_cv_HAVE_IFACE_IFCONF=cross
+ samba_cv_HAVE_NETMASK_AIX=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8642 "configure"
+#line 8496 "configure"
#include "confdefs.h"
-#define HAVE_IFACE_IFCONF 1
-#define AUTOCONF_TEST 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/interfaces.c"
+#define HAVE_NETMASK_AIX 1
+#define AUTOCONF 1
+#include "${srcdir-.}/lib/netmask.c"
EOF
-if { (eval echo configure:8650: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8503: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
- samba_cv_HAVE_IFACE_IFCONF=yes
+ samba_cv_HAVE_NETMASK_AIX=yes
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
- samba_cv_HAVE_IFACE_IFCONF=no
+ samba_cv_HAVE_NETMASK_AIX=no
fi
rm -fr conftest*
fi
fi
-echo "$ac_t""$samba_cv_HAVE_IFACE_IFCONF" 1>&6
-if test x"$samba_cv_HAVE_IFACE_IFCONF" = x"yes"; then
- iface=yes;cat >> confdefs.h <<\EOF
-#define HAVE_IFACE_IFCONF 1
+echo "$ac_t""$samba_cv_HAVE_NETMASK_AIX" 1>&6
+if test x"$samba_cv_HAVE_NETMASK_AIX" = x"yes"; then
+ netmask=yes;cat >> confdefs.h <<\EOF
+#define HAVE_NETMASK_AIX 1
EOF
fi
fi
-if test $iface = no; then
-echo $ac_n "checking for iface ifreq""... $ac_c" 1>&6
-echo "configure:8675: checking for iface ifreq" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_IFREQ'+set}'`\" = set"; then
+echo $ac_n "checking for trapdoor seteuid""... $ac_c" 1>&6
+echo "configure:8527: checking for trapdoor seteuid" >&5
+if eval "test \"`echo '$''{'samba_cv_HAVE_TRAPDOOR_UID'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$cross_compiling" = yes; then
- samba_cv_HAVE_IFACE_IFREQ=cross
+ :
else
cat > conftest.$ac_ext <<EOF
-#line 8684 "configure"
+#line 8536 "configure"
#include "confdefs.h"
-
-#define HAVE_IFACE_IFREQ 1
-#define AUTOCONF_TEST 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/interfaces.c"
+#include "${srcdir-.}/tests/trapdoor.c"
EOF
-if { (eval echo configure:8692: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8540: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
- samba_cv_HAVE_IFACE_IFREQ=yes
+ samba_cv_HAVE_TRAPDOOR_UID=no
else
echo "configure: failed program was:" >&5
cat conftest.$ac_ext >&5
rm -fr conftest*
- samba_cv_HAVE_IFACE_IFREQ=no
+ samba_cv_HAVE_TRAPDOOR_UID=yes
fi
rm -fr conftest*
fi
fi
-echo "$ac_t""$samba_cv_HAVE_IFACE_IFREQ" 1>&6
-if test x"$samba_cv_HAVE_IFACE_IFREQ" = x"yes"; then
- iface=yes;cat >> confdefs.h <<\EOF
-#define HAVE_IFACE_IFREQ 1
+echo "$ac_t""$samba_cv_HAVE_TRAPDOOR_UID" 1>&6
+if test x"$samba_cv_HAVE_TRAPDOOR_UID" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_TRAPDOOR_UID 1
EOF
fi
-fi
-
################################################
# look for a method of setting the effective uid
seteuid=no;
if test $seteuid = no; then
echo $ac_n "checking for setresuid""... $ac_c" 1>&6
-echo "configure:8721: checking for setresuid" >&5
+echo "configure:8567: checking for setresuid" >&5
if eval "test \"`echo '$''{'samba_cv_USE_SETRESUID'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8726,7 +8572,7 @@ if test "$cross_compiling" = yes; then
samba_cv_USE_SETRESUID=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8730 "configure"
+#line 8576 "configure"
#include "confdefs.h"
#define AUTOCONF_TEST 1
@@ -8734,7 +8580,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/util_sec.c"
EOF
-if { (eval echo configure:8738: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8584: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_USE_SETRESUID=yes
else
@@ -8760,7 +8606,7 @@ fi
if test $seteuid = no; then
echo $ac_n "checking for setreuid""... $ac_c" 1>&6
-echo "configure:8764: checking for setreuid" >&5
+echo "configure:8610: checking for setreuid" >&5
if eval "test \"`echo '$''{'samba_cv_USE_SETREUID'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8769,7 +8615,7 @@ if test "$cross_compiling" = yes; then
samba_cv_USE_SETREUID=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8773 "configure"
+#line 8619 "configure"
#include "confdefs.h"
#define AUTOCONF_TEST 1
@@ -8777,7 +8623,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/util_sec.c"
EOF
-if { (eval echo configure:8781: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8627: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_USE_SETREUID=yes
else
@@ -8802,7 +8648,7 @@ fi
if test $seteuid = no; then
echo $ac_n "checking for seteuid""... $ac_c" 1>&6
-echo "configure:8806: checking for seteuid" >&5
+echo "configure:8652: checking for seteuid" >&5
if eval "test \"`echo '$''{'samba_cv_USE_SETEUID'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8811,7 +8657,7 @@ if test "$cross_compiling" = yes; then
samba_cv_USE_SETEUID=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8815 "configure"
+#line 8661 "configure"
#include "confdefs.h"
#define AUTOCONF_TEST 1
@@ -8819,7 +8665,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/util_sec.c"
EOF
-if { (eval echo configure:8823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8669: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_USE_SETEUID=yes
else
@@ -8844,7 +8690,7 @@ fi
if test $seteuid = no; then
echo $ac_n "checking for setuidx""... $ac_c" 1>&6
-echo "configure:8848: checking for setuidx" >&5
+echo "configure:8694: checking for setuidx" >&5
if eval "test \"`echo '$''{'samba_cv_USE_SETUIDX'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8853,7 +8699,7 @@ if test "$cross_compiling" = yes; then
samba_cv_USE_SETUIDX=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8857 "configure"
+#line 8703 "configure"
#include "confdefs.h"
#define AUTOCONF_TEST 1
@@ -8861,7 +8707,7 @@ else
#include "confdefs.h"
#include "${srcdir-.}/lib/util_sec.c"
EOF
-if { (eval echo configure:8865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8711: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_USE_SETUIDX=yes
else
@@ -8886,7 +8732,7 @@ fi
echo $ac_n "checking for shared mmap""... $ac_c" 1>&6
-echo "configure:8890: checking for shared mmap" >&5
+echo "configure:8736: checking for shared mmap" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_SHARED_MMAP'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8895,11 +8741,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_SHARED_MMAP=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8899 "configure"
+#line 8745 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/shared_mmap.c"
EOF
-if { (eval echo configure:8903: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8749: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_SHARED_MMAP=yes
else
@@ -8925,44 +8771,8 @@ EOF
fi
-echo $ac_n "checking for ftruncate needs root""... $ac_c" 1>&6
-echo "configure:8930: checking for ftruncate needs root" >&5
-if eval "test \"`echo '$''{'samba_cv_FTRUNCATE_NEEDS_ROOT'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
-if test "$cross_compiling" = yes; then
- samba_cv_FTRUNCATE_NEEDS_ROOT=cross
-else
- cat > conftest.$ac_ext <<EOF
-#line 8939 "configure"
-#include "confdefs.h"
-#include "${srcdir-.}/tests/ftruncroot.c"
-EOF
-if { (eval echo configure:8943: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- samba_cv_FTRUNCATE_NEEDS_ROOT=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- samba_cv_FTRUNCATE_NEEDS_ROOT=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$samba_cv_FTRUNCATE_NEEDS_ROOT" 1>&6
-if test x"$samba_cv_FTRUNCATE_NEEDS_ROOT" = x"yes"; then
- cat >> confdefs.h <<\EOF
-#define FTRUNCATE_NEEDS_ROOT 1
-EOF
-
-fi
-
echo $ac_n "checking for fcntl locking""... $ac_c" 1>&6
-echo "configure:8966: checking for fcntl locking" >&5
+echo "configure:8776: checking for fcntl locking" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_FCNTL_LOCK'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -8971,11 +8781,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_FCNTL_LOCK=cross
else
cat > conftest.$ac_ext <<EOF
-#line 8975 "configure"
+#line 8785 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/fcntl_lock.c"
EOF
-if { (eval echo configure:8979: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8789: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_FCNTL_LOCK=yes
else
@@ -8997,60 +8807,19 @@ EOF
fi
-echo $ac_n "checking for broken (glibc2.1/x86) 64 bit fcntl locking""... $ac_c" 1>&6
-echo "configure:9002: checking for broken (glibc2.1/x86) 64 bit fcntl locking" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_FCNTL64_LOCKS'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
-if test "$cross_compiling" = yes; then
- samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=cross
-else
- cat > conftest.$ac_ext <<EOF
-#line 9011 "configure"
-#include "confdefs.h"
-#include "${srcdir-.}/tests/fcntl_lock64.c"
-EOF
-if { (eval echo configure:9015: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=no
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$samba_cv_HAVE_BROKEN_FCNTL64_LOCKS" 1>&6
-if test x"$samba_cv_HAVE_BROKEN_FCNTL64_LOCKS" = x"yes"; then
- cat >> confdefs.h <<\EOF
-#define HAVE_BROKEN_FCNTL64_LOCKS 1
-EOF
-
-
-else
-
-
- echo $ac_n "checking for 64 bit fcntl locking""... $ac_c" 1>&6
-echo "configure:9040: checking for 64 bit fcntl locking" >&5
+echo $ac_n "checking for 64 bit fcntl locking""... $ac_c" 1>&6
+echo "configure:8812: checking for 64 bit fcntl locking" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_STRUCT_FLOCK64'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
- if test "$cross_compiling" = yes; then
+if test "$cross_compiling" = yes; then
samba_cv_HAVE_STRUCT_FLOCK64=cross
else
cat > conftest.$ac_ext <<EOF
-#line 9049 "configure"
+#line 8821 "configure"
#include "confdefs.h"
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
#include <stdio.h>
#include <stdlib.h>
@@ -9069,7 +8838,7 @@ exit(1);
#endif
}
EOF
-if { (eval echo configure:9073: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8842: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_STRUCT_FLOCK64=yes
else
@@ -9084,17 +8853,15 @@ fi
fi
echo "$ac_t""$samba_cv_HAVE_STRUCT_FLOCK64" 1>&6
-
- if test x"$samba_cv_HAVE_STRUCT_FLOCK64" = x"yes"; then
- cat >> confdefs.h <<\EOF
+if test x"$samba_cv_HAVE_STRUCT_FLOCK64" = x"yes"; then
+ cat >> confdefs.h <<\EOF
#define HAVE_STRUCT_FLOCK64 1
EOF
- fi
fi
echo $ac_n "checking for sysv ipc""... $ac_c" 1>&6
-echo "configure:9098: checking for sysv ipc" >&5
+echo "configure:8865: checking for sysv ipc" >&5
if eval "test \"`echo '$''{'samba_cv_HAVE_SYSV_IPC'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -9103,11 +8870,11 @@ if test "$cross_compiling" = yes; then
samba_cv_HAVE_SYSV_IPC=cross
else
cat > conftest.$ac_ext <<EOF
-#line 9107 "configure"
+#line 8874 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/sysv_ipc.c"
EOF
-if { (eval echo configure:9111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:8878: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
samba_cv_HAVE_SYSV_IPC=yes
else
@@ -9129,120 +8896,328 @@ EOF
fi
-echo $ac_n "checking for IRIX sysv ipc semun problem using gcc""... $ac_c" 1>&6
-echo "configure:9134: checking for IRIX sysv ipc semun problem using gcc" >&5
-if eval "test \"`echo '$''{'samba_cv_NEED_SGI_SEMUN_HACK'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+#################################################
+# decide for the default sam-password-database
+echo $ac_n "checking which sam password database to use""... $ac_c" 1>&6
+echo "configure:8903: checking which sam password database to use" >&5
+# Check whether --with-sam_pwdb or --without-sam_pwdb was given.
+if test "${with_sam_pwdb+set}" = set; then
+ withval="$with_sam_pwdb"
+ case "$withval" in
+ ""|passdb)
+ SAM_PWDB_LIB='$(SAMRPASSLIB) $(SMBPWLIB)'
+ sampwlibname="passdb"
+ ;;
+ tdb)
+ SAM_PWDB_LIB='$(SAMRTDBLIB)'
+ sampwlibname="tdb"
+ ;;
+ nt5ldap)
+ SAM_PWDB_LIB='$(SAMRNT5LDAPLIB)'
+ sampwlibname="nt5ldap (must also specify --with-nt5ldap)"
+ ;;
+ *)
+ SAM_PWDB_LIB='$(SAMRPASSLIB)'
+ sampwlibname="passdb (unknown specified!)"
+ ;;
+esac
else
-if test "$cross_compiling" = yes; then
- samba_cv_NEED_SGI_SEMUN_HACK=cross
-else
- cat > conftest.$ac_ext <<EOF
-#line 9143 "configure"
-#include "confdefs.h"
-#include "${srcdir-.}/tests/sgi_sysv_hack.c"
+ SAM_PWDB_LIB='$(SAMRPASSLIB) $(SMBPWLIB)'
+ sampwlibname="passdb (default)"
+
+fi
+
+echo "$ac_t""$sampwlibname" 1>&6
+
+
+
+#################################################
+# check for libmsrpc support
+echo $ac_n "checking whether to use libmsrpc""... $ac_c" 1>&6
+echo "configure:8939: checking whether to use libmsrpc" >&5
+# Check whether --with-libmsrpc or --without-libmsrpc was given.
+if test "${with_libmsrpc+set}" = set; then
+ withval="$with_libmsrpc"
+ case "$withval" in
+ no)
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define WITH_LIBMSRPC 1
EOF
-if { (eval echo configure:9147: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- samba_cv_NEED_SGI_SEMUN_HACK=yes
+
+ LIBMSRPC="bin/libmsrpc.so"
+
+ if test x$ATTEMPT_LIBMSRPC32_BUILD = x; then
+ LIBMSRPC32=""
+ else
+ LIBMSRPC32=bin/libmsrpc.32.so
+ fi
+
+# Conditions under which libmsrpc should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libmsrpc
+ LIBMSRPC=""
+ LIBMSRPC32=""
+ fi
+ ;;
+ *)
+ echo "$ac_t""no" 1>&6
+ ;;
+ esac
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- samba_cv_NEED_SGI_SEMUN_HACK=no
-fi
-rm -fr conftest*
-fi
+ echo "$ac_t""yes" 1>&6
fi
-echo "$ac_t""$samba_cv_NEED_SGI_SEMUN_HACK" 1>&6
-if test x"$samba_cv_NEED_SGI_SEMUN_HACK" = x"yes"; then
+
+#################################################
+# check for libubiqx support
+echo $ac_n "checking whether to use libubiqx""... $ac_c" 1>&6
+echo "configure:8979: checking whether to use libubiqx" >&5
+# Check whether --with-libubiqx or --without-libubiqx was given.
+if test "${with_libubiqx+set}" = set; then
+ withval="$with_libubiqx"
+ case "$withval" in
+ yes)
+ echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
-#define NEED_SGI_SEMUN_HACK 1
+#define WITH_LIBUBIQX 1
EOF
-fi
+ LIBUBIQX="bin/libubiqx.so"
-echo $ac_n "checking for a crypt that needs truncated salt""... $ac_c" 1>&6
-echo "configure:9170: checking for a crypt that needs truncated salt" >&5
-if eval "test \"`echo '$''{'samba_cv_HAVE_TRUNCATED_SALT'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
-else
-
-if test "$cross_compiling" = yes; then
- samba_cv_HAVE_TRUNCATED_SALT=cross
+ if test x$ATTEMPT_LIBUBIQX32_BUILD = x; then
+ LIBUBIQX32=""
+ else
+ LIBUBIQX32=bin/libubiqx.32.so
+ fi
+
+# Conditions under which libubiqx should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libubiqx
+ LIBUBIQX=""
+ LIBUBIQX32=""
+ fi
+ ;;
+ *)
+ echo "$ac_t""no" 1>&6
+ ;;
+ esac
else
- cat > conftest.$ac_ext <<EOF
-#line 9179 "configure"
-#include "confdefs.h"
-#include "${srcdir-.}/tests/crypttest.c"
+ echo "$ac_t""yes" 1>&6
+
+fi
+
+
+#################################################
+# check for libsamba support
+echo $ac_n "checking whether to use libsamba""... $ac_c" 1>&6
+echo "configure:9019: checking whether to use libsamba" >&5
+# Check whether --with-libsamba or --without-libsamba was given.
+if test "${with_libsamba+set}" = set; then
+ withval="$with_libsamba"
+ case "$withval" in
+ yes)
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define WITH_LIBSAMBA 1
EOF
-if { (eval echo configure:9183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
-then
- samba_cv_HAVE_TRUNCATED_SALT=no
+
+ LIBSAMBA="bin/libsamba.so"
+
+ if test x$ATTEMPT_LIBSAMBA32_BUILD = x; then
+ LIBSAMBA32=""
+ else
+ LIBSAMBA32=bin/libsamba.32.so
+ fi
+
+# Conditions under which libsamba should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libsamba
+ LIBSAMBA=""
+ LIBSAMBA32=""
+ fi
+ ;;
+ *)
+ echo "$ac_t""no" 1>&6
+ ;;
+ esac
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -fr conftest*
- samba_cv_HAVE_TRUNCATED_SALT=yes
-fi
-rm -fr conftest*
-fi
+ echo "$ac_t""yes" 1>&6
fi
-echo "$ac_t""$samba_cv_HAVE_TRUNCATED_SALT" 1>&6
-if test x"$samba_cv_HAVE_TRUNCATED_SALT" = x"yes"; then
+
+#################################################
+# check for libnmb support
+echo $ac_n "checking whether to use libnmb""... $ac_c" 1>&6
+echo "configure:9059: checking whether to use libnmb" >&5
+# Check whether --with-libnmb or --without-libnmb was given.
+if test "${with_libnmb+set}" = set; then
+ withval="$with_libnmb"
+ case "$withval" in
+ yes)
+ echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
-#define HAVE_TRUNCATED_SALT 1
+#define WITH_LIBNMB 1
EOF
-fi
+ LIBNMB="bin/libnmb.so"
-echo $ac_n "checking for broken nisplus include files""... $ac_c" 1>&6
-echo "configure:9206: checking for broken nisplus include files" >&5
-if eval "test \"`echo '$''{'samba_cv_BROKEN_NISPLUS_INCLUDE_FILES'+set}'`\" = set"; then
- echo $ac_n "(cached) $ac_c" 1>&6
+ if test x$ATTEMPT_LIBNMB32_BUILD = x; then
+ LIBNMB32=""
+ else
+ LIBNMB32=bin/libnmb.32.so
+ fi
+
+# Conditions under which libnmb should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libnmb
+ LIBNMB=""
+ LIBNMB32=""
+ fi
+ ;;
+ *)
+ echo "$ac_t""no" 1>&6
+ ;;
+ esac
else
-
-cat > conftest.$ac_ext <<EOF
-#line 9212 "configure"
-#include "confdefs.h"
-#include <sys/acl.h>
-#if defined(HAVE_RPCSVC_NIS_H)
-#include <rpcsvc/nis.h>
-#endif
-int main() {
-return 0;
-; return 0; }
+ echo "$ac_t""yes" 1>&6
+
+fi
+
+
+#################################################
+# check for libsurs support
+echo $ac_n "checking whether to use libsurs""... $ac_c" 1>&6
+echo "configure:9099: checking whether to use libsurs" >&5
+# Check whether --with-libsurs or --without-libsurs was given.
+if test "${with_libsurs+set}" = set; then
+ withval="$with_libsurs"
+ case "$withval" in
+ yes)
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define WITH_LIBSURS 1
EOF
-if { (eval echo configure:9222: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=no
+
+ LIBSURS="bin/libsurs.so"
+
+ if test x$ATTEMPT_LIBSURS32_BUILD = x; then
+ LIBSURS32=""
+ else
+ LIBSURS32=bin/libsurs.32.so
+ fi
+
+# Conditions under which libsurs should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libsurs
+ LIBSURS=""
+ LIBSURS32=""
+ fi
+ ;;
+ *)
+ echo "$ac_t""no" 1>&6
+ ;;
+ esac
else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=yes
+ echo "$ac_t""yes" 1>&6
+
fi
-rm -f conftest*
+
+
+#################################################
+# check for libsmbpw support
+echo $ac_n "checking whether to use libsmbpw""... $ac_c" 1>&6
+echo "configure:9139: checking whether to use libsmbpw" >&5
+# Check whether --with-libsmbpw or --without-libsmbpw was given.
+if test "${with_libsmbpw+set}" = set; then
+ withval="$with_libsmbpw"
+ case "$withval" in
+ yes)
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define WITH_LIBSMBPW 1
+EOF
+
+ LIBSMBPW="bin/libsmbpw.so"
+
+ if test x$ATTEMPT_LIBSMBPW32_BUILD = x; then
+ LIBSMBPW32=""
+ else
+ LIBSMBPW32=bin/libsmbpw.32.so
+ fi
+
+# Conditions under which libsmbpw should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libsmbpw
+ LIBSMBPW=""
+ LIBSMBPW32=""
+ fi
+ ;;
+ *)
+ echo "$ac_t""no" 1>&6
+ ;;
+ esac
+else
+ echo "$ac_t""yes" 1>&6
+
fi
-echo "$ac_t""$samba_cv_BROKEN_NISPLUS_INCLUDE_FILES" 1>&6
-if test x"$samba_cv_BROKEN_NISPLUS_INCLUDE_FILES" = x"yes"; then
+
+
+#################################################
+# check for libsmb support
+echo $ac_n "checking whether to use libsmb""... $ac_c" 1>&6
+echo "configure:9180: checking whether to use libsmb" >&5
+# Check whether --with-libsmb or --without-libsmb was given.
+if test "${with_libsmb+set}" = set; then
+ withval="$with_libsmb"
+ case "$withval" in
+ yes)
+ echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
-#define BROKEN_NISPLUS_INCLUDE_FILES 1
+#define WITH_LIBSMB 1
EOF
+ LIBSMB="bin/libsmb.so"
+
+ if test x$ATTEMPT_LIBSMB32_BUILD = x; then
+ LIBSMB32=""
+ else
+ LIBSMB32=bin/libsmb.32.so
+ fi
+
+# Conditions under which libsmb should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libsmb
+ LIBSMB=""
+ LIBSMB32=""
+ fi
+ ;;
+ *)
+ echo "$ac_t""no" 1>&6
+ ;;
+ esac
+else
+ echo "$ac_t""yes" 1>&6
+
fi
+
#################################################
# check for smbwrapper support
echo $ac_n "checking whether to use smbwrapper""... $ac_c" 1>&6
-echo "configure:9246: checking whether to use smbwrapper" >&5
+echo "configure:9221: checking whether to use smbwrapper" >&5
# Check whether --with-smbwrapper or --without-smbwrapper was given.
if test "${with_smbwrapper+set}" = set; then
withval="$with_smbwrapper"
@@ -9253,12 +9228,12 @@ if test "${with_smbwrapper+set}" = set; then
#define WITH_SMBWRAPPER 1
EOF
- WRAP="bin/smbsh bin/smbwrapper.$SHLIBEXT"
+ WRAP="bin/smbsh bin/smbwrapper.so"
if test x$ATTEMPT_WRAP32_BUILD = x; then
WRAP32=""
else
- WRAP32=bin/smbwrapper.32.$SHLIBEXT
+ WRAP32=bin/smbwrapper.32.so
fi
# Conditions under which smbwrapper should not be built.
@@ -9286,7 +9261,7 @@ fi
#################################################
# check for the AFS filesystem
echo $ac_n "checking whether to use AFS""... $ac_c" 1>&6
-echo "configure:9290: checking whether to use AFS" >&5
+echo "configure:9265: checking whether to use AFS" >&5
# Check whether --with-afs or --without-afs was given.
if test "${with_afs+set}" = set; then
withval="$with_afs"
@@ -9312,7 +9287,7 @@ fi
#################################################
# check for the DFS auth system
echo $ac_n "checking whether to use DFS auth""... $ac_c" 1>&6
-echo "configure:9316: checking whether to use DFS auth" >&5
+echo "configure:9291: checking whether to use DFS auth" >&5
# Check whether --with-dfs or --without-dfs was given.
if test "${with_dfs+set}" = set; then
withval="$with_dfs"
@@ -9337,7 +9312,7 @@ fi
#################################################
# check for Kerberos IV auth system
echo $ac_n "checking whether to use Kerberos IV""... $ac_c" 1>&6
-echo "configure:9341: checking whether to use Kerberos IV" >&5
+echo "configure:9316: checking whether to use Kerberos IV" >&5
# Check whether --with-krb4 or --without-krb4 was given.
if test "${with_krb4+set}" = set; then
withval="$with_krb4"
@@ -9347,7 +9322,7 @@ if test "${with_krb4+set}" = set; then
EOF
echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6
-echo "configure:9351: checking for dn_expand in -lresolv" >&5
+echo "configure:9326: checking for dn_expand in -lresolv" >&5
ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -9355,7 +9330,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lresolv $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 9359 "configure"
+#line 9334 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -9366,7 +9341,7 @@ int main() {
dn_expand()
; return 0; }
EOF
-if { (eval echo configure:9370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:9345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -9403,30 +9378,9 @@ fi
#################################################
-# check for Kerberos 5 auth system
-echo $ac_n "checking whether to use Kerberos 5""... $ac_c" 1>&6
-echo "configure:9409: checking whether to use Kerberos 5" >&5
-# Check whether --with-krb5 or --without-krb5 was given.
-if test "${with_krb5+set}" = set; then
- withval="$with_krb5"
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define KRB5_AUTH 1
-EOF
-
- LIBS="$LIBS -ldes425 -lkrb5 -lcrypto -lcom_err"
- CFLAGS="$CFLAGS -I$withval/include"
- LDFLAGS="$LDFLAGS -L$withval/lib"
-else
- echo "$ac_t""no" 1>&6
-
-fi
-
-
-#################################################
# check for automount support
echo $ac_n "checking whether to use AUTOMOUNT""... $ac_c" 1>&6
-echo "configure:9430: checking whether to use AUTOMOUNT" >&5
+echo "configure:9384: checking whether to use AUTOMOUNT" >&5
# Check whether --with-automount or --without-automount was given.
if test "${with_automount+set}" = set; then
withval="$with_automount"
@@ -9451,7 +9405,7 @@ fi
#################################################
# check for smbmount support
echo $ac_n "checking whether to use SMBMOUNT""... $ac_c" 1>&6
-echo "configure:9455: checking whether to use SMBMOUNT" >&5
+echo "configure:9409: checking whether to use SMBMOUNT" >&5
# Check whether --with-smbmount or --without-smbmount was given.
if test "${with_smbmount+set}" = set; then
withval="$with_smbmount"
@@ -9476,22 +9430,20 @@ else
fi
-
#################################################
-# check for a PAM password database
-echo $ac_n "checking whether to use PAM password database""... $ac_c" 1>&6
-echo "configure:9484: checking whether to use PAM password database" >&5
-# Check whether --with-pam or --without-pam was given.
-if test "${with_pam+set}" = set; then
- withval="$with_pam"
+# check to use a tdb surs database
+echo $ac_n "checking whether to use SURS tdb database""... $ac_c" 1>&6
+echo "configure:9437: checking whether to use SURS tdb database" >&5
+# Check whether --with-surstdb or --without-surstdb was given.
+if test "${with_surstdb+set}" = set; then
+ withval="$with_surstdb"
case "$withval" in
yes)
echo "$ac_t""yes" 1>&6
cat >> confdefs.h <<\EOF
-#define WITH_PAM 1
+#define WITH_TDBSURS 1
EOF
- LIBS="$LIBS -lpam"
;;
*)
echo "$ac_t""no" 1>&6
@@ -9503,11 +9455,10 @@ else
fi
-
#################################################
# check for a LDAP password database
echo $ac_n "checking whether to use LDAP password database""... $ac_c" 1>&6
-echo "configure:9511: checking whether to use LDAP password database" >&5
+echo "configure:9462: checking whether to use LDAP password database" >&5
# Check whether --with-ldap or --without-ldap was given.
if test "${with_ldap+set}" = set; then
withval="$with_ldap"
@@ -9518,7 +9469,59 @@ if test "${with_ldap+set}" = set; then
#define WITH_LDAP 1
EOF
- { echo "configure: error: LDAP password database not supported in this version." 1>&2; exit 1; }
+ LIBS="$LIBS -lldap -llber"
+ ;;
+ *)
+ echo "$ac_t""no" 1>&6
+ ;;
+ esac
+else
+ echo "$ac_t""no" 1>&6
+
+fi
+
+
+#################################################
+# check for a LDAP password database
+echo $ac_n "checking whether to use LDAP password database""... $ac_c" 1>&6
+echo "configure:9488: checking whether to use LDAP password database" >&5
+# Check whether --with-nt5ldap or --without-nt5ldap was given.
+if test "${with_nt5ldap+set}" = set; then
+ withval="$with_nt5ldap"
+ case "$withval" in
+ yes)
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define WITH_NT5LDAP 1
+EOF
+
+ LIBS="$LIBS -lldap -llber"
+ ;;
+ *)
+ echo "$ac_t""no" 1>&6
+ ;;
+ esac
+else
+ echo "$ac_t""no" 1>&6
+
+fi
+
+
+#################################################
+# check for a LDAP password database
+echo $ac_n "checking whether to use LDAP password database""... $ac_c" 1>&6
+echo "configure:9514: checking whether to use LDAP password database" >&5
+# Check whether --with-nt5ldap or --without-nt5ldap was given.
+if test "${with_nt5ldap+set}" = set; then
+ withval="$with_nt5ldap"
+ case "$withval" in
+ yes)
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define WITH_NT5LDAP 1
+EOF
+
+ LIBS="$LIBS -lldap -llber"
;;
*)
echo "$ac_t""no" 1>&6
@@ -9533,7 +9536,7 @@ fi
#################################################
# check for a NISPLUS password database
echo $ac_n "checking whether to use NISPLUS password database""... $ac_c" 1>&6
-echo "configure:9537: checking whether to use NISPLUS password database" >&5
+echo "configure:9540: checking whether to use NISPLUS password database" >&5
# Check whether --with-nisplus or --without-nisplus was given.
if test "${with_nisplus+set}" = set; then
withval="$with_nisplus"
@@ -9558,7 +9561,7 @@ fi
#################################################
# check for a NISPLUS_HOME support
echo $ac_n "checking whether to use NISPLUS_HOME""... $ac_c" 1>&6
-echo "configure:9562: checking whether to use NISPLUS_HOME" >&5
+echo "configure:9565: checking whether to use NISPLUS_HOME" >&5
# Check whether --with-nisplus-home or --without-nisplus-home was given.
if test "${with_nisplus_home+set}" = set; then
withval="$with_nisplus_home"
@@ -9583,7 +9586,7 @@ fi
#################################################
# check for the secure socket layer
echo $ac_n "checking whether to use SSL""... $ac_c" 1>&6
-echo "configure:9587: checking whether to use SSL" >&5
+echo "configure:9590: checking whether to use SSL" >&5
# Check whether --with-ssl or --without-ssl was given.
if test "${with_ssl+set}" = set; then
withval="$with_ssl"
@@ -9594,39 +9597,30 @@ if test "${with_ssl+set}" = set; then
#define WITH_SSL 1
EOF
- withval="/usr/local/ssl" # default
-
- if test "${with_sslinc+set}" = set; then
-
- withval="$with_sslinc"
- case "$withval" in
- yes|no)
- echo "configure: warning: --with-sslinc called without argument - will use default" 1>&w
- CFLAGS="-I/usr/local/ssl/include $CFLAGS"
- LIBS="-lssl -lcrypto $LIBS"
- LDFLAGS="=L/usr/local/ssl/lib $LDFLAGS"
- ;;
- * )
- CFLAGS="-I${withval}/include $CFLAGS"
- LIBS="-lssl -lcrypto $LIBS"
- LDFLAGS="-L${withval}/lib $LDFLAGS"
- ;;
- esac
-
- else
-
- CFLAGS="-I/usr/local/ssl/include $CFLAGS"
- LIBS="-lssl -lcrypto $LIBS"
- LDFLAGS="-L/usr/local/ssl/lib $LDFLAGS"
+ ;;
+ *)
+ echo "$ac_t""no" 1>&6
+ ;;
+ esac
+else
+ echo "$ac_t""no" 1>&6
- fi
+fi
- if test ! -d ${withval}; then
- echo "configure: error: called with --with-ssl, but ssl base directory ${withval} does not exist or is not a directory. Aborting config" 1>&2
- exit 1
- fi
- CFLAGS="-DHAVE_CRYPT_DECL $CFLAGS" # Damn, SSLeay defines its own
+#################################################
+# check for experimental mmap support
+echo $ac_n "checking whether to use MMAP""... $ac_c" 1>&6
+echo "configure:9615: checking whether to use MMAP" >&5
+# Check whether --with-mmap or --without-mmap was given.
+if test "${with_mmap+set}" = set; then
+ withval="$with_mmap"
+ case "$withval" in
+ yes)
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define WITH_MMAP 1
+EOF
;;
*)
@@ -9642,7 +9636,7 @@ fi
#################################################
# check for syslog logging
echo $ac_n "checking whether to use syslog logging""... $ac_c" 1>&6
-echo "configure:9646: checking whether to use syslog logging" >&5
+echo "configure:9640: checking whether to use syslog logging" >&5
# Check whether --with-syslog or --without-syslog was given.
if test "${with_syslog+set}" = set; then
withval="$with_syslog"
@@ -9667,7 +9661,7 @@ fi
#################################################
# check for a shared memory profiling support
echo $ac_n "checking whether to use profiling""... $ac_c" 1>&6
-echo "configure:9671: checking whether to use profiling" >&5
+echo "configure:9665: checking whether to use profiling" >&5
# Check whether --with-profile or --without-profile was given.
if test "${with_profile+set}" = set; then
withval="$with_profile"
@@ -9693,7 +9687,7 @@ fi
#################################################
# check for experimental netatalk resource fork support
echo $ac_n "checking whether to support netatalk""... $ac_c" 1>&6
-echo "configure:9697: checking whether to support netatalk" >&5
+echo "configure:9691: checking whether to support netatalk" >&5
# Check whether --with-netatalk or --without-netatalk was given.
if test "${with_netatalk+set}" = set; then
withval="$with_netatalk"
@@ -9720,7 +9714,7 @@ fi
QUOTAOBJS=noquotas.o
echo $ac_n "checking whether to support disk-quotas""... $ac_c" 1>&6
-echo "configure:9724: checking whether to support disk-quotas" >&5
+echo "configure:9718: checking whether to support disk-quotas" >&5
# Check whether --with-quotas or --without-quotas was given.
if test "${with_quotas+set}" = set; then
withval="$with_quotas"
@@ -9741,117 +9735,16 @@ fi
#################################################
-# check for experimental utmp accounting
-
-echo $ac_n "checking whether to support utmp accounting""... $ac_c" 1>&6
-echo "configure:9748: checking whether to support utmp accounting" >&5
-# Check whether --with-utmp or --without-utmp was given.
-if test "${with_utmp+set}" = set; then
- withval="$with_utmp"
- case "$withval" in
- yes)
- echo "$ac_t""yes" 1>&6
- cat >> confdefs.h <<\EOF
-#define WITH_UTMP 1
-EOF
-
- ;;
- *)
- echo "$ac_t""no" 1>&6
- ;;
- esac
-else
- echo "$ac_t""no" 1>&6
-
-fi
-
-
-#################################################
-# set private directory location
-# Check whether --with-privatedir or --without-privatedir was given.
-if test "${with_privatedir+set}" = set; then
- withval="$with_privatedir"
- case "$withval" in
- yes|no)
- #
- # Just in case anybody calls it without argument
- #
- echo "configure: warning: --with-privatedir called without argument - will use default" 1>&2
- privatedir='${prefix}/private'
- ;;
- * )
- privatedir="$withval"
- ;;
- esac
-
-else
- privatedir='${prefix}/private'
-
-
-fi
-
-
-#################################################
-# set lock directory location
-# Check whether --with-lockdir or --without-lockdir was given.
-if test "${with_lockdir+set}" = set; then
- withval="$with_lockdir"
- case "$withval" in
- yes|no)
- #
- # Just in case anybody calls it without argument
- #
- echo "configure: warning: --with-lockdir called without argument - will use default" 1>&2
- lockdir='$(VARDIR)/locks'
- ;;
- * )
- lockdir="$withval"
- ;;
- esac
-
-else
- lockdir='$(VARDIR)/locks'
-
-
-fi
-
-
-#################################################
-# set SWAT directory location
-# Check whether --with-swatdir or --without-swatdir was given.
-if test "${with_swatdir+set}" = set; then
- withval="$with_swatdir"
- case "$withval" in
- yes|no)
- #
- # Just in case anybody does it
- #
- echo "configure: warning: --with-swatdir called without argument - will use default" 1>&2
- swatdir='${prefix}/swat'
- ;;
- * )
- swatdir="$withval"
- ;;
- esac
-
-else
- swatdir='${prefix}/swat'
-
-
-fi
-
-
-#################################################
# these tests are taken from the GNU fileutils package
echo "checking how to get filesystem space usage" 1>&6
-echo "configure:9848: checking how to get filesystem space usage" >&5
+echo "configure:9741: checking how to get filesystem space usage" >&5
space=no
# Test for statvfs64.
if test $space = no; then
# SVR4
echo $ac_n "checking statvfs64 function (SVR4)""... $ac_c" 1>&6
-echo "configure:9855: checking statvfs64 function (SVR4)" >&5
+echo "configure:9748: checking statvfs64 function (SVR4)" >&5
if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs64'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -9859,21 +9752,18 @@ else
fu_cv_sys_stat_statvfs64=cross
else
cat > conftest.$ac_ext <<EOF
-#line 9863 "configure"
+#line 9756 "configure"
#include "confdefs.h"
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
#include <sys/types.h>
#include <sys/statvfs.h>
main ()
{
struct statvfs64 fsd;
- exit (statvfs64 (".", &fsd));
+ exit (statfs64 (".", &fsd));
}
EOF
-if { (eval echo configure:9877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
fu_cv_sys_stat_statvfs64=yes
else
@@ -9906,12 +9796,12 @@ fi
if test $space = no; then
# SVR4
echo $ac_n "checking statvfs function (SVR4)""... $ac_c" 1>&6
-echo "configure:9910: checking statvfs function (SVR4)" >&5
+echo "configure:9800: checking statvfs function (SVR4)" >&5
if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 9915 "configure"
+#line 9805 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/statvfs.h>
@@ -9919,7 +9809,7 @@ int main() {
struct statvfs fsd; statvfs (0, &fsd);
; return 0; }
EOF
-if { (eval echo configure:9923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:9813: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
fu_cv_sys_stat_statvfs=yes
else
@@ -9944,7 +9834,7 @@ fi
if test $space = no; then
# DEC Alpha running OSF/1
echo $ac_n "checking for 3-argument statfs function (DEC OSF/1)""... $ac_c" 1>&6
-echo "configure:9948: checking for 3-argument statfs function (DEC OSF/1)" >&5
+echo "configure:9838: checking for 3-argument statfs function (DEC OSF/1)" >&5
if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs3_osf1'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -9952,7 +9842,7 @@ else
fu_cv_sys_stat_statfs3_osf1=no
else
cat > conftest.$ac_ext <<EOF
-#line 9956 "configure"
+#line 9846 "configure"
#include "confdefs.h"
#include <sys/param.h>
@@ -9965,7 +9855,7 @@ else
exit (statfs (".", &fsd, sizeof (struct statfs)));
}
EOF
-if { (eval echo configure:9969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9859: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
fu_cv_sys_stat_statfs3_osf1=yes
else
@@ -9992,7 +9882,7 @@ fi
if test $space = no; then
# AIX
echo $ac_n "checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)""... $ac_c" 1>&6
-echo "configure:9996: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5
+echo "configure:9886: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5
if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_bsize'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -10000,7 +9890,7 @@ else
fu_cv_sys_stat_statfs2_bsize=no
else
cat > conftest.$ac_ext <<EOF
-#line 10004 "configure"
+#line 9894 "configure"
#include "confdefs.h"
#ifdef HAVE_SYS_PARAM_H
@@ -10019,7 +9909,7 @@ else
exit (statfs (".", &fsd));
}
EOF
-if { (eval echo configure:10023: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9913: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
fu_cv_sys_stat_statfs2_bsize=yes
else
@@ -10046,7 +9936,7 @@ fi
if test $space = no; then
# SVR3
echo $ac_n "checking for four-argument statfs (AIX-3.2.5, SVR3)""... $ac_c" 1>&6
-echo "configure:10050: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5
+echo "configure:9940: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5
if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs4'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -10054,7 +9944,7 @@ else
fu_cv_sys_stat_statfs4=no
else
cat > conftest.$ac_ext <<EOF
-#line 10058 "configure"
+#line 9948 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/statfs.h>
@@ -10064,7 +9954,7 @@ else
exit (statfs (".", &fsd, sizeof fsd, 0));
}
EOF
-if { (eval echo configure:10068: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:9958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
fu_cv_sys_stat_statfs4=yes
else
@@ -10091,7 +9981,7 @@ fi
if test $space = no; then
# 4.4BSD and NetBSD
echo $ac_n "checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)""... $ac_c" 1>&6
-echo "configure:10095: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5
+echo "configure:9985: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5
if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_fsize'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -10099,7 +9989,7 @@ else
fu_cv_sys_stat_statfs2_fsize=no
else
cat > conftest.$ac_ext <<EOF
-#line 10103 "configure"
+#line 9993 "configure"
#include "confdefs.h"
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
@@ -10115,7 +10005,7 @@ else
exit (statfs (".", &fsd));
}
EOF
-if { (eval echo configure:10119: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10009: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
fu_cv_sys_stat_statfs2_fsize=yes
else
@@ -10142,7 +10032,7 @@ fi
if test $space = no; then
# Ultrix
echo $ac_n "checking for two-argument statfs with struct fs_data (Ultrix)""... $ac_c" 1>&6
-echo "configure:10146: checking for two-argument statfs with struct fs_data (Ultrix)" >&5
+echo "configure:10036: checking for two-argument statfs with struct fs_data (Ultrix)" >&5
if eval "test \"`echo '$''{'fu_cv_sys_stat_fs_data'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -10150,7 +10040,7 @@ else
fu_cv_sys_stat_fs_data=no
else
cat > conftest.$ac_ext <<EOF
-#line 10154 "configure"
+#line 10044 "configure"
#include "confdefs.h"
#include <sys/types.h>
#ifdef HAVE_SYS_PARAM_H
@@ -10170,7 +10060,7 @@ else
exit (statfs (".", &fsd) != 1);
}
EOF
-if { (eval echo configure:10174: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10064: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
fu_cv_sys_stat_fs_data=yes
else
@@ -10194,59 +10084,16 @@ EOF
fi
fi
-#
-# As a gating factor for large file support, in order to
-# use <4GB files we must have the following minimal support
-# available.
-# long long, and a 64 bit off_t or off64_t.
-# If we don't have all of these then disable large
-# file support.
-#
-echo "checking if large file support can be enabled"
-cat > conftest.$ac_ext <<EOF
-#line 10208 "configure"
-#include "confdefs.h"
-
-#if defined(HAVE_LONGLONG) && (defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8)))
-#include <sys/types.h>
-#else
-__COMPILE_ERROR_
-#endif
-
-int main() {
-int i
-; return 0; }
-EOF
-if { (eval echo configure:10221: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
- rm -rf conftest*
- samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=yes
-else
- echo "configure: failed program was:" >&5
- cat conftest.$ac_ext >&5
- rm -rf conftest*
- samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=no
-fi
-rm -f conftest*
-if test x"$samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT" = x"yes"; then
- echo "yes"
- cat >> confdefs.h <<\EOF
-#define HAVE_EXPLICIT_LARGEFILE_SUPPORT 1
-EOF
-
-else
- echo "no"
-fi
-
echo "checking configure summary"
if test "$cross_compiling" = yes; then
:
else
cat > conftest.$ac_ext <<EOF
-#line 10246 "configure"
+#line 10093 "configure"
#include "confdefs.h"
#include "${srcdir-.}/tests/summary.c"
EOF
-if { (eval echo configure:10250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:10097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
echo "configure OK";
else
@@ -10285,7 +10132,7 @@ EOF
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
- case `(ac_space=' '; set) 2>&1` in
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
*ac_space=\ *)
# `set' does not quote correctly, so add quotes (double-quote substitution
# turns \\\\ into \\, and sed turns \\ into \).
@@ -10352,7 +10199,7 @@ do
echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
- echo "$CONFIG_STATUS generated by autoconf version 2.12"
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
exit 0 ;;
-help | --help | --hel | --he | --h)
echo "\$ac_cs_usage"; exit 0 ;;
@@ -10372,9 +10219,11 @@ sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
+s%@SHELL@%$SHELL%g
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
@@ -10393,20 +10242,31 @@ s%@includedir@%$includedir%g
s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
-s%@SHELL@%$SHELL%g
-s%@RUNPROG@%$RUNPROG%g
s%@MPROGS@%$MPROGS%g
s%@LDSHFLAGS@%$LDSHFLAGS%g
s%@HOST_OS@%$HOST_OS%g
+s%@LIBMSRPC@%$LIBMSRPC%g
+s%@LIBMSRPC32@%$LIBMSRPC32%g
+s%@LIBNMB@%$LIBNMB%g
+s%@LIBNMB32@%$LIBNMB32%g
+s%@LIBSMB@%$LIBSMB%g
+s%@LIBSURS@%$LIBSURS%g
+s%@LIBSMBPW@%$LIBSMBPW%g
+s%@LIBSMB32@%$LIBSMB32%g
+s%@LIBSURS32@%$LIBSURS32%g
+s%@LIBSMBPW32@%$LIBSMBPW32%g
+s%@LIBUBIQX@%$LIBUBIQX%g
+s%@LIBUBIQX32@%$LIBUBIQX32%g
+s%@LIBSAMBA@%$LIBSAMBA%g
+s%@LIBSAMBA32@%$LIBSAMBA32%g
s%@WRAP@%$WRAP%g
s%@WRAP32@%$WRAP32%g
s%@PICFLAG@%$PICFLAG%g
-s%@SHLIBEXT@%$SHLIBEXT%g
s%@CC@%$CC%g
s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
s%@INSTALL_DATA@%$INSTALL_DATA%g
s%@AWK@%$AWK%g
-s%@BROKEN_CC@%$BROKEN_CC%g
s%@host@%$host%g
s%@host_alias@%$host_alias%g
s%@host_cpu@%$host_cpu%g
@@ -10426,12 +10286,14 @@ s%@MAINT@%$MAINT%g
s%@AUTOCONF@%$AUTOCONF%g
s%@AUTOHEADER@%$AUTOHEADER%g
s%@CPP@%$CPP%g
+s%@RANLIB@%$RANLIB%g
+s%@LN_S@%$LN_S%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@LIBTOOL_DEPS@%$LIBTOOL_DEPS%g
s%@LIBOBJS@%$LIBOBJS%g
s%@ROFF@%$ROFF%g
+s%@SAM_PWDB_LIB@%$SAM_PWDB_LIB%g
s%@QUOTAOBJS@%$QUOTAOBJS%g
-s%@privatedir@%$privatedir%g
-s%@lockdir@%$lockdir%g
-s%@swatdir@%$swatdir%g
s%@builddir@%$builddir%g
CEOF
diff --git a/source/configure.developer b/source/configure.developer
index 6cc442b1aca..ab732416f1e 100755
--- a/source/configure.developer
+++ b/source/configure.developer
@@ -1,3 +1,3 @@
#!/bin/sh
-export CFLAGS="-g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -DDEBUG_PASSWORD"
+CFLAGS="-g -O2 -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -DDEBUG_PASSWORD"; export CFLAGS
./configure $*
diff --git a/source/configure.in b/source/configure.in
index 4d8ef647c80..edc043a6f9f 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -6,14 +6,26 @@ AC_PREFIX_DEFAULT(/usr/local/samba)
dnl Unique-to-Samba variables we'll be playing with.
AC_SUBST(SHELL)
-AC_SUBST(RUNPROG)
AC_SUBST(MPROGS)
AC_SUBST(LDSHFLAGS)
AC_SUBST(HOST_OS)
+AC_SUBST(LIBMSRPC)
+AC_SUBST(LIBMSRPC32)
+AC_SUBST(LIBNMB)
+AC_SUBST(LIBNMB32)
+AC_SUBST(LIBSMB)
+AC_SUBST(LIBSURS)
+AC_SUBST(LIBSMBPW)
+AC_SUBST(LIBSMB32)
+AC_SUBST(LIBSURS32)
+AC_SUBST(LIBSMBPW32)
+AC_SUBST(LIBUBIQX)
+AC_SUBST(LIBUBIQX32)
+AC_SUBST(LIBSAMBA)
+AC_SUBST(LIBSAMBA32)
AC_SUBST(WRAP)
AC_SUBST(WRAP32)
AC_SUBST(PICFLAG)
-AC_SUBST(SHLIBEXT)
# compile with optimisation and without debugging by default
CFLAGS=${CFLAGS-"-O"}
@@ -23,25 +35,6 @@ AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_AWK
-dnl Check if C compiler understands -c and -o at the same time
-AC_PROG_CC_C_O
-if eval "test \"`echo '$ac_cv_prog_cc_'${ac_cc}_c_o`\" = no"; then
- BROKEN_CC=
-else
- BROKEN_CC=#
-fi
-AC_SUBST(BROKEN_CC)
-
-dnl Check if the C compiler understands volatile (it should, being ANSI).
-AC_CACHE_CHECK([that the C compiler understands volatile],samba_cv_volatile, [
- AC_TRY_COMPILE([#include <sys/types.h>],[volatile int i = 0],
- samba_cv_volatile=yes,samba_cv_volatile=no)])
-if test x"$samba_cv_volatile" = x"yes"; then
- AC_DEFINE(HAVE_VOLATILE)
-fi
-
-
-
AC_CANONICAL_SYSTEM
AC_VALIDATE_CACHE_SYSTEM_TYPE
SAMBA_MAINTAINER_MODE
@@ -57,114 +50,24 @@ case "$host_os" in
if test $ac_cv_prog_cc_Ae = yes; then
CPPFLAGS="$CPPFLAGS -Ae"
fi
-#
-# Defines needed for HPUX support.
-# HPUX has bigcrypt but (sometimes?) doesn't use it for
-# password hashing - hence the USE_BOTH_CRYPT_CALLS define.
-#
- case `uname -r` in
- *9*|*10*)
- CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE"
- AC_DEFINE(USE_BOTH_CRYPT_CALLS)
- ;;
- *11*)
- CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_POSIX_SOURCE -D_LARGEFILE64_SOURCE"
- AC_DEFINE(USE_BOTH_CRYPT_CALLS)
- ;;
- esac
;;
#
-# AIX4.x doesn't even admit to having large
+# AIX4.x is *so* broken. It doesn't even admit to having large
# files *at all* unless the -D_LARGE_FILE or -D_LARGE_FILE_API flags are set.
#
*aix4*)
- AC_MSG_RESULT([enabling large file support])
CPPFLAGS="$CPPFLAGS -D_LARGE_FILES"
;;
#
-# Defines needed for Solaris 2.6/2.7 aka 7.0 to make it admit
-# to the existance of large files..
-# Note that -D_LARGEFILE64_SOURCE is different from the Sun
-# recommendations on large file support, however it makes the
-# compile work using gcc 2.7 and 2.8, whereas using the Sun
-# recommendation makes the compile fail on gcc2.7. JRA.
-#
- *solaris*)
- case `uname -r` in
- 5.6*|5.7*)
- AC_MSG_RESULT([enabling large file support])
- if test "$ac_cv_prog_gcc" = yes; then
- ${CC-cc} -v >conftest.c 2>&1
- ac_cv_gcc_compiler_version_number=`grep 'gcc version' conftest.c`
- rm -fr conftest.c
- case "$ac_cv_gcc_compiler_version_number" in
- *"gcc version 2.6"*|*"gcc version 2.7"*)
- CPPFLAGS="$CPPFLAGS -D_LARGEFILE64_SOURCE"
- ;;
- *)
- CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
- ;;
- esac
- else
- CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
- fi
- ;;
- esac
- ;;
-#
-# Tests needed for SINIX large file support.
+# Irix needs standards.h to detect netinet
#
- *sysv4*)
- if test $host = mips-sni-sysv4 ; then
- AC_MSG_CHECKING([for LFS support])
- old_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS"
- AC_TRY_RUN([
-#include <unistd.h>
-main () {
-#if _LFS64_LARGEFILE == 1
-exit(0);
-#else
-exit(1);
-#endif
-}], [SINIX_LFS_SUPPORT=yes], [SINIX_LFS_SUPPORT=no], [SINIX_LFS_SUPPORT=cross])
- CPPFLAGS="$old_CPPFLAGS"
- if test x$SINIX_LFS_SUPPORT = xyes ; then
- CPPFLAGS="-D_LARGEFILE64_SOURCE $CPPFLAGS"
- CFLAGS="`getconf LFS64_CFLAGS` $CFLAGS"
- LDFLAGS="`getconf LFS64_LDFLAGS` $LDFLAGS"
- LIBS="`getconf LFS64_LIBS` $LIBS"
- fi
- AC_MSG_RESULT([$SINIX_LFS_SUPPORT])
- fi
- ;;
-
-#
-# Tests needed for glibc 2.1 large file support.
-#
- *linux*)
- AC_MSG_RESULT([disabling large file support for glibc2.1 on Linux])
- ;;
- *hurd*)
- AC_MSG_CHECKING([for LFS support])
- old_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS"
- AC_TRY_RUN([
-#include <unistd.h>
-main () {
-#if _LFS64_LARGEFILE == 1
-exit(0);
-#else
-exit(1);
-#endif
-}], [GLIBC_LFS_SUPPORT=yes], [GLIBC_LFS_SUPPORT=no], [GLIBC_LFS_SUPPORT=cross])
- CPPFLAGS="$old_CPPFLAGS"
- if test x$GLIBC_LFS_SUPPORT = xyes ; then
- CPPFLAGS="-D_LARGEFILE64_SOURCE -D_GNU_SOURCE $CPPFLAGS"
- fi
- AC_MSG_RESULT([$GLIBC_LFS_SUPPORT])
- ;;
-
+ *irix*)
+ AC_CHECK_HEADERS(standards.h,
+ cat >> confdefs.h <<EOF
+#include <standards.h>
+EOF
+)
+ ;;
esac
AC_INLINE
@@ -172,34 +75,18 @@ AC_HEADER_STDC
AC_HEADER_DIRENT
AC_HEADER_TIME
AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(arpa/inet.h sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h)
-AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h net/if.h)
-AC_CHECK_HEADERS(compat.h rpc/rpc.h rpcsvc/nis.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h)
-AC_CHECK_HEADERS(sys/param.h ctype.h sys/un.h sys/wait.h sys/resource.h sys/ioctl.h sys/mode.h)
-AC_CHECK_HEADERS(sys/mman.h sys/filio.h sys/priv.h string.h strings.h stdlib.h sys/socket.h)
-AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h termio.h)
-AC_CHECK_HEADERS(sys/termio.h sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h)
-#
-# HPUX has a bug in that including shadow.h causes a re-definition of MAXINT.
-# This causes configure to fail to detect it. Check for shadow separately on HPUX.
-#
-case "$host_os" in
- *hpux*)
- AC_TRY_COMPILE([#include <shadow.h>],[struct spwd testme],
- ac_cv_header_shadow_h=yes,ac_cv_header_shadow_h=no)
- if test x"$ac_cv_header_shadow_h" = x"yes"; then
- AC_DEFINE(HAVE_SHADOW_H)
- fi
- ;;
-esac
-AC_CHECK_HEADERS(shadow.h netinet/ip.h netinet/tcp.h netinet/in_systm.h netinet/in_ip.h)
-AC_CHECK_HEADERS(sys/security.h security/pam_appl.h)
+AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h)
+AC_CHECK_HEADERS(sys/param.h ctype.h )
+AC_CHECK_HEADERS(unistd.h utime.h grp.h sys/id.h limits.h memory.h net/route.h net/if.h)
+AC_CHECK_HEADERS(compat.h rpc/rpc.h rpcsvc/yp_prot.h rpcsvc/ypclnt.h sys/param.h ctype.h )
+AC_CHECK_HEADERS(sys/wait.h sys/resource.h sys/ioctl.h sys/mode.h sys/mman.h)
+AC_CHECK_HEADERS(sys/filio.h string.h strings.h stdlib.h sys/socket.h sys/un.h)
+AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/fs/s5param.h sys/filsys.h termios.h)
+AC_CHECK_HEADERS(sys/statfs.h sys/dustat.h sys/statvfs.h stdarg.h sys/sockio.h)
+AC_CHECK_HEADERS(shadow.h netinet/tcp.h sys/security.h security/pam_appl.h)
AC_CHECK_HEADERS(stropts.h poll.h readline.h history.h readline/readline.h)
AC_CHECK_HEADERS(readline/history.h sys/capability.h syscall.h sys/syscall.h)
-AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h)
-
-# For experimental utmp support
-AC_CHECK_HEADERS(utmp.h utmpx.h)
+AC_CHECK_HEADERS(sys/acl.h sys/cdefs.h glob.h mysql.h)
AC_CHECK_SIZEOF(int,cross)
AC_CHECK_SIZEOF(long,cross)
@@ -210,6 +97,10 @@ AC_C_INLINE
AC_C_BIGENDIAN
AC_C_CHAR_UNSIGNED
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+
AC_TYPE_SIGNAL
AC_TYPE_UID_T
AC_TYPE_MODE_T
@@ -222,31 +113,10 @@ AC_CHECK_TYPE(ino_t,unsigned)
AC_CHECK_TYPE(loff_t,off_t)
AC_CHECK_TYPE(offset_t,loff_t)
AC_CHECK_TYPE(ssize_t, int)
-AC_CHECK_TYPE(wchar_t, unsigned short)
-
-# we need libcups for CUPS support...
-AC_CHECK_LIB(cups,httpConnect)
-
-# we need libdl for PAM and the new VFS code
-AC_CHECK_LIB(dl, dlopen, [LIBS="$LIBS -ldl";
- AC_DEFINE(HAVE_LIBDL)])
-
-AC_CACHE_CHECK([for sig_atomic_t type],samba_cv_sig_atomic_t, [
- AC_TRY_COMPILE([
-#include <sys/types.h>
-#if STDC_HEADERS
-#include <stdlib.h>
-#include <stddef.h>
-#endif
-#include <signal.h>],[sig_atomic_t i = 0],
- samba_cv_sig_atomic_t=yes,samba_cv_sig_atomic_t=no)])
-if test x"$samba_cv_sig_atomic_t" = x"yes"; then
- AC_DEFINE(HAVE_SIG_ATOMIC_T_TYPE)
-fi
AC_CACHE_CHECK([for errno in errno.h],samba_cv_errno, [
AC_TRY_COMPILE([#include <errno.h>],[int i = errno],
- samba_cv_errno=yes,samba_cv_have_errno=no)])
+ samba_cv_errno=yes,samba_cv_have_errno_decl=no)])
if test x"$samba_cv_errno" = x"yes"; then
AC_DEFINE(HAVE_ERRNO_DECL)
fi
@@ -260,11 +130,11 @@ if test x"$samba_cv_have_setresuid_decl" = x"yes"; then
fi
# stupid glibc has the functions but no declaration. grrrr.
-AC_CACHE_CHECK([for setresgid declaration],samba_cv_have_setresgid_decl,[
- AC_TRY_COMPILE([#include <unistd.h>],[int i = (int)setresgid],
- samba_cv_have_setresgid_decl=yes,samba_cv_have_setresgid_decl=no)])
-if test x"$samba_cv_have_setresgid_decl" = x"yes"; then
- AC_DEFINE(HAVE_SETRESGID_DECL)
+AC_CACHE_CHECK([for crypt declaration],samba_cv_have_crypt_decl,[
+ AC_TRY_COMPILE([#include <unistd.h>],[int i = (int)crypt],
+ samba_cv_have_crypt_decl=yes,samba_cv_have_crypt_decl=no)])
+if test x"$samba_cv_have_crypt_decl" = x"yes"; then
+ AC_DEFINE(HAVE_CRYPT_DECL)
fi
# and glibc has setresuid under linux but the function does
@@ -277,17 +147,6 @@ if test x"$samba_cv_have_setresuid" = x"yes"; then
AC_DEFINE(HAVE_SETRESUID)
fi
-# Do the same check for setresguid...
-#
-AC_CACHE_CHECK([for real setresgid],samba_cv_have_setresgid,[
- AC_TRY_RUN([#include <unistd.h>
-#include <errno.h>
-main() { errno = 0; setresgid(1,1,1); exit(errno != 0 ? (errno==EPERM ? 0 : 1) : 0);}],
- samba_cv_have_setresgid=yes,samba_cv_have_setresgid=no,samba_cv_have_setresgid=cross)])
-if test x"$samba_cv_have_setresgid" = x"yes"; then
- AC_DEFINE(HAVE_SETRESGID)
-fi
-
AC_FUNC_MEMCMP
###############################################
@@ -300,13 +159,37 @@ fi
###############################################
-# test for where we get readline() from
+# test for where we get pam_authenticate() from
+# might need libdl for this to work
+if test "$ac_cv_header_security_pam_appl_h" = "yes"; then
+ AC_CHECK_LIB(dl,main)
+fi
+AC_CHECK_FUNCS(pam_authenticate)
+if test x"$ac_cv_func_pam_authenticate" = x"no"; then
+ AC_CHECK_LIB(pam, pam_authenticate, [LIBS="$LIBS -lpam"
+ AC_DEFINE(HAVE_PAM_AUTHENTICATE)])
+fi
+
+###############################################
+# readline requires some curses routines
if test "$ac_cv_header_readline_h" = "yes" ||
test "$ac_cv_header_readline_readline_h" = "yes"; then
+ AC_CHECK_FUNCS(tputs)
+ AC_CHECK_LIB(curses, tputs, [LIBS="$LIBS -lcurses"])
AC_CHECK_LIB(readline,readline)
+ AC_CACHE_CHECK([for filename_completion_function proto],samba_cv_have_fcf_proto,[
+ AC_TRY_COMPILE([#include <stdio.h>
+#ifdef HAVE_READLINE_H
+#include <readline.h>
+#else
+#include <readline/readline.h>
+#endif],[filename_completion_function],
+ samba_cv_have_fcf_proto=yes,samba_cv_have_fcf_proto=no)])
+ if test x"$samba_cv_have_fcf_proto" = x"yes"; then
+ AC_DEFINE(HAVE_READLINE_FCF_PROTO)
+ fi
fi
-
# The following test taken from the cvs sources
# If we can't find connect, try looking in -lsocket, -lnsl, and -linet.
# The Irix 5 libc.so has connect and gethostbyname, but Irix 5 also has
@@ -341,24 +224,16 @@ if test x"$ac_cv_func_connect" = x"no"; then
fi
fi
-# Check if we have execl, if not we need to compile smbrun.
-AC_CHECK_FUNCS(execl)
-if test x"$ac_cv_func_execl" = x"no"; then
- RUNPROG="bin/smbrun"
-else
- RUNPROG=""
-fi
AC_CHECK_FUNCS(waitpid getcwd strdup strtoul strerror chown chmod chroot)
-AC_CHECK_FUNCS(fstat strchr utime utimes getrlimit fsync bzero memset)
+AC_CHECK_FUNCS(fstat strchr utime utimes getrlimit fsync execl bzero memset)
AC_CHECK_FUNCS(memmove vsnprintf snprintf setsid glob strpbrk pipe crypt16 getauthuid)
AC_CHECK_FUNCS(strftime sigprocmask sigblock sigaction innetgr setnetgrent getnetgrent endnetgrent)
-AC_CHECK_FUNCS(initgroups select rdchk getgrnam getgrent pathconf)
-AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate stat64 fstat64)
-AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64)
-AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid yp_get_default_domain getpwanam)
-AC_CHECK_FUNCS(srandom random srand rand setenv usleep mmap64 strcasecmp fcvt fcvtl)
-
+AC_CHECK_FUNCS(initgroups select rdchk getgrnam pathconf)
+AC_CHECK_FUNCS(setuidx setgroups mktime rename ftruncate stat64 fstat64 lstat64 fopen64)
+AC_CHECK_FUNCS(atexit grantpt dup2 lseek64 ftruncate64)
+AC_CHECK_FUNCS(fseek64 ftell64 setluid yp_get_default_domain getpwanam)
+AC_CHECK_FUNCS(srandom random srand rand setenv mmap64)
# syscall() is needed for smbwrapper.
AC_CHECK_FUNCS(syscall)
@@ -378,63 +253,6 @@ AC_CHECK_FUNCS(pwrite _pwrite __pwrite pwrite64 _pwrite64 __pwrite64)
AC_CHECK_FUNCS(open64 _open64 __open64 creat64)
#
-# stat64 family may need <sys/stat.h> on some systems, notably ReliantUNIX
-#
-
-if test x$ac_cv_func_stat64 = xno ; then
- AC_MSG_CHECKING([for stat64 in <sys/stat.h>])
- AC_TRY_LINK([
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <sys/stat.h>
-], [struct stat64 st64; exit(stat64(".",&st64));], [ac_cv_func_stat64=yes])
- AC_MSG_RESULT([$ac_cv_func_stat64])
- if test x$ac_cv_func_stat64 = xyes ; then
- AC_DEFINE(HAVE_STAT64)
- fi
-fi
-
-if test x$ac_cv_func_lstat64 = xno ; then
- AC_MSG_CHECKING([for lstat64 in <sys/stat.h>])
- AC_TRY_LINK([
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <sys/stat.h>
-], [struct stat64 st64; exit(lstat64(".",&st64));], [ac_cv_func_lstat64=yes])
- AC_MSG_RESULT([$ac_cv_func_lstat64])
- if test x$ac_cv_func_lstat64 = xyes ; then
- AC_DEFINE(HAVE_LSTAT64)
- fi
-fi
-
-if test x$ac_cv_func_fstat64 = xno ; then
- AC_MSG_CHECKING([for fstat64 in <sys/stat.h>])
- AC_TRY_LINK([
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <sys/stat.h>
-], [struct stat64 st64; exit(fstat64(0,&st64));], [ac_cv_func_fstat64=yes])
- AC_MSG_RESULT([$ac_cv_func_fstat64])
- if test x$ac_cv_func_fstat64 = xyes ; then
- AC_DEFINE(HAVE_FSTAT64)
- fi
-fi
-
-#
-# If no strcasecmp, check for it in some known places
-# It is in -lresolv on ReliantUNIX and UnixWare
-# -lresolve *must* follow -lnsl for name resolution to work properly
-#
-
-if test x$ac_cv_func_strcasecmp = xno ; then
- AC_CHECK_LIB(resolv,strcasecmp,[LIBS="$LIBS -lresolv"]
- AC_DEFINE(HAVE_STRCASECMP))
-fi
-
-#
# Check for the functions putprpwnam, set_auth_parameters,
# getspnam, bigcrypt and getprpwnam in -lsec and -lsecurity
# Needed for OSF1 and HPUX.
@@ -446,9 +264,6 @@ AC_LIBTESTFUNC(sec, putprpwnam)
AC_LIBTESTFUNC(security, set_auth_parameters)
AC_LIBTESTFUNC(sec, set_auth_parameters)
-# UnixWare 7.x has its getspnam in -lgen
-AC_LIBTESTFUNC(gen, getspnam)
-
AC_LIBTESTFUNC(security, getspnam)
AC_LIBTESTFUNC(sec, getspnam)
@@ -465,8 +280,6 @@ AC_LIBTESTFUNC(sec, getprpwnam)
# these are the defaults, good for lots of systems
HOST_OS="$host_os"
LDSHFLAGS="-shared"
-PICFLAG=""
-SHLIBEXT="so"
# and these are for particular systems
case "$host_os" in
@@ -480,60 +293,42 @@ case "$host_os" in
*bsd*) LDSHFLAGS="-shared -Bshareable"
;;
*irix*) AC_DEFINE(IRIX)
- case "$host_os" in
- *irix6*) AC_DEFINE(IRIX6)
- ;;
- esac
ATTEMPT_WRAP32_BUILD=yes
+ ATTEMPT_LIBSMB32_BUILD=yes
+ ATTEMPT_LIBSURS32_BUILD=yes
+ ATTEMPT_LIBSMBPW32_BUILD=yes
+ ATTEMPT_LIBNMB32_BUILD=yes
+ ATTEMPT_LIBSAMBA32_BUILD=yes
+ ATTEMPT_LIBUBIQX32_BUILD=yes
+ ATTEMPT_LIBMSRPC32_BUILD=yes
;;
*aix*) AC_DEFINE(AIX);;
- *hpux*) AC_DEFINE(HPUX)
- SHLIBEXT="sl"
- # Use special PIC flags for the native HP-UX compiler.
- if test $ac_cv_prog_cc_Ae = yes; then
- LDSHFLAGS="-b"
- PICFLAG="+z"
- fi
- ;;
+ *hpux*) AC_DEFINE(HPUX);;
*qnx*) AC_DEFINE(QNX);;
*osf*) AC_DEFINE(OSF1);;
*sco*) AC_DEFINE(SCO);;
*next2*) AC_DEFINE(NEXT2);;
*dgux*) AC_CHECK_PROG( ROFF, groff, [groff -etpsR -Tascii -man]);;
- *sysv4*)
- case "$host" in
- *-univel-*) if [ test "$GCC" != yes ]; then
- AC_DEFINE(HAVE_MEMSET)
- fi
- LDSHFLAGS="-G"
- ;;
- *mips-sni-sysv4*) AC_DEFINE(RELIANTUNIX);;
- esac
- ;;
- *sysv5*)
- if [ test "$GCC" != yes ]; then
- AC_DEFINE(HAVE_MEMSET)
- fi
- LDSHFLAGS="-G"
- ;;
+ *sysv4.2*) AC_CHECK_LIB(resolv, strcasecmp);;
esac
# try to work out how to produce pic code with this compiler
+PICFLAG=""
AC_PROG_CC_FLAG(fpic)
if test $ac_cv_prog_cc_fpic = yes; then
- PICFLAG="-fpic";
+ PICFLAG="-fpic";
fi
if test x$PICFLAG = x; then
AC_PROG_CC_FLAG(Kpic)
if test $ac_cv_prog_cc_Kpic = yes; then
PICFLAG="-Kpic";
- fi
+ fi
fi
if test x$PICFLAG = x; then
AC_PROG_CC_FLAG(KPIC)
if test $ac_cv_prog_cc_KPIC = yes; then
PICFLAG="-KPIC";
- fi
+ fi
fi
################
@@ -556,11 +351,7 @@ if test x"$samba_cv_SIZEOF_OFF_T" = x"yes"; then
fi
AC_CACHE_CHECK([for off64_t],samba_cv_HAVE_OFF64_T,[
-AC_TRY_RUN([
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <stdio.h>
+AC_TRY_RUN([#include <stdio.h>
#include <sys/stat.h>
main() { struct stat64 st; off64_t s; if (sizeof(off_t) == sizeof(off64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
samba_cv_HAVE_OFF64_T=yes,samba_cv_HAVE_OFF64_T=no,samba_cv_HAVE_OFF64_T=cross)])
@@ -578,11 +369,7 @@ if test x"$samba_cv_SIZEOF_INO_T" = x"yes"; then
fi
AC_CACHE_CHECK([for ino64_t],samba_cv_HAVE_INO64_T,[
-AC_TRY_RUN([
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <stdio.h>
+AC_TRY_RUN([#include <stdio.h>
#include <sys/stat.h>
main() { struct stat64 st; ino64_t s; if (sizeof(ino_t) == sizeof(ino64_t)) exit(1); exit((lstat64("/dev/null", &st)==0)?0:1); }],
samba_cv_HAVE_INO64_T=yes,samba_cv_HAVE_INO64_T=no,samba_cv_HAVE_INO64_T=cross)])
@@ -590,19 +377,6 @@ if test x"$samba_cv_HAVE_INO64_T" = x"yes"; then
AC_DEFINE(HAVE_INO64_T)
fi
-AC_CACHE_CHECK([for struct dirent64],samba_cv_HAVE_STRUCT_DIRENT64,[
-AC_TRY_COMPILE([
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <sys/types.h>
-#include <dirent.h>],
-[struct dirent64 de;],
-samba_cv_HAVE_STRUCT_DIRENT64=yes,samba_cv_HAVE_STRUCT_DIRENT64=no)])
-if test x"$samba_cv_HAVE_STRUCT_DIRENT64" = x"yes"; then
- AC_DEFINE(HAVE_STRUCT_DIRENT64)
-fi
-
AC_CACHE_CHECK([for union semun],samba_cv_HAVE_UNION_SEMUN,[
AC_TRY_RUN([
#include <sys/types.h>
@@ -762,28 +536,6 @@ if test x"$samba_cv_HAVE_UINT32_FROM_RPC_RPC_H" = x"yes"; then
AC_DEFINE(HAVE_UINT32_FROM_RPC_RPC_H)
fi
-dnl
-dnl Some systems (SCO) have a problem including
-dnl <prot.h> and <rpc/rpc.h> due to AUTH_ERROR being defined
-dnl as a #define in <prot.h> and as part of an enum
-dnl in <rpc/rpc.h>.
-dnl
-
-AC_CACHE_CHECK([for conflicting AUTH_ERROR define in rpc/rpc.h],samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT,[
-AC_TRY_COMPILE([#include <sys/types.h>
-#ifdef HAVE_SYS_SECURITY_H
-#include <sys/security.h>
-#include <prot.h>
-#endif /* HAVE_SYS_SECURITY_H */
-#if defined(HAVE_RPC_RPC_H)
-#include <rpc/rpc.h>
-#endif],
-[int testvar;],
-samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=no,samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT=yes)])
-if test x"$samba_cv_HAVE_RPC_AUTH_ERROR_CONFLICT" = x"yes"; then
- AC_DEFINE(HAVE_RPC_AUTH_ERROR_CONFLICT)
-fi
-
AC_MSG_CHECKING([for test routines])
AC_TRY_RUN([#include "${srcdir-.}/tests/trivial.c"],
AC_MSG_RESULT(yes),
@@ -806,7 +558,7 @@ fi
AC_CACHE_CHECK([whether getpass should be replaced],samba_cv_REPLACE_GETPASS,[
SAVE_CPPFLAGS="$CPPFLAGS"
-CPPFLAGS="$CPPFLAGS -I${srcdir-.}/include -I${srcdir-.}/ubiqx -I${srcdir-.}/smbwrapper"
+CPPFLAGS="$CPPFLAGS -I${srcdir-.}/include -I${srcdir-.}/ubiqx"
AC_TRY_COMPILE([
#define REPLACE_GETPASS 1
#define NO_CONFIG_H 1
@@ -820,22 +572,12 @@ if test x"$samba_cv_REPLACE_GETPASS" = x"yes"; then
AC_DEFINE(REPLACE_GETPASS)
fi
-AC_CACHE_CHECK([for working fnmatch],samba_cv_HAVE_FNMATCH,[
-AC_TRY_RUN([#include <fnmatch.h>
-main() { exit(fnmatch("*.o", "x.o", FNM_PATHNAME) == 0? 0: 1); }],
-samba_cv_HAVE_FNMATCH=yes,samba_cv_HAVE_FNMATCH=no,samba_cv_HAVE_FNMATCH=cross)])
-if test x"$samba_cv_HAVE_FNMATCH" = x"yes"; then
- AC_DEFINE(HAVE_FNMATCH)
-fi
-
AC_CACHE_CHECK([for broken inet_ntoa],samba_cv_REPLACE_INET_NTOA,[
AC_TRY_RUN([
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
-#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
-#endif
main() { struct in_addr ip; ip.s_addr = 0x12345678;
if (strcmp(inet_ntoa(ip),"18.52.86.120") &&
strcmp(inet_ntoa(ip),"120.86.52.18")) { exit(0); }
@@ -845,14 +587,6 @@ if test x"$samba_cv_REPLACE_INET_NTOA" = x"yes"; then
AC_DEFINE(REPLACE_INET_NTOA)
fi
-AC_CACHE_CHECK([for sysconf(_SC_NGROUPS_MAX)],samba_cv_SYSCONF_SC_NGROUPS_MAX,[
-AC_TRY_RUN([#include <unistd.h>
-main() { exit(sysconf(_SC_NGROUPS_MAX) == -1 ? 1 : 0); }],
-samba_cv_SYSCONF_SC_NGROUPS_MAX=yes,samba_cv_SYSCONF_SC_NGROUPS_MAX=no,samba_cv_SYSCONF_SC_NGROUPS_MAX=cross)])
-if test x"$samba_cv_SYSCONF_SC_NGROUPS_MAX" = x"yes"; then
- AC_DEFINE(SYSCONF_SC_NGROUPS_MAX)
-fi
-
AC_CACHE_CHECK([for root],samba_cv_HAVE_ROOT,[
AC_TRY_RUN([main() { exit(getuid() != 0); }],
samba_cv_HAVE_ROOT=yes,samba_cv_HAVE_ROOT=no,samba_cv_HAVE_ROOT=cross)])
@@ -862,46 +596,47 @@ else
AC_MSG_WARN(running as non-root will disable some tests)
fi
-##################
-# look for a method of finding the list of network interfaces
-iface=no;
-AC_CACHE_CHECK([for iface AIX],samba_cv_HAVE_IFACE_AIX,[
+netmask=no;
+AC_CACHE_CHECK([for netmask ifconf],samba_cv_HAVE_NETMASK_IFCONF,[
AC_TRY_RUN([
-#define HAVE_IFACE_AIX 1
-#define AUTOCONF_TEST 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/interfaces.c"],
- samba_cv_HAVE_IFACE_AIX=yes,samba_cv_HAVE_IFACE_AIX=no,samba_cv_HAVE_IFACE_AIX=cross)])
-if test x"$samba_cv_HAVE_IFACE_AIX" = x"yes"; then
- iface=yes;AC_DEFINE(HAVE_IFACE_AIX)
+#define HAVE_NETMASK_IFCONF 1
+#define AUTOCONF 1
+#include "${srcdir-.}/lib/netmask.c"],
+ samba_cv_HAVE_NETMASK_IFCONF=yes,samba_cv_HAVE_NETMASK_IFCONF=no,samba_cv_HAVE_NETMASK_IFCONF=cross)])
+if test x"$samba_cv_HAVE_NETMASK_IFCONF" = x"yes"; then
+ netmask=yes;AC_DEFINE(HAVE_NETMASK_IFCONF)
fi
-if test $iface = no; then
-AC_CACHE_CHECK([for iface ifconf],samba_cv_HAVE_IFACE_IFCONF,[
+if test $netmask = no; then
+AC_CACHE_CHECK([for netmask ifreq],samba_cv_HAVE_NETMASK_IFREQ,[
AC_TRY_RUN([
-#define HAVE_IFACE_IFCONF 1
-#define AUTOCONF_TEST 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/interfaces.c"],
- samba_cv_HAVE_IFACE_IFCONF=yes,samba_cv_HAVE_IFACE_IFCONF=no,samba_cv_HAVE_IFACE_IFCONF=cross)])
-if test x"$samba_cv_HAVE_IFACE_IFCONF" = x"yes"; then
- iface=yes;AC_DEFINE(HAVE_IFACE_IFCONF)
+#define HAVE_NETMASK_IFREQ 1
+#define AUTOCONF 1
+#include "${srcdir-.}/lib/netmask.c"],
+ samba_cv_HAVE_NETMASK_IFREQ=yes,samba_cv_HAVE_NETMASK_IFREQ=no,samba_cv_HAVE_NETMASK_IFREQ=cross)])
+if test x"$samba_cv_HAVE_NETMASK_IFREQ" = x"yes"; then
+ netmask=yes;AC_DEFINE(HAVE_NETMASK_IFREQ)
fi
fi
-if test $iface = no; then
-AC_CACHE_CHECK([for iface ifreq],samba_cv_HAVE_IFACE_IFREQ,[
+if test $netmask = no; then
+AC_CACHE_CHECK([for netmask AIX],samba_cv_HAVE_NETMASK_AIX,[
AC_TRY_RUN([
-#define HAVE_IFACE_IFREQ 1
-#define AUTOCONF_TEST 1
-#include "confdefs.h"
-#include "${srcdir-.}/lib/interfaces.c"],
- samba_cv_HAVE_IFACE_IFREQ=yes,samba_cv_HAVE_IFACE_IFREQ=no,samba_cv_HAVE_IFACE_IFREQ=cross)])
-if test x"$samba_cv_HAVE_IFACE_IFREQ" = x"yes"; then
- iface=yes;AC_DEFINE(HAVE_IFACE_IFREQ)
+#define HAVE_NETMASK_AIX 1
+#define AUTOCONF 1
+#include "${srcdir-.}/lib/netmask.c"],
+ samba_cv_HAVE_NETMASK_AIX=yes,samba_cv_HAVE_NETMASK_AIX=no,samba_cv_HAVE_NETMASK_AIX=cross)])
+if test x"$samba_cv_HAVE_NETMASK_AIX" = x"yes"; then
+ netmask=yes;AC_DEFINE(HAVE_NETMASK_AIX)
fi
fi
+AC_CACHE_CHECK([for trapdoor seteuid],samba_cv_HAVE_TRAPDOOR_UID,[
+AC_TRY_RUN([#include "${srcdir-.}/tests/trapdoor.c"],
+ samba_cv_HAVE_TRAPDOOR_UID=no,samba_cv_HAVE_TRAPDOOR_UID=yes,:)])
+if test x"$samba_cv_HAVE_TRAPDOOR_UID" = x"yes"; then
+ AC_DEFINE(HAVE_TRAPDOOR_UID)
+fi
################################################
# look for a method of setting the effective uid
@@ -968,13 +703,6 @@ if test x"$samba_cv_HAVE_SHARED_MMAP" = x"yes"; then
AC_DEFINE(HAVE_MMAP)
fi
-AC_CACHE_CHECK([for ftruncate needs root],samba_cv_FTRUNCATE_NEEDS_ROOT,[
-AC_TRY_RUN([#include "${srcdir-.}/tests/ftruncroot.c"],
- samba_cv_FTRUNCATE_NEEDS_ROOT=yes,samba_cv_FTRUNCATE_NEEDS_ROOT=no,samba_cv_FTRUNCATE_NEEDS_ROOT=cross)])
-if test x"$samba_cv_FTRUNCATE_NEEDS_ROOT" = x"yes"; then
- AC_DEFINE(FTRUNCATE_NEEDS_ROOT)
-fi
-
AC_CACHE_CHECK([for fcntl locking],samba_cv_HAVE_FCNTL_LOCK,[
AC_TRY_RUN([#include "${srcdir-.}/tests/fcntl_lock.c"],
samba_cv_HAVE_FCNTL_LOCK=yes,samba_cv_HAVE_FCNTL_LOCK=no,samba_cv_HAVE_FCNTL_LOCK=cross)])
@@ -982,24 +710,8 @@ if test x"$samba_cv_HAVE_FCNTL_LOCK" = x"yes"; then
AC_DEFINE(HAVE_FCNTL_LOCK)
fi
-AC_CACHE_CHECK([for broken (glibc2.1/x86) 64 bit fcntl locking],samba_cv_HAVE_BROKEN_FCNTL64_LOCKS,[
-AC_TRY_RUN([#include "${srcdir-.}/tests/fcntl_lock64.c"],
- samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=yes,samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=no,samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=cross)])
-if test x"$samba_cv_HAVE_BROKEN_FCNTL64_LOCKS" = x"yes"; then
- AC_DEFINE(HAVE_BROKEN_FCNTL64_LOCKS)
-
-else
-
-dnl
-dnl Don't check for 64 bit fcntl locking if we know that the
-dnl glibc2.1 broken check has succeeded.
-dnl
-
- AC_CACHE_CHECK([for 64 bit fcntl locking],samba_cv_HAVE_STRUCT_FLOCK64,[
- AC_TRY_RUN([
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
+AC_CACHE_CHECK([for 64 bit fcntl locking],samba_cv_HAVE_STRUCT_FLOCK64,[
+AC_TRY_RUN([
#include <stdio.h>
#include <stdlib.h>
@@ -1018,10 +730,8 @@ exit(1);
#endif
}],
samba_cv_HAVE_STRUCT_FLOCK64=yes,samba_cv_HAVE_STRUCT_FLOCK64=no,samba_cv_HAVE_STRUCT_FLOCK64=cross)])
-
- if test x"$samba_cv_HAVE_STRUCT_FLOCK64" = x"yes"; then
- AC_DEFINE(HAVE_STRUCT_FLOCK64)
- fi
+if test x"$samba_cv_HAVE_STRUCT_FLOCK64" = x"yes"; then
+ AC_DEFINE(HAVE_STRUCT_FLOCK64)
fi
AC_CACHE_CHECK([for sysv ipc],samba_cv_HAVE_SYSV_IPC,[
@@ -1031,30 +741,268 @@ if test x"$samba_cv_HAVE_SYSV_IPC" = x"yes"; then
AC_DEFINE(HAVE_SYSV_IPC)
fi
-AC_CACHE_CHECK([for IRIX sysv ipc semun problem using gcc],samba_cv_NEED_SGI_SEMUN_HACK,[
-AC_TRY_RUN([#include "${srcdir-.}/tests/sgi_sysv_hack.c"],
- samba_cv_NEED_SGI_SEMUN_HACK=yes,samba_cv_NEED_SGI_SEMUN_HACK=no,samba_cv_NEED_SGI_SEMUN_HACK=cross)])
-if test x"$samba_cv_NEED_SGI_SEMUN_HACK" = x"yes"; then
- AC_DEFINE(NEED_SGI_SEMUN_HACK)
-fi
+#################################################
+# decide for the default sam-password-database
+AC_MSG_CHECKING(which sam password database to use)
+AC_ARG_WITH(sam_pwdb,
+[ --with-sam-pwdb={passdb,tdb,nt5ldap}
+ which password-database to use (passdb)],
+[ case "$withval" in
+ ""|passdb)
+ SAM_PWDB_LIB='$(SAMRPASSLIB) $(SMBPWLIB)'
+ sampwlibname="passdb"
+ ;;
+ tdb)
+ SAM_PWDB_LIB='$(SAMRTDBLIB)'
+ sampwlibname="tdb"
+ ;;
+ nt5ldap)
+ SAM_PWDB_LIB='$(SAMRNT5LDAPLIB)'
+ sampwlibname="nt5ldap (must also specify --with-nt5ldap)"
+ ;;
+ *)
+ SAM_PWDB_LIB='$(SAMRPASSLIB)'
+ sampwlibname="passdb (unknown specified!)"
+ ;;
+esac], [
+ SAM_PWDB_LIB='$(SAMRPASSLIB) $(SMBPWLIB)'
+ sampwlibname="passdb (default)"
+])
+AC_MSG_RESULT($sampwlibname)
+AC_SUBST(SAM_PWDB_LIB)
-AC_CACHE_CHECK([for a crypt that needs truncated salt],samba_cv_HAVE_TRUNCATED_SALT,[
-AC_TRY_RUN([#include "${srcdir-.}/tests/crypttest.c"],
- samba_cv_HAVE_TRUNCATED_SALT=no,samba_cv_HAVE_TRUNCATED_SALT=yes,samba_cv_HAVE_TRUNCATED_SALT=cross)])
-if test x"$samba_cv_HAVE_TRUNCATED_SALT" = x"yes"; then
- AC_DEFINE(HAVE_TRUNCATED_SALT)
-fi
-AC_CACHE_CHECK([for broken nisplus include files],samba_cv_BROKEN_NISPLUS_INCLUDE_FILES,[
-AC_TRY_COMPILE([#include <sys/acl.h>
-#if defined(HAVE_RPCSVC_NIS_H)
-#include <rpcsvc/nis.h>
-#endif],
-[return 0;],
-samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=no,samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=yes)])
-if test x"$samba_cv_BROKEN_NISPLUS_INCLUDE_FILES" = x"yes"; then
- AC_DEFINE(BROKEN_NISPLUS_INCLUDE_FILES)
-fi
+#################################################
+# check for libmsrpc support
+AC_MSG_CHECKING(whether to use libmsrpc)
+AC_ARG_WITH(libmsrpc,
+[ --with-libmsrpc Include libmsrpc support (default)
+ --without-libmsrpc Don't include libmsrpc support ],
+[ case "$withval" in
+ no)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_LIBMSRPC)
+ LIBMSRPC="bin/libmsrpc.so"
+
+ if test x$ATTEMPT_LIBMSRPC32_BUILD = x; then
+ LIBMSRPC32=""
+ else
+ LIBMSRPC32=bin/libmsrpc.32.so
+ fi
+
+# Conditions under which libmsrpc should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libmsrpc
+ LIBMSRPC=""
+ LIBMSRPC32=""
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(yes)
+)
+
+#################################################
+# check for libubiqx support
+AC_MSG_CHECKING(whether to use libubiqx)
+AC_ARG_WITH(libubiqx,
+[ --with-libubiqx Include SMB libubiqx support (default)
+ --without-libubiqx Don't include SMB libubiqx support ],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_LIBUBIQX)
+ LIBUBIQX="bin/libubiqx.so"
+
+ if test x$ATTEMPT_LIBUBIQX32_BUILD = x; then
+ LIBUBIQX32=""
+ else
+ LIBUBIQX32=bin/libubiqx.32.so
+ fi
+
+# Conditions under which libubiqx should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libubiqx
+ LIBUBIQX=""
+ LIBUBIQX32=""
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(yes)
+)
+
+#################################################
+# check for libsamba support
+AC_MSG_CHECKING(whether to use libsamba)
+AC_ARG_WITH(libsamba,
+[ --with-libsamba Include SMB libsamba support (default)
+ --without-libsamba Don't include SMB libsamba support ],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_LIBSAMBA)
+ LIBSAMBA="bin/libsamba.so"
+
+ if test x$ATTEMPT_LIBSAMBA32_BUILD = x; then
+ LIBSAMBA32=""
+ else
+ LIBSAMBA32=bin/libsamba.32.so
+ fi
+
+# Conditions under which libsamba should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libsamba
+ LIBSAMBA=""
+ LIBSAMBA32=""
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(yes)
+)
+
+#################################################
+# check for libnmb support
+AC_MSG_CHECKING(whether to use libnmb)
+AC_ARG_WITH(libnmb,
+[ --with-libnmb Include NMB libnmb support (default)
+ --without-libnmb Don't include NMB libnmb support ],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_LIBNMB)
+ LIBNMB="bin/libnmb.so"
+
+ if test x$ATTEMPT_LIBNMB32_BUILD = x; then
+ LIBNMB32=""
+ else
+ LIBNMB32=bin/libnmb.32.so
+ fi
+
+# Conditions under which libnmb should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libnmb
+ LIBNMB=""
+ LIBNMB32=""
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(yes)
+)
+
+#################################################
+# check for libsurs support
+AC_MSG_CHECKING(whether to use libsurs)
+AC_ARG_WITH(libsurs,
+[ --with-libsurs Include SMB libsurs support (default)
+ --without-libsurs Don't include SMB libsurs support ],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_LIBSURS)
+ LIBSURS="bin/libsurs.so"
+
+ if test x$ATTEMPT_LIBSURS32_BUILD = x; then
+ LIBSURS32=""
+ else
+ LIBSURS32=bin/libsurs.32.so
+ fi
+
+# Conditions under which libsurs should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libsurs
+ LIBSURS=""
+ LIBSURS32=""
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(yes)
+)
+
+#################################################
+# check for libsmbpw support
+AC_MSG_CHECKING(whether to use libsmbpw)
+AC_ARG_WITH(libsmbpw,
+[ --with-libsmbpw Include SMB libsmbpw support (default)
+ --without-libsmbpw Don't include SMB libsmbpw support ],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_LIBSMBPW)
+ LIBSMBPW="bin/libsmbpw.so"
+
+ if test x$ATTEMPT_LIBSMBPW32_BUILD = x; then
+ LIBSMBPW32=""
+ else
+ LIBSMBPW32=bin/libsmbpw.32.so
+ fi
+
+# Conditions under which libsmbpw should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libsmbpw
+ LIBSMBPW=""
+ LIBSMBPW32=""
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(yes)
+)
+
+
+#################################################
+# check for libsmb support
+AC_MSG_CHECKING(whether to use libsmb)
+AC_ARG_WITH(libsmb,
+[ --with-libsmb Include SMB libsmb support (default)
+ --without-libsmb Don't include SMB libsmb support ],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_LIBSMB)
+ LIBSMB="bin/libsmb.so"
+
+ if test x$ATTEMPT_LIBSMB32_BUILD = x; then
+ LIBSMB32=""
+ else
+ LIBSMB32=bin/libsmb.32.so
+ fi
+
+# Conditions under which libsmb should not be built.
+
+ if test x$PICFLAG = x; then
+ echo No support for PIC code - disabling libsmb
+ LIBSMB=""
+ LIBSMB32=""
+ fi
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(yes)
+)
#################################################
@@ -1067,12 +1015,12 @@ AC_ARG_WITH(smbwrapper,
yes)
AC_MSG_RESULT(yes)
AC_DEFINE(WITH_SMBWRAPPER)
- WRAP="bin/smbsh bin/smbwrapper.$SHLIBEXT"
+ WRAP="bin/smbsh bin/smbwrapper.so"
if test x$ATTEMPT_WRAP32_BUILD = x; then
WRAP32=""
else
- WRAP32=bin/smbwrapper.32.$SHLIBEXT
+ WRAP32=bin/smbwrapper.32.so
fi
# Conditions under which smbwrapper should not be built.
@@ -1136,7 +1084,7 @@ AC_ARG_WITH(dfs,
AC_MSG_CHECKING(whether to use Kerberos IV)
AC_ARG_WITH(krb4,
[ --with-krb4=base-dir Include Kerberos IV support
- --without-krb4 Don't include Kerbers IV support (default)],
+ --without-krb4 Don't include Kerberos IV support (default)],
[ AC_MSG_RESULT(yes)
AC_DEFINE(KRB4_AUTH)
AC_CHECK_LIB(resolv, dn_expand)
@@ -1147,20 +1095,6 @@ AC_ARG_WITH(krb4,
)
#################################################
-# check for Kerberos 5 auth system
-AC_MSG_CHECKING(whether to use Kerberos 5)
-AC_ARG_WITH(krb5,
-[ --with-krb5=base-dir Include Kerberos 5 support
- --without-krb5 Don't include Kerbers 5 support (default)],
-[ AC_MSG_RESULT(yes)
- AC_DEFINE(KRB5_AUTH)
- LIBS="$LIBS -ldes425 -lkrb5 -lcrypto -lcom_err"
- CFLAGS="$CFLAGS -I$withval/include"
- LDFLAGS="$LDFLAGS -L$withval/lib"],
- AC_MSG_RESULT(no)
-)
-
-#################################################
# check for automount support
AC_MSG_CHECKING(whether to use AUTOMOUNT)
AC_ARG_WITH(automount,
@@ -1199,18 +1133,16 @@ AC_ARG_WITH(smbmount,
MPROGS=
)
-
#################################################
-# check for a PAM password database
-AC_MSG_CHECKING(whether to use PAM password database)
-AC_ARG_WITH(pam,
-[ --with-pam Include PAM password database support
- --without-pam Don't include PAM password database support (default)],
+# check to use a tdb surs database
+AC_MSG_CHECKING(whether to use SURS tdb database)
+AC_ARG_WITH(surstdb,
+[ --with-surstdb Use SURS tdb database
+ --without-surstdb Don't use SURS tdb database (default)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_PAM)
- LIBS="$LIBS -lpam"
+ AC_DEFINE(WITH_TDBSURS)
;;
*)
AC_MSG_RESULT(no)
@@ -1219,7 +1151,6 @@ AC_ARG_WITH(pam,
AC_MSG_RESULT(no)
)
-
#################################################
# check for a LDAP password database
AC_MSG_CHECKING(whether to use LDAP password database)
@@ -1230,7 +1161,45 @@ AC_ARG_WITH(ldap,
yes)
AC_MSG_RESULT(yes)
AC_DEFINE(WITH_LDAP)
- AC_MSG_ERROR([LDAP password database not supported in this version.])
+ LIBS="$LIBS -lldap -llber"
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+)
+
+#################################################
+# check for a LDAP password database
+AC_MSG_CHECKING(whether to use LDAP password database)
+AC_ARG_WITH(nt5ldap,
+[ --with-nt5ldap Include NT5 LDAP support
+ --without-nt5ldap Don't include NT5 LDAP support (default)],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_NT5LDAP)
+ LIBS="$LIBS -lldap -llber"
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+)
+
+#################################################
+# check for a LDAP password database
+AC_MSG_CHECKING(whether to use LDAP password database)
+AC_ARG_WITH(nt5ldap,
+[ --with-nt5ldap Include NT5 LDAP support
+ --without-nt5ldap Don't include NT5 LDAP support (default)],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_NT5LDAP)
+ LIBS="$LIBS -lldap -llber"
;;
*)
AC_MSG_RESULT(no)
@@ -1280,46 +1249,29 @@ AC_ARG_WITH(nisplus-home,
AC_MSG_CHECKING(whether to use SSL)
AC_ARG_WITH(ssl,
[ --with-ssl Include SSL support
- --without-ssl Don't include SSL support (default)
- --with-sslinc=DIR Where the SSL includes are (defaults to /usr/local/ssl)],
+ --without-ssl Don't include SSL support (default)],
[ case "$withval" in
yes)
AC_MSG_RESULT(yes)
AC_DEFINE(WITH_SSL)
- withval="/usr/local/ssl" # default
-
- if test "${with_sslinc+set}" = set; then
-
- withval="$with_sslinc"
- case "$withval" in
- yes|no)
- echo "configure: warning: --with-sslinc called without argument - will use default" 1>&w
- CFLAGS="-I/usr/local/ssl/include $CFLAGS"
- LIBS="-lssl -lcrypto $LIBS"
- LDFLAGS="=L/usr/local/ssl/lib $LDFLAGS"
- ;;
- * )
- CFLAGS="-I${withval}/include $CFLAGS"
- LIBS="-lssl -lcrypto $LIBS"
- LDFLAGS="-L${withval}/lib $LDFLAGS"
- ;;
- esac
-
- else
-
- CFLAGS="-I/usr/local/ssl/include $CFLAGS"
- LIBS="-lssl -lcrypto $LIBS"
- LDFLAGS="-L/usr/local/ssl/lib $LDFLAGS"
-
- fi
-
- if test ! -d ${withval}; then
- echo "configure: error: called with --with-ssl, but ssl base directory ${withval} does not exist or is not a directory. Aborting config" 1>&2
- exit 1
- fi
-
- CFLAGS="-DHAVE_CRYPT_DECL $CFLAGS" # Damn, SSLeay defines its own
+ ;;
+ *)
+ AC_MSG_RESULT(no)
+ ;;
+ esac ],
+ AC_MSG_RESULT(no)
+)
+#################################################
+# check for experimental mmap support
+AC_MSG_CHECKING(whether to use MMAP)
+AC_ARG_WITH(mmap,
+[ --with-mmap Include experimental MMAP support
+ --without-mmap Don't include MMAP support (default)],
+[ case "$withval" in
+ yes)
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_MMAP)
;;
*)
AC_MSG_RESULT(no)
@@ -1405,88 +1357,6 @@ AC_ARG_WITH(quotas,
AC_SUBST(QUOTAOBJS)
#################################################
-# check for experimental utmp accounting
-
-AC_MSG_CHECKING(whether to support utmp accounting)
-AC_ARG_WITH(utmp,
-[ --with-utmp Include experimental utmp accounting
- --without-utmp Don't include experimental utmp accounting (default)],
-[ case "$withval" in
- yes)
- AC_MSG_RESULT(yes)
- AC_DEFINE(WITH_UTMP)
- ;;
- *)
- AC_MSG_RESULT(no)
- ;;
- esac ],
- AC_MSG_RESULT(no)
-)
-
-#################################################
-# set private directory location
-AC_ARG_WITH(privatedir,
-[ --with-privatedir=DIR Where to put smbpasswd ($ac_default_prefix/private)],
-[ case "$withval" in
- yes|no)
- #
- # Just in case anybody calls it without argument
- #
- AC_MSG_WARN([--with-privatedir called without argument - will use default])
- privatedir='${prefix}/private'
- ;;
- * )
- privatedir="$withval"
- ;;
- esac
- AC_SUBST(privatedir)],
- [privatedir='${prefix}/private'
- AC_SUBST(privatedir)]
-)
-
-#################################################
-# set lock directory location
-AC_ARG_WITH(lockdir,
-[ --with-lockdir=DIR Where to put lock files ($ac_default_prefix/var/locks)],
-[ case "$withval" in
- yes|no)
- #
- # Just in case anybody calls it without argument
- #
- AC_MSG_WARN([--with-lockdir called without argument - will use default])
- lockdir='$(VARDIR)/locks'
- ;;
- * )
- lockdir="$withval"
- ;;
- esac
- AC_SUBST(lockdir)],
- [lockdir='$(VARDIR)/locks'
- AC_SUBST(lockdir)]
-)
-
-#################################################
-# set SWAT directory location
-AC_ARG_WITH(swatdir,
-[ --with-swatdir=DIR Where to put SWAT files ($ac_default_prefix/swat)],
-[ case "$withval" in
- yes|no)
- #
- # Just in case anybody does it
- #
- AC_MSG_WARN([--with-swatdir called without argument - will use default])
- swatdir='${prefix}/swat'
- ;;
- * )
- swatdir="$withval"
- ;;
- esac
- AC_SUBST(swatdir)],
- [swatdir='${prefix}/swat'
- AC_SUBST(swatdir)]
-)
-
-#################################################
# these tests are taken from the GNU fileutils package
AC_CHECKING(how to get filesystem space usage)
space=no
@@ -1496,15 +1366,12 @@ if test $space = no; then
# SVR4
AC_CACHE_CHECK([statvfs64 function (SVR4)], fu_cv_sys_stat_statvfs64,
[AC_TRY_RUN([
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
#include <sys/types.h>
#include <sys/statvfs.h>
main ()
{
struct statvfs64 fsd;
- exit (statvfs64 (".", &fsd));
+ exit (statfs64 (".", &fsd));
}],
fu_cv_sys_stat_statvfs64=yes,
fu_cv_sys_stat_statvfs64=no,
@@ -1670,31 +1537,6 @@ if test $space = no; then
fi
fi
-#
-# As a gating factor for large file support, in order to
-# use <4GB files we must have the following minimal support
-# available.
-# long long, and a 64 bit off_t or off64_t.
-# If we don't have all of these then disable large
-# file support.
-#
-echo "checking if large file support can be enabled"
-AC_TRY_COMPILE([
-#if defined(HAVE_LONGLONG) && (defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8)))
-#include <sys/types.h>
-#else
-__COMPILE_ERROR_
-#endif
-],
-[int i],
-samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=yes,samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=no)
-if test x"$samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT" = x"yes"; then
- echo "yes"
- AC_DEFINE(HAVE_EXPLICIT_LARGEFILE_SUPPORT)
-else
- echo "no"
-fi
-
echo "checking configure summary"
AC_TRY_RUN([#include "${srcdir-.}/tests/summary.c"],
echo "configure OK";,
diff --git a/source/configure.nodebug.developer b/source/configure.nodebug.developer
new file mode 100755
index 00000000000..65e21b4bdf4
--- /dev/null
+++ b/source/configure.nodebug.developer
@@ -0,0 +1,3 @@
+#!/bin/sh
+CFLAGS="-Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -DDEBUG_PASSWORD"; export CFLAGS
+./configure $*
diff --git a/source/groupdb/.cvsignore b/source/groupdb/.cvsignore
new file mode 100644
index 00000000000..af9d6be961b
--- /dev/null
+++ b/source/groupdb/.cvsignore
@@ -0,0 +1 @@
+*.lo \ No newline at end of file
diff --git a/source/groupdb/aliasdb.c b/source/groupdb/aliasdb.c
index e5e6ebfa53f..2dce670994e 100644
--- a/source/groupdb/aliasdb.c
+++ b/source/groupdb/aliasdb.c
@@ -22,17 +22,16 @@
#include "includes.h"
#include "nterr.h"
+#include "sids.h"
extern int DEBUGLEVEL;
-extern fstring global_sam_name;
-
/*
* NOTE. All these functions are abstracted into a structure
* that points to the correct function for the selected database. JRA.
*/
-static struct aliasdb_ops *aldb_ops;
+static struct aliasdb_ops *aldb_ops = NULL;
/***************************************************************
Initialise the alias db operations.
@@ -47,10 +46,12 @@ BOOL initialise_alias_db(void)
#ifdef WITH_NISPLUS
aldb_ops = nisplus_initialise_alias_db();
+#elif defined(WITH_NT5LDAP)
+ aldb_ops = nt5ldap_initialise_alias_db();
#elif defined(WITH_LDAP)
aldb_ops = ldap_initialise_alias_db();
-#else
- aldb_ops = file_initialise_alias_db();
+#elif defined(USE_SMBUNIX_DB)
+ aldb_ops = unix_initialise_alias_db();
#endif
return (aldb_ops != NULL);
@@ -67,7 +68,28 @@ BOOL initialise_alias_db(void)
*************************************************************************/
LOCAL_GRP *iterate_getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem)
{
- return iterate_getaliasrid(pwdb_gid_to_alias_rid(gid), mem, num_mem);
+ DOM_NAME_MAP gmep;
+ uint32 rid;
+ if (!lookupsmbgrpgid(gid, &gmep))
+ {
+ DEBUG(0,("iterate_getaliasgid: gid %d does not map to one of our Domain's Aliases\n", gid));
+ return NULL;
+ }
+
+ if (gmep.type != SID_NAME_ALIAS )
+ {
+ DEBUG(0,("iterate_getaliasgid: gid %d does not map to one of our Domain's Aliases\n", gid));
+ return NULL;
+ }
+
+ sid_split_rid(&gmep.sid, &rid);
+ if (!sid_equal(&gmep.sid, &global_sam_sid))
+ {
+ DEBUG(0,("iterate_getaliasgid: gid %d does not map into our Domain SID\n", gid));
+ return NULL;
+ }
+
+ return iterate_getaliasrid(rid, mem, num_mem);
}
/************************************************************************
@@ -92,6 +114,7 @@ LOCAL_GRP *iterate_getaliasrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem)
while ((als = getaliasent(fp, mem, num_mem)) != NULL && als->rid != rid)
{
+ DEBUG(10,("iterate: %s 0x%x", als->name, als->rid));
}
if (als != NULL)
@@ -107,7 +130,7 @@ LOCAL_GRP *iterate_getaliasrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem)
Utility function to search alias database by name. use this if your database
does not have search facilities.
*************************************************************************/
-LOCAL_GRP *iterate_getaliasnam(char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
+LOCAL_GRP *iterate_getaliasntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
{
LOCAL_GRP *als = NULL;
void *fp = NULL;
@@ -166,11 +189,11 @@ BOOL add_domain_alias(LOCAL_GRP **alss, int *num_alss, LOCAL_GRP *als)
/*************************************************************************
checks to see if a user is a member of a domain alias
*************************************************************************/
-static BOOL user_is_member(char *user_name, LOCAL_GRP_MEMBER *mem, int num_mem)
+static BOOL user_is_member(const char *user_name, LOCAL_GRP_MEMBER *mem, int num_mem)
{
int i;
pstring name;
- slprintf(name, sizeof(name)-1, "\\%s\\%s", global_sam_name, user_name);
+ slprintf(name, sizeof(name)-1, "%s\\%s", global_sam_name, user_name);
for (i = 0; i < num_mem; i++)
{
@@ -189,16 +212,16 @@ static BOOL user_is_member(char *user_name, LOCAL_GRP_MEMBER *mem, int num_mem)
gets an array of aliases that a user is in. use this if your database
does not have search facilities
*************************************************************************/
-BOOL iterate_getuseraliasnam(char *user_name, LOCAL_GRP **alss, int *num_alss)
+BOOL iterate_getuseraliasntnam(const char *user_name, LOCAL_GRP **alss, int *num_alss)
{
- LOCAL_GRP *als;
+ LOCAL_GRP *als = NULL;
LOCAL_GRP_MEMBER *mem = NULL;
int num_mem = 0;
void *fp = NULL;
DEBUG(10, ("search for useralias by name: %s\n", user_name));
- if (user_name == NULL || als == NULL || num_alss == NULL)
+ if (user_name == NULL || alss == NULL || num_alss == NULL)
{
return False;
}
@@ -254,12 +277,12 @@ BOOL iterate_getuseraliasnam(char *user_name, LOCAL_GRP **alss, int *num_alss)
*************************************************************************/
BOOL enumdomaliases(LOCAL_GRP **alss, int *num_alss)
{
- LOCAL_GRP *als;
+ LOCAL_GRP *als = NULL;
void *fp = NULL;
DEBUG(10, ("enum user aliases\n"));
- if (als == NULL || num_alss == NULL)
+ if (alss == NULL || num_alss == NULL)
{
return False;
}
@@ -325,11 +348,25 @@ LOCAL_GRP *getaliasent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem)
/************************************************************************
Routine to add an entry to the alias database file.
+ on entry, the entry is added by name.
+ on exit, the RID is expected to have been set.
*************************************************************************/
-
-BOOL add_alias_entry(LOCAL_GRP *newals)
+BOOL add_alias_entry(LOCAL_GRP *newgrp)
{
- return aldb_ops->add_alias_entry(newals);
+ BOOL ret;
+ if (newgrp->rid != 0xffffffff)
+{
+ DEBUG(0,("add_alias_entry - RID must be 0xffffffff, \
+database instance is responsible for allocating the RID, not you.\n"));
+ return False;
+ }
+ ret = aldb_ops->add_alias_entry(newgrp);
+ if (newgrp->rid == 0xffffffff)
+ {
+ DEBUG(0,("add_alias_entry - RID has not been set by database\n"));
+ return False;
+ }
+ return ret;
}
/************************************************************************
@@ -343,12 +380,35 @@ BOOL mod_alias_entry(LOCAL_GRP* als)
}
/************************************************************************
+ Routine to delete alias database entry matching by rid.
+************************************************************************/
+BOOL del_alias_entry(uint32 rid)
+{
+ return aldb_ops->del_alias_entry(rid);
+}
+
+/************************************************************************
+ Routine to add a member to an entry in the alias database file.
+*************************************************************************/
+BOOL add_alias_member(uint32 rid, const DOM_SID *member_sid)
+{
+ return aldb_ops->add_alias_member(rid, member_sid);
+}
+
+/************************************************************************
+ Routine to delete a member from an entry in the alias database file.
+*************************************************************************/
+BOOL del_alias_member(uint32 rid, const DOM_SID *member_sid)
+{
+ return aldb_ops->del_alias_member(rid, member_sid);
+}
+/************************************************************************
Routine to search alias database by name.
*************************************************************************/
-LOCAL_GRP *getaliasnam(char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
+LOCAL_GRP *getaliasntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
{
- return aldb_ops->getaliasnam(name, mem, num_mem);
+ return aldb_ops->getaliasntnam(name, mem, num_mem);
}
/************************************************************************
@@ -372,18 +432,65 @@ LOCAL_GRP *getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem)
/*************************************************************************
gets an array of aliases that a user is in.
*************************************************************************/
-BOOL getuseraliasnam(char *user_name, LOCAL_GRP **als, int *num_alss)
+BOOL getuseraliasntnam(const char *user_name, LOCAL_GRP **als, int *num_alss)
{
- return aldb_ops->getuseraliasnam(user_name, als, num_alss);
+ return aldb_ops->getuseraliasntnam(user_name, als, num_alss);
}
/*************************************************************
initialises a LOCAL_GRP.
**************************************************************/
-
void aldb_init_als(LOCAL_GRP *als)
{
if (als == NULL) return;
ZERO_STRUCTP(als);
}
+/*************************************************************
+ turns an alias entry into a string.
+ **************************************************************/
+BOOL make_alias_line(char *p, int max_len,
+ LOCAL_GRP *als,
+ LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ int i;
+ int len;
+ len = slprintf(p, max_len-1, "%s:%s:%d:", als->name, als->comment, als->rid);
+
+ if (len == -1)
+ {
+ DEBUG(0,("make_alias_line: cannot create entry\n"));
+ return False;
+ }
+
+ p += len;
+ max_len -= len;
+
+ if (mem == NULL || num_mem == NULL)
+ {
+ return True;
+ }
+
+ for (i = 0; i < (*num_mem); i++)
+ {
+ len = strlen((*mem)[i].name);
+ p = safe_strcpy(p, (*mem)[i].name, max_len);
+
+ if (p == NULL)
+ {
+ DEBUG(0, ("make_alias_line: out of space for aliases!\n"));
+ return False;
+ }
+
+ max_len -= len;
+
+ if (i != (*num_mem)-1)
+ {
+ *p = ',';
+ p++;
+ max_len--;
+ }
+ }
+
+ return True;
+}
diff --git a/source/groupdb/aliasfile.c b/source/groupdb/aliasfile.c
index 4b8bbe3079f..c09d6cc23ed 100644
--- a/source/groupdb/aliasfile.c
+++ b/source/groupdb/aliasfile.c
@@ -19,7 +19,7 @@
#include "includes.h"
-#ifdef USE_SMBPASS_DB
+#ifdef USE_SMBGROUP_DB
static int al_file_lock_depth = 0;
extern int DEBUGLEVEL;
@@ -33,7 +33,7 @@ static char s_readbuf[1024];
static void *startalsfilepwent(BOOL update)
{
- return startfilepwent(lp_smb_alias_file(),
+ return startfileent(lp_smb_alias_file(),
s_readbuf, sizeof(s_readbuf),
&al_file_lock_depth, update);
}
@@ -44,7 +44,7 @@ static void *startalsfilepwent(BOOL update)
static void endalsfilepwent(void *vp)
{
- endfilepwent(vp, &al_file_lock_depth);
+ endfileent(vp, &al_file_lock_depth);
}
/*************************************************************************
@@ -65,51 +65,6 @@ static BOOL setalsfilepwpos(void *vp, SMB_BIG_UINT tok)
return setfilepwpos(vp, tok);
}
-static BOOL make_alias_line(char *p, int max_len,
- LOCAL_GRP *als,
- LOCAL_GRP_MEMBER **mem, int *num_mem)
-{
- int i;
- int len;
- len = slprintf(p, max_len-1, "%s:%s:%d:", als->name, als->comment, als->rid);
-
- if (len == -1)
- {
- DEBUG(0,("make_alias_line: cannot create entry\n"));
- return False;
- }
-
- p += len;
- max_len -= len;
-
- if (mem == NULL || num_mem == NULL)
- {
- return True;
- }
-
- for (i = 0; i < (*num_mem); i++)
- {
- len = strlen((*mem)[i].name);
- p = safe_strcpy(p, (*mem)[i].name, max_len);
-
- if (p == NULL)
- {
- DEBUG(0, ("make_alias_line: out of space for aliases!\n"));
- return False;
- }
-
- max_len -= len;
-
- if (i != (*num_mem)-1)
- {
- *p = ',';
- p++;
- max_len--;
- }
- }
-
- return True;
-}
/*************************************************************************
Routine to return the next entry in the smbdomainalias list.
@@ -130,24 +85,36 @@ static char *get_alias_members(char *p, int *num_mem, LOCAL_GRP_MEMBER **members
{
DOM_SID sid;
uint8 type;
+ BOOL found = False;
- if (lookup_sid(name, &sid, &type))
+ if (strnequal(name, "S-", 2))
{
- (*members) = Realloc((*members), ((*num_mem)+1) * sizeof(LOCAL_GRP_MEMBER));
- (*num_mem)++;
+ /* sid entered directly */
+ string_to_sid(&sid, name);
+ found = lookup_sid(&sid, name, &type) == 0x0;
}
else
{
+ found = lookup_name(name, &sid, &type) == 0x0;
+ }
+
+ if (!found)
+ {
DEBUG(0,("alias database: could not resolve alias named %s\n", name));
continue;
}
+
+ (*members) = Realloc((*members), ((*num_mem)+1) * sizeof(LOCAL_GRP_MEMBER));
+
if ((*members) == NULL)
{
return NULL;
}
- fstrcpy((*members)[(*num_mem)-1].name, name);
- (*members)[(*num_mem)-1].sid_use = type;
- sid_copy(&(*members)[(*num_mem)-1].sid, &sid);
+
+ fstrcpy((*members)[*num_mem].name, name);
+ (*members)[*num_mem].sid_use = type;
+ sid_copy(&(*members)[*num_mem].sid, &sid);
+ (*num_mem)++;
}
return p;
}
@@ -164,15 +131,17 @@ static LOCAL_GRP *getalsfilepwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
pstring linebuf;
char *p;
- size_t linebuf_len;
+ uint8 type;
aldb_init_als(&al_buf);
/*
* Scan the file, a line at a time and check if the name matches.
*/
- while ((linebuf_len = getfileline(vp, linebuf, sizeof(linebuf))) > 0)
+ while (getfileline(vp, linebuf, sizeof(linebuf)) > 0)
{
+ DOM_NAME_MAP gmep;
+
/* get alias name */
p = strncpyn(al_buf.name, linebuf, sizeof(al_buf.name), ':');
@@ -224,9 +193,25 @@ static LOCAL_GRP *getalsfilepwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem
}
}
- /* ok, set up the static data structure and return it */
+ /*
+ * look up the gid, turn it into a rid. the _correct_ type of rid */
+ */
- al_buf.rid = pwdb_gid_to_alias_rid((gid_t)gidval);
+ if (!lookupsmbgrpgid((gid_t)gidval, &gmep))
+ {
+ continue;
+ }
+ if (gmep.type != SID_NAME_DOM_GRP &&
+ gmep.type != SID_NAME_WKN_GRP))
+ {
+ continue;
+ }
+
+ sid_split_rid(&gmep.sid, &gp_buf.rid);
+ if (!sid_equal(&gmep.sid, &global_sam_sid))
+ {
+ continue;
+ }
make_alias_line(linebuf, sizeof(linebuf), &al_buf, mem, num_mem);
DEBUG(10,("line: '%s'\n", linebuf));
@@ -250,11 +235,7 @@ static BOOL add_alsfileals_entry(LOCAL_GRP *newals)
/************************************************************************
Routine to search the aliasdb file for an entry matching the aliasname.
- and then modify its alias entry. We can't use the startalspwent()/
- getalspwent()/endalspwent() interfaces here as we depend on looking
- in the actual file to decide how much room we have to write data.
- override = False, normal
- override = True, override XXXXXXXX'd out alias or NO PASS
+ and then modify its alias entry.
************************************************************************/
static BOOL mod_alsfileals_entry(LOCAL_GRP* als)
@@ -271,7 +252,7 @@ static struct aliasdb_ops file_ops =
getalsfilepwpos,
setalsfilepwpos,
- iterate_getaliasnam, /* In aliasdb.c */
+ iterate_getaliasntnam, /* In aliasdb.c */
iterate_getaliasgid, /* In aliasdb.c */
iterate_getaliasrid, /* In aliasdb.c */
getalsfilepwent,
@@ -279,7 +260,7 @@ static struct aliasdb_ops file_ops =
add_alsfileals_entry,
mod_alsfileals_entry,
- iterate_getuseraliasnam /* in aliasdb.c */
+ iterate_getuseraliasntnam /* in aliasdb.c */
};
struct aliasdb_ops *file_initialise_alias_db(void)
diff --git a/source/groupdb/aliasldap.c b/source/groupdb/aliasldap.c
new file mode 100644
index 00000000000..1e9a72a9d41
--- /dev/null
+++ b/source/groupdb/aliasldap.c
@@ -0,0 +1,425 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP local group database for SAMBA
+ Copyright (C) Matthew Chapman 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+
+#ifdef WITH_LDAP
+
+#include <lber.h>
+#include <ldap.h>
+
+extern int DEBUGLEVEL;
+
+/* Internal state */
+extern LDAP *ldap_struct;
+extern LDAPMessage *ldap_results;
+extern LDAPMessage *ldap_entry;
+
+/* Static structure filled for requests */
+static LOCAL_GRP localgrp;
+
+
+/***************************************************************
+ Get group and membership information.
+ ****************************************************************/
+
+static LOCAL_GRP *ldapalias_getgrp(LOCAL_GRP *group,
+ LOCAL_GRP_MEMBER **members, int *num_membs)
+{
+ fstring temp;
+ char **values;
+ LOCAL_GRP_MEMBER *memblist;
+ char *value, *sep;
+ int i;
+
+ if(!ldap_entry)
+ return NULL;
+
+ if(!ldap_get_attribute("cn", group->name)) {
+ DEBUG(0, ("Missing cn\n"));
+ return NULL; }
+
+ DEBUG(2,("Retrieving alias [%s]\n", group->name));
+
+ if(ldap_get_attribute("rid", temp)) {
+ group->rid = strtol(temp, NULL, 16);
+ } else {
+ DEBUG(0, ("Missing rid\n"));
+ return NULL;
+ }
+
+ if(!ldap_get_attribute("description", group->comment))
+ group->comment[0] = 0;
+
+ if(!members || !num_membs) {
+ ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
+ return group;
+ }
+
+ if(values = ldap_get_values(ldap_struct, ldap_entry, "member")) {
+
+ *num_membs = i = ldap_count_values(values);
+ *members = memblist = malloc(i * sizeof(LOCAL_GRP_MEMBER));
+
+ do {
+ value = values[--i];
+
+ if(!(sep = strchr(value, ','))) {
+ DEBUG(0, ("Malformed alias member\n"));
+ return NULL;
+ }
+ *(sep++) = 0;
+ fstrcpy(memblist[i].name, value);
+
+ if(!(value = strchr(sep, ','))) {
+ DEBUG(0, ("Malformed alias member\n"));
+ return NULL;
+ }
+ *(value++) = 0;
+ string_to_sid(&memblist[i].sid, sep);
+
+ if((memblist[i].sid_use = atoi(value))
+ >= SID_NAME_UNKNOWN)
+ DEBUG(0, ("Invalid SID use in alias"));
+
+ } while(i > 0);
+
+ ldap_value_free(values);
+
+ } else {
+ *num_membs = 0;
+ *members = NULL;
+ }
+
+ return group;
+}
+
+
+/************************************************************************
+ Queues the necessary modifications to save a LOCAL_GRP structure
+ ************************************************************************/
+
+static void ldapalias_grpmods(LOCAL_GRP *group, LDAPMod ***mods, int operation)
+{
+ fstring temp;
+
+ *mods = NULL;
+
+ if(operation == LDAP_MOD_ADD) { /* immutable attributes */
+ ldap_make_mod(mods, LDAP_MOD_ADD, "objectClass", "sambaAlias");
+ ldap_make_mod(mods, LDAP_MOD_ADD, "cn", group->name);
+
+ slprintf(temp, sizeof(temp)-1, "%x", group->rid);
+ ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp);
+ }
+
+ ldap_make_mod(mods, operation, "description", group->comment);
+}
+
+
+/************************************************************************
+ Create a alias member entry
+ ************************************************************************/
+
+static BOOL ldapalias_memmods(DOM_SID *user_sid, LDAPMod ***mods,
+ int operation)
+{
+ pstring member;
+ pstring sid_str;
+ fstring name;
+ uint8 type;
+
+ if (lookup_sid(user_sid, name, &type))
+ return (False);
+ sid_to_string(sid_str, user_sid);
+
+ slprintf(member, sizeof(member)-1, "%s,%s,%d", name, sid_str, type);
+
+ *mods = NULL;
+ ldap_make_mod(mods, operation, "member", member);
+ return True;
+}
+
+
+/***************************************************************
+ Begin/end smbgrp enumeration.
+ ****************************************************************/
+
+static void *ldapalias_enumfirst(BOOL update)
+{
+ if (lp_server_role() == ROLE_DOMAIN_NONE)
+ return NULL;
+
+ if (!ldap_connect())
+ return NULL;
+
+ ldap_search_for("objectClass=sambaAlias");
+
+ return ldap_struct;
+}
+
+static void ldapalias_enumclose(void *vp)
+{
+ ldap_disconnect();
+}
+
+
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
+
+static SMB_BIG_UINT ldapalias_getdbpos(void *vp)
+{
+ return (SMB_BIG_UINT)((ulong)ldap_entry);
+}
+
+static BOOL ldapalias_setdbpos(void *vp, SMB_BIG_UINT tok)
+{
+ ldap_entry = (LDAPMessage *)((ulong)tok);
+ return (True);
+}
+
+
+/*************************************************************************
+ Return limited smb_passwd information, and group membership.
+ *************************************************************************/
+
+static LOCAL_GRP *ldapalias_getgrpbynam(const char *name,
+ LOCAL_GRP_MEMBER **members, int *num_membs)
+{
+ fstring filter;
+ LOCAL_GRP *ret;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(cn=%s)(objectClass=sambaAlias))", name);
+ ldap_search_for(filter);
+
+ ret = ldapalias_getgrp(&localgrp, members, num_membs);
+
+ ldap_disconnect();
+ return ret;
+}
+
+static LOCAL_GRP *ldapalias_getgrpbygid(gid_t grp_id,
+ LOCAL_GRP_MEMBER **members, int *num_membs)
+{
+ fstring filter;
+ LOCAL_GRP *ret;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(gidNumber=%d)(objectClass=sambaAlias))", grp_id);
+ ldap_search_for(filter);
+ ret = ldapalias_getgrp(&localgrp, members, num_membs);
+
+ ldap_disconnect();
+ return ret;
+}
+
+static LOCAL_GRP *ldapalias_getgrpbyrid(uint32 grp_rid,
+ LOCAL_GRP_MEMBER **members, int *num_membs)
+{
+ fstring filter;
+ LOCAL_GRP *ret;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(rid=%x)(objectClass=sambaAlias))", grp_rid);
+ ldap_search_for(filter);
+ ret = ldapalias_getgrp(&localgrp, members, num_membs);
+
+ ldap_disconnect();
+ return ret;
+}
+
+static LOCAL_GRP *ldapalias_getcurrentgrp(void *vp,
+ LOCAL_GRP_MEMBER **members, int *num_membs)
+{
+ return ldapalias_getgrp(&localgrp, members, num_membs);
+}
+
+
+/*************************************************************************
+ Add/modify/delete aliases.
+ *************************************************************************/
+
+static BOOL ldapalias_addgrp(LOCAL_GRP *group)
+{
+ LDAPMod **mods;
+
+ if (!ldap_allocaterid(&group->rid))
+ {
+ DEBUG(0,("RID generation failed\n"));
+ return (False);
+ }
+
+ ldapalias_grpmods(group, &mods, LDAP_MOD_ADD);
+ return ldap_makemods("cn", group->name, mods, True);
+}
+
+static BOOL ldapalias_modgrp(LOCAL_GRP *group)
+{
+ LDAPMod **mods;
+
+ ldapalias_grpmods(group, &mods, LDAP_MOD_REPLACE);
+ return ldap_makemods("cn", group->name, mods, False);
+}
+
+static BOOL ldapalias_delgrp(uint32 grp_rid)
+{
+ fstring filter;
+ char *dn;
+ int err;
+
+ if (!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(rid=%x)(objectClass=sambaAlias))", grp_rid);
+ ldap_search_for(filter);
+
+ if (!ldap_entry || !(dn = ldap_get_dn(ldap_struct, ldap_entry)))
+ {
+ ldap_disconnect();
+ return (False);
+ }
+
+ err = ldap_delete_s(ldap_struct, dn);
+ free(dn);
+ ldap_disconnect();
+
+ if (err != LDAP_SUCCESS)
+ {
+ DEBUG(0, ("delete: %s\n", ldap_err2string(err)));
+ return (False);
+ }
+
+ return True;
+}
+
+
+/*************************************************************************
+ Add users to/remove users from aliases.
+ *************************************************************************/
+
+static BOOL ldapalias_addmem(uint32 grp_rid, DOM_SID *user_sid)
+{
+ LDAPMod **mods;
+ fstring rid_str;
+
+ slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid);
+
+ if(!ldapalias_memmods(user_sid, &mods, LDAP_MOD_ADD))
+ return (False);
+
+ return ldap_makemods("rid", rid_str, mods, False);
+}
+
+static BOOL ldapalias_delmem(uint32 grp_rid, DOM_SID *user_sid)
+{
+ LDAPMod **mods;
+ fstring rid_str;
+
+ slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid);
+
+ if(!ldapalias_memmods(user_sid, &mods, LDAP_MOD_DELETE))
+ return (False);
+
+ return ldap_makemods("rid", rid_str, mods, False);
+}
+
+
+/*************************************************************************
+ Return aliases that a user is in.
+ *************************************************************************/
+
+static BOOL ldapalias_getusergroups(const char *name, LOCAL_GRP **groups,
+ int *num_grps)
+{
+ LOCAL_GRP *grouplist;
+ fstring filter;
+ int i;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(pstring)-1,
+ "(&(member=%s,*)(objectclass=sambaAlias))", name);
+ ldap_search_for(filter);
+
+ *num_grps = i = ldap_count_entries(ldap_struct, ldap_results);
+
+ if(!i) {
+ *groups = NULL;
+ ldap_disconnect();
+ return (True);
+ }
+
+ *groups = grouplist = malloc(i * sizeof(LOCAL_GRP));
+ do {
+ i--;
+ } while(ldapalias_getgrp(&grouplist[i], NULL, NULL) && (i > 0));
+
+ ldap_disconnect();
+ return (True);
+}
+
+
+static struct aliasdb_ops ldapalias_ops =
+{
+ ldapalias_enumfirst,
+ ldapalias_enumclose,
+ ldapalias_getdbpos,
+ ldapalias_setdbpos,
+
+ ldapalias_getgrpbynam,
+ ldapalias_getgrpbygid,
+ ldapalias_getgrpbyrid,
+ ldapalias_getcurrentgrp,
+
+ ldapalias_addgrp,
+ ldapalias_modgrp,
+ ldapalias_delgrp,
+
+ ldapalias_addmem,
+ ldapalias_delmem,
+
+ ldapalias_getusergroups
+};
+
+struct aliasdb_ops *ldap_initialise_alias_db(void)
+{
+ return &ldapalias_ops;
+}
+
+#else
+ void aliasldap_dummy_function(void);
+ void aliasldap_dummy_function(void) { } /* stop some compilers complaining */
+#endif
+
diff --git a/source/groupdb/aliasnt5ldap.c b/source/groupdb/aliasnt5ldap.c
new file mode 100644
index 00000000000..4f01d829120
--- /dev/null
+++ b/source/groupdb/aliasnt5ldap.c
@@ -0,0 +1,476 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP local group database for SAMBA
+ Copyright (C) Matthew Chapman 1998
+ Copyright (C) Luke Howard 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include "includes.h"
+
+#ifdef WITH_NT5LDAP
+
+#include <lber.h>
+#include <ldap.h>
+#include "ldapdb.h"
+
+extern int DEBUGLEVEL;
+
+/* Static structure filled for requests */
+static LOCAL_GRP localgrp;
+
+/***************************************************************
+ Begin/end smbgrp enumeration.
+ ****************************************************************/
+
+static void *
+nt5ldapalias_enumfirst (BOOL update)
+{
+ LDAPDB_DECLARE_HANDLE (hds);
+ fstring filter;
+
+ if (lp_server_role () == ROLE_DOMAIN_NONE)
+ return NULL;
+
+ if (!ldapdb_open (&hds))
+ return NULL;
+
+ slprintf (filter, sizeof (filter) - 1, "(&(objectClass=Group)(groupType=%d))",
+ NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, LDAP_NO_LIMIT))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ return hds;
+}
+
+static void
+nt5ldapalias_enumclose (void *vp)
+{
+ LDAPDB *hds = (LDAPDB *) vp;
+
+ ldapdb_close (&hds);
+}
+
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
+
+static SMB_BIG_UINT
+nt5ldapalias_getdbpos (void *vp)
+{
+ return 0;
+}
+
+static BOOL
+nt5ldapalias_setdbpos (void *vp, SMB_BIG_UINT tok)
+{
+ return False;
+}
+
+
+/*************************************************************************
+ Return limited smb_passwd information, and group membership.
+ *************************************************************************/
+
+static LOCAL_GRP *
+nt5ldapalias_getgrpbynam (const char *name,
+ LOCAL_GRP_MEMBER ** members, int *num_membs)
+{
+ fstring filter;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ return (NULL);
+
+ slprintf (filter, sizeof (filter) - 1,
+ "(&(objectClass=Group)(sAMAccountName=%s)(groupType=%d))", name,
+ NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, 1))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldap_make_local_grp (hds, &localgrp, members, num_membs, 0);
+
+ ldapdb_close (&hds);
+
+ return ret ? &localgrp : NULL;
+}
+
+static LOCAL_GRP *
+nt5ldapalias_getgrpbygid (gid_t grp_id,
+ LOCAL_GRP_MEMBER ** members, int *num_membs)
+{
+ fstring filter;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ return (NULL);
+
+ slprintf (filter, sizeof (filter) - 1,
+ "(&(objectClass=Group)(gidNumber=%d)(groupType=%d))", grp_id,
+ NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, 1))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldap_make_local_grp (hds, &localgrp, members, num_membs, 0);
+
+ ldapdb_close (&hds);
+
+ return ret ? &localgrp : NULL;
+}
+
+static LOCAL_GRP *
+nt5ldapalias_getgrpbyrid (uint32 grp_rid,
+ LOCAL_GRP_MEMBER ** members, int *num_membs)
+{
+ fstring filter;
+ fstring sidfilter;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_make_rid_filter ("objectSid", grp_rid, sidfilter))
+ {
+ return NULL;
+ }
+
+ slprintf (filter, sizeof (filter) - 1,
+ "(&(objectClass=Group)(%s)(groupType=%d))", sidfilter,
+ NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, 1))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldap_make_local_grp (hds, &localgrp, members, num_membs, 0);
+
+ ldapdb_close (&hds);
+
+ return ret ? &localgrp : NULL;
+}
+
+static LOCAL_GRP *
+nt5ldapalias_getcurrentgrp (void *vp,
+ LOCAL_GRP_MEMBER ** members, int *num_membs)
+{
+ BOOL ret = False;
+
+ do
+ {
+ if ((ret = nt5ldap_make_local_grp ((LDAPDB *)vp, &localgrp, members, num_membs, 0)) == True)
+ break;
+ }
+ while (ldapdb_seq((LDAPDB *)vp) == True);
+
+ return ret ? &localgrp : NULL;
+}
+
+
+/*************************************************************************
+ Add/modify/delete aliases.
+ *************************************************************************/
+
+static BOOL
+nt5ldapalias_addgrp (LOCAL_GRP * group)
+{
+ LDAPMod **mods = NULL;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_allocate_rid (hds, &group->rid))
+ {
+ DEBUG (0, ("RID generation failed\n"));
+ return False;
+ }
+
+ if (!nt5ldap_local_grp_mods (group, &mods, LDAP_MOD_ADD, 0))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_update (hds, lp_ldap_builtin_subcontext (), "cn", group->name, mods, True);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapalias_modgrp (LOCAL_GRP * group)
+{
+ LDAPMod **mods = NULL;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!nt5ldap_local_grp_mods (group, &mods, LDAP_MOD_REPLACE, 0))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_update (hds, lp_ldap_builtin_subcontext (), "cn", group->name, mods, False);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapalias_delgrp (uint32 grp_rid)
+{
+ pstring dn;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_rid_to_dn (hds, grp_rid, dn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ ret = ldapdb_delete (hds, dn);
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+
+/*************************************************************************
+ Add users to/remove users from aliases.
+ *************************************************************************/
+
+static BOOL
+nt5ldapalias_addmem (uint32 grp_rid, const DOM_SID * user_sid)
+{
+ LDAPMod **mods = NULL;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+ pstring userdn, groupdn;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_rid_to_dn (hds, grp_rid, groupdn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!nt5ldap_local_grp_member_mods (user_sid, &mods, LDAP_MOD_ADD, userdn))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_commit (hds, groupdn, mods, False);
+ }
+
+ if (ret == True)
+ {
+ mods = NULL;
+ ret = ldapdb_queue_mod (&mods, LDAP_MOD_ADD, "memberOf", groupdn) &&
+ ldapdb_commit (hds, userdn, mods, False);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapalias_delmem (uint32 grp_rid, const DOM_SID * user_sid)
+{
+ LDAPMod **mods = NULL;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+ pstring userdn, groupdn;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_rid_to_dn (hds, grp_rid, groupdn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!nt5ldap_local_grp_member_mods (user_sid, &mods, LDAP_MOD_DELETE, userdn))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_commit (hds, groupdn, mods, False);
+ }
+
+ if (ret == True)
+ {
+ mods = NULL;
+ ret = ldapdb_queue_mod (&mods, LDAP_MOD_DELETE, "memberOf", groupdn) &&
+ ldapdb_commit (hds, userdn, mods, False);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+
+/*************************************************************************
+ Return aliases that a user is in.
+ *************************************************************************/
+
+static BOOL
+nt5ldapalias_getusergroups (const char *name, LOCAL_GRP ** groups,
+ int *num_grps)
+{
+ LOCAL_GRP *grouplist;
+ fstring filter;
+ int i, ngroups;
+ pstring dn;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_ntname_to_dn (hds, name, dn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ slprintf (filter, sizeof (pstring) - 1, "(&(objectClass=Group)(member=%s)(groupType=%d))", dn,
+ NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+
+ (void) ldapdb_set_synchronous (hds, True);
+ if (!ldapdb_search (hds, NULL, filter, NULL, LDAP_NO_LIMIT))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!ldapdb_count_entries (hds, &ngroups))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ grouplist = calloc (ngroups, sizeof (LOCAL_GRP));
+ if (grouplist == NULL)
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ *num_grps = 0;
+
+ for (i = 0; i < ngroups; i++)
+ {
+ if (nt5ldap_make_local_grp (hds, &grouplist[*num_grps], NULL, NULL, 0))
+ {
+ (*num_grps)++;
+ }
+ if (!ldapdb_seq (hds))
+ {
+ break;
+ }
+ }
+
+ ldapdb_close (&hds);
+
+ *groups = grouplist;
+
+ return True;
+}
+
+
+static struct aliasdb_ops nt5ldapalias_ops =
+{
+ nt5ldapalias_enumfirst,
+ nt5ldapalias_enumclose,
+ nt5ldapalias_getdbpos,
+ nt5ldapalias_setdbpos,
+
+ nt5ldapalias_getgrpbynam,
+ nt5ldapalias_getgrpbygid,
+ nt5ldapalias_getgrpbyrid,
+ nt5ldapalias_getcurrentgrp,
+
+ nt5ldapalias_addgrp,
+ nt5ldapalias_modgrp,
+ nt5ldapalias_delgrp,
+
+ nt5ldapalias_addmem,
+ nt5ldapalias_delmem,
+
+ nt5ldapalias_getusergroups
+};
+
+struct aliasdb_ops *
+nt5ldap_initialise_alias_db (void)
+{
+ return &nt5ldapalias_ops;
+}
+
+#else
+void aliasnt5ldap_dummy_function (void);
+void
+aliasnt5ldap_dummy_function (void)
+{
+} /* stop some compilers complaining */
+#endif
diff --git a/source/groupdb/aliasunix.c b/source/groupdb/aliasunix.c
new file mode 100644
index 00000000000..bb519ab680f
--- /dev/null
+++ b/source/groupdb/aliasunix.c
@@ -0,0 +1,331 @@
+/*
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "sids.h"
+
+#ifdef USE_SMBUNIX_DB
+
+extern int DEBUGLEVEL;
+
+struct unix_entries
+{
+ struct group *grps;
+ int num_grps;
+ int grp_idx;
+};
+
+/***************************************************************
+ Start to enumerate the alspasswd list. Returns a void pointer
+ to ensure no modification outside this module.
+****************************************************************/
+
+static void *startalsunixpwent(BOOL update)
+{
+ struct unix_entries *grps;
+ grps = (struct unix_entries*)malloc(sizeof(struct unix_entries));
+
+ if (grps == NULL)
+ {
+ return NULL;
+ }
+
+ if (!get_unix_grps(&grps->num_grps, &grps->grps))
+ {
+ free(grps);
+ return NULL;
+ }
+
+ grps->grp_idx = 0;
+
+ return (void*)grps;
+}
+
+/***************************************************************
+ End enumeration of the alspasswd list.
+****************************************************************/
+
+static void endalsunixpwent(void *vp)
+{
+ struct unix_entries *grps = (struct unix_entries *)vp;
+
+ if (grps != NULL)
+ {
+ free_unix_grps(grps->num_grps, grps->grps);
+ free(vp);
+ }
+}
+
+/*************************************************************************
+ Return the current position in the alspasswd list as an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+static SMB_BIG_UINT getalsunixpwpos(void *vp)
+{
+ return (SMB_BIG_UINT)0;
+}
+
+/*************************************************************************
+ Set the current position in the alspasswd list from an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+static BOOL setalsunixpwpos(void *vp, SMB_BIG_UINT tok)
+{
+ return False;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smbdomainalias list.
+ *************************************************************************/
+BOOL get_unixalias_members(struct group *grp,
+ int *num_mem, LOCAL_GRP_MEMBER **members)
+{
+ int i;
+ char *unix_name;
+
+ if (num_mem == NULL || members == NULL)
+ {
+ return False;
+ }
+
+ (*num_mem) = 0;
+ (*members) = NULL;
+
+ for (i = 0; (unix_name = grp->gr_mem[i]) != NULL; i++)
+ {
+ fstring name;
+ DOM_NAME_MAP gmep;
+ LOCAL_GRP_MEMBER *mem;
+
+ fstrcpy(name, unix_name);
+
+ if (!lookupsmbpwnam (name, &gmep) &&
+ !lookupsmbgrpnam(name, &gmep))
+ {
+ continue;
+ }
+
+ if (!sid_front_equal(&global_sam_sid, &gmep.sid))
+ {
+ DEBUG(0,("alias database: could not resolve name %s (wrong Domain SID)\n",
+ name));
+ continue;
+ }
+
+ (*num_mem)++;
+ (*members) = Realloc((*members), (*num_mem) * sizeof(LOCAL_GRP_MEMBER));
+ if ((*members) == NULL)
+ {
+ DEBUG(0,("get_unixalias_members: could not realloc LOCAL_GRP_MEMBERs\n"));
+ return False;
+ }
+
+ mem = &(*members)[(*num_mem)-1];
+ slprintf(mem->name, sizeof(mem->name)-1, "%s\\%s",
+ gmep.nt_domain, gmep.nt_name);
+ sid_copy(&mem->sid, &gmep.sid);
+ mem->sid_use = gmep.type;
+
+ DEBUG(10,("get_unixalias_members: adding alias %s\n",
+ mem->name));
+ }
+ return True;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the domain alias list.
+
+ when we are a PDC or BDC, then unix groups that are explicitly NOT mapped
+ to aliases are treated as DOMAIN groups (see groupunix.c).
+
+ when we are a member of a domain (not a PDC or BDC) then unix groups
+ that are explicitly NOT mapped to aliases (map_alias_gid) are treated
+ as LOCAL groups.
+
+ the reasoning behind this is to make it as simple as possible (not an easy
+ task) for people to set up a domain-aware samba server, in each role that
+ the server can take.
+
+ *************************************************************************/
+static LOCAL_GRP *getalsunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ /* Static buffers we will return. */
+ static LOCAL_GRP gp_buf;
+ struct group unix_grp;
+ struct unix_entries *grps = (struct unix_entries *)vp;
+
+ if (lp_server_role() == ROLE_DOMAIN_NONE)
+ {
+ /*
+ * no domain role, no domain aliases (or domain groups,
+ * but that's dealt with by groupdb...).
+ */
+
+ return NULL;
+ }
+
+ aldb_init_als(&gp_buf);
+
+ /* get array of unix names + gids. this function does NOT
+ get a copy of the unix group members
+ */
+
+ /* cycle through unix groups */
+ for (; grps->grp_idx < grps->num_grps; grps->grp_idx++)
+ {
+ DOM_NAME_MAP gmep;
+ fstring sid_str;
+
+ memcpy(&unix_grp, &grps->grps[grps->grp_idx], sizeof(unix_grp));
+
+ DEBUG(10,("getgrpunixpwent: enum unix group entry %s\n",
+ unix_grp.gr_name));
+
+ if (!lookupsmbgrpgid(unix_grp.gr_gid, &gmep))
+ {
+ continue;
+ }
+
+ sid_to_string(sid_str, &gmep.sid);
+ DEBUG(10,("group %s found, sid %s type %d\n",
+ gmep.nt_name, sid_str, gmep.type));
+
+ if (gmep.type != SID_NAME_ALIAS)
+ {
+ continue;
+ }
+
+ sid_split_rid(&gmep.sid, &gp_buf.rid);
+ if (!sid_equal(&global_sam_sid, &gmep.sid))
+ {
+ continue;
+ }
+
+ fstrcpy(gp_buf.name, gmep.nt_name);
+ break;
+ }
+
+ if (grps->grp_idx >= grps->num_grps)
+ {
+ return NULL;
+ }
+
+ /* get the user's domain aliases. there are a maximum of 32 */
+
+ if (mem != NULL && num_mem != NULL)
+ {
+ (*mem) = NULL;
+ (*num_mem) = 0;
+
+ memcpy(&unix_grp, getgrgid(unix_grp.gr_gid), sizeof(unix_grp));
+ get_unixalias_members(&unix_grp, num_mem, mem);
+ }
+
+ {
+ pstring linebuf;
+ make_alias_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
+ DEBUG(10,("line: '%s'\n", linebuf));
+ }
+
+ grps->grp_idx++; /* advance so next enum gets next entry */
+ return &gp_buf;
+}
+
+/************************************************************************
+ Routine to add an entry to the alspasswd file.
+*************************************************************************/
+
+static BOOL add_alsunixgrp_entry(LOCAL_GRP *newals)
+{
+ DEBUG(0, ("add_alsunixgrp_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to search the alspasswd file for an entry matching the aliasname.
+ and then modify its alias entry.
+************************************************************************/
+
+static BOOL mod_alsunixgrp_entry(LOCAL_GRP* als)
+{
+ DEBUG(0, ("mod_alsunixgrp_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to search the grppasswd file for an entry matching the rid.
+ and then delete it.
+************************************************************************/
+
+static BOOL del_alsunixgrp_entry(uint32 rid)
+{
+ DEBUG(0, ("del_alsunixgrp_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to add a member to an entry to the grppasswd file.
+*************************************************************************/
+static BOOL add_alsunixgrp_member(uint32 rid, DOM_SID *member_sid)
+{
+ DEBUG(0, ("add_alsunixgrp_member: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to delete a member from an entry to the grppasswd file.
+*************************************************************************/
+static BOOL del_alsunixgrp_member(uint32 rid, DOM_SID *member_sid)
+{
+ DEBUG(0, ("del_alsunixgrp_member: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+
+static struct aliasdb_ops unix_ops =
+{
+ startalsunixpwent,
+ endalsunixpwent,
+ getalsunixpwpos,
+ setalsunixpwpos,
+
+ iterate_getaliasntnam, /* In aliasdb.c */
+ iterate_getaliasgid, /* In aliasdb.c */
+ iterate_getaliasrid, /* In aliasdb.c */
+ getalsunixpwent,
+
+ add_alsunixgrp_entry,
+ mod_alsunixgrp_entry,
+ del_alsunixgrp_entry,
+
+ add_alsunixgrp_member,
+ del_alsunixgrp_member,
+
+ iterate_getuseraliasntnam /* in aliasdb.c */
+};
+
+struct aliasdb_ops *unix_initialise_alias_db(void)
+{
+ return &unix_ops;
+}
+
+#else
+ /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
+ void unix_alspass_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* USE_SMBPASS_DB */
diff --git a/source/groupdb/builtindb.c b/source/groupdb/builtindb.c
new file mode 100644
index 00000000000..f6a8ea5dd6a
--- /dev/null
+++ b/source/groupdb/builtindb.c
@@ -0,0 +1,475 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Pasesword and authentication handling
+ Copyright (C) Jeremy Allison 1996-1998
+ Copyright (C) Luke Kenneth Caseson Leighton 1996-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mases Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/*
+ * NOTE. All these functions are abstracted into a structure
+ * that points to the correct function for the selected database. JRA.
+ */
+
+static struct aliasdb_ops *bidb_ops = NULL;
+
+/***************************************************************
+ Initialise the builtin db operations.
+***************************************************************/
+
+BOOL initialise_builtin_db(void)
+{
+ if (bidb_ops)
+ {
+ return True;
+ }
+
+#ifdef WITH_NISPLUS
+ bidb_ops = nisplus_initialise_builtin_db();
+#elif defined(WITH_NT5LDAP)
+ bidb_ops = nt5ldap_initialise_builtin_db();
+#elif defined(WITH_LDAP)
+ bidb_ops = ldap_initialise_builtin_db();
+#elif defined(USE_SMBUNIX_DB)
+ bidb_ops = unix_initialise_builtin_db();
+#endif
+
+ return (bidb_ops != NULL);
+}
+
+/*
+ * Functions that return/manipulate a LOCAL_GRP.
+ */
+
+/************************************************************************
+ Utility function to search builtin database by gid: the LOCAL_GRP
+ structure does not have a gid member, so we have to convert here
+ from gid to builtin rid.
+*************************************************************************/
+LOCAL_GRP *iterate_getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ DOM_NAME_MAP gmep;
+ uint32 rid;
+ if (!lookupsmbgrpgid(gid, &gmep))
+ {
+ DEBUG(0,("iterate_getbuiltingid: gid %d does not map to one of our Domain's Aliases\n", gid));
+ return NULL;
+ }
+
+ if (gmep.type != SID_NAME_ALIAS )
+ {
+ DEBUG(0,("iterate_getbuiltingid: gid %d does not map to one of our Domain's Aliases\n", gid));
+ return NULL;
+ }
+
+ sid_split_rid(&gmep.sid, &rid);
+ if (!sid_equal(&gmep.sid, &global_sam_sid))
+ {
+ DEBUG(0,("iterate_getbuiltingid: gid %d does not map into our Domain SID\n", gid));
+ return NULL;
+ }
+
+ return iterate_getbuiltinrid(rid, mem, num_mem);
+}
+
+/************************************************************************
+ Utility function to search builtin database by rid. use this if your database
+ does not have search facilities.
+*************************************************************************/
+LOCAL_GRP *iterate_getbuiltinrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ LOCAL_GRP *blt = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by rid: 0x%x\n", rid));
+
+ /* Open the builtin database file - not for update. */
+ fp = startbuiltinent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open builtin database.\n"));
+ return NULL;
+ }
+
+ while ((blt = getbuiltinent(fp, mem, num_mem)) != NULL && blt->rid != rid)
+ {
+ DEBUG(10,("iterate: %s 0x%x", blt->name, blt->rid));
+ }
+
+ if (blt != NULL)
+ {
+ DEBUG(10, ("found builtin %s by rid: 0x%x\n", blt->name, rid));
+ }
+
+ endbuiltinent(fp);
+ return blt;
+}
+
+/************************************************************************
+ Utility function to search builtin database by name. use this if your database
+ does not have search facilities.
+*************************************************************************/
+LOCAL_GRP *iterate_getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ LOCAL_GRP *blt = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by name: %s\n", name));
+
+ /* Open the builtin database file - not for update. */
+ fp = startbuiltinent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open builtin database.\n"));
+ return NULL;
+ }
+
+ while ((blt = getbuiltinent(fp, mem, num_mem)) != NULL && !strequal(blt->name, name))
+ {
+ }
+
+ if (blt != NULL)
+ {
+ DEBUG(10, ("found by name: %s\n", name));
+ }
+
+ endbuiltinent(fp);
+ return blt;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smbdomainbuiltin list.
+ *************************************************************************/
+BOOL add_domain_builtin(LOCAL_GRP **blts, int *num_blts, LOCAL_GRP *blt)
+{
+ if (blts == NULL || num_blts == NULL || blt == NULL)
+ {
+ return False;
+ }
+
+ (*blts) = Realloc((*blts), ((*num_blts)+1) * sizeof(LOCAL_GRP));
+ if ((*blts) == NULL)
+ {
+ return False;
+ }
+
+ DEBUG(10,("adding builtin %s(%s)\n", blt->name, blt->comment));
+
+ fstrcpy((*blts)[(*num_blts)].name , blt->name);
+ fstrcpy((*blts)[(*num_blts)].comment, blt->comment);
+ (*blts)[(*num_blts)].rid = blt->rid;
+
+ (*num_blts)++;
+
+ return True;
+}
+
+/*************************************************************************
+ checks to see if a user is a member of a domain builtin
+ *************************************************************************/
+static BOOL user_is_member(const char *user_name, LOCAL_GRP_MEMBER *mem, int num_mem)
+{
+ int i;
+ pstring name;
+ slprintf(name, sizeof(name)-1, "%s\\%s", global_sam_name, user_name);
+
+ for (i = 0; i < num_mem; i++)
+ {
+ DEBUG(10,("searching against user %s...\n", mem[i].name));
+ if (strequal(mem[i].name, name))
+ {
+ DEBUG(10,("searching for user %s: found\n", name));
+ return True;
+ }
+ }
+ DEBUG(10,("searching for user %s: not found\n", name));
+ return False;
+}
+
+/*************************************************************************
+ gets an array of builtin aliases that a user is in. use this if your database
+ does not have search facilities
+ *************************************************************************/
+BOOL iterate_getuserbuiltinntnam(const char *user_name, LOCAL_GRP **blts, int *num_blts)
+{
+ LOCAL_GRP *blt = NULL;
+ LOCAL_GRP_MEMBER *mem = NULL;
+ int num_mem = 0;
+ void *fp = NULL;
+
+ DEBUG(10, ("search for userbuiltin by name: %s\n", user_name));
+
+ if (user_name == NULL || blts == NULL || num_blts == NULL)
+ {
+ return False;
+ }
+
+ (*blts) = NULL;
+ (*num_blts) = 0;
+
+ /* Open the builtin database file - not for update. */
+ fp = startbuiltinent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open builtin database.\n"));
+ return False;
+ }
+
+ /* iterate through all builtin aliases. search members for required user */
+ while ((blt = getbuiltinent(fp, &mem, &num_mem)) != NULL)
+ {
+ DEBUG(5,("builtin name %s members: %d\n", blt->name, num_mem));
+ if (num_mem != 0 && mem != NULL)
+ {
+ BOOL ret = True;
+ if (user_is_member(user_name, mem, num_mem))
+ {
+ ret = add_domain_builtin(blts, num_blts, blt);
+ }
+
+ free(mem);
+ mem = NULL;
+ num_mem = 0;
+
+ if (!ret)
+ {
+ (*num_blts) = 0;
+ break;
+ }
+ }
+ }
+
+ if ((*num_blts) != 0)
+ {
+ DEBUG(10, ("found %d user builtin aliases:\n", (*num_blts)));
+ }
+
+ endbuiltinent(fp);
+ return True;
+}
+
+/*************************************************************************
+ gets an array of builtin aliases that a user is in. use this if your database
+ does not have search facilities
+ *************************************************************************/
+BOOL enumdombuiltins(LOCAL_GRP **blts, int *num_blts)
+{
+ LOCAL_GRP *blt = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("enum user builtin aliases\n"));
+
+ if (blts == NULL || num_blts == NULL)
+ {
+ return False;
+ }
+
+ (*blts) = NULL;
+ (*num_blts) = 0;
+
+ /* Open the builtin database file - not for update. */
+ fp = startbuiltinent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open builtin database.\n"));
+ return False;
+ }
+
+ /* iterate through all builtin aliases. */
+ while ((blt = getbuiltinent(fp, NULL, NULL)) != NULL)
+ {
+ if (!add_domain_builtin(blts, num_blts, blt))
+ {
+ DEBUG(0,("unable to add builtin while enumerating\n"));
+ return False;
+ }
+ }
+
+ if ((*num_blts) != 0)
+ {
+ DEBUG(10, ("found %d user builtin aliases:\n", (*num_blts)));
+ }
+
+ endbuiltinent(fp);
+ return True;
+}
+
+/***************************************************************
+ Start to enumerate the builtin database list. Returns a void pointer
+ to ensure no modification outside this module.
+****************************************************************/
+
+void *startbuiltinent(BOOL update)
+{
+ return bidb_ops->startaliasent(update);
+}
+
+/***************************************************************
+ End enumeration of the builtin database list.
+****************************************************************/
+
+void endbuiltinent(void *vp)
+{
+ bidb_ops->endaliasent(vp);
+}
+
+/*************************************************************************
+ Routine to return the next entry in the builtin database list.
+ *************************************************************************/
+
+LOCAL_GRP *getbuiltinent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ return bidb_ops->getaliasent(vp, mem, num_mem);
+}
+
+/************************************************************************
+ Routine to add an entry to the builtin database file.
+*************************************************************************/
+
+BOOL add_builtin_entry(LOCAL_GRP *newblt)
+{
+ return bidb_ops->add_alias_entry(newblt);
+}
+
+/************************************************************************
+ Routine to search the builtin database file for an entry matching the builtinname.
+ and then replace the entry.
+************************************************************************/
+
+BOOL mod_builtin_entry(LOCAL_GRP* blt)
+{
+ return bidb_ops->mod_alias_entry(blt);
+}
+
+/************************************************************************
+ Routine to add a member to an entry in the builtin database file.
+*************************************************************************/
+BOOL add_builtin_member(uint32 rid, const DOM_SID *member_sid)
+{
+ return bidb_ops->add_alias_member(rid, member_sid);
+}
+
+/************************************************************************
+ Routine to delete a member from an entry in the builtindatabase file.
+*************************************************************************/
+BOOL del_builtin_member(uint32 rid, const DOM_SID *member_sid)
+{
+ return bidb_ops->del_alias_member(rid, member_sid);
+}
+
+/************************************************************************
+ Routine to search builtin database by name.
+*************************************************************************/
+
+LOCAL_GRP *getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ return bidb_ops->getaliasntnam(name, mem, num_mem);
+}
+
+/************************************************************************
+ Routine to search builtin database by builtin rid.
+*************************************************************************/
+
+LOCAL_GRP *getbuiltinrid(uint32 builtin_rid, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ return bidb_ops->getaliasrid(builtin_rid, mem, num_mem);
+}
+
+/************************************************************************
+ Routine to search builtin database by gid.
+*************************************************************************/
+
+LOCAL_GRP *getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ return bidb_ops->getaliasgid(gid, mem, num_mem);
+}
+
+/*************************************************************************
+ gets an array of builtin aliases that a user is in.
+ *************************************************************************/
+BOOL getuserbuiltinntnam(const char *user_name, LOCAL_GRP **blt, int *num_blts)
+{
+ return bidb_ops->getuseraliasntnam(user_name, blt, num_blts);
+}
+
+/*************************************************************
+ initialises a LOCAL_GRP.
+ **************************************************************/
+void bidb_init_blt(LOCAL_GRP *blt)
+{
+ if (blt == NULL) return;
+ ZERO_STRUCTP(blt);
+}
+
+/*************************************************************
+ turns an builtin entry into a string.
+ **************************************************************/
+BOOL make_builtin_line(char *p, int max_len,
+ LOCAL_GRP *blt,
+ LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ int i;
+ int len;
+ len = slprintf(p, max_len-1, "%s:%s:%d:", blt->name, blt->comment, blt->rid);
+
+ if (len == -1)
+ {
+ DEBUG(0,("make_builtin_line: cannot create entry\n"));
+ return False;
+ }
+
+ p += len;
+ max_len -= len;
+
+ if (mem == NULL || num_mem == NULL)
+ {
+ return True;
+ }
+
+ for (i = 0; i < (*num_mem); i++)
+ {
+ len = strlen((*mem)[i].name);
+ p = safe_strcpy(p, (*mem)[i].name, max_len);
+
+ if (p == NULL)
+ {
+ DEBUG(0, ("make_builtin_line: out of space for builtin aliases!\n"));
+ return False;
+ }
+
+ max_len -= len;
+
+ if (i != (*num_mem)-1)
+ {
+ *p = ',';
+ p++;
+ max_len--;
+ }
+ }
+
+ return True;
+}
diff --git a/source/groupdb/builtinldap.c b/source/groupdb/builtinldap.c
new file mode 100644
index 00000000000..baac82f1bab
--- /dev/null
+++ b/source/groupdb/builtinldap.c
@@ -0,0 +1,426 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP builtin group database for SAMBA
+ Copyright (C) Matthew Chapman 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+
+#ifdef WITH_LDAP
+
+#include <lber.h>
+#include <ldap.h>
+
+extern int DEBUGLEVEL;
+
+/* Internal state */
+extern LDAP *ldap_struct;
+extern LDAPMessage *ldap_results;
+extern LDAPMessage *ldap_entry;
+
+/* Static structure filled for requests */
+static LOCAL_GRP localgrp;
+
+
+/***************************************************************
+ Get group and membership information.
+ ****************************************************************/
+
+static LOCAL_GRP *ldapbuiltin_getgrp(LOCAL_GRP *group,
+ LOCAL_GRP_MEMBER **members, int *num_membs)
+{
+ fstring temp;
+ char **values;
+ LOCAL_GRP_MEMBER *memblist;
+ char *value, *sep;
+ int i;
+
+ if(!ldap_entry)
+ return NULL;
+
+ if(!ldap_get_attribute("cn", group->name)) {
+ DEBUG(0, ("Missing cn\n"));
+ return NULL; }
+
+ DEBUG(2,("Retrieving builtin alias [%s]\n", group->name));
+
+ if(ldap_get_attribute("rid", temp)) {
+ group->rid = strtol(temp, NULL, 16);
+ } else {
+ DEBUG(0, ("Missing rid\n"));
+ return NULL;
+ }
+
+ if(!ldap_get_attribute("description", group->comment))
+ group->comment[0] = 0;
+
+ if(!members || !num_membs) {
+ ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
+ return group;
+ }
+
+ if(values = ldap_get_values(ldap_struct, ldap_entry, "member")) {
+
+ *num_membs = i = ldap_count_values(values);
+ *members = memblist = malloc(i * sizeof(LOCAL_GRP_MEMBER));
+
+ do {
+ value = values[--i];
+
+ if(!(sep = strchr(value, ','))) {
+ DEBUG(0, ("Malformed alias member\n"));
+ return NULL;
+ }
+ *(sep++) = 0;
+ fstrcpy(memblist[i].name, value);
+
+ if(!(value = strchr(sep, ','))) {
+ DEBUG(0, ("Malformed alias member\n"));
+ return NULL;
+ }
+ *(value++) = 0;
+ string_to_sid(&memblist[i].sid, sep);
+
+ if((memblist[i].sid_use = atoi(value))
+ >= SID_NAME_UNKNOWN)
+ DEBUG(0, ("Invalid SID use in alias"));
+
+ } while(i > 0);
+
+ ldap_value_free(values);
+
+ } else {
+ *num_membs = 0;
+ *members = NULL;
+ }
+
+ return group;
+}
+
+
+/************************************************************************
+ Queues the necessary modifications to save a LOCAL_GRP structure
+ ************************************************************************/
+
+static void ldapbuiltin_grpmods(LOCAL_GRP *group, LDAPMod ***mods,
+ int operation)
+{
+ fstring temp;
+
+ *mods = NULL;
+
+ if(operation == LDAP_MOD_ADD) { /* immutable attributes */
+ ldap_make_mod(mods, LDAP_MOD_ADD, "objectClass", "sambaBuiltin");
+ ldap_make_mod(mods, LDAP_MOD_ADD, "cn", group->name);
+
+ slprintf(temp, sizeof(temp)-1, "%x", group->rid);
+ ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp);
+ }
+
+ ldap_make_mod(mods, operation, "description", group->comment);
+}
+
+
+/************************************************************************
+ Create a builtin alias member entry
+ ************************************************************************/
+
+static BOOL ldapbuiltin_memmods(DOM_SID *user_sid, LDAPMod ***mods,
+ int operation)
+{
+ pstring member;
+ pstring sid_str;
+ fstring name;
+ uint8 type;
+
+ if (lookup_sid(user_sid, name, &type))
+ return (False);
+ sid_to_string(sid_str, user_sid);
+
+ slprintf(member, sizeof(member)-1, "%s,%s,%d", name, sid_str, type);
+
+ *mods = NULL;
+ ldap_make_mod(mods, operation, "member", member);
+ return True;
+}
+
+
+/***************************************************************
+ Begin/end smbgrp enumeration.
+ ****************************************************************/
+
+static void *ldapbuiltin_enumfirst(BOOL update)
+{
+ if (lp_server_role() == ROLE_DOMAIN_NONE)
+ return NULL;
+
+ if (!ldap_connect())
+ return NULL;
+
+ ldap_search_for("objectClass=sambaBuiltin");
+
+ return ldap_struct;
+}
+
+static void ldapbuiltin_enumclose(void *vp)
+{
+ ldap_disconnect();
+}
+
+
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
+
+static SMB_BIG_UINT ldapbuiltin_getdbpos(void *vp)
+{
+ return (SMB_BIG_UINT)((ulong)ldap_entry);
+}
+
+static BOOL ldapbuiltin_setdbpos(void *vp, SMB_BIG_UINT tok)
+{
+ ldap_entry = (LDAPMessage *)((ulong)tok);
+ return (True);
+}
+
+
+/*************************************************************************
+ Return limited smb_passwd information, and group membership.
+ *************************************************************************/
+
+static LOCAL_GRP *ldapbuiltin_getgrpbynam(const char *name,
+ LOCAL_GRP_MEMBER **members, int *num_membs)
+{
+ fstring filter;
+ LOCAL_GRP *ret;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(cn=%s)(objectClass=sambaBuiltin))", name);
+ ldap_search_for(filter);
+
+ ret = ldapbuiltin_getgrp(&localgrp, members, num_membs);
+
+ ldap_disconnect();
+ return ret;
+}
+
+static LOCAL_GRP *ldapbuiltin_getgrpbygid(gid_t grp_id,
+ LOCAL_GRP_MEMBER **members, int *num_membs)
+{
+ fstring filter;
+ LOCAL_GRP *ret;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(gidNumber=%d)(objectClass=sambaBuiltin))", grp_id);
+ ldap_search_for(filter);
+ ret = ldapbuiltin_getgrp(&localgrp, members, num_membs);
+
+ ldap_disconnect();
+ return ret;
+}
+
+static LOCAL_GRP *ldapbuiltin_getgrpbyrid(uint32 grp_rid,
+ LOCAL_GRP_MEMBER **members, int *num_membs)
+{
+ fstring filter;
+ LOCAL_GRP *ret;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(rid=%x)(objectClass=sambaBuiltin))", grp_rid);
+ ldap_search_for(filter);
+ ret = ldapbuiltin_getgrp(&localgrp, members, num_membs);
+
+ ldap_disconnect();
+ return ret;
+}
+
+static LOCAL_GRP *ldapbuiltin_getcurrentgrp(void *vp,
+ LOCAL_GRP_MEMBER **members, int *num_membs)
+{
+ return ldapbuiltin_getgrp(&localgrp, members, num_membs);
+}
+
+
+/*************************************************************************
+ Add/modify/delete builtin aliases.
+ *************************************************************************/
+
+static BOOL ldapbuiltin_addgrp(LOCAL_GRP *group)
+{
+ LDAPMod **mods;
+
+ if (!ldap_allocaterid(&group->rid))
+ {
+ DEBUG(0,("RID generation failed\n"));
+ return (False);
+ }
+
+ ldapbuiltin_grpmods(group, &mods, LDAP_MOD_ADD);
+ return ldap_makemods("cn", group->name, mods, True);
+}
+
+static BOOL ldapbuiltin_modgrp(LOCAL_GRP *group)
+{
+ LDAPMod **mods;
+
+ ldapbuiltin_grpmods(group, &mods, LDAP_MOD_REPLACE);
+ return ldap_makemods("cn", group->name, mods, False);
+}
+
+static BOOL ldapbuiltin_delgrp(uint32 grp_rid)
+{
+ fstring filter;
+ char *dn;
+ int err;
+
+ if (!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(rid=%x)(objectClass=sambaBuiltin))", grp_rid);
+ ldap_search_for(filter);
+
+ if (!ldap_entry || !(dn = ldap_get_dn(ldap_struct, ldap_entry)))
+ {
+ ldap_disconnect();
+ return (False);
+ }
+
+ err = ldap_delete_s(ldap_struct, dn);
+ free(dn);
+ ldap_disconnect();
+
+ if (err != LDAP_SUCCESS)
+ {
+ DEBUG(0, ("delete: %s\n", ldap_err2string(err)));
+ return (False);
+ }
+
+ return True;
+}
+
+
+/*************************************************************************
+ Add users to/remove users from aliases.
+ *************************************************************************/
+
+static BOOL ldapbuiltin_addmem(uint32 grp_rid, DOM_SID *user_sid)
+{
+ LDAPMod **mods;
+ fstring rid_str;
+
+ slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid);
+
+ if(!ldapbuiltin_memmods(user_sid, &mods, LDAP_MOD_ADD))
+ return (False);
+
+ return ldap_makemods("rid", rid_str, mods, False);
+}
+
+static BOOL ldapbuiltin_delmem(uint32 grp_rid, DOM_SID *user_sid)
+{
+ LDAPMod **mods;
+ fstring rid_str;
+
+ slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid);
+
+ if(!ldapbuiltin_memmods(user_sid, &mods, LDAP_MOD_DELETE))
+ return (False);
+
+ return ldap_makemods("rid", rid_str, mods, False);
+}
+
+
+/*************************************************************************
+ Return builtin aliases that a user is in.
+ *************************************************************************/
+
+static BOOL ldapbuiltin_getusergroups(const char *name,
+ LOCAL_GRP **groups, int *num_grps)
+{
+ LOCAL_GRP *grouplist;
+ fstring filter;
+ int i;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(pstring)-1,
+ "(&(member=%s,*)(objectclass=sambaBuiltin))", name);
+ ldap_search_for(filter);
+
+ *num_grps = i = ldap_count_entries(ldap_struct, ldap_results);
+
+ if(!i) {
+ *groups = NULL;
+ ldap_disconnect();
+ return (True);
+ }
+
+ *groups = grouplist = malloc(i * sizeof(LOCAL_GRP));
+ do {
+ i--;
+ } while(ldapbuiltin_getgrp(&grouplist[i], NULL, NULL) && (i > 0));
+
+ ldap_disconnect();
+ return (True);
+}
+
+
+static struct aliasdb_ops ldapbuiltin_ops =
+{
+ ldapbuiltin_enumfirst,
+ ldapbuiltin_enumclose,
+ ldapbuiltin_getdbpos,
+ ldapbuiltin_setdbpos,
+
+ ldapbuiltin_getgrpbynam,
+ ldapbuiltin_getgrpbygid,
+ ldapbuiltin_getgrpbyrid,
+ ldapbuiltin_getcurrentgrp,
+
+ ldapbuiltin_addgrp,
+ ldapbuiltin_modgrp,
+ ldapbuiltin_delgrp,
+
+ ldapbuiltin_addmem,
+ ldapbuiltin_delmem,
+
+ ldapbuiltin_getusergroups
+};
+
+struct aliasdb_ops *ldap_initialise_builtin_db(void)
+{
+ return &ldapbuiltin_ops;
+}
+
+#else
+ void builtinldap_dummy_function(void);
+ void builtinldap_dummy_function(void) { } /* stop some compilers complaining */
+#endif
+
diff --git a/source/groupdb/builtinnt5ldap.c b/source/groupdb/builtinnt5ldap.c
new file mode 100644
index 00000000000..1427e53dbed
--- /dev/null
+++ b/source/groupdb/builtinnt5ldap.c
@@ -0,0 +1,487 @@
+
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP builtin group database for SAMBA
+ Copyright (C) Matthew Chapman 1998
+ Copyright (C) Luke Howard 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include "includes.h"
+
+#ifdef WITH_NT5LDAP
+
+#include <lber.h>
+#include <ldap.h>
+#include "ldapdb.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/* Static structure filled for requests */
+static LOCAL_GRP localgrp;
+
+
+/***************************************************************
+ Begin/end smbgrp enumeration.
+ ****************************************************************/
+
+static void *
+nt5ldapbuiltin_enumfirst (BOOL update)
+{
+ LDAPDB_DECLARE_HANDLE (hds);
+ fstring filter;
+
+ if (lp_server_role () == ROLE_DOMAIN_NONE)
+ return NULL;
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ slprintf (filter, sizeof (filter) - 1, "(&(objectClass=Group)(groupType=%d))",
+ NTDS_GROUP_TYPE_BUILTIN_GROUP | NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, LDAP_NO_LIMIT))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ return hds;
+}
+
+static void
+nt5ldapbuiltin_enumclose (void *vp)
+{
+ LDAPDB *hds = (LDAPDB *) vp;
+
+ ldapdb_close (&hds);
+ return;
+}
+
+
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
+
+static SMB_BIG_UINT
+nt5ldapbuiltin_getdbpos (void *vp)
+{
+ return 0;
+}
+
+static BOOL
+nt5ldapbuiltin_setdbpos (void *vp, SMB_BIG_UINT tok)
+{
+ return False;
+}
+
+
+/*************************************************************************
+ Return limited smb_passwd information, and group membership.
+ *************************************************************************/
+
+static LOCAL_GRP *
+nt5ldapbuiltin_getgrpbynam (const char *name,
+ LOCAL_GRP_MEMBER ** members, int *num_membs)
+{
+ fstring filter;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return (NULL);
+ }
+
+ slprintf (filter, sizeof (filter) - 1,
+ "(&(objectClass=Group)(sAMAccountName=%s)(groupType=%d))", name,
+ NTDS_GROUP_TYPE_BUILTIN_GROUP | NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, 1))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldap_make_local_grp (hds, &localgrp, members, num_membs, NTDS_GROUP_TYPE_BUILTIN_GROUP);
+
+ ldapdb_close (&hds);
+
+ return ret ? &localgrp : NULL;
+}
+
+static LOCAL_GRP *
+nt5ldapbuiltin_getgrpbygid (gid_t grp_id,
+ LOCAL_GRP_MEMBER ** members, int *num_membs)
+{
+ fstring filter;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return (NULL);
+ }
+
+ slprintf (filter, sizeof (filter) - 1,
+ "(&(objectClass=Group)(gidNumber=%d)(groupType=%d))", grp_id,
+ NTDS_GROUP_TYPE_BUILTIN_GROUP | NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, 1))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldap_make_local_grp (hds, &localgrp, members, num_membs, NTDS_GROUP_TYPE_BUILTIN_GROUP);
+
+ ldapdb_close (&hds);
+
+ return ret ? &localgrp : NULL;
+}
+
+static LOCAL_GRP *
+nt5ldapbuiltin_getgrpbyrid (uint32 grp_rid,
+ LOCAL_GRP_MEMBER ** members, int *num_membs)
+{
+ fstring filter;
+ fstring sidfilter;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_make_rid_filter ("objectSid", grp_rid, sidfilter))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ slprintf (filter, sizeof (filter) - 1,
+ "(&(objectClass=Group)(%s)(groupType=%d))", sidfilter,
+ NTDS_GROUP_TYPE_BUILTIN_GROUP | NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, 1))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldap_make_local_grp (hds, &localgrp, members, num_membs, NTDS_GROUP_TYPE_BUILTIN_GROUP);
+
+ ldapdb_close (&hds);
+
+ return ret ? &localgrp : NULL;
+}
+
+static LOCAL_GRP *
+nt5ldapbuiltin_getcurrentgrp (void *vp,
+ LOCAL_GRP_MEMBER ** members, int *num_membs)
+{
+ BOOL ret = False;
+
+ do
+ {
+ if ((ret = nt5ldap_make_local_grp ((LDAPDB *)vp, &localgrp, members, num_membs, NTDS_GROUP_TYPE_BUILTIN_GROUP)))
+ break;
+ }
+ while (ldapdb_seq((LDAPDB *)vp) == True);
+
+ return ret ? &localgrp : NULL;
+}
+
+
+/*************************************************************************
+ Add/modify/delete builtin aliases.
+ *************************************************************************/
+
+static BOOL
+nt5ldapbuiltin_addgrp (LOCAL_GRP * group)
+{
+ LDAPMod **mods = NULL;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_allocate_rid (hds, &group->rid))
+ {
+ DEBUG (0, ("RID generation failed\n"));
+ return False;
+ }
+
+ if (!nt5ldap_local_grp_mods (group, &mods, LDAP_MOD_ADD, NTDS_GROUP_TYPE_BUILTIN_GROUP))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_update (hds, lp_ldap_builtin_subcontext (), "cn", group->name, mods, True);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapbuiltin_modgrp (LOCAL_GRP * group)
+{
+ LDAPMod **mods = NULL;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!nt5ldap_local_grp_mods (group, &mods, LDAP_MOD_REPLACE, NTDS_GROUP_TYPE_BUILTIN_GROUP))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_update (hds, lp_ldap_builtin_subcontext (), "cn", group->name, mods, False);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapbuiltin_delgrp (uint32 grp_rid)
+{
+ pstring dn;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_rid_to_dn (hds, grp_rid, dn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ ret = ldapdb_delete (hds, dn);
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+
+/*************************************************************************
+ Add users to/remove users from aliases.
+ *************************************************************************/
+
+static BOOL
+nt5ldapbuiltin_addmem (uint32 grp_rid, const DOM_SID * user_sid)
+{
+ LDAPMod **mods = NULL;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+ pstring userdn, groupdn;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_rid_to_dn (hds, grp_rid, groupdn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!nt5ldap_local_grp_member_mods (user_sid, &mods, LDAP_MOD_ADD, userdn))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_commit (hds, groupdn, mods, False);
+ }
+
+ if (ret == True)
+ {
+ mods = NULL;
+ ret = ldapdb_queue_mod (&mods, LDAP_MOD_ADD, "memberOf", groupdn) &&
+ ldapdb_commit (hds, userdn, mods, False);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapbuiltin_delmem (uint32 grp_rid, const DOM_SID * user_sid)
+{
+ LDAPMod **mods = NULL;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+ pstring userdn, groupdn;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_rid_to_dn (hds, grp_rid, groupdn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!nt5ldap_local_grp_member_mods (user_sid, &mods, LDAP_MOD_DELETE, userdn))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_commit (hds, groupdn, mods, False);
+ }
+
+ if (ret == True)
+ {
+ mods = NULL;
+ ret = ldapdb_queue_mod (&mods, LDAP_MOD_DELETE, "memberOf", groupdn) &&
+ ldapdb_commit (hds, userdn, mods, False);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+
+/*************************************************************************
+ Return builtin aliases that a user is in.
+ *************************************************************************/
+
+static BOOL
+nt5ldapbuiltin_getusergroups (const char *name, LOCAL_GRP ** groups,
+ int *num_grps)
+{
+ LOCAL_GRP *grouplist;
+ fstring filter;
+ int i, ngroups;
+ pstring dn;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_ntname_to_dn (hds, name, dn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ slprintf (filter, sizeof (pstring) - 1, "(&(objectclass=Group)(member=%s)(groupType=%d))", dn,
+ NTDS_GROUP_TYPE_BUILTIN_GROUP | NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+
+ (void) ldapdb_set_synchronous (hds, True);
+ if (!ldapdb_search (hds, NULL, filter, NULL, LDAP_NO_LIMIT))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!ldapdb_count_entries (hds, &ngroups))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ grouplist = calloc (ngroups, sizeof (LOCAL_GRP));
+ if (grouplist == NULL)
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ *num_grps = 0;
+
+ for (i = 0; i < ngroups; i++)
+ {
+ if (nt5ldap_make_local_grp (hds, &grouplist[*num_grps], NULL, NULL, NTDS_GROUP_TYPE_BUILTIN_GROUP))
+ {
+ (*num_grps)++;
+ }
+ if (!ldapdb_seq (hds))
+ {
+ break;
+ }
+ }
+
+ ldapdb_close (&hds);
+
+ *groups = grouplist;
+
+ return True;
+}
+
+
+static struct aliasdb_ops nt5ldapbuiltin_ops =
+{
+ nt5ldapbuiltin_enumfirst,
+ nt5ldapbuiltin_enumclose,
+ nt5ldapbuiltin_getdbpos,
+ nt5ldapbuiltin_setdbpos,
+
+ nt5ldapbuiltin_getgrpbynam,
+ nt5ldapbuiltin_getgrpbygid,
+ nt5ldapbuiltin_getgrpbyrid,
+ nt5ldapbuiltin_getcurrentgrp,
+
+ nt5ldapbuiltin_addgrp,
+ nt5ldapbuiltin_modgrp,
+ nt5ldapbuiltin_delgrp,
+
+ nt5ldapbuiltin_addmem,
+ nt5ldapbuiltin_delmem,
+
+ nt5ldapbuiltin_getusergroups
+};
+
+struct aliasdb_ops *
+nt5ldap_initialise_builtin_db (void)
+{
+ return &nt5ldapbuiltin_ops;
+}
+
+#else
+void builtinnt5ldap_dummy_function (void);
+void
+builtinnt5ldap_dummy_function (void)
+{
+} /* stop some compilers complaining */
+#endif
diff --git a/source/groupdb/builtinunix.c b/source/groupdb/builtinunix.c
new file mode 100644
index 00000000000..b9738eb1546
--- /dev/null
+++ b/source/groupdb/builtinunix.c
@@ -0,0 +1,324 @@
+/*
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "sids.h"
+
+#ifdef USE_SMBUNIX_DB
+
+extern int DEBUGLEVEL;
+
+struct unix_entries
+{
+ struct group *grps;
+ int num_grps;
+ int grp_idx;
+};
+
+/***************************************************************
+ Start to enumerate the bltpasswd list. Returns a void pointer
+ to ensure no modification outside this module.
+****************************************************************/
+
+static void *startbltunixpwent(BOOL update)
+{
+ struct unix_entries *grps;
+ grps = (struct unix_entries*)malloc(sizeof(struct unix_entries));
+
+ if (grps == NULL)
+ {
+ return NULL;
+ }
+
+ if (!get_unix_grps(&grps->num_grps, &grps->grps))
+ {
+ free(grps);
+ return NULL;
+ }
+
+ grps->grp_idx = 0;
+
+ return (void*)grps;
+}
+
+/***************************************************************
+ End enumeration of the bltpasswd list.
+****************************************************************/
+
+static void endbltunixpwent(void *vp)
+{
+ struct unix_entries *grps = (struct unix_entries *)vp;
+
+ if (grps != NULL)
+ {
+ free_unix_grps(grps->num_grps, grps->grps);
+ free(vp);
+ }
+}
+
+/*************************************************************************
+ Return the current position in the bltpasswd list as an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+static SMB_BIG_UINT getbltunixpwpos(void *vp)
+{
+ return (SMB_BIG_UINT)0;
+}
+
+/*************************************************************************
+ Set the current position in the bltpasswd list from an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+static BOOL setbltunixpwpos(void *vp, SMB_BIG_UINT tok)
+{
+ return False;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smbdomainbuiltin list.
+ *************************************************************************/
+BOOL get_unixbuiltin_members(struct group *grp,
+ int *num_mem, LOCAL_GRP_MEMBER **members)
+{
+ int i;
+ char *unix_name;
+
+ if (num_mem == NULL || members == NULL)
+ {
+ return False;
+ }
+
+ (*num_mem) = 0;
+ (*members) = NULL;
+
+ for (i = 0; (unix_name = grp->gr_mem[i]) != NULL; i++)
+ {
+ fstring name;
+ DOM_NAME_MAP gmep;
+ LOCAL_GRP_MEMBER *mem;
+
+ fstrcpy(name, unix_name);
+
+ if (!lookupsmbpwnam (name, &gmep) &&
+ !lookupsmbgrpnam(name, &gmep))
+ {
+ continue;
+ }
+
+ if (!sid_front_equal(&global_sam_sid, &gmep.sid))
+ {
+ DEBUG(0,("builtin database: could not resolve name %s (wrong Domain SID)\n",
+ name));
+ continue;
+ }
+
+ (*num_mem)++;
+ (*members) = Realloc((*members), (*num_mem) * sizeof(LOCAL_GRP_MEMBER));
+ if ((*members) == NULL)
+ {
+ DEBUG(0,("get_unixbuiltin_members: could not realloc LOCAL_GRP_MEMBERs\n"));
+ return False;
+ }
+
+ mem = &(*members)[(*num_mem)-1];
+ slprintf(mem->name, sizeof(mem->name)-1, "%s\\%s",
+ gmep.nt_domain, gmep.nt_name);
+ sid_copy(&mem->sid, &gmep.sid);
+ mem->sid_use = gmep.type;
+
+ DEBUG(10,("get_unixbuiltin_members: adding to builtin alias %s\n",
+ mem->name));
+ }
+ return True;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the domain builtin list.
+
+ when we are a PDC or BDC, then unix groups that are explicitly NOT mapped
+ to builtin aliases are treated as DOMAIN groups (see groupunix.c).
+
+ when we are a member of a domain (not a PDC or BDC) then unix groups
+ that are explicitly NOT mapped to builtin aliases are treated
+ as LOCAL groups.
+
+ the reasoning behind this is to make it as simple as possible (not an easy
+ task) for people to set up a domain-aware samba server, in each role that
+ the server can take.
+
+ *************************************************************************/
+static LOCAL_GRP *getbltunixpwent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem)
+{
+ /* Static buffers we will return. */
+ static LOCAL_GRP gp_buf;
+ struct group unix_grp;
+ struct unix_entries *grps = (struct unix_entries *)vp;
+
+ if (grps == NULL)
+ {
+ return NULL;
+ }
+
+ if (lp_server_role() == ROLE_DOMAIN_NONE)
+ {
+ /*
+ * no domain role, no domain aliases (or domain groups,
+ * but that's dealt with by groupdb...).
+ */
+
+ return NULL;
+ }
+
+ bidb_init_blt(&gp_buf);
+
+ /* get array of unix names + gids. this function does NOT
+ get a copy of the unix group members
+ */
+
+ /* cycle through unix groups */
+ for (; grps->grp_idx < grps->num_grps; grps->grp_idx++)
+ {
+ DOM_NAME_MAP gmep;
+ fstring sid_str;
+
+ memcpy(&unix_grp, &grps->grps[grps->grp_idx], sizeof(unix_grp));
+
+ DEBUG(10,("getgrpunixpwent: enum unix group entry %s\n",
+ unix_grp.gr_name));
+
+ if (!lookupsmbgrpgid(unix_grp.gr_gid, &gmep))
+ {
+ continue;
+ }
+
+ sid_to_string(sid_str, &gmep.sid);
+ DEBUG(10,("group %s found, sid %s type %d\n",
+ gmep.nt_name, sid_str, gmep.type));
+
+ if (gmep.type != SID_NAME_ALIAS)
+ {
+ continue;
+ }
+
+ sid_split_rid(&gmep.sid, &gp_buf.rid);
+ if (!sid_equal(&global_sam_sid, &gmep.sid))
+ {
+ continue;
+ }
+
+ fstrcpy(gp_buf.name, gmep.nt_name);
+ break;
+ }
+
+ if (grps->grp_idx >= grps->num_grps)
+ {
+ return NULL;
+ }
+
+ /* get the user's domain aliases. there are a maximum of 32 */
+
+ if (mem != NULL && num_mem != NULL)
+ {
+ (*mem) = NULL;
+ (*num_mem) = 0;
+
+ memcpy(&unix_grp, getgrgid(unix_grp.gr_gid), sizeof(unix_grp));
+ get_unixbuiltin_members(&unix_grp, num_mem, mem);
+ }
+
+ {
+ pstring linebuf;
+ make_alias_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
+ DEBUG(10,("line: '%s'\n", linebuf));
+ }
+
+ grps->grp_idx++; /* advance so next enum gets next entry */
+ return &gp_buf;
+}
+
+/************************************************************************
+ Routine to add an entry to the bltpasswd file.
+*************************************************************************/
+
+static BOOL add_bltunixgrp_entry(LOCAL_GRP *newblt)
+{
+ DEBUG(0, ("add_bltunixgrp_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to search the bltpasswd file for an entry matching the builtinname.
+ and then modify its builtin entry.
+************************************************************************/
+
+static BOOL mod_bltunixgrp_entry(LOCAL_GRP* blt)
+{
+ DEBUG(0, ("mod_bltunixgrp_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to add a member to an entry to the bltpasswd file.
+*************************************************************************/
+static BOOL add_bltunixgrp_member(uint32 rid, DOM_SID *member_sid)
+{
+ DEBUG(0, ("add_bltunixgrp_member: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to delete a member from an entry to the bltpasswd file.
+*************************************************************************/
+static BOOL del_bltunixgrp_member(uint32 rid, DOM_SID *member_sid)
+{
+ DEBUG(0, ("del_bltunixgrp_member: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+static struct aliasdb_ops unix_ops =
+{
+ startbltunixpwent,
+ endbltunixpwent,
+ getbltunixpwpos,
+ setbltunixpwpos,
+
+ iterate_getbuiltinntnam, /* In builtindb.c */
+ iterate_getbuiltingid, /* In builtindb.c */
+ iterate_getbuiltinrid, /* In builtindb.c */
+ getbltunixpwent,
+
+ add_bltunixgrp_entry,
+ mod_bltunixgrp_entry,
+ NULL, /* deliberately NULL: you can't delete builtin aliases */
+
+ add_bltunixgrp_member,
+ del_bltunixgrp_member,
+
+ iterate_getuserbuiltinntnam /* in builtindb.c */
+};
+
+struct aliasdb_ops *unix_initialise_builtin_db(void)
+{
+ return &unix_ops;
+}
+
+#else
+ /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
+ void unix_bltpass_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* USE_SMBPASS_DB */
diff --git a/source/groupdb/groupdb.c b/source/groupdb/groupdb.c
index b8952358fbc..bfb3a254e6a 100644
--- a/source/groupdb/groupdb.c
+++ b/source/groupdb/groupdb.c
@@ -22,6 +22,7 @@
#include "includes.h"
#include "nterr.h"
+#include "sids.h"
extern int DEBUGLEVEL;
@@ -30,7 +31,7 @@ extern int DEBUGLEVEL;
* that points to the correct function for the selected database. JRA.
*/
-static struct groupdb_ops *gpdb_ops;
+static struct groupdb_ops *gpdb_ops = NULL;
/***************************************************************
Initialise the group db operations.
@@ -45,10 +46,12 @@ BOOL initialise_group_db(void)
#ifdef WITH_NISPLUS
gpdb_ops = nisplus_initialise_group_db();
+#elif defined(WITH_NT5LDAP)
+ gpdb_ops = nt5ldap_initialise_group_db();
#elif defined(WITH_LDAP)
gpdb_ops = ldap_initialise_group_db();
-#else
- gpdb_ops = file_initialise_group_db();
+#elif defined(USE_SMBUNIX_DB)
+ gpdb_ops = unix_initialise_group_db();
#endif
return (gpdb_ops != NULL);
@@ -65,7 +68,28 @@ BOOL initialise_group_db(void)
*************************************************************************/
DOMAIN_GRP *iterate_getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
{
- return iterate_getgrouprid(pwdb_gid_to_group_rid(gid), mem, num_mem);
+ DOM_NAME_MAP gmep;
+ uint32 rid;
+ if (!lookupsmbgrpgid(gid, &gmep))
+ {
+ DEBUG(0,("iterate_getgroupgid: gid %d does not map to one of our Domain's Groups\n", gid));
+ return NULL;
+ }
+
+ if (gmep.type != SID_NAME_DOM_GRP && gmep.type != SID_NAME_WKN_GRP)
+ {
+ DEBUG(0,("iterate_getgroupgid: gid %d does not map to one of our Domain's Groups\n", gid));
+ return NULL;
+ }
+
+ sid_split_rid(&gmep.sid, &rid);
+ if (!sid_equal(&gmep.sid, &global_sam_sid))
+ {
+ DEBUG(0,("iterate_getgroupgid: gid %d does not map into our Domain SID\n", gid));
+ return NULL;
+ }
+
+ return iterate_getgrouprid(rid, mem, num_mem);
}
/************************************************************************
@@ -105,7 +129,7 @@ DOMAIN_GRP *iterate_getgrouprid(uint32 rid, DOMAIN_GRP_MEMBER **mem, int *num_me
Utility function to search group database by name. use this if your database
does not have search facilities.
*************************************************************************/
-DOMAIN_GRP *iterate_getgroupnam(char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+DOMAIN_GRP *iterate_getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
{
DOMAIN_GRP *grp = NULL;
void *fp = NULL;
@@ -165,7 +189,7 @@ BOOL add_domain_group(DOMAIN_GRP **grps, int *num_grps, DOMAIN_GRP *grp)
/*************************************************************************
checks to see if a user is a member of a domain group
*************************************************************************/
-static BOOL user_is_member(char *user_name, DOMAIN_GRP_MEMBER *mem, int num_mem)
+static BOOL user_is_member(const char *user_name, DOMAIN_GRP_MEMBER *mem, int num_mem)
{
int i;
for (i = 0; i < num_mem; i++)
@@ -185,16 +209,16 @@ static BOOL user_is_member(char *user_name, DOMAIN_GRP_MEMBER *mem, int num_mem)
gets an array of groups that a user is in. use this if your database
does not have search facilities
*************************************************************************/
-BOOL iterate_getusergroupsnam(char *user_name, DOMAIN_GRP **grps, int *num_grps)
+BOOL iterate_getusergroupsnam(const char *user_name, DOMAIN_GRP **grps, int *num_grps)
{
- DOMAIN_GRP *grp;
+ DOMAIN_GRP *grp = NULL;
DOMAIN_GRP_MEMBER *mem = NULL;
int num_mem = 0;
void *fp = NULL;
DEBUG(10, ("search for usergroups by name: %s\n", user_name));
- if (user_name == NULL || grp == NULL || num_grps == NULL)
+ if (user_name == NULL || grps == NULL || num_grps == NULL)
{
return False;
}
@@ -250,12 +274,12 @@ BOOL iterate_getusergroupsnam(char *user_name, DOMAIN_GRP **grps, int *num_grps)
*************************************************************************/
BOOL enumdomgroups(DOMAIN_GRP **grps, int *num_grps)
{
- DOMAIN_GRP *grp;
+ DOMAIN_GRP *grp = NULL;
void *fp = NULL;
DEBUG(10, ("enum user groups\n"));
- if (grp == NULL || num_grps == NULL)
+ if (grps == NULL || num_grps == NULL)
{
return False;
}
@@ -321,15 +345,38 @@ DOMAIN_GRP *getgroupent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem)
/************************************************************************
Routine to add an entry to the group database file.
+ on entry, the entry is added by name.
+ on exit, the RID is expected to have been set.
*************************************************************************/
BOOL add_group_entry(DOMAIN_GRP *newgrp)
{
- return gpdb_ops->add_group_entry(newgrp);
+ BOOL ret;
+ if (newgrp->rid != 0xffffffff)
+ {
+ DEBUG(0,("add_group_entry - RID must be 0xffffffff, \
+database instance is responsible for allocating the RID, not you.\n"));
+ return False;
+ }
+ ret = gpdb_ops->add_group_entry(newgrp);
+ if (newgrp->rid == 0xffffffff)
+ {
+ DEBUG(0,("add_group_entry - RID has not been set by database\n"));
+ return False;
+ }
+ return ret;
}
/************************************************************************
- Routine to search the group database file for an entry matching the groupname.
+ Routine to delete group database entry matching by rid.
+************************************************************************/
+BOOL del_group_entry(uint32 rid)
+{
+ return gpdb_ops->del_group_entry(rid);
+}
+
+/************************************************************************
+ Routine to search group database file for entry matching by rid or groupname.
and then replace the entry.
************************************************************************/
@@ -339,12 +386,28 @@ BOOL mod_group_entry(DOMAIN_GRP* grp)
}
/************************************************************************
+ Routine to add a member to an entry in the group database file.
+*************************************************************************/
+BOOL add_group_member(uint32 rid, uint32 member_rid)
+{
+ return gpdb_ops->add_group_member(rid, member_rid);
+}
+
+/************************************************************************
+ Routine to delete a member from an entry in the group database file.
+*************************************************************************/
+BOOL del_group_member(uint32 rid, uint32 member_rid)
+{
+ return gpdb_ops->del_group_member(rid, member_rid);
+}
+
+/************************************************************************
Routine to search group database by name.
*************************************************************************/
-DOMAIN_GRP *getgroupnam(char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+DOMAIN_GRP *getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem)
{
- return gpdb_ops->getgroupnam(name, mem, num_mem);
+ return gpdb_ops->getgroupntnam(name, mem, num_mem);
}
/************************************************************************
@@ -368,9 +431,9 @@ DOMAIN_GRP *getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem)
/*************************************************************************
gets an array of groups that a user is in.
*************************************************************************/
-BOOL getusergroupsnam(char *user_name, DOMAIN_GRP **grp, int *num_grps)
+BOOL getusergroupsntnam(const char *user_name, DOMAIN_GRP **grp, int *num_grps)
{
- return gpdb_ops->getusergroupsnam(user_name, grp, num_grps);
+ return gpdb_ops->getusergroupsntnam(user_name, grp, num_grps);
}
/*************************************************************
@@ -383,3 +446,51 @@ void gpdb_init_grp(DOMAIN_GRP *grp)
ZERO_STRUCTP(grp);
}
+/*************************************************************************
+ turns a list of groups into a string.
+*************************************************************************/
+BOOL make_group_line(char *p, int max_len,
+ DOMAIN_GRP *grp,
+ DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ int i;
+ int len;
+ len = slprintf(p, max_len-1, "%s:%s:%d:", grp->name, grp->comment, grp->rid);
+
+ if (len == -1)
+ {
+ DEBUG(0,("make_group_line: cannot create entry\n"));
+ return False;
+ }
+
+ p += len;
+ max_len -= len;
+
+ if (mem == NULL || num_mem == NULL)
+ {
+ return True;
+ }
+
+ for (i = 0; i < (*num_mem); i++)
+ {
+ len = strlen((*mem)[i].name);
+ p = safe_strcpy(p, (*mem)[i].name, max_len);
+
+ if (p == NULL)
+ {
+ DEBUG(0, ("make_group_line: out of space for groups!\n"));
+ return False;
+ }
+
+ max_len -= len;
+
+ if (i != (*num_mem)-1)
+ {
+ *p = ',';
+ p++;
+ max_len--;
+ }
+ }
+
+ return True;
+}
diff --git a/source/groupdb/groupfile.c b/source/groupdb/groupfile.c
index 88d362e7d4c..b4349476919 100644
--- a/source/groupdb/groupfile.c
+++ b/source/groupdb/groupfile.c
@@ -18,8 +18,9 @@
*/
#include "includes.h"
+#include "sids.h"
-#ifdef USE_SMBPASS_DB
+#ifdef USE_SMBGROUP_DB
static int gp_file_lock_depth = 0;
extern int DEBUGLEVEL;
@@ -33,7 +34,7 @@ static char s_readbuf[1024];
static void *startgrpfilepwent(BOOL update)
{
- return startfilepwent(lp_smb_group_file(),
+ return startfileent(lp_smb_group_file(),
s_readbuf, sizeof(s_readbuf),
&gp_file_lock_depth, update);
}
@@ -44,7 +45,7 @@ static void *startgrpfilepwent(BOOL update)
static void endgrpfilepwent(void *vp)
{
- endfilepwent(vp, &gp_file_lock_depth);
+ endfileent(vp, &gp_file_lock_depth);
}
/*************************************************************************
@@ -65,51 +66,6 @@ static BOOL setgrpfilepwpos(void *vp, SMB_BIG_UINT tok)
return setfilepwpos(vp, tok);
}
-static BOOL make_group_line(char *p, int max_len,
- DOMAIN_GRP *grp,
- DOMAIN_GRP_MEMBER **mem, int *num_mem)
-{
- int i;
- int len;
- len = slprintf(p, max_len-1, "%s:%s:%d:", grp->name, grp->comment, grp->rid);
-
- if (len == -1)
- {
- DEBUG(0,("make_group_line: cannot create entry\n"));
- return False;
- }
-
- p += len;
- max_len -= len;
-
- if (mem == NULL || num_mem == NULL)
- {
- return True;
- }
-
- for (i = 0; i < (*num_mem); i++)
- {
- len = strlen((*mem)[i].name);
- p = safe_strcpy(p, (*mem)[i].name, max_len);
-
- if (p == NULL)
- {
- DEBUG(0, ("make_group_line: out of space for groups!\n"));
- return False;
- }
-
- max_len -= len;
-
- if (i != (*num_mem)-1)
- {
- *p = ',';
- p++;
- max_len--;
- }
- }
-
- return True;
-}
/*************************************************************************
Routine to return the next entry in the smbdomaingroup list.
@@ -128,11 +84,36 @@ static char *get_group_members(char *p, int *num_mem, DOMAIN_GRP_MEMBER **member
while (next_token(&p, name, ",", sizeof(fstring)))
{
+ DOM_SID sid;
+ uint8 type;
+ BOOL found = False;
+
+ if (isdigit(name))
+ {
+ uint32 rid = get_number(name);
+ sid_copy(&sid, &global_sam_sid);
+ sid_append_rid(&sid, rid);
+
+ found = lookup_sid(&sid, name, &type) == 0x0;
+ }
+ else
+ {
+ found = lookup_name(name, &sid, &type) == 0x0;
+ }
+
+ if (!found)
+ {
+ DEBUG(0,("group database: could not resolve name %s in domain %s\n",
+ name, global_sam_name));
+ continue;
+ }
+
(*members) = Realloc((*members), ((*num_mem)+1) * sizeof(DOMAIN_GRP_MEMBER));
if ((*members) == NULL)
{
return NULL;
}
+
fstrcpy((*members)[(*num_mem)].name, name);
(*members)[(*num_mem)].attr = 0x07;
(*num_mem)++;
@@ -147,19 +128,19 @@ static DOMAIN_GRP *getgrpfilepwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_m
{
/* Static buffers we will return. */
static DOMAIN_GRP gp_buf;
+ DOM_NAME_MAP gmep;
int gidval;
pstring linebuf;
char *p;
- size_t linebuf_len;
gpdb_init_grp(&gp_buf);
/*
* Scan the file, a line at a time and check if the name matches.
*/
- while ((linebuf_len = getfileline(vp, linebuf, sizeof(linebuf))) > 0)
+ while (getfileline(vp, linebuf, sizeof(linebuf)) > 0)
{
/* get group name */
@@ -214,7 +195,22 @@ static DOMAIN_GRP *getgrpfilepwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_m
/* ok, set up the static data structure and return it */
- gp_buf.rid = pwdb_gid_to_group_rid((gid_t)gidval);
+ if (!lookupsmbgrpgid((gid_t)gidval, &gmep))
+ {
+ continue;
+ }
+ if (gmep.type != SID_NAME_DOM_GRP &&
+ gmep.type != SID_NAME_WKN_GRP))
+ {
+ continue;
+ }
+
+ sid_split_rid(&gmep.sid, &gp_buf.rid);
+ if (!sid_equal(&gmep.sid, &global_sam_sid))
+ {
+ continue;
+ }
+
gp_buf.attr = 0x07;
make_group_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
@@ -239,11 +235,7 @@ static BOOL add_grpfilegrp_entry(DOMAIN_GRP *newgrp)
/************************************************************************
Routine to search the grppasswd file for an entry matching the groupname.
- and then modify its group entry. We can't use the startgrppwent()/
- getgrppwent()/endgrppwent() interfaces here as we depend on looking
- in the actual file to decide how much room we have to write data.
- override = False, normal
- override = True, override XXXXXXXX'd out group or NO PASS
+ and then modify its group entry.
************************************************************************/
static BOOL mod_grpfilegrp_entry(DOMAIN_GRP* grp)
@@ -260,7 +252,7 @@ static struct groupdb_ops file_ops =
getgrpfilepwpos,
setgrpfilepwpos,
- iterate_getgroupnam, /* In groupdb.c */
+ iterate_getgroupntnam, /* In groupdb.c */
iterate_getgroupgid, /* In groupdb.c */
iterate_getgrouprid, /* In groupdb.c */
getgrpfilepwent,
@@ -268,7 +260,7 @@ static struct groupdb_ops file_ops =
add_grpfilegrp_entry,
mod_grpfilegrp_entry,
- iterate_getusergroupsnam /* in groupdb.c */
+ iterate_getusergroupntnam /* in groupdb.c */
};
struct groupdb_ops *file_initialise_group_db(void)
diff --git a/source/groupdb/groupldap.c b/source/groupdb/groupldap.c
new file mode 100644
index 00000000000..086df4717d5
--- /dev/null
+++ b/source/groupdb/groupldap.c
@@ -0,0 +1,436 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP domain group database for SAMBA
+ Copyright (C) Matthew Chapman 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+#include "sids.h"
+
+#ifdef WITH_LDAP
+
+#include <lber.h>
+#include <ldap.h>
+
+extern int DEBUGLEVEL;
+
+/* Internal state */
+extern LDAP *ldap_struct;
+extern LDAPMessage *ldap_results;
+extern LDAPMessage *ldap_entry;
+
+/* Static structure filled for requests */
+static DOMAIN_GRP domgrp;
+
+
+/***************************************************************
+ Get group and membership information.
+ ****************************************************************/
+
+static DOMAIN_GRP *ldapgroup_getgrp(DOMAIN_GRP *group,
+ DOMAIN_GRP_MEMBER **members, int *num_membs)
+{
+ fstring temp;
+ char **values;
+ DOMAIN_GRP_MEMBER *memblist;
+ char *value, *sep;
+ int i;
+
+ if(!ldap_entry)
+ return NULL;
+
+ if(!ldap_get_attribute("cn", group->name)) {
+ DEBUG(0, ("Missing cn\n"));
+ return NULL; }
+
+ DEBUG(2,("Retrieving group [%s]\n", group->name));
+
+ if(ldap_get_attribute("rid", temp)) {
+ group->rid = strtol(temp, NULL, 16);
+ } else {
+ DEBUG(0, ("Missing rid\n"));
+ return NULL;
+ }
+
+ if(!ldap_get_attribute("description", group->comment))
+ group->comment[0] = 0;
+
+ group->attr = 0x7;
+
+ if(!members || !num_membs) {
+ ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
+ return group;
+ }
+
+ if(values = ldap_get_values(ldap_struct, ldap_entry, "member")) {
+
+ *num_membs = i = ldap_count_values(values);
+ *members = memblist = malloc(i * sizeof(DOMAIN_GRP_MEMBER));
+
+ do {
+ value = values[--i];
+
+ if(!(sep = strchr(value, ','))) {
+ DEBUG(0, ("Malformed group member\n"));
+ return NULL;
+ }
+ *(sep++) = 0;
+ fstrcpy(memblist[i].name, value);
+
+ if(!(value = strchr(sep, ','))) {
+ DEBUG(0, ("Malformed group member\n"));
+ return NULL;
+ }
+ memblist[i].rid = strtol(sep, &value, 16);
+
+ if((memblist[i].sid_use = atoi(value+1))
+ >= SID_NAME_UNKNOWN)
+ DEBUG(0, ("Invalid SID use in group"));
+
+ memblist[i].attr = 0x7;
+
+ } while(i > 0);
+
+ ldap_value_free(values);
+
+ } else {
+ *num_membs = 0;
+ *members = NULL;
+ }
+
+ ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
+ return group;
+}
+
+
+/************************************************************************
+ Queues the necessary modifications to save a DOMAIN_GRP structure
+ ************************************************************************/
+
+static void ldapgroup_grpmods(DOMAIN_GRP *group, LDAPMod ***mods,
+ int operation)
+{
+ fstring temp;
+
+ *mods = NULL;
+
+ if(operation == LDAP_MOD_ADD) { /* immutable attributes */
+ ldap_make_mod(mods, LDAP_MOD_ADD, "objectClass", "sambaGroup");
+ ldap_make_mod(mods, LDAP_MOD_ADD, "cn", group->name);
+
+ slprintf(temp, sizeof(temp)-1, "%x", group->rid);
+ ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp);
+ }
+
+ ldap_make_mod(mods, operation, "description", group->comment);
+}
+
+
+/************************************************************************
+ Create a group member entry
+ ************************************************************************/
+
+static BOOL ldapgroup_memmods(uint32 user_rid, LDAPMod ***mods, int operation)
+{
+ pstring member;
+ fstring name;
+ DOM_SID sid;
+ uint8 type;
+
+ sid_copy(&sid, &global_sam_sid);
+ sid_append_rid(&sid, user_rid);
+ if (lookup_sid(&sid, name, &type))
+ return (False);
+
+ slprintf(member, sizeof(member)-1, "%s,%x,%d", name, user_rid, type);
+
+ *mods = NULL;
+ ldap_make_mod(mods, operation, "member", member);
+ return True;
+}
+
+
+/***************************************************************
+ Begin/end domain group enumeration.
+ ****************************************************************/
+
+static void *ldapgroup_enumfirst(BOOL update)
+{
+ int server_role = lp_server_role();
+
+ if (server_role == ROLE_DOMAIN_NONE ||
+ server_role == ROLE_DOMAIN_MEMBER)
+ return NULL;
+
+ if (!ldap_connect())
+ return NULL;
+
+ ldap_search_for("objectclass=sambaGroup");
+
+ return ldap_struct;
+}
+
+static void ldapgroup_enumclose(void *vp)
+{
+ ldap_disconnect();
+}
+
+
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
+
+static SMB_BIG_UINT ldapgroup_getdbpos(void *vp)
+{
+ return (SMB_BIG_UINT)((ulong)ldap_entry);
+}
+
+static BOOL ldapgroup_setdbpos(void *vp, SMB_BIG_UINT tok)
+{
+ ldap_entry = (LDAPMessage *)((ulong)tok);
+ return (True);
+}
+
+
+/*************************************************************************
+ Return information about domain groups and their members.
+ *************************************************************************/
+
+static DOMAIN_GRP *ldapgroup_getgrpbynam(const char *name,
+ DOMAIN_GRP_MEMBER **members, int *num_membs)
+{
+ fstring filter;
+ DOMAIN_GRP *ret;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(cn=%s*)(objectClass=sambaGroup))", name);
+ ldap_search_for(filter);
+
+ ret = ldapgroup_getgrp(&domgrp, members, num_membs);
+
+ ldap_disconnect();
+ return ret;
+}
+
+static DOMAIN_GRP *ldapgroup_getgrpbygid(gid_t grp_id,
+ DOMAIN_GRP_MEMBER **members, int *num_membs)
+{
+ fstring filter;
+ DOMAIN_GRP *ret;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(gidNumber=%d)(objectClass=sambaGroup))", grp_id);
+ ldap_search_for(filter);
+
+ ret = ldapgroup_getgrp(&domgrp, members, num_membs);
+
+ ldap_disconnect();
+ return ret;
+}
+
+static DOMAIN_GRP *ldapgroup_getgrpbyrid(uint32 grp_rid,
+ DOMAIN_GRP_MEMBER **members, int *num_membs)
+{
+ fstring filter;
+ DOMAIN_GRP *ret;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(rid=%x)(objectClass=sambaGroup))", grp_rid);
+ ldap_search_for(filter);
+
+ ret = ldapgroup_getgrp(&domgrp, members, num_membs);
+
+ ldap_disconnect();
+ return ret;
+}
+
+static DOMAIN_GRP *ldapgroup_getcurrentgrp(void *vp,
+ DOMAIN_GRP_MEMBER **members, int *num_membs)
+{
+ return ldapgroup_getgrp(&domgrp, members, num_membs);
+}
+
+
+/*************************************************************************
+ Add/modify/delete domain groups.
+ *************************************************************************/
+
+static BOOL ldapgroup_addgrp(DOMAIN_GRP *group)
+{
+ LDAPMod **mods;
+
+ if (!ldap_allocaterid(&group->rid))
+ {
+ DEBUG(0,("RID generation failed\n"));
+ return (False);
+ }
+
+ ldapgroup_grpmods(group, &mods, LDAP_MOD_ADD);
+ return ldap_makemods("cn", group->name, mods, True);
+}
+
+static BOOL ldapgroup_modgrp(DOMAIN_GRP *group)
+{
+ LDAPMod **mods;
+
+ ldapgroup_grpmods(group, &mods, LDAP_MOD_REPLACE);
+ return ldap_makemods("cn", group->name, mods, False);
+}
+
+static BOOL ldapgroup_delgrp(uint32 grp_rid)
+{
+ fstring filter;
+ char *dn;
+ int err;
+
+ if (!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(rid=%x)(objectClass=sambaGroup))", grp_rid);
+ ldap_search_for(filter);
+
+ if (!ldap_entry || !(dn = ldap_get_dn(ldap_struct, ldap_entry)))
+ {
+ ldap_disconnect();
+ return (False);
+ }
+
+ err = ldap_delete_s(ldap_struct, dn);
+ free(dn);
+ ldap_disconnect();
+
+ if (err != LDAP_SUCCESS)
+ {
+ DEBUG(0, ("delete: %s\n", ldap_err2string(err)));
+ return (False);
+ }
+
+ return True;
+}
+
+
+/*************************************************************************
+ Add users to/remove users from groups.
+ *************************************************************************/
+
+static BOOL ldapgroup_addmem(uint32 grp_rid, uint32 user_rid)
+{
+ LDAPMod **mods;
+ fstring rid_str;
+
+ slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid);
+
+ if(!ldapgroup_memmods(user_rid, &mods, LDAP_MOD_ADD))
+ return (False);
+
+ return ldap_makemods("rid", rid_str, mods, False);
+}
+
+static BOOL ldapgroup_delmem(uint32 grp_rid, uint32 user_rid)
+{
+ LDAPMod **mods;
+ fstring rid_str;
+
+ slprintf(rid_str, sizeof(rid_str)-1, "%x", grp_rid);
+
+ if(!ldapgroup_memmods(user_rid, &mods, LDAP_MOD_DELETE))
+ return (False);
+
+ return ldap_makemods("rid", rid_str, mods, False);
+}
+
+
+/*************************************************************************
+ Return domain groups that a user is in.
+ *************************************************************************/
+
+static BOOL ldapgroup_getusergroups(const char *name, DOMAIN_GRP **groups,
+ int *num_grps)
+{
+ DOMAIN_GRP *grouplist;
+ fstring filter;
+ int i;
+
+ if(!ldap_connect())
+ return (False);
+
+ slprintf(filter, sizeof(pstring)-1,
+ "(&(member=%s,*)(objectclass=sambaGroup))", name);
+ ldap_search_for(filter);
+
+ *num_grps = i = ldap_count_entries(ldap_struct, ldap_results);
+
+ if(!i) {
+ *groups = NULL;
+ ldap_disconnect();
+ return (True);
+ }
+
+ *groups = grouplist = malloc(i * sizeof(DOMAIN_GRP));
+ do {
+ i--;
+ } while(ldapgroup_getgrp(&grouplist[i], NULL, NULL) && (i > 0));
+
+ ldap_disconnect();
+ return (True);
+}
+
+
+static struct groupdb_ops ldapgroup_ops =
+{
+ ldapgroup_enumfirst,
+ ldapgroup_enumclose,
+ ldapgroup_getdbpos,
+ ldapgroup_setdbpos,
+
+ ldapgroup_getgrpbynam,
+ ldapgroup_getgrpbygid,
+ ldapgroup_getgrpbyrid,
+ ldapgroup_getcurrentgrp,
+
+ ldapgroup_addgrp,
+ ldapgroup_modgrp,
+ ldapgroup_delgrp,
+
+ ldapgroup_addmem,
+ ldapgroup_delmem,
+
+ ldapgroup_getusergroups
+};
+
+struct groupdb_ops *ldap_initialise_group_db(void)
+{
+ return &ldapgroup_ops;
+}
+
+#else
+ void groupldap_dummy_function(void);
+ void groupldap_dummy_function(void) { } /* stop some compilers complaining */
+#endif
+
diff --git a/source/groupdb/groupnt5ldap.c b/source/groupdb/groupnt5ldap.c
new file mode 100644
index 00000000000..2f1211eb62f
--- /dev/null
+++ b/source/groupdb/groupnt5ldap.c
@@ -0,0 +1,488 @@
+
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP domain group database for SAMBA
+ Copyright (C) Matthew Chapman 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include "includes.h"
+
+#ifdef WITH_NT5LDAP
+
+#include <lber.h>
+#include <ldap.h>
+#include "ldapdb.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/* Static structure filled for requests */
+static DOMAIN_GRP domgrp;
+
+/***************************************************************
+ Begin/end domain group enumeration.
+ ****************************************************************/
+
+static void *
+nt5ldapgroup_enumfirst (BOOL update)
+{
+ fstring filter;
+ int server_role = lp_server_role ();
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (server_role == ROLE_DOMAIN_NONE ||
+ server_role == ROLE_DOMAIN_MEMBER)
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ slprintf (filter, sizeof (filter) - 1, "(&(objectClass=Group)(groupType=%d))",
+ NTDS_GROUP_TYPE_GLOBAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, LDAP_NO_LIMIT))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ return hds;
+}
+
+static void
+nt5ldapgroup_enumclose (void *vp)
+{
+ LDAPDB *hds = (LDAPDB *) vp;
+
+ ldapdb_close (&hds);
+
+ return;
+}
+
+
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
+
+static SMB_BIG_UINT
+nt5ldapgroup_getdbpos (void *vp)
+{
+ return 0;
+}
+
+static BOOL
+nt5ldapgroup_setdbpos (void *vp, SMB_BIG_UINT tok)
+{
+ return False;
+}
+
+
+/*************************************************************************
+ Return information about domain groups and their members.
+ *************************************************************************/
+
+static DOMAIN_GRP *
+nt5ldapgroup_getgrpbynam (const char *name,
+ DOMAIN_GRP_MEMBER ** members, int *num_membs)
+{
+ fstring filter;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ slprintf (filter, sizeof (filter) - 1,
+ "(&(objectClass=Group)(sAMAccountName=%s)(groupType=%d))", name,
+ NTDS_GROUP_TYPE_GLOBAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, 1))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldap_make_domain_grp (hds, &domgrp, members, num_membs);
+
+ ldapdb_close (&hds);
+
+ return ret ? &domgrp : NULL;
+}
+
+static DOMAIN_GRP *
+nt5ldapgroup_getgrpbygid (gid_t grp_id,
+ DOMAIN_GRP_MEMBER ** members, int *num_membs)
+{
+ fstring filter;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ slprintf (filter, sizeof (filter) - 1,
+ "(&(objectClass=Group)(gidNumber=%d)(groupType=%d))", grp_id,
+ NTDS_GROUP_TYPE_GLOBAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, 1))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldap_make_domain_grp (hds, &domgrp, members, num_membs);
+
+ ldapdb_close (&hds);
+
+ return ret ? &domgrp : NULL;
+}
+
+static DOMAIN_GRP *
+nt5ldapgroup_getgrpbyrid (uint32 grp_rid,
+ DOMAIN_GRP_MEMBER ** members, int *num_membs)
+{
+ fstring filter;
+ fstring sidfilter;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_make_rid_filter ("objectSid", grp_rid, sidfilter))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ slprintf (filter, sizeof (filter) - 1,
+ "(&(objectClass=Group)(%s)(groupType=%d))", sidfilter,
+ NTDS_GROUP_TYPE_GLOBAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_search (hds, NULL, filter, NULL, 1))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldap_make_domain_grp (hds, &domgrp, members, num_membs);
+
+ ldapdb_close (&hds);
+
+ return ret ? &domgrp : NULL;
+}
+
+static DOMAIN_GRP *
+nt5ldapgroup_getcurrentgrp (void *vp,
+ DOMAIN_GRP_MEMBER ** members, int *num_membs)
+{
+ BOOL ret = False;
+
+ do
+ {
+ if ((ret = nt5ldap_make_domain_grp ((LDAPDB *)vp, &domgrp, members, num_membs)))
+ break;
+ }
+ while (ldapdb_seq((LDAPDB *)vp) == True);
+
+ return ret ? &domgrp : NULL;
+}
+
+
+/*************************************************************************
+ Add/modify/delete domain groups.
+ *************************************************************************/
+
+static BOOL
+nt5ldapgroup_addgrp (DOMAIN_GRP * group)
+{
+ LDAPMod **mods = NULL;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_allocate_rid (hds, &group->rid))
+ {
+ DEBUG (0, ("RID generation failed\n"));
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!nt5ldap_domain_grp_mods (group, &mods, LDAP_MOD_ADD))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_update (hds, lp_ldap_users_subcontext (), "cn", group->name, mods, True);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapgroup_modgrp (DOMAIN_GRP * group)
+{
+ LDAPMod **mods = NULL;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!nt5ldap_domain_grp_mods (group, &mods, LDAP_MOD_REPLACE))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_update (hds, lp_ldap_users_subcontext (), "cn", group->name, mods, False);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapgroup_delgrp (uint32 grp_rid)
+{
+ LDAPDB_DECLARE_HANDLE (hds);
+ pstring dn;
+ BOOL ret;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_rid_to_dn (hds, grp_rid, dn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ ret = ldapdb_delete (hds, dn);
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+
+/*************************************************************************
+ Add users to/remove users from groups.
+ *************************************************************************/
+
+static BOOL
+nt5ldapgroup_addmem (uint32 grp_rid, uint32 user_rid)
+{
+ LDAPMod **mods = NULL;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+ pstring userdn, groupdn;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_rid_to_dn (hds, grp_rid, groupdn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!nt5ldap_domain_grp_member_mods (user_rid, &mods, LDAP_MOD_ADD, userdn))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_commit (hds, groupdn, mods, False);
+ }
+
+ if (ret == True)
+ {
+ mods = NULL;
+ ret = ldapdb_queue_mod (&mods, LDAP_MOD_ADD, "memberOf", groupdn) &&
+ ldapdb_commit (hds, userdn, mods, False);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapgroup_delmem (uint32 grp_rid, uint32 user_rid)
+{
+ LDAPMod **mods = NULL;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+ pstring userdn, groupdn;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_rid_to_dn (hds, grp_rid, groupdn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!nt5ldap_domain_grp_member_mods (user_rid, &mods, LDAP_MOD_DELETE, userdn))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_commit (hds, groupdn, mods, False);
+ }
+
+ if (ret == True)
+ {
+ mods = NULL;
+ ret = ldapdb_lookup_by_rid (hds, user_rid) &&
+ ldapdb_queue_mod (&mods, LDAP_MOD_DELETE, "memberOf", groupdn) &&
+ ldapdb_commit (hds, userdn, mods, False);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+
+/*************************************************************************
+ Return domain groups that a user is in.
+ *************************************************************************/
+
+static BOOL
+nt5ldapgroup_getusergroups (const char *name, DOMAIN_GRP ** groups,
+ int *num_grps)
+{
+ DOMAIN_GRP *grouplist;
+ fstring filter;
+ int i, ngroups;
+ pstring dn;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_ntname_to_dn (hds, name, dn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ slprintf (filter, sizeof (pstring) - 1, "(&(objectClass=Group)(member=%s)(groupType=%d))",
+ dn, NTDS_GROUP_TYPE_GLOBAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ (void) ldapdb_set_synchronous (hds, True);
+ if (!ldapdb_search (hds, NULL, filter, NULL, LDAP_NO_LIMIT))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!ldapdb_count_entries (hds, &ngroups))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ grouplist = calloc (ngroups, sizeof (DOMAIN_GRP));
+ if (grouplist == NULL)
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+ *num_grps = 0;
+
+ for (i = 0; i < ngroups; i++)
+ {
+ if (nt5ldap_make_domain_grp (hds, &grouplist[*num_grps], NULL, NULL))
+ {
+ (*num_grps)++;
+ }
+ if (!ldapdb_seq (hds))
+ {
+ break;
+ }
+ }
+
+ ldapdb_close (&hds);
+
+ *groups = grouplist;
+
+ return True;
+}
+
+static struct groupdb_ops nt5ldapgroup_ops =
+{
+ nt5ldapgroup_enumfirst,
+ nt5ldapgroup_enumclose,
+ nt5ldapgroup_getdbpos,
+ nt5ldapgroup_setdbpos,
+
+ nt5ldapgroup_getgrpbynam,
+ nt5ldapgroup_getgrpbygid,
+ nt5ldapgroup_getgrpbyrid,
+ nt5ldapgroup_getcurrentgrp,
+
+ nt5ldapgroup_addgrp,
+ nt5ldapgroup_modgrp,
+ nt5ldapgroup_delgrp,
+
+ nt5ldapgroup_addmem,
+ nt5ldapgroup_delmem,
+
+ nt5ldapgroup_getusergroups
+};
+
+struct groupdb_ops *
+nt5ldap_initialise_group_db (void)
+{
+ return &nt5ldapgroup_ops;
+}
+
+#else
+void groupnt5ldap_dummy_function (void);
+void
+groupnt5ldap_dummy_function (void)
+{
+} /* stop some compilers complaining */
+#endif
diff --git a/source/groupdb/groupunix.c b/source/groupdb/groupunix.c
new file mode 100644
index 00000000000..e4e21dbc696
--- /dev/null
+++ b/source/groupdb/groupunix.c
@@ -0,0 +1,338 @@
+/*
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "sids.h"
+
+#ifdef USE_SMBUNIX_DB
+
+extern int DEBUGLEVEL;
+
+
+/***************************************************************
+ Start to enumerate the grppasswd list. Returns a void pointer
+ to ensure no modification outside this module.
+****************************************************************/
+
+struct unix_entries
+{
+ struct group *grps;
+ int num_grps;
+ int grp_idx;
+};
+
+static void *startgrpunixpwent(BOOL update)
+{
+ struct unix_entries *grps;
+ grps = (struct unix_entries*)malloc(sizeof(struct unix_entries));
+
+ if (grps == NULL)
+ {
+ return NULL;
+ }
+
+ if (!get_unix_grps(&grps->num_grps, &grps->grps))
+ {
+ free(grps);
+ return NULL;
+ }
+
+ grps->grp_idx = 0;
+
+ return (void*)grps;
+}
+
+/***************************************************************
+ End enumeration of the grppasswd list.
+****************************************************************/
+
+static void endgrpunixpwent(void *vp)
+{
+ struct unix_entries *grps = (struct unix_entries *)vp;
+
+ if (grps != NULL)
+ {
+ free_unix_grps(grps->num_grps, grps->grps);
+ free(vp);
+ }
+}
+
+/*************************************************************************
+ Return the current position in the grppasswd list as an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+static SMB_BIG_UINT getgrpunixpwpos(void *vp)
+{
+ return (SMB_BIG_UINT)0;
+}
+
+/*************************************************************************
+ Set the current position in the grppasswd list from an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+static BOOL setgrpunixpwpos(void *vp, SMB_BIG_UINT tok)
+{
+ return False;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smbdomaingroup list.
+ *************************************************************************/
+BOOL get_unixgroup_members(struct group *grp,
+ int *num_mem, DOMAIN_GRP_MEMBER **members)
+{
+ int i;
+ char *unix_name;
+
+ if (num_mem == NULL || members == NULL)
+ {
+ return False;
+ }
+
+ (*num_mem) = 0;
+ (*members) = NULL;
+
+ for (i = 0; (unix_name = grp->gr_mem[i]) != NULL; i++)
+ {
+ DOM_NAME_MAP gmep;
+ DOMAIN_GRP_MEMBER *mem;
+ uint32 rid;
+
+ if (!lookupsmbpwnam (unix_name, &gmep) &&
+ !lookupsmbgrpnam(unix_name, &gmep))
+ {
+ continue;
+ }
+
+ if (gmep.type != SID_NAME_DOM_GRP &&
+ gmep.type != SID_NAME_USER &&
+ gmep.type != SID_NAME_WKN_GRP)
+ {
+ DEBUG(0,("group database: name %s is not in a Domain Group\n",
+ unix_name));
+ continue;
+ }
+
+ sid_split_rid(&gmep.sid, &rid);
+ if (!sid_equal(&global_sam_sid, &gmep.sid))
+ {
+ DEBUG(0,("group database: could not resolve name %s (wrong Domain SID)\n",
+ unix_name));
+ continue;
+ }
+
+ (*members) = Realloc((*members), ((*num_mem)+1) * sizeof(DOMAIN_GRP_MEMBER));
+ if ((*members) == NULL)
+ {
+ return False;
+ }
+
+ mem = &(*members)[(*num_mem)];
+ (*num_mem)++;
+
+ fstrcpy(mem->name, gmep.nt_name);
+ mem->attr = 0x07;
+ mem->sid_use = gmep.type;
+ mem->rid = rid;
+ }
+ return True;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the domain group list.
+
+ if we are not a PDC or BDC, then we do NOT support Domain groups, only
+ aliases. try running MUSRMGR.EXE or running USRMGR.EXE selected on a
+ workstation, you will find that no Domain groups are listed: only aliases.
+
+ so, as a PDC or BDC, all unix groups not explicitly mapped using
+ map_group_gid() are treated as Domain groups.
+
+ *************************************************************************/
+static DOMAIN_GRP *getgrpunixpwent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem)
+{
+ /* Static buffers we will return. */
+ static DOMAIN_GRP gp_buf;
+ struct group unix_grp;
+ struct unix_entries *grps = (struct unix_entries *)vp;
+
+ if (grps == NULL)
+ {
+ return NULL;
+ }
+
+ if (lp_server_role() == ROLE_DOMAIN_NONE ||
+ lp_server_role() == ROLE_DOMAIN_MEMBER)
+ {
+ /*
+ * only PDC and BDC have domain groups in the SAM.
+ * (however as member of domain you can have LOCAL groups,
+ * but that's dealt with in the aliasdb...)
+ */
+
+ return NULL;
+ }
+
+ gpdb_init_grp(&gp_buf);
+
+ fstrcpy(gp_buf.comment, "");
+ gp_buf.attr = 0x07;
+
+ /* get array of unix names + gids. this function does NOT
+ get a copy of the unix group members
+ */
+
+ /* cycle through unix groups */
+ for (; grps->grp_idx < grps->num_grps; grps->grp_idx++)
+ {
+ DOM_NAME_MAP gmep;
+
+ memcpy(&unix_grp, &grps->grps[grps->grp_idx], sizeof(unix_grp));
+
+ DEBUG(10,("getgrpunixpwent: enum unix group entry %s\n",
+ unix_grp.gr_name));
+
+ if (!lookupsmbgrpgid(unix_grp.gr_gid, &gmep))
+ {
+ continue;
+ }
+
+ if (gmep.type != SID_NAME_DOM_GRP &&
+ gmep.type != SID_NAME_WKN_GRP)
+ {
+ continue;
+ }
+
+ sid_split_rid(&gmep.sid, &gp_buf.rid);
+ if (!sid_equal(&gmep.sid, &global_sam_sid))
+ {
+ continue;
+ }
+
+ fstrcpy(gp_buf.name, gmep.nt_name);
+ break;
+ }
+
+ if (grps->grp_idx >= grps->num_grps)
+ {
+ return NULL;
+ }
+
+ /* get the user's domain groups. there are a maximum of 32 */
+
+ if (mem != NULL && num_mem != NULL)
+ {
+ (*mem) = NULL;
+ (*num_mem) = 0;
+
+ memcpy(&unix_grp, getgrgid(unix_grp.gr_gid), sizeof(unix_grp));
+ get_unixgroup_members(&unix_grp, num_mem, mem);
+ }
+
+ {
+ pstring linebuf;
+ make_group_line(linebuf, sizeof(linebuf), &gp_buf, mem, num_mem);
+ DEBUG(10,("line: '%s'\n", linebuf));
+ }
+
+ grps->grp_idx++; /* advance so next enum gets next entry */
+ return &gp_buf;
+}
+
+/************************************************************************
+ Routine to add an entry to the grppasswd file.
+*************************************************************************/
+
+static BOOL add_grpunixgrp_entry(DOMAIN_GRP *newgrp)
+{
+ DEBUG(0, ("add_grpunixgrp_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to search database for entry matching the groupname and/or rid.
+ and then modify its group entry.
+************************************************************************/
+
+static BOOL mod_grpunixgrp_entry(DOMAIN_GRP* grp)
+{
+ DEBUG(0, ("mod_grpunixgrp_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to search the grppasswd file for an entry matching the rid.
+ and then delete it.
+************************************************************************/
+
+static BOOL del_grpunixgrp_entry(uint32 rid)
+{
+ DEBUG(0, ("del_grpunixgrp_entry: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to add a member to an entry to the grppasswd file.
+*************************************************************************/
+static BOOL add_grpunixgrp_member(uint32 rid, uint32 member_rid)
+{
+ DEBUG(0, ("add_grpunixgrp_member: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+/************************************************************************
+ Routine to delete a member from an entry to the grppasswd file.
+*************************************************************************/
+static BOOL del_grpunixgrp_member(uint32 rid, uint32 member_rid)
+{
+ DEBUG(0, ("del_grpunixgrp_member: NOT IMPLEMENTED\n"));
+ return False;
+}
+
+static struct groupdb_ops unix_ops =
+{
+ startgrpunixpwent,
+ endgrpunixpwent,
+ getgrpunixpwpos,
+ setgrpunixpwpos,
+
+ iterate_getgroupntnam, /* In groupdb.c */
+ iterate_getgroupgid, /* In groupdb.c */
+ iterate_getgrouprid, /* In groupdb.c */
+ getgrpunixpwent,
+
+ add_grpunixgrp_entry,
+ mod_grpunixgrp_entry,
+ del_grpunixgrp_entry,
+
+ add_grpunixgrp_member,
+ del_grpunixgrp_member,
+
+ iterate_getusergroupsnam /* in groupdb.c */
+};
+
+struct groupdb_ops *unix_initialise_group_db(void)
+{
+ return &unix_ops;
+}
+
+#else
+ /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
+ void unix_grppass_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* USE_SMBPASS_DB */
diff --git a/source/include/DesktopDB.h b/source/include/DesktopDB.h
new file mode 100644
index 00000000000..c0efa2b4a46
--- /dev/null
+++ b/source/include/DesktopDB.h
@@ -0,0 +1,32 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ service (connection) opening and closing
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#define DESKTOPDB_FOLDER "./.streams/.DesktopDBFolder/"
+#define DESKTOPDB_DF_PATH "./.streams/.DesktopDBFolder/DesktopDF"
+#define THE_ZERO_DB_ENTRY "ZERO_DB"
+
+typedef struct IconKey
+{
+ uint32 ftype; /* The file type */
+ uint32 isize; /* Size of the Icon */
+ uint16 itype; /* Icon Type */
+} IconKey;
diff --git a/source/include/byteorder.h b/source/include/byteorder.h
index 59ae4979fde..8fff630a98e 100644
--- a/source/include/byteorder.h
+++ b/source/include/byteorder.h
@@ -160,26 +160,31 @@ it also defines lots of intermediate macros, just ignore those :-)
*/
/* get single value from an SMB buffer */
-#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
-#define IVAL(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
-#define SVALS(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
-#define IVALS(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
+#define SVAL(buf,pos) (*(const uint16 *)((const char *)(buf) + (pos)))
+#define IVAL(buf,pos) (*(const uint32 *)((const char *)(buf) + (pos)))
+#define SVALS(buf,pos) (*(const int16 *)((const char *)(buf) + (pos)))
+#define IVALS(buf,pos) (*(const int32 *)((const char *)(buf) + (pos)))
/* store single value in an SMB buffer */
-#define SSVAL(buf,pos,val) SVAL(buf,pos)=((uint16)(val))
-#define SIVAL(buf,pos,val) IVAL(buf,pos)=((uint32)(val))
-#define SSVALS(buf,pos,val) SVALS(buf,pos)=((int16)(val))
-#define SIVALS(buf,pos,val) IVALS(buf,pos)=((int32)(val))
+#define SVALMOD(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
+#define IVALMOD(buf,pos) (*(uint32 *)((char *)(buf) + (pos)))
+#define SVALSMOD(buf,pos) (*(int16 *)((char *)(buf) + (pos)))
+#define IVALSMOD(buf,pos) (*(int32 *)((char *)(buf) + (pos)))
+
+#define SSVAL(buf,pos,val) SVALMOD(buf,pos)=((uint16)(val))
+#define SIVAL(buf,pos,val) IVALMOD(buf,pos)=((uint32)(val))
+#define SSVALS(buf,pos,val) SVALSMOD(buf,pos)=((int16)(val))
+#define SIVALS(buf,pos,val) IVALSMOD(buf,pos)=((int32)(val))
#endif /* CAREFUL_ALIGNMENT */
/* macros for reading / writing arrays */
#define SMBMACRO(macro,buf,pos,val,len,size) \
-{ int l; for (l = 0; l < (len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
+{ uint32 l; for (l = 0; l < (uint32)(len); l++) (val)[l] = macro((buf), (pos) + (size)*l); }
#define SSMBMACRO(macro,buf,pos,val,len,size) \
-{ int l; for (l = 0; l < (len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
+{ uint32 l; for (l = 0; l < (uint32)(len); l++) macro((buf), (pos) + (size)*l, (val)[l]); }
/* reads multiple data from an SMB buffer */
#define PCVAL(buf,pos,val,len) SMBMACRO(CVAL,buf,pos,val,len,1)
@@ -228,7 +233,7 @@ it also defines lots of intermediate macros, just ignore those :-)
DEBUG(5,("%s%04x %s: ", \
tab_depth(depth), base,string)); \
if (charmode) print_asc(5, (unsigned char*)(outbuf), (len)); else \
- { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (outbuf)[idx])); } } \
+ { uint32 idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (outbuf)[idx])); } } \
DEBUG(5,("\n")); }
#define DBG_RW_PSVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
@@ -236,7 +241,7 @@ it also defines lots of intermediate macros, just ignore those :-)
DEBUG(5,("%s%04x %s: ", \
tab_depth(depth), base,string)); \
if (charmode) print_asc(5, (unsigned char*)(outbuf), 2*(len)); else \
- { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (outbuf)[idx])); } } \
+ { uint32 idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (outbuf)[idx])); } } \
DEBUG(5,("\n")); }
#define DBG_RW_PIVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \
@@ -244,7 +249,7 @@ it also defines lots of intermediate macros, just ignore those :-)
DEBUG(5,("%s%04x %s: ", \
tab_depth(depth), base,string)); \
if (charmode) print_asc(5, (unsigned char*)(outbuf), 4*(len)); else \
- { int idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (outbuf)[idx])); } } \
+ { uint32 idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (outbuf)[idx])); } } \
DEBUG(5,("\n")); }
#define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \
diff --git a/source/include/charset.h b/source/include/charset.h
index 7c6fbe5509b..b6f79c03dde 100644
--- a/source/include/charset.h
+++ b/source/include/charset.h
@@ -1,6 +1,3 @@
-#ifndef _CHARSET_H
-#define _CHARSET_H
-
/*
Unix SMB/Netbios implementation.
Version 1.9.
@@ -76,16 +73,3 @@ extern void charset_initialise(void);
#define CODEPAGE_VERSION_OFFSET 0
#define CODEPAGE_CLIENT_CODEPAGE_OFFSET 2
#define CODEPAGE_LENGTH_OFFSET 4
-
-/* Version id for dynamically loadable unicode map files. */
-#define UNICODE_MAP_FILE_VERSION_ID 0x8001
-/* Version 0x80000001 unicode map file header size. */
-#define UNICODE_MAP_HEADER_SIZE 30
-#define UNICODE_MAP_CODEPAGE_ID_SIZE 20
-/* Offsets for unicode map file header entries. */
-#define UNICODE_MAP_VERSION_OFFSET 0
-#define UNICODE_MAP_CLIENT_CODEPAGE_OFFSET 2
-#define UNICODE_MAP_CP_TO_UNICODE_LENGTH_OFFSET 22
-#define UNICODE_MAP_UNICODE_TO_CP_LENGTH_OFFSET 26
-
-#endif /* _CHARSET_H */
diff --git a/source/include/client.h b/source/include/client.h
index 2a780ece26a..88e882f9429 100644
--- a/source/include/client.h
+++ b/source/include/client.h
@@ -27,7 +27,7 @@
/* the client asks for a smaller buffer to save ram and also to get more
overlap on the wire. This size gives us a nice read/write size, which
will be a multiple of the page size on almost any system */
-#define CLI_BUFFER_SIZE (0xFFFF)
+#define CLI_BUFFER_SIZE (0x4400)
/*
* These definitions depend on smb.h
@@ -44,7 +44,8 @@ typedef struct file_info
time_t atime;
time_t ctime;
pstring name;
-} file_info;
+}
+file_info;
struct print_job_info
{
@@ -56,7 +57,8 @@ struct print_job_info
time_t t;
};
-struct cli_state {
+struct cli_state
+{
int port;
int fd;
uint16 cnum;
@@ -68,10 +70,11 @@ struct cli_state {
int rap_error;
int privileges;
+ struct ntuser_creds usr;
+ BOOL retry;
+
fstring eff_name;
fstring desthost;
- fstring user_name;
- fstring domain;
/*
* The following strings are the
@@ -86,17 +89,23 @@ struct cli_state {
fstring dev;
struct nmb_name called;
struct nmb_name calling;
- fstring full_dest_host_name;
struct in_addr dest_ip;
- struct pwd_info pwd;
unsigned char cryptkey[8];
+ unsigned char lm_cli_chal[8];
+ unsigned char nt_cli_chal[128];
+ size_t nt_cli_chal_len;
+
+ BOOL use_ntlmv2;
+ BOOL redirect;
+ BOOL reuse;
+
uint32 sesskey;
int serverzone;
uint32 servertime;
int readbraw_supported;
int writebraw_supported;
- int timeout; /* in milliseconds. */
+ int timeout;
int max_xmit;
int max_mux;
char *outbuf;
@@ -106,25 +115,11 @@ struct cli_state {
int win95;
uint32 capabilities;
- /*
- * Only used in NT domain calls.
- */
+ struct ntdom_info nt;
- uint32 nt_error; /* NT RPC error code. */
- uint16 nt_pipe_fnum; /* Pipe handle. */
- unsigned char sess_key[16]; /* Current session key. */
- unsigned char ntlmssp_hash[258]; /* ntlmssp data. */
- uint32 ntlmssp_cli_flgs; /* ntlmssp client flags */
- uint32 ntlmssp_srv_flgs; /* ntlmssp server flags */
- uint32 ntlmssp_seq_num; /* ntlmssp sequence number */
- DOM_CRED clnt_cred; /* Client credential. */
- fstring mach_acct; /* MYNAME$. */
- fstring srv_name_slash; /* \\remote server. */
- fstring clnt_name_slash; /* \\local client. */
- uint16 max_xmit_frag;
- uint16 max_recv_frag;
-
- BOOL use_oplocks; /* should we use oplocks? */
+ uint32 nt_error; /* NT RPC error code. */
};
+struct cli_connection;
+
#endif /* _CLIENT_H */
diff --git a/source/include/config.h.in b/source/include/config.h.in
index 0b3872e7ced..6c417f6f193 100644
--- a/source/include/config.h.in
+++ b/source/include/config.h.in
@@ -18,9 +18,6 @@
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
-/* Define if your system has a working fnmatch function. */
-#undef HAVE_FNMATCH
-
/* Define if you have a working `mmap' system call. */
#undef HAVE_MMAP
@@ -36,9 +33,6 @@
/* Define to `int' if <sys/types.h> doesn't define. */
#undef mode_t
-/* Define if your C compiler doesn't accept -c and -o together. */
-#undef NO_MINUS_C_MINUS_O
-
/* Define to `long' if <sys/types.h> doesn't define. */
#undef off_t
@@ -64,7 +58,6 @@
byte first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
-#undef HAVE_VOLATILE
#undef HAVE_BROKEN_READDIR
#undef HAVE_ERRNO_DECL
#undef HAVE_LONGLONG
@@ -72,14 +65,12 @@
#undef HAVE_REMSH
#undef HAVE_UNSIGNED_CHAR
#undef HAVE_UTIMBUF
-#undef HAVE_SIG_ATOMIC_T_TYPE
#undef ssize_t
#undef ino_t
#undef ssize_t
#undef loff_t
#undef offset_t
#undef aclent_t
-#undef wchar_t
#undef HAVE_CONNECT
#undef HAVE_SHORT_INO_T
#undef WITH_SMBWRAPPER
@@ -91,22 +82,19 @@
#undef AIX
#undef BSD
#undef IRIX
-#undef IRIX6
#undef HPUX
#undef QNX
#undef SCO
#undef OSF1
#undef NEXT2
-#undef RELIANTUNIX
#undef HAVE_SHARED_MMAP
-#undef HAVE_MMAP
#undef HAVE_SYSV_IPC
#undef HAVE_FCNTL_LOCK
#undef HAVE_FTRUNCATE_EXTEND
-#undef FTRUNCATE_NEEDS_ROOT
#undef HAVE_TRAPDOOR_UID
#undef HAVE_ROOT
#undef HAVE_UNION_SEMUN
+#undef HAVE_NETMASK_IFCONF
#undef HAVE_GETTIMEOFDAY_TZ
#undef HAVE_SOCK_SIN_LEN
#undef STAT_READ_FILSYS
@@ -117,36 +105,38 @@
#undef STAT_STATFS4
#undef STAT_STATVFS
#undef STAT_STATVFS64
-#undef HAVE_IFACE_AIX
-#undef HAVE_IFACE_IFCONF
-#undef HAVE_IFACE_IFREQ
+#undef HAVE_NETMASK_IFREQ
+#undef HAVE_NETMASK_AIX
#undef HAVE_CRYPT
#undef HAVE_PUTPRPWNAM
#undef HAVE_SET_AUTH_PARAMETERS
+#undef WITH_MMAP
#undef WITH_SYSLOG
#undef WITH_PROFILE
#undef WITH_SSL
#undef WITH_LDAP
+#undef WITH_TDBSURS
#undef WITH_NISPLUS
-#undef WITH_PAM
#undef WITH_NISPLUS_HOME
#undef WITH_AUTOMOUNT
#undef WITH_SMBMOUNT
+#undef HAVE_PAM_AUTHENTICATE
#undef HAVE_BROKEN_GETGROUPS
#undef REPLACE_GETPASS
#undef REPLACE_INET_NTOA
#undef HAVE_FILE_MACRO
#undef HAVE_FUNCTION_MACRO
#undef HAVE_SETRESUID_DECL
+#undef HAVE_CRYPT_DECL
#undef HAVE_SETRESUID
#undef WITH_NETATALK
-#undef WITH_UTMP
#undef HAVE_INO64_T
#undef HAVE_STRUCT_FLOCK64
#undef SIZEOF_INO_T
#undef SIZEOF_OFF_T
#undef STAT_STATVFS64
#undef HAVE_LIBREADLINE
+#undef HAVE_READLINE_FCF_PROTO
#undef HAVE_KERNEL_OPLOCKS
#undef HAVE_IRIX_SPECIFIC_CAPABILITIES
#undef HAVE_INT16_FROM_RPC_RPC_H
@@ -154,35 +144,26 @@
#undef HAVE_INT32_FROM_RPC_RPC_H
#undef HAVE_UINT32_FROM_RPC_RPC_H
#undef KRB4_AUTH
-#undef KRB5_AUTH
#undef SEEKDIR_RETURNS_VOID
#undef HAVE_DIRENT_D_OFF
#undef HAVE_GETSPNAM
#undef HAVE_BIGCRYPT
#undef HAVE_GETPRPWNAM
-#undef HAVE_FSTAT64
-#undef HAVE_LSTAT64
-#undef HAVE_STAT64
-#undef HAVE_SETRESGID
-#undef HAVE_SETRESGID_DECL
-#undef HAVE_SHADOW_H
-#undef HAVE_MEMSET
-#undef HAVE_STRCASECMP
-#undef HAVE_STRUCT_DIRENT64
-#undef HAVE_TRUNCATED_SALT
-#undef BROKEN_NISPLUS_INCLUDE_FILES
-#undef HAVE_RPC_AUTH_ERROR_CONFLICT
-#undef HAVE_EXPLICIT_LARGEFILE_SUPPORT
-#undef USE_BOTH_CRYPT_CALLS
-#undef HAVE_BROKEN_FCNTL64_LOCKS
-#undef HAVE_FNMATCH
+
+#undef WITH_LIBMSRPC
+#undef WITH_LIBNMB
+#undef WITH_LIBSAMBA
+#undef WITH_LIBSMB
+#undef WITH_LIBSURS
+#undef WITH_LIBSMBPW
+#undef WITH_LIBUBIQX
+
#undef USE_SETEUID
#undef USE_SETRESUID
#undef USE_SETREUID
#undef USE_SETUIDX
-#undef HAVE_LIBDL
-#undef NEED_SGI_SEMUN_HACK
-#undef SYSCONF_SC_NGROUPS_MAX
+
+#undef WITH_NT5LDAP
/* The number of bytes in a int. */
#undef SIZEOF_INT
@@ -442,21 +423,12 @@
/* Define if you have the execl function. */
#undef HAVE_EXECL
-/* Define if you have the fcvt function. */
-#undef HAVE_FCVT
-
-/* Define if you have the fcvtl function. */
-#undef HAVE_FCVTL
-
/* Define if you have the fopen64 function. */
#undef HAVE_FOPEN64
/* Define if you have the fseek64 function. */
#undef HAVE_FSEEK64
-/* Define if you have the fseeko64 function. */
-#undef HAVE_FSEEKO64
-
/* Define if you have the fstat function. */
#undef HAVE_FSTAT
@@ -469,9 +441,6 @@
/* Define if you have the ftell64 function. */
#undef HAVE_FTELL64
-/* Define if you have the ftello64 function. */
-#undef HAVE_FTELLO64
-
/* Define if you have the ftruncate function. */
#undef HAVE_FTRUNCATE
@@ -487,9 +456,6 @@
/* Define if you have the getdents function. */
#undef HAVE_GETDENTS
-/* Define if you have the getgrent function. */
-#undef HAVE_GETGRENT
-
/* Define if you have the getgrnam function. */
#undef HAVE_GETGRNAM
@@ -544,6 +510,9 @@
/* Define if you have the open64 function. */
#undef HAVE_OPEN64
+/* Define if you have the pam_authenticate function. */
+#undef HAVE_PAM_AUTHENTICATE
+
/* Define if you have the pathconf function. */
#undef HAVE_PATHCONF
@@ -589,9 +558,6 @@
/* Define if you have the setenv function. */
#undef HAVE_SETENV
-/* Define if you have the setgidx function. */
-#undef HAVE_SETGIDX
-
/* Define if you have the setgroups function. */
#undef HAVE_SETGROUPS
@@ -601,9 +567,6 @@
/* Define if you have the setnetgrent function. */
#undef HAVE_SETNETGRENT
-/* Define if you have the setpriv function. */
-#undef HAVE_SETPRIV
-
/* Define if you have the setsid function. */
#undef HAVE_SETSID
@@ -631,9 +594,6 @@
/* Define if you have the stat64 function. */
#undef HAVE_STAT64
-/* Define if you have the strcasecmp function. */
-#undef HAVE_STRCASECMP
-
/* Define if you have the strchr function. */
#undef HAVE_STRCHR
@@ -655,11 +615,8 @@
/* Define if you have the syscall function. */
#undef HAVE_SYSCALL
-/* Define if you have the sysconf function. */
-#undef HAVE_SYSCONF
-
-/* Define if you have the usleep function. */
-#undef HAVE_USLEEP
+/* Define if you have the tputs function. */
+#undef HAVE_TPUTS
/* Define if you have the utime function. */
#undef HAVE_UTIME
@@ -676,9 +633,6 @@
/* Define if you have the yp_get_default_domain function. */
#undef HAVE_YP_GET_DEFAULT_DOMAIN
-/* Define if you have the <arpa/inet.h> header file. */
-#undef HAVE_ARPA_INET_H
-
/* Define if you have the <compat.h> header file. */
#undef HAVE_COMPAT_H
@@ -706,20 +660,17 @@
/* Define if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
+/* Define if you have the <mysql.h> header file. */
+#undef HAVE_MYSQL_H
+
/* Define if you have the <ndir.h> header file. */
#undef HAVE_NDIR_H
/* Define if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
-/* Define if you have the <netinet/in_ip.h> header file. */
-#undef HAVE_NETINET_IN_IP_H
-
-/* Define if you have the <netinet/in_systm.h> header file. */
-#undef HAVE_NETINET_IN_SYSTM_H
-
-/* Define if you have the <netinet/ip.h> header file. */
-#undef HAVE_NETINET_IP_H
+/* Define if you have the <net/route.h> header file. */
+#undef HAVE_NET_ROUTE_H
/* Define if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H
@@ -739,9 +690,6 @@
/* Define if you have the <rpc/rpc.h> header file. */
#undef HAVE_RPC_RPC_H
-/* Define if you have the <rpcsvc/nis.h> header file. */
-#undef HAVE_RPCSVC_NIS_H
-
/* Define if you have the <rpcsvc/yp_prot.h> header file. */
#undef HAVE_RPCSVC_YP_PROT_H
@@ -817,9 +765,6 @@
/* Define if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
-/* Define if you have the <sys/priv.h> header file. */
-#undef HAVE_SYS_PRIV_H
-
/* Define if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
@@ -844,9 +789,6 @@
/* Define if you have the <sys/syscall.h> header file. */
#undef HAVE_SYS_SYSCALL_H
-/* Define if you have the <sys/termio.h> header file. */
-#undef HAVE_SYS_TERMIO_H
-
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
@@ -865,9 +807,6 @@
/* Define if you have the <syscall.h> header file. */
#undef HAVE_SYSCALL_H
-/* Define if you have the <termio.h> header file. */
-#undef HAVE_TERMIO_H
-
/* Define if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
@@ -877,17 +816,8 @@
/* Define if you have the <utime.h> header file. */
#undef HAVE_UTIME_H
-/* Define if you have the <utmp.h> header file. */
-#undef HAVE_UTMP_H
-
-/* Define if you have the <utmpx.h> header file. */
-#undef HAVE_UTMPX_H
-
-/* Define if you have the cups library (-lcups). */
-#undef HAVE_LIBCUPS
-
-/* Define if you have the gen library (-lgen). */
-#undef HAVE_LIBGEN
+/* Define if you have the dl library (-ldl). */
+#undef HAVE_LIBDL
/* Define if you have the inet library (-linet). */
#undef HAVE_LIBINET
diff --git a/source/include/debug.h b/source/include/debug.h
index c6ddf615253..df74da0b415 100644
--- a/source/include/debug.h
+++ b/source/include/debug.h
@@ -96,6 +96,24 @@ BOOL dbgtext();
#define DEBUGADD( level, body ) \
(void)( (DEBUGLEVEL >= (level)) && (dbgtext body) )
+/* -------------------------------------------------------------------------- **
+ * These are the tokens returned by dbg_char2token().
+ */
+
+typedef enum
+ {
+ dbg_null = 0,
+ dbg_ignore,
+ dbg_header,
+ dbg_timestamp,
+ dbg_level,
+ dbg_sourcefile,
+ dbg_function,
+ dbg_lineno,
+ dbg_message,
+ dbg_eof
+ } dbg_Token;
+
/* End Debugging code section.
* -------------------------------------------------------------------------- **
*/
diff --git a/source/include/dfs.h b/source/include/dfs.h
new file mode 100644
index 00000000000..1bf26e230b1
--- /dev/null
+++ b/source/include/dfs.h
@@ -0,0 +1,53 @@
+
+typedef struct _referal_trans_param
+{
+ uint16 level;
+ char directory[255];
+ uint16 type;
+} referal_trans_param;
+
+typedef struct _referal_ver_2
+{
+ uint16 version;
+ uint16 size;
+ uint16 server_type;
+ uint16 flags;
+ uint32 proximity;
+ uint32 ttl;
+ uint16 filename_offset;
+ uint16 mangledname_offset;
+ uint16 sharename_offset;
+ char sharename[255];
+} referal_ver_2;
+
+typedef struct _dfs_response
+{
+ uint16 path_consumed;
+ uint16 number_of_referal;
+ uint32 server_function;
+ referal_ver_2 *referal;
+ char filename[255];
+ char mangledname[255];
+ struct _dfs_response *next;
+} dfs_response;
+
+
+typedef struct _dfs_internal_table
+{
+ pstring localpath;
+ pstring mangledpath;
+ pstring sharename;
+ unsigned int proximity;
+ unsigned int type;
+ int localpath_length;
+ int mangledpath_length;
+ int sharename_length;
+} dfs_internal_table;
+
+typedef struct _dfs_internal
+{
+
+ dfs_internal_table *table;
+ int size;
+ BOOL ready;
+} dfs_internal;
diff --git a/source/include/hmacmd5.h b/source/include/hmacmd5.h
new file mode 100644
index 00000000000..adb52058a89
--- /dev/null
+++ b/source/include/hmacmd5.h
@@ -0,0 +1,33 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Interface header: Scheduler service
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+ Copyright (C) Andrew Tridgell 1992-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _HMAC_MD5_H
+
+typedef struct
+{
+ struct MD5Context ctx;
+ uchar k_ipad[65];
+ uchar k_opad[65];
+
+} HMACMD5Context;
+
+#endif /* _HMAC_MD5_H */
diff --git a/source/include/includes.h b/source/include/includes.h
index 1929df3b7d0..2f1413bf2f6 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -45,34 +45,15 @@
#undef HAVE_TERMIOS_H
#endif
-#ifdef LINUX
-#define DEFAULT_PRINTING PRINT_BSD
-#define PRINTCAP_NAME "/etc/printcap"
-#endif
-#ifdef RELIANTUNIX
-/*
- * <unistd.h> has to be included before any other to get
- * large file support on Reliant UNIX
- */
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
+/* if we have both SYSV IPC and shared mmap then we need to
+ choose. For most systems it is much faster to use SYSV IPC. We used
+ to make an exception for Linux, but now Linux 2.2 has made it
+ better to use sysv if possible */
+#if (defined(HAVE_SYSV_IPC) && defined(HAVE_SHARED_MMAP))
+# undef HAVE_SHARED_MMAP
#endif
-#endif /* RELIANTUNIX */
-
-#ifdef HAVE_SYSV_IPC
-#define USE_SYSV_IPC
-#endif
-
-#ifdef HAVE_SHARED_MMAP
-#define USE_SHARED_MMAP
-#endif
-
-/* if we have both SYSV IPC and shared mmap then we need to choose */
-#if (defined(USE_SYSV_IPC) && defined(USE_SHARED_MMAP))
-# undef USE_SHARED_MMAP
-#endif
#include <sys/types.h>
@@ -98,6 +79,11 @@
#include <stdio.h>
#include <stddef.h>
+#include <netinet/in.h>
+#if defined(HAVE_RPC_RPC_H)
+#include <rpc/rpc.h>
+#endif
+
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
@@ -132,9 +118,13 @@
#include <memory.h>
#endif
+#ifdef MEM_MAN
+#include "../mem_man/mem_man.h"
+#else
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
+#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
@@ -169,9 +159,6 @@
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
-#ifdef HAVE_SYS_PRIV_H
-#include <sys/priv.h>
-#endif
#ifdef HAVE_SYS_ID_H
#include <sys/id.h>
#endif
@@ -198,6 +185,7 @@
#endif
#include <pwd.h>
+#include <grp.h>
#ifdef HAVE_STDARG_H
#include <stdarg.h>
@@ -205,7 +193,6 @@
#include <varargs.h>
#endif
-#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <syslog.h>
@@ -215,32 +202,8 @@
#include <netinet/tcp.h>
#endif
-/*
- * The next three defines are needed to access the IPTOS_* options
- * on some systems.
- */
-
-#ifdef HAVE_NETINET_IN_SYSTM_H
-#include <netinet/in_systm.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_IP_H
-#include <netinet/in_ip.h>
-#endif
-
-#ifdef HAVE_NETINET_IP_H
-#include <netinet/ip.h>
-#endif
-
-#if defined(HAVE_TERMIOS_H)
-/* POSIX terminal handling. */
+#ifdef HAVE_TERMIOS_H
#include <termios.h>
-#elif defined(HAVE_TERMIO_H)
-/* Older SYSV terminal handling - don't use if we can avoid it. */
-#include <termio.h>
-#elif defined(HAVE_SYS_TERMIO_H)
-/* Older SYSV terminal handling - don't use if we can avoid it. */
-#include <sys/termio.h>
#endif
#if HAVE_DIRENT_H
@@ -268,24 +231,18 @@
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
+#endif
+#if 0
/*
- * The following is needed if compiling
- * with gcc on SGI IRIX 6.5.x systems as
- * the structure packing for system calls is
- * different between IRIX cc and gcc.
- */
-
-#ifdef NEED_SGI_SEMUN_HACK
-union semun_hack {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- char __dummy[5];
-};
-#define semun semun_hack
-#endif /* NEED_SGI_SEMUN_HACK */
-#endif /* HAVE_SYSV_IPC */
+ * I have removed this as it prevents compilation under SCO Server
+ * 3.2. If you need to add it back in then please add a comment as to
+ * why it's needed and what OS it's needed for so we can work out how
+ * to test for it properly (tridge) */
+#ifdef HAVE_NET_ROUTE_H
+#include <net/route.h>
+#endif
+#endif
#ifdef HAVE_NET_IF_H
#include <net/if.h>
@@ -357,12 +314,6 @@ union semun_hack {
#endif
#if defined(HAVE_RPC_RPC_H)
-/*
- * Check for AUTH_ERROR define conflict with rpc/rpc.h in prot.h.
- */
-#if defined(HAVE_SYS_SECURITY_H) && defined(HAVE_RPC_AUTH_ERROR_CONFLICT)
-#undef AUTH_ERROR
-#endif
#include <rpc/rpc.h>
#endif
@@ -379,24 +330,19 @@ union semun_hack {
#endif
#endif /* HAVE_NETGROUP */
-/*
- * Define VOLATILE if needed.
- */
-
-#if defined(HAVE_VOLATILE)
-#define VOLATILE volatile
+#if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
+#include <lber.h>
+#include <ldap.h>
#else
-#define VOLATILE
+#define LDAPMod void
#endif
-/*
- * Define SIG_ATOMIC_T if needed.
- */
-
-#if defined(HAVE_SIG_ATOMIC_T_TYPE)
-#define SIG_ATOMIC_T sig_atomic_t
+#if defined(HAVE_MYSQL_H)
+#include <mysql.h>
#else
-#define SIG_ATOMIC_T int
+/* needed to get make proto to work with no <mysql.h> */
+#define MYSQL void
+#define MYSQL_ROW void
#endif
#ifndef uchar
@@ -481,7 +427,7 @@ union semun_hack {
*/
#ifndef SMB_INO_T
-# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_INO64_T)
+# ifdef HAVE_INO64_T
# define SMB_INO_T ino64_t
# else
# define SMB_INO_T ino_t
@@ -489,7 +435,7 @@ union semun_hack {
#endif
#ifndef LARGE_SMB_INO_T
-# if (defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_INO64_T)) || (defined(SIZEOF_INO_T) && (SIZEOF_INO_T == 8))
+# if defined(HAVE_INO64_T) || (defined(SIZEOF_INO_T) && (SIZEOF_INO_T == 8))
# define LARGE_SMB_INO_T 1
# endif
#endif
@@ -501,16 +447,13 @@ union semun_hack {
#endif
#ifndef SMB_OFF_T
-# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T)
+# ifdef HAVE_OFF64_T
# define SMB_OFF_T off64_t
# else
# define SMB_OFF_T off_t
# endif
#endif
-/* this should really be a 64 bit type if possible */
-#define br_off SMB_BIG_UINT
-
#define SMB_OFF_T_BITS (sizeof(SMB_OFF_T)*8)
/*
@@ -519,7 +462,7 @@ union semun_hack {
*/
#ifndef LARGE_SMB_OFF_T
-# if (defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T)) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8))
+# if defined(HAVE_OFF64_T) || (defined(SIZEOF_OFF_T) && (SIZEOF_OFF_T == 8))
# define LARGE_SMB_OFF_T 1
# endif
#endif
@@ -535,7 +478,7 @@ union semun_hack {
*/
#ifndef SMB_STRUCT_STAT
-# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STAT64) && defined(HAVE_OFF64_T)
+# if defined(HAVE_STAT64) && defined(HAVE_OFF64_T)
# define SMB_STRUCT_STAT struct stat64
# else
# define SMB_STRUCT_STAT struct stat
@@ -543,23 +486,11 @@ union semun_hack {
#endif
/*
- * Type for dirent structure.
- */
-
-#ifndef SMB_STRUCT_DIRENT
-# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_DIRENT64)
-# define SMB_STRUCT_DIRENT struct dirent64
-# else
-# define SMB_STRUCT_DIRENT struct dirent
-# endif
-#endif
-
-/*
* Defines for 64 bit fcntl locks.
*/
#ifndef SMB_STRUCT_FLOCK
-# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+# if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
# define SMB_STRUCT_FLOCK struct flock64
# else
# define SMB_STRUCT_FLOCK struct flock
@@ -567,7 +498,7 @@ union semun_hack {
#endif
#ifndef SMB_F_SETLKW
-# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+# if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
# define SMB_F_SETLKW F_SETLKW64
# else
# define SMB_F_SETLKW F_SETLKW
@@ -575,7 +506,7 @@ union semun_hack {
#endif
#ifndef SMB_F_SETLK
-# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+# if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
# define SMB_F_SETLK F_SETLK64
# else
# define SMB_F_SETLK F_SETLK
@@ -583,7 +514,7 @@ union semun_hack {
#endif
#ifndef SMB_F_GETLK
-# if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
+# if defined(HAVE_STRUCT_FLOCK64) && defined(HAVE_OFF64_T)
# define SMB_F_GETLK F_GETLK64
# else
# define SMB_F_GETLK F_GETLK
@@ -593,11 +524,9 @@ union semun_hack {
#if defined(HAVE_LONGLONG)
#define SMB_BIG_UINT unsigned long long
#define SMB_BIG_INT long long
-#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,(v)>>32))
#else
#define SMB_BIG_UINT unsigned long
#define SMB_BIG_INT long
-#define SBIG_UINT(p, ofs, v) (SIVAL(p,ofs,v),SIVAL(p,(ofs)+4,0))
#endif
#ifndef MIN
@@ -628,31 +557,17 @@ extern int errno;
#define GID_T gid_t
#endif
-#ifndef NGROUPS_MAX
-#define NGROUPS_MAX 32 /* Guess... */
-#endif
/* Lists, trees, caching, datbase... */
#include "ubi_sLinkList.h"
#include "ubi_dLinkList.h"
#include "dlinklist.h"
#include "../tdb/tdb.h"
-#include "talloc.h"
-#include "interfaces.h"
-#include "hash.h"
-
-#ifdef HAVE_FNMATCH
-#include <fnmatch.h>
-#else
-#include "fnmatch.h"
-#endif
#ifndef UBI_BINTREE_H
#include "ubi_Cache.h"
#endif /* UBI_BINTREE_H */
-#include "debugparse.h"
-
#include "version.h"
#include "smb.h"
#include "smbw.h"
@@ -663,8 +578,6 @@ extern int errno;
#include "kanji.h"
#include "charset.h"
-#include "nterr.h"
-
#ifdef WITH_PROFILE
#include "profile.h"
#endif
@@ -673,37 +586,8 @@ extern int errno;
#define MAXCODEPAGELINES 256
#endif
-/*
- * Type for wide character dirent structure.
- * Only d_name is defined by POSIX.
- */
-
-typedef struct smb_wdirent {
- wpstring d_name;
-} SMB_STRUCT_WDIRENT;
-
-/*
- * Type for wide character passwd structure.
- */
-
-typedef struct smb_wpasswd {
- wfstring pw_name;
- char *pw_passwd;
- uid_t pw_uid;
- gid_t pw_gid;
- wpstring pw_gecos;
- wpstring pw_dir;
- wpstring pw_shell;
-} SMB_STRUCT_WPASSWD;
-
-/* Defines for wisXXX functions. */
-#define UNI_UPPER 0x1
-#define UNI_LOWER 0x2
-#define UNI_DIGIT 0x4
-#define UNI_XDIGIT 0x8
-#define UNI_SPACE 0x10
-
/***** automatically generated prototypes *****/
+#include "ldapdb.h"
#include "proto.h"
/* String routines */
@@ -719,15 +603,12 @@ typedef struct smb_wpasswd {
#endif
/* this guess needs to be improved (tridge) */
-#if (defined(STAT_STATVFS) || defined(STAT_STATVFS64)) && !defined(SYSV)
+#if defined(STAT_STATVFS) && !defined(SYSV)
#define SYSV 1
#endif
#ifndef DEFAULT_PRINTING
-#ifdef HAVE_LIBCUPS
-#define DEFAULT_PRINTING PRINT_CUPS
-#define PRINTCAP_NAME "cups"
-#elif defined(SYSV)
+#ifdef SYSV
#define DEFAULT_PRINTING PRINT_SYSV
#define PRINTCAP_NAME "lpstat"
#else
@@ -762,14 +643,19 @@ union semun {
#endif
#endif
-#if (!defined(WITH_NISPLUS) && !defined(WITH_LDAP))
+#if (!defined(WITH_NISPLUS) && !defined(WITH_LDAP) && !defined(WITH_NT5LDAP))
#define USE_SMBPASS_DB 1
+#define USE_SMBUNIX_DB 1
#endif
#if defined(HAVE_PUTPRPWNAM) && defined(AUTH_CLEARTEXT_SEG_CHARS)
#define OSF1_ENH_SEC 1
#endif
+#if defined(HAVE_PAM_AUTHENTICATE) && defined(HAVE_SECURITY_PAM_APPL_H)
+#define HAVE_PAM 1
+#endif
+
#ifndef ALLOW_CHANGE_PASSWORD
#if (defined(HAVE_TERMIOS_H) && defined(HAVE_DUP2) && defined(HAVE_SETSID))
#define ALLOW_CHANGE_PASSWORD 1
@@ -794,6 +680,10 @@ union semun {
#define MAXPATHLEN 256
#endif
+#ifndef MAX_SERVER_POLICY_HANDLES
+#define MAX_SERVER_POLICY_HANDLES 64
+#endif
+
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
@@ -814,6 +704,14 @@ union semun {
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
#endif
+#ifndef SHM_R
+#define SHM_R (0400)
+#endif
+
+#ifndef SHM_W
+#define SHM_W (0200)
+#endif
+
#if defined(HAVE_CRYPT16) && defined(HAVE_GETAUTHUID)
#define ULTRIX_AUTH 1
#endif
@@ -834,6 +732,14 @@ union semun {
# undef HAVE_LIBREADLINE
# endif
# endif
+
+/* Some old versions of readline don't define a prototype for
+ filename_completion_function() */
+
+# ifndef HAVE_READLINE_FCF_PROTO
+char *filename_completion_function(void);
+# endif
+
#endif
#ifndef HAVE_STRDUP
@@ -860,10 +766,6 @@ time_t mktime(struct tm *t);
int ftruncate(int f,long l);
#endif
-#ifndef HAVE_STRTOUL
-unsigned long strtoul(const char *nptr, char **endptr, int base);
-#endif
-
#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESUID_DECL))
/* stupid glibc */
int setresuid(uid_t ruid, uid_t euid, uid_t suid);
@@ -872,6 +774,11 @@ int setresuid(uid_t ruid, uid_t euid, uid_t suid);
int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
#endif
+#if (defined(HAVE_CRYPT) && !defined(HAVE_CRYPT_DECL) && !defined(KRB4_AUTH))
+/* stupid glibc */
+int crypt(const char *key, const char *salt);
+#endif
+
#if !defined(HAVE_BZERO) && defined(HAVE_MEMSET)
#define bzero(a,b) memset((a),'\0',(b))
#endif
@@ -880,38 +787,8 @@ int setresgid(gid_t rgid, gid_t egid, gid_t sgid);
#define getpass(prompt) getsmbpass((prompt))
#endif
-/*
- * Some older systems seem not to have MAXHOSTNAMELEN
- * defined.
- */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 254
-#endif
-
/* yuck, I'd like a better way of doing this */
#define DIRP_SIZE (256 + 32)
-
-/*
- * glibc on linux doesn't seem to have MSG_WAITALL
- * defined. I think the kernel has it though..
- */
-
-#ifndef MSG_WAITALL
-#define MSG_WAITALL 0
-#endif
-
-/* default socket options. Dave Miller thinks we should default to TCP_NODELAY
- given the socket IO pattern that Samba uses */
-#ifdef TCP_NODELAY
-#define DEFAULT_SOCKET_OPTIONS "TCP_NODELAY"
-#else
-#define DEFAULT_SOCKET_OPTIONS ""
-#endif
-
-/* Load header file for libdl stuff */
-
-#ifdef HAVE_LIBDL
-#include <dlfcn.h>
-#endif
-
+/* change initialization ... support for IRIX cc */
+#define VUSER_KEY vuser_key key; key.pid=conn->smbd_pid; key.vuid=vuid
#endif /* _INCLUDES_H */
diff --git a/source/include/ldapdb.h b/source/include/ldapdb.h
new file mode 100644
index 00000000000..8bf2851c5d9
--- /dev/null
+++ b/source/include/ldapdb.h
@@ -0,0 +1,319 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ LDAP and NTDS prototypes &c
+
+ Copyright (C) Luke Howard (PADL Software Pty Ltd) 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * The LDAP DB (LDAPDB) API is desgined to provide a nice,
+ * database library-like, abstraction on top of the LDAP API for
+ * the purposes of SAMBA. Eventually we'll write a general purpose
+ * DB API, but it will probably look more like ADSI than DB.
+ *
+ * The primitive is the opaque LDAPDB.
+ *
+ * The LDAPDB contains the following state:
+ *
+ * - the connection to the LDAP server
+ * - the current search (msgid for async, chain for sync)
+ * - the current search position (an LDAPMessage *)
+ *
+ * You should use a separate LDAPDB for each subsequent search;
+ * it's like a DB* that you can step through with smb_ldapdb_seq(), except
+ * for the fact that (at present) the cursor is part of the handle.
+ * This should probably be changed but it makes it an easy API
+ * to write to for the moment, and it's sure better than having
+ * a global LDAP structure / result.
+ *
+ * If you want to do another search without disturbing the existing
+ * state, whilst still sharing the same connection to the LDAP server,
+ * then you can create a duplicate handle with:
+ *
+ * BOOL ret = smb_ldapdb_dup(original_handle, &new_handle);
+ *
+ * In fact the current implementation of smb_ldapdb_open() does this internally,
+ * so that there is a single connection to the LDAP server. smb_ldapdb_dup()
+ * sets an "owner" flag inside the handle so that when ldapdb_close() is
+ * called the LDAP connection isn't closed unless it was the handle
+ * that created it. The connection itself is referenced counted so
+ * whenever ldapdb_dup() is called the count is incremented, and ds_close()
+ * will only free the connection (nb: it will always free the result
+ * chain) when the count drops to 1. Hopefully it will be OK to
+ * _replace_ the connection if it becomes invalid without invalidating
+ * the existing handles.
+ *
+ * LDAPDB_DECLARE_HANDLE(hds);
+ *
+ * if (!ldapdb_open(&hds)) {
+ * return False;
+ * }
+ *
+ * // hds->flags |= LDAPDB_RETRIEVE_SYNCHRONOUSLY to use ldap_search_s()
+ * if (!ldapdb_search(hds, "cn=users,dc=samba,dc=org", "(samaccountname=lkcl)", 1)) {
+ * return False;
+ * }
+ *
+ * // now hds->entry has the entry
+ *
+ * ldapdb_close(&hds);
+ */
+
+#ifndef _LDAPDB_H
+#define _LDAPDB_H
+
+/* in ds.c */
+struct ldapdb_handle_info;
+typedef struct ldapdb_handle_info LDAPDB;
+typedef LDAPDB *PLDAPDB;
+
+#ifdef WITH_NT5LDAP
+
+#include <lber.h>
+#include <ldap.h>
+
+/* always declare a handle like this, as ldapdb_open() will attempt to reuse a non-NULL handle */
+#define LDAPDB_DECLARE_HANDLE(hds) LDAPDB *hds = NULL
+
+/*
+ * BOOL func(LDAPDB *_hds, ...)
+ * {
+ * LDAPDB_DECLARE_HANDLE(hds);
+ * BOOL ret = LDAPDB_OPEN(_hds, _hds);
+ * ...
+ * ldapdb_close(&hds);
+ * }
+ *
+ * Use this where you can pass an optional handle. If a handle was passed,
+ * then we duplicate it; otherwise, we just allocate a new one. If we
+ * didn't call ldapdb_dup() (as done by DS_OPEN()) then, if a handle was
+ * passed, then we would act as if we owned it, which we don't!
+ */
+#define LDAPDB_OPEN(_hds, hds) ((ldapdb_dup(_hds, hds) == TRUE) ? ldapdb_open(hds) : FALSE)
+
+/* used to indicate handles which may be NULL if a temporary one is to be created */
+/* these are used for functions that create a temporary handle anyway because
+ * they would otherwise change the handle's state.
+ */
+
+/* One time library initialization. */
+BOOL ldapdb_init(void);
+
+/* Add/modify an entry in the directory */
+BOOL ldapdb_update(PLDAPDB hds, const char *context, const char *attribute, const char *value, LDAPMod **mods, BOOL replace); /* FREES mods */
+
+/* Add/modify an entry in the directory */
+BOOL ldapdb_commit(LDAPDB *hds, const char *dn, LDAPMod **mods, BOOL create); /* FREES mods */
+
+/* Enqueue a mod */
+BOOL ldapdb_queue_mod(LDAPMod ***modlist,int modop, const char *attribute, const char *value);
+BOOL ldapdb_queue_unistr_mod(LDAPMod ***modlist,int modop, const char *attribute, const UNISTR2 *value);
+BOOL ldapdb_queue_uint32_mod(LDAPMod ***modlist, int modop, const char *attribute, uint32 value);
+
+/* Enqueue a binary mod */
+BOOL ldapdb_queue_mod_len(LDAPMod ***modlist,int modop, const char *attribute, struct berval *bv);
+
+/* Search the directory */
+/*
+ * Note: AD has a bitwise matching rule that lets them search, say, on
+ * specific bit of groupType. Whilst we could construct a filter that
+ * used that matching rule, it's unlikely that non-AD directory servers
+ * are going to support it, so for the moment we construct an equality
+ * filter. I will perhaps get around to adding support for the AD
+ * AND/NOT matching rules to OpenLDAP.
+ */
+BOOL ldapdb_search(LDAPDB *hds, const char *subcontext, const char *filter, char *const *attrs, int sizelimit);
+
+/* Get a new handle for a new search, or just allocate an empty one */
+BOOL ldapdb_dup(PLDAPDB in, PLDAPDB *out);
+
+/* Open up a handle */
+BOOL ldapdb_open(PLDAPDB *phds);
+
+/* Close off a handle. Closes off connection only if we own it */
+void ldapdb_close(LDAPDB **phds);
+
+/* Read an entry */
+BOOL ldapdb_read(LDAPDB *hds, const char *dn, char *const *attrs);
+
+/* Count entries, if we retrieved them synchronously */
+BOOL ldapdb_count_entries(LDAPDB *hds, int *);
+
+/* Set the synchronous flag; old flag value returned. */
+BOOL ldapdb_set_synchronous(LDAPDB *hds, BOOL setto);
+
+/* Delete an entry */
+BOOL ldapdb_delete(LDAPDB *hds, const char *dn);
+
+/* get dn */
+BOOL ldapdb_get_dn(LDAPDB *hds, char **dn);
+
+/* advance to the next entry */
+BOOL ldapdb_seq(LDAPDB *hds);
+
+/* get a value, caller suplies buffer */
+BOOL ldapdb_get_value(LDAPDB *hds, const char *attribute, char *buf, size_t buflen);
+
+#define ldapdb_get_pvalue(h, a, b) ldapdb_get_value(h, a, b, (sizeof(pstring)-1))
+#define ldapdb_get_fvalue(h, a, b) ldapdb_get_value(h, a, b, (sizeof(fstring)-1))
+
+BOOL ldapdb_get_unistr_value(LDAPDB *hds, const char *attribute, UNISTR2 *buf);
+
+/* get values, caller frees memory */
+BOOL ldapdb_get_values(LDAPDB *hds, const char *attribute, char ***values);
+
+BOOL ldapdb_get_value_len(LDAPDB *hds, const char *attribute, struct berval **value);
+BOOL ldapdb_get_values_len(LDAPDB *hds, const char *attribute, struct berval ***value);
+
+/* get the entry, callee owns */
+BOOL ldapdb_get_entry(LDAPDB *hds, LDAPMessage **e);
+
+BOOL ldapdb_get_uint32(LDAPDB *hds, const char *attribute, uint32 *val);
+
+/* extract a sid from the current entry. objectSid attribute used. */
+BOOL ldapdb_get_sid(LDAPDB *hds, const char *attribute, DOM_SID *sid);
+
+/* extract a rid from the current entry. objectSid attribute used. */
+BOOL ldapdb_get_rid(LDAPDB *hds, const char *attribute, uint32 *rid);
+
+/* caller frees */
+BOOL ldapdb_get_sids(LDAPDB *hds, const char *attribute, DOM_SID ***sid);
+BOOL ldapdb_get_rids(LDAPDB *hds, const char *attribute, uint32 **rid);
+
+
+/* check whether we have an entry */
+BOOL ldapdb_peek(LDAPDB *hds);
+
+/* get a new RID from the RID allocator */
+BOOL ldapdb_allocate_rid(LDAPDB *hds, uint32 *rid);
+
+/* lookup entry by posix name */
+BOOL ldapdb_lookup_by_posix_name(LDAPDB *hds, const char *name);
+
+/* lookup entry by posix uid */
+BOOL ldapdb_lookup_by_posix_uid(LDAPDB *hds, uid_t uid);
+BOOL ldapdb_lookup_by_posix_gid(LDAPDB *hds, gid_t uid);
+
+/* decode a SID from LDAP attribute value */
+BOOL berval_to_sid(const struct berval *siddata, DOM_SID *sid);
+
+/* encode a SID into an LDAP attribute value */
+BOOL sid_to_berval(const DOM_SID *sid, struct berval **siddata);
+
+/* decode a RID using ldapdb_decode_sid() and global_sid */
+BOOL berval_to_rid(struct berval *siddata, uint32 *rid);
+
+/* encode a RID using ldapdb_encode_sid() and global_sid */
+BOOL rid_to_berval(uint32 rid, struct berval **siddata);
+
+BOOL berval_to_unicodepwd(const struct berval *bv, uint8 pwd[16]);
+BOOL berval_to_dbcspwd(const struct berval *bv, uint8 pwd[16]);
+BOOL unicodepwd_to_berval(const uint8 pwd[16], struct berval **bvp);
+BOOL dbcspwd_to_berval(const uint8 pwd[16], struct berval **bvp);
+
+/* name cracking */
+BOOL ldapdb_dnsdomain_to_dn(const char *dnsdomain, pstring dn);
+BOOL ldapdb_dn_to_dnsdomain(const char *dn, pstring dns);
+const char *ldapdb_get_realm_name(void);
+
+/* name mapping; can pass a NULL handle if you don't have a conn handy */
+
+/* get the DN for a SAM account name */
+BOOL ldapdb_ntname_to_dn(PLDAPDB hds, const char *ntname, pstring dn);
+
+/* get the SAM account name for a DN */
+BOOL ldapdb_dn_to_ntname(PLDAPDB hds, const char *dn, pstring ntname);
+
+/* get the SID for a DN */
+BOOL ldapdb_sid_to_dn(PLDAPDB hds, const DOM_SID *sid, pstring dn);
+
+/* get the RID for a DN */
+BOOL ldapdb_rid_to_dn(PLDAPDB hds, uint32 rid, pstring dn);
+
+/* get sid filter */
+BOOL ldapdb_make_sid_filter(const char *attribute, const DOM_SID *sid, fstring filter);
+BOOL ldapdb_make_rid_filter(const char *attribute, uint32 rid, fstring filter);
+
+/* get domain SID */
+BOOL ldapdb_get_domain_info(PLDAPDB _hds, const char *dnsdomain, DOM_SID *sid, fstring nbname);
+
+/* get the DN for a filter somewhere */
+BOOL ldapdb_lookup_name(PLDAPDB hds, const char *, const char *, pstring dn);
+
+/* lookup new entry by RID */
+BOOL ldapdb_lookup_by_rid(LDAPDB *, uint32 rid);
+
+/* lookup new entry by SID. How are we going to do this? objectSid is bianry. */
+BOOL ldapdb_lookup_by_sid(LDAPDB *, const DOM_SID *sid);
+
+/* lookup by sam account name */
+BOOL ldapdb_lookup_by_ntname(LDAPDB *, const char *ntname);
+BOOL ldapdb_lookup_by_unistr_ntname(LDAPDB *, const UNISTR2 *ntname);
+
+/* lookup by nETBIOSName */
+BOOL ldapdb_lookup_by_netbiosname (LDAPDB *hds, const char *nbname);
+
+/* save time in modlist. need to do this not as a unix time_t. */
+BOOL ldapdb_queue_time(LDAPMod ***modlist, int modop, const char *attribute, NTTIME *nttime);
+
+/* parse out an NT5 timeval into an NT time */
+BOOL ldapdb_parse_time(const char *timeval, NTTIME *nttime);
+
+/* get some time attribute, uses ldapdb_parse_time() */
+BOOL ldapdb_get_time(LDAPDB *hds, const char *attribute, NTTIME *nttime);
+
+BOOL ldapdb_oc_check(LDAPDB *hds, const char *ocname);
+
+/* Convert a UNISTR2 structure to a UTF8 string. */
+void unistr2_to_utf8(char *dest, const UNISTR2 *str, size_t maxlen);
+
+void utf8_to_unistr2(UNISTR2 *dest, const char *str);
+
+/* in nt5ldap.c */
+BOOL nt5ldap_make_local_grp_member(LDAPDB *hds, const char *dn, LOCAL_GRP_MEMBER *group);
+BOOL nt5ldap_make_local_grp(LDAPDB *hds, LOCAL_GRP *group, LOCAL_GRP_MEMBER **members, int *num_memb, uint32 req_type);
+BOOL nt5ldap_local_grp_mods (const LOCAL_GRP *group, LDAPMod ***mods, int operation, uint32 req_type);
+BOOL nt5ldap_local_grp_member_mods (const DOM_SID *sid, LDAPMod ***mods, int operation, pstring member);
+BOOL nt5ldap_make_domain_grp_member(LDAPDB *hds, const char *dn, DOMAIN_GRP_MEMBER *group);
+BOOL nt5ldap_make_domain_grp (LDAPDB * hds, DOMAIN_GRP * group, DOMAIN_GRP_MEMBER ** members, int *num_membs);
+BOOL nt5ldap_domain_grp_mods (const DOMAIN_GRP * group, LDAPMod *** mods, int operation);
+BOOL nt5ldap_domain_grp_member_mods (uint32 user_rid, LDAPMod *** mods, int operation, pstring member);
+BOOL nt5ldap_make_sam_user_info21(LDAPDB *hds, SAM_USER_INFO_21 *usr);
+BOOL nt5ldap_sam_user_info21_mods(const SAM_USER_INFO_21 *usr, LDAPMod ***mods, int op, char *rdn, size_t rdnmaxlen, BOOL *iscomputer_p);
+BOOL nt5ldap_make_group_rids (LDAPDB * _hds, const char *dn, uint32 ** rids, int *numrids, uint32 req_type);
+
+/* in smbpassldap.c */
+/* turn the currnet entry into an smb_passwd */
+struct smb_passwd *nt5ldapsmb_getent(LDAPDB *hds);
+/* get mods for an smb password */
+BOOL nt5ldapsmb_smbmods(struct smb_passwd *newpwd, LDAPMod ***mods, int operation);
+
+/* in sampassldap.c */
+/* turn the currnet entry into an sam_passwd */
+struct sam_passwd *nt5ldapsam_getent(LDAPDB *hds);
+/* get mods for a sam password */
+BOOL nt5ldapsam_sammods(struct sam_passwd *newpwd, LDAPMod ***mods, int operation);
+
+/* in sampassdb.c */
+/* convert between sam/smb password types */
+struct sam_passwd *pwdb_smb_to_sam(struct smb_passwd *user);
+struct smb_passwd *pwdb_sam_to_smb(struct sam_passwd *user);
+
+#endif /* WITH_NT5LDAP */
+
+#endif /* _LDAPDB_H */
diff --git a/source/include/lib_smb_proto.h b/source/include/lib_smb_proto.h
new file mode 100644
index 00000000000..2a19b45afa7
--- /dev/null
+++ b/source/include/lib_smb_proto.h
@@ -0,0 +1,682 @@
+#ifndef _LIB_SMB_PROTO_H_
+#define _LIB_SMB_PROTO_H_
+/* This file is automatically generated with "make proto". DO NOT EDIT */
+
+
+/*The following definitions come from lib/crc32.c */
+
+uint32 crc32_calc_buffer( uint32 count, char *buffer);
+
+/*The following definitions come from lib/hmacmd5.c */
+
+void hmac_md5_init_rfc2104(uchar* key, int key_len, HMACMD5Context *ctx);
+void hmac_md5_init_limK_to_64(const uchar* key, int key_len,
+ HMACMD5Context *ctx);
+void hmac_md5_update(const uchar* text, int text_len, HMACMD5Context *ctx);
+void hmac_md5_final(uchar *digest, HMACMD5Context *ctx);
+void hmac_md5( uchar key[16], uchar* data, int data_len, uchar* digest);
+
+/*The following definitions come from lib/md5.c */
+
+void MD5Init(struct MD5Context *ctx);
+void MD5Update(struct MD5Context *ctx, uchar const *buf, unsigned len);
+void MD5Final(uchar digest[16], struct MD5Context *ctx);
+void MD5Transform(uint32 buf[4], const uchar inext[64]);
+
+/*The following definitions come from lib/util_hnd.c */
+
+struct policy_cache *get_global_hnd_cache(void);
+struct policy_cache *init_policy_cache(int num_pol_hnds);
+void free_policy_cache(struct policy_cache *cache);
+BOOL policy_hnd_set_name(struct policy_cache *cache,
+ POLICY_HND *hnd, const char *name);
+const char *policy_hnd_get_name(struct policy_cache *cache,
+ const POLICY_HND *hnd);
+BOOL dup_policy_hnd(struct policy_cache *cache,
+ POLICY_HND *hnd,
+ const POLICY_HND *from);
+BOOL register_policy_hnd(struct policy_cache *cache,
+ const vuser_key *key,
+ POLICY_HND *hnd,
+ uint32 access_mask);
+BOOL open_policy_hnd(struct policy_cache *cache,
+ const vuser_key *key,
+ POLICY_HND *hnd,
+ uint32 access_mask);
+BOOL open_policy_hnd_link(struct policy_cache *cache,
+ const POLICY_HND *parent_hnd,
+ POLICY_HND *hnd,
+ uint32 access_mask);
+int find_policy_by_hnd(struct policy_cache *cache, const POLICY_HND *hnd);
+BOOL set_policy_state(struct policy_cache *cache, POLICY_HND *hnd,
+ void(*fn)(void*), void *dev);
+void *get_policy_state_info(struct policy_cache *cache, const POLICY_HND *hnd);
+BOOL policy_hnd_set_state_type(struct policy_cache *cache,
+ POLICY_HND *hnd, int type);
+int policy_hnd_get_state_type(struct policy_cache *cache,
+ const POLICY_HND *hnd);
+BOOL policy_hnd_check_state_type(struct policy_cache *cache,
+ const POLICY_HND *hnd, int type);
+BOOL close_policy_hnd(struct policy_cache *cache, POLICY_HND *hnd);
+BOOL policy_link_key(struct policy_cache *cache, const POLICY_HND *hnd,
+ POLICY_HND *to);
+const vuser_key *get_policy_vuser_key(struct policy_cache *cache,
+ const POLICY_HND *hnd);
+BOOL pol_get_usr_sesskey(struct policy_cache *cache, const POLICY_HND *hnd,
+ uchar usr_sess_key[16]);
+
+/*The following definitions come from lib/vuser.c */
+
+BOOL is_valid_user_struct(const vuser_key * key);
+user_struct *get_valid_user_struct(const vuser_key * key);
+void invalidate_vuid(vuser_key * key);
+BOOL validated_username(vuser_key * key, char *name, size_t len);
+uint16 create_vuid(pid_t pid,
+ uid_t uid, gid_t gid,
+ int n_groups, gid_t * groups,
+ const char *unix_name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+uint16 register_vuid(pid_t pid, uid_t uid, gid_t gid,
+ const char *unix_name,
+ const char *requested_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+BOOL check_vuser_ok(struct uid_cache *cache, user_struct * vuser, int snum);
+
+/*The following definitions come from lib/vuser_db.c */
+
+BOOL tdb_delete_vuid( const vuser_key *uk);
+BOOL tdb_lookup_vuid( const vuser_key *uk, user_struct **usr);
+BOOL tdb_store_vuid( const vuser_key *uk, user_struct *usr);
+BOOL vuid_init_db(void);
+
+/*The following definitions come from libsmb/clientgen.c */
+
+int cli_set_port(struct cli_state *cli, int port);
+char *cli_errstr(struct cli_state *cli);
+void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len);
+BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen);
+void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen);
+BOOL cli_send_trans(struct cli_state *cli, int trans,
+ char *name, int pipe_name_len,
+ int fid, int flags,
+ uint16 *setup, int lsetup, int msetup,
+ char *param, int lparam, int mparam,
+ char *data, int ldata, int mdata);
+BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len,
+ uint16 *setup, uint32 setup_count, uint32 max_setup_count,
+ char *params, uint32 param_count, uint32 max_param_count,
+ char *data, uint32 data_count, uint32 max_data_count,
+ char **rparam, uint32 *rparam_count,
+ char **rdata, uint32 *rdata_count);
+BOOL cli_api(struct cli_state *cli,
+ char *param, int prcnt, int mprcnt,
+ char *data, int drcnt, int mdrcnt,
+ char **rparam, int *rprcnt,
+ char **rdata, int *rdrcnt);
+BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
+BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *));
+BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
+ void (*fn)(const char *, uint32, const char *));
+BOOL cli_session_setup_x(struct cli_state *cli,
+ char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *user_domain);
+BOOL cli_session_setup(struct cli_state *cli,
+ char *myhostname, char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *user_domain);
+BOOL cli_ulogoff(struct cli_state *cli);
+BOOL cli_send_tconX(struct cli_state *cli,
+ char *share, char *dev, char *pass, int passlen);
+BOOL cli_tdis(struct cli_state *cli);
+BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst);
+BOOL cli_unlink(struct cli_state *cli, char *fname);
+BOOL cli_mkdir(struct cli_state *cli, char *dname);
+BOOL cli_rmdir(struct cli_state *cli, char *dname);
+int cli_nt_create(struct cli_state *cli, const char *fname);
+int cli_open(struct cli_state *cli, const char *fname,
+ int flags, int share_mode);
+BOOL cli_close(struct cli_state *cli, int fnum);
+BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
+BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
+size_t cli_read_one(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
+size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size, BOOL overlap);
+ssize_t cli_write(struct cli_state *cli,
+ int fnum, uint16 write_mode,
+ char *buf, off_t offset, size_t size, size_t bytes_left);
+BOOL cli_getattrE(struct cli_state *cli, int fd,
+ uint16 *attr, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time);
+BOOL cli_getatr(struct cli_state *cli, char *fname,
+ uint16 *attr, size_t *size, time_t *t);
+BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t);
+BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ size_t *size, uint16 *mode);
+BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ time_t *w_time, size_t *size, uint16 *mode,
+ SMB_INO_T *ino);
+BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
+ uint16 *mode, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ time_t *w_time, SMB_INO_T *ino);
+int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
+ void (*fn)(file_info *, const char *));
+BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
+ const char *old_password);
+BOOL cli_negprot(struct cli_state *cli);
+BOOL cli_session_request(struct cli_state *cli,
+ struct nmb_name *calling, struct nmb_name *called);
+BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip);
+void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr);
+struct cli_state *cli_initialise(struct cli_state *cli);
+void cli_close_socket(struct cli_state *cli);
+void cli_shutdown(struct cli_state *cli);
+int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num);
+void cli_sockopt(struct cli_state *cli, char *options);
+uint16 cli_setpid(struct cli_state *cli, uint16 pid);
+BOOL cli_reestablish_connection(struct cli_state *cli);
+BOOL cli_establish_connection(struct cli_state *cli,
+ const char *dest_host, struct in_addr *dest_ip,
+ struct nmb_name *calling, struct nmb_name *called,
+ char *service, char *service_type,
+ BOOL do_shutdown, BOOL do_tcon);
+BOOL cli_connect_auth(struct cli_state *cli,
+ const char* desthost,
+ struct in_addr *dest_ip,
+ const struct ntuser_creds *usr);
+BOOL cli_connect_servers_auth(struct cli_state *cli,
+ char *p,
+ const struct ntuser_creds *usr);
+BOOL cli_connect_serverlist(struct cli_state *cli, char *p);
+int cli_printjob_del(struct cli_state *cli, int job);
+int cli_print_queue(struct cli_state *cli,
+ void (*fn)(struct print_job_info *));
+BOOL cli_chkpath(struct cli_state *cli, char *path);
+BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
+ int *grp);
+BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp);
+BOOL cli_message_end(struct cli_state *cli, int grp);
+BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail);
+BOOL get_any_dc_name(const char *domain, char *srv_name);
+
+/*The following definitions come from libsmb/credentials.c */
+
+char *credstr(const uchar *cred);
+void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, const char *pass,
+ uchar session_key[8]);
+void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp,
+ DOM_CHAL *cred);
+int cred_assert(const DOM_CHAL *cred, uchar session_key[8],
+ DOM_CHAL *stored_cred, UTIME timestamp);
+BOOL clnt_deal_with_creds(uchar sess_key[8],
+ DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred);
+BOOL deal_with_creds(uchar sess_key[8],
+ DOM_CRED *sto_clnt_cred,
+ const DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred);
+
+/*The following definitions come from libsmb/nterr.c */
+
+BOOL get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len);
+const char *get_nt_error_msg(uint32 nt_code);
+
+/*The following definitions come from libsmb/pwd_cache.c */
+
+void pwd_init(struct pwd_info *pwd);
+BOOL pwd_is_nullpwd(const struct pwd_info *pwd);
+void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key);
+BOOL pwd_compare(const struct pwd_info *_pwd1, const struct pwd_info *_pwd2);
+void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt);
+void pwd_set_nullpwd(struct pwd_info *pwd);
+void pwd_set_cleartext(struct pwd_info *pwd, char *clr);
+void pwd_get_cleartext(struct pwd_info *pwd, char *clr);
+void pwd_set_lm_nt_16(struct pwd_info *pwd,
+ const uchar lm_pwd[16],
+ const uchar nt_pwd[16]);
+void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
+void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr);
+void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
+ const char *user, const char *server, const char *domain,
+ uchar sess_key[16]);
+void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
+ uchar sess_key[16]);
+void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
+ uchar *nt_owf, size_t *nt_owf_len);
+
+/*The following definitions come from libsmb/smbdes.c */
+
+void smbhash(uchar *out, const uchar *in, const uchar *key, int forw);
+void E_P16(uchar *p14,uchar *p16);
+void E_P24(const uchar *p21, const uchar *c8, uchar *p24);
+void D_P16(const uchar *p14, const uchar *in, uchar *out);
+void E_old_pw_hash( const uchar *p14, const uchar *in, uchar *out);
+void cred_hash1(uchar *out, const uchar *in, const uchar *key);
+void cred_hash2(uchar *out,uchar *in,uchar *key);
+void cred_hash3(uchar *out, const uchar *in,uchar *key, int forw);
+void SamOEMhash( uchar *data, const uchar *key, int val);
+void sam_pwd_hash(uint32 rid, const uchar *in, uchar *out, int forw);
+
+/*The following definitions come from libsmb/smbencrypt.c */
+
+void SMBencrypt(uchar * pwrd, uchar * c8, uchar * p24);
+void SMBNTencrypt(uchar * pwrd, uchar * c8, uchar * p24);
+void E_md4hash(uchar * pwrd, uchar * p16);
+void lm_owf_genW(const UNISTR2 * pwd, uchar p16[16]);
+void lm_owf_gen(const char *pwd, uchar p16[16]);
+void nt_owf_genW(const UNISTR2 * pwd, uchar nt_p16[16]);
+void nt_owf_gen(const char *pwd, uchar nt_p16[16]);
+void nt_lm_owf_genW(const UNISTR2 * pwd, uchar nt_p16[16], uchar lm_p16[16]);
+void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16]);
+void SMBOWFencrypt(const uchar pwrd[16], const uchar * c8, uchar p24[24]);
+void SMBOWFencrypt_ntv2(const uchar kr[16],
+ const uchar * srv_chal, int srv_chal_len,
+ const uchar * cli_chal, int cli_chal_len,
+ char resp_buf[16]);
+void SMBsesskeygen_ntv2(const uchar kr[16],
+ const uchar * nt_resp, char sess_key[16]);
+void SMBsesskeygen_ntv1(const uchar kr[16],
+ const uchar * nt_resp, char sess_key[16]);
+void SMBgenclientchals(char *lm_cli_chal,
+ char *nt_cli_chal, int *nt_cli_chal_len,
+ const char *srv, const char *dom);
+void ntv2_owf_gen(const uchar owf[16],
+ const char *user_n, const char *domain_n, uchar kr_buf[16]);
+void NTLMSSPOWFencrypt(const uchar pwrd[8], const uchar * ntlmchalresp,
+ uchar p24[24]);
+BOOL make_oem_passwd_hash(uchar data[516],
+ const char *pwrd, int new_pw_len,
+ const uchar old_pw_hash[16], BOOL unicode);
+BOOL nt_encrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
+BOOL nt_decrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
+void create_ntlmssp_resp(struct pwd_info *pwd,
+ char *domain, char *user_name, char *my_name,
+ uint32 ntlmssp_cli_flgs, prs_struct * auth_resp);
+BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
+ int new_pwrd_size, uint32 * new_pw_len);
+BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
+ int new_pw_len, BOOL nt_pass_set);
+
+/*The following definitions come from libsmb/smberr.c */
+
+char *smb_err_msg(uint8 class, uint32 num);
+BOOL smb_safe_err_msg(uint8 class, uint32 num, char *ret, size_t len);
+BOOL smb_safe_errstr(char *inbuf, char *msg, size_t len);
+char *smb_errstr(char *inbuf);
+
+/*The following definitions come from rpc_parse/parse_creds.c */
+
+BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name,
+ const char* requested_name,
+ const char* real_name,
+ BOOL guest);
+BOOL creds_io_unix(char *desc, CREDS_UNIX *r_u, prs_struct *ps, int depth);
+void creds_free_unix(CREDS_UNIX *r_u);
+BOOL make_creds_unix_sec(CREDS_UNIX_SEC *r_u,
+ uint32 uid, uint32 gid, uint32 num_grps, gid_t *grps);
+BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth);
+void creds_free_unix_sec(CREDS_UNIX_SEC *r_u);
+BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth);
+BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth);
+void creds_free_nt(CREDS_NT *r_u);
+BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth);
+void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from);
+void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from);
+void copy_nt_creds(struct ntuser_creds *to,
+ const struct ntuser_creds *from);
+void copy_user_creds(struct user_creds *to,
+ const struct user_creds *from);
+void free_user_creds(struct user_creds *creds);
+BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth);
+BOOL create_ntuser_creds( prs_struct *ps,
+ const char* name,
+ uint16 version, uint16 command,
+ const vuser_key *key,
+ const struct ntuser_creds *ntu,
+ BOOL reuse);
+BOOL create_user_creds( prs_struct *ps,
+ const char* name,
+ uint16 version, uint16 command,
+ const vuser_key *key,
+ const struct user_creds *usr);
+
+/*The following definitions come from rpc_parse/parse_misc.c */
+
+BOOL smb_io_bigint(char *desc, BIGINT *bigint, prs_struct *ps, int depth);
+BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth);
+BOOL smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth);
+uint32 get_enum_hnd(ENUM_HND *enh);
+BOOL make_enum_hnd(ENUM_HND *enh, uint32 hnd);
+BOOL smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth);
+BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth);
+BOOL make_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid);
+BOOL smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth);
+BOOL make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer);
+BOOL smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth);
+BOOL make_strhdr2(STRHDR2 *hdr, uint32 max_len, uint32 len, uint32 buffer);
+BOOL smb_io_strhdr2(char *desc, STRHDR2 *hdr, prs_struct *ps, int depth);
+BOOL make_uni_hdr(UNIHDR *hdr, int len);
+BOOL make_unihdr_from_unistr2(UNIHDR *hdr, const UNISTR2 *str);
+BOOL smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth);
+BOOL make_buf_hdr(BUFHDR *hdr, int max_len, int len);
+BOOL smb_io_hdrbuf_pre(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset);
+BOOL smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
+ uint32 ptr_hdrbuf, uint32 max_len, uint32 len);
+BOOL smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth);
+BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer);
+BOOL smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth);
+BOOL make_uni_hdr2(UNIHDR2 *hdr, int len);
+BOOL make_unihdr2_from_unistr2(UNIHDR2 *hdr, const UNISTR2 *str);
+BOOL smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth);
+BOOL make_unistr(UNISTR *str, char *buf);
+BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth);
+BOOL make_buffer3_uint32(BUFFER3 *str, uint32 val);
+BOOL make_buffer3_str(BUFFER3 *str, const char *buf, int len);
+BOOL make_buffer3_hex(BUFFER3 *str, char *buf);
+BOOL make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len);
+BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth);
+BOOL make_buffer4_str(BUFFER4 *str, const char *buf, int len);
+BOOL smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth);
+BOOL init_buffer5(BUFFER5 **str);
+BOOL clear_buffer5(BUFFER5 **str);
+BOOL make_buffer5(BUFFER5 *str, char *buf, int len);
+BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth);
+BOOL make_buffer2_multi(BUFFER2 *str, char *const* const buf, uint32 num);
+BOOL make_buffer2(BUFFER2 *str, const char *buf, int len);
+BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf);
+BOOL make_string2(STRING2 *str, const char *buf, int len);
+BOOL make_buf_string2(STRING2 *str, uint32 *ptr, const char *buf);
+BOOL smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_unistr2(UNISTR2 *str, const char *buf, int len);
+BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx);
+BOOL smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth);
+BOOL make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type);
+BOOL smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth);
+BOOL make_log_info(DOM_LOG_INFO *log,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name);
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth);
+BOOL smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth);
+BOOL smb_io_cred(char *desc, DOM_CRED *cred, prs_struct *ps, int depth);
+BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
+ const char *logon_srv, const char *comp_name,
+ DOM_CRED *clnt_cred);
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
+BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CRED *cred);
+BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth);
+BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16]);
+BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
+BOOL smb_io_gid(char *desc, DOM_GID *gid, prs_struct *ps, int depth);
+BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
+BOOL smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
+BOOL smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
+BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_net.c */
+
+BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l,
+ const char* srv_name,
+ uint32 function_code,
+ uint32 query_level,
+ uint32 switch_value);
+BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth);
+BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l,
+ uint32 switch_value,
+ NETLOGON_INFO *logon_info,
+ uint32 status);
+BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth);
+BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth);
+BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth);
+BOOL make_q_req_chal(NET_Q_REQ_CHAL *q_c,
+ const char *logon_srv, const char *logon_clnt,
+ DOM_CHAL *clnt_chal);
+BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth);
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth);
+BOOL make_q_auth(NET_Q_AUTH *q_a,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CHAL *clnt_chal);
+BOOL net_io_q_auth(char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth(char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth);
+BOOL make_q_auth_2(NET_Q_AUTH_2 *q_a,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CHAL *clnt_chal, uint32 clnt_flgs);
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth);
+BOOL make_q_srv_pwset(NET_Q_SRV_PWSET *q_s,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CRED *cred, char nt_cypher[16]);
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth);
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth);
+BOOL make_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low,
+ uint32 log_id_high,
+ const char *user_name,
+ const char *wksta_name,
+ const char sess_key[16],
+ const uchar lm_cypher[16],
+ const uchar nt_cypher[16]);
+BOOL make_id_info4(NET_ID_INFO_4 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const char *general);
+BOOL make_id_info2(NET_ID_INFO_2 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const uchar lm_challenge[8],
+ const uchar *lm_chal_resp,
+ int lm_chal_len,
+ const uchar *nt_chal_resp,
+ int nt_chal_len);
+BOOL make_sam_info(DOM_SAM_INFO *sam,
+ const char *logon_srv, const char *comp_name,
+ DOM_CRED *clnt_cred,
+ DOM_CRED *rtn_cred, uint16 logon_level,
+ NET_ID_INFO_CTR *ctr);
+BOOL make_net_user_info3W(NET_USER_INFO_3 *usr,
+
+ const NTTIME *logon_time,
+ const NTTIME *logoff_time,
+ const NTTIME *kickoff_time,
+ const NTTIME *pass_last_set_time,
+ const NTTIME *pass_can_change_time,
+ const NTTIME *pass_must_change_time,
+
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+
+ uint16 logon_count,
+ uint16 bad_pw_count,
+
+ uint32 user_id,
+ uint32 group_id,
+ uint32 num_groups,
+ const DOM_GID *gids,
+ uint32 user_flgs,
+
+ const char sess_key[16],
+
+ const UNISTR2 *logon_srv,
+ const UNISTR2 *logon_dom,
+
+ const char *padding,
+
+ const DOM_SID *dom_sid,
+ const char *other_sids);
+BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
+
+ NTTIME *logon_time,
+ NTTIME *logoff_time,
+ NTTIME *kickoff_time,
+ NTTIME *pass_last_set_time,
+ NTTIME *pass_can_change_time,
+ NTTIME *pass_must_change_time,
+
+ char *user_name,
+ char *full_name,
+ char *logon_script,
+ char *profile_path,
+ char *home_dir,
+ char *dir_drive,
+
+ uint16 logon_count,
+ uint16 bad_pw_count,
+
+ uint32 user_id,
+ uint32 group_id,
+ uint32 num_groups,
+ DOM_GID *gids,
+ uint32 user_flgs,
+
+ char sess_key[16],
+
+ char *logon_srv,
+ char *logon_dom,
+
+ char *padding,
+
+ DOM_SID *dom_sid,
+ char *other_sids);
+BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth);
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
+BOOL make_r_sam_logon(NET_R_SAM_LOGON *r_s,
+ const DOM_CRED *srv_creds,
+ uint16 switch_value,
+ NET_USER_INFO_3 *user_info,
+ uint32 status);
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
+BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth);
+BOOL make_r_sam_logoff(NET_R_SAM_LOGOFF *r_s,
+ const DOM_CRED *srv_cred,
+ uint32 status);
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth);
+BOOL make_q_sam_sync(NET_Q_SAM_SYNC *q_s,
+ const char *srv_name,
+ const char *cli_name,
+ DOM_CRED *cli_creds, uint32 database_id);
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC *q_s, prs_struct *ps, int depth);
+BOOL make_sam_delta_hdr(SAM_DELTA_HDR *delta, uint16 type, uint32 rid);
+BOOL make_sam_account_info(SAM_ACCOUNT_INFO *info,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ uint32 user_rid, uint32 group_rid,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *desc,
+ uint32 acb_info,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial);
+BOOL make_r_sam_sync(NET_R_SAM_SYNC *r_s,
+ const DOM_CRED *srv_cred,
+ uint32 sync_context,
+ uint32 num_deltas,
+ uint32 num_deltas2,
+ SAM_DELTA_HDR *hdr_deltas,
+ SAM_DELTA_CTR *deltas,
+ uint32 status);
+BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
+ NET_R_SAM_SYNC *r_s, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_ntlmssp.c */
+
+BOOL rpc_hdr_ntlmssp_auth_chk(RPC_HDR_AUTH *rai);
+BOOL make_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
+ uint32 neg_flgs,
+ fstring myname, fstring domain);
+BOOL smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth);
+BOOL make_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
+ uint32 neg_flags,
+ uint8 challenge[8]);
+BOOL smb_io_rpc_auth_ntlmssp_chal(char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth);
+BOOL make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
+ uchar lm_resp[24],
+ uchar *nt_resp, size_t nt_len,
+ char *domain, char *user, char *wks,
+ uint32 neg_flags);
+BOOL smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth);
+BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_num);
+BOOL make_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
+ uint32 ver, uint32 crc32, uint32 seq_num);
+BOOL smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_prs.c */
+
+void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name);
+void prs_debug_out(const prs_struct *ps, char *msg, int level);
+void prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io);
+void prs_set_packtype(prs_struct *ps, const uint8 *pack_type);
+void prs_create(prs_struct *ps, char *data, uint32 size, uint8 align, BOOL io);
+BOOL prs_copy(prs_struct *ps, const prs_struct *from);
+BOOL prs_alloc_data(prs_struct *buf, int size);
+BOOL prs_buf_copy(char *copy_into, const prs_struct *buf,
+ uint32 offset, uint32 len);
+void prs_struct_free(prs_struct **buf);
+void prs_free_data(prs_struct *buf);
+BOOL prs_realloc_data(prs_struct *buf, size_t new_size);
+BOOL prs_grow_data(prs_struct *buf, BOOL io, int new_size, BOOL force_grow);
+uint32 prs_buf_len(const prs_struct *buf);
+char *prs_data(const prs_struct *buf, uint32 offset);
+void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next);
+void prs_align(prs_struct *ps);
+BOOL prs_grow(prs_struct *ps, uint32 new_size);
+BOOL prs_append_data(prs_struct *ps, const char *data, int len);
+BOOL prs_add_data(prs_struct *ps, const char *data, int len);
+BOOL _prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8);
+BOOL _prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16);
+BOOL _prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16]);
+BOOL _prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32);
+BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
+BOOL _prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
+BOOL _prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
+BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str);
+BOOL _prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str);
+BOOL _prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str);
+BOOL _prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth);
+BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str);
+BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size);
+BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
+BOOL _prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
+ uint32 ptr_uint16, uint32 start_offset);
+BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
+BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
+ uint32 ptr_uint32, uint32 data_size);
+int prs_tdb_delete(TDB_CONTEXT *tdb, prs_struct *pk);
+int prs_tdb_store(TDB_CONTEXT *tdb, int flgs, prs_struct *pk, prs_struct *pd);
+void prs_tdb_fetch(TDB_CONTEXT *tdb, prs_struct *pk, prs_struct *pd);
+
+/*The following definitions come from rpc_parse/parse_vuid.c */
+
+BOOL vuid_io_key(char *desc, vuser_key * r_u, prs_struct * ps, int depth);
+BOOL make_vuid_user_struct(user_struct * r_u,
+ uid_t uid, gid_t gid,
+ const char *name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest,
+ uint32 n_groups, const gid_t * groups,
+ const NET_USER_INFO_3 * usr);
+BOOL vuid_io_user_struct(char *desc, user_struct * r_u, prs_struct * ps,
+ int depth);
+void vuid_free_user_struct(user_struct * r_u);
+#endif /* _LIB_SMB_PROTO_H_ */
diff --git a/source/include/local.h b/source/include/local.h
index bd75d4e3858..e6e2fd4badb 100644
--- a/source/include/local.h
+++ b/source/include/local.h
@@ -32,15 +32,7 @@
/* max number of directories open at once */
/* note that with the new directory code this no longer requires a
file handle per directory, but large numbers do use more memory */
-#define MAX_OPEN_DIRECTORIES 256
-
-/* max number of directory handles */
-/* As this now uses the bitmap code this can be
- quite large. */
-#define MAX_DIRECTORY_HANDLES 2048
-
-/* maximum number of file caches per smbd */
-#define MAX_WRITE_CACHES 10
+#define MAX_OPEN_DIRECTORIES 64
/* define what facility to use for syslog */
#ifndef SYSLOG_FACILITY
@@ -74,9 +66,6 @@
/* separators for lists */
#define LIST_SEP " \t,;:\n\r"
-/* wchar separators for lists */
-#define LIST_SEP_W wchar_list_sep
-
#ifndef LOCKDIR
/* this should have been set in the Makefile */
#define LOCKDIR "/tmp/samba"
@@ -109,6 +98,12 @@
#define GUEST_ACCOUNT "nobody"
#endif
+/* do you want smbd to send a 1 byte packet to nmbd to trigger it to start
+ when smbd starts? */
+#ifndef PRIME_NMBD
+#define PRIME_NMBD 1
+#endif
+
/* the default pager to use for the client "more" command. Users can
override this with the PAGER environment variable */
#ifndef PAGER
@@ -126,19 +121,16 @@
/* the following control timings of various actions. Don't change
them unless you know what you are doing. These are all in seconds */
#define DEFAULT_SMBD_TIMEOUT (60*60*24*7)
-#define SMBD_RELOAD_CHECK (180)
+#define SMBD_RELOAD_CHECK (60)
#define IDLE_CLOSED_TIMEOUT (60)
#define DPTR_IDLE_TIMEOUT (120)
-#define SMBD_SELECT_TIMEOUT (60)
-#define SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS (10)
+#define SMBD_SELECT_LOOP (10)
#define NMBD_SELECT_LOOP (10)
#define BROWSE_INTERVAL (60)
#define REGISTRATION_INTERVAL (10*60)
#define NMBD_INETD_TIMEOUT (120)
#define NMBD_MAX_TTL (24*60*60)
#define LPQ_LOCK_TIMEOUT (5)
-#define NMBD_INTERFACES_RELOAD (120)
-#define NMBD_UNEXPECTED_TIMEOUT (15)
/* the following are in milliseconds */
#define LOCK_RETRY_TIMEOUT (100)
@@ -154,9 +146,17 @@
/* shall we support browse requests via a FIFO to nmbd? */
#define ENABLE_FIFO 1
-/* how long (in miliseconds) to wait for a socket connect to happen */
-#define LONG_CONNECT_TIMEOUT 30000
-#define SHORT_CONNECT_TIMEOUT 5000
+/* how long to wait for a socket connect to happen */
+#define LONG_CONNECT_TIMEOUT 30
+#define SHORT_CONNECT_TIMEOUT 5
+
+/* default socket options. Dave Miller thinks we should default to TCP_NODELAY
+ given the socket IO pattern that Samba uses*/
+#ifdef TCP_NODELAY
+#define DEFAULT_SOCKET_OPTIONS "TCP_NODELAY"
+#else
+#define DEFAULT_SOCKET_OPTIONS ""
+#endif
/* the default netbios keepalive timeout */
#define DEFAULT_KEEPALIVE 300
@@ -169,6 +169,10 @@
#define OPLOCK_BREAK_TIMEOUT 30
+/* how many times do we try to resend the oplock break request - useful
+ for buggy MS clients */
+#define OPLOCK_BREAK_RESENDS 3
+
/* Timout (in seconds) to add to the oplock break timeout
to wait for the smbd to smbd message to return. */
@@ -181,13 +185,4 @@
/* name of directory that netatalk uses to store macintosh resource forks */
#define APPLEDOUBLE ".AppleDouble/"
-/*
- * Default passwd chat script.
- */
-
-#define DEFAULT_PASSWD_CHAT "*new*password* %n\\n *new*password* %n\\n *changed*"
-
-/* Minimum length of allowed password when changing UNIX password. */
-#define MINPASSWDLENGTH 5
-
#endif
diff --git a/source/include/md5.h b/source/include/md5.h
new file mode 100644
index 00000000000..070d8c307da
--- /dev/null
+++ b/source/include/md5.h
@@ -0,0 +1,32 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef MD5_H
+#define MD5_H
+
+struct MD5Context
+{
+ uint32 buf[4];
+ uint32 bits[2];
+ uchar in[64];
+};
+
+#endif /* !MD5_H */
diff --git a/source/include/nameserv.h b/source/include/nameserv.h
index 3473c74a56a..0de00f36368 100644
--- a/source/include/nameserv.h
+++ b/source/include/nameserv.h
@@ -142,7 +142,7 @@ enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH,
enum name_source {LMHOSTS_NAME, REGISTER_NAME, SELF_NAME, DNS_NAME,
DNSFAIL_NAME, PERMANENT_NAME, WINS_PROXY_NAME};
enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3};
-enum packet_type {NMB_PACKET, DGRAM_PACKET};
+enum packet_type {NMB_PACKET, DGRAM_PACKET, NMB_SOCK_PACKET, DGRAM_SOCK_PACKET };
enum master_state
{
@@ -501,6 +501,7 @@ struct packet_struct
#define QUERYFORPDC_R 12 /* Response to Query for PDC. */
#define SAMLOGON 18
#define SAMLOGON_R 19
+#define SAMLOGON_UNK_R 21
/* Ids for netbios packet types. */
@@ -546,6 +547,11 @@ struct packet_struct
affects non-permanent self names (in seconds) */
#define MAX_REFRESH_TIME (60*20)
+/* Types of machine we can announce as. */
+#define ANNOUNCE_AS_NT 1
+#define ANNOUNCE_AS_WIN95 2
+#define ANNOUNCE_AS_WFW 3
+
/* Macro's to enumerate subnets either with or without
the UNICAST subnet. */
diff --git a/source/include/nt_printing.h b/source/include/nt_printing.h
index 22c837c7481..a575c01e496 100644
--- a/source/include/nt_printing.h
+++ b/source/include/nt_printing.h
@@ -1,113 +1,3 @@
-#define ORIENTATION 0x00000001L
-#define PAPERSIZE 0x00000002L
-#define PAPERLENGTH 0x00000004L
-#define PAPERWIDTH 0x00000008L
-#define SCALE 0x00000010L
-#define COPIES 0x00000100L
-#define DEFAULTSOURCE 0x00000200L
-#define PRINTQUALITY 0x00000400L
-#define COLOR 0x00000800L
-#define DUPLEX 0x00001000L
-#define YRESOLUTION 0x00002000L
-#define TTOPTION 0x00004000L
-#define COLLATE 0x00008000L
-#define FORMNAME 0x00010000L
-#define LOGPIXELS 0x00020000L
-#define BITSPERPEL 0x00040000L
-#define PELSWIDTH 0x00080000L
-#define PELSHEIGHT 0x00100000L
-#define DISPLAYFLAGS 0x00200000L
-#define DISPLAYFREQUENCY 0x00400000L
-#define PANNINGWIDTH 0x00800000L
-#define PANNINGHEIGHT 0x01000000L
-
-#define ORIENT_PORTRAIT 1
-#define ORIENT_LANDSCAPE 2
-
-#define PAPER_FIRST PAPER_LETTER
-#define PAPER_LETTER 1 /* Letter 8 1/2 x 11 in */
-#define PAPER_LETTERSMALL 2 /* Letter Small 8 1/2 x 11 in */
-#define PAPER_TABLOID 3 /* Tabloid 11 x 17 in */
-#define PAPER_LEDGER 4 /* Ledger 17 x 11 in */
-#define PAPER_LEGAL 5 /* Legal 8 1/2 x 14 in */
-#define PAPER_STATEMENT 6 /* Statement 5 1/2 x 8 1/2 in */
-#define PAPER_EXECUTIVE 7 /* Executive 7 1/4 x 10 1/2 in */
-#define PAPER_A3 8 /* A3 297 x 420 mm */
-#define PAPER_A4 9 /* A4 210 x 297 mm */
-#define PAPER_A4SMALL 10 /* A4 Small 210 x 297 mm */
-#define PAPER_A5 11 /* A5 148 x 210 mm */
-#define PAPER_B4 12 /* B4 (JIS) 250 x 354 */
-#define PAPER_B5 13 /* B5 (JIS) 182 x 257 mm */
-#define PAPER_FOLIO 14 /* Folio 8 1/2 x 13 in */
-#define PAPER_QUARTO 15 /* Quarto 215 x 275 mm */
-#define PAPER_10X14 16 /* 10x14 in */
-#define PAPER_11X17 17 /* 11x17 in */
-#define PAPER_NOTE 18 /* Note 8 1/2 x 11 in */
-#define PAPER_ENV_9 19 /* Envelope #9 3 7/8 x 8 7/8 */
-#define PAPER_ENV_10 20 /* Envelope #10 4 1/8 x 9 1/2 */
-#define PAPER_ENV_11 21 /* Envelope #11 4 1/2 x 10 3/8 */
-#define PAPER_ENV_12 22 /* Envelope #12 4 \276 x 11 */
-#define PAPER_ENV_14 23 /* Envelope #14 5 x 11 1/2 */
-#define PAPER_CSHEET 24 /* C size sheet */
-#define PAPER_DSHEET 25 /* D size sheet */
-#define PAPER_ESHEET 26 /* E size sheet */
-#define PAPER_ENV_DL 27 /* Envelope DL 110 x 220mm */
-#define PAPER_ENV_C5 28 /* Envelope C5 162 x 229 mm */
-#define PAPER_ENV_C3 29 /* Envelope C3 324 x 458 mm */
-#define PAPER_ENV_C4 30 /* Envelope C4 229 x 324 mm */
-#define PAPER_ENV_C6 31 /* Envelope C6 114 x 162 mm */
-#define PAPER_ENV_C65 32 /* Envelope C65 114 x 229 mm */
-#define PAPER_ENV_B4 33 /* Envelope B4 250 x 353 mm */
-#define PAPER_ENV_B5 34 /* Envelope B5 176 x 250 mm */
-#define PAPER_ENV_B6 35 /* Envelope B6 176 x 125 mm */
-#define PAPER_ENV_ITALY 36 /* Envelope 110 x 230 mm */
-#define PAPER_ENV_MONARCH 37 /* Envelope Monarch 3.875 x 7.5 in */
-#define PAPER_ENV_PERSONAL 38 /* 6 3/4 Envelope 3 5/8 x 6 1/2 in */
-#define PAPER_FANFOLD_US 39 /* US Std Fanfold 14 7/8 x 11 in */
-#define PAPER_FANFOLD_STD_GERMAN 40 /* German Std Fanfold 8 1/2 x 12 in */
-#define PAPER_FANFOLD_LGL_GERMAN 41 /* German Legal Fanfold 8 1/2 x 13 in */
-
-#define PAPER_LAST PAPER_FANFOLD_LGL_GERMAN
-#define PAPER_USER 256
-
-#define BIN_FIRST BIN_UPPER
-#define BIN_UPPER 1
-#define BIN_ONLYONE 1
-#define BIN_LOWER 2
-#define BIN_MIDDLE 3
-#define BIN_MANUAL 4
-#define BIN_ENVELOPE 5
-#define BIN_ENVMANUAL 6
-#define BIN_AUTO 7
-#define BIN_TRACTOR 8
-#define BIN_SMALLFMT 9
-#define BIN_LARGEFMT 10
-#define BIN_LARGECAPACITY 11
-#define BIN_CASSETTE 14
-#define BIN_FORMSOURCE 15
-#define BIN_LAST BIN_FORMSOURCE
-
-#define BIN_USER 256 /* device specific bins start here */
-
-#define RES_DRAFT (-1)
-#define RES_LOW (-2)
-#define RES_MEDIUM (-3)
-#define RES_HIGH (-4)
-
-#define COLOR_MONOCHROME 1
-#define COLOR_COLOR 2
-
-#define DUP_SIMPLEX 1
-#define DUP_VERTICAL 2
-#define DUP_HORIZONTAL 3
-
-#define TT_BITMAP 1 /* print TT fonts as graphics */
-#define TT_DOWNLOAD 2 /* download TT fonts as soft fonts */
-#define TT_SUBDEV 3 /* substitute device fonts for TT fonts */
-
-#define COLLATE_FALSE 0
-#define COLLATE_TRUE 1
-
typedef struct nt_printer_driver_info_level_3
{
uint32 cversion;
@@ -209,29 +99,4 @@ typedef struct nt_printer_info_level
NT_PRINTER_INFO_LEVEL_2 *info_2;
} NT_PRINTER_INFO_LEVEL;
-typedef struct
-{
- char name[100];
- uint32 flag;
- uint32 width;
- uint32 length;
- uint32 left;
- uint32 top;
- uint32 right;
- uint32 bottom;
-} nt_forms_struct;
-/*
-typedef struct _form
-{
- uint32 flags;
- uint32 name_ptr;
- uint32 size_x;
- uint32 size_y;
- uint32 left;
- uint32 top;
- uint32 right;
- uint32 bottom;
- UNISTR2 name;
-} FORM;
-*/
diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h
index 7f3d4b49503..7925ab50ae8 100644
--- a/source/include/ntdomain.h
+++ b/source/include/ntdomain.h
@@ -21,178 +21,271 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */
-#define _NT_DOMAIN_H
+#ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */
+#define _NT_DOMAIN_H
-/*
- * A bunch of stuff that was put into smb.h
- * in the NTDOM branch - it didn't belong there.
- */
/* dce/rpc support */
#include "rpc_dce.h"
+/* dce/rpc authentication support */
+#include "rpc_ntlmssp.h"
+#include "rpc_netsec.h"
+
/* miscellaneous structures / defines */
#include "rpc_misc.h"
/* security descriptor structures */
-#include "rpc_secdes.h"
-
-typedef struct _prs_struct
-{
- BOOL io; /* parsing in or out of data stream */
- /*
- * If the (incoming) data is big-endian. On output we are
- * always little-endian.
- */
- BOOL bigendian_data;
- uint8 align; /* data alignment */
- BOOL is_dynamic; /* Do we own this memory or not ? */
- uint32 data_offset; /* Current working offset into data. */
- uint32 buffer_size; /* Current size of the buffer. */
- char *data_p; /* The buffer itself. */
-} prs_struct;
+#include "rpc_secdes.h"
-/*
- * Defines for io member of prs_struct.
+/* different dce/rpc pipes */
+#include "rpc_lsa.h"
+#include "rpc_netlogon.h"
+#include "rpc_samr.h"
+#include "rpc_srvsvc.h"
+#include "rpc_svcctl.h"
+#include "rpc_wkssvc.h"
+#include "rpc_atsvc.h"
+#include "rpc_spoolss.h"
+#include "rpc_eventlog.h"
+
+/* MS AD prototypes */
+#include "sam.h"
+
+/*
+ * A bunch of stuff that was put into smb.h
+ * in the NTDOM branch - it didn't belong there.
*/
-#define MARSHALL 0
-#define UNMARSHALL 1
-
-#define MARSHALLING(ps) (!(ps)->io)
-#define UNMARSHALLING(ps) ((ps)->io)
-
-typedef struct _input_data {
- /*
- * This is the current incoming pdu. The data here
- * is collected via multiple writes until a complete
- * pdu is seen, then the data is copied into the in_data
- * structure. The maximum size of this is 64k (2 byte length).
- */
- prs_struct in_pdu;
-
- /*
- * The amount of data needed to complete the in_pdu.
- * If this is zero, then we are at the start of a new
- * pdu.
- */
- uint32 in_pdu_needed_len;
-
- /*
- * This is the collection of input data with all
- * the rpc headers and auth footers removed.
- * The maximum length of this is strictly enforced.
- */
- prs_struct in_data;
-} input_data;
-
-typedef struct _output_data {
- /*
- * Raw RPC output data. This does not include RPC headers or footers.
- */
- prs_struct rdata;
-
- /* The amount of data sent from the current rdata struct. */
- uint32 data_sent_length;
-
- /*
- * The current PDU being returned. This inclues
- * headers, data and authentication footer.
- */
- unsigned char current_pdu[MAX_PDU_FRAG_LEN];
-
- /* The amount of data in the current_pdu buffer. */
- uint32 current_pdu_len;
-
- /* The amount of data sent from the current PDU. */
- uint32 current_pdu_sent;
-} output_data;
+#define CHECK_STRUCT(data) \
+{ \
+ if ((data)->struct_start != 0xfefefefe || \
+ (data)->struct_end != 0xdcdcdcdc) \
+ { \
+ DEBUG(0,("uninitialised structure (%s, %d)\n", \
+ FUNCTION_MACRO, __LINE__)); \
+ sleep(30); \
+ } \
+}
+
+typedef struct parse_struct
+{
+ uint32 struct_start;
-typedef struct pipes_struct
+ char *data; /* memory buffer */
+ size_t data_size; /* current memory buffer size */
+ /* array memory offsets */
+ uint32 start;
+ uint32 end;
+
+ uint32 offset; /* offset currently being accessed in memory buffer */
+ uint8 align; /* data alignment */
+ BOOL io; /* parsing in or out of data stream */
+ BOOL error; /* error occurred while parsing (out of memory bounds) */
+ BOOL bigendian; /* big-endian data */
+
+ struct parse_struct *next;
+
+ uint32 struct_end;
+
+}
+prs_struct;
+
+typedef struct netsec_auth_struct
{
- struct pipes_struct *next, *prev;
- int pnum;
- connection_struct *conn;
- uint16 vuid;
- BOOL open; /* open connection */
- uint16 device_state;
- uint16 priority;
- fstring name;
- fstring pipe_srv_name;
+ RPC_AUTH_NETSEC_NEG netsec_neg;
+ uchar sess_key[16];
- RPC_HDR hdr; /* Incoming RPC header. */
- RPC_HDR_REQ hdr_req; /* Incoming request header. */
+ uint32 seq_num;
+
+}
+netsec_auth_struct;
+
+typedef struct ntlmssp_auth_struct
+{
+ RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal;
- uint32 ntlmssp_chal_flags; /* Client challenge flags. */
- BOOL ntlmssp_auth_requested; /* If the client wanted authenticated rpc. */
- BOOL ntlmssp_auth_validated; /* If the client *got* authenticated rpc. */
- unsigned char challenge[8];
unsigned char ntlmssp_hash[258];
uint32 ntlmssp_seq_num;
- /*
- * Windows user info.
- */
- fstring user_name;
- fstring domain;
- fstring wks;
+}
+ntlmssp_auth_struct;
+
+struct srv_auth_fns;
+
+typedef struct rpcsrv_struct
+{
+ prs_struct data_i; /* input data (intermediate, for fragments) */
+ prs_struct rdata; /* output data (to create fragments from */
+
+ /* indicates how far in rdata we have got, creating fragments */
+ uint32 rdata_offset;
+
+ prs_struct smb_pdu;
+ prs_struct rsmb_pdu;
+
+ void *auth_info;
+ struct srv_auth_fns *auth;
+
+ /* set of authentication modules. does not include noauth */
+ uint32 num_auths;
+ struct srv_auth_fns **auth_fns;
+
+ BOOL auth_validated;
+ BOOL faulted_once_before;
- /*
- * Unix user name and credentials.
- */
- fstring unix_user_name;
- uid_t uid;
- gid_t gid;
+ RPC_HDR hdr;
+ RPC_HDR_BA hdr_ba;
+ RPC_HDR_RB hdr_rb;
+ RPC_HDR_REQ hdr_req;
- /*
- * Struct to deal with multiple pdu inputs.
- */
+ vuser_key key;
- input_data in_data;
+ int c; /* socket */
+
+}
+rpcsrv_struct;
+
+struct cli_connection;
+
+typedef struct cli_auth_fns
+{
+ /* these three will do for now. they *should* match with server-side */
+ BOOL (*create_bind_req) (struct cli_connection *, prs_struct *,
+ uint32, RPC_IFACE *, RPC_IFACE *);
+ BOOL (*decode_bind_resp) (struct cli_connection *, prs_struct *);
+ BOOL (*create_bind_cont) (struct cli_connection *, prs_struct *,
+ uint32);
+ /* creates an authenticated PDU */
+ BOOL (*cli_create_pdu) (struct cli_connection *, uint8,
+ prs_struct *, int, int *,
+ prs_struct *, uint8 *);
+ /* decodes an authenticated PDU */
+ BOOL (*cli_decode_pdu) (struct cli_connection *, prs_struct *,
+ int, int);
+
+}
+cli_auth_fns;
+
+typedef struct srv_auth_fns
+{
+ BOOL (*api_is_auth) (RPC_HDR_AUTH *, void **auth_info);
- /*
- * Struct to deal with multiple pdu outputs.
- */
+ /* state-based authentication: one to decode, one to generate */
+ BOOL (*api_auth_chk) (rpcsrv_struct *, enum RPC_PKT_TYPE);
+ BOOL (*api_auth_gen) (rpcsrv_struct *, prs_struct *,
+ enum RPC_PKT_TYPE);
- output_data out_data;
+ /* decodes an authenticated PDU */
+ BOOL (*api_decode_pdu) (rpcsrv_struct *);
+ /* creates an authenticated PDU */
+ BOOL (*api_create_pdu) (rpcsrv_struct *, uint32, prs_struct *);
- /* When replying to an SMBtrans, this is the maximum amount of
- data that can be sent in the initial reply. */
- int max_trans_reply;
+}
+srv_auth_fns;
+
+typedef struct pipes_struct
+{
+ struct pipes_struct *next, *prev;
+ int pnum;
+ vuser_key key;
+ uint16 device_state;
+ uint16 priority;
+ fstring name;
+ fstring pipe_srv_name;
/* remote, server-side rpc redirection */
- struct msrpc_state *m;
+ struct msrpc_local *m;
-} pipes_struct;
+ /* local, server-side rpc state processing */
+ rpcsrv_struct *l;
-struct api_struct
-{
- char *name;
- uint8 opnum;
- BOOL (*fn) (uint16 vuid, prs_struct*, prs_struct*);
-};
+}
+pipes_struct;
-typedef struct
-{
- uint32 rid;
- char *name;
+typedef struct msrpc_service_fns
+{
+ void (*auth_init) (rpcsrv_struct *);
+ void (*service_init) (char *);
+ BOOL (*reload_services) (BOOL);
+ int (*main_init) (int, char *[]);
+ void (*idle) (void);
+
+}
+msrpc_service_fns;
-} rid_name;
+struct api_struct
+{
+ char *name;
+ uint8 opnum;
+ BOOL (*fn) (rpcsrv_struct *, prs_struct *, prs_struct *);
+};
struct acct_info
{
- fstring acct_name; /* account name */
- uint32 smb_userid; /* domain-relative RID */
+ fstring acct_name; /* account name */
+ fstring acct_desc; /* account description */
+ uint32 rid; /* domain-relative RID */
};
-/* different dce/rpc pipes */
-#include "rpc_lsa.h"
-#include "rpc_netlogon.h"
-#include "rpc_reg.h"
-#include "rpc_samr.h"
-#include "rpc_srvsvc.h"
-#include "rpc_wkssvc.h"
-#include "rpc_spoolss.h"
+/*
+ * higher order functions for use with msrpc client code
+ */
+
+#define ALIAS_FN(fn)\
+ void (*fn)(const char*, const DOM_SID*, uint32, const char*)
+#define ALIAS_INFO_FN(fn)\
+ void (*fn)(const char*, const DOM_SID*, uint32, ALIAS_INFO_CTR *const)
+#define ALIAS_MEM_FN(fn)\
+ void(*fn)(const char*, const DOM_SID*, uint32, const char*,\
+ uint32, DOM_SID *const *const, char *const *const,\
+ uint32*const)
+
+#define GROUP_FN(fn)\
+ void (*fn)(const char*, const DOM_SID*, uint32, const char*)
+#define GROUP_INFO_FN(fn)\
+ void (*fn)(const char*, const DOM_SID*, uint32, GROUP_INFO_CTR *const)
+#define GROUP_MEM_FN(fn)\
+ void(*fn)(const char*, const DOM_SID*, uint32, const char*,\
+ uint32, const uint32*, char *const *const,\
+ uint32*const)
+
+#define DOMAIN_FN(fn)\
+ void (*fn)(const char*)
+#define DOMAIN_INFO_FN(fn)\
+ void (*fn)(const char*, const DOM_SID *, uint32, SAM_UNK_CTR *)
+
+#define USER_FN(fn)\
+ void (*fn)(const char*, const DOM_SID*, uint32, const char*)
+#define USER_INFO_FN(fn)\
+ void (*fn)(const char*, const DOM_SID*, uint32, \
+ SAM_USERINFO_CTR *const)
+#define USER_MEM_FN(fn)\
+ void (*fn)(const char*, const DOM_SID*, uint32, const char*,\
+ uint32, const uint32*, char *const *const, uint32* const)
+
+#define DISP_FN(fn)\
+ void (*fn)(const char*, const DOM_SID*, uint16, uint32, \
+ SAM_DISPINFO_CTR *)
+
+#define REG_FN(fn)\
+ void (*fn)(int, const char *, int)
+#define REG_KEY_FN(fn)\
+ void (*fn)(const char*, const char*, time_t)
+#define REG_VAL_FN(fn)\
+ void (*fn)(const char *, const char*, uint32, const BUFFER2 *)
+
+#define SVC_QUERY_FN(fn)\
+ void (*fn)(const QUERY_SERVICE_CONFIG *)
+#define SVC_INFO_FN(fn)\
+ void (*fn)(const ENUM_SRVC_STATUS *)
+
+#define TPRT_INFO_FN(fn)\
+ void (*fn)(const SRV_TPRT_INFO_CTR *)
+
+#define PRINT_INFO_FN(fn)\
+ void (*fn)(const char*, uint32, uint32, void *const *const)
+#define JOB_INFO_FN(fn)\
+ void (*fn)(const char*, const char*, uint32, uint32, void *const *const)
#endif /* _NT_DOMAIN_H */
diff --git a/source/include/nterr.h b/source/include/nterr.h
index 87935091195..78c1adb5adf 100644
--- a/source/include/nterr.h
+++ b/source/include/nterr.h
@@ -1,4 +1,3 @@
-
/* Win32 Status codes. */
#define STATUS_BUFFER_OVERFLOW (5)
@@ -8,511 +7,512 @@
#define ERROR_INSUFFICIENT_BUFFER (122)
#define STATUS_1804 (1804)
+
/* these are the NT error codes less than 1000. They are here for when
we start supporting NT error codes in Samba. They were extracted
using a loop in smbclient then printing a netmon sniff to a file */
-#define NT_STATUS_NO_PROBLEMO (0)
-#define NT_STATUS_UNSUCCESSFUL (1)
-#define NT_STATUS_NOT_IMPLEMENTED (2)
-#define NT_STATUS_INVALID_INFO_CLASS (3)
-#define NT_STATUS_INFO_LENGTH_MISMATCH (4)
-#define NT_STATUS_ACCESS_VIOLATION (5)
-#define STATUS_BUFFER_OVERFLOW (5)
-#define NT_STATUS_IN_PAGE_ERROR (6)
-#define NT_STATUS_PAGEFILE_QUOTA (7)
-#define NT_STATUS_INVALID_HANDLE (8)
-#define NT_STATUS_BAD_INITIAL_STACK (9)
-#define NT_STATUS_BAD_INITIAL_PC (10)
-#define NT_STATUS_INVALID_CID (11)
-#define NT_STATUS_TIMER_NOT_CANCELED (12)
-#define NT_STATUS_INVALID_PARAMETER (13)
-#define NT_STATUS_NO_SUCH_DEVICE (14)
-#define NT_STATUS_NO_SUCH_FILE (15)
-#define NT_STATUS_INVALID_DEVICE_REQUEST (16)
-#define NT_STATUS_END_OF_FILE (17)
-#define NT_STATUS_WRONG_VOLUME (18)
-#define NT_STATUS_NO_MEDIA_IN_DEVICE (19)
-#define NT_STATUS_UNRECOGNIZED_MEDIA (20)
-#define NT_STATUS_NONEXISTENT_SECTOR (21)
-#define NT_STATUS_MORE_PROCESSING_REQUIRED (22)
-#define NT_STATUS_NO_MEMORY (23)
-#define NT_STATUS_CONFLICTING_ADDRESSES (24)
-#define NT_STATUS_NOT_MAPPED_VIEW (25)
-#define NT_STATUS_UNABLE_TO_FREE_VM (26)
-#define NT_STATUS_UNABLE_TO_DELETE_SECTION (27)
-#define NT_STATUS_INVALID_SYSTEM_SERVICE (28)
-#define NT_STATUS_ILLEGAL_INSTRUCTION (29)
-#define NT_STATUS_INVALID_LOCK_SEQUENCE (30)
-#define NT_STATUS_INVALID_VIEW_SIZE (31)
-#define NT_STATUS_INVALID_FILE_FOR_SECTION (32)
-#define NT_STATUS_ALREADY_COMMITTED (33)
-#define NT_STATUS_ACCESS_DENIED (34)
-#define NT_STATUS_BUFFER_TOO_SMALL (35)
-#define NT_STATUS_OBJECT_TYPE_MISMATCH (36)
-#define NT_STATUS_NONCONTINUABLE_EXCEPTION (37)
-#define NT_STATUS_INVALID_DISPOSITION (38)
-#define NT_STATUS_UNWIND (39)
-#define NT_STATUS_BAD_STACK (40)
-#define NT_STATUS_INVALID_UNWIND_TARGET (41)
-#define NT_STATUS_NOT_LOCKED (42)
-#define NT_STATUS_PARITY_ERROR (43)
-#define NT_STATUS_UNABLE_TO_DECOMMIT_VM (44)
-#define NT_STATUS_NOT_COMMITTED (45)
-#define NT_STATUS_INVALID_PORT_ATTRIBUTES (46)
-#define NT_STATUS_PORT_MESSAGE_TOO_LONG (47)
-#define NT_STATUS_INVALID_PARAMETER_MIX (48)
-#define NT_STATUS_INVALID_QUOTA_LOWER (49)
-#define NT_STATUS_DISK_CORRUPT_ERROR (50)
-#define NT_STATUS_OBJECT_NAME_INVALID (51)
-#define NT_STATUS_OBJECT_NAME_NOT_FOUND (52)
-#define NT_STATUS_OBJECT_NAME_COLLISION (53)
-#define NT_STATUS_HANDLE_NOT_WAITABLE (54)
-#define NT_STATUS_PORT_DISCONNECTED (55)
-#define NT_STATUS_DEVICE_ALREADY_ATTACHED (56)
-#define NT_STATUS_OBJECT_PATH_INVALID (57)
-#define NT_STATUS_OBJECT_PATH_NOT_FOUND (58)
-#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD (59)
-#define NT_STATUS_DATA_OVERRUN (60)
-#define NT_STATUS_DATA_LATE_ERROR (61)
-#define NT_STATUS_DATA_ERROR (62)
-#define NT_STATUS_CRC_ERROR (63)
-#define NT_STATUS_SECTION_TOO_BIG (64)
-#define NT_STATUS_PORT_CONNECTION_REFUSED (65)
-#define NT_STATUS_INVALID_PORT_HANDLE (66)
-#define NT_STATUS_SHARING_VIOLATION (67)
-#define NT_STATUS_QUOTA_EXCEEDED (68)
-#define NT_STATUS_INVALID_PAGE_PROTECTION (69)
-#define NT_STATUS_MUTANT_NOT_OWNED (70)
-#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED (71)
-#define NT_STATUS_PORT_ALREADY_SET (72)
-#define NT_STATUS_SECTION_NOT_IMAGE (73)
-#define NT_STATUS_SUSPEND_COUNT_EXCEEDED (74)
-#define NT_STATUS_THREAD_IS_TERMINATING (75)
-#define NT_STATUS_BAD_WORKING_SET_LIMIT (76)
-#define NT_STATUS_INCOMPATIBLE_FILE_MAP (77)
-#define NT_STATUS_SECTION_PROTECTION (78)
-#define NT_STATUS_EAS_NOT_SUPPORTED (79)
-#define NT_STATUS_EA_TOO_LARGE (80)
-#define NT_STATUS_NONEXISTENT_EA_ENTRY (81)
-#define NT_STATUS_NO_EAS_ON_FILE (82)
-#define NT_STATUS_EA_CORRUPT_ERROR (83)
-#define NT_STATUS_FILE_LOCK_CONFLICT (84)
-#define NT_STATUS_LOCK_NOT_GRANTED (85)
-#define NT_STATUS_DELETE_PENDING (86)
-#define NT_STATUS_CTL_FILE_NOT_SUPPORTED (87)
-#define NT_STATUS_UNKNOWN_REVISION (88)
-#define NT_STATUS_REVISION_MISMATCH (89)
-#define NT_STATUS_INVALID_OWNER (90)
-#define NT_STATUS_INVALID_PRIMARY_GROUP (91)
-#define NT_STATUS_NO_IMPERSONATION_TOKEN (92)
-#define NT_STATUS_CANT_DISABLE_MANDATORY (93)
-#define NT_STATUS_NO_LOGON_SERVERS (94)
-#define NT_STATUS_NO_SUCH_LOGON_SESSION (95)
-#define NT_STATUS_NO_SUCH_PRIVILEGE (96)
-#define NT_STATUS_PRIVILEGE_NOT_HELD (97)
-#define NT_STATUS_INVALID_ACCOUNT_NAME (98)
-#define NT_STATUS_USER_EXISTS (99)
-#define NT_STATUS_NO_SUCH_USER (100)
-#define NT_STATUS_GROUP_EXISTS (101)
-#define NT_STATUS_NO_SUCH_GROUP (102)
-#define NT_STATUS_MEMBER_IN_GROUP (103)
-#define NT_STATUS_MEMBER_NOT_IN_GROUP (104)
-#define NT_STATUS_LAST_ADMIN (105)
-#define NT_STATUS_WRONG_PASSWORD (106)
-#define NT_STATUS_ILL_FORMED_PASSWORD (107)
-#define NT_STATUS_PASSWORD_RESTRICTION (108)
-#define NT_STATUS_LOGON_FAILURE (109)
-#define NT_STATUS_ACCOUNT_RESTRICTION (110)
-#define NT_STATUS_INVALID_LOGON_HOURS (111)
-#define NT_STATUS_INVALID_WORKSTATION (112)
-#define NT_STATUS_PASSWORD_EXPIRED (113)
-#define NT_STATUS_ACCOUNT_DISABLED (114)
-#define NT_STATUS_NONE_MAPPED (115)
-#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED (116)
-#define NT_STATUS_LUIDS_EXHAUSTED (117)
-#define NT_STATUS_INVALID_SUB_AUTHORITY (118)
-#define NT_STATUS_INVALID_ACL (119)
-#define NT_STATUS_INVALID_SID (120)
-#define NT_STATUS_INVALID_SECURITY_DESCR (121)
-#define NT_STATUS_PROCEDURE_NOT_FOUND (122)
-#define NT_STATUS_INVALID_IMAGE_FORMAT (123)
-#define NT_STATUS_NO_TOKEN (124)
-#define NT_STATUS_BAD_INHERITANCE_ACL (125)
-#define NT_STATUS_RANGE_NOT_LOCKED (126)
-#define NT_STATUS_DISK_FULL (127)
-#define NT_STATUS_SERVER_DISABLED (128)
-#define NT_STATUS_SERVER_NOT_DISABLED (129)
-#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED (130)
-#define NT_STATUS_GUIDS_EXHAUSTED (131)
-#define NT_STATUS_INVALID_ID_AUTHORITY (132)
-#define NT_STATUS_AGENTS_EXHAUSTED (133)
-#define NT_STATUS_INVALID_VOLUME_LABEL (134)
-#define NT_STATUS_SECTION_NOT_EXTENDED (135)
-#define NT_STATUS_NOT_MAPPED_DATA (136)
-#define NT_STATUS_RESOURCE_DATA_NOT_FOUND (137)
-#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND (138)
-#define NT_STATUS_RESOURCE_NAME_NOT_FOUND (139)
-#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED (140)
-#define NT_STATUS_FLOAT_DENORMAL_OPERAND (141)
-#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO (142)
-#define NT_STATUS_FLOAT_INEXACT_RESULT (143)
-#define NT_STATUS_FLOAT_INVALID_OPERATION (144)
-#define NT_STATUS_FLOAT_OVERFLOW (145)
-#define NT_STATUS_FLOAT_STACK_CHECK (146)
-#define NT_STATUS_FLOAT_UNDERFLOW (147)
-#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO (148)
-#define NT_STATUS_INTEGER_OVERFLOW (149)
-#define NT_STATUS_PRIVILEGED_INSTRUCTION (150)
-#define NT_STATUS_TOO_MANY_PAGING_FILES (151)
-#define NT_STATUS_FILE_INVALID (152)
-#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED (153)
-#define NT_STATUS_INSUFFICIENT_RESOURCES (154)
-#define NT_STATUS_DFS_EXIT_PATH_FOUND (155)
-#define NT_STATUS_DEVICE_DATA_ERROR (156)
-#define NT_STATUS_DEVICE_NOT_CONNECTED (157)
-#define NT_STATUS_DEVICE_POWER_FAILURE (158)
-#define NT_STATUS_FREE_VM_NOT_AT_BASE (159)
-#define NT_STATUS_MEMORY_NOT_ALLOCATED (160)
-#define NT_STATUS_WORKING_SET_QUOTA (161)
-#define NT_STATUS_MEDIA_WRITE_PROTECTED (162)
-#define NT_STATUS_DEVICE_NOT_READY (163)
-#define NT_STATUS_INVALID_GROUP_ATTRIBUTES (164)
-#define NT_STATUS_BAD_IMPERSONATION_LEVEL (165)
-#define NT_STATUS_CANT_OPEN_ANONYMOUS (166)
-#define NT_STATUS_BAD_VALIDATION_CLASS (167)
-#define NT_STATUS_BAD_TOKEN_TYPE (168)
-#define NT_STATUS_BAD_MASTER_BOOT_RECORD (169)
-#define NT_STATUS_INSTRUCTION_MISALIGNMENT (170)
-#define NT_STATUS_INSTANCE_NOT_AVAILABLE (171)
-#define NT_STATUS_PIPE_NOT_AVAILABLE (172)
-#define NT_STATUS_INVALID_PIPE_STATE (173)
-#define NT_STATUS_PIPE_BUSY (174)
-#define NT_STATUS_ILLEGAL_FUNCTION (175)
-#define NT_STATUS_PIPE_DISCONNECTED (176)
-#define NT_STATUS_PIPE_CLOSING (177)
-#define NT_STATUS_PIPE_CONNECTED (178)
-#define NT_STATUS_PIPE_LISTENING (179)
-#define NT_STATUS_INVALID_READ_MODE (180)
-#define NT_STATUS_IO_TIMEOUT (181)
-#define NT_STATUS_FILE_FORCED_CLOSED (182)
-#define NT_STATUS_PROFILING_NOT_STARTED (183)
-#define NT_STATUS_PROFILING_NOT_STOPPED (184)
-#define NT_STATUS_COULD_NOT_INTERPRET (185)
-#define NT_STATUS_FILE_IS_A_DIRECTORY (186)
-#define NT_STATUS_NOT_SUPPORTED (187)
-#define NT_STATUS_REMOTE_NOT_LISTENING (188)
-#define NT_STATUS_DUPLICATE_NAME (189)
-#define NT_STATUS_BAD_NETWORK_PATH (190)
-#define NT_STATUS_NETWORK_BUSY (191)
-#define NT_STATUS_DEVICE_DOES_NOT_EXIST (192)
-#define NT_STATUS_TOO_MANY_COMMANDS (193)
-#define NT_STATUS_ADAPTER_HARDWARE_ERROR (194)
-#define NT_STATUS_INVALID_NETWORK_RESPONSE (195)
-#define NT_STATUS_UNEXPECTED_NETWORK_ERROR (196)
-#define NT_STATUS_BAD_REMOTE_ADAPTER (197)
-#define NT_STATUS_PRINT_QUEUE_FULL (198)
-#define NT_STATUS_NO_SPOOL_SPACE (199)
-#define NT_STATUS_PRINT_CANCELLED (200)
-#define NT_STATUS_NETWORK_NAME_DELETED (201)
-#define NT_STATUS_NETWORK_ACCESS_DENIED (202)
-#define NT_STATUS_BAD_DEVICE_TYPE (203)
-#define NT_STATUS_BAD_NETWORK_NAME (204)
-#define NT_STATUS_TOO_MANY_NAMES (205)
-#define NT_STATUS_TOO_MANY_SESSIONS (206)
-#define NT_STATUS_SHARING_PAUSED (207)
-#define NT_STATUS_REQUEST_NOT_ACCEPTED (208)
-#define NT_STATUS_REDIRECTOR_PAUSED (209)
-#define NT_STATUS_NET_WRITE_FAULT (210)
-#define NT_STATUS_PROFILING_AT_LIMIT (211)
-#define NT_STATUS_NOT_SAME_DEVICE (212)
-#define NT_STATUS_FILE_RENAMED (213)
-#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED (214)
-#define NT_STATUS_NO_SECURITY_ON_OBJECT (215)
-#define NT_STATUS_CANT_WAIT (216)
-#define NT_STATUS_PIPE_EMPTY (217)
-#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO (218)
-#define NT_STATUS_CANT_TERMINATE_SELF (219)
-#define NT_STATUS_INVALID_SERVER_STATE (220)
-#define NT_STATUS_INVALID_DOMAIN_STATE (221)
-#define NT_STATUS_INVALID_DOMAIN_ROLE (222)
-#define NT_STATUS_NO_SUCH_DOMAIN (223)
-#define NT_STATUS_DOMAIN_EXISTS (224)
-#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED (225)
-#define NT_STATUS_OPLOCK_NOT_GRANTED (226)
-#define NT_STATUS_INVALID_OPLOCK_PROTOCOL (227)
-#define NT_STATUS_INTERNAL_DB_CORRUPTION (228)
-#define NT_STATUS_INTERNAL_ERROR (229)
-#define NT_STATUS_GENERIC_NOT_MAPPED (230)
-#define NT_STATUS_BAD_DESCRIPTOR_FORMAT (231)
-#define NT_STATUS_INVALID_USER_BUFFER (232)
-#define NT_STATUS_UNEXPECTED_IO_ERROR (233)
-#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR (234)
-#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR (235)
-#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR (236)
-#define NT_STATUS_NOT_LOGON_PROCESS (237)
-#define NT_STATUS_LOGON_SESSION_EXISTS (238)
-#define NT_STATUS_INVALID_PARAMETER_1 (239)
-#define NT_STATUS_INVALID_PARAMETER_2 (240)
-#define NT_STATUS_INVALID_PARAMETER_3 (241)
-#define NT_STATUS_INVALID_PARAMETER_4 (242)
-#define NT_STATUS_INVALID_PARAMETER_5 (243)
-#define NT_STATUS_INVALID_PARAMETER_6 (244)
-#define NT_STATUS_INVALID_PARAMETER_7 (245)
-#define NT_STATUS_INVALID_PARAMETER_8 (246)
-#define NT_STATUS_INVALID_PARAMETER_9 (247)
-#define NT_STATUS_INVALID_PARAMETER_10 (248)
-#define NT_STATUS_INVALID_PARAMETER_11 (249)
-#define NT_STATUS_INVALID_PARAMETER_12 (250)
-#define NT_STATUS_REDIRECTOR_NOT_STARTED (251)
-#define NT_STATUS_REDIRECTOR_STARTED (252)
-#define NT_STATUS_STACK_OVERFLOW (253)
-#define NT_STATUS_NO_SUCH_PACKAGE (254)
-#define NT_STATUS_BAD_FUNCTION_TABLE (255)
-#define NT_STATUS_DIRECTORY_NOT_EMPTY (257)
-#define NT_STATUS_FILE_CORRUPT_ERROR (258)
-#define NT_STATUS_NOT_A_DIRECTORY (259)
-#define NT_STATUS_BAD_LOGON_SESSION_STATE (260)
-#define NT_STATUS_LOGON_SESSION_COLLISION (261)
-#define NT_STATUS_NAME_TOO_LONG (262)
-#define NT_STATUS_FILES_OPEN (263)
-#define NT_STATUS_CONNECTION_IN_USE (264)
-#define NT_STATUS_MESSAGE_NOT_FOUND (265)
-#define NT_STATUS_PROCESS_IS_TERMINATING (266)
-#define NT_STATUS_INVALID_LOGON_TYPE (267)
-#define NT_STATUS_NO_GUID_TRANSLATION (268)
-#define NT_STATUS_CANNOT_IMPERSONATE (269)
-#define NT_STATUS_IMAGE_ALREADY_LOADED (270)
-#define NT_STATUS_ABIOS_NOT_PRESENT (271)
-#define NT_STATUS_ABIOS_LID_NOT_EXIST (272)
-#define NT_STATUS_ABIOS_LID_ALREADY_OWNED (273)
-#define NT_STATUS_ABIOS_NOT_LID_OWNER (274)
-#define NT_STATUS_ABIOS_INVALID_COMMAND (275)
-#define NT_STATUS_ABIOS_INVALID_LID (276)
-#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE (277)
-#define NT_STATUS_ABIOS_INVALID_SELECTOR (278)
-#define NT_STATUS_NO_LDT (279)
-#define NT_STATUS_INVALID_LDT_SIZE (280)
-#define NT_STATUS_INVALID_LDT_OFFSET (281)
-#define NT_STATUS_INVALID_LDT_DESCRIPTOR (282)
-#define NT_STATUS_INVALID_IMAGE_NE_FORMAT (283)
-#define NT_STATUS_RXACT_INVALID_STATE (284)
-#define NT_STATUS_RXACT_COMMIT_FAILURE (285)
-#define NT_STATUS_MAPPED_FILE_SIZE_ZERO (286)
-#define NT_STATUS_TOO_MANY_OPENED_FILES (287)
-#define NT_STATUS_CANCELLED (288)
-#define NT_STATUS_CANNOT_DELETE (289)
-#define NT_STATUS_INVALID_COMPUTER_NAME (290)
-#define NT_STATUS_FILE_DELETED (291)
-#define NT_STATUS_SPECIAL_ACCOUNT (292)
-#define NT_STATUS_SPECIAL_GROUP (293)
-#define NT_STATUS_SPECIAL_USER (294)
-#define NT_STATUS_MEMBERS_PRIMARY_GROUP (295)
-#define NT_STATUS_FILE_CLOSED (296)
-#define NT_STATUS_TOO_MANY_THREADS (297)
-#define NT_STATUS_THREAD_NOT_IN_PROCESS (298)
-#define NT_STATUS_TOKEN_ALREADY_IN_USE (299)
-#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED (300)
-#define NT_STATUS_COMMITMENT_LIMIT (301)
-#define NT_STATUS_INVALID_IMAGE_LE_FORMAT (302)
-#define NT_STATUS_INVALID_IMAGE_NOT_MZ (303)
-#define NT_STATUS_INVALID_IMAGE_PROTECT (304)
-#define NT_STATUS_INVALID_IMAGE_WIN_16 (305)
-#define NT_STATUS_LOGON_SERVER_CONFLICT (306)
-#define NT_STATUS_TIME_DIFFERENCE_AT_DC (307)
-#define NT_STATUS_SYNCHRONIZATION_REQUIRED (308)
-#define NT_STATUS_DLL_NOT_FOUND (309)
-#define NT_STATUS_OPEN_FAILED (310)
-#define NT_STATUS_IO_PRIVILEGE_FAILED (311)
-#define NT_STATUS_ORDINAL_NOT_FOUND (312)
-#define NT_STATUS_ENTRYPOINT_NOT_FOUND (313)
-#define NT_STATUS_CONTROL_C_EXIT (314)
-#define NT_STATUS_LOCAL_DISCONNECT (315)
-#define NT_STATUS_REMOTE_DISCONNECT (316)
-#define NT_STATUS_REMOTE_RESOURCES (317)
-#define NT_STATUS_LINK_FAILED (318)
-#define NT_STATUS_LINK_TIMEOUT (319)
-#define NT_STATUS_INVALID_CONNECTION (320)
-#define NT_STATUS_INVALID_ADDRESS (321)
-#define NT_STATUS_DLL_INIT_FAILED (322)
-#define NT_STATUS_MISSING_SYSTEMFILE (323)
-#define NT_STATUS_UNHANDLED_EXCEPTION (324)
-#define NT_STATUS_APP_INIT_FAILURE (325)
-#define NT_STATUS_PAGEFILE_CREATE_FAILED (326)
-#define NT_STATUS_NO_PAGEFILE (327)
-#define NT_STATUS_INVALID_LEVEL (328)
-#define NT_STATUS_WRONG_PASSWORD_CORE (329)
-#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT (330)
-#define NT_STATUS_PIPE_BROKEN (331)
-#define NT_STATUS_REGISTRY_CORRUPT (332)
-#define NT_STATUS_REGISTRY_IO_FAILED (333)
-#define NT_STATUS_NO_EVENT_PAIR (334)
-#define NT_STATUS_UNRECOGNIZED_VOLUME (335)
-#define NT_STATUS_SERIAL_NO_DEVICE_INITED (336)
-#define NT_STATUS_NO_SUCH_ALIAS (337)
-#define NT_STATUS_MEMBER_NOT_IN_ALIAS (338)
-#define NT_STATUS_MEMBER_IN_ALIAS (339)
-#define NT_STATUS_ALIAS_EXISTS (340)
-#define NT_STATUS_LOGON_NOT_GRANTED (341)
-#define NT_STATUS_TOO_MANY_SECRETS (342)
-#define NT_STATUS_SECRET_TOO_LONG (343)
-#define NT_STATUS_INTERNAL_DB_ERROR (344)
-#define NT_STATUS_FULLSCREEN_MODE (345)
-#define NT_STATUS_TOO_MANY_CONTEXT_IDS (346)
-#define NT_STATUS_LOGON_TYPE_NOT_GRANTED (347)
-#define NT_STATUS_NOT_REGISTRY_FILE (348)
-#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED (349)
-#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR (350)
-#define NT_STATUS_FT_MISSING_MEMBER (351)
-#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY (352)
-#define NT_STATUS_ILLEGAL_CHARACTER (353)
-#define NT_STATUS_UNMAPPABLE_CHARACTER (354)
-#define NT_STATUS_UNDEFINED_CHARACTER (355)
-#define NT_STATUS_FLOPPY_VOLUME (356)
-#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND (357)
-#define NT_STATUS_FLOPPY_WRONG_CYLINDER (358)
-#define NT_STATUS_FLOPPY_UNKNOWN_ERROR (359)
-#define NT_STATUS_FLOPPY_BAD_REGISTERS (360)
-#define NT_STATUS_DISK_RECALIBRATE_FAILED (361)
-#define NT_STATUS_DISK_OPERATION_FAILED (362)
-#define NT_STATUS_DISK_RESET_FAILED (363)
-#define NT_STATUS_SHARED_IRQ_BUSY (364)
-#define NT_STATUS_FT_ORPHANING (365)
-#define NT_STATUS_PARTITION_FAILURE (370)
-#define NT_STATUS_INVALID_BLOCK_LENGTH (371)
-#define NT_STATUS_DEVICE_NOT_PARTITIONED (372)
-#define NT_STATUS_UNABLE_TO_LOCK_MEDIA (373)
-#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA (374)
-#define NT_STATUS_EOM_OVERFLOW (375)
-#define NT_STATUS_NO_MEDIA (376)
-#define NT_STATUS_NO_SUCH_MEMBER (378)
-#define NT_STATUS_INVALID_MEMBER (379)
-#define NT_STATUS_KEY_DELETED (380)
-#define NT_STATUS_NO_LOG_SPACE (381)
-#define NT_STATUS_TOO_MANY_SIDS (382)
-#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED (383)
-#define NT_STATUS_KEY_HAS_CHILDREN (384)
-#define NT_STATUS_CHILD_MUST_BE_VOLATILE (385)
-#define NT_STATUS_DEVICE_CONFIGURATION_ERROR (386)
-#define NT_STATUS_DRIVER_INTERNAL_ERROR (387)
-#define NT_STATUS_INVALID_DEVICE_STATE (388)
-#define NT_STATUS_IO_DEVICE_ERROR (389)
-#define NT_STATUS_DEVICE_PROTOCOL_ERROR (390)
-#define NT_STATUS_BACKUP_CONTROLLER (391)
-#define NT_STATUS_LOG_FILE_FULL (392)
-#define NT_STATUS_TOO_LATE (393)
-#define NT_STATUS_NO_TRUST_LSA_SECRET (394)
-#define NT_STATUS_NO_TRUST_SAM_ACCOUNT (395)
-#define NT_STATUS_TRUSTED_DOMAIN_FAILURE (396)
-#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE (397)
-#define NT_STATUS_EVENTLOG_FILE_CORRUPT (398)
-#define NT_STATUS_EVENTLOG_CANT_START (399)
-#define NT_STATUS_TRUST_FAILURE (400)
-#define NT_STATUS_MUTANT_LIMIT_EXCEEDED (401)
-#define NT_STATUS_NETLOGON_NOT_STARTED (402)
-#define NT_STATUS_ACCOUNT_EXPIRED (403)
-#define NT_STATUS_POSSIBLE_DEADLOCK (404)
-#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT (405)
-#define NT_STATUS_REMOTE_SESSION_LIMIT (406)
-#define NT_STATUS_EVENTLOG_FILE_CHANGED (407)
-#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT (408)
-#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT (409)
-#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT (410)
-#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT (411)
-#define NT_STATUS_FS_DRIVER_REQUIRED (412)
-#define NT_STATUS_NO_USER_SESSION_KEY (514)
-#define NT_STATUS_USER_SESSION_DELETED (515)
-#define NT_STATUS_RESOURCE_LANG_NOT_FOUND (516)
-#define NT_STATUS_INSUFF_SERVER_RESOURCES (517)
-#define NT_STATUS_INVALID_BUFFER_SIZE (518)
-#define NT_STATUS_INVALID_ADDRESS_COMPONENT (519)
-#define NT_STATUS_INVALID_ADDRESS_WILDCARD (520)
-#define NT_STATUS_TOO_MANY_ADDRESSES (521)
-#define NT_STATUS_ADDRESS_ALREADY_EXISTS (522)
-#define NT_STATUS_ADDRESS_CLOSED (523)
-#define NT_STATUS_CONNECTION_DISCONNECTED (524)
-#define NT_STATUS_CONNECTION_RESET (525)
-#define NT_STATUS_TOO_MANY_NODES (526)
-#define NT_STATUS_TRANSACTION_ABORTED (527)
-#define NT_STATUS_TRANSACTION_TIMED_OUT (528)
-#define NT_STATUS_TRANSACTION_NO_RELEASE (529)
-#define NT_STATUS_TRANSACTION_NO_MATCH (530)
-#define NT_STATUS_TRANSACTION_RESPONDED (531)
-#define NT_STATUS_TRANSACTION_INVALID_ID (532)
-#define NT_STATUS_TRANSACTION_INVALID_TYPE (533)
-#define NT_STATUS_NOT_SERVER_SESSION (534)
-#define NT_STATUS_NOT_CLIENT_SESSION (535)
-#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE (536)
-#define NT_STATUS_DEBUG_ATTACH_FAILED (537)
-#define NT_STATUS_SYSTEM_PROCESS_TERMINATED (538)
-#define NT_STATUS_DATA_NOT_ACCEPTED (539)
-#define NT_STATUS_NO_BROWSER_SERVERS_FOUND (540)
-#define NT_STATUS_VDM_HARD_ERROR (541)
-#define NT_STATUS_DRIVER_CANCEL_TIMEOUT (542)
-#define NT_STATUS_REPLY_MESSAGE_MISMATCH (543)
-#define NT_STATUS_MAPPED_ALIGNMENT (544)
-#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH (545)
-#define NT_STATUS_LOST_WRITEBEHIND_DATA (546)
-#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID (547)
-#define NT_STATUS_PASSWORD_MUST_CHANGE (548)
-#define NT_STATUS_NOT_FOUND (549)
-#define NT_STATUS_NOT_TINY_STREAM (550)
-#define NT_STATUS_RECOVERY_FAILURE (551)
-#define NT_STATUS_STACK_OVERFLOW_READ (552)
-#define NT_STATUS_FAIL_CHECK (553)
-#define NT_STATUS_DUPLICATE_OBJECTID (554)
-#define NT_STATUS_OBJECTID_EXISTS (555)
-#define NT_STATUS_CONVERT_TO_LARGE (556)
-#define NT_STATUS_RETRY (557)
-#define NT_STATUS_FOUND_OUT_OF_SCOPE (558)
-#define NT_STATUS_ALLOCATE_BUCKET (559)
-#define NT_STATUS_PROPSET_NOT_FOUND (560)
-#define NT_STATUS_MARSHALL_OVERFLOW (561)
-#define NT_STATUS_INVALID_VARIANT (562)
-#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND (563)
-#define NT_STATUS_ACCOUNT_LOCKED_OUT (564)
-#define NT_STATUS_HANDLE_NOT_CLOSABLE (565)
-#define NT_STATUS_CONNECTION_REFUSED (566)
-#define NT_STATUS_GRACEFUL_DISCONNECT (567)
-#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED (568)
-#define NT_STATUS_ADDRESS_NOT_ASSOCIATED (569)
-#define NT_STATUS_CONNECTION_INVALID (570)
-#define NT_STATUS_CONNECTION_ACTIVE (571)
-#define NT_STATUS_NETWORK_UNREACHABLE (572)
-#define NT_STATUS_HOST_UNREACHABLE (573)
-#define NT_STATUS_PROTOCOL_UNREACHABLE (574)
-#define NT_STATUS_PORT_UNREACHABLE (575)
-#define NT_STATUS_REQUEST_ABORTED (576)
-#define NT_STATUS_CONNECTION_ABORTED (577)
-#define NT_STATUS_BAD_COMPRESSION_BUFFER (578)
-#define NT_STATUS_USER_MAPPED_FILE (579)
-#define NT_STATUS_AUDIT_FAILED (580)
-#define NT_STATUS_TIMER_RESOLUTION_NOT_SET (581)
-#define NT_STATUS_CONNECTION_COUNT_LIMIT (582)
-#define NT_STATUS_LOGIN_TIME_RESTRICTION (583)
-#define NT_STATUS_LOGIN_WKSTA_RESTRICTION (584)
-#define NT_STATUS_IMAGE_MP_UP_MISMATCH (585)
-#define NT_STATUS_INSUFFICIENT_LOGON_INFO (592)
-#define NT_STATUS_BAD_DLL_ENTRYPOINT (593)
-#define NT_STATUS_BAD_SERVICE_ENTRYPOINT (594)
-#define NT_STATUS_LPC_REPLY_LOST (595)
-#define NT_STATUS_IP_ADDRESS_CONFLICT1 (596)
-#define NT_STATUS_IP_ADDRESS_CONFLICT2 (597)
-#define NT_STATUS_REGISTRY_QUOTA_LIMIT (598)
-#define NT_STATUS_PATH_NOT_COVERED (599)
-#define NT_STATUS_NO_CALLBACK_ACTIVE (600)
-#define NT_STATUS_LICENSE_QUOTA_EXCEEDED (601)
-#define NT_STATUS_PWD_TOO_SHORT (602)
-#define NT_STATUS_PWD_TOO_RECENT (603)
-#define NT_STATUS_PWD_HISTORY_CONFLICT (604)
-#define NT_STATUS_PLUGPLAY_NO_DEVICE (606)
-#define NT_STATUS_UNSUPPORTED_COMPRESSION (607)
-#define NT_STATUS_INVALID_HW_PROFILE (608)
-#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH (609)
-#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND (610)
-#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND (611)
-#define NT_STATUS_RESOURCE_NOT_OWNED (612)
-#define NT_STATUS_TOO_MANY_LINKS (613)
-#define NT_STATUS_QUOTA_LIST_INCONSISTENT (614)
-#define NT_STATUS_FILE_IS_OFFLINE (615)
-#define NT_STATUS_NOTIFY_ENUM_DIR (0x10C)
+#define NT_STATUS_NOPROBLEMO (0x0)
+#define NT_STATUS_UNSUCCESSFUL (0xC0000000 | 1)
+#define NT_STATUS_NOT_IMPLEMENTED (0xC0000000 | 2)
+#define NT_STATUS_INVALID_INFO_CLASS (0xC0000000 | 3)
+#define NT_STATUS_INFO_LENGTH_MISMATCH (0xC0000000 | 4)
+#define NT_STATUS_ACCESS_VIOLATION (0xC0000000 | 5)
+#define NT_STATUS_IN_PAGE_ERROR (0xC0000000 | 6)
+#define NT_STATUS_PAGEFILE_QUOTA (0xC0000000 | 7)
+#define NT_STATUS_INVALID_HANDLE (0xC0000000 | 8)
+#define NT_STATUS_BAD_INITIAL_STACK (0xC0000000 | 9)
+#define NT_STATUS_BAD_INITIAL_PC (0xC0000000 | 10)
+#define NT_STATUS_INVALID_CID (0xC0000000 | 11)
+#define NT_STATUS_TIMER_NOT_CANCELED (0xC0000000 | 12)
+#define NT_STATUS_INVALID_PARAMETER (0xC0000000 | 13)
+#define NT_STATUS_NO_SUCH_DEVICE (0xC0000000 | 14)
+#define NT_STATUS_NO_SUCH_FILE (0xC0000000 | 15)
+#define NT_STATUS_INVALID_DEVICE_REQUEST (0xC0000000 | 16)
+#define NT_STATUS_END_OF_FILE (0xC0000000 | 17)
+#define NT_STATUS_WRONG_VOLUME (0xC0000000 | 18)
+#define NT_STATUS_NO_MEDIA_IN_DEVICE (0xC0000000 | 19)
+#define NT_STATUS_UNRECOGNIZED_MEDIA (0xC0000000 | 20)
+#define NT_STATUS_NONEXISTENT_SECTOR (0xC0000000 | 21)
+#define NT_STATUS_MORE_PROCESSING_REQUIRED (0xC0000000 | 22)
+#define NT_STATUS_NO_MEMORY (0xC0000000 | 23)
+#define NT_STATUS_CONFLICTING_ADDRESSES (0xC0000000 | 24)
+#define NT_STATUS_NOT_MAPPED_VIEW (0xC0000000 | 25)
+#define NT_STATUS_UNABLE_TO_FREE_VM (0x80000000 | 26)
+#define NT_STATUS_UNABLE_TO_DELETE_SECTION (0xC0000000 | 27)
+#define NT_STATUS_INVALID_SYSTEM_SERVICE (0xC0000000 | 28)
+#define NT_STATUS_ILLEGAL_INSTRUCTION (0xC0000000 | 29)
+#define NT_STATUS_INVALID_LOCK_SEQUENCE (0xC0000000 | 30)
+#define NT_STATUS_INVALID_VIEW_SIZE (0xC0000000 | 31)
+#define NT_STATUS_INVALID_FILE_FOR_SECTION (0xC0000000 | 32)
+#define NT_STATUS_ALREADY_COMMITTED (0xC0000000 | 33)
+#define NT_STATUS_ACCESS_DENIED (0xC0000000 | 34)
+#define NT_STATUS_BUFFER_TOO_SMALL (0xC0000000 | 35)
+#define NT_STATUS_OBJECT_TYPE_MISMATCH (0xC0000000 | 36)
+#define NT_STATUS_NONCONTINUABLE_EXCEPTION (0xC0000000 | 37)
+#define NT_STATUS_INVALID_DISPOSITION (0xC0000000 | 38)
+#define NT_STATUS_UNWIND (0xC0000000 | 39)
+#define NT_STATUS_BAD_STACK (0xC0000000 | 40)
+#define NT_STATUS_INVALID_UNWIND_TARGET (0xC0000000 | 41)
+#define NT_STATUS_NOT_LOCKED (0xC0000000 | 42)
+#define NT_STATUS_PARITY_ERROR (0xC0000000 | 43)
+#define NT_STATUS_UNABLE_TO_DECOMMIT_VM (0xC0000000 | 44)
+#define NT_STATUS_NOT_COMMITTED (0xC0000000 | 45)
+#define NT_STATUS_INVALID_PORT_ATTRIBUTES (0xC0000000 | 46)
+#define NT_STATUS_PORT_MESSAGE_TOO_LONG (0xC0000000 | 47)
+#define NT_STATUS_INVALID_PARAMETER_MIX (0xC0000000 | 48)
+#define NT_STATUS_INVALID_QUOTA_LOWER (0xC0000000 | 49)
+#define NT_STATUS_DISK_CORRUPT_ERROR (0xC0000000 | 50)
+#define NT_STATUS_OBJECT_NAME_INVALID (0xC0000000 | 51)
+#define NT_STATUS_OBJECT_NAME_NOT_FOUND (0xC0000000 | 52)
+#define NT_STATUS_OBJECT_NAME_COLLISION (0xC0000000 | 53)
+#define NT_STATUS_HANDLE_NOT_WAITABLE (0xC0000000 | 54)
+#define NT_STATUS_PORT_DISCONNECTED (0xC0000000 | 55)
+#define NT_STATUS_DEVICE_ALREADY_ATTACHED (0xC0000000 | 56)
+#define NT_STATUS_OBJECT_PATH_INVALID (0xC0000000 | 57)
+#define NT_STATUS_OBJECT_PATH_NOT_FOUND (0xC0000000 | 58)
+#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD (0xC0000000 | 59)
+#define NT_STATUS_DATA_OVERRUN (0xC0000000 | 60)
+#define NT_STATUS_DATA_LATE_ERROR (0xC0000000 | 61)
+#define NT_STATUS_DATA_ERROR (0xC0000000 | 62)
+#define NT_STATUS_CRC_ERROR (0xC0000000 | 63)
+#define NT_STATUS_SECTION_TOO_BIG (0xC0000000 | 64)
+#define NT_STATUS_PORT_CONNECTION_REFUSED (0xC0000000 | 65)
+#define NT_STATUS_INVALID_PORT_HANDLE (0xC0000000 | 66)
+#define NT_STATUS_SHARING_VIOLATION (0xC0000000 | 67)
+#define NT_STATUS_QUOTA_EXCEEDED (0xC0000000 | 68)
+#define NT_STATUS_INVALID_PAGE_PROTECTION (0xC0000000 | 69)
+#define NT_STATUS_MUTANT_NOT_OWNED (0xC0000000 | 70)
+#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED (0xC0000000 | 71)
+#define NT_STATUS_PORT_ALREADY_SET (0xC0000000 | 72)
+#define NT_STATUS_SECTION_NOT_IMAGE (0xC0000000 | 73)
+#define NT_STATUS_SUSPEND_COUNT_EXCEEDED (0xC0000000 | 74)
+#define NT_STATUS_THREAD_IS_TERMINATING (0xC0000000 | 75)
+#define NT_STATUS_BAD_WORKING_SET_LIMIT (0xC0000000 | 76)
+#define NT_STATUS_INCOMPATIBLE_FILE_MAP (0xC0000000 | 77)
+#define NT_STATUS_SECTION_PROTECTION (0xC0000000 | 78)
+#define NT_STATUS_EAS_NOT_SUPPORTED (0xC0000000 | 79)
+#define NT_STATUS_EA_TOO_LARGE (0xC0000000 | 80)
+#define NT_STATUS_NONEXISTENT_EA_ENTRY (0xC0000000 | 81)
+#define NT_STATUS_NO_EAS_ON_FILE (0xC0000000 | 82)
+#define NT_STATUS_EA_CORRUPT_ERROR (0xC0000000 | 83)
+#define NT_STATUS_FILE_LOCK_CONFLICT (0xC0000000 | 84)
+#define NT_STATUS_LOCK_NOT_GRANTED (0xC0000000 | 85)
+#define NT_STATUS_DELETE_PENDING (0xC0000000 | 86)
+#define NT_STATUS_CTL_FILE_NOT_SUPPORTED (0xC0000000 | 87)
+#define NT_STATUS_UNKNOWN_REVISION (0xC0000000 | 88)
+#define NT_STATUS_REVISION_MISMATCH (0xC0000000 | 89)
+#define NT_STATUS_INVALID_OWNER (0xC0000000 | 90)
+#define NT_STATUS_INVALID_PRIMARY_GROUP (0xC0000000 | 91)
+#define NT_STATUS_NO_IMPERSONATION_TOKEN (0xC0000000 | 92)
+#define NT_STATUS_CANT_DISABLE_MANDATORY (0xC0000000 | 93)
+#define NT_STATUS_NO_LOGON_SERVERS (0xC0000000 | 94)
+#define NT_STATUS_NO_SUCH_LOGON_SESSION (0xC0000000 | 95)
+#define NT_STATUS_NO_SUCH_PRIVILEGE (0xC0000000 | 96)
+#define NT_STATUS_PRIVILEGE_NOT_HELD (0xC0000000 | 97)
+#define NT_STATUS_INVALID_ACCOUNT_NAME (0xC0000000 | 98)
+#define NT_STATUS_USER_EXISTS (0xC0000000 | 99)
+#define NT_STATUS_NO_SUCH_USER (0xC0000000 | 100)
+#define NT_STATUS_GROUP_EXISTS (0xC0000000 | 101)
+#define NT_STATUS_NO_SUCH_GROUP (0xC0000000 | 102)
+#define NT_STATUS_MEMBER_IN_GROUP (0xC0000000 | 103)
+#define NT_STATUS_MEMBER_NOT_IN_GROUP (0xC0000000 | 104)
+#define NT_STATUS_LAST_ADMIN (0xC0000000 | 105)
+#define NT_STATUS_WRONG_PASSWORD (0xC0000000 | 106)
+#define NT_STATUS_ILL_FORMED_PASSWORD (0xC0000000 | 107)
+#define NT_STATUS_PASSWORD_RESTRICTION (0xC0000000 | 108)
+#define NT_STATUS_LOGON_FAILURE (0xC0000000 | 109)
+#define NT_STATUS_ACCOUNT_RESTRICTION (0xC0000000 | 110)
+#define NT_STATUS_INVALID_LOGON_HOURS (0xC0000000 | 111)
+#define NT_STATUS_INVALID_WORKSTATION (0xC0000000 | 112)
+#define NT_STATUS_PASSWORD_EXPIRED (0xC0000000 | 113)
+#define NT_STATUS_ACCOUNT_DISABLED (0xC0000000 | 114)
+#define NT_STATUS_NONE_MAPPED (0xC0000000 | 115)
+#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED (0xC0000000 | 116)
+#define NT_STATUS_LUIDS_EXHAUSTED (0xC0000000 | 117)
+#define NT_STATUS_INVALID_SUB_AUTHORITY (0xC0000000 | 118)
+#define NT_STATUS_INVALID_ACL (0xC0000000 | 119)
+#define NT_STATUS_INVALID_SID (0xC0000000 | 120)
+#define NT_STATUS_INVALID_SECURITY_DESCR (0xC0000000 | 121)
+#define NT_STATUS_PROCEDURE_NOT_FOUND (0xC0000000 | 122)
+#define NT_STATUS_INVALID_IMAGE_FORMAT (0xC0000000 | 123)
+#define NT_STATUS_NO_TOKEN (0xC0000000 | 124)
+#define NT_STATUS_BAD_INHERITANCE_ACL (0xC0000000 | 125)
+#define NT_STATUS_RANGE_NOT_LOCKED (0xC0000000 | 126)
+#define NT_STATUS_DISK_FULL (0xC0000000 | 127)
+#define NT_STATUS_SERVER_DISABLED (0xC0000000 | 128)
+#define NT_STATUS_SERVER_NOT_DISABLED (0xC0000000 | 129)
+#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED (0xC0000000 | 130)
+#define NT_STATUS_GUIDS_EXHAUSTED (0xC0000000 | 131)
+#define NT_STATUS_INVALID_ID_AUTHORITY (0xC0000000 | 132)
+#define NT_STATUS_AGENTS_EXHAUSTED (0xC0000000 | 133)
+#define NT_STATUS_INVALID_VOLUME_LABEL (0xC0000000 | 134)
+#define NT_STATUS_SECTION_NOT_EXTENDED (0xC0000000 | 135)
+#define NT_STATUS_NOT_MAPPED_DATA (0xC0000000 | 136)
+#define NT_STATUS_RESOURCE_DATA_NOT_FOUND (0xC0000000 | 137)
+#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND (0xC0000000 | 138)
+#define NT_STATUS_RESOURCE_NAME_NOT_FOUND (0xC0000000 | 139)
+#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED (0xC0000000 | 140)
+#define NT_STATUS_FLOAT_DENORMAL_OPERAND (0xC0000000 | 141)
+#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO (0xC0000000 | 142)
+#define NT_STATUS_FLOAT_INEXACT_RESULT (0xC0000000 | 143)
+#define NT_STATUS_FLOAT_INVALID_OPERATION (0xC0000000 | 144)
+#define NT_STATUS_FLOAT_OVERFLOW (0xC0000000 | 145)
+#define NT_STATUS_FLOAT_STACK_CHECK (0xC0000000 | 146)
+#define NT_STATUS_FLOAT_UNDERFLOW (0xC0000000 | 147)
+#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO (0xC0000000 | 148)
+#define NT_STATUS_INTEGER_OVERFLOW (0xC0000000 | 149)
+#define NT_STATUS_PRIVILEGED_INSTRUCTION (0xC0000000 | 150)
+#define NT_STATUS_TOO_MANY_PAGING_FILES (0xC0000000 | 151)
+#define NT_STATUS_FILE_INVALID (0xC0000000 | 152)
+#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED (0xC0000000 | 153)
+#define NT_STATUS_INSUFFICIENT_RESOURCES (0xC0000000 | 154)
+#define NT_STATUS_DFS_EXIT_PATH_FOUND (0xC0000000 | 155)
+#define NT_STATUS_DEVICE_DATA_ERROR (0xC0000000 | 156)
+#define NT_STATUS_DEVICE_NOT_CONNECTED (0xC0000000 | 157)
+#define NT_STATUS_DEVICE_POWER_FAILURE (0xC0000000 | 158)
+#define NT_STATUS_FREE_VM_NOT_AT_BASE (0xC0000000 | 159)
+#define NT_STATUS_MEMORY_NOT_ALLOCATED (0xC0000000 | 160)
+#define NT_STATUS_WORKING_SET_QUOTA (0xC0000000 | 161)
+#define NT_STATUS_MEDIA_WRITE_PROTECTED (0xC0000000 | 162)
+#define NT_STATUS_DEVICE_NOT_READY (0xC0000000 | 163)
+#define NT_STATUS_INVALID_GROUP_ATTRIBUTES (0xC0000000 | 164)
+#define NT_STATUS_BAD_IMPERSONATION_LEVEL (0xC0000000 | 165)
+#define NT_STATUS_CANT_OPEN_ANONYMOUS (0xC0000000 | 166)
+#define NT_STATUS_BAD_VALIDATION_CLASS (0xC0000000 | 167)
+#define NT_STATUS_BAD_TOKEN_TYPE (0xC0000000 | 168)
+#define NT_STATUS_BAD_MASTER_BOOT_RECORD (0xC0000000 | 169)
+#define NT_STATUS_INSTRUCTION_MISALIGNMENT (0xC0000000 | 170)
+#define NT_STATUS_INSTANCE_NOT_AVAILABLE (0xC0000000 | 171)
+#define NT_STATUS_PIPE_NOT_AVAILABLE (0xC0000000 | 172)
+#define NT_STATUS_INVALID_PIPE_STATE (0xC0000000 | 173)
+#define NT_STATUS_PIPE_BUSY (0xC0000000 | 174)
+#define NT_STATUS_ILLEGAL_FUNCTION (0xC0000000 | 175)
+#define NT_STATUS_PIPE_DISCONNECTED (0xC0000000 | 176)
+#define NT_STATUS_PIPE_CLOSING (0xC0000000 | 177)
+#define NT_STATUS_PIPE_CONNECTED (0xC0000000 | 178)
+#define NT_STATUS_PIPE_LISTENING (0xC0000000 | 179)
+#define NT_STATUS_INVALID_READ_MODE (0xC0000000 | 180)
+#define NT_STATUS_IO_TIMEOUT (0xC0000000 | 181)
+#define NT_STATUS_FILE_FORCED_CLOSED (0xC0000000 | 182)
+#define NT_STATUS_PROFILING_NOT_STARTED (0xC0000000 | 183)
+#define NT_STATUS_PROFILING_NOT_STOPPED (0xC0000000 | 184)
+#define NT_STATUS_COULD_NOT_INTERPRET (0xC0000000 | 185)
+#define NT_STATUS_FILE_IS_A_DIRECTORY (0xC0000000 | 186)
+#define NT_STATUS_NOT_SUPPORTED (0xC0000000 | 187)
+#define NT_STATUS_REMOTE_NOT_LISTENING (0xC0000000 | 188)
+#define NT_STATUS_DUPLICATE_NAME (0xC0000000 | 189)
+#define NT_STATUS_BAD_NETWORK_PATH (0xC0000000 | 190)
+#define NT_STATUS_NETWORK_BUSY (0xC0000000 | 191)
+#define NT_STATUS_DEVICE_DOES_NOT_EXIST (0xC0000000 | 192)
+#define NT_STATUS_TOO_MANY_COMMANDS (0xC0000000 | 193)
+#define NT_STATUS_ADAPTER_HARDWARE_ERROR (0xC0000000 | 194)
+#define NT_STATUS_INVALID_NETWORK_RESPONSE (0xC0000000 | 195)
+#define NT_STATUS_UNEXPECTED_NETWORK_ERROR (0xC0000000 | 196)
+#define NT_STATUS_BAD_REMOTE_ADAPTER (0xC0000000 | 197)
+#define NT_STATUS_PRINT_QUEUE_FULL (0xC0000000 | 198)
+#define NT_STATUS_NO_SPOOL_SPACE (0xC0000000 | 199)
+#define NT_STATUS_PRINT_CANCELLED (0xC0000000 | 200)
+#define NT_STATUS_NETWORK_NAME_DELETED (0xC0000000 | 201)
+#define NT_STATUS_NETWORK_ACCESS_DENIED (0xC0000000 | 202)
+#define NT_STATUS_BAD_DEVICE_TYPE (0xC0000000 | 203)
+#define NT_STATUS_BAD_NETWORK_NAME (0xC0000000 | 204)
+#define NT_STATUS_TOO_MANY_NAMES (0xC0000000 | 205)
+#define NT_STATUS_TOO_MANY_SESSIONS (0xC0000000 | 206)
+#define NT_STATUS_SHARING_PAUSED (0xC0000000 | 207)
+#define NT_STATUS_REQUEST_NOT_ACCEPTED (0xC0000000 | 208)
+#define NT_STATUS_REDIRECTOR_PAUSED (0xC0000000 | 209)
+#define NT_STATUS_NET_WRITE_FAULT (0xC0000000 | 210)
+#define NT_STATUS_PROFILING_AT_LIMIT (0xC0000000 | 211)
+#define NT_STATUS_NOT_SAME_DEVICE (0xC0000000 | 212)
+#define NT_STATUS_FILE_RENAMED (0xC0000000 | 213)
+#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED (0xC0000000 | 214)
+#define NT_STATUS_NO_SECURITY_ON_OBJECT (0xC0000000 | 215)
+#define NT_STATUS_CANT_WAIT (0xC0000000 | 216)
+#define NT_STATUS_PIPE_EMPTY (0xC0000000 | 217)
+#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO (0xC0000000 | 218)
+#define NT_STATUS_CANT_TERMINATE_SELF (0xC0000000 | 219)
+#define NT_STATUS_INVALID_SERVER_STATE (0xC0000000 | 220)
+#define NT_STATUS_INVALID_DOMAIN_STATE (0xC0000000 | 221)
+#define NT_STATUS_INVALID_DOMAIN_ROLE (0xC0000000 | 222)
+#define NT_STATUS_NO_SUCH_DOMAIN (0xC0000000 | 223)
+#define NT_STATUS_DOMAIN_EXISTS (0xC0000000 | 224)
+#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED (0xC0000000 | 225)
+#define NT_STATUS_OPLOCK_NOT_GRANTED (0xC0000000 | 226)
+#define NT_STATUS_INVALID_OPLOCK_PROTOCOL (0xC0000000 | 227)
+#define NT_STATUS_INTERNAL_DB_CORRUPTION (0xC0000000 | 228)
+#define NT_STATUS_INTERNAL_ERROR (0xC0000000 | 229)
+#define NT_STATUS_GENERIC_NOT_MAPPED (0xC0000000 | 230)
+#define NT_STATUS_BAD_DESCRIPTOR_FORMAT (0xC0000000 | 231)
+#define NT_STATUS_INVALID_USER_BUFFER (0xC0000000 | 232)
+#define NT_STATUS_UNEXPECTED_IO_ERROR (0xC0000000 | 233)
+#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR (0xC0000000 | 234)
+#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR (0xC0000000 | 235)
+#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR (0xC0000000 | 236)
+#define NT_STATUS_NOT_LOGON_PROCESS (0xC0000000 | 237)
+#define NT_STATUS_LOGON_SESSION_EXISTS (0xC0000000 | 238)
+#define NT_STATUS_INVALID_PARAMETER_1 (0xC0000000 | 239)
+#define NT_STATUS_INVALID_PARAMETER_2 (0xC0000000 | 240)
+#define NT_STATUS_INVALID_PARAMETER_3 (0xC0000000 | 241)
+#define NT_STATUS_INVALID_PARAMETER_4 (0xC0000000 | 242)
+#define NT_STATUS_INVALID_PARAMETER_5 (0xC0000000 | 243)
+#define NT_STATUS_INVALID_PARAMETER_6 (0xC0000000 | 244)
+#define NT_STATUS_INVALID_PARAMETER_7 (0xC0000000 | 245)
+#define NT_STATUS_INVALID_PARAMETER_8 (0xC0000000 | 246)
+#define NT_STATUS_INVALID_PARAMETER_9 (0xC0000000 | 247)
+#define NT_STATUS_INVALID_PARAMETER_10 (0xC0000000 | 248)
+#define NT_STATUS_INVALID_PARAMETER_11 (0xC0000000 | 249)
+#define NT_STATUS_INVALID_PARAMETER_12 (0xC0000000 | 250)
+#define NT_STATUS_REDIRECTOR_NOT_STARTED (0xC0000000 | 251)
+#define NT_STATUS_REDIRECTOR_STARTED (0xC0000000 | 252)
+#define NT_STATUS_STACK_OVERFLOW (0xC0000000 | 253)
+#define NT_STATUS_NO_SUCH_PACKAGE (0xC0000000 | 254)
+#define NT_STATUS_BAD_FUNCTION_TABLE (0xC0000000 | 255)
+#define NT_STATUS_DIRECTORY_NOT_EMPTY (0xC0000000 | 257)
+#define NT_STATUS_FILE_CORRUPT_ERROR (0xC0000000 | 258)
+#define NT_STATUS_NOT_A_DIRECTORY (0xC0000000 | 259)
+#define NT_STATUS_BAD_LOGON_SESSION_STATE (0xC0000000 | 260)
+#define NT_STATUS_LOGON_SESSION_COLLISION (0xC0000000 | 261)
+#define NT_STATUS_NAME_TOO_LONG (0xC0000000 | 262)
+#define NT_STATUS_FILES_OPEN (0xC0000000 | 263)
+#define NT_STATUS_CONNECTION_IN_USE (0xC0000000 | 264)
+#define NT_STATUS_MESSAGE_NOT_FOUND (0xC0000000 | 265)
+#define NT_STATUS_PROCESS_IS_TERMINATING (0xC0000000 | 266)
+#define NT_STATUS_INVALID_LOGON_TYPE (0xC0000000 | 267)
+#define NT_STATUS_NO_GUID_TRANSLATION (0xC0000000 | 268)
+#define NT_STATUS_CANNOT_IMPERSONATE (0xC0000000 | 269)
+#define NT_STATUS_IMAGE_ALREADY_LOADED (0xC0000000 | 270)
+#define NT_STATUS_ABIOS_NOT_PRESENT (0xC0000000 | 271)
+#define NT_STATUS_ABIOS_LID_NOT_EXIST (0xC0000000 | 272)
+#define NT_STATUS_ABIOS_LID_ALREADY_OWNED (0xC0000000 | 273)
+#define NT_STATUS_ABIOS_NOT_LID_OWNER (0xC0000000 | 274)
+#define NT_STATUS_ABIOS_INVALID_COMMAND (0xC0000000 | 275)
+#define NT_STATUS_ABIOS_INVALID_LID (0xC0000000 | 276)
+#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE (0xC0000000 | 277)
+#define NT_STATUS_ABIOS_INVALID_SELECTOR (0xC0000000 | 278)
+#define NT_STATUS_NO_LDT (0xC0000000 | 279)
+#define NT_STATUS_INVALID_LDT_SIZE (0xC0000000 | 280)
+#define NT_STATUS_INVALID_LDT_OFFSET (0xC0000000 | 281)
+#define NT_STATUS_INVALID_LDT_DESCRIPTOR (0xC0000000 | 282)
+#define NT_STATUS_INVALID_IMAGE_NE_FORMAT (0xC0000000 | 283)
+#define NT_STATUS_RXACT_INVALID_STATE (0xC0000000 | 284)
+#define NT_STATUS_RXACT_COMMIT_FAILURE (0xC0000000 | 285)
+#define NT_STATUS_MAPPED_FILE_SIZE_ZERO (0xC0000000 | 286)
+#define NT_STATUS_TOO_MANY_OPENED_FILES (0xC0000000 | 287)
+#define NT_STATUS_CANCELLED (0xC0000000 | 288)
+#define NT_STATUS_CANNOT_DELETE (0xC0000000 | 289)
+#define NT_STATUS_INVALID_COMPUTER_NAME (0xC0000000 | 290)
+#define NT_STATUS_FILE_DELETED (0xC0000000 | 291)
+#define NT_STATUS_SPECIAL_ACCOUNT (0xC0000000 | 292)
+#define NT_STATUS_SPECIAL_GROUP (0xC0000000 | 293)
+#define NT_STATUS_SPECIAL_USER (0xC0000000 | 294)
+#define NT_STATUS_MEMBERS_PRIMARY_GROUP (0xC0000000 | 295)
+#define NT_STATUS_FILE_CLOSED (0xC0000000 | 296)
+#define NT_STATUS_TOO_MANY_THREADS (0xC0000000 | 297)
+#define NT_STATUS_THREAD_NOT_IN_PROCESS (0xC0000000 | 298)
+#define NT_STATUS_TOKEN_ALREADY_IN_USE (0xC0000000 | 299)
+#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED (0xC0000000 | 300)
+#define NT_STATUS_COMMITMENT_LIMIT (0xC0000000 | 301)
+#define NT_STATUS_INVALID_IMAGE_LE_FORMAT (0xC0000000 | 302)
+#define NT_STATUS_INVALID_IMAGE_NOT_MZ (0xC0000000 | 303)
+#define NT_STATUS_INVALID_IMAGE_PROTECT (0xC0000000 | 304)
+#define NT_STATUS_INVALID_IMAGE_WIN_16 (0xC0000000 | 305)
+#define NT_STATUS_LOGON_SERVER_CONFLICT (0xC0000000 | 306)
+#define NT_STATUS_TIME_DIFFERENCE_AT_DC (0xC0000000 | 307)
+#define NT_STATUS_SYNCHRONIZATION_REQUIRED (0xC0000000 | 308)
+#define NT_STATUS_DLL_NOT_FOUND (0xC0000000 | 309)
+#define NT_STATUS_OPEN_FAILED (0xC0000000 | 310)
+#define NT_STATUS_IO_PRIVILEGE_FAILED (0xC0000000 | 311)
+#define NT_STATUS_ORDINAL_NOT_FOUND (0xC0000000 | 312)
+#define NT_STATUS_ENTRYPOINT_NOT_FOUND (0xC0000000 | 313)
+#define NT_STATUS_CONTROL_C_EXIT (0xC0000000 | 314)
+#define NT_STATUS_LOCAL_DISCONNECT (0xC0000000 | 315)
+#define NT_STATUS_REMOTE_DISCONNECT (0xC0000000 | 316)
+#define NT_STATUS_REMOTE_RESOURCES (0xC0000000 | 317)
+#define NT_STATUS_LINK_FAILED (0xC0000000 | 318)
+#define NT_STATUS_LINK_TIMEOUT (0xC0000000 | 319)
+#define NT_STATUS_INVALID_CONNECTION (0xC0000000 | 320)
+#define NT_STATUS_INVALID_ADDRESS (0xC0000000 | 321)
+#define NT_STATUS_DLL_INIT_FAILED (0xC0000000 | 322)
+#define NT_STATUS_MISSING_SYSTEMFILE (0xC0000000 | 323)
+#define NT_STATUS_UNHANDLED_EXCEPTION (0xC0000000 | 324)
+#define NT_STATUS_APP_INIT_FAILURE (0xC0000000 | 325)
+#define NT_STATUS_PAGEFILE_CREATE_FAILED (0xC0000000 | 326)
+#define NT_STATUS_NO_PAGEFILE (0xC0000000 | 327)
+#define NT_STATUS_INVALID_LEVEL (0xC0000000 | 328)
+#define NT_STATUS_WRONG_PASSWORD_CORE (0xC0000000 | 329)
+#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT (0xC0000000 | 330)
+#define NT_STATUS_PIPE_BROKEN (0xC0000000 | 331)
+#define NT_STATUS_REGISTRY_CORRUPT (0xC0000000 | 332)
+#define NT_STATUS_REGISTRY_IO_FAILED (0xC0000000 | 333)
+#define NT_STATUS_NO_EVENT_PAIR (0xC0000000 | 334)
+#define NT_STATUS_UNRECOGNIZED_VOLUME (0xC0000000 | 335)
+#define NT_STATUS_SERIAL_NO_DEVICE_INITED (0xC0000000 | 336)
+#define NT_STATUS_NO_SUCH_ALIAS (0xC0000000 | 337)
+#define NT_STATUS_MEMBER_NOT_IN_ALIAS (0xC0000000 | 338)
+#define NT_STATUS_MEMBER_IN_ALIAS (0xC0000000 | 339)
+#define NT_STATUS_ALIAS_EXISTS (0xC0000000 | 340)
+#define NT_STATUS_LOGON_NOT_GRANTED (0xC0000000 | 341)
+#define NT_STATUS_TOO_MANY_SECRETS (0xC0000000 | 342)
+#define NT_STATUS_SECRET_TOO_LONG (0xC0000000 | 343)
+#define NT_STATUS_INTERNAL_DB_ERROR (0xC0000000 | 344)
+#define NT_STATUS_FULLSCREEN_MODE (0xC0000000 | 345)
+#define NT_STATUS_TOO_MANY_CONTEXT_IDS (0xC0000000 | 346)
+#define NT_STATUS_LOGON_TYPE_NOT_GRANTED (0xC0000000 | 347)
+#define NT_STATUS_NOT_REGISTRY_FILE (0xC0000000 | 348)
+#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED (0xC0000000 | 349)
+#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR (0xC0000000 | 350)
+#define NT_STATUS_FT_MISSING_MEMBER (0xC0000000 | 351)
+#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY (0xC0000000 | 352)
+#define NT_STATUS_ILLEGAL_CHARACTER (0xC0000000 | 353)
+#define NT_STATUS_UNMAPPABLE_CHARACTER (0xC0000000 | 354)
+#define NT_STATUS_UNDEFINED_CHARACTER (0xC0000000 | 355)
+#define NT_STATUS_FLOPPY_VOLUME (0xC0000000 | 356)
+#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND (0xC0000000 | 357)
+#define NT_STATUS_FLOPPY_WRONG_CYLINDER (0xC0000000 | 358)
+#define NT_STATUS_FLOPPY_UNKNOWN_ERROR (0xC0000000 | 359)
+#define NT_STATUS_FLOPPY_BAD_REGISTERS (0xC0000000 | 360)
+#define NT_STATUS_DISK_RECALIBRATE_FAILED (0xC0000000 | 361)
+#define NT_STATUS_DISK_OPERATION_FAILED (0xC0000000 | 362)
+#define NT_STATUS_DISK_RESET_FAILED (0xC0000000 | 363)
+#define NT_STATUS_SHARED_IRQ_BUSY (0xC0000000 | 364)
+#define NT_STATUS_FT_ORPHANING (0xC0000000 | 365)
+#define NT_STATUS_PARTITION_FAILURE (0xC0000000 | 370)
+#define NT_STATUS_INVALID_BLOCK_LENGTH (0xC0000000 | 371)
+#define NT_STATUS_DEVICE_NOT_PARTITIONED (0xC0000000 | 372)
+#define NT_STATUS_UNABLE_TO_LOCK_MEDIA (0xC0000000 | 373)
+#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA (0xC0000000 | 374)
+#define NT_STATUS_EOM_OVERFLOW (0xC0000000 | 375)
+#define NT_STATUS_NO_MEDIA (0xC0000000 | 376)
+#define NT_STATUS_NO_SUCH_MEMBER (0xC0000000 | 378)
+#define NT_STATUS_INVALID_MEMBER (0xC0000000 | 379)
+#define NT_STATUS_KEY_DELETED (0xC0000000 | 380)
+#define NT_STATUS_NO_LOG_SPACE (0xC0000000 | 381)
+#define NT_STATUS_TOO_MANY_SIDS (0xC0000000 | 382)
+#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED (0xC0000000 | 383)
+#define NT_STATUS_KEY_HAS_CHILDREN (0xC0000000 | 384)
+#define NT_STATUS_CHILD_MUST_BE_VOLATILE (0xC0000000 | 385)
+#define NT_STATUS_DEVICE_CONFIGURATION_ERROR (0xC0000000 | 386)
+#define NT_STATUS_DRIVER_INTERNAL_ERROR (0xC0000000 | 387)
+#define NT_STATUS_INVALID_DEVICE_STATE (0xC0000000 | 388)
+#define NT_STATUS_IO_DEVICE_ERROR (0xC0000000 | 389)
+#define NT_STATUS_DEVICE_PROTOCOL_ERROR (0xC0000000 | 390)
+#define NT_STATUS_BACKUP_CONTROLLER (0xC0000000 | 391)
+#define NT_STATUS_LOG_FILE_FULL (0xC0000000 | 392)
+#define NT_STATUS_TOO_LATE (0xC0000000 | 393)
+#define NT_STATUS_NO_TRUST_LSA_SECRET (0xC0000000 | 394)
+#define NT_STATUS_NO_TRUST_SAM_ACCOUNT (0xC0000000 | 395)
+#define NT_STATUS_TRUSTED_DOMAIN_FAILURE (0xC0000000 | 396)
+#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE (0xC0000000 | 397)
+#define NT_STATUS_EVENTLOG_FILE_CORRUPT (0xC0000000 | 398)
+#define NT_STATUS_EVENTLOG_CANT_START (0xC0000000 | 399)
+#define NT_STATUS_TRUST_FAILURE (0xC0000000 | 400)
+#define NT_STATUS_MUTANT_LIMIT_EXCEEDED (0xC0000000 | 401)
+#define NT_STATUS_NETLOGON_NOT_STARTED (0xC0000000 | 402)
+#define NT_STATUS_ACCOUNT_EXPIRED (0xC0000000 | 403)
+#define NT_STATUS_POSSIBLE_DEADLOCK (0xC0000000 | 404)
+#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT (0xC0000000 | 405)
+#define NT_STATUS_REMOTE_SESSION_LIMIT (0xC0000000 | 406)
+#define NT_STATUS_EVENTLOG_FILE_CHANGED (0xC0000000 | 407)
+#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT (0xC0000000 | 408)
+#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT (0xC0000000 | 409)
+#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT (0xC0000000 | 410)
+#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT (0xC0000000 | 411)
+#define NT_STATUS_FS_DRIVER_REQUIRED (0xC0000000 | 412)
+#define NT_STATUS_NO_USER_SESSION_KEY (0xC0000000 | 514)
+#define NT_STATUS_USER_SESSION_DELETED (0xC0000000 | 515)
+#define NT_STATUS_RESOURCE_LANG_NOT_FOUND (0xC0000000 | 516)
+#define NT_STATUS_INSUFF_SERVER_RESOURCES (0xC0000000 | 517)
+#define NT_STATUS_INVALID_BUFFER_SIZE (0xC0000000 | 518)
+#define NT_STATUS_INVALID_ADDRESS_COMPONENT (0xC0000000 | 519)
+#define NT_STATUS_INVALID_ADDRESS_WILDCARD (0xC0000000 | 520)
+#define NT_STATUS_TOO_MANY_ADDRESSES (0xC0000000 | 521)
+#define NT_STATUS_ADDRESS_ALREADY_EXISTS (0xC0000000 | 522)
+#define NT_STATUS_ADDRESS_CLOSED (0xC0000000 | 523)
+#define NT_STATUS_CONNECTION_DISCONNECTED (0xC0000000 | 524)
+#define NT_STATUS_CONNECTION_RESET (0xC0000000 | 525)
+#define NT_STATUS_TOO_MANY_NODES (0xC0000000 | 526)
+#define NT_STATUS_TRANSACTION_ABORTED (0xC0000000 | 527)
+#define NT_STATUS_TRANSACTION_TIMED_OUT (0xC0000000 | 528)
+#define NT_STATUS_TRANSACTION_NO_RELEASE (0xC0000000 | 529)
+#define NT_STATUS_TRANSACTION_NO_MATCH (0xC0000000 | 530)
+#define NT_STATUS_TRANSACTION_RESPONDED (0xC0000000 | 531)
+#define NT_STATUS_TRANSACTION_INVALID_ID (0xC0000000 | 532)
+#define NT_STATUS_TRANSACTION_INVALID_TYPE (0xC0000000 | 533)
+#define NT_STATUS_NOT_SERVER_SESSION (0xC0000000 | 534)
+#define NT_STATUS_NOT_CLIENT_SESSION (0xC0000000 | 535)
+#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE (0xC0000000 | 536)
+#define NT_STATUS_DEBUG_ATTACH_FAILED (0xC0000000 | 537)
+#define NT_STATUS_SYSTEM_PROCESS_TERMINATED (0xC0000000 | 538)
+#define NT_STATUS_DATA_NOT_ACCEPTED (0xC0000000 | 539)
+#define NT_STATUS_NO_BROWSER_SERVERS_FOUND (0xC0000000 | 540)
+#define NT_STATUS_VDM_HARD_ERROR (0xC0000000 | 541)
+#define NT_STATUS_DRIVER_CANCEL_TIMEOUT (0xC0000000 | 542)
+#define NT_STATUS_REPLY_MESSAGE_MISMATCH (0xC0000000 | 543)
+#define NT_STATUS_MAPPED_ALIGNMENT (0xC0000000 | 544)
+#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH (0xC0000000 | 545)
+#define NT_STATUS_LOST_WRITEBEHIND_DATA (0xC0000000 | 546)
+#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID (0xC0000000 | 547)
+#define NT_STATUS_PASSWORD_MUST_CHANGE (0xC0000000 | 548)
+#define NT_STATUS_NOT_FOUND (0xC0000000 | 549)
+#define NT_STATUS_NOT_TINY_STREAM (0xC0000000 | 550)
+#define NT_STATUS_RECOVERY_FAILURE (0xC0000000 | 551)
+#define NT_STATUS_STACK_OVERFLOW_READ (0xC0000000 | 552)
+#define NT_STATUS_FAIL_CHECK (0xC0000000 | 553)
+#define NT_STATUS_DUPLICATE_OBJECTID (0xC0000000 | 554)
+#define NT_STATUS_OBJECTID_EXISTS (0xC0000000 | 555)
+#define NT_STATUS_CONVERT_TO_LARGE (0xC0000000 | 556)
+#define NT_STATUS_RETRY (0xC0000000 | 557)
+#define NT_STATUS_FOUND_OUT_OF_SCOPE (0xC0000000 | 558)
+#define NT_STATUS_ALLOCATE_BUCKET (0xC0000000 | 559)
+#define NT_STATUS_PROPSET_NOT_FOUND (0xC0000000 | 560)
+#define NT_STATUS_MARSHALL_OVERFLOW (0xC0000000 | 561)
+#define NT_STATUS_INVALID_VARIANT (0xC0000000 | 562)
+#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND (0xC0000000 | 563)
+#define NT_STATUS_ACCOUNT_LOCKED_OUT (0xC0000000 | 564)
+#define NT_STATUS_HANDLE_NOT_CLOSABLE (0xC0000000 | 565)
+#define NT_STATUS_CONNECTION_REFUSED (0xC0000000 | 566)
+#define NT_STATUS_GRACEFUL_DISCONNECT (0xC0000000 | 567)
+#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED (0xC0000000 | 568)
+#define NT_STATUS_ADDRESS_NOT_ASSOCIATED (0xC0000000 | 569)
+#define NT_STATUS_CONNECTION_INVALID (0xC0000000 | 570)
+#define NT_STATUS_CONNECTION_ACTIVE (0xC0000000 | 571)
+#define NT_STATUS_NETWORK_UNREACHABLE (0xC0000000 | 572)
+#define NT_STATUS_HOST_UNREACHABLE (0xC0000000 | 573)
+#define NT_STATUS_PROTOCOL_UNREACHABLE (0xC0000000 | 574)
+#define NT_STATUS_PORT_UNREACHABLE (0xC0000000 | 575)
+#define NT_STATUS_REQUEST_ABORTED (0xC0000000 | 576)
+#define NT_STATUS_CONNECTION_ABORTED (0xC0000000 | 577)
+#define NT_STATUS_BAD_COMPRESSION_BUFFER (0xC0000000 | 578)
+#define NT_STATUS_USER_MAPPED_FILE (0xC0000000 | 579)
+#define NT_STATUS_AUDIT_FAILED (0xC0000000 | 580)
+#define NT_STATUS_TIMER_RESOLUTION_NOT_SET (0xC0000000 | 581)
+#define NT_STATUS_CONNECTION_COUNT_LIMIT (0xC0000000 | 582)
+#define NT_STATUS_LOGIN_TIME_RESTRICTION (0xC0000000 | 583)
+#define NT_STATUS_LOGIN_WKSTA_RESTRICTION (0xC0000000 | 584)
+#define NT_STATUS_IMAGE_MP_UP_MISMATCH (0xC0000000 | 585)
+#define NT_STATUS_INSUFFICIENT_LOGON_INFO (0xC0000000 | 592)
+#define NT_STATUS_BAD_DLL_ENTRYPOINT (0xC0000000 | 593)
+#define NT_STATUS_BAD_SERVICE_ENTRYPOINT (0xC0000000 | 594)
+#define NT_STATUS_LPC_REPLY_LOST (0xC0000000 | 595)
+#define NT_STATUS_IP_ADDRESS_CONFLICT1 (0xC0000000 | 596)
+#define NT_STATUS_IP_ADDRESS_CONFLICT2 (0xC0000000 | 597)
+#define NT_STATUS_REGISTRY_QUOTA_LIMIT (0xC0000000 | 598)
+#define NT_STATUS_PATH_NOT_COVERED (0xC0000000 | 599)
+#define NT_STATUS_NO_CALLBACK_ACTIVE (0xC0000000 | 600)
+#define NT_STATUS_LICENSE_QUOTA_EXCEEDED (0xC0000000 | 601)
+#define NT_STATUS_PWD_TOO_SHORT (0xC0000000 | 602)
+#define NT_STATUS_PWD_TOO_RECENT (0xC0000000 | 603)
+#define NT_STATUS_PWD_HISTORY_CONFLICT (0xC0000000 | 604)
+#define NT_STATUS_PLUGPLAY_NO_DEVICE (0xC0000000 | 606)
+#define NT_STATUS_UNSUPPORTED_COMPRESSION (0xC0000000 | 607)
+#define NT_STATUS_INVALID_HW_PROFILE (0xC0000000 | 608)
+#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH (0xC0000000 | 609)
+#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND (0xC0000000 | 610)
+#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND (0xC0000000 | 611)
+#define NT_STATUS_RESOURCE_NOT_OWNED (0xC0000000 | 612)
+#define NT_STATUS_TOO_MANY_LINKS (0xC0000000 | 613)
+#define NT_STATUS_QUOTA_LIST_INCONSISTENT (0xC0000000 | 614)
+#define NT_STATUS_FILE_IS_OFFLINE (0xC0000000 | 615)
+#define NT_STATUS_NOTIFY_ENUM_DIR (0xC0000000 | 0x10C)
+#define NT_STATUS_NO_SUCH_JOB (0xC0000000 | 0xEDE) /* scheduler */
diff --git a/source/include/profile.h b/source/include/profile.h
index 0924dc29372..353f6a6b429 100644
--- a/source/include/profile.h
+++ b/source/include/profile.h
@@ -23,13 +23,7 @@
/* this file defines the profile structure in the profile shared
memory area */
-#define PROF_SHMEM_KEY ((key_t)0x07021999)
-#define PROF_SHM_MAGIC 0x6349985
-#define PROF_SHM_VERSION 1
-
struct profile_struct {
- int prof_shm_magic;
- int prof_shm_version;
unsigned smb_count; /* how many SMB packets we have processed */
unsigned uid_changes; /* how many times we change our effective uid */
};
diff --git a/source/include/proto.h b/source/include/proto.h
index 234e51d1846..5dde2fb45a2 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -3,10 +3,16 @@
/* This file is automatically generated with "make proto". DO NOT EDIT */
+/*The following definitions come from browserd/browserd.c */
+
+msrpc_service_fns *get_service_fns(void);
+uint32 _brs_query_info( const UNISTR2 *srv_name, uint16 switch_value,
+ void *id);
+
/*The following definitions come from client/client.c */
void do_list(const char *mask,uint16 attribute,void (*fn)(file_info *),BOOL rec, BOOL dirs);
-struct cli_state *do_connect(char *server, char *share);
+struct cli_state *do_connect(char *server, char *share, int smb_port);
/*The following definitions come from client/clitar.c */
@@ -17,6 +23,130 @@ void cmd_tar(void);
int process_tar(void);
int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind);
+/*The following definitions come from groupdb/aliasdb.c */
+
+BOOL initialise_alias_db(void);
+LOCAL_GRP *iterate_getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem);
+LOCAL_GRP *iterate_getaliasrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem);
+LOCAL_GRP *iterate_getaliasntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem);
+BOOL add_domain_alias(LOCAL_GRP **alss, int *num_alss, LOCAL_GRP *als);
+BOOL iterate_getuseraliasntnam(const char *user_name, LOCAL_GRP **alss, int *num_alss);
+BOOL enumdomaliases(LOCAL_GRP **alss, int *num_alss);
+void *startaliasent(BOOL update);
+void endaliasent(void *vp);
+LOCAL_GRP *getaliasent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem);
+BOOL add_alias_entry(LOCAL_GRP *newgrp);
+BOOL mod_alias_entry(LOCAL_GRP* als);
+BOOL del_alias_entry(uint32 rid);
+BOOL add_alias_member(uint32 rid, const DOM_SID *member_sid);
+BOOL del_alias_member(uint32 rid, const DOM_SID *member_sid);
+LOCAL_GRP *getaliasntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem);
+LOCAL_GRP *getaliasrid(uint32 alias_rid, LOCAL_GRP_MEMBER **mem, int *num_mem);
+LOCAL_GRP *getaliasgid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem);
+BOOL getuseraliasntnam(const char *user_name, LOCAL_GRP **als, int *num_alss);
+void aldb_init_als(LOCAL_GRP *als);
+BOOL make_alias_line(char *p, int max_len,
+ LOCAL_GRP *als,
+ LOCAL_GRP_MEMBER **mem, int *num_mem);
+
+/*The following definitions come from groupdb/aliasfile.c */
+
+struct aliasdb_ops *file_initialise_alias_db(void);
+
+/*The following definitions come from groupdb/aliasldap.c */
+
+struct aliasdb_ops *ldap_initialise_alias_db(void);
+
+/*The following definitions come from groupdb/aliasnt5ldap.c */
+
+
+/*The following definitions come from groupdb/aliasunix.c */
+
+BOOL get_unixalias_members(struct group *grp,
+ int *num_mem, LOCAL_GRP_MEMBER **members);
+struct aliasdb_ops *unix_initialise_alias_db(void);
+
+/*The following definitions come from groupdb/builtindb.c */
+
+BOOL initialise_builtin_db(void);
+LOCAL_GRP *iterate_getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem);
+LOCAL_GRP *iterate_getbuiltinrid(uint32 rid, LOCAL_GRP_MEMBER **mem, int *num_mem);
+LOCAL_GRP *iterate_getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem);
+BOOL add_domain_builtin(LOCAL_GRP **blts, int *num_blts, LOCAL_GRP *blt);
+BOOL iterate_getuserbuiltinntnam(const char *user_name, LOCAL_GRP **blts, int *num_blts);
+BOOL enumdombuiltins(LOCAL_GRP **blts, int *num_blts);
+void *startbuiltinent(BOOL update);
+void endbuiltinent(void *vp);
+LOCAL_GRP *getbuiltinent(void *vp, LOCAL_GRP_MEMBER **mem, int *num_mem);
+BOOL add_builtin_entry(LOCAL_GRP *newblt);
+BOOL mod_builtin_entry(LOCAL_GRP* blt);
+BOOL add_builtin_member(uint32 rid, const DOM_SID *member_sid);
+BOOL del_builtin_member(uint32 rid, const DOM_SID *member_sid);
+LOCAL_GRP *getbuiltinntnam(const char *name, LOCAL_GRP_MEMBER **mem, int *num_mem);
+LOCAL_GRP *getbuiltinrid(uint32 builtin_rid, LOCAL_GRP_MEMBER **mem, int *num_mem);
+LOCAL_GRP *getbuiltingid(gid_t gid, LOCAL_GRP_MEMBER **mem, int *num_mem);
+BOOL getuserbuiltinntnam(const char *user_name, LOCAL_GRP **blt, int *num_blts);
+void bidb_init_blt(LOCAL_GRP *blt);
+BOOL make_builtin_line(char *p, int max_len,
+ LOCAL_GRP *blt,
+ LOCAL_GRP_MEMBER **mem, int *num_mem);
+
+/*The following definitions come from groupdb/builtinldap.c */
+
+struct aliasdb_ops *ldap_initialise_builtin_db(void);
+
+/*The following definitions come from groupdb/builtinnt5ldap.c */
+
+
+/*The following definitions come from groupdb/builtinunix.c */
+
+BOOL get_unixbuiltin_members(struct group *grp,
+ int *num_mem, LOCAL_GRP_MEMBER **members);
+struct aliasdb_ops *unix_initialise_builtin_db(void);
+
+/*The following definitions come from groupdb/groupdb.c */
+
+BOOL initialise_group_db(void);
+DOMAIN_GRP *iterate_getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem);
+DOMAIN_GRP *iterate_getgrouprid(uint32 rid, DOMAIN_GRP_MEMBER **mem, int *num_mem);
+DOMAIN_GRP *iterate_getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem);
+BOOL add_domain_group(DOMAIN_GRP **grps, int *num_grps, DOMAIN_GRP *grp);
+BOOL iterate_getusergroupsnam(const char *user_name, DOMAIN_GRP **grps, int *num_grps);
+BOOL enumdomgroups(DOMAIN_GRP **grps, int *num_grps);
+void *startgroupent(BOOL update);
+void endgroupent(void *vp);
+DOMAIN_GRP *getgroupent(void *vp, DOMAIN_GRP_MEMBER **mem, int *num_mem);
+BOOL add_group_entry(DOMAIN_GRP *newgrp);
+BOOL del_group_entry(uint32 rid);
+BOOL mod_group_entry(DOMAIN_GRP* grp);
+BOOL add_group_member(uint32 rid, uint32 member_rid);
+BOOL del_group_member(uint32 rid, uint32 member_rid);
+DOMAIN_GRP *getgroupntnam(const char *name, DOMAIN_GRP_MEMBER **mem, int *num_mem);
+DOMAIN_GRP *getgrouprid(uint32 group_rid, DOMAIN_GRP_MEMBER **mem, int *num_mem);
+DOMAIN_GRP *getgroupgid(gid_t gid, DOMAIN_GRP_MEMBER **mem, int *num_mem);
+BOOL getusergroupsntnam(const char *user_name, DOMAIN_GRP **grp, int *num_grps);
+void gpdb_init_grp(DOMAIN_GRP *grp);
+BOOL make_group_line(char *p, int max_len,
+ DOMAIN_GRP *grp,
+ DOMAIN_GRP_MEMBER **mem, int *num_mem);
+
+/*The following definitions come from groupdb/groupfile.c */
+
+struct groupdb_ops *file_initialise_group_db(void);
+
+/*The following definitions come from groupdb/groupldap.c */
+
+struct groupdb_ops *ldap_initialise_group_db(void);
+
+/*The following definitions come from groupdb/groupnt5ldap.c */
+
+
+/*The following definitions come from groupdb/groupunix.c */
+
+BOOL get_unixgroup_members(struct group *grp,
+ int *num_mem, DOMAIN_GRP_MEMBER **members);
+struct groupdb_ops *unix_initialise_group_db(void);
+
/*The following definitions come from lib/access.c */
BOOL allow_access(char *deny_list,char *allow_list,
@@ -35,7 +165,7 @@ int bitmap_find(struct bitmap *bm, unsigned ofs);
char *unix2dos_format(char *str,BOOL overwrite);
char *dos2unix_format(char *str, BOOL overwrite);
-void interpret_character_set(char *str, int codepage);
+void interpret_character_set(char *str);
/*The following definitions come from lib/charset.c */
@@ -43,12 +173,29 @@ void charset_initialise(void);
void codepage_initialise(int client_codepage);
void add_char_string(char *s);
+/*The following definitions come from lib/cmd_interp.c */
+
+void free_cmd_set_array(uint32 num_entries, struct command_set **entries);
+struct command_set *add_cmd_set_to_array(uint32 * len,
+ struct command_set ***array,
+ const struct command_set *cmd);
+void add_command_set(const struct command_set *cmds);
+char *complete_samenum_usr(char *text, int state);
+char *complete_samenum_als(char *text, int state);
+char *complete_samenum_grp(char *text, int state);
+char *complete_samenum_usr(char *text, int state);
+char *complete_samenum_als(char *text, int state);
+char *complete_samenum_grp(char *text, int state);
+void readline_init(void);
+int command_main(int argc, char *argv[]);
+
/*The following definitions come from lib/crc32.c */
-uint32 crc32_calc_buffer( char *buffer, uint32 count);
+uint32 crc32_calc_buffer( uint32 count, char *buffer);
/*The following definitions come from lib/debug.c */
+BOOL dbg_interactive(void);
void sig_usr2( int sig );
void sig_usr1( int sig );
void setup_logging( char *pname, BOOL interactive );
@@ -56,6 +203,26 @@ void reopen_logs( void );
void force_check_log_size( void );
void dbgflush( void );
BOOL dbghdr( int level, char *file, char *func, int line );
+dbg_Token dbg_char2token( dbg_Token *state, int c );
+
+/*The following definitions come from lib/domain_namemap.c */
+
+BOOL map_unix_group_name(char *group_name, DOM_NAME_MAP *grp_info);
+BOOL map_unix_alias_name(char *alias_name, DOM_NAME_MAP *grp_info);
+BOOL map_nt_alias_name(char *ntalias_name, char *nt_domain, DOM_NAME_MAP *grp_info);
+BOOL map_nt_group_name(char *ntgroup_name, char *nt_domain, DOM_NAME_MAP *grp_info);
+BOOL map_alias_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info);
+BOOL map_group_sid(DOM_SID *psid, DOM_NAME_MAP *grp_info);
+BOOL lookupsmbpwnam(const char *unix_usr_name, DOM_NAME_MAP *grp);
+BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep);
+BOOL lookupsmbpwntnam(const char *fullntname, DOM_NAME_MAP *gmep);
+BOOL lookupsmbpwsid(DOM_SID *sid, DOM_NAME_MAP *gmep);
+BOOL lookupsmbgrpnam(const char *unix_grp_name, DOM_NAME_MAP *grp);
+BOOL lookupsmbgrpsid(DOM_SID *sid, DOM_NAME_MAP *gmep);
+BOOL lookupsmbgrpgid(gid_t gid, DOM_NAME_MAP *gmep);
+const struct passwd *map_nt_and_unix_username(const char *domain,
+ const char *ntuser,
+ char *unix_user, char *nt_user);
/*The following definitions come from lib/doscalls.c */
@@ -63,7 +230,6 @@ int dos_unlink(char *fname);
int dos_open(char *fname,int flags,mode_t mode);
DIR *dos_opendir(char *dname);
char *dos_readdirname(DIR *p);
-int dos_chown(char *fname, uid_t uid, gid_t gid);
int dos_stat(char *fname,SMB_STRUCT_STAT *sbuf);
int dos_lstat(char *fname,SMB_STRUCT_STAT *sbuf);
int dos_mkdir(char *dname,mode_t mode);
@@ -85,10 +251,6 @@ char *dos_GetWd(char *path);
void fault_setup(void (*fn)(void *));
-/*The following definitions come from lib/fnmatch.c */
-
-int fnmatch (const char *pattern, const char *string, int flags);
-
/*The following definitions come from lib/genrand.c */
void generate_random_buffer( unsigned char *out, int len, BOOL re_seed);
@@ -97,74 +259,76 @@ void generate_random_buffer( unsigned char *out, int len, BOOL re_seed);
char *getsmbpass(char *prompt) ;
-/*The following definitions come from lib/hash.c */
+/*The following definitions come from lib/hmacmd5.c */
-BOOL hash_table_init(hash_table *table, int num_buckets, compare_function compare_func);
-int string_hash(int hash_size, const char *key);
-hash_element *hash_lookup(hash_table *table, char *key);
-hash_element *hash_insert(hash_table *table, char *value, char *key);
-void hash_remove(hash_table *table, hash_element *hash_elem);
-void hash_clear(hash_table *table);
+void hmac_md5_init_rfc2104(uchar* key, int key_len, HMACMD5Context *ctx);
+void hmac_md5_init_limK_to_64(const uchar* key, int key_len,
+ HMACMD5Context *ctx);
+void hmac_md5_update(const uchar* text, int text_len, HMACMD5Context *ctx);
+void hmac_md5_final(uchar *digest, HMACMD5Context *ctx);
+void hmac_md5( uchar key[16], uchar* data, int data_len, uchar* digest);
/*The following definitions come from lib/interface.c */
void load_interfaces(void);
-BOOL interfaces_changed(void);
+void iface_set_default(char *ip,char *bcast,char *nmask);
BOOL ismyip(struct in_addr ip);
BOOL is_local_net(struct in_addr from);
int iface_count(void);
BOOL we_are_multihomed(void);
struct interface *get_interface(int n);
struct in_addr *iface_n_ip(int n);
-struct in_addr *iface_n_bcast(int n);
unsigned iface_hash(void);
struct in_addr *iface_bcast(struct in_addr ip);
struct in_addr *iface_ip(struct in_addr ip);
-/*The following definitions come from lib/interfaces.c */
-
-int get_interfaces(struct iface_struct *ifaces, int max_interfaces);
-
/*The following definitions come from lib/kanji.c */
void interpret_coding_system(char *str);
+BOOL is_multibyte_codepage(void);
void initialize_multibyte_vectors( int client_codepage);
/*The following definitions come from lib/md4.c */
-void mdfour(unsigned char *out, unsigned char *in, int n);
+void mdfour(unsigned char *out, const unsigned char *in, int n);
+
+/*The following definitions come from lib/md5.c */
+
+void MD5Init(struct MD5Context *ctx);
+void MD5Update(struct MD5Context *ctx, uchar const *buf, unsigned len);
+void MD5Final(uchar digest[16], struct MD5Context *ctx);
+void MD5Transform(uint32 buf[4], const uchar inext[64]);
/*The following definitions come from lib/msrpc-client.c */
-BOOL receive_msrpc(int fd, prs_struct *data, unsigned int timeout);
-BOOL msrpc_send(int fd, prs_struct *ps);
-BOOL msrpc_receive(int fd, prs_struct *ps);
-BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name);
-void msrpc_init_creds(struct msrpc_state *msrpc, const struct user_creds *usr);
-void msrpc_close_socket(struct msrpc_state *msrpc);
-void msrpc_sockopt(struct msrpc_state *msrpc, char *options);
-BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
- uint32 pid,
- const char* pipename,
- const struct user_creds *usr);
-struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc, uint32 pid);
-void msrpc_shutdown(struct msrpc_state *msrpc);
-BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
- const char *pipe_name);
-
-/*The following definitions come from lib/msrpc_use.c */
-
-void init_msrpc_use(void);
-void free_msrpc_use(void);
-struct msrpc_state *msrpc_use_add(const char* pipe_name,
- uint32 pid,
- const struct user_creds *usr_creds,
- BOOL redir);
-BOOL msrpc_use_del(const char* pipe_name,
- const struct user_creds *usr_creds,
- BOOL force_close,
- BOOL *connection_closed);
-void msrpc_net_use_enum(uint32 *num_cons, struct use_info ***use);
+BOOL receive_msrpc(int fd, prs_struct * data, unsigned int timeout);
+BOOL msrpc_send(int fd, prs_struct * ps);
+BOOL msrpc_receive(int fd, prs_struct * ps);
+BOOL ncalrpc_l_connect(struct msrpc_local *msrpc, const char *pipe_name);
+void ncalrpc_l_close_socket(struct msrpc_local *msrpc);
+void ncalrpc_l_sockopt(struct msrpc_local *msrpc, char *options);
+BOOL ncalrpc_l_connect_auth(struct msrpc_local *msrpc,
+ const vuser_key * key, const char *pipename);
+struct msrpc_local *ncalrpc_l_initialise(struct msrpc_local *msrpc,
+ const vuser_key * key);
+void ncalrpc_l_shutdown(struct msrpc_local *msrpc);
+BOOL ncalrpc_l_establish_connection(struct msrpc_local *msrpc,
+ const char *pipe_name);
+
+/*The following definitions come from lib/netmask.c */
+
+int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask);
+
+/*The following definitions come from lib/passcheck.c */
+
+BOOL smb_password_ok(uint16 acct_ctrl,
+ uchar smb_passwd[16],
+ uchar smb_nt_passwd[16],
+ const uchar challenge[8],
+ const char *user, const char *domain,
+ const uchar *lm_pass, size_t lm_pwd_len,
+ const uchar *nt_pass, size_t nt_pwd_len,
+ uchar user_sess_key[16]);
/*The following definitions come from lib/pidfile.c */
@@ -175,6 +339,44 @@ void pidfile_create(char *name);
char *rep_inet_ntoa(struct in_addr ip);
+/*The following definitions come from lib/set_uid.c */
+
+const vuser_key *get_sec_ctx(void);
+void init_uid(void);
+BOOL become_uid(uid_t uid);
+BOOL become_gid(gid_t gid);
+BOOL unbecome_to_initial_uid(void);
+BOOL become_id(uid_t uid,gid_t gid);
+BOOL become_unix_sec_ctx(const vuser_key *k, connection_struct *conn,
+ uid_t new_uid, gid_t new_gid,
+ int n_groups, gid_t* groups);
+BOOL become_guest(void);
+void become_root(BOOL save_dir) ;
+void unbecome_root(BOOL restore_dir);
+
+/*The following definitions come from lib/set_vuid.c */
+
+void init_vuid(void);
+BOOL become_vuser(const vuser_key *k);
+BOOL unbecome_vuser(void);
+
+/*The following definitions come from lib/sids.c */
+
+struct sid_map* add_sidmap_to_array(uint32 *len, struct sid_map ***array,
+ const struct sid_map *name);
+void get_sam_domain_name(void);
+BOOL get_member_domain_sid(void);
+void generate_wellknown_sids(void);
+BOOL create_sidmap_table(void);
+BOOL generate_sam_sid(char *domain_name, DOM_SID *sid);
+BOOL pwdb_initialise(BOOL is_server);
+BOOL map_domain_name_to_sid(DOM_SID *sid, char **nt_domain);
+BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain);
+BOOL map_domain_sid_to_any_dc(DOM_SID *sid, char *dc_name);
+BOOL split_domain_name(const char *fullname, char *domain, char *name);
+BOOL enumtrustdoms(char ***doms, uint32 *num_entries);
+BOOL enumdomains(char ***doms, uint32 *num_entries);
+
/*The following definitions come from lib/signal.c */
void BlockSignals(BOOL block,int signum);
@@ -193,11 +395,42 @@ int smbrun(char *cmd,char *outfile,BOOL shared);
/*The following definitions come from lib/snprintf.c */
+/*The following definitions come from lib/stub_uid.c */
+
+void become_root(BOOL save_dir);
+void unbecome_root(BOOL restore_dir);
+const vuser_key *get_sec_ctx(void);
+
+/*The following definitions come from lib/surs.c */
+
+BOOL surs_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id, BOOL create);
+BOOL surs_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid, BOOL create);
+
+/*The following definitions come from lib/sursalgdomonly.c */
+
+BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id,
+ BOOL create);
+BOOL surs_algdomonly_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid,
+ BOOL create);
+
+/*The following definitions come from lib/sursalgnt5ldap.c */
+
+BOOL surs_nt5ldap_sam_sid_to_unixid(LDAPDB *hds, DOM_SID * sid, uint32 type,
+ uint32 * id, BOOL create);
+BOOL surs_nt5ldap_unixid_to_sam_sid(LDAPDB *hds, uint32 id, uint32 type,
+ DOM_SID * sid, BOOL create);
+
+/*The following definitions come from lib/surstdb.c */
+
+BOOL surs_tdb_sam_sid_to_unixid(DOM_SID * sid, uint32 type, uint32 * id,
+ BOOL create);
+BOOL surs_tdb_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID * sid,
+ BOOL create);
+
/*The following definitions come from lib/system.c */
-int sys_select(int maxfd, fd_set *fds,struct timeval *tval);
-int sys_select(int maxfd, fd_set *fds,struct timeval *tval);
-int sys_usleep(long usecs);
+int sys_select(int maxfd, fd_set *fds, fd_set *w_fds, struct timeval *tval);
+int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval);
int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf);
int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf);
int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf);
@@ -209,7 +442,6 @@ int sys_creat(const char *path, mode_t mode);
int sys_open(const char *path, int oflag, mode_t mode);
FILE *sys_fopen(const char *path, const char *type);
void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, SMB_OFF_T offset);
-SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp);
int sys_waitpid(pid_t pid,int *status,int options);
char *sys_getwd(char *s);
int sys_chown(const char *fname,uid_t uid,gid_t gid);
@@ -219,28 +451,10 @@ BOOL set_process_capability( uint32 cap_flag, BOOL enable );
BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable );
long sys_random(void);
void sys_srandom(unsigned int seed);
-int groups_max(void);
int sys_getgroups(int setlen, gid_t *gidset);
-int sys_setgroups(int setlen, gid_t *gidset);
+struct passwd *copy_passwd_struct(struct passwd *pass);
struct passwd *sys_getpwnam(const char *name);
struct passwd *sys_getpwuid(uid_t uid);
-int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf);
-int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf);
-int wsys_creat(const smb_ucs2_t *wfname, mode_t mode);
-int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode);
-FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type);
-DIR *wsys_opendir(const smb_ucs2_t *wfname);
-smb_ucs2_t *wsys_getwd(smb_ucs2_t *s);
-int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid);
-int wsys_chroot(const smb_ucs2_t *wfname);
-FILE *sys_popen(const char *command, const char *mode);
-int sys_pclose( FILE *fp);
-
-/*The following definitions come from lib/talloc.c */
-
-TALLOC_CTX *talloc_init(void);
-void *talloc(TALLOC_CTX *t, size_t size);
-void talloc_destroy(TALLOC_CTX *t);
/*The following definitions come from lib/time.c */
@@ -248,9 +462,10 @@ void GetTimeOfDay(struct timeval *tval);
void TimeInit(void);
int TimeDiff(time_t t);
struct tm *LocalTime(time_t *t);
-time_t nt_time_to_unix(NTTIME *nt);
+time_t nt_time_to_unix(const NTTIME *nt);
time_t interpret_long_date(char *p);
void unix_to_nt_time(NTTIME *nt, time_t t);
+void init_nt_time(NTTIME *nt);
void put_long_date(char *p,time_t t);
BOOL null_mtime(time_t mtime);
void put_dos_date(char *buf,int offset,time_t unixdate);
@@ -260,7 +475,7 @@ time_t make_unix_date(void *date_ptr);
time_t make_unix_date2(void *date_ptr);
time_t make_unix_date3(void *date_ptr);
char *http_timestring(time_t t);
-char *timestring(BOOL hires);
+char *timestring(void );
time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs);
/*The following definitions come from lib/ufc.c */
@@ -269,87 +484,120 @@ char *ufc_crypt(char *key,char *salt);
/*The following definitions come from lib/username.c */
-char *get_user_home_dir(char *user);
+struct passwd *hashed_getpwnam(const char *name);
+char *uidtoname(uid_t uid);
+char *get_unixhome_dir(char *user);
BOOL map_username(char *user);
-struct passwd *Get_Pwnam(char *user,BOOL allow_change);
+const struct passwd *Get_Pwnam(char *user,BOOL allow_change);
+BOOL user_ok(char *user,int snum);
BOOL user_in_list(char *user,char *list);
/*The following definitions come from lib/util.c */
+BOOL init_myworkgroup(void);
char *tmpdir(void);
-BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups);
+BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t * groups);
+uint32 get_number(const char *tmp);
char *Atoic(char *p, int *n, char *c);
-char *get_numlist(char *p, uint32 **num, int *count);
-char *dns_to_netbios_name(char *dns_name);
-int name_mangle( char *In, char *Out, char name_type );
-BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf);
+uint32 *add_num_to_list(uint32 ** num, int *count, int val);
+char *get_numlist(char *p, uint32 ** num, int *count);
+void putip(void *dest, void *src);
+BOOL file_exist(char *fname, SMB_STRUCT_STAT * sbuf);
int file_rename(char *from, char *to);
time_t file_modtime(char *fname);
-BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st);
-SMB_OFF_T get_file_size(char *file_name);
+BOOL directory_exist(char *dname, SMB_STRUCT_STAT * st);
+SMB_OFF_T file_size(char *file_name);
char *attrib_string(uint16 mode);
+void unix_format(char *fname);
+void dos_format(char *fname);
void show_msg(char *buf);
-void smb_setlen(char *buf,int len);
-int set_message(char *buf,int num_words,int num_bytes,BOOL zero);
+int smb_len(char *buf);
+void _smb_setlen(char *buf, int len);
+void smb_setlen(char *buf, int len);
+int set_message(char *buf, int num_words, int num_bytes, BOOL zero);
+int smb_buflen(char *buf);
+char *smb_buf(char *buf);
+int smb_offset(char *p, char *buf);
void dos_clean_name(char *s);
-void unix_clean_name(char *s);
-BOOL reduce_name(char *s,char *dir,BOOL widelinks);
-void expand_mask(char *Mask,BOOL doext);
-void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date);
+void make_dir_struct(char *buf, char *mask, char *fname, SMB_OFF_T size,
+ int mode, time_t date);
void close_low_fds(void);
int set_blocking(int fd, BOOL set);
-SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align);
-int name_extract(char *buf,int ofs,char *name);
-int name_len(char *s1);
+int TvalDiff(struct timeval *tvalold, struct timeval *tvalnew);
+SMB_OFF_T transfer_file(int infd, int outfd, SMB_OFF_T n, char *header,
+ int headlen, int align);
void msleep(int t);
-BOOL unix_do_match(char *str, char *regexp, BOOL case_sig);
-BOOL mask_match(char *str, char *regexp, BOOL case_sig, BOOL trans2);
+BOOL get_file_match(const char *dirname, const char *regexp,
+ uint32 * total, char ***list);
+BOOL do_match(char *str, const char *regexp, int case_sig);
+BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2);
void become_daemon(void);
BOOL yesno(char *p);
int set_filelen(int fd, SMB_OFF_T len);
-void *Realloc(void *p,size_t size);
+void *Realloc(void *p, size_t size);
void safe_free(void *p);
-BOOL get_myname(char *my_name);
-int interpret_protocol(char *str,int def);
-BOOL is_ipaddress(const char *str);
+BOOL get_myname(char *my_name, struct in_addr *ip);
+BOOL ip_equal(struct in_addr ip1, struct in_addr ip2);
+int interpret_protocol(char *str, int def);
uint32 interpret_addr(char *str);
struct in_addr *interpret_addr2(char *str);
BOOL zero_ip(struct in_addr ip);
-BOOL matchname(char *remotehost,struct in_addr addr);
+BOOL matchname(char *remotehost, struct in_addr addr);
void standard_sub_basic(char *str);
-void standard_sub(connection_struct *conn,char *str);
-BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask);
+void standard_sub_vuser(const user_struct * vuser, char *str);
+void standard_sub(connection_struct * conn, user_struct * vuser, char *str);
+BOOL same_net(struct in_addr ip1, struct in_addr ip2, struct in_addr mask);
struct hostent *Get_Hostbyname(const char *name);
-BOOL process_exists(pid_t pid);
-char *uidtoname(uid_t uid);
+BOOL process_exists(int pid);
+int get_unixgroups(const char *user, uid_t uid, gid_t gid, int *p_ngroups,
+ gid_t ** p_groups);
+BOOL get_unix_grps(int *p_ngroups, struct group **p_groups);
+void free_unix_grps(int ngroups, struct group *p_groups);
char *gidtoname(gid_t gid);
-uid_t nametouid(const char *name);
-gid_t nametogid(const char *name);
+BOOL nametogid(const char *name, gid_t * gid);
+BOOL nametouid(const char *name, uid_t * uid);
void smb_panic(char *why);
-char *readdirname(DIR *p);
-BOOL is_in_path(char *name, name_compare_entry *namelist);
-void set_namearray(name_compare_entry **ppname_array, char *namelist);
-void free_namearray(name_compare_entry *name_array);
-uint32 map_lock_offset(uint32 high, uint32 low);
-BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
+char *readdirname(DIR * p);
+BOOL is_in_path(char *name, name_compare_entry * namelist);
+void set_namearray(name_compare_entry ** ppname_array, char *namelist);
+void free_namearray(name_compare_entry * name_array);
BOOL is_myname(char *s);
void set_remote_arch(enum remote_arch_types type);
enum remote_arch_types get_remote_arch(void);
+char *align4(char *q, char *base);
char *align2(char *q, char *base);
-void out_ascii(FILE *f, unsigned char *buf,int len);
-void out_data(FILE *f,char *buf1,int len, int per_line);
-void print_asc(int level, unsigned char *buf,int len);
-void dump_data(int level,char *buf1,int len);
+void out_ascii(FILE * f, const uchar * buf, int len);
+void out_struct(FILE * f, const char *buf1, int len, int per_line);
+void out_data(FILE * f, const char *buf1, int len, int per_line);
+void print_asc(int level, uchar const *buf, int len);
+void dump_data(int level, const char *buf1, int len);
+void dump_data_pw(const char *msg, const uchar * data, size_t len);
char *tab_depth(int depth);
int str_checksum(const char *s);
void zero_free(void *p, size_t size);
int set_maxfiles(int requested_max);
-BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name);
-char *smbd_mktemp(char *template);
-void *memdup(void *p, size_t size);
-char *myhostname(void);
+void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name);
+BOOL reg_split_key(const char *full_keyname, uint32 * reg_type,
+ char *key_name);
+char *get_trusted_serverlist(const char *domain);
+uint16 pwdb_acct_ctrl_from_ad(NTDS_USER_FLAG_ENUM adac);
+char *pwdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
+uint16 pwdb_decode_acct_ctrl(const char *p);
+time_t pwdb_get_time_last_changed(const char *p);
+time_t pwdb_get_last_set_time(const char *p);
+void pwdb_set_logon_time(char *p, int max_len, time_t t);
+void pwdb_set_logoff_time(char *p, int max_len, time_t t);
+void pwdb_set_kickoff_time(char *p, int max_len, time_t t);
+void pwdb_set_can_change_time(char *p, int max_len, time_t t);
+void pwdb_set_time_last_changed(char *p, int max_len, time_t t);
+void pwdb_set_must_change_time(char *p, int max_len, time_t t);
+void pwdb_set_last_set_time(char *p, int max_len, time_t t);
+void pwdb_sethexpwd(char *p, const uchar * pwd, uint16 acct_ctrl);
+BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 * acct_ctrl);
+void *memdup(const void *p, size_t size);
+char *passdb_path(char *name);
char *lock_path(char *name);
-char *parent_dirname(const char *path);
+const char *get_sid_name_use_str(uint32 sid_name_use);
/*The following definitions come from lib/util_array.c */
@@ -365,6 +613,8 @@ void free_char_array(uint32 num_entries, char **entries);
char* add_chars_to_array(uint32 *len, char ***array, const char *name);
void free_uint32_array(uint32 num_entries, uint32 **entries);
uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name);
+void free_unistr_array(uint32 num_entries, UNISTR2 **entries);
+UNISTR2* add_unistr_to_array(uint32 *len, UNISTR2 ***array, UNISTR2 *name);
void free_sid_array(uint32 num_entries, DOM_SID **entries);
DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid);
@@ -373,13 +623,77 @@ DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid);
BOOL do_file_lock(int fd, int waitsecs, int type);
BOOL file_lock(int fd, int type, int secs, int *plock_depth);
BOOL file_unlock(int fd, int *plock_depth);
-void *startfilepwent(char *pfile, char *s_readbuf, int bufsize,
+BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
+void *startfileent(char *pfile, char *s_readbuf, int bufsize,
int *file_lock_depth, BOOL update);
-void endfilepwent(void *vp, int *file_lock_depth);
+void endfileent(void *vp, int *file_lock_depth);
SMB_BIG_UINT getfilepwpos(void *vp);
BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok);
int getfileline(void *vp, char *linebuf, int linebuf_size);
char *fgets_slash(char *s2,int maxlen,FILE *f);
+BOOL file_modified(const char *filename, time_t *lastmodified);
+void *open_file_if_modified(const char *filename, char *mode, time_t *lastmodified);
+
+/*The following definitions come from lib/util_hnd.c */
+
+struct policy_cache *get_global_hnd_cache(void);
+struct policy_cache *init_policy_cache(int num_pol_hnds);
+void free_policy_cache(struct policy_cache *cache);
+BOOL policy_hnd_set_name(struct policy_cache *cache,
+ POLICY_HND *hnd, const char *name);
+const char *policy_hnd_get_name(struct policy_cache *cache,
+ const POLICY_HND *hnd);
+BOOL dup_policy_hnd(struct policy_cache *cache,
+ POLICY_HND *hnd,
+ const POLICY_HND *from);
+BOOL register_policy_hnd(struct policy_cache *cache,
+ const vuser_key *key,
+ POLICY_HND *hnd,
+ uint32 access_mask);
+BOOL open_policy_hnd(struct policy_cache *cache,
+ const vuser_key *key,
+ POLICY_HND *hnd,
+ uint32 access_mask);
+BOOL open_policy_hnd_link(struct policy_cache *cache,
+ const POLICY_HND *parent_hnd,
+ POLICY_HND *hnd,
+ uint32 access_mask);
+int find_policy_by_hnd(struct policy_cache *cache, const POLICY_HND *hnd);
+BOOL set_policy_state(struct policy_cache *cache, POLICY_HND *hnd,
+ void(*fn)(void*), void *dev);
+void *get_policy_state_info(struct policy_cache *cache, const POLICY_HND *hnd);
+BOOL policy_hnd_set_state_type(struct policy_cache *cache,
+ POLICY_HND *hnd, int type);
+int policy_hnd_get_state_type(struct policy_cache *cache,
+ const POLICY_HND *hnd);
+BOOL policy_hnd_check_state_type(struct policy_cache *cache,
+ const POLICY_HND *hnd, int type);
+BOOL close_policy_hnd(struct policy_cache *cache, POLICY_HND *hnd);
+BOOL policy_link_key(struct policy_cache *cache, const POLICY_HND *hnd,
+ POLICY_HND *to);
+const vuser_key *get_policy_vuser_key(struct policy_cache *cache,
+ const POLICY_HND *hnd);
+BOOL pol_get_usr_sesskey(struct policy_cache *cache, const POLICY_HND *hnd,
+ uchar usr_sess_key[16]);
+
+/*The following definitions come from lib/util_pwdb.c */
+
+uint32 lookup_wk_group_name(const char *group_name, const char *domain,
+ DOM_SID *sid, uint32 *type);
+uint32 lookup_wk_user_name(const char *user_name, const char *domain,
+ DOM_SID *sid, uint32 *type);
+uint32 lookup_builtin_alias_name(const char *alias_name, const char *domain,
+ DOM_SID *sid, uint32 *type);
+char *lookup_wk_alias_rid(uint32 rid);
+char *lookup_wk_user_rid(uint32 rid);
+char *lookup_wk_group_rid(uint32 rid);
+
+/*The following definitions come from lib/util_seaccess.c */
+
+BOOL se_access_check(const SEC_DESC * sd, const NET_USER_INFO_3 * user,
+ uint32 acc_req, uint32 prev_grant_acc,
+ uint32 * acc_grant,
+ uint32 * status);
/*The following definitions come from lib/util_sec.c */
@@ -394,22 +708,17 @@ void become_user_permanently(uid_t uid, gid_t gid);
/*The following definitions come from lib/util_sid.c */
-void generate_wellknown_sids(void);
-BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain);
-BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, uint8 *psid_name_use);
-BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain);
-void split_domain_name(const char *fullname, char *domain, char *name);
-char *sid_to_string(fstring sidstr_out, DOM_SID *sid);
-BOOL string_to_sid(DOM_SID *sidout, char *sidstr);
+char *sid_to_string(pstring sidstr_out, const DOM_SID *sid);
+BOOL string_to_sid(DOM_SID *sidout, const char *sidstr);
BOOL sid_append_rid(DOM_SID *sid, uint32 rid);
BOOL sid_split_rid(DOM_SID *sid, uint32 *rid);
-void sid_copy(DOM_SID *dst, const DOM_SID *src);
-DOM_SID *sid_dup(DOM_SID *src);
-BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid);
-BOOL sid_equal(DOM_SID *sid1, DOM_SID *sid2);
-size_t sid_size(DOM_SID *sid);
-BOOL read_sid(char *sam_name, DOM_SID *sid);
-BOOL write_sid(char *sam_name, DOM_SID *sid);
+void sid_copy(DOM_SID *sid1, const DOM_SID *sid2);
+BOOL sid_front_equal(const DOM_SID *sid1, const DOM_SID *sid2);
+BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2);
+int sid_size(const DOM_SID *sid);
+DOM_SID *sid_dup(const DOM_SID *src);
+BOOL read_sid(char *domain_name, DOM_SID *sid);
+BOOL write_sid(char *domain_name, DOM_SID *sid);
BOOL create_new_sid(DOM_SID *sid);
/*The following definitions come from lib/util_sock.c */
@@ -417,21 +726,24 @@ BOOL create_new_sid(DOM_SID *sid);
BOOL is_a_socket(int fd);
void set_socket_options(int fd, char *options);
void close_sockets(void );
+ssize_t write_socket(int fd,char *buf,size_t len);
ssize_t read_udp_socket(int fd,char *buf,size_t len);
ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out);
BOOL send_keepalive(int client);
ssize_t read_data(int fd,char *buffer,size_t N);
ssize_t write_data(int fd,char *buffer,size_t N);
-ssize_t write_socket_data(int fd,char *buffer,size_t N);
-ssize_t write_socket(int fd,char *buf,size_t len);
ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout);
BOOL receive_smb(int fd,char *buffer, unsigned int timeout);
BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout);
-BOOL send_null_session_msg(int fd);
BOOL send_smb(int fd,char *buffer);
BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type);
-int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind);
+int open_socket_in(int type, int port, int dlevel,uint32 socket_addr,
+ BOOL rebind);
int open_socket_out(int type, struct in_addr *addr, int port ,int timeout);
+void set_client_connection_name(const char* name, int fd);
+void set_client_connection_addr(const char* addr, int fd);
+char *client_connection_name(void);
+char *client_connection_addr(void);
void reset_globals_after_fork(void);
char *client_name(int fd);
char *client_addr(int fd);
@@ -439,6 +751,12 @@ int open_pipe_sock(char *path);
int create_pipe_socket(char *dir, int dir_perms,
char *path, int path_perms);
+/*The following definitions come from lib/util_status.c */
+
+BOOL get_connection_status(struct connect_record **crec,
+ uint32 *connection_count);
+BOOL get_session_count(struct connect_record **srec,uint32 *session_count);
+
/*The following definitions come from lib/util_str.c */
void set_first_token(char *ptr);
@@ -460,107 +778,92 @@ BOOL trim_string(char *s,const char *front,const char *back);
BOOL strhasupper(const char *s);
BOOL strhaslower(const char *s);
size_t count_chars(const char *s,char c);
-BOOL str_is_all(const char *s,char c);
char *safe_strcpy(char *dest,const char *src, size_t maxlength);
char *safe_strcat(char *dest, const char *src, size_t maxlength);
-char *alpha_strcpy(char *dest, const char *src, size_t maxlength);
+char *StrCpy(char *dest,const char *src);
char *StrnCpy(char *dest,const char *src,size_t n);
-char *strncpyn(char *dest, const char *src,size_t n, char c);
+char *strncpyn(char *dest, char *src,size_t n, char c);
size_t strhex_to_str(char *p, size_t len, const char *strhex);
BOOL in_list(char *s,char *list,BOOL casesensitive);
+BOOL string_init(char **dest,const char *src);
void string_free(char **s);
BOOL string_set(char **dest,const char *src);
-void string_sub(char *s,const char *pattern,const char *insert, size_t len);
-void fstring_sub(char *s,const char *pattern,const char *insert);
-void pstring_sub(char *s,const char *pattern,const char *insert);
+void string_sub(char *s,const char *pattern,const char *insert);
void all_string_sub(char *s,const char *pattern,const char *insert, size_t len);
+void split_at_first_component(char *path, char *front, char sep, char *back);
void split_at_last_component(char *path, char *front, char sep, char *back);
-char *octal_string(int i);
-char *string_truncate(char *s, int length);
+char *bit_field_to_str(uint32 type, struct field_info *bs);
+char *enum_field_to_str(uint32 type, struct field_info *bs, BOOL first_default);
/*The following definitions come from lib/util_unistr.c */
-int dos_PutUniCode(char *dst,const char *src, ssize_t len);
+char *ascii_to_unibuf(char *dest, const char *src, int maxlen);
+const char* unibuf_to_ascii(char *dest, const char *src, int maxlen);
void ascii_to_unistr(uint16 *dest, const char *src, int maxlen);
void unistr_to_ascii(char *dest, const uint16 *src, int len);
-char *skip_unicode_string(char *buf,int n);
-char *dos_unistrn2(uint16 *src, int len);
-char *dos_unistr2(uint16 *src);
-char *dos_unistr2_to_str(UNISTR2 *str);
-void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen);
-uint32 buffer2_to_uint32(BUFFER2 *str);
-char *dos_buffer2_to_str(BUFFER2 *str);
-char *dos_buffer2_to_multistr(BUFFER2 *str);
-size_t dos_struni2(char *dst, const char *src, size_t max_len);
-char *dos_unistr(char *buf);
-int unistrcpy(char *dst, char *src);
-void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp);
-BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp);
-BOOL load_dos_unicode_map(int codepage);
-BOOL load_unix_unicode_map(const char *unix_char_set);
-smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
- size_t dst_len, smb_ucs2_t *cp_to_ucs2);
-char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len);
-smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len);
-char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len);
-smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len);
-size_t strlen_w(const smb_ucs2_t *src);
-smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength);
-smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength);
-int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
-int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len);
-smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
-smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c);
-smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c);
-smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2);
-smb_ucs2_t *strdup_w(const smb_ucs2_t *s);
-int isupper_w( smb_ucs2_t val);
-int islower_w( smb_ucs2_t val);
-int isdigit_w( smb_ucs2_t val);
-int isxdigit_w( smb_ucs2_t val);
-int isspace_w( smb_ucs2_t val);
-smb_ucs2_t toupper_w( smb_ucs2_t val );
-smb_ucs2_t tolower_w( smb_ucs2_t val );
-void set_first_token_w(smb_ucs2_t *ptr);
-BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize);
-smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep);
-int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t);
-int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n);
-BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2);
-BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n);
-BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2);
-void strlower_w(smb_ucs2_t *s);
-void strupper_w(smb_ucs2_t *s);
-void strnorm_w(smb_ucs2_t *s);
-BOOL strisnormal_w(smb_ucs2_t *s);
-void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc);
-smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n);
-size_t str_charnum_w(const smb_ucs2_t *s);
-BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back);
-BOOL strhasupper_w(const smb_ucs2_t *s);
-BOOL strhaslower_w(const smb_ucs2_t *s);
-size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c);
-BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c);
-smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength);
-smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n);
-smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c);
-size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex);
-BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive);
-BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src);
-void string_free_w(smb_ucs2_t **s);
-BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src);
-void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len);
-void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert);
-void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert);
-void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len);
-void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back);
-smb_ucs2_t *octal_string_w(int i);
-smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length);
+char *unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen);
+char *skip_unibuf(char *srcbuf, int len);
+char *uni_strncpy(char *destbuf, const char *srcbuf, int len);
+uint32 buffer2_to_uint32(const BUFFER2 *str);
+void buffer2_to_multistr(char *dest, const BUFFER2 *str, size_t maxlen);
+void buffer4_to_str(char *dest, const BUFFER4 *str, size_t maxlen);
+UNISTR2 *unistr2_new(const char *init);
+UNISTR2 *unistr2_assign(UNISTR2 *str, const uint16 *src, size_t len);
+UNISTR2 *unistr2_assign_ascii(UNISTR2 *str, const char *buf, int len);
+UNISTR2 *unistr2_assign_ascii_str(UNISTR2 *str, const char *buf);
+UNISTR2 *unistr2_grow(UNISTR2 *str, size_t new_size);
+BOOL unistr2upper(UNISTR2 *str, const UNISTR2 *from);
+BOOL copy_unistr2(UNISTR2 *str, const UNISTR2 *from);
+UNISTR2 *unistr2_dup(const UNISTR2 *name);
+void unistr2_free(UNISTR2 *name);
+int StrCaseCmpW(const UNISTR2 *ws, const UNISTR2 *wt);
+BOOL unistr2equal(const UNISTR2 *s1, const UNISTR2 *s2);
+
+/*The following definitions come from lib/vagent.c */
+
+void init_sock_redir(struct vagent_ops*va);
+void free_sock_redir(struct vagent_ops*va);
+void start_agent(struct vagent_ops *va);
+
+/*The following definitions come from lib/vuser.c */
+
+BOOL is_valid_user_struct(const vuser_key * key);
+user_struct *get_valid_user_struct(const vuser_key * key);
+void invalidate_vuid(vuser_key * key);
+BOOL validated_username(vuser_key * key, char *name, size_t len);
+uint16 create_vuid(pid_t pid,
+ uid_t uid, gid_t gid,
+ int n_groups, gid_t * groups,
+ const char *unix_name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+uint16 register_vuid(pid_t pid, uid_t uid, gid_t gid,
+ const char *unix_name,
+ const char *requested_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+BOOL check_vuser_ok(struct uid_cache *cache, user_struct * vuser, int snum);
+
+/*The following definitions come from lib/vuser_db.c */
+
+BOOL tdb_delete_vuid( const vuser_key *uk);
+BOOL tdb_lookup_vuid( const vuser_key *uk, user_struct **usr);
+BOOL tdb_store_vuid( const vuser_key *uk, user_struct *usr);
+BOOL vuid_init_db(void);
/*The following definitions come from libsmb/clientgen.c */
int cli_set_port(struct cli_state *cli, int port);
char *cli_errstr(struct cli_state *cli);
+void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len);
+BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen);
+void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen);
+BOOL cli_send_trans(struct cli_state *cli, int trans,
+ char *name, int pipe_name_len,
+ int fid, int flags,
+ uint16 *setup, int lsetup, int msetup,
+ char *param, int lparam, int mparam,
+ char *data, int ldata, int mdata);
BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len,
uint16 *setup, uint32 setup_count, uint32 max_setup_count,
char *params, uint32 param_count, uint32 max_param_count,
@@ -573,14 +876,19 @@ BOOL cli_api(struct cli_state *cli,
char **rparam, int *rprcnt,
char **rdata, int *rdrcnt);
BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
-int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *));
+BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *));
BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
void (*fn)(const char *, uint32, const char *));
+BOOL cli_session_setup_x(struct cli_state *cli,
+ char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *user_domain);
BOOL cli_session_setup(struct cli_state *cli,
- char *user,
- char *pass, int passlen,
- char *ntpass, int ntpasslen,
- char *workgroup);
+ char *myhostname, char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *user_domain);
BOOL cli_ulogoff(struct cli_state *cli);
BOOL cli_send_tconX(struct cli_state *cli,
char *share, char *dev, char *pass, int passlen);
@@ -589,18 +897,17 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst);
BOOL cli_unlink(struct cli_state *cli, char *fname);
BOOL cli_mkdir(struct cli_state *cli, char *dname);
BOOL cli_rmdir(struct cli_state *cli, char *dname);
-int cli_nt_create(struct cli_state *cli, char *fname);
-int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode);
+int cli_nt_create(struct cli_state *cli, const char *fname);
+int cli_open(struct cli_state *cli, const char *fname,
+ int flags, int share_mode);
BOOL cli_close(struct cli_state *cli, int fnum);
-BOOL cli_lock(struct cli_state *cli, int fnum,
- uint32 offset, uint32 len, int timeout, enum brl_type lock_type);
-BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len);
-size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
+BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
+BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
+size_t cli_read_one(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
+size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size, BOOL overlap);
ssize_t cli_write(struct cli_state *cli,
int fnum, uint16 write_mode,
- char *buf, off_t offset, size_t size);
-ssize_t cli_smbwrite(struct cli_state *cli,
- int fnum, char *buf, off_t offset, size_t size1);
+ char *buf, off_t offset, size_t size, size_t bytes_left);
BOOL cli_getattrE(struct cli_state *cli, int fd,
uint16 *attr, size_t *size,
time_t *c_time, time_t *a_time, time_t *m_time);
@@ -626,17 +933,27 @@ BOOL cli_negprot(struct cli_state *cli);
BOOL cli_session_request(struct cli_state *cli,
struct nmb_name *calling, struct nmb_name *called);
BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip);
+void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr);
struct cli_state *cli_initialise(struct cli_state *cli);
+void cli_close_socket(struct cli_state *cli);
void cli_shutdown(struct cli_state *cli);
-int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error);
+int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num);
void cli_sockopt(struct cli_state *cli, char *options);
uint16 cli_setpid(struct cli_state *cli, uint16 pid);
BOOL cli_reestablish_connection(struct cli_state *cli);
BOOL cli_establish_connection(struct cli_state *cli,
- char *dest_host, struct in_addr *dest_ip,
+ const char *dest_host, struct in_addr *dest_ip,
struct nmb_name *calling, struct nmb_name *called,
char *service, char *service_type,
BOOL do_shutdown, BOOL do_tcon);
+BOOL cli_connect_auth(struct cli_state *cli,
+ const char* desthost,
+ struct in_addr *dest_ip,
+ const struct ntuser_creds *usr);
+BOOL cli_connect_servers_auth(struct cli_state *cli,
+ char *p,
+ const struct ntuser_creds *usr);
+BOOL cli_connect_serverlist(struct cli_state *cli, char *p);
int cli_printjob_del(struct cli_state *cli, int job);
int cli_print_queue(struct cli_state *cli,
void (*fn)(struct print_job_info *));
@@ -646,61 +963,63 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp);
BOOL cli_message_end(struct cli_state *cli, int grp);
BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail);
-BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost,
- struct in_addr *pdest_ip);
+BOOL get_any_dc_name(const char *domain, char *srv_name);
/*The following definitions come from libsmb/credentials.c */
-char *credstr(uchar *cred);
-void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass,
+char *credstr(const uchar *cred);
+void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, const char *pass,
uchar session_key[8]);
void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp,
DOM_CHAL *cred);
-int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred,
- UTIME timestamp);
+int cred_assert(const DOM_CHAL *cred, uchar session_key[8],
+ DOM_CHAL *stored_cred, UTIME timestamp);
BOOL clnt_deal_with_creds(uchar sess_key[8],
DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred);
BOOL deal_with_creds(uchar sess_key[8],
DOM_CRED *sto_clnt_cred,
- DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred);
+ const DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred);
/*The following definitions come from libsmb/namequery.c */
BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
- struct in_addr to_ip,char *master,char *rname);
-struct in_addr *name_query(int fd,const char *name,int name_type,
- BOOL bcast,BOOL recurse,
- struct in_addr to_ip, int *count);
+ struct in_addr to_ip,char *master,char *rname,
+ void (*fn)(struct packet_struct *));
+struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse,
+ struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *));
FILE *startlmhosts(char *fname);
BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr);
void endlmhosts(FILE *fp);
+BOOL is_ip_address(const char *name);
BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type);
+BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
+ struct in_addr *ip);
BOOL find_master_ip(char *group, struct in_addr *master_ip);
-BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name);
-BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count);
/*The following definitions come from libsmb/nmblib.c */
void debug_nmb_packet(struct packet_struct *p);
char *nmb_namestr(struct nmb_name *n);
+void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len);
struct packet_struct *copy_packet(struct packet_struct *packet);
void free_packet(struct packet_struct *packet);
-struct packet_struct *parse_packet(char *buf,int length,
- enum packet_type packet_type);
struct packet_struct *read_packet(int fd,enum packet_type packet_type);
-void make_nmb_name( struct nmb_name *n, const char *name, int type);
+void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope );
BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
-int build_packet(char *buf, struct packet_struct *p);
BOOL send_packet(struct packet_struct *p);
struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
-struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id);
-struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name);
-BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name);
void sort_query_replies(char *data, int n, struct in_addr ip);
+BOOL read_nmb_sock(int c, struct nmb_state *con);
+int get_nmb_sock(void);
+char *dns_to_netbios_name(char *dns_name);
+int name_mangle( char *In, char *Out, char name_type );
+int name_extract(char *buf,int ofs,char *name);
+int name_len(char *s1);
/*The following definitions come from libsmb/nterr.c */
-char *get_nt_error_msg(uint32 nt_code);
+BOOL get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len);
+const char *get_nt_error_msg(uint32 nt_code);
/*The following definitions come from libsmb/passchange.c */
@@ -711,79 +1030,95 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
/*The following definitions come from libsmb/pwd_cache.c */
void pwd_init(struct pwd_info *pwd);
+BOOL pwd_is_nullpwd(const struct pwd_info *pwd);
void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key);
-BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2);
+BOOL pwd_compare(const struct pwd_info *_pwd1, const struct pwd_info *_pwd2);
void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt);
void pwd_set_nullpwd(struct pwd_info *pwd);
void pwd_set_cleartext(struct pwd_info *pwd, char *clr);
void pwd_get_cleartext(struct pwd_info *pwd, char *clr);
-void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
-void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
+void pwd_set_lm_nt_16(struct pwd_info *pwd,
+ const uchar lm_pwd[16],
+ const uchar nt_pwd[16]);
+void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr);
-void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]);
-void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]);
+void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
+ const char *user, const char *server, const char *domain,
+ uchar sess_key[16]);
+void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
+ uchar sess_key[16]);
+void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
+ uchar *nt_owf, size_t *nt_owf_len);
/*The following definitions come from libsmb/smbdes.c */
-void E_P16(unsigned char *p14,unsigned char *p16);
-void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
-void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
-void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out);
-void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key);
-void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key);
-void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw);
-void SamOEMhash( unsigned char *data, unsigned char *key, int val);
+void smbhash(uchar *out, const uchar *in, const uchar *key, int forw);
+void E_P16(uchar *p14,uchar *p16);
+void E_P24(const uchar *p21, const uchar *c8, uchar *p24);
+void D_P16(const uchar *p14, const uchar *in, uchar *out);
+void E_old_pw_hash( const uchar *p14, const uchar *in, uchar *out);
+void cred_hash1(uchar *out, const uchar *in, const uchar *key);
+void cred_hash2(uchar *out,uchar *in,uchar *key);
+void cred_hash3(uchar *out, const uchar *in,uchar *key, int forw);
+void SamOEMhash( uchar *data, const uchar *key, int val);
+void sam_pwd_hash(uint32 rid, const uchar *in, uchar *out, int forw);
/*The following definitions come from libsmb/smbencrypt.c */
-void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24);
-void E_md4hash(uchar *passwd, uchar *p16);
-void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]);
-void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
-void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]);
-void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24);
-BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode);
+void SMBencrypt(uchar * pwrd, uchar * c8, uchar * p24);
+void SMBNTencrypt(uchar * pwrd, uchar * c8, uchar * p24);
+void E_md4hash(uchar * pwrd, uchar * p16);
+void lm_owf_genW(const UNISTR2 * pwd, uchar p16[16]);
+void lm_owf_gen(const char *pwd, uchar p16[16]);
+void nt_owf_genW(const UNISTR2 * pwd, uchar nt_p16[16]);
+void nt_owf_gen(const char *pwd, uchar nt_p16[16]);
+void nt_lm_owf_genW(const UNISTR2 * pwd, uchar nt_p16[16], uchar lm_p16[16]);
+void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16]);
+void SMBOWFencrypt(const uchar pwrd[16], const uchar * c8, uchar p24[24]);
+void SMBOWFencrypt_ntv2(const uchar kr[16],
+ const uchar * srv_chal, int srv_chal_len,
+ const uchar * cli_chal, int cli_chal_len,
+ char resp_buf[16]);
+void SMBsesskeygen_ntv2(const uchar kr[16],
+ const uchar * nt_resp, char sess_key[16]);
+void SMBsesskeygen_ntv1(const uchar kr[16],
+ const uchar * nt_resp, char sess_key[16]);
+void SMBgenclientchals(char *lm_cli_chal,
+ char *nt_cli_chal, int *nt_cli_chal_len,
+ const char *srv, const char *dom);
+void ntv2_owf_gen(const uchar owf[16],
+ const char *user_n, const char *domain_n, uchar kr_buf[16]);
+void NTLMSSPOWFencrypt(const uchar pwrd[8], const uchar * ntlmchalresp,
+ uchar p24[24]);
+BOOL make_oem_passwd_hash(uchar data[516],
+ const char *pwrd, int new_pw_len,
+ const uchar old_pw_hash[16], BOOL unicode);
+BOOL nt_encrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
+BOOL nt_decrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
+void create_ntlmssp_resp(struct pwd_info *pwd,
+ char *domain, char *user_name, char *my_name,
+ uint32 ntlmssp_cli_flgs, prs_struct * auth_resp);
+BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
+ int new_pwrd_size, uint32 * new_pw_len);
+BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
+ int new_pw_len, BOOL nt_pass_set);
/*The following definitions come from libsmb/smberr.c */
+char *smb_err_msg(uint8 class, uint32 num);
+BOOL smb_safe_err_msg(uint8 class, uint32 num, char *ret, size_t len);
+BOOL smb_safe_errstr(char *inbuf, char *msg, size_t len);
char *smb_errstr(char *inbuf);
-/*The following definitions come from libsmb/unexpected.c */
-
-void unexpected_packet(struct packet_struct *p);
-void clear_unexpected(time_t t);
-struct packet_struct *receive_unexpected(enum packet_type packet_type, int id,
- char *mailslot_name);
-
-/*The following definitions come from locking/brlock.c */
-
-void brl_init(int read_only);
-BOOL brl_lock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
- uint16 smbpid, pid_t pid, uint16 tid,
- br_off start, br_off size,
- enum brl_type lock_type);
-BOOL brl_unlock(SMB_DEV_T dev, SMB_INO_T ino, int fnum,
- uint16 smbpid, pid_t pid, uint16 tid,
- br_off start, br_off size);
-BOOL brl_locktest(SMB_DEV_T dev, SMB_INO_T ino,
- uint16 smbpid, pid_t pid, uint16 tid,
- br_off start, br_off size,
- enum brl_type lock_type);
-void brl_close(SMB_DEV_T dev, SMB_INO_T ino, pid_t pid, int tid, int fnum);
-int brl_forall(BRLOCK_FN(fn));
-
/*The following definitions come from locking/locking.c */
-void locking_close_file(files_struct *fsp);
BOOL is_locked(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset,
- enum brl_type lock_type);
+ SMB_OFF_T count,SMB_OFF_T offset, int lock_type);
BOOL do_lock(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset,enum brl_type lock_type,
+ SMB_OFF_T count,SMB_OFF_T offset,int lock_type,
int *eclass,uint32 *ecode);
BOOL do_unlock(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset,
- int *eclass,uint32 *ecode);
+ SMB_OFF_T count,SMB_OFF_T offset,int *eclass,uint32 *ecode);
BOOL locking_init(int read_only);
BOOL locking_end(void);
BOOL lock_share_entry(connection_struct *conn,
@@ -798,7 +1133,128 @@ BOOL set_share_mode(files_struct *fsp, uint16 port, uint16 op_type);
BOOL remove_share_oplock(files_struct *fsp);
BOOL downgrade_share_oplock(files_struct *fsp);
BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock);
-int share_mode_forall(SHAREMODE_FN(fn));
+int share_mode_forall(void (*fn)(share_mode_entry *, char *));
+
+/*The following definitions come from lsarpcd/lsarpcd.c */
+
+msrpc_service_fns *get_service_fns(void);
+
+/*The following definitions come from lsarpcd/secret_db.c */
+
+BOOL tdb_delete_secret(TDB_CONTEXT * tdb, const UNISTR2 * uk);
+BOOL tdb_lookup_secret(TDB_CONTEXT * tdb, const UNISTR2 * uk,
+ LSA_SECRET ** usr);
+BOOL tdb_store_secret(TDB_CONTEXT * tdb, const UNISTR2 * uk, LSA_SECRET * usr);
+TDB_CONTEXT *open_secret_db(int perms);
+BOOL secret_init_db(void);
+
+/*The following definitions come from lsarpcd/srv_lsa.c */
+
+BOOL api_ntlsa_rpc(rpcsrv_struct *p);
+
+/*The following definitions come from lsarpcd/srv_lsa_samdb.c */
+
+BOOL set_tdbsecname(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT *tdb,
+ const UNISTR2 *name);
+BOOL get_tdbsecname(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT **tdb,
+ UNISTR2 *name);
+uint32 _lsa_open_policy2(const UNISTR2 *server_name, POLICY_HND *hnd,
+ const LSA_OBJ_ATTR *attr,
+ uint32 des_access);
+uint32 _lsa_open_policy(const UNISTR2 *server_name, POLICY_HND *hnd,
+ const LSA_OBJ_ATTR *attr,
+ uint32 des_access);
+uint32 _lsa_enum_trust_dom(POLICY_HND *hnd, uint32 *enum_ctx,
+ uint32 *num_doms, UNISTR2 **uni_names,
+ DOM_SID ***sids);
+uint32 _lsa_lookup_sids(const POLICY_HND *hnd,
+ uint32 num_entries, DOM_SID2 *sid,
+ const LOOKUP_LEVEL *level,
+ DOM_R_REF *ref,
+ LSA_TRANS_NAME_ENUM *trn,
+ uint32 *mapped_count);
+uint32 _lsa_query_info_pol(POLICY_HND *hnd, uint16 info_class,
+ fstring domain_name, DOM_SID *domain_sid);
+uint32 _lsa_close(POLICY_HND *hnd);
+uint32 _lsa_set_secret(const POLICY_HND *hnd_secret,
+ const STRING2 *val,
+ uint32 unknown);
+uint32 _lsa_query_secret(const POLICY_HND *hnd_secret,
+ STRING2 *curval, NTTIME *curtime,
+ STRING2 *oldval, NTTIME *oldtime);
+uint32 _lsa_create_secret(const POLICY_HND *hnd,
+ const UNISTR2 *secret_name, uint32 des_access,
+ POLICY_HND *hnd_secret);
+uint32 _lsa_open_secret(const POLICY_HND *hnd,
+ const UNISTR2 *secret_name, uint32 des_access,
+ POLICY_HND *hnd_secret);
+
+/*The following definitions come from msrpc/msrpcd.c */
+
+void exit_server(char *reason);
+
+/*The following definitions come from msrpc/msrpcd_process.c */
+
+BOOL get_user_creds(int c, vuser_key * uk);
+void close_srv_auth_array(rpcsrv_struct * l);
+void add_srv_auth_fn(rpcsrv_struct * l, srv_auth_fns * fn);
+BOOL msrpcd_init(int c, rpcsrv_struct ** l);
+void msrpcd_process(msrpc_service_fns * fn, rpcsrv_struct * l,
+ const char *name);
+
+/*The following definitions come from netlogond/creds_db.c */
+
+BOOL cred_get(uint32 pid, const char *domain, const char* wks, struct dcinfo *dc);
+BOOL cred_store(uint32 pid, const char *domain, const char* wks, struct dcinfo *dc);
+BOOL cred_init_db(void);
+
+/*The following definitions come from netlogond/netlogond.c */
+
+msrpc_service_fns *get_service_fns(void);
+
+/*The following definitions come from netlogond/srv_netlogon_nt.c */
+
+uint32 _net_req_chal(const UNISTR2 * uni_logon_server,
+ const UNISTR2 * uni_logon_client,
+ const DOM_CHAL * clnt_chal,
+ DOM_CHAL * srv_chal, uint16 remote_pid);
+uint32 _net_logon_ctrl2(const UNISTR2 * uni_server_name,
+ uint32 function_code,
+ uint32 query_level,
+ uint32 switch_value,
+ uint32 * reply_switch_value,
+ NETLOGON_INFO * logon_info);
+uint32 _net_trust_dom_list(const UNISTR2 * uni_server_name,
+ uint32 function_code, BUFFER2 * uni_trust_dom_name);
+uint32 _net_auth(const DOM_LOG_INFO * clnt_id,
+ const DOM_CHAL * clnt_chal,
+ DOM_CHAL * srv_chal, uint16 remote_pid);
+uint32 _net_auth_2(const DOM_LOG_INFO * clnt_id,
+ const DOM_CHAL * clnt_chal,
+ const NEG_FLAGS * clnt_flgs,
+ DOM_CHAL * srv_chal,
+ NEG_FLAGS * srv_flgs, uint16 remote_pid);
+uint32 _net_srv_pwset(const DOM_CLNT_INFO * clnt_id,
+ const uint8 pwd[16],
+ DOM_CRED * srv_cred, uint16 remote_pid);
+uint32 _net_sam_logon(const DOM_SAM_INFO * sam_id,
+ uint16 validation_level,
+ DOM_CRED * srv_creds,
+ uint16 * switch_value,
+ NET_USER_INFO_3 * user, uint16 remote_pid);
+uint32 _net_sam_logoff(const DOM_SAM_INFO * sam_id,
+ DOM_CRED * srv_creds, uint16 remote_pid);
+uint32 _net_sam_sync(const UNISTR2 * uni_srv_name,
+ const UNISTR2 * uni_cli_name,
+ uint32 database_id,
+ uint32 restart_state,
+ uint32 * sync_context,
+ uint32 max_size,
+ uint32 * num_deltas,
+ uint32 * num_deltas2,
+ SAM_DELTA_HDR * hdr_deltas, SAM_DELTA_CTR * deltas);
/*The following definitions come from nmbd/asyncdns.c */
@@ -814,7 +1270,6 @@ void kill_async_dns_child(void);
/*The following definitions come from nmbd/nmbd.c */
-BOOL reload_services(BOOL test);
/*The following definitions come from nmbd/nmbd_become_dmb.c */
@@ -891,7 +1346,6 @@ void add_logon_names(void);
/*The following definitions come from nmbd/nmbd_mynames.c */
-void register_my_workgroup_one_subnet(struct subnet_record *subrec);
BOOL register_my_workgroup_and_names(void);
void release_my_names(void);
void refresh_my_names(time_t t);
@@ -1091,8 +1545,6 @@ void write_browse_list(time_t t, BOOL force_write);
/*The following definitions come from nmbd/nmbd_subnetdb.c */
-void close_subnet(struct subnet_record *subrec);
-struct subnet_record *make_normal_subnet(struct interface *iface);
BOOL create_subnets(void);
BOOL we_are_a_wins_client(void);
struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec);
@@ -1143,20 +1595,21 @@ void expire_workgroups_and_servers(time_t t);
/*The following definitions come from param/loadparm.c */
-void lp_talloc_free(void);
+struct vfs_options *lp_vfsoptions(int i) ;
char *lp_logfile(void);
char *lp_smbrun(void);
char *lp_configfile(void);
char *lp_smb_passwd_file(void);
+char *lp_sam_directory(void);
+char *lp_smb_passgrp_file(void);
+char *lp_smb_group_file(void);
+char *lp_smb_alias_file(void);
char *lp_serverstring(void);
char *lp_printcapname(void);
char *lp_lockdir(void);
-char *lp_utmpdir(void);
char *lp_rootdir(void);
-char *lp_source_environment(void);
char *lp_defaultservice(void);
char *lp_msg_command(void);
-char *lp_dfree_command(void);
char *lp_hosts_equiv(void);
char *lp_auto_services(void);
char *lp_passwd_program(void);
@@ -1164,12 +1617,14 @@ char *lp_passwd_chat(void);
char *lp_passwordserver(void);
char *lp_name_resolve_order(void);
char *lp_workgroup(void);
+char *lp_trusted_domains(void);
+char *lp_trusting_domains(void);
char *lp_username_map(void);
+char *lp_aliasname_map(void);
char *lp_groupname_map(void);
-char *lp_logon_script(void);
-char *lp_logon_path(void);
-char *lp_logon_drive(void);
-char *lp_logon_home(void);
+char *lp_builtinname_map(void);
+char *lp_builtinrid_file(void);
+char *lp_ntusrname_map(void);
char *lp_remote_announce(void);
char *lp_remote_browse_sync(void);
char *lp_wins_server(void);
@@ -1179,21 +1634,18 @@ char *lp_nis_home_map_name(void);
char *lp_netbios_aliases(void);
char *lp_driverfile(void);
char *lp_panic_action(void);
-char *lp_adduser_script(void);
-char *lp_deluser_script(void);
-char *lp_wins_hook(void);
-char *lp_domain_groups(void);
-char *lp_domain_admin_group(void);
-char *lp_domain_guest_group(void);
-char *lp_domain_admin_users(void);
-char *lp_domain_guest_users(void);
char *lp_nt_forms(void);
char *lp_nt_drivers_file(void);
+char *lp_dfs_map(void);
char *lp_ldap_server(void);
char *lp_ldap_suffix(void);
-char *lp_ldap_filter(void);
-char *lp_ldap_root(void);
-char *lp_ldap_rootpasswd(void);
+char *lp_ldap_bind_as(void);
+char *lp_ldap_passwd_file(void);
+char *lp_ldap_url(void);
+char *lp_ldap_realm(void);
+char *lp_ldap_computers_subcontext(void);
+char *lp_ldap_users_subcontext(void);
+char *lp_ldap_builtin_subcontext(void);
int lp_ssl_version(void);
char *lp_ssl_hosts(void);
char *lp_ssl_hosts_resign(void);
@@ -1213,9 +1665,7 @@ BOOL lp_wins_support(void);
BOOL lp_we_are_a_wins_server(void);
BOOL lp_wins_proxy(void);
BOOL lp_local_master(void);
-BOOL lp_domain_master(void);
BOOL lp_domain_logons(void);
-BOOL lp_preferred_master(void);
BOOL lp_load_printers(void);
BOOL lp_use_rhosts(void);
BOOL lp_readprediction(void);
@@ -1226,11 +1676,12 @@ BOOL lp_null_passwords(void);
BOOL lp_strip_dot(void);
BOOL lp_encrypted_passwords(void);
BOOL lp_update_encrypted(void);
+BOOL lp_client_ntlmv2(void);
+BOOL lp_server_ntlmv2(void);
+BOOL lp_client_schannel(void);
+BOOL lp_server_schannel(void);
BOOL lp_syslog_only(void);
BOOL lp_timestamp_logs(void);
-BOOL lp_debug_hires_timestamp(void);
-BOOL lp_debug_pid(void);
-BOOL lp_debug_uid(void);
BOOL lp_browse_list(void);
BOOL lp_unix_realname(void);
BOOL lp_nis_home_map(void);
@@ -1240,10 +1691,7 @@ BOOL lp_passwd_chat_debug(void);
BOOL lp_ole_locking_compat(void);
BOOL lp_nt_smb_support(void);
BOOL lp_nt_pipe_support(void);
-BOOL lp_nt_acl_support(void);
BOOL lp_stat_cache(void);
-BOOL lp_allow_trusted_domains(void);
-BOOL lp_restrict_anonymous(void);
int lp_os_level(void);
int lp_max_ttl(void);
int lp_max_wins_ttl(void);
@@ -1269,9 +1717,12 @@ int lp_machine_password_timeout(void);
int lp_change_notify_timeout(void);
int lp_stat_cache_size(void);
int lp_map_to_guest(void);
-int lp_min_passwd_length(void);
-int lp_oplock_break_wait_time(void);
int lp_ldap_port(void);
+int lp_ldap_protocol_version(void);
+char *lp_logon_script(const user_struct* );
+char *lp_logon_path(const user_struct* );
+char *lp_logon_drive(const user_struct* );
+char *lp_logon_home(const user_struct* );
char *lp_preexec(int );
char *lp_postexec(int );
char *lp_rootpreexec(int );
@@ -1309,8 +1760,6 @@ char *lp_veto_files(int );
char *lp_hide_files(int );
char *lp_veto_oplocks(int );
char *lp_driverlocation(int );
-BOOL lp_preexec_close(int );
-BOOL lp_rootpreexec_close(int );
BOOL lp_revalidate(int );
BOOL lp_casesensitive(int );
BOOL lp_preservecase(int );
@@ -1329,10 +1778,8 @@ BOOL lp_map_hidden(int );
BOOL lp_map_archive(int );
BOOL lp_locking(int );
BOOL lp_strict_locking(int );
-BOOL lp_utmp(int );
BOOL lp_share_modes(int );
BOOL lp_oplocks(int );
-BOOL lp_level2_oplocks(int );
BOOL lp_onlyuser(int );
BOOL lp_manglednames(int );
BOOL lp_widelinks(int );
@@ -1347,22 +1794,20 @@ BOOL lp_dos_filetimes(int );
BOOL lp_dos_filetime_resolution(int );
BOOL lp_fake_dir_create_times(int );
BOOL lp_blocking_locks(int );
-BOOL lp_inherit_perms(int );
-int lp_create_mask(int );
+int lp_create_mode(int );
int lp_force_create_mode(int );
-int _lp_security_mask(int );
-int _lp_force_security_mode(int );
-int lp_dir_mask(int );
+int lp_dir_mode(int );
int lp_force_dir_mode(int );
-int _lp_dir_security_mask(int );
-int _lp_force_dir_security_mode(int );
int lp_max_connections(int );
int lp_defaultcase(int );
int lp_minprintspace(int );
int lp_printing(int );
-int lp_oplock_contention_limit(int );
-int lp_write_cache_size(int );
char lp_magicchar(int );
+char *lp_mysql_host(void);
+char *lp_mysql_user(void);
+char *lp_mysql_passfile(void);
+char *lp_mysql_db(void);
+char *lp_mysql_table(void);
BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir);
int lp_add_service(char *pszService, int iDefaultService);
BOOL lp_add_printer(char *pszPrintername, int iDefaultService);
@@ -1376,10 +1821,8 @@ void lp_add_one_printer(char *name,char *comment);
BOOL lp_loaded(void);
void lp_killunused(BOOL (*snumused)(int ));
BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc);
-void lp_resetnumservices(void);
int lp_numservices(void);
-void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint);
-void lp_dump_one(FILE *f, BOOL show_defaults, int snum);
+void lp_dump(FILE *f, BOOL show_defaults);
int lp_servicenumber(char *pszServiceName);
char *volume_label(int snum);
void lp_remove_service(int snum);
@@ -1390,10 +1833,9 @@ int lp_minor_announce_version(void);
void lp_set_name_resolve_order(char *new_order);
void lp_set_kernel_oplocks(BOOL val);
BOOL lp_kernel_oplocks(void);
-int lp_security_mask(int snum);
-int lp_force_security_mode(int snum);
-int lp_dir_security_mask(int snum);
-int lp_force_dir_security_mode(int snum);
+int lp_server_role(void);
+BOOL lp_domain_master(void);
+BOOL lp_preferred_master(void);
/*The following definitions come from param/params.c */
@@ -1403,88 +1845,191 @@ BOOL pm_process( char *FileName,
/*The following definitions come from passdb/ldap.c */
-struct passdb_ops *ldap_initialize_password_db(void);
+BOOL ldap_connect(void);
+void ldap_disconnect(void);
+BOOL ldap_search_for(char *filter);
+BOOL ldap_search_by_name(const char *user);
+BOOL ldap_search_by_uid(int uid);
+BOOL ldap_get_attribute(char *attribute, char *value);
+struct smb_passwd *ldap_getpw(void);
+BOOL ldap_allocaterid(uint32 *rid);
+struct smb_passdb_ops *ldap_initialise_password_db(void);
+
+/*The following definitions come from passdb/ldapdb.c */
+
+BOOL ldapdb_init(void);
+BOOL ldapdb_get_uint32(LDAPDB *hds, const char *attribute, uint32 *val);
+BOOL ldapdb_get_unistr_value(LDAPDB *hds, const char *attribute, UNISTR2 *buf);
+BOOL ldapdb_oc_check(LDAPDB *hds, const char *ocname);
+BOOL ldapdb_queue_unistr_mod(LDAPMod ***modlist,int modop, const char *attribute, const UNISTR2 *value);
+BOOL ldapdb_queue_uint32_mod(LDAPMod ***modlist, int modop, const char *attribute, uint32 value);
+BOOL ldapdb_get_domain_info(PLDAPDB _hds, const char *realm, DOM_SID *sid, fstring nbname);
+void unistr2_to_utf8(char *dest, const UNISTR2 *str, size_t maxlen);
+void utf8_to_unistr2(UNISTR2 *unistr, const char *str);
+
+/*The following definitions come from passdb/mysqlpass.c */
+
+int mysql_db_lock_connect( MYSQL *handle );
+void *mysql_startpwent( BOOL update );
+void mysql_endpwent( void *ptr );
+SMB_BIG_UINT mysql_getpwpos(void *vp);
+BOOL mysql_setpwpos(void *vp, SMB_BIG_UINT pos);
+void *mysql_fill_smb_passwd( MYSQL_ROW *row );
+struct smb_passwd *mysql_getsmbpwent(void *vp);
+void *mysql_fetch_passwd( void *(*filler)(MYSQL_ROW*), char *where );
+void *mysql_getpwuid(void *(*filler)(MYSQL_ROW *), uid_t uid);
+struct smb_passwd *mysql_getsmbpwuid(uid_t uid);
+void *mysql_getpwnam(void *(*filler)(MYSQL_ROW *), char *field, const char *name);
+struct smb_passwd *mysql_getsmbpwnam(const char *unix_name);
+BOOL mysql_del_smb( MYSQL *handle, char *unix_name );
+BOOL mysql_add_smb( MYSQL *handle, struct smb_passwd *smb );
+BOOL mysql_mod_smb( MYSQL *handle, struct smb_passwd *smb, BOOL override );
+BOOL mysql_add_smbpwd_entry(struct smb_passwd *smb);
+BOOL mysql_mod_smbpwd_entry(struct smb_passwd *smb, BOOL override);
+struct smb_passdb_ops *mysql_initialise_password_db(void);
+
+/*The following definitions come from passdb/mysqlsampass.c */
+
+void *mysql_fill_sam_passwd( MYSQL_ROW *row );
+struct sam_passwd *mysql_getsampwent(void *vp);
+struct sam_passwd *mysql_getsampwrid(uint32 rid);
+struct sam_passwd *mysql_getsampwuid(uid_t uid);
+struct sam_passwd *mysql_getsampwntnam(const char *nt_name);
+struct sam_disp_info *mysql_getsamdispntnam(const char *nt_name);
+struct sam_disp_info *mysql_getsamdisprid(uint32 rid);
+struct sam_disp_info *mysql_getsamdispent(void *vp);
+BOOL mysql_add_sampwd_entry(struct sam_passwd *sam);
+BOOL mysql_mod_sampwd_entry(struct sam_passwd *sam, BOOL override);
+struct sam_passdb_ops *mysql_initialise_sam_password_db(void);
/*The following definitions come from passdb/nispass.c */
-struct passdb_ops *nisplus_initialize_password_db(void);
+struct passdb_ops *nisplus_initialise_password_db(void);
+
+/*The following definitions come from passdb/nt5ldap.c */
+
+BOOL nt5ldap_make_local_grp(LDAPDB * hds, LOCAL_GRP * group,
+ LOCAL_GRP_MEMBER ** members, int *num_membs, uint32 req_type);
+BOOL nt5ldap_make_sam_user_info21(LDAPDB *hds, SAM_USER_INFO_21 *usr);
+BOOL nt5ldap_sam_user_info21_mods(const SAM_USER_INFO_21 *usr, LDAPMod ***mods, int op,
+ char *rdn, size_t rdnmaxlen, BOOL *iscomputer_p);
/*The following definitions come from passdb/pass_check.c */
void dfs_unlogin(void);
-BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
- BOOL (*fn)(char *, char *));
+BOOL pass_check(const char *_user, const char *_password,
+ int pwlen, const struct passwd *pwd,
+ BOOL (*fn)(const char *, const char *));
/*The following definitions come from passdb/passdb.c */
-BOOL initialize_password_db(void);
-struct smb_passwd *iterate_getsmbpwrid(uint32 user_rid);
-struct smb_passwd *iterate_getsmbpwuid(uid_t smb_userid);
-struct smb_passwd *iterate_getsmbpwnam(char *name);
+BOOL initialise_password_db(void);
+struct smb_passwd *iterate_getsmbpwuid(uid_t unix_uid);
+struct smb_passwd *iterate_getsmbpwnam(const char *name);
void *startsmbpwent(BOOL update);
void endsmbpwent(void *vp);
+SMB_BIG_UINT getsmbpwpos(void *vp);
+BOOL setsmbpwpos(void *vp, SMB_BIG_UINT tok);
struct smb_passwd *getsmbpwent(void *vp);
BOOL add_smbpwd_entry(struct smb_passwd *newpwd);
BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override);
-BOOL del_smbpwd_entry(const char *name);
-struct smb_passwd *getsmbpwnam(char *name);
-struct smb_passwd *getsmbpwrid(uint32 user_rid);
-struct smb_passwd *getsmbpwuid(uid_t smb_userid);
-struct sam_passwd *iterate_getsam21pwnam(char *name);
+struct smb_passwd *getsmbpwnam(const char *name);
+struct smb_passwd *getsmbpwuid(uid_t unix_uid);
+void pwdb_init_smb(struct smb_passwd *user);
+struct smb_passwd *pwdb_smb_map_names(struct smb_passwd *smb);
+
+/*The following definitions come from passdb/passgrp.c */
+
+BOOL initialise_passgrp_db(void);
+struct smb_passwd *iterate_getsmbgrprid(uint32 user_rid,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss);
+struct smb_passwd *iterate_getsmbgrpuid(uid_t unix_uid,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss);
+struct smb_passwd *iterate_getsmbgrpntnam(const char *nt_name,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss);
+void *startsmbgrpent(BOOL update);
+void endsmbgrpent(void *vp);
+struct smb_passwd *getsmbgrpent(void *vp,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss);
+struct smb_passwd *getsmbgrpntnam(char *name,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss);
+struct smb_passwd *getsmbgrprid(uint32 user_rid,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss);
+struct smb_passwd *getsmbgrpuid(uid_t unix_uid,
+ uint32 **grps, int *num_grps,
+ uint32 **alss, int *num_alss);
+
+/*The following definitions come from passdb/passgrpldap.c */
+
+struct passgrp_ops *ldap_initialise_password_grp(void);
+
+/*The following definitions come from passdb/passgrpnt5ldap.c */
+
+
+/*The following definitions come from passdb/sampass.c */
+
+struct sam_passdb_ops *file_initialise_sam_password_db(void);
+
+/*The following definitions come from passdb/sampassdb.c */
+
+BOOL initialise_sam_password_db(void);
+void *startsam21pwent(BOOL update);
+void endsam21pwent(void *vp);
+struct sam_passwd *getsam21pwent(void *vp);
+BOOL mod_sam21pwd_entry(struct sam_passwd* pwd, BOOL override);
+struct sam_passwd *iterate_getsam21pwntnam(const char *ntname);
struct sam_passwd *iterate_getsam21pwrid(uint32 rid);
struct sam_passwd *iterate_getsam21pwuid(uid_t uid);
struct sam_disp_info *getsamdisprid(uint32 rid);
-struct sam_passwd *getsam21pwent(void *vp);
-struct sam_passwd *getsam21pwnam(char *name);
+struct sam_passwd *getsam21pwntnam(const char *name);
struct sam_passwd *getsam21pwrid(uint32 rid);
-void pdb_init_smb(struct smb_passwd *user);
-void pdb_init_sam(struct sam_passwd *user);
-struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user);
-struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user);
-struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user);
-char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
-uint16 pdb_decode_acct_ctrl(const char *p);
-time_t pdb_get_last_set_time(const char *p);
-void pdb_set_logon_time(char *p, int max_len, time_t t);
-void pdb_set_logoff_time(char *p, int max_len, time_t t);
-void pdb_set_kickoff_time(char *p, int max_len, time_t t);
-void pdb_set_can_change_time(char *p, int max_len, time_t t);
-void pdb_set_must_change_time(char *p, int max_len, time_t t);
-void pdb_set_last_set_time(char *p, int max_len, time_t t);
-void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl);
-BOOL pdb_gethexpwd(char *p, unsigned char *pwd);
-BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid);
-BOOL pdb_generate_sam_sid(char *domain_name, DOM_SID *sid);
-uid_t pdb_user_rid_to_uid(uint32 user_rid);
-gid_t pdb_user_rid_to_gid(uint32 user_rid);
-uint32 pdb_uid_to_user_rid(uid_t uid);
-uint32 pdb_gid_to_group_rid(gid_t gid);
-BOOL pdb_rid_is_user(uint32 rid);
-BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use);
-BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use);
+void pwdb_init_sam(struct sam_passwd *user);
+struct sam_disp_info *pwdb_sam_to_dispinfo(struct sam_passwd *user);
+void copy_id23_to_sam_passwd(struct sam_passwd *to, const SAM_USER_INFO_23 *from);
+void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from);
+struct smb_passwd *pwdb_sam_to_smb(struct sam_passwd *user);
+struct sam_passwd *pwdb_smb_to_sam(struct smb_passwd *user);
+struct sam_passwd *pwdb_sam_map_names(struct sam_passwd *sam);
+
+/*The following definitions come from passdb/sampassldap.c */
+
+BOOL ldap_search_by_rid(uint32 rid);
+BOOL ldap_search_by_ntname(const char *ntname);
+struct sam_passdb_ops *ldap_initialise_sam_password_db(void);
+
+/*The following definitions come from passdb/sampassnt5ldap.c */
+
/*The following definitions come from passdb/smbpass.c */
-char *format_new_smbpasswd_entry(struct smb_passwd *newpwd);
-struct passdb_ops *file_initialize_password_db(void);
+struct smb_passwd *getsmbfilepwent(void *vp);
+struct smb_passdb_ops *file_initialise_password_db(void);
/*The following definitions come from passdb/smbpasschange.c */
-BOOL local_password_change(char *user_name, int local_flags,
- char *new_passwd,
- char *err_str, size_t err_str_len,
- char *msg_str, size_t msg_str_len);
+BOOL local_password_change(char *user_name,
+ BOOL add_user,
+ uint16 acb_info, uint16 acb_mask,
+ char *new_passwd,
+ char *err_str, size_t err_str_len,
+ char *msg_str, size_t msg_str_len);
+
+/*The following definitions come from passdb/smbpassgroup.c */
-/*The following definitions come from passdb/smbpassfile.c */
+struct passgrp_ops *file_initialise_password_grp(void);
+
+/*The following definitions come from passdb/smbpassgroupunix.c */
+
+struct passgrp_ops *unix_initialise_password_grp(void);
+
+/*The following definitions come from passdb/smbpassnt5ldap.c */
-BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth);
-BOOL pw_file_unlock(int fd, int *plock_depth);
-BOOL trust_password_lock( char *domain, char *name, BOOL update);
-BOOL trust_password_unlock(void);
-BOOL trust_password_delete( char *domain, char *name );
-BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_time);
-BOOL set_trust_account_password( unsigned char *md4_new_pwd);
-BOOL trust_get_passwd( unsigned char trust_passwd[16], char *domain, char *myname);
/*The following definitions come from printing/nt_printing.c */
@@ -1515,11 +2060,6 @@ void init_devicemode(NT_DEVICEMODE *nt_devmode);
BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname);
void pcap_printer_fn(void (*fn)(char *, char *));
-/*The following definitions come from printing/print_cups.c */
-
-void cups_printer_fn(void (*fn)(char *, char *));
-int cups_printername_ok(char *name);
-
/*The following definitions come from printing/print_svid.c */
void sysv_printer_fn(void (*fn)(char *, char *));
@@ -1528,182 +2068,745 @@ int sysv_printername_ok(char *name);
/*The following definitions come from printing/printing.c */
void lpq_reset(int snum);
-void print_file(connection_struct *conn, files_struct *file);
-int get_printqueue(int snum,
- connection_struct *conn,print_queue_struct **queue,
+void print_file(connection_struct *conn, const vuser_key *key,
+ int snum, files_struct *file);
+int get_printqueue(int snum, connection_struct *conn, const vuser_key *key,
+ print_queue_struct **queue,
print_status_struct *status);
-void del_printqueue(connection_struct *conn,int snum,int jobid);
-void status_printjob(connection_struct *conn,int snum,int jobid,int status);
+void del_printqueue(connection_struct *conn,const vuser_key *key,
+ int snum,int jobid);
+void status_printjob(connection_struct *conn,const vuser_key *key,
+ int snum,int jobid,int status);
int printjob_encode(int snum, int job);
void printjob_decode(int jobid, int *snum, int *job);
-void status_printqueue(connection_struct *conn,int snum,int status);
+uint32 status_printqueue(connection_struct *conn,const vuser_key *key,
+ int snum,int status);
void load_printers(void);
/*The following definitions come from profile/profile.c */
BOOL profile_setup(BOOL rdonly);
+/*The following definitions come from rpc_client/cli_atsvc.c */
+
+BOOL at_add_job(
+ char *srv_name, AT_JOB_INFO *info, char *command,
+ uint32 *jobid);
+BOOL at_del_job( char *srv_name, uint32 min_jobid, uint32 max_jobid);
+BOOL at_enum_jobs( char *srv_name, uint32 *num_jobs,
+ AT_ENUM_INFO *jobs, char ***commands);
+BOOL at_query_job(char *srv_name,
+ uint32 jobid, AT_JOB_INFO *job, fstring command);
+
+/*The following definitions come from rpc_client/cli_brs.c */
+
+BOOL brs_query_info( const char *srv_name, uint32 switch_value,
+ void *id);
+
+/*The following definitions come from rpc_client/cli_connect.c */
+
+void init_connections(void);
+void free_connections(void);
+void cli_connection_free(struct cli_connection *con);
+void cli_connection_unlink(struct cli_connection *con);
+BOOL cli_connection_init(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con);
+BOOL cli_connection_init_auth(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con,
+ cli_auth_fns * auth, void *auth_creds);
+BOOL cli_connection_getsrv(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con);
+BOOL cli_connection_get(const POLICY_HND * pol, struct cli_connection **con);
+BOOL cli_pol_link(POLICY_HND * to, const POLICY_HND * from);
+BOOL cli_get_usr_sesskey(const POLICY_HND * pol, uchar usr_sess_key[16]);
+BOOL cli_set_con_usr_sesskey(struct cli_connection *con,
+ const uchar usr_sess_key[16]);
+const vuser_key *cli_con_sec_ctx(struct cli_connection *con);
+struct cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con);
+void *cli_conn_get_auth_creds(struct cli_connection *con);
+void *cli_conn_get_auth_info(struct cli_connection *con);
+BOOL cli_conn_set_auth_info(struct cli_connection *con, void *auth_info);
+struct ntdom_info *cli_conn_get_ntinfo(struct cli_connection *con);
+BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16]);
+BOOL cli_con_get_srvname(struct cli_connection *con, char *srv_name);
+BOOL cli_get_sesskey(const POLICY_HND * pol, uchar sess_key[16]);
+BOOL cli_get_sesskey_srv(const char *srv_name, uchar sess_key[16]);
+void cli_con_gen_next_creds(struct cli_connection *con,
+ DOM_CRED * new_clnt_cred);
+void cli_con_get_cli_cred(struct cli_connection *con, DOM_CRED * clnt_cred);
+BOOL cli_con_deal_with_creds(struct cli_connection *con,
+ DOM_CRED * rcv_srv_cred);
+BOOL cli_con_set_creds(const char *srv_name, const uchar sess_key[16],
+ DOM_CRED * cred);
+BOOL rpc_hnd_pipe_req(const POLICY_HND * hnd, uint8 op_num,
+ prs_struct * data, prs_struct * rdata);
+BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
+ prs_struct * data, prs_struct * rdata);
+BOOL rpc_api_write(struct cli_connection *con, prs_struct * data);
+BOOL rpc_api_rcv_pdu(struct cli_connection *con, prs_struct * rdata);
+BOOL rpc_api_send_rcv_pdu(struct cli_connection *con, prs_struct * data,
+ prs_struct * rdata);
+BOOL set_policy_con(struct policy_cache *cache, POLICY_HND * hnd,
+ struct cli_connection *con,
+ void (*free_fn) (struct cli_connection *));
+BOOL get_policy_con(struct policy_cache *cache, const POLICY_HND * hnd,
+ struct cli_connection **con);
+
+/*The following definitions come from rpc_client/cli_eventlog.c */
+
+BOOL event_open(const char* srv_name, const char *log, POLICY_HND *hnd);
+BOOL event_close( POLICY_HND *hnd);
+BOOL event_numofeventlogrec( POLICY_HND *hnd, uint32 *number);
+BOOL event_readeventlog(POLICY_HND *hnd,
+ uint32 number, uint32 flags, uint32 offset,
+ uint32 *number_of_bytes, EVENTLOGRECORD *ev);
+
/*The following definitions come from rpc_client/cli_login.c */
-BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16]);
-BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd);
-BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username,
- uint32 smb_userid_low, char *password,
- NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
-BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username,
- uint32 smb_userid_low, char lm_chal[8], char lm_chal_resp[24],
- char nt_chal_resp[24],
- NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3);
-BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
+uint32 cli_nt_setup_creds(const char *srv_name,
+ const char *domain,
+ const char *myhostname,
+ const char *trust_acct,
+ const uchar trust_pwd[16], uint16 sec_chan);
+BOOL cli_nt_srv_pwset(const char *srv_name, const char *myhostname,
+ const char *trust_acct,
+ const uchar * new_hashof_trust_pwd, uint16 sec_chan);
+BOOL cli_nt_login_general(const char *srv_name, const char *myhostname,
+ const char *domain, const char *username,
+ uint32 luid_low,
+ const char *general,
+ NET_ID_INFO_CTR * ctr, NET_USER_INFO_3 * user_info3);
+BOOL cli_nt_login_interactive(const char *srv_name, const char *myhostname,
+ const char *domain, const char *username,
+ uint32 luid_low,
+ const uchar * lm_owf_user_pwd,
+ const uchar * nt_owf_user_pwd,
+ NET_ID_INFO_CTR * ctr,
+ NET_USER_INFO_3 * user_info3);
+BOOL cli_nt_login_network(const char *srv_name, const char *myhostname,
+ const char *domain, const char *username,
+ uint32 luid_low, const char lm_chal[8],
+ const char *lm_chal_resp,
+ int lm_chal_len,
+ const char *nt_chal_resp,
+ int nt_chal_len,
+ NET_ID_INFO_CTR * ctr, NET_USER_INFO_3 * user_info3);
+BOOL cli_nt_logoff(const char *srv_name, const char *myhostname,
+ NET_ID_INFO_CTR * ctr);
+BOOL net_sam_sync(const char *srv_name,
+ const char *domain,
+ const char *myhostname,
+ const char *trust_acct,
+ uchar trust_passwd[16],
+ SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS],
+ SAM_DELTA_CTR deltas[MAX_SAM_DELTAS], uint32 * num_deltas);
/*The following definitions come from rpc_client/cli_lsarpc.c */
-BOOL do_lsa_open_policy(struct cli_state *cli,
- char *system_name, POLICY_HND *hnd,
- BOOL sec_qos);
-BOOL do_lsa_lookup_sids(struct cli_state *cli,
- POLICY_HND *hnd,
- int num_sids,
- DOM_SID **sids,
- char ***names,
- int *num_names);
-BOOL do_lsa_query_info_pol(struct cli_state *cli,
- POLICY_HND *hnd, uint16 info_class,
- fstring domain_name, DOM_SID *domain_sid);
-BOOL do_lsa_close(struct cli_state *cli, POLICY_HND *hnd);
+BOOL get_domain_sids(const char *domain, DOM_SID * sid3, DOM_SID * sid5);
+BOOL get_trust_sid_and_domain(const char *myname, char *server,
+ DOM_SID * sid, char *domain, size_t len);
+BOOL lsa_open_policy(const char *system_name, POLICY_HND *hnd,
+ BOOL sec_qos, uint32 des_access);
+BOOL lsa_open_policy2(const char *system_name, POLICY_HND *hnd,
+ BOOL sec_qos, uint32 des_access);
+BOOL lsa_create_secret(const POLICY_HND *hnd,
+ const char *secret_name,
+ uint32 des_access, POLICY_HND *hnd_secret);
+BOOL lsa_open_secret(const POLICY_HND *hnd,
+ const char *secret_name,
+ uint32 des_access, POLICY_HND *hnd_secret);
+uint32 lsa_set_secret(POLICY_HND *hnd, const STRING2 * secret);
+BOOL lsa_query_secret(POLICY_HND *hnd, STRING2 * secret, NTTIME * last_update);
+BOOL lsa_lookup_names(POLICY_HND *hnd,
+ int num_names,
+ char **names,
+ DOM_SID ** sids, uint32 ** types, int *num_sids);
+BOOL lsa_lookup_sids(POLICY_HND *hnd,
+ int num_sids,
+ DOM_SID ** sids,
+ char ***names, uint32 ** types, int *num_names);
+BOOL lsa_query_sec_obj(const POLICY_HND *hnd, uint32 sec_info,
+ SEC_DESC_BUF *sec_buf);
+BOOL lsa_query_info_pol(POLICY_HND *hnd, uint16 info_class,
+ fstring domain_name, DOM_SID * domain_sid);
+BOOL lsa_enum_trust_dom(POLICY_HND *hnd, uint32 * enum_ctx,
+ uint32 * num_doms, char ***names, DOM_SID *** sids);
+BOOL lsa_close(POLICY_HND *hnd);
/*The following definitions come from rpc_client/cli_netlogon.c */
-BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level);
-BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
- uint32 neg_flags, DOM_CHAL *srv_chal);
-BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
-BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16]);
-BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
- NET_USER_INFO_3 *user_info3);
-BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr);
-BOOL change_trust_account_password( char *domain, char *remote_machine_list);
+void gen_next_creds( struct ntdom_info *nt, DOM_CRED *new_clnt_cred);
+BOOL cli_net_logon_ctrl2(const char* srv_name, uint32 status_level);
+uint32 cli_net_auth2(const char *srv_name,
+ const char *trust_acct,
+ const char *acct_name,
+ uint16 sec_chan,
+ uint32 *neg_flags, DOM_CHAL *srv_chal);
+uint32 cli_net_req_chal( const char *srv_name, const char* myhostname,
+ DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
+BOOL cli_net_srv_pwset(const char* srv_name,
+ const char* myhostname,
+ const char* trust_acct,
+ const uint8 hashed_trust_pwd[16],
+ uint16 sec_chan_type);
+uint32 cli_net_sam_logon(const char* srv_name, const char* myhostname,
+ NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3);
+BOOL cli_net_sam_logoff(const char* srv_name, const char* myhostname,
+ NET_ID_INFO_CTR *ctr);
+BOOL cli_net_sam_sync( const char* srv_name, const char* myhostname,
+ uint32 database_id,
+ uint32 *num_deltas,
+ SAM_DELTA_HDR *hdr_deltas,
+ SAM_DELTA_CTR *deltas);
+
+/*The following definitions come from rpc_client/cli_netlogon_sync.c */
+
+BOOL synchronise_passdb(void);
/*The following definitions come from rpc_client/cli_pipe.c */
-BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
- prs_struct *data, prs_struct *rdata);
+BOOL create_rpc_request(prs_struct * rhdr, uint16 vuid,
+ uint8 op_num, uint8 flags, int data_len, int auth_len);
+BOOL rpc_api_pipe_req(struct cli_connection *con, uint8 opnum,
+ prs_struct * data, prs_struct * rdata);
+BOOL cli_send_and_rcv_pdu_trans(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu);
+BOOL cli_send_and_rcv_pdu_rw(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu);
+BOOL cli_send_and_rcv_pdu(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu);
+BOOL cli_rcv_pdu(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum, prs_struct *rdata);
+BOOL rpc_pipe_bind(struct cli_connection *con,
+ const char *pipe_name,
+ RPC_IFACE * abstract, RPC_IFACE * transfer);
void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs);
-BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name);
-void cli_nt_session_close(struct cli_state *cli);
+BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name,
+ uint16 * fnum);
+void cli_nt_session_close(struct cli_state *cli, uint16 fnum);
+
+/*The following definitions come from rpc_client/cli_pipe_netsec.c */
+
+
+/*The following definitions come from rpc_client/cli_pipe_noauth.c */
+
+
+/*The following definitions come from rpc_client/cli_pipe_ntlmssp.c */
+
/*The following definitions come from rpc_client/cli_reg.c */
-BOOL do_reg_connect(struct cli_state *cli, char *full_keyname, char *key_name,
+BOOL reg_connect( const char* srv_name,
+ const char *full_keyname,
+ char *key_name,
+ uint32 access_mask,
POLICY_HND *reg_hnd);
-BOOL do_reg_open_hklm(struct cli_state *cli, uint16 unknown_0, uint32 level,
+BOOL reg_open_hkcr( struct cli_connection *con,
+ uint16 unknown_0, uint32 level,
POLICY_HND *hnd);
-BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level,
+BOOL reg_open_hklm( struct cli_connection *con,
+ uint16 unknown_0, uint32 level,
POLICY_HND *hnd);
-BOOL do_reg_flush_key(struct cli_state *cli, POLICY_HND *hnd);
-BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd,
- char *class, uint32 *class_len,
+BOOL reg_open_hku( struct cli_connection *con,
+ uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd);
+BOOL reg_flush_key( POLICY_HND *hnd);
+BOOL reg_query_key( POLICY_HND *hnd,
+ char *key_class, uint32 *class_len,
uint32 *num_subkeys, uint32 *max_subkeylen,
uint32 *max_subkeysize, uint32 *num_values,
uint32 *max_valnamelen, uint32 *max_valbufsize,
uint32 *sec_desc, NTTIME *mod_time);
-BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk);
-BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd,
- char *type, uint32 *unk_0, uint32 *unk_1);
-BOOL do_reg_set_key_sec(struct cli_state *cli, POLICY_HND *hnd, SEC_DESC_BUF *sec_desc_buf);
-BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, uint32 *sec_buf_size, SEC_DESC_BUF **ppsec_desc_buf);
-BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name);
-BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name);
-BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
+BOOL reg_unknown_1a( POLICY_HND *hnd, uint32 *unk);
+BOOL reg_query_info( POLICY_HND *hnd,
+ const char* val_name,
+ uint32 *type, BUFFER2 *buffer);
+BOOL reg_set_key_sec( POLICY_HND *hnd,
+ uint32 sec_info,
+ uint32 sec_buf_size, SEC_DESC *sec_buf);
+BOOL reg_get_key_sec( POLICY_HND *hnd,
+ uint32 sec_info,
+ uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf);
+BOOL reg_delete_val( POLICY_HND *hnd, char *val_name);
+BOOL reg_delete_key( POLICY_HND *hnd, char *key_name);
+BOOL reg_create_key( POLICY_HND *hnd,
char *key_name, char *key_class,
SEC_ACCESS *sam_access,
POLICY_HND *key);
-BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd,
+BOOL reg_enum_key( POLICY_HND *hnd,
int key_index, char *key_name,
uint32 *unk_1, uint32 *unk_2,
time_t *mod_time);
-BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd,
+BOOL reg_create_val( POLICY_HND *hnd,
char *val_name, uint32 type, BUFFER3 *data);
-BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd,
+BOOL reg_enum_val( POLICY_HND *hnd,
int val_index, int max_valnamelen, int max_valbufsize,
fstring val_name,
uint32 *val_type, BUFFER2 *value);
-BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd,
+BOOL reg_open_entry( POLICY_HND *hnd,
char *key_name, uint32 unk_0,
POLICY_HND *key_hnd);
-BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd);
+BOOL reg_close( POLICY_HND *hnd);
+BOOL reg_shutdown(const char *srv_name,
+ const char *msg, uint32 timeout, uint16 flags);
/*The following definitions come from rpc_client/cli_samr.c */
-BOOL get_samr_query_usergroups(struct cli_state *cli,
- POLICY_HND *pol_open_domain, uint32 user_rid,
- uint32 *num_groups, DOM_GID *gid);
-BOOL get_samr_query_userinfo(struct cli_state *cli,
- POLICY_HND *pol_open_domain,
- uint32 info_level,
- uint32 user_rid, SAM_USER_INFO_21 *usr);
-BOOL do_samr_chgpasswd_user(struct cli_state *cli,
- char *srv_name, char *user_name,
- char nt_newpass[516], uchar nt_oldhash[16],
- char lm_newpass[516], uchar lm_oldhash[16]);
-BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name);
-BOOL do_samr_query_dom_info(struct cli_state *cli,
- POLICY_HND *domain_pol, uint16 switch_value);
-BOOL do_samr_enum_dom_users(struct cli_state *cli,
- POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
+BOOL samr_chgpasswd_user( struct cli_connection *con,
+ const char *srv_name, const char *user_name,
+ const char nt_newpass[516], const uchar nt_oldhash[16],
+ const char lm_newpass[516], const uchar lm_oldhash[16]);
+BOOL samr_get_dom_pwinfo(struct cli_connection *con, const char *srv_name);
+BOOL samr_query_dom_info( POLICY_HND *domain_pol, uint16 switch_value,
+ SAM_UNK_CTR *ctr);
+uint32 samr_enum_domains( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_domains);
+uint32 samr_enum_dom_groups( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_groups);
+uint32 samr_enum_dom_aliases( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_aliases);
+uint32 samr_enum_dom_users( POLICY_HND *pol, uint32 *start_idx,
uint16 acb_mask, uint16 unk_1, uint32 size,
struct acct_info **sam,
- int *num_sam_users);
-BOOL do_samr_connect(struct cli_state *cli,
- char *srv_name, uint32 unknown_0,
+ uint32 *num_sam_users);
+BOOL samr_connect( const char *srv_name, uint32 access_mask,
POLICY_HND *connect_pol);
-BOOL do_samr_open_user(struct cli_state *cli,
- POLICY_HND *pol, uint32 unk_0, uint32 rid,
+BOOL samr_query_sec_obj( const POLICY_HND *pol,
+ uint32 type,
+ SEC_DESC_BUF *buf);
+BOOL samr_open_user( const POLICY_HND *pol,
+ uint32 unk_0, uint32 rid,
POLICY_HND *user_pol);
-BOOL do_samr_open_domain(struct cli_state *cli,
- POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
+BOOL samr_open_alias( const POLICY_HND *domain_pol,
+ uint32 flags, uint32 rid,
+ POLICY_HND *alias_pol);
+BOOL samr_del_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid);
+BOOL samr_add_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid);
+BOOL samr_delete_dom_alias( POLICY_HND *alias_pol);
+uint32 samr_create_dom_user( POLICY_HND *domain_pol, const char *acct_name,
+ uint32 unk_0, uint32 unk_1,
+ POLICY_HND *user_pol, uint32 *rid);
+BOOL samr_create_dom_alias( POLICY_HND *domain_pol, const char *acct_name,
+ POLICY_HND *alias_pol, uint32 *rid);
+BOOL samr_query_aliasinfo( POLICY_HND *alias_pol, uint16 switch_value,
+ ALIAS_INFO_CTR *ctr);
+BOOL samr_set_aliasinfo( POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr);
+BOOL samr_open_group( const POLICY_HND *domain_pol,
+ uint32 flags, uint32 rid,
+ POLICY_HND *group_pol);
+BOOL samr_del_groupmem( POLICY_HND *group_pol, uint32 rid);
+BOOL samr_add_groupmem( POLICY_HND *group_pol, uint32 rid);
+BOOL samr_delete_dom_user( POLICY_HND *user_pol);
+BOOL samr_delete_dom_group( POLICY_HND *group_pol);
+BOOL samr_create_dom_group( POLICY_HND *domain_pol, const char *acct_name,
+ POLICY_HND *group_pol, uint32 *rid);
+BOOL samr_set_groupinfo( POLICY_HND *group_pol, GROUP_INFO_CTR *ctr);
+BOOL samr_unknown_2d( const POLICY_HND *domain_pol,
+ const DOM_SID *sid);
+BOOL samr_open_domain( const POLICY_HND *connect_pol,
+ uint32 ace_perms,
+ const DOM_SID *sid,
POLICY_HND *domain_pol);
-BOOL do_samr_query_unknown_12(struct cli_state *cli,
- POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
- uint32 *num_aliases,
- fstring als_names [MAX_LOOKUP_SIDS],
- uint32 num_als_users[MAX_LOOKUP_SIDS]);
-BOOL do_samr_query_usergroups(struct cli_state *cli,
- POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid);
-BOOL do_samr_query_userinfo(struct cli_state *cli,
- POLICY_HND *pol, uint16 switch_value, void* usr);
-BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd);
+BOOL samr_query_lookup_domain( POLICY_HND *pol, const char *dom_name,
+ DOM_SID *dom_sid);
+BOOL samr_query_lookup_names(const POLICY_HND *pol, uint32 flags,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids, uint32 **types);
+BOOL samr_query_lookup_rids( const POLICY_HND *pol, uint32 flags,
+ uint32 num_rids, const uint32 *rids,
+ uint32 *num_names,
+ char ***names,
+ uint32 **type);
+BOOL samr_query_aliasmem( const POLICY_HND *alias_pol,
+ uint32 *num_mem, DOM_SID2 *sid);
+BOOL samr_query_useraliases( const POLICY_HND *pol,
+ uint32 *ptr_sid, DOM_SID2 *sid,
+ uint32 *num_aliases, uint32 **rid);
+BOOL samr_query_groupmem( POLICY_HND *group_pol,
+ uint32 *num_mem, uint32 **rid, uint32 **attr);
+BOOL samr_query_usergroups( POLICY_HND *pol, uint32 *num_groups,
+ DOM_GID **gid);
+BOOL samr_query_groupinfo( POLICY_HND *pol,
+ uint16 switch_value, GROUP_INFO_CTR* ctr);
+BOOL samr_set_userinfo2( POLICY_HND *pol, uint16 switch_value,
+ void* usr);
+BOOL samr_set_userinfo( POLICY_HND *pol, uint16 switch_value, void* usr);
+BOOL samr_query_userinfo( POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+BOOL samr_close( POLICY_HND *hnd);
+BOOL samr_query_dispinfo( POLICY_HND *pol_domain, uint16 level,
+ uint32 *num_entries,
+ SAM_DISPINFO_CTR *ctr);
+
+/*The following definitions come from rpc_client/cli_spoolss.c */
+
+BOOL spoolss_enum_printers(uint32 flags, const char *srv_name,
+ uint32 level,
+ uint32 *count,
+ void ***printers);
+uint32 spoolss_enum_jobs( const POLICY_HND *hnd,
+ uint32 firstjob,
+ uint32 numofjobs,
+ uint32 level,
+ uint32 *buf_size,
+ uint32 *count,
+ void ***jobs);
+BOOL spoolss_open_printer_ex( const char *printername,
+ uint32 cbbuf, uint32 devmod, uint32 des_access,
+ const char *station, const char *username,
+ POLICY_HND *hnd);
+BOOL spoolss_closeprinter(POLICY_HND *hnd);
/*The following definitions come from rpc_client/cli_srvsvc.c */
-BOOL do_srv_net_srv_conn_enum(struct cli_state *cli,
- char *server_name, char *qual_name,
+BOOL srv_net_srv_tprt_enum(
+ const char *srv_name,
+ uint32 switch_value, SRV_TPRT_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_net_srv_conn_enum( char *srv_name, char *qual_name,
uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd);
-BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
- char *server_name, char *qual_name,
+BOOL srv_net_srv_sess_enum( char *srv_name, char *qual_name, char *user_name,
uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd);
-BOOL do_srv_net_srv_share_enum(struct cli_state *cli,
- char *server_name,
- uint32 switch_value, SRV_R_NET_SHARE_ENUM *r_o,
- uint32 preferred_len, ENUM_HND *hnd);
-BOOL do_srv_net_srv_file_enum(struct cli_state *cli,
- char *server_name, char *qual_name,
+BOOL srv_net_srv_share_enum( char *srv_name,
+ uint32 switch_value, SRV_SHARE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_net_srv_share_get_info(const char *srv_name,
+ const char *share_name,
+ uint32 info_level);
+BOOL srv_net_srv_file_enum( char *srv_name, char *qual_name, uint32 file_id,
uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd);
-BOOL do_srv_net_srv_get_info(struct cli_state *cli,
- char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr);
+BOOL srv_net_srv_get_info( char *srv_name, uint32 switch_value,
+ SRV_INFO_CTR *ctr);
+BOOL srv_net_remote_tod( char *srv_name, TIME_OF_DAY_INFO *tod);
+
+/*The following definitions come from rpc_client/cli_svcctl.c */
+
+BOOL svc_open_sc_man( const char *srv_name, char *db_name,
+ uint32 des_access,
+ POLICY_HND *hnd);
+BOOL svc_open_service( POLICY_HND *scm_hnd,
+ const char *srv_name,
+ uint32 des_access,
+ POLICY_HND *hnd);
+BOOL svc_enum_svcs( POLICY_HND *hnd,
+ uint32 services_type, uint32 services_state,
+ uint32 *buf_size, uint32 *resume_hnd,
+ uint32 *dos_error,
+ ENUM_SRVC_STATUS **svcs, uint32 *num_svcs);
+BOOL svc_stop_service( POLICY_HND *hnd,
+ uint32 unknown);
+BOOL svc_start_service( POLICY_HND *hnd,
+ uint32 argc,
+ char **argv);
+BOOL svc_query_svc_cfg( POLICY_HND *hnd,
+ QUERY_SERVICE_CONFIG *cfg,
+ uint32 *buf_size);
+BOOL svc_close(POLICY_HND *hnd);
+BOOL svc_change_svc_cfg( POLICY_HND *hnd,
+ uint32 service_type, uint32 start_type,
+ uint32 unknown_0,
+ uint32 error_control,
+ char* bin_path_name, char* load_order_grp,
+ uint32 tag_id,
+ char* dependencies, char* service_start_name,
+ char* password,
+ char* disp_name);
+
+/*The following definitions come from rpc_client/cli_use.c */
+
+void init_cli_use(void);
+void free_cli_use(void);
+struct cli_state *cli_net_use_add(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL redir, BOOL reuse, BOOL *is_new);
+BOOL cli_net_use_del(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL force_close, BOOL *connection_closed);
+void cli_net_use_enum(uint32 * num_cons, struct use_info ***use);
+void cli_use_wait_keyboard(void);
/*The following definitions come from rpc_client/cli_wkssvc.c */
-BOOL do_wks_query_info(struct cli_state *cli,
- char *server_name, uint32 switch_value,
+BOOL wks_query_info( char *srv_name, uint32 switch_value,
WKS_INFO_100 *wks100);
+/*The following definitions come from rpc_client/msrpc_lsarpc.c */
+
+uint32 lookup_lsa_names(const char *srv_name,
+ uint32 num_names, char **names,
+ uint32 * num_sids, DOM_SID ** sids, uint32 ** types);
+uint32 lookup_lsa_name(const char *domain,
+ char *name, DOM_SID * sid, uint32 * type);
+uint32 lookup_lsa_sid(const char *domain,
+ DOM_SID * sid, char *name, uint32 * type);
+BOOL msrpc_lsa_create_secret(const char *srv_name, const char *secret_name,
+ uint32 access_rights);
+void secret_store_data(STRING2 * secret, const char* data, int len);
+void secret_store_data2(STRING2 * secret, const char* data, int len);
+BOOL msrpc_lsa_set_secret(const char *srv_name,
+ const char *secret_name, const char *data, int len);
+BOOL msrpc_lsa_query_secret(const char *srv_name,
+ const char *secret_name,
+ STRING2 * secret, NTTIME * last_update);
+BOOL secret_get_data(const STRING2 *secret, uchar *data, uint32 *len);
+BOOL msrpc_lsa_query_trust_passwd(const char *srv_name,
+ const char *secret_name,
+ uchar trust_passwd[16],
+ NTTIME * last_update);
+
+/*The following definitions come from rpc_client/msrpc_netlogon.c */
+
+BOOL modify_trust_password(const char *domain, const char *srv_name,
+ const uchar orig_trust_passwd_hash[16],
+ const uchar new_trust_passwd_hash[16],
+ uint16 sec_chan);
+uint32 check_domain_security(const char *orig_user, const char *domain,
+ const uchar * challenge,
+ const char *smb_apasswd, int smb_apasslen,
+ const char *smb_ntpasswd, int smb_ntpasslen,
+ NET_USER_INFO_3 * info3);
+
+/*The following definitions come from rpc_client/msrpc_samr.c */
+
+uint32 lookup_sam_domainname(const char *srv_name,
+ const char *domain, DOM_SID *sid);
+uint32 lookup_sam_names(const char *domain, const DOM_SID *sid,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids, uint32 **types);
+uint32 lookup_sam_name(const char *domain, DOM_SID *sid,
+ char *name, uint32 *rid, uint32 *type);
+uint32 lookup_sam_rid(const char *domain, DOM_SID *sid,
+ uint32 rid, char *name, uint32 *type);
+BOOL req_user_info( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid, uint16 info_level,
+ USER_INFO_FN(usr_inf));
+uint32 sam_query_usergroups( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid,
+ const char *user_name,
+ uint32 *num_groups,
+ DOM_GID **gid,
+ char ***name,
+ uint32 **type,
+ USER_MEM_FN(usr_mem));
+void msrpc_sam_user( const POLICY_HND *pol_dom, const POLICY_HND *pol_blt,
+ const char* domain,
+ const DOM_SID *sid1,
+ const DOM_SID *blt_sid1,
+ uint32 user_rid, uint16 info_level,
+ char *user_name,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn));
+BOOL msrpc_sam_query_user( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid,
+ char *user_name,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn));
+int msrpc_sam_enum_users( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn));
+BOOL sam_query_dominfo(const char* srv_name,
+ const DOM_SID *sid1,
+ uint32 switch_value, SAM_UNK_CTR *ctr);
+BOOL query_aliasinfo( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ ALIAS_INFO_FN(grp_inf));
+BOOL sam_query_aliasmem(const char *srv_name,
+ const POLICY_HND *pol_dom,
+ uint32 alias_rid,
+ uint32 *num_names,
+ DOM_SID ***sids,
+ char ***name,
+ uint32 **type);
+BOOL req_aliasmem_info(const char* srv_name,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ const char *alias_name,
+ ALIAS_MEM_FN(als_mem));
+BOOL sam_query_groupmem( const POLICY_HND *pol_dom,
+ uint32 group_rid,
+ uint32 *num_names,
+ uint32 **rid_mem,
+ char ***name,
+ uint32 **type);
+BOOL query_groupinfo( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ GROUP_INFO_FN(grp_inf));
+BOOL req_groupmem_info( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ const char *group_name,
+ GROUP_MEM_FN(grp_mem));
+uint32 msrpc_sam_get_first_domain( const char* srv_name,
+ char *dom_name,
+ DOM_SID *dom_sid);
+uint32 msrpc_sam_enum_domains( const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ DOMAIN_FN(dom_fn),
+ DOMAIN_INFO_FN(dom_inf_fn));
+uint32 msrpc_sam_enum_groups( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ GROUP_FN(grp_fn),
+ GROUP_INFO_FN(grp_inf_fn),
+ GROUP_MEM_FN(grp_mem_fn));
+uint32 msrpc_sam_enum_aliases( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ ALIAS_FN(als_fn),
+ ALIAS_INFO_FN(als_inf_fn),
+ ALIAS_MEM_FN(als_mem_fn));
+BOOL create_samr_domain_user( POLICY_HND *pol_dom,
+ char *acct_name, uint16 acb_info,
+ const char* password, int plen,
+ uint32 *rid);
+BOOL create_samr_domain_alias( POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid);
+BOOL create_samr_domain_group( POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid);
+BOOL get_samr_query_usergroups( const POLICY_HND *pol_open_domain,
+ uint32 user_rid,
+ uint32 *num_groups, DOM_GID **gid);
+BOOL delete_samr_dom_group( POLICY_HND *pol_open_domain,
+ uint32 group_rid);
+BOOL get_samr_query_groupmem(
+ const POLICY_HND *pol_open_domain,
+ uint32 group_rid, uint32 *num_mem,
+ uint32 **rid, uint32 **attr);
+BOOL delete_samr_dom_alias(
+ POLICY_HND *pol_open_domain,
+ uint32 alias_rid);
+BOOL get_samr_query_aliasmem(
+ const POLICY_HND *pol_open_domain,
+ uint32 alias_rid, uint32 *num_mem, DOM_SID2 *sid);
+BOOL set_samr_set_userinfo2(
+ POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, void *usr);
+BOOL set_samr_set_userinfo( const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, void *usr);
+BOOL get_samr_query_userinfo( const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, SAM_USERINFO_CTR *ctr);
+BOOL get_samr_query_groupinfo(
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 group_rid, GROUP_INFO_CTR *ctr);
+BOOL get_samr_query_aliasinfo(
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 alias_rid, ALIAS_INFO_CTR *ctr);
+BOOL msrpc_sam_create_dom_user(const char* srv_name, DOM_SID *sid1,
+ char *acct_name, uint16 acb_info,
+ const char *password, int plen,
+ uint32 *rid);
+BOOL msrpc_sam_query_dispinfo(const char* srv_name, const char* domain,
+ DOM_SID *sid1,
+ uint16 switch_value,
+ uint32 *num_entries, SAM_DISPINFO_CTR *ctr,
+ DISP_FN(disp_fn));
+BOOL msrpc_sam_ntchange_pwd(const char* srv_name,
+ const char* domain,
+ const char *ntuser,
+ const uchar lm_oldhash[16],
+ const uchar nt_oldhash[16],
+ const char* new_passwd);
+BOOL msrpc_sam_ntpasswd_set(const char* srv_name, const char *user,
+ struct ntuser_creds *samr_creds,
+ const uchar lm_newpass[516],
+ const uchar lm_hshhash[16],
+ const uchar nt_newpass[516],
+ const uchar nt_hshhash[16]);
+BOOL msrpc_sam_query_userinfo(const char* srv_name, const DOM_SID *sid,
+ const char *user_name, uint16 info_level,
+ SAM_USERINFO_CTR *ctr);
+
+/*The following definitions come from rpc_client/ncacn_np_use.c */
+
+BOOL ncacn_np_establish_connection(struct ncacn_np *cli,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ const char *pipe_name, BOOL redir,
+ BOOL reuse);
+void init_ncacn_np_use(void);
+void free_ncacn_np_use(void);
+struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
+ const vuser_key * key);
+struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
+ const vuser_key * key,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ BOOL redir,
+ BOOL reuse, BOOL *is_new_connection);
+BOOL ncacn_np_use_del(const char *pipe_name,
+ const vuser_key * key,
+ BOOL force_close, BOOL *connection_closed);
+void ncacn_np_use_enum(uint32 * num_cons, struct use_info ***use);
+
+/*The following definitions come from rpc_client/ncalrpc_l_use.c */
+
+void init_ncalrpc_use(void);
+void free_ncalrpc_use(void);
+struct msrpc_local *ncalrpc_l_use_add(const char *pipe_name,
+ const vuser_key * key,
+ BOOL redir, BOOL reuse, BOOL *is_new);
+BOOL ncalrpc_l_use_del(const char *pipe_name,
+ const vuser_key * key,
+ BOOL force_close, BOOL *connection_closed);
+void ncalrpc_l_use_enum(uint32 * num_cons, struct use_info ***use);
+void ncalrpc_use_wait_keyboard(void);
+
/*The following definitions come from rpc_parse/parse_creds.c */
BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name,
@@ -1716,16 +2819,11 @@ BOOL make_creds_unix_sec(CREDS_UNIX_SEC *r_u,
uint32 uid, uint32 gid, uint32 num_grps, gid_t *grps);
BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth);
void creds_free_unix_sec(CREDS_UNIX_SEC *r_u);
-BOOL make_creds_nt_sec(CREDS_NT_SEC *r_u,
- DOM_SID *sid, uint32 num_grps, uint32 *grps);
-BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth);
-void creds_free_nt_sec(CREDS_NT_SEC *r_u);
BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth);
BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth);
void creds_free_nt(CREDS_NT *r_u);
BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth);
void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from);
-void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from);
void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from);
void copy_nt_creds(struct ntuser_creds *to,
const struct ntuser_creds *from);
@@ -1736,164 +2834,193 @@ BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth);
BOOL create_ntuser_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
- uint32 pid,
+ const vuser_key *key,
const struct ntuser_creds *ntu,
BOOL reuse);
BOOL create_user_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
- uint32 pid,
+ const vuser_key *key,
const struct user_creds *usr);
-/*The following definitions come from rpc_parse/parse_lsa.c */
-
-void init_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
- uint32 sid_name_use, char *name, uint32 idx);
-void init_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff,
- uint32 unknown);
-void init_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos);
-void init_q_open_pol(LSA_Q_OPEN_POL *r_q, uint16 system_name,
- uint32 attributes,
- uint32 desired_access,
- LSA_SEC_QOS *qos);
-BOOL lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth);
-BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth);
-void init_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, char *server_name,
- uint32 attributes,
- uint32 desired_access,
- LSA_SEC_QOS *qos);
-BOOL lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, int depth);
-BOOL lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 *r_p, prs_struct *ps, int depth);
-void init_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class);
-BOOL lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth);
-BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth);
-void init_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e,
- uint32 enum_context, char *domain_name, DOM_SID *domain_sid,
- uint32 status);
-BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth);
-BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth);
-void init_lsa_sid_enum(LSA_SID_ENUM *sen, int num_entries, DOM_SID **sids);
-void init_q_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, POLICY_HND *hnd,
- int num_sids, DOM_SID **sids,
- uint16 level);
-BOOL lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, int depth);
-BOOL lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, int depth);
-void init_q_lookup_names(LSA_Q_LOOKUP_NAMES *q_l, POLICY_HND *hnd,
- int num_names, char **names);
-BOOL lsa_io_q_lookup_names(char *desc, LSA_Q_LOOKUP_NAMES *q_r, prs_struct *ps, int depth);
-BOOL lsa_io_r_lookup_names(char *desc, LSA_R_LOOKUP_NAMES *r_r, prs_struct *ps, int depth);
-void init_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd);
-BOOL lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth);
-BOOL lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth);
-
/*The following definitions come from rpc_parse/parse_misc.c */
-BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth);
+BOOL smb_io_bigint(char *desc, BIGINT *bigint, prs_struct *ps, int depth);
+BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth);
BOOL smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth);
uint32 get_enum_hnd(ENUM_HND *enh);
-void init_enum_hnd(ENUM_HND *enh, uint32 hnd);
-BOOL smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth);
-BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth);
-void init_dom_sid(DOM_SID *sid, char *str_sid);
-void init_dom_sid2(DOM_SID2 *sid2, DOM_SID *sid);
-BOOL smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth);
-void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer);
+BOOL make_enum_hnd(ENUM_HND *enh, uint32 hnd);
+BOOL smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth);
+BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth);
+BOOL make_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid);
+BOOL smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth);
+BOOL make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer);
BOOL smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth);
-void init_uni_hdr(UNIHDR *hdr, int len);
-BOOL smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth);
-void init_buf_hdr(BUFHDR *hdr, int max_len, int len);
-BOOL smb_io_hdrbuf_pre(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset);
-BOOL smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
+BOOL make_strhdr2(STRHDR2 *hdr, uint32 max_len, uint32 len, uint32 buffer);
+BOOL smb_io_strhdr2(char *desc, STRHDR2 *hdr, prs_struct *ps, int depth);
+BOOL make_uni_hdr(UNIHDR *hdr, int len);
+BOOL make_unihdr_from_unistr2(UNIHDR *hdr, const UNISTR2 *str);
+BOOL smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth);
+BOOL make_buf_hdr(BUFHDR *hdr, int max_len, int len);
+BOOL smb_io_hdrbuf_pre(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset);
+BOOL smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
uint32 ptr_hdrbuf, uint32 max_len, uint32 len);
-BOOL smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth);
-void init_uni_hdr2(UNIHDR2 *hdr, int len);
-BOOL smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth);
-void init_unistr(UNISTR *str, char *buf);
-BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth);
-void init_buffer3_uint32(BUFFER3 *str, uint32 val);
-void init_buffer3_str(BUFFER3 *str, char *buf, int len);
-void init_buffer3_hex(BUFFER3 *str, char *buf);
-void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len);
-BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth);
+BOOL smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth);
+BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer);
+BOOL smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth);
+BOOL make_uni_hdr2(UNIHDR2 *hdr, int len);
+BOOL make_unihdr2_from_unistr2(UNIHDR2 *hdr, const UNISTR2 *str);
+BOOL smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth);
+BOOL make_unistr(UNISTR *str, char *buf);
+BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth);
+BOOL make_buffer3_uint32(BUFFER3 *str, uint32 val);
+BOOL make_buffer3_str(BUFFER3 *str, const char *buf, int len);
+BOOL make_buffer3_hex(BUFFER3 *str, char *buf);
+BOOL make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len);
+BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth);
+BOOL make_buffer4_str(BUFFER4 *str, const char *buf, int len);
+BOOL smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth);
+BOOL init_buffer5(BUFFER5 **str);
+BOOL clear_buffer5(BUFFER5 **str);
+BOOL make_buffer5(BUFFER5 *str, char *buf, int len);
BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth);
-void init_buffer2(BUFFER2 *str, uint8 *buf, int len);
-BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth);
-void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf);
-void copy_unistr2(UNISTR2 *str, UNISTR2 *from);
-void init_string2(STRING2 *str, char *buf, int len);
-BOOL smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
-void init_unistr2(UNISTR2 *str, char *buf, int len);
-BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
-void init_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx);
-BOOL smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth);
-void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type);
-BOOL smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth);
-void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid);
-void init_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
- uint16 sec_chan, char *comp_name);
-BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth);
-BOOL smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth);
+BOOL make_buffer2_multi(BUFFER2 *str, char *const* const buf, uint32 num);
+BOOL make_buffer2(BUFFER2 *str, const char *buf, int len);
+BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf);
+BOOL make_string2(STRING2 *str, const char *buf, int len);
+BOOL make_buf_string2(STRING2 *str, uint32 *ptr, const char *buf);
+BOOL smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_unistr2(UNISTR2 *str, const char *buf, int len);
+BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx);
+BOOL smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth);
+BOOL make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type);
+BOOL smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth);
+BOOL make_log_info(DOM_LOG_INFO *log,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name);
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth);
+BOOL smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth);
BOOL smb_io_cred(char *desc, DOM_CRED *cred, prs_struct *ps, int depth);
-void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
- char *logon_srv, char *comp_name,
+BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
+ const char *logon_srv, const char *comp_name,
DOM_CRED *clnt_cred);
-BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
-void init_clnt_info(DOM_CLNT_INFO *clnt,
- char *logon_srv, char *acct_name,
- uint16 sec_chan, char *comp_name,
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
+BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
DOM_CRED *cred);
BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth);
-void init_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high);
-BOOL smb_io_logon_id(char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth);
-void init_owf_info(OWF_INFO *hash, uint8 data[16]);
+BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16]);
BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
BOOL smb_io_gid(char *desc, DOM_GID *gid, prs_struct *ps, int depth);
-BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
-BOOL smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
-BOOL smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
-BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth);
+BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
+BOOL smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
+BOOL smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
+BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_net.c */
-BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth);
-void init_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
- uint32 flags, uint32 pdc_status, uint32 logon_attempts,
- uint32 tc_status, char *trusted_domain_name);
-BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth);
-void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
- uint32 num_doms, char *dom_name);
-BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth);
-BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth);
-void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
- char *logon_srv, char *logon_clnt,
+BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l,
+ const char* srv_name,
+ uint32 function_code,
+ uint32 query_level,
+ uint32 switch_value);
+BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth);
+BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l,
+ uint32 switch_value,
+ NETLOGON_INFO *logon_info,
+ uint32 status);
+BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth);
+BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth);
+BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth);
+BOOL make_q_req_chal(NET_Q_REQ_CHAL *q_c,
+ const char *logon_srv, const char *logon_clnt,
DOM_CHAL *clnt_chal);
BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth);
-BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth);
-void init_q_auth_2(NET_Q_AUTH_2 *q_a,
- char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth);
+BOOL make_q_auth(NET_Q_AUTH *q_a,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CHAL *clnt_chal);
+BOOL net_io_q_auth(char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth(char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth);
+BOOL make_q_auth_2(NET_Q_AUTH_2 *q_a,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
DOM_CHAL *clnt_chal, uint32 clnt_flgs);
-BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth);
-BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth);
-void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name,
- uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16]);
-BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth);
-BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth);
-void init_id_info1(NET_ID_INFO_1 *id, char *domain_name,
- uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
- char *user_name, char *wksta_name,
- char sess_key[16],
- unsigned char lm_cypher[16], unsigned char nt_cypher[16]);
-void init_id_info2(NET_ID_INFO_2 *id, char *domain_name,
- uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
- char *user_name, char *wksta_name,
- unsigned char lm_challenge[8],
- unsigned char lm_chal_resp[24],
- unsigned char nt_chal_resp[24]);
-void init_sam_info(DOM_SAM_INFO *sam,
- char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth);
+BOOL make_q_srv_pwset(NET_Q_SRV_PWSET *q_s,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CRED *cred, char nt_cypher[16]);
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth);
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth);
+BOOL make_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low,
+ uint32 log_id_high,
+ const char *user_name,
+ const char *wksta_name,
+ const char sess_key[16],
+ const uchar lm_cypher[16],
+ const uchar nt_cypher[16]);
+BOOL make_id_info4(NET_ID_INFO_4 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const char *general);
+BOOL make_id_info2(NET_ID_INFO_2 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const uchar lm_challenge[8],
+ const uchar *lm_chal_resp,
+ int lm_chal_len,
+ const uchar *nt_chal_resp,
+ int nt_chal_len);
+BOOL make_sam_info(DOM_SAM_INFO *sam,
+ const char *logon_srv, const char *comp_name,
+ DOM_CRED *clnt_cred,
DOM_CRED *rtn_cred, uint16 logon_level,
NET_ID_INFO_CTR *ctr);
-void init_net_user_info3(NET_USER_INFO_3 *usr,
+BOOL make_net_user_info3W(NET_USER_INFO_3 *usr,
+
+ const NTTIME *logon_time,
+ const NTTIME *logoff_time,
+ const NTTIME *kickoff_time,
+ const NTTIME *pass_last_set_time,
+ const NTTIME *pass_can_change_time,
+ const NTTIME *pass_must_change_time,
+
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+
+ uint16 logon_count,
+ uint16 bad_pw_count,
+
+ uint32 user_id,
+ uint32 group_id,
+ uint32 num_groups,
+ const DOM_GID *gids,
+ uint32 user_flgs,
+
+ const char sess_key[16],
+
+ const UNISTR2 *logon_srv,
+ const UNISTR2 *logon_dom,
+
+ const char *padding,
+
+ const DOM_SID *dom_sid,
+ const char *other_sids);
+BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
NTTIME *logon_time,
NTTIME *logoff_time,
@@ -1923,638 +3050,237 @@ void init_net_user_info3(NET_USER_INFO_3 *usr,
char *logon_srv,
char *logon_dom,
+ char *padding,
+
DOM_SID *dom_sid,
char *other_sids);
-BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
-BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
+BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth);
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
+BOOL make_r_sam_logon(NET_R_SAM_LOGON *r_s,
+ const DOM_CRED *srv_creds,
+ uint16 switch_value,
+ NET_USER_INFO_3 *user_info,
+ uint32 status);
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth);
-BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth);
+BOOL make_r_sam_logoff(NET_R_SAM_LOGOFF *r_s,
+ const DOM_CRED *srv_cred,
+ uint32 status);
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth);
+BOOL make_q_sam_sync(NET_Q_SAM_SYNC *q_s,
+ const char *srv_name,
+ const char *cli_name,
+ DOM_CRED *cli_creds, uint32 database_id);
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC *q_s, prs_struct *ps, int depth);
+BOOL make_sam_delta_hdr(SAM_DELTA_HDR *delta, uint16 type, uint32 rid);
+BOOL make_sam_account_info(SAM_ACCOUNT_INFO *info,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ uint32 user_rid, uint32 group_rid,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *desc,
+ uint32 acb_info,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial);
+BOOL make_r_sam_sync(NET_R_SAM_SYNC *r_s,
+ const DOM_CRED *srv_cred,
+ uint32 sync_context,
+ uint32 num_deltas,
+ uint32 num_deltas2,
+ SAM_DELTA_HDR *hdr_deltas,
+ SAM_DELTA_CTR *deltas,
+ uint32 status);
+BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
+ NET_R_SAM_SYNC *r_s, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_netsec.c */
+
+BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH *rai);
+BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
+ fstring domain,
+ fstring myname);
+BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG *neg, prs_struct *ps, int depth);
+BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP *rsp, uint32 flags);
+BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP *rsp, prs_struct *ps, int depth);
+BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk);
+BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk,
+ const uchar sig[8],
+ const uchar data1[8],
+ const uchar data3[8],
+ const uchar data8[8]);
+BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK *chk, prs_struct *ps, int depth);
+BOOL netsec_encode(struct netsec_auth_struct *a,
+ RPC_AUTH_NETSEC_CHK *verf,
+ char *data, size_t data_len);
+BOOL netsec_decode(struct netsec_auth_struct *a,
+ RPC_AUTH_NETSEC_CHK *verf,
+ char *data, size_t data_len);
+
+/*The following definitions come from rpc_parse/parse_ntlmssp.c */
+
+BOOL rpc_hdr_ntlmssp_auth_chk(RPC_HDR_AUTH *rai);
+BOOL make_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
+ uint32 neg_flgs,
+ fstring myname, fstring domain);
+BOOL smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth);
+BOOL make_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
+ uint32 neg_flags,
+ uint8 challenge[8]);
+BOOL smb_io_rpc_auth_ntlmssp_chal(char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth);
+BOOL make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
+ uchar lm_resp[24],
+ uchar *nt_resp, size_t nt_len,
+ char *domain, char *user, char *wks,
+ uint32 neg_flags);
+BOOL smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth);
+BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_num);
+BOOL make_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
+ uint32 ver, uint32 crc32, uint32 seq_num);
+BOOL smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth);
/*The following definitions come from rpc_parse/parse_prs.c */
-void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name);
-BOOL prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io);
-BOOL prs_read(prs_struct *ps, int fd, size_t len, int timeout);
-void prs_mem_free(prs_struct *ps);
-void prs_give_memory(prs_struct *ps, char *buf, uint32 size, BOOL is_dynamic);
-char *prs_take_memory(prs_struct *ps, uint32 *psize);
-BOOL prs_grow(prs_struct *ps, uint32 extra_space);
-BOOL prs_force_grow(prs_struct *ps, uint32 extra_space);
-char *prs_data_p(prs_struct *ps);
-uint32 prs_data_size(prs_struct *ps);
-uint32 prs_offset(prs_struct *ps);
-BOOL prs_set_offset(prs_struct *ps, uint32 offset);
-BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src);
-BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uint32 len);
-BOOL prs_append_data(prs_struct *dst, char *src, uint32 len);
-void prs_set_bigendian_data(prs_struct *ps);
-BOOL prs_align(prs_struct *ps);
-char *prs_mem_get(prs_struct *ps, uint32 extra_size);
-BOOL prs_switch_type(prs_struct *ps, BOOL io);
-void prs_force_dynamic(prs_struct *ps);
-BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8);
-BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16);
-BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32);
-BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
-BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
-BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
-BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str);
-BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str);
-BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str);
-BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth);
-BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str);
-BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, int len, int max_buf_size);
-BOOL prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
-BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
+void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name);
+void prs_debug_out(const prs_struct *ps, char *msg, int level);
+void prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io);
+void prs_set_packtype(prs_struct *ps, const uint8 *pack_type);
+void prs_create(prs_struct *ps, char *data, uint32 size, uint8 align, BOOL io);
+BOOL prs_copy(prs_struct *ps, const prs_struct *from);
+BOOL prs_alloc_data(prs_struct *buf, int size);
+BOOL prs_buf_copy(char *copy_into, const prs_struct *buf,
+ uint32 offset, uint32 len);
+void prs_struct_free(prs_struct **buf);
+void prs_free_data(prs_struct *buf);
+BOOL prs_realloc_data(prs_struct *buf, size_t new_size);
+BOOL prs_grow_data(prs_struct *buf, BOOL io, int new_size, BOOL force_grow);
+uint32 prs_buf_len(const prs_struct *buf);
+char *prs_data(const prs_struct *buf, uint32 offset);
+void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next);
+void prs_align(prs_struct *ps);
+BOOL prs_grow(prs_struct *ps, uint32 new_size);
+BOOL prs_append_data(prs_struct *ps, const char *data, int len);
+BOOL prs_add_data(prs_struct *ps, const char *data, int len);
+BOOL _prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8);
+BOOL _prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16);
+BOOL _prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16]);
+BOOL _prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32);
+BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
+BOOL _prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
+BOOL _prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
+BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str);
+BOOL _prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str);
+BOOL _prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str);
+BOOL _prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth);
+BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str);
+BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size);
+BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
+BOOL _prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
uint32 ptr_uint16, uint32 start_offset);
-BOOL prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
-BOOL prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
+BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
+BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
uint32 ptr_uint32, uint32 data_size);
-
-/*The following definitions come from rpc_parse/parse_reg.c */
-
-void init_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
- uint16 unknown_0, uint32 level);
-BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth);
-void init_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol);
-BOOL reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth);
-void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
- char *name, char *class, SEC_ACCESS *sam_access,
- SEC_DESC_BUF *sec_buf);
-BOOL reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_create_key(char *desc, REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth);
-void init_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
- char *name);
-BOOL reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth);
-void init_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
- char *name);
-BOOL reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth);
-void init_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
- uint32 max_class_len);
-BOOL reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth);
-void init_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd);
-BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth);
-void init_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
- uint16 unknown_0, uint32 level);
-BOOL reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth);
-void init_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd);
-BOOL reg_io_q_close(char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int depth);
-BOOL reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth);
-void init_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol, SEC_DESC_BUF *sec_desc_buf);
-BOOL reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
-void init_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol,
- uint32 sec_buf_size, SEC_DESC_BUF *psdb);
-BOOL reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
-BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
-void init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char *product_type,
- time_t unix_time, uint8 major, uint8 minor);
-BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth);
-void init_reg_r_info(REG_R_INFO *r_r,
- uint32 level, char *os_type,
- uint32 unknown_0, uint32 unknown_1,
- uint32 status);
-BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth);
-void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
- uint32 val_idx, uint32 max_val_len,
- uint32 max_buf_len);
-BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth);
-void init_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
- char *val_name, uint32 type,
- BUFFER3 *val);
-BOOL reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth);
-void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx);
-BOOL reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth);
-BOOL reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth);
-void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
- char *key_name, uint32 unk);
-BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth);
-void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
- POLICY_HND *pol, uint32 status);
-BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth);
+int prs_tdb_delete(TDB_CONTEXT *tdb, prs_struct *pk);
+int prs_tdb_store(TDB_CONTEXT *tdb, int flgs, prs_struct *pk, prs_struct *pd);
+void prs_tdb_fetch(TDB_CONTEXT *tdb, prs_struct *pk, prs_struct *pd);
/*The following definitions come from rpc_parse/parse_rpc.c */
-void init_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
+BOOL make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
uint32 call_id, int data_len, int auth_len);
BOOL smb_io_rpc_hdr(char *desc, RPC_HDR *rpc, prs_struct *ps, int depth);
-void init_rpc_hdr_rb(RPC_HDR_RB *rpc,
+BOOL is_complete_pdu(prs_struct *ps);
+BOOL smb_io_rpc_hdr_nack(char *desc, RPC_HDR_NACK *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_fault(char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_rb(RPC_HDR_RB *rpc,
uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
RPC_IFACE *abstract, RPC_IFACE *transfer);
-BOOL smb_io_rpc_hdr_rb(char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth);
-void init_rpc_hdr_ba(RPC_HDR_BA *rpc,
+BOOL smb_io_rpc_hdr_rb(char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_ba(RPC_HDR_BA *rpc,
uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
- char *pipe_addr,
+ const char *pipe_addr,
uint8 num_results, uint16 result, uint16 reason,
RPC_IFACE *transfer);
-BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth);
-void init_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum);
-BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth);
-BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth);
-void init_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
+BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 vuid,
+ uint16 opnum);
+BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
uint16 max_tsize, uint16 max_rsize,
uint8 auth_type, uint8 auth_level,
uint8 stub_type_len);
BOOL smb_io_rpc_hdr_autha(char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth);
-BOOL rpc_hdr_auth_chk(RPC_HDR_AUTH *rai);
-void init_rpc_hdr_auth(RPC_HDR_AUTH *rai,
+BOOL make_rpc_hdr_auth(RPC_HDR_AUTH *rai,
uint8 auth_type, uint8 auth_level,
uint8 stub_type_len,
uint32 ptr);
BOOL smb_io_rpc_hdr_auth(char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, int depth);
-BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
- char *signature, uint32 msg_type);
-void init_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
+BOOL make_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
char *signature, uint32 msg_type);
BOOL smb_io_rpc_auth_verifier(char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth);
-void init_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
- uint32 neg_flgs,
- fstring myname, fstring domain);
-BOOL smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth);
-void init_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
- uint32 neg_flags,
- uint8 challenge[8]);
-BOOL smb_io_rpc_auth_ntlmssp_chal(char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth);
-void init_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
- uchar lm_resp[24], uchar nt_resp[24],
- char *domain, char *user, char *wks,
- uint32 neg_flags);
-BOOL smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth);
-BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_num);
-void init_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
- uint32 ver, uint32 crc32, uint32 seq_num);
-BOOL smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth);
-
-/*The following definitions come from rpc_parse/parse_samr.c */
-
-void init_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd);
-BOOL samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND *q_u, prs_struct *ps, int depth);
-BOOL samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND *r_u, prs_struct *ps, int depth);
-void init_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
- POLICY_HND *connect_pol, uint32 rid,
- DOM_SID *sid);
-BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth);
-BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth);
-void init_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol);
-BOOL samr_io_q_unknown_2c(char *desc, SAMR_Q_UNKNOWN_2C *q_u, prs_struct *ps, int depth);
-void init_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status);
-BOOL samr_io_r_unknown_2c(char *desc, SAMR_R_UNKNOWN_2C *r_u, prs_struct *ps, int depth);
-void init_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
- POLICY_HND *user_pol, uint16 switch_value);
-BOOL samr_io_q_unknown_3(char *desc, SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int depth);
-void init_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
- POLICY_HND *domain_pol, uint16 switch_value);
-BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *ps, int depth);
-void init_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server);
-BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth);
-void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u,
- uint16 switch_value, SAM_UNK_CTR *ctr,
- uint32 status);
-BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO *r_u, prs_struct *ps, int depth);
-void init_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid);
-void init_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
- uint16 unknown_2, uint16 unknown_3,
- uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
- int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS],
- uint32 status);
-BOOL samr_io_r_unknown_3(char *desc, SAMR_R_UNKNOWN_3 *r_u, prs_struct *ps, int depth);
-void init_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
- uint16 req_num_entries, uint16 unk_0,
- uint16 acb_mask, uint16 unk_1, uint32 size);
-BOOL samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth);
-void init_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
- uint16 total_num_entries, uint16 unk_0,
- uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status);
-BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth);
-void init_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol, uint32 size);
-BOOL samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth);
-void init_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
- uint32 num_sam_entries, SAM_USER_INFO_21 grps[MAX_SAM_ENTRIES],
- uint32 status);
-BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth);
-void init_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
- uint16 switch_level, uint32 start_idx, uint32 size);
-BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth);
-void init_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask,
- uint32 start_idx, uint32 num_sam_entries,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
-void init_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask,
- uint32 start_idx, uint32 num_sam_entries,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
-void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
- uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status);
-BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth);
-void init_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
- uint16 switch_level, uint32 start_idx, uint32 size);
-BOOL samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth);
-void init_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
- uint32 start_idx, uint32 num_sam_entries,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES],
- uint32 status);
-BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth);
-void init_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
- POLICY_HND *pol,
- uint16 switch_level);
-BOOL samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps, int depth);
-void init_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u,
- uint16 switch_value, char *acct_desc,
- uint32 status);
-BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth);
-BOOL samr_io_q_lookup_ids(char *desc, SAMR_Q_LOOKUP_IDS *q_u, prs_struct *ps, int depth);
-void init_samr_r_lookup_ids(SAMR_R_LOOKUP_IDS *r_u,
- uint32 num_rids, uint32 *rid, uint32 status);
-BOOL samr_io_r_lookup_ids(char *desc, SAMR_R_LOOKUP_IDS *r_u, prs_struct *ps, int depth);
-BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth);
-void init_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
- uint32 num_rids, uint32 *rid, uint8 *type, uint32 status);
-BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth);
-BOOL samr_io_q_unknown_12(char *desc, SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, int depth);
-void init_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
- uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
- uint32 status);
-BOOL samr_io_r_unknown_12(char *desc, SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, int depth);
-void init_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
- POLICY_HND *pol,
- uint32 unk_0, uint32 rid);
-BOOL samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth);
-BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth);
-void init_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
- POLICY_HND *hnd);
-BOOL samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth);
-void init_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
- uint32 num_gids, DOM_GID *gid, uint32 status);
-BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth);
-void init_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
- POLICY_HND *hnd, uint16 switch_value);
-BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth);
-void init_sam_user_info10(SAM_USER_INFO_10 *usr,
- uint32 acb_info);
-BOOL sam_io_user_info10(char *desc, SAM_USER_INFO_10 *usr, prs_struct *ps, int depth);
-void init_sam_user_info11(SAM_USER_INFO_11 *usr,
- NTTIME *expiry,
- char *mach_acct,
- uint32 rid_user,
- uint32 rid_group,
- uint16 acct_ctrl);
-BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int depth);
-void init_sam_user_info21(SAM_USER_INFO_21 *usr,
- NTTIME *logon_time,
- NTTIME *logoff_time,
- NTTIME *kickoff_time,
- NTTIME *pass_last_set_time,
- NTTIME *pass_can_change_time,
- NTTIME *pass_must_change_time,
-
- char *user_name,
- char *full_name,
- char *home_dir,
- char *dir_drive,
- char *logon_script,
- char *profile_path,
- char *description,
- char *workstations,
- char *unknown_str,
- char *munged_dial,
-
- uint32 user_rid,
- uint32 group_rid,
- uint16 acb_info,
-
- uint32 unknown_3,
- uint16 logon_divs,
- LOGON_HRS *hrs,
- uint32 unknown_5,
- uint32 unknown_6);
-void init_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
- uint16 switch_value, void *info, uint32 status);
-BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth);
-BOOL samr_io_q_unknown_32(char *desc, SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps, int depth);
-BOOL samr_io_r_unknown_32(char *desc, SAMR_R_UNKNOWN_32 *r_u, prs_struct *ps, int depth);
-void init_samr_q_connect(SAMR_Q_CONNECT *q_u,
- char *srv_name, uint32 unknown_0);
-BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth);
-BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT *r_u, prs_struct *ps, int depth);
-void init_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u);
-BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth);
-BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth);
-void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
- uint32 unknown_0, uint32 rid);
-BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth);
-BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth);
-void init_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
- POLICY_HND *pol, uint32 rid,
- uint32 num_gids, uint32 *gid);
-void init_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
- POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
-void init_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
- POLICY_HND *hnd, uint16 unk_1, uint16 unk_2);
-void init_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name);
-BOOL samr_io_q_unknown_38(char *desc, SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth);
-void init_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u);
-BOOL samr_io_r_unknown_38(char *desc, SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth);
-void init_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512]);
-BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth);
-void init_enc_hash(SAMR_ENC_HASH *hsh, uchar hash[16]);
-BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth);
-void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
- char *dest_host, char *user_name,
- char nt_newpass[516], uchar nt_oldhash[16],
- char lm_newpass[516], uchar lm_oldhash[16]);
-BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth);
-void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status);
-BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct *ps, int depth);
+BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
+ char *signature, uint32 msg_type);
/*The following definitions come from rpc_parse/parse_sec.c */
-void init_sec_access(SEC_ACCESS *t, uint32 mask);
+BOOL make_sec_access(SEC_ACCESS *t, uint32 mask);
BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth);
-void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag);
-BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth);
-SEC_ACL *make_sec_acl(uint16 revision, int num_aces, SEC_ACE *ace_list);
-SEC_ACL *dup_sec_acl( SEC_ACL *src);
-void free_sec_acl(SEC_ACL **ppsa);
-BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth);
-SEC_DESC *make_sec_desc(uint16 revision, uint16 type,
+BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag);
+BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth);
+BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace);
+void free_sec_acl(SEC_ACL *t);
+BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth);
+int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
DOM_SID *owner_sid, DOM_SID *grp_sid,
- SEC_ACL *sacl, SEC_ACL *dacl, size_t *sec_desc_size);
-SEC_DESC *dup_sec_desc( SEC_DESC *src);
-void free_sec_desc(SEC_DESC **ppsd);
-SEC_DESC *make_standard_sec_desc(DOM_SID *owner_sid, DOM_SID *grp_sid,
- SEC_ACL *dacl, size_t *sec_desc_size);
-BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth);
-SEC_DESC_BUF *make_sec_desc_buf(int len, SEC_DESC *sec_desc);
-SEC_DESC_BUF *dup_sec_desc_buf(SEC_DESC_BUF *src);
-void free_sec_desc_buf(SEC_DESC_BUF **ppsdb);
-BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth);
-
-/*The following definitions come from rpc_parse/parse_spoolss.c */
-
-BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
-BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
- prs_struct *ps, int depth);
-BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth);
-BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
- POLICY_HND *handle,
- char *valuename,
- uint32 size);
-BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth);
-BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd);
-BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth);
-BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth);
-BOOL new_smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth);
-BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth);
-BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) ;
-BOOL new_smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) ;
-BOOL new_smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth);
-BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth);
-BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth);
-BOOL new_smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth);
-void new_spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest);
-void new_spoolss_allocate_buffer(NEW_BUFFER **buffer);
-void new_spoolss_free_buffer(NEW_BUFFER *buffer);
-uint32 new_get_buffer_size(NEW_BUFFER *buffer);
-BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth);
-BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth);
-BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth);
-BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth);
-BOOL smb_io_printprocdatatype_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth);
-BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth);
-BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth);
-uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info);
-uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info);
-uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info);
-uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info);
-uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info);
-uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info);
-uint32 spoolss_size_job_info_1(JOB_INFO_1 *info);
-uint32 spoolss_size_job_info_2(JOB_INFO_2 *info);
-uint32 spoolss_size_form_1(FORM_1 *info);
-uint32 spoolss_size_port_info_1(PORT_INFO_1 *info);
-uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info);
-uint32 spoolss_size_port_info_2(PORT_INFO_2 *info);
-uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info);
-uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info);
-uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info);
-uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info);
-BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth);
-BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth);
-BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
- uint32 firstjob,
- uint32 numofjobs,
- uint32 level,
- uint32 buf_size);
-BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth);
-BOOL new_spoolss_io_r_enumprinterdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth);
-BOOL new_spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth);
-BOOL new_spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth);
-BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth);
-BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth);
-BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth);
-BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u,
- prs_struct *ps, int depth);
-BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar);
-BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth);
-BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth);
-BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
-BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
- NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc);
-BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
- NT_PRINTER_INFO_LEVEL_2 **asc);
-BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumprintprocdatatypes(char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth);
-BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
- uint32 type, const uint8 *data, uint32 len);
-BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth);
-BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth);
-void free_devmode(DEVICEMODE *devmode);
-void free_printer_info_2(PRINTER_INFO_2 *printer);
-void free_print2_array(uint32 num_entries, PRINTER_INFO_2 **entries);
-void free_print1_array(uint32 num_entries, PRINTER_INFO_1 **entries);
-void free_job1_array(uint32 num_entries, JOB_INFO_1 **entries);
-void free_job_info_2(JOB_INFO_2 *job);
-void free_job2_array(uint32 num_entries, JOB_INFO_2 **entries);
-
-/*The following definitions come from rpc_parse/parse_srv.c */
-
-void init_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark);
-void init_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark);
-void init_srv_share_info2_str(SH_INFO_2_STR *sh2,
- char *net_name, char *remark,
- char *path, char *passwd);
-void init_srv_share_info2(SH_INFO_2 *sh2,
- char *net_name, uint32 type, char *remark,
- uint32 perms, uint32 max_uses, uint32 num_uses,
- char *path, char *passwd);
-void free_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr);
-void free_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n);
-void free_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n);
-void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
- char *srv_name, uint32 info_level,
- uint32 preferred_len, ENUM_HND *hnd);
-BOOL srv_io_q_net_share_enum(char *desc, SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth);
-BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth);
-void free_srv_q_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n);
-void free_srv_r_net_share_get_info(SRV_R_NET_SHARE_GET_INFO *r_n);
-BOOL srv_io_q_net_share_get_info(char *desc, SRV_Q_NET_SHARE_GET_INFO *q_n, prs_struct *ps, int depth);
-BOOL srv_io_r_net_share_get_info(char *desc, SRV_R_NET_SHARE_GET_INFO *r_n, prs_struct *ps, int depth);
-void init_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name);
-void init_srv_sess_info0(SESS_INFO_0 *ss0, char *name);
-void init_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user);
-void init_srv_sess_info1(SESS_INFO_1 *ss1,
- char *name, char *user,
- uint32 num_opens, uint32 open_time, uint32 idle_time,
- uint32 user_flags);
-void init_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
- char *srv_name, char *qual_name,
- uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
- uint32 preferred_len,
- ENUM_HND *hnd);
-BOOL srv_io_q_net_sess_enum(char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth);
-BOOL srv_io_r_net_sess_enum(char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth);
-void init_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id);
-void init_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name);
-void init_srv_conn_info1(CONN_INFO_1 *ss1,
- uint32 id, uint32 type,
- uint32 num_opens, uint32 num_users, uint32 open_time,
- char *usr_name, char *net_name);
-void init_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
- char *srv_name, char *qual_name,
- uint32 conn_level, SRV_CONN_INFO_CTR *ctr,
- uint32 preferred_len,
- ENUM_HND *hnd);
-BOOL srv_io_q_net_conn_enum(char *desc, SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth);
-BOOL srv_io_r_net_conn_enum(char *desc, SRV_R_NET_CONN_ENUM *r_n, prs_struct *ps, int depth);
-void init_srv_file_info3_str(FILE_INFO_3_STR *fi3, char *user_name, char *path_name);
-void init_srv_file_info3(FILE_INFO_3 *fl3,
- uint32 id, uint32 perms, uint32 num_locks,
- char *path_name, char *user_name);
-void init_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
- char *srv_name, char *qual_name,
- uint32 file_level, SRV_FILE_INFO_CTR *ctr,
- uint32 preferred_len,
- ENUM_HND *hnd);
-BOOL srv_io_q_net_file_enum(char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth);
-BOOL srv_io_r_net_file_enum(char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth);
-void init_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id, char *name,
- uint32 ver_major, uint32 ver_minor,
- uint32 srv_type, char *comment);
-void init_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
- char *comment, uint32 ver_major, uint32 ver_minor,
- uint32 srv_type, uint32 users, uint32 disc, uint32 hidden,
- uint32 announce, uint32 ann_delta, uint32 licenses,
- char *usr_path);
-void init_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
- char *server_name, uint32 switch_value);
-BOOL srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth);
-void init_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
- uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status);
-BOOL srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth);
-BOOL srv_io_q_net_remote_tod(char *desc, SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth);
-void init_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
- uint32 hours, uint32 mins, uint32 secs, uint32 hunds,
- uint32 zone, uint32 tintervals, uint32 day,
- uint32 month, uint32 year, uint32 weekday);
-BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *ps, int depth);
-
-/*The following definitions come from rpc_parse/parse_wks.c */
-
-void init_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
- char *server, uint16 switch_value) ;
-BOOL wks_io_q_query_info(char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth);
-void init_wks_info_100(WKS_INFO_100 *inf,
- uint32 platform_id, uint32 ver_major, uint32 ver_minor,
- char *my_name, char *domain_name);
-void init_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
- uint32 switch_value, WKS_INFO_100 *wks100,
- int status) ;
-BOOL wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth);
-
-/*The following definitions come from rpc_server/srv_lsa.c */
-
-BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data);
-
-/*The following definitions come from rpc_server/srv_lsa_hnd.c */
-
-void init_lsa_policy_hnd(void);
-BOOL open_lsa_policy_hnd(POLICY_HND *hnd);
-int find_lsa_policy_by_hnd(POLICY_HND *hnd);
-BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid);
-BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status);
-BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid);
-BOOL get_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid);
-uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd);
-BOOL set_lsa_policy_reg_name(POLICY_HND *hnd, fstring name);
-BOOL close_lsa_policy_hnd(POLICY_HND *hnd);
+ SEC_ACL *sacl, SEC_ACL *dacl);
+void free_sec_desc(SEC_DESC *t);
+BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth);
+BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data);
+void free_sec_desc_buf(SEC_DESC_BUF *buf);
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_vuid.c */
+
+BOOL vuid_io_key(char *desc, vuser_key * r_u, prs_struct * ps, int depth);
+BOOL make_vuid_user_struct(user_struct * r_u,
+ uid_t uid, gid_t gid,
+ const char *name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest,
+ uint32 n_groups, const gid_t * groups,
+ const NET_USER_INFO_3 * usr);
+BOOL vuid_io_user_struct(char *desc, user_struct * r_u, prs_struct * ps,
+ int depth);
+void vuid_free_user_struct(user_struct * r_u);
+
+/*The following definitions come from rpc_server/srv_brs.c */
+
+BOOL api_brs_rpc(rpcsrv_struct *p);
+
+/*The following definitions come from rpc_server/srv_lookup.c */
+
+uint32 make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids);
+int get_domain_user_groups(DOMAIN_GRP_MEMBER **grp_members, uint32 group_rid);
+uint32 lookup_sid(DOM_SID *sid, char *name, uint32 *type);
+uint32 lookup_added_user_rids(char *nt_name,
+ uint32 *usr_rid, uint32 *grp_rid);
+uint32 lookup_name(const char *name, DOM_SID *sid, uint32 *type);
/*The following definitions come from rpc_server/srv_netlog.c */
-BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data);
+BOOL api_netlog_rpc(rpcsrv_struct *p);
/*The following definitions come from rpc_server/srv_pipe.c */
BOOL readwrite_pipe(pipes_struct *p, char *data, int len,
- char **rdata, int *rlen);
+ char **rdata, int *rlen,
+ BOOL *pipe_outstanding);
ssize_t write_pipe(pipes_struct *p, char *data, size_t n);
int read_pipe(pipes_struct *p, char *data, int n);
@@ -2563,292 +3289,858 @@ int read_pipe(pipes_struct *p, char *data, int n);
void set_pipe_handle_offset(int max_open_files);
void reset_chain_p(void);
void init_rpc_pipe_hnd(void);
-BOOL pipe_init_outgoing_data(output_data *out_data);
-pipes_struct *open_rpc_pipe_p(char *pipe_name,
- connection_struct *conn, uint16 vuid);
-ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n);
-int read_from_pipe(pipes_struct *p, char *data, int n);
-BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority);
-BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state);
-BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn);
+pipes_struct *open_rpc_pipe_p(char *pipe_name, const vuser_key * key,
+ rpcsrv_struct * l);
+BOOL wait_rpc_pipe_hnd_state(pipes_struct * p, uint16 priority);
+BOOL set_rpc_pipe_hnd_state(pipes_struct * p, uint16 device_state);
+BOOL close_rpc_pipe_hnd(pipes_struct * p);
pipes_struct *get_rpc_pipe_p(char *buf, int where);
+pipes_struct *get_rpc_vuser(const vuser_key * key);
pipes_struct *get_rpc_pipe(int pnum);
+/*The following definitions come from rpc_server/srv_pipe_netsec.c */
+
+
+/*The following definitions come from rpc_server/srv_pipe_noauth.c */
+
+
+/*The following definitions come from rpc_server/srv_pipe_ntlmssp.c */
+
+
/*The following definitions come from rpc_server/srv_pipe_srv.c */
-BOOL create_next_pdu(pipes_struct *p);
-BOOL rpc_command(pipes_struct *p, char *input_data, int data_len);
-BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
- prs_struct *rpc_in);
+void close_msrpc_command_processor(void);
+void add_msrpc_command_processor(char *pipe_name,
+ char *process_name,
+ BOOL (*fn) (rpcsrv_struct *));
+BOOL api_rpcTNP(rpcsrv_struct * l, const char *rpc_name,
+ const struct api_struct *api_rpc_cmds);
+BOOL rpc_local(rpcsrv_struct * l, char *data, int len, const char *name);
/*The following definitions come from rpc_server/srv_reg.c */
-BOOL api_reg_rpc(pipes_struct *p, prs_struct *data);
+BOOL api_reg_rpc(rpcsrv_struct *p);
/*The following definitions come from rpc_server/srv_samr.c */
-BOOL api_samr_rpc(pipes_struct *p, prs_struct *data);
+BOOL api_samr_rpc(rpcsrv_struct *p);
/*The following definitions come from rpc_server/srv_spoolss.c */
-BOOL api_spoolss_rpc(pipes_struct *p, prs_struct *data);
-
-/*The following definitions come from rpc_server/srv_spoolss_nt.c */
-
-void init_printer_hnd(void);
-uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
- const PRINTER_DEFAULT *printer_default,
- uint32 user_switch, SPOOL_USER_CTR user_ctr,
- POLICY_HND *handle);
-uint32 _spoolss_closeprinter(POLICY_HND *handle);
-uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename,
- uint32 in_size,
- uint32 *type,
- uint32 *out_size,
- uint8 **data,
- uint32 *needed);
-uint32 _spoolss_rffpcnex(const POLICY_HND *handle, uint32 flags, uint32 options,
- const UNISTR2 *localmachine, uint32 printerlocal,
- SPOOL_NOTIFY_OPTION *option);
-uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, uint32 change,
- SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info);
-uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned);
-uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
- NEW_BUFFER *buffer, uint32 offered, uint32 *needed);
-uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, uint32 unknown,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *unknown0, uint32 *unknown1);
-uint32 _spoolss_startpageprinter(const POLICY_HND *handle);
-uint32 _spoolss_endpageprinter(const POLICY_HND *handle);
-uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level,
- DOC_INFO *docinfo, uint32 *jobid);
-uint32 _spoolss_enddocprinter(const POLICY_HND *handle);
-uint32 _spoolss_writeprinter( const POLICY_HND *handle,
- uint32 buffer_size,
- const uint8 *buffer,
- uint32 *buffer_written);
-uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level,
- const SPOOL_PRINTER_INFO_LEVEL *info,
- const DEVMODE_CTR devmode_ctr,
- uint32 command);
-uint32 _spoolss_fcpn(const POLICY_HND *handle);
-uint32 _spoolss_addjob(const POLICY_HND *handle, uint32 level,
- NEW_BUFFER *buffer, uint32 offered);
-uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned);
-uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid);
-uint32 _spoolss_setjob( const POLICY_HND *handle,
- uint32 jobid,
- uint32 level,
- JOB_INFO *ctr,
- uint32 command);
-uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned);
-uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *numofforms);
-uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned);
-uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
- const SPOOL_PRINTER_INFO_LEVEL *info,
- uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
- uint32 user_switch, const SPOOL_USER_CTR *user,
- POLICY_HND *handle);
-uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
- uint32 level,
- const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info);
-uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed);
-uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 index,
- uint32 in_value_len, uint32 in_data_len,
- uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
- uint32 *out_type,
- uint32 *out_max_data_len, uint8 **out_data, uint32 *out_data_len);
-uint32 _spoolss_setprinterdata( const POLICY_HND *handle,
- const UNISTR2 *value,
- uint32 type,
- uint32 max_len,
- const uint8 *data,
- uint32 real_len,
- uint32 numeric_data);
-uint32 _spoolss_addform( const POLICY_HND *handle,
- uint32 level,
- const FORM *form);
-uint32 _spoolss_setform( const POLICY_HND *handle,
- const UNISTR2 *uni_name,
- uint32 level,
- const FORM *form);
-uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned);
-uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned);
-uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned);
-uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed);
+BOOL api_spoolss_rpc(rpcsrv_struct *p);
/*The following definitions come from rpc_server/srv_srvsvc.c */
-BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data);
+BOOL api_srvsvc_rpc(rpcsrv_struct *p);
-/*The following definitions come from rpc_server/srv_util.c */
+/*The following definitions come from rpc_server/srv_svcctl.c */
-int make_dom_gids(char *gids_str, DOM_GID **ppgids);
-void get_domain_user_groups(char *domain_groups, char *user);
-uint32 lookup_group_name(uint32 rid, char *group_name, uint32 *type);
-uint32 lookup_alias_name(uint32 rid, char *alias_name, uint32 *type);
-uint32 lookup_user_name(uint32 rid, char *user_name, uint32 *type);
-uint32 lookup_group_rid(char *group_name, uint32 *rid);
-uint32 lookup_alias_rid(char *alias_name, uint32 *rid);
-uint32 lookup_user_rid(char *user_name, uint32 *rid);
+BOOL api_svcctl_rpc(rpcsrv_struct *p);
/*The following definitions come from rpc_server/srv_wkssvc.c */
-BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data);
+BOOL api_wkssvc_rpc(rpcsrv_struct *p);
+
+/*The following definitions come from rpcclient/cmd_atsvc.c */
+
+void cmd_at(struct client_info *info, int argc, char *argv[]);
+
+/*The following definitions come from rpcclient/cmd_brs.c */
+
+void cmd_brs_query_info(struct client_info *info, int argc, char *argv[]);
+
+/*The following definitions come from rpcclient/cmd_eventlog.c */
+
+void cmd_eventlog(struct client_info *info, int argc, char *argv[]);
/*The following definitions come from rpcclient/cmd_lsarpc.c */
-void cmd_lsa_query_info(struct client_info *info);
-void cmd_lsa_lookup_sids(struct client_info *info);
+void cmd_lsa_enum_trust_dom(struct client_info *info, int argc, char *argv[]);
+void cmd_lsa_query_info(struct client_info *info, int argc, char *argv[]);
+void cmd_lsa_lookup_names(struct client_info *info, int argc, char *argv[]);
+void cmd_lsa_lookup_sids(struct client_info *info, int argc, char *argv[]);
+void cmd_lsa_set_secret(struct client_info *info, int argc, char *argv[]);
+void cmd_lsa_create_secret(struct client_info *info, int argc, char *argv[]);
+void cmd_lsa_query_secret_secobj(struct client_info *info, int argc, char *argv[]);
+void cmd_lsa_query_secret(struct client_info *info, int argc, char *argv[]);
/*The following definitions come from rpcclient/cmd_netlogon.c */
-void cmd_netlogon_login_test(struct client_info *info);
+void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[]);
+void cmd_netlogon_domain_test(struct client_info *info, int argc,
+ char *argv[]);
+void cmd_sam_sync(struct client_info *info, int argc, char *argv[]);
/*The following definitions come from rpcclient/cmd_reg.c */
-void cmd_reg_enum(struct client_info *info);
-void cmd_reg_query_key(struct client_info *info);
-void cmd_reg_create_val(struct client_info *info);
-void cmd_reg_delete_val(struct client_info *info);
-void cmd_reg_delete_key(struct client_info *info);
-void cmd_reg_create_key(struct client_info *info);
-void cmd_reg_test_key_sec(struct client_info *info);
-void cmd_reg_get_key_sec(struct client_info *info);
+void split_server_keyname(char *srv_name, char *key, const char* arg);
+BOOL msrpc_reg_enum_key(const char* srv_name, const char* full_keyname,
+ REG_FN(reg_fn),
+ REG_KEY_FN(reg_key_fn),
+ REG_VAL_FN(reg_val_fn));
+void cmd_reg_enum(struct client_info *info, int argc, char *argv[]);
+void cmd_reg_query_info(struct client_info *info, int argc, char *argv[]);
+void cmd_reg_query_key(struct client_info *info, int argc, char *argv[]);
+void cmd_reg_create_val(struct client_info *info, int argc, char *argv[]);
+void cmd_reg_delete_val(struct client_info *info, int argc, char *argv[]);
+void cmd_reg_delete_key(struct client_info *info, int argc, char *argv[]);
+void cmd_reg_create_key(struct client_info *info, int argc, char *argv[]);
+void cmd_reg_test_key_sec(struct client_info *info, int argc, char *argv[]);
+void cmd_reg_get_key_sec(struct client_info *info, int argc, char *argv[]);
+void cmd_reg_shutdown(struct client_info *info, int argc, char *argv[]);
/*The following definitions come from rpcclient/cmd_samr.c */
-void cmd_sam_ntchange_pwd(struct client_info *info);
-void cmd_sam_test(struct client_info *info);
-void cmd_sam_enum_users(struct client_info *info);
-void cmd_sam_query_user(struct client_info *info);
-void cmd_sam_query_groups(struct client_info *info);
-void cmd_sam_enum_aliases(struct client_info *info);
+void cmd_sam_ntchange_pwd(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_test(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_lookup_domain(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_lookup_names(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_lookup_rids(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_del_aliasmem(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_delete_dom_alias(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_add_aliasmem(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_create_dom_trusting(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_create_dom_user(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_create_dom_alias(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_del_groupmem(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_delete_dom_user(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_delete_dom_group(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_add_groupmem(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_create_dom_group(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_enum_users(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_query_groupmem(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_query_group(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_query_sec_obj(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_query_user(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_set_userinfo2(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_set_userinfo(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_query_dispinfo(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_query_dominfo(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_query_aliasmem(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_query_alias(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_enum_aliases(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_enum_groups(struct client_info *info, int argc, char *argv[]);
+void cmd_sam_enum_domains(struct client_info *info, int argc, char *argv[]);
+
+/*The following definitions come from rpcclient/cmd_spoolss.c */
+
+BOOL msrpc_spoolss_enum_printers( const char* srv_name,
+ uint32 level,
+ uint32 *num,
+ void ***ctr,
+ PRINT_INFO_FN(fn));
+void cmd_spoolss_enum_printers(struct client_info *info, int argc, char *argv[]);
+void cmd_spoolss_open_printer_ex(struct client_info *info, int argc, char *argv[]);
+BOOL msrpc_spoolss_enum_jobs( const char* printer_name,
+ const char* station, const char* user_name,
+ uint32 level,
+ uint32 *num,
+ void ***ctr,
+ JOB_INFO_FN(fn));
+void cmd_spoolss_enum_jobs(struct client_info *info, int argc, char *argv[]);
/*The following definitions come from rpcclient/cmd_srvsvc.c */
-void cmd_srv_query_info(struct client_info *info);
-void cmd_srv_enum_conn(struct client_info *info);
-void cmd_srv_enum_shares(struct client_info *info);
-void cmd_srv_enum_sess(struct client_info *info);
-void cmd_srv_enum_files(struct client_info *info);
+BOOL net_srv_get_info(struct client_info *info,
+ uint32 info_level,
+ SRV_INFO_CTR *ctr);
+void cmd_srv_query_info(struct client_info *info, int argc, char *argv[]);
+BOOL msrpc_srv_enum_tprt( const char* dest_srv,
+ uint32 info_level,
+ SRV_TPRT_INFO_CTR *ctr,
+ TPRT_INFO_FN(tprt_fn));
+void cmd_srv_enum_tprt(struct client_info *info, int argc, char *argv[]);
+void cmd_srv_enum_conn(struct client_info *info, int argc, char *argv[]);
+void cmd_srv_enum_shares(struct client_info *info, int argc, char *argv[]);
+void cmd_srv_share_get_info(struct client_info *info, int argc, char *argv[]);
+void cmd_srv_enum_sess(struct client_info *info, int argc, char *argv[]);
+void cmd_srv_enum_files(struct client_info *info, int argc, char *argv[]);
+void cmd_time(struct client_info *info, int argc, char *argv[]);
+
+/*The following definitions come from rpcclient/cmd_svcctl.c */
+
+void svc_display_query_svc_cfg(const QUERY_SERVICE_CONFIG *cfg);
+BOOL svc_query_service( POLICY_HND *pol_scm,
+ const char *svc_name,
+ SVC_QUERY_FN(svc_query_fn));
+void cmd_svc_info(struct client_info *info, int argc, char *argv[]);
+BOOL msrpc_svc_enum(const char* srv_name,
+ ENUM_SRVC_STATUS **svcs,
+ uint32 *num_svcs,
+ SVC_INFO_FN(info_fn),
+ SVC_QUERY_FN(query_fn));
+void cmd_svc_enum(struct client_info *info, int argc, char *argv[]);
+void cmd_svc_stop(struct client_info *info, int argc, char *argv[]);
+void cmd_svc_start(struct client_info *info, int argc, char *argv[]);
+void cmd_svc_set(struct client_info *info, int argc, char *argv[]);
/*The following definitions come from rpcclient/cmd_wkssvc.c */
-void cmd_wks_query_info(struct client_info *info);
+void cmd_wks_query_info(struct client_info *info, int argc, char *argv[]);
+
+/*The following definitions come from rpcclient/cmdat.c */
+
+
+/*The following definitions come from rpcclient/cmdat_cmds.c */
+
+void add_at_commands(void);
+
+/*The following definitions come from rpcclient/display_at.c */
+
+void display_at_enum_info(FILE *out_hnd, enum action_type action,
+ uint32 num_jobs, const AT_ENUM_INFO *const jobs,
+ char *const *const commands);
+void display_at_job_info(FILE *out_hnd, enum action_type action,
+ AT_JOB_INFO *const job, fstring command);
+
+/*The following definitions come from rpcclient/display_event.c */
-/*The following definitions come from rpcclient/display.c */
+void display_eventlog_eventrecord(FILE *out_hnd, enum action_type action, EVENTLOGRECORD *const ev);
+
+/*The following definitions come from rpcclient/display_reg.c */
+
+char *get_reg_val_type_str(uint32 type);
+void display_reg_value_info(FILE *out_hnd, enum action_type action,
+ const char *val_name,
+ uint32 val_type, const BUFFER2 *value);
+void display_reg_key_info(FILE *out_hnd, enum action_type action,
+ const char *key_name, time_t key_mod_time);
+
+/*The following definitions come from rpcclient/display_sam.c */
+
+void display_alias_members(FILE *out_hnd, enum action_type action,
+ uint32 num_mem, char *const *const sid_mem,
+ uint32 *const type);
+void display_alias_rid_info(FILE *out_hnd, enum action_type action,
+ DOM_SID *const sid,
+ uint32 num_rids, uint32 *const rid);
+void display_group_members(FILE *out_hnd, enum action_type action,
+ uint32 num_mem, char *const *const name, uint32 *const type);
+void display_group_info1(FILE *out_hnd, enum action_type action, GROUP_INFO1 *const info1);
+void display_group_info4(FILE *out_hnd, enum action_type action, GROUP_INFO4 *const info4);
+void display_group_info_ctr(FILE *out_hnd, enum action_type action,
+ GROUP_INFO_CTR *const ctr);
+void display_group_rid_info(FILE *out_hnd, enum action_type action,
+ uint32 num_gids, DOM_GID *const gid);
+void display_alias_name_info(FILE *out_hnd, enum action_type action,
+ uint32 num_aliases, fstring *const alias_name, const uint32 *const num_als_usrs);
+void display_alias_info3(FILE *out_hnd, enum action_type action, ALIAS_INFO3 *const info3);
+void display_alias_info_ctr(FILE *out_hnd, enum action_type action,
+ ALIAS_INFO_CTR *const ctr);
+void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *const usr);
+void display_sam_unk_info_2(FILE *out_hnd, enum action_type action,
+ SAM_UNK_INFO_2 *const info2);
+void display_sam_unk_ctr(FILE *out_hnd, enum action_type action,
+ uint32 switch_value, SAM_UNK_CTR *const ctr);
+void display_sam_info_1(FILE *out_hnd, enum action_type action,
+ SAM_ENTRY1 *const e1, SAM_STR1 *const s1);
+void display_sam_info_1_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, SAM_DISPINFO_1 *const ctr);
+void display_sam_disp_info_ctr(FILE *out_hnd, enum action_type action,
+ uint16 level, uint32 count,
+ SAM_DISPINFO_CTR *const ctr);
+
+/*The following definitions come from rpcclient/display_sec.c */
+
+char *get_sec_mask_str(uint32 type);
+void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *const info);
+void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *const ace);
+void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *const sec_acl);
+void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *const sec);
+
+/*The following definitions come from rpcclient/display_spool.c */
+
+void display_print_info_0(FILE *out_hnd, enum action_type action,
+ PRINTER_INFO_0 *const i0);
+void display_print_info_1(FILE *out_hnd, enum action_type action,
+ PRINTER_INFO_1 *const i1);
+void display_printer_info_0_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, PRINTER_INFO_0 *const *const ctr);
+void display_printer_info_1_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, PRINTER_INFO_1 *const *const ctr);
+void display_printer_info_ctr(FILE *out_hnd, enum action_type action,
+ uint32 level, uint32 count,
+ void *const *const ctr);
+void display_job_info_2(FILE *out_hnd, enum action_type action,
+ JOB_INFO_2 *const i2);
+void display_job_info_1(FILE *out_hnd, enum action_type action,
+ JOB_INFO_1 *const i1);
+void display_job_info_2_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, JOB_INFO_2 *const *const ctr);
+void display_job_info_1_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, JOB_INFO_1 *const *const ctr);
+void display_job_info_ctr(FILE *out_hnd, enum action_type action,
+ uint32 level, uint32 count,
+ void *const *const ctr);
+
+/*The following definitions come from rpcclient/display_srv.c */
char *get_file_mode_str(uint32 share_mode);
char *get_file_oplock_str(uint32 op_type);
-char *get_share_type_str(uint32 type);
char *get_server_type_str(uint32 type);
-void display_srv_info_101(FILE *out_hnd, enum action_type action,
- SRV_INFO_101 *sv101);
-void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102);
-void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr);
-void display_conn_info_0(FILE *out_hnd, enum action_type action,
- CONN_INFO_0 *info0);
-void display_conn_info_1(FILE *out_hnd, enum action_type action,
- CONN_INFO_1 *info1, CONN_INFO_1_STR *str1);
-void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action,
- SRV_CONN_INFO_0 *ctr);
-void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action,
- SRV_CONN_INFO_1 *ctr);
-void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action,
- SRV_CONN_INFO_CTR *ctr);
-void display_share_info_1(FILE *out_hnd, enum action_type action,
- SRV_SHARE_INFO_1 *info1);
-void display_share_info_2(FILE *out_hnd, enum action_type action,
- SRV_SHARE_INFO_2 *info2);
-void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action,
- SRV_SHARE_INFO_CTR *ctr);
-void display_file_info_3(FILE *out_hnd, enum action_type action,
- FILE_INFO_3 *info3, FILE_INFO_3_STR *str3);
-void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action,
- SRV_FILE_INFO_3 *ctr);
-void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action,
- SRV_FILE_INFO_CTR *ctr);
-void display_server(FILE *out_hnd, enum action_type action,
- char *sname, uint32 type, char *comment);
-void display_share(FILE *out_hnd, enum action_type action,
- char *sname, uint32 type, char *comment);
-void display_share2(FILE *out_hnd, enum action_type action,
- char *sname, uint32 type, char *comment,
- uint32 perms, uint32 max_uses, uint32 num_uses,
- char *path, char *passwd);
-void display_name(FILE *out_hnd, enum action_type action,
- char *sname);
-void display_group_rid_info(FILE *out_hnd, enum action_type action,
- uint32 num_gids, DOM_GID *gid);
-void display_alias_name_info(FILE *out_hnd, enum action_type action,
- uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs);
-void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr);
-char *get_sec_mask_str(uint32 type);
-void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info);
-void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace);
-void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl);
-void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec);
-char *get_reg_val_type_str(uint32 type);
-void display_reg_value_info(FILE *out_hnd, enum action_type action,
- char *val_name, uint32 val_type, BUFFER2 *value);
-void display_reg_key_info(FILE *out_hnd, enum action_type action,
- char *key_name, time_t key_mod_time);
+void display_srv_info_ctr(FILE *out_hnd, enum action_type action,
+ const SRV_INFO_CTR *ctr);
+void display_conn_info_0(FILE *out_hnd, enum action_type action,
+ CONN_INFO_0 *const info0);
+void display_conn_info_1(FILE *out_hnd, enum action_type action,
+ CONN_INFO_1 *const info1, CONN_INFO_1_STR *const str1);
+void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_0 *const ctr);
+void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_1 *const ctr);
+void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_CTR *const ctr);
+void display_tprt_info_0(FILE *out_hnd, enum action_type action,
+ TPRT_INFO_0 *const info0, TPRT_INFO_0_STR *const str0);
+void display_srv_tprt_info_0_ctr(FILE *out_hnd, enum action_type action,
+ const SRV_TPRT_INFO_0 *const ctr);
+void display_srv_tprt_info_ctr(FILE *out_hnd, enum action_type action,
+ const SRV_TPRT_INFO_CTR *const ctr);
+void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_CTR *const ctr);
+void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_FILE_INFO_CTR *const ctr);
+void display_sess_info_0(FILE *out_hnd, enum action_type action,
+ SESS_INFO_0 *const info0, SESS_INFO_0_STR *const str0);
+void display_sess_info_1(FILE *out_hnd, enum action_type action,
+ SESS_INFO_1 *const info1, SESS_INFO_1_STR *const str1);
+void display_srv_sess_info_0_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SESS_INFO_0 *const ctr);
+void display_srv_sess_info_1_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SESS_INFO_1 *const ctr);
+void display_srv_sess_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SESS_INFO_CTR *const ctr);
+void display_server(FILE *out_hnd, enum action_type action,
+ char *const sname, uint32 type, char *const comment);
+void display_share(FILE *out_hnd, enum action_type action,
+ char *const sname, uint32 type, char *const comment);
+void display_share2(FILE *out_hnd, enum action_type action,
+ char *const sname, uint32 type, char *const comment,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ char *const path, char *const password);
+void display_name(FILE *out_hnd, enum action_type action,
+ char *const sname);
+
+/*The following definitions come from rpcclient/display_svc.c */
+
+char *get_svc_start_type_str(uint32 type);
+void display_query_svc_cfg(FILE *out_hnd, enum action_type action,
+ const QUERY_SERVICE_CONFIG *const cfg);
+void display_svc_info(FILE *out_hnd, enum action_type action,
+ const ENUM_SRVC_STATUS *const svc);
+
+/*The following definitions come from rpcclient/display_sync.c */
+
+void display_sam_sync_ctr(FILE *out_hnd, enum action_type action,
+ SAM_DELTA_HDR *const delta,
+ SAM_DELTA_CTR *const ctr);
+void display_sam_sync(FILE *out_hnd, enum action_type action,
+ SAM_DELTA_HDR *const deltas,
+ SAM_DELTA_CTR *const ctr,
+ uint32 num);
+
+/*The following definitions come from rpcclient/eventlog.c */
+
+int main(int argc, char *argv[]);
+
+/*The following definitions come from rpcclient/eventlog_cmds.c */
+
+void add_evt_commands(void);
+
+/*The following definitions come from rpcclient/lsa.c */
+
+
+/*The following definitions come from rpcclient/lsa_cmds.c */
+
+void add_lsa_commands(void);
+
+/*The following definitions come from rpcclient/net.c */
+
+
+/*The following definitions come from rpcclient/net_cmds.c */
+
+void add_net_commands(void);
+
+/*The following definitions come from rpcclient/netlogon_cmds.c */
+
+void add_ntl_commands(void);
+
+/*The following definitions come from rpcclient/regedit.c */
+
+
+/*The following definitions come from rpcclient/regedit_cmds.c */
+
+void add_reg_commands(void);
/*The following definitions come from rpcclient/rpcclient.c */
-void rpcclient_init(void);
+
+/*The following definitions come from rpcclient/samedit.c */
+
+
+/*The following definitions come from rpcclient/samedit_cmds.c */
+
+void add_sam_commands(void);
+
+/*The following definitions come from rpcclient/spoolss.c */
+
+int main(int argc, char *argv[]);
+
+/*The following definitions come from rpcclient/spoolss_cmds.c */
+
+void add_spl_commands(void);
+
+/*The following definitions come from rpcclient/svcctrl.c */
+
+int main(int argc, char *argv[]);
+
+/*The following definitions come from rpcclient/svcctrl_cmds.c */
+
+char *complete_svcenum(char *text, int state);
+void add_svc_commands(void);
+
+/*The following definitions come from samrd/samrd.c */
+
+msrpc_service_fns *get_service_fns(void);
+
+/*The following definitions come from samrd/srv_samr_als_tdb.c */
+
+uint32 _samr_add_aliasmem(const POLICY_HND *alias_pol, const DOM_SID *sid);
+uint32 _samr_del_aliasmem(const POLICY_HND *alias_pol, const DOM_SID *sid);
+uint32 _samr_query_aliasinfo(const POLICY_HND *alias_pol,
+ uint16 switch_level,
+ ALIAS_INFO_CTR *ctr);
+uint32 _samr_delete_dom_alias(POLICY_HND *alias_pol);
+uint32 _samr_query_aliasmem(const POLICY_HND *alias_pol,
+ uint32 *num_mem, DOM_SID2 **sid);
+uint32 _samr_create_dom_alias(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_acct_name,
+ uint32 access_mask,
+ POLICY_HND *alias_pol, uint32 *rid);
+uint32 _samr_open_alias(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 alias_rid,
+ POLICY_HND *alias_pol);
+
+/*The following definitions come from samrd/srv_samr_dom_nt5ldap.c */
+
+uint32 _samr_open_domain(const POLICY_HND *connect_pol,
+ uint32 ace_perms,
+ const DOM_SID *sid,
+ POLICY_HND *domain_pol);
+uint32 _samr_enum_dom_users( const POLICY_HND *pol, uint32 *start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_users);
+uint32 _samr_enum_dom_groups(const POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_groups);
+uint32 _samr_enum_dom_aliases(const POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_aliases);
+uint32 _samr_query_dispinfo( const POLICY_HND *domain_pol, uint16 level,
+ uint32 start_idx,
+ uint32 max_entries,
+ uint32 max_size,
+ uint32 *data_size,
+ uint32 *num_entries,
+ SAM_DISPINFO_CTR *ctr);
+uint32 _samr_lookup_names(const POLICY_HND *dom_pol,
+
+ uint32 num_names,
+ uint32 flags,
+ uint32 ptr,
+ const UNISTR2 *uni_name,
+
+ uint32 *num_rids,
+ uint32 rid[MAX_SAM_ENTRIES],
+ uint32 *num_types,
+ uint32 type[MAX_SAM_ENTRIES]);
+uint32 _samr_lookup_rids(const POLICY_HND *dom_pol,
+ uint32 num_rids, uint32 flags,
+ const uint32 *rids,
+ uint32 *num_names,
+ UNIHDR **hdr_name, UNISTR2** uni_name,
+ uint32 **types);
+uint32 _samr_query_dom_info(const POLICY_HND *domain_pol,
+ uint16 switch_value,
+ SAM_UNK_CTR *ctr);
+uint32 _samr_set_groupinfo(const POLICY_HND *pol,
+ uint16 switch_level,
+ const GROUP_INFO_CTR* ctr);
+uint32 _samr_unknown_2d(const POLICY_HND *domain_pol, const DOM_SID *sid);
+
+/*The following definitions come from samrd/srv_samr_dom_tdb.c */
+
+uint32 _samr_open_domain(const POLICY_HND *connect_pol,
+ uint32 ace_perms,
+ const DOM_SID * sid, POLICY_HND *domain_pol);
+uint32 _samr_enum_dom_users(const POLICY_HND *pol, uint32 * start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ SAM_ENTRY ** sam,
+ UNISTR2 ** uni_acct_name, uint32 * num_sam_users);
+uint32 _samr_enum_dom_groups(const POLICY_HND *pol,
+ uint32 * start_idx, uint32 size,
+ SAM_ENTRY ** sam,
+ UNISTR2 ** uni_acct_name,
+ uint32 * num_sam_groups);
+uint32 _samr_enum_dom_aliases(const POLICY_HND *pol,
+ uint32 * start_idx, uint32 size,
+ SAM_ENTRY ** sam,
+ UNISTR2 ** uni_acct_name,
+ uint32 * num_sam_aliases);
+uint32 _samr_query_dispinfo(const POLICY_HND *domain_pol, uint16 level,
+ uint32 start_idx,
+ uint32 max_entries,
+ uint32 max_size,
+ uint32 * data_size,
+ uint32 * num_entries, SAM_DISPINFO_CTR * ctr);
+BOOL dom_user_traverse(const DOM_SID * dom_sid,
+ int (*fn) (TDB_CONTEXT *, void *), void *state);
+uint32 _samr_lookup_names(const POLICY_HND *dom_pol,
+ uint32 num_names,
+ uint32 flags,
+ uint32 ptr,
+ const UNISTR2 * uni_name,
+ uint32 * num_rids,
+ uint32 rid[MAX_SAM_ENTRIES],
+ uint32 * num_types, uint32 type[MAX_SAM_ENTRIES]);
+uint32 _samr_lookup_rids(const POLICY_HND *dom_pol,
+ uint32 num_rids, uint32 flags,
+ const uint32 * rids,
+ uint32 * num_names,
+ UNIHDR ** hdr_name, UNISTR2 ** uni_name,
+ uint32 ** types);
+uint32 _samr_query_dom_info(const POLICY_HND *domain_pol,
+ uint16 switch_value, SAM_UNK_CTR * ctr);
+uint32 _samr_unknown_2d(const POLICY_HND *domain_pol, const DOM_SID * sid);
+
+/*The following definitions come from samrd/srv_samr_grp_tdb.c */
+
+uint32 _samr_add_groupmem(const POLICY_HND *pol, uint32 rid, uint32 unknown);
+uint32 _samr_del_groupmem(const POLICY_HND *pol, uint32 rid);
+uint32 _samr_delete_dom_group(POLICY_HND *group_pol);
+uint32 _samr_query_groupmem(const POLICY_HND *group_pol,
+ uint32 * num_mem, uint32 ** rid, uint32 ** attr);
+uint32 _samr_set_groupinfo(const POLICY_HND *pol,
+ uint16 switch_level, const GROUP_INFO_CTR * ctr);
+uint32 _samr_query_groupinfo(const POLICY_HND *pol,
+ uint16 switch_level, GROUP_INFO_CTR * ctr);
+uint32 _samr_create_dom_group(const POLICY_HND *domain_pol,
+ const UNISTR2 * uni_acct_name,
+ uint32 access_mask,
+ POLICY_HND *group_pol, uint32 * group_rid);
+uint32 _samr_open_group(const POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 group_rid, POLICY_HND *group_pol);
+
+/*The following definitions come from samrd/srv_samr_nt5ldap.c */
+
+BOOL set_nt5ldaprid(struct policy_cache *cache, POLICY_HND *hnd,
+ LDAPDB *hds, uint32 rid);
+BOOL get_nt5ldaprid(struct policy_cache *cache, const POLICY_HND *hnd,
+ LDAPDB **hds, uint32 *rid);
+BOOL set_nt5ldapsam(struct policy_cache *cache, POLICY_HND *hnd,
+ LDAPDB *hds);
+BOOL get_nt5ldapsam(struct policy_cache *cache, const POLICY_HND *hnd,
+ LDAPDB **hds);
+BOOL set_nt5ldapdomsid(struct policy_cache *cache, POLICY_HND *hnd,
+ LDAPDB *hds,
+ const DOM_SID *sid);
+BOOL get_nt5ldapdomsid(struct policy_cache *cache, const POLICY_HND *hnd,
+ LDAPDB **hds,
+ DOM_SID *sid);
+BOOL set_nt5ldapsid(struct policy_cache *cache, POLICY_HND *hnd,
+ LDAPDB *hds, const DOM_SID *sid);
+BOOL get_nt5ldapsid(struct policy_cache *cache, const POLICY_HND *hnd,
+ LDAPDB **hds, DOM_SID *sid);
+uint32 samr_open_by_nt5ldaprid( LDAPDB *hds,
+ const POLICY_HND *parent_pol,
+ POLICY_HND *pol, uint32 access_mask, uint32 rid);
+BOOL pwdbsam_initialise(void);
+
+/*The following definitions come from samrd/srv_samr_passdb.c */
+
+uint32 _samr_close(POLICY_HND *hnd);
+uint32 _samr_unknown_2d(const POLICY_HND *domain_pol, const DOM_SID *sid);
+uint32 _samr_open_domain(const POLICY_HND *connect_pol,
+ uint32 ace_perms,
+ const DOM_SID *sid,
+ POLICY_HND *domain_pol);
+uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
+ uint32 *unknown_0,
+ uint32 *unknown_1);
+uint32 _samr_query_sec_obj(const POLICY_HND *user_pol, SEC_DESC_BUF *buf);
+uint32 _samr_enum_dom_users( const POLICY_HND *pol, uint32 *start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_users);
+uint32 _samr_add_groupmem(const POLICY_HND *pol, uint32 rid, uint32 unknown);
+uint32 _samr_del_groupmem(const POLICY_HND *pol, uint32 rid);
+uint32 _samr_add_aliasmem(const POLICY_HND *alias_pol, const DOM_SID *sid);
+uint32 _samr_del_aliasmem(const POLICY_HND *alias_pol, const DOM_SID *sid);
+uint32 _samr_enum_domains(const POLICY_HND *pol, uint32 *start_idx,
+ uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_users);
+uint32 _samr_enum_dom_groups(const POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_groups);
+uint32 _samr_enum_dom_aliases(const POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_aliases);
+uint32 _samr_query_dispinfo( const POLICY_HND *domain_pol, uint16 level,
+ uint32 start_idx,
+ uint32 max_entries,
+ uint32 max_size,
+ uint32 *data_size,
+ uint32 *num_entries,
+ SAM_DISPINFO_CTR *ctr);
+uint32 _samr_delete_dom_user(POLICY_HND *user_pol);
+uint32 _samr_delete_dom_group(POLICY_HND *group_pol);
+uint32 _samr_query_groupmem(const POLICY_HND *group_pol,
+ uint32 *num_mem,
+ uint32 **rid,
+ uint32 **attr);
+uint32 _samr_set_groupinfo(const POLICY_HND *pol,
+ uint16 switch_level,
+ const GROUP_INFO_CTR* ctr);
+uint32 _samr_query_groupinfo(const POLICY_HND *pol,
+ uint16 switch_level,
+ GROUP_INFO_CTR* ctr);
+uint32 _samr_query_aliasinfo(const POLICY_HND *alias_pol,
+ uint16 switch_level,
+ ALIAS_INFO_CTR *ctr);
+uint32 _samr_query_useraliases(const POLICY_HND *pol,
+ const uint32 *ptr_sid, const DOM_SID2 *sid,
+ uint32 *num_aliases, uint32 **rid);
+uint32 _samr_delete_dom_alias(POLICY_HND *alias_pol);
+uint32 _samr_query_aliasmem(const POLICY_HND *alias_pol,
+ uint32 *num_mem, DOM_SID2 **sid);
+uint32 _samr_lookup_names(const POLICY_HND *pol,
+
+ uint32 num_names1,
+ uint32 flags,
+ uint32 ptr,
+ const UNISTR2 *uni_name,
+
+ uint32 *num_rids1,
+ uint32 rid[MAX_SAM_ENTRIES],
+ uint32 *num_types1,
+ uint32 type[MAX_SAM_ENTRIES]);
+uint32 _samr_chgpasswd_user( const UNISTR2 *uni_dest_host,
+ const UNISTR2 *uni_user_name,
+ const char nt_newpass[516],
+ const uchar nt_oldhash[16],
+ const char lm_newpass[516],
+ const uchar lm_oldhash[16]);
+uint32 _samr_get_dom_pwinfo(const UNISTR2 *uni_srv_name,
+ uint16 *unk_0, uint16 *unk_1, uint16 *unk_2);
+uint32 _samr_lookup_rids(const POLICY_HND *pol,
+ uint32 num_rids, uint32 flags,
+ const uint32 *rids,
+ uint32 *num_names,
+ UNIHDR **hdr_name, UNISTR2** uni_name,
+ uint32 **types);
+uint32 _samr_open_user(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 user_rid,
+ POLICY_HND *user_pol);
+uint32 _samr_query_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+uint32 _samr_set_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+uint32 _samr_set_userinfo2(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+uint32 _samr_query_usergroups(const POLICY_HND *pol,
+ uint32 *num_groups,
+ DOM_GID **gids);
+uint32 _samr_create_dom_alias(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_acct_name,
+ uint32 access_mask,
+ POLICY_HND *alias_pol, uint32 *rid);
+uint32 _samr_create_dom_group(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_acct_name,
+ uint32 access_mask,
+ POLICY_HND *group_pol, uint32 *rid);
+uint32 _samr_query_dom_info(const POLICY_HND *domain_pol,
+ uint16 switch_value,
+ SAM_UNK_CTR *ctr);
+uint32 _samr_create_user(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_username,
+ uint16 acb_info, uint32 access_mask,
+ POLICY_HND *user_pol,
+ uint32 *unknown_0, uint32 *user_rid);
+uint32 _samr_connect_anon(const UNISTR2 *srv_name, uint32 access_mask,
+ POLICY_HND *connect_pol);
+uint32 _samr_connect(const UNISTR2 *srv_name, uint32 access_mask,
+ POLICY_HND *connect_pol);
+uint32 _samr_open_alias(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 alias_rid,
+ POLICY_HND *alias_pol);
+uint32 _samr_open_group(const POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 group_rid,
+ POLICY_HND *group_pol);
+uint32 _samr_lookup_domain(const POLICY_HND *connect_pol,
+ const UNISTR2 *uni_domain,
+ DOM_SID *dom_sid);
+BOOL pwdbsam_initialise(void);
+
+/*The following definitions come from samrd/srv_samr_sam_tdb.c */
+
+uint32 _samr_enum_domains(const POLICY_HND *pol, uint32 *start_idx,
+ uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_users);
+uint32 _samr_connect_anon(const UNISTR2 *srv_name, uint32 access_mask,
+ POLICY_HND *connect_pol);
+uint32 _samr_connect(const UNISTR2 *srv_name, uint32 access_mask,
+ POLICY_HND *connect_pol);
+uint32 _samr_lookup_domain(const POLICY_HND *connect_pol,
+ const UNISTR2 *uni_domain,
+ DOM_SID *dom_sid);
+uint32 _samr_close(POLICY_HND *hnd);
+uint32 _samr_chgpasswd_user( const UNISTR2 *uni_dest_host,
+ const UNISTR2 *uni_user_name,
+ const char nt_newpass[516],
+ const uchar nt_oldhash[16],
+ const char lm_newpass[516],
+ const uchar lm_oldhash[16]);
+uint32 _samr_get_dom_pwinfo(const UNISTR2 *uni_srv_name,
+ uint16 *unk_0, uint16 *unk_1, uint16 *unk_2);
+uint32 _samr_query_sec_obj(const POLICY_HND *pol, SEC_DESC_BUF *buf);
+
+/*The following definitions come from samrd/srv_samr_tdb.c */
+
+BOOL set_tdbrid(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT * usr_tdb,
+ TDB_CONTEXT * grp_tdb, TDB_CONTEXT * als_tdb, uint32 rid);
+BOOL get_tdbrid(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT ** usr_tdb,
+ TDB_CONTEXT ** grp_tdb, TDB_CONTEXT ** als_tdb, uint32 * rid);
+BOOL set_tdbsam(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT * tdb);
+BOOL get_tdbsam(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT ** tdb);
+BOOL set_tdbdomsid(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT * usr_tdb,
+ TDB_CONTEXT * usg_tdb,
+ TDB_CONTEXT * usa_tdb,
+ TDB_CONTEXT * grp_tdb,
+ TDB_CONTEXT * als_tdb, const DOM_SID * sid);
+BOOL get_tdbdomsid(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT ** usr_tdb,
+ TDB_CONTEXT ** usg_tdb,
+ TDB_CONTEXT ** usa_tdb,
+ TDB_CONTEXT ** grp_tdb,
+ TDB_CONTEXT ** als_tdb, DOM_SID * sid);
+BOOL set_tdbsid(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT * tdb, const DOM_SID * sid);
+BOOL get_tdbsid(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT ** tdb, DOM_SID * sid);
+TDB_CONTEXT *open_usr_db(const DOM_SID * sid, uint32 rid, int perms);
+uint32 samr_open_user_tdb(const POLICY_HND *parent_pol,
+ const DOM_SID * sid,
+ TDB_CONTEXT * usr_tdb,
+ POLICY_HND *pol, uint32 ace_perms, uint32 rid);
+
+/*The following definitions come from samrd/srv_samr_tdb_init.c */
+
+uint32 initialise_dom_tdb(const DOM_SID * sid);
+uint32 initialise_sam_tdb(const char *sam_name, const DOM_SID * sam_sid);
+BOOL pwdbsam_initialise(void);
+
+/*The following definitions come from samrd/srv_samr_usr_nt5ldap.c */
+
+uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
+ uint32 *unknown_0,
+ uint32 *unknown_1);
+uint32 _samr_query_sec_obj(const POLICY_HND *pol, SEC_DESC_BUF *buf);
+uint32 _samr_query_usergroups(const POLICY_HND *pol,
+ uint32 *num_groups,
+ DOM_GID **gids);
+uint32 _samr_query_useraliases(const POLICY_HND *pol,
+ const uint32 *ptr_sid, const DOM_SID2 *sid,
+ uint32 *num_aliases, uint32 **rid);
+uint32 _samr_open_user(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 user_rid,
+ POLICY_HND *user_pol);
+uint32 _samr_query_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+uint32 _samr_set_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+uint32 _samr_set_userinfo2(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+uint32 _samr_create_user(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_username,
+ uint16 acb_info, uint32 access_mask,
+ POLICY_HND *user_pol,
+ uint32 *unknown_0, uint32 *user_rid);
+uint32 _samr_delete_dom_user(POLICY_HND *user_pol);
+
+/*The following definitions come from samrd/srv_samr_usr_tdb.c */
+
+BOOL tdb_lookup_user(TDB_CONTEXT * tdb, SAM_USER_INFO_21 * usr);
+uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
+ uint32 * unknown_0, uint32 * unknown_1);
+uint32 _samr_query_usergroups(const POLICY_HND *pol,
+ uint32 * num_groups, DOM_GID ** gids);
+uint32 _samr_query_useraliases(const POLICY_HND *domain_pol,
+ const uint32 * ptr_sid, const DOM_SID2 * sid,
+ uint32 * num_aliases, uint32 ** rid);
+uint32 _samr_open_user(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 user_rid,
+ POLICY_HND *user_pol);
+uint32 _samr_query_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR * ctr);
+uint32 _samr_set_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR * ctr);
+uint32 _samr_set_userinfo2(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR * ctr);
+uint32 _samr_create_user(const POLICY_HND *domain_pol,
+ const UNISTR2 * uni_username,
+ uint16 acb_info, uint32 access_mask,
+ POLICY_HND *user_pol,
+ uint32 * unknown_0, uint32 * user_rid);
+uint32 _samr_delete_dom_user(POLICY_HND *user_pol);
/*The following definitions come from smbd/blocking.c */
BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num);
void remove_pending_lock_requests_by_fid(files_struct *fsp);
void remove_pending_lock_requests_by_mid(int mid);
-BOOL blocking_locks_pending(void);
void process_blocking_lock_queue(time_t t);
+/*The following definitions come from smbd/challenge.c */
+
+void generate_next_challenge(char *challenge);
+BOOL set_challenge(unsigned char *challenge);
+BOOL last_challenge(unsigned char *challenge);
+
/*The following definitions come from smbd/chgpasswd.c */
-BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root);
-BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root);
-BOOL check_lanman_password(char *user, uchar *pass1,
- uchar *pass2, struct smb_passwd **psmbpw);
-BOOL change_lanman_password(struct smb_passwd *smbpw, uchar *pass1, uchar *pass2);
-BOOL pass_oem_change(char *user,
- uchar *lmdata, uchar *lmhash,
- uchar *ntdata, uchar *nthash);
-BOOL check_oem_password(char *user,
- uchar *lmdata, uchar *lmhash,
- uchar *ntdata, uchar *nthash,
- struct smb_passwd **psmbpw, char *new_passwd,
- int new_passwd_size);
-BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd, BOOL override);
-BOOL check_plaintext_password(char *user,char *old_passwd,
- int old_passwd_size, struct smb_passwd **psmbpw);
+BOOL chgpasswd(const char *_name,char *oldpass,char *newpass, BOOL as_root);
+BOOL chgpasswd(const char *name,char *oldpass,char *newpass, BOOL as_root);
+BOOL pass_oem_change(const char *user,
+ const uchar *lmdata, const uchar *lmhash,
+ const uchar *ntdata, const uchar *nthash);
+BOOL change_oem_password(struct smb_passwd *smbpw, UNISTR2 *new_passwd,
+ BOOL unicode, BOOL override);
+BOOL update_smbpassword_file(const char *user, const char *password);
/*The following definitions come from smbd/close.c */
-int close_file(files_struct *fsp, BOOL normal_close);
+void close_file(files_struct *fsp, BOOL normal_close);
+void close_directory(files_struct *fsp);
/*The following definitions come from smbd/conn.c */
@@ -2868,8 +4160,13 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
/*The following definitions come from smbd/dfree.c */
-SMB_BIG_UINT sys_disk_free(char *path, BOOL small_query,
- SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize);
+SMB_BIG_UINT sys_disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize);
+
+/*The following definitions come from smbd/dfs.c */
+
+BOOL init_dfs_table(void);
+int under_dfs(connection_struct *conn, const char *path,
+ char *local_path, size_t local_plen);
/*The following definitions come from smbd/dir.c */
@@ -2879,12 +4176,13 @@ char *dptr_wcard(int key);
BOOL dptr_set_wcard(int key, char *wcard);
BOOL dptr_set_attr(int key, uint16 attr);
uint16 dptr_attr(int key);
-void dptr_close(int *key);
+void dptr_close(int key);
void dptr_closecnum(connection_struct *conn);
void dptr_idlecnum(connection_struct *conn);
-void dptr_closepath(char *path,uint16 spid);
-int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect_close,uint16 spid);
+void dptr_closepath(char *path,int pid);
+int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid);
BOOL dptr_fill(char *buf1,unsigned int key);
+BOOL dptr_zero(char *buf);
void *dptr_fetch(char *buf,int *num);
void *dptr_fetch_lanman2(int dptr_num);
BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype);
@@ -2901,7 +4199,7 @@ void DirCacheFlush(int snum);
/*The following definitions come from smbd/dosmode.c */
-mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname);
+mode_t unix_mode(connection_struct *conn,int dosmode);
int dos_mode(connection_struct *conn,char *path,SMB_STRUCT_STAT *sbuf);
int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *st);
int file_utime(connection_struct *conn, char *fname, struct utimbuf *times);
@@ -2916,21 +4214,20 @@ int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int
/*The following definitions come from smbd/fileio.c */
SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos);
-BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n);
ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n);
-ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n);
-void delete_write_cache(files_struct *fsp);
-void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size);
-ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason);
-void sys_fsync_file(connection_struct *conn, files_struct *fsp);
+ssize_t write_file(files_struct *fsp,char *data,size_t n);
+void sys_sync_file(int fd);
/*The following definitions come from smbd/filename.c */
void print_stat_cache_statistics(void);
-BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
- BOOL *bad_path, SMB_STRUCT_STAT *pst);
+BOOL unix_dfs_convert(char *name,connection_struct *conn,
+ char *saved_last_component,
+ BOOL *bad_path, SMB_STRUCT_STAT *pst);
+BOOL unix_convert(char *name,connection_struct *conn,
+ char *saved_last_component,
+ BOOL *bad_path, SMB_STRUCT_STAT *pst);
BOOL check_name(char *name,connection_struct *conn);
-BOOL reset_stat_cache( void );
/*The following definitions come from smbd/files.c */
@@ -2954,8 +4251,18 @@ void file_chain_restore(void);
/*The following definitions come from smbd/ipc.c */
+void send_trans_reply(char *outbuf,
+ prs_struct *rdata,
+ prs_struct *rparam,
+ uint16 *setup, int lsetup, int max_data_ret,
+ BOOL pipe_data_outstanding);
int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bufsize);
+/*The following definitions come from smbd/lanman.c */
+
+int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
+ int tdscnt,int tpscnt,int mdrcnt,int mprcnt);
+
/*The following definitions come from smbd/mangle.c */
BOOL is_mangled( char *s );
@@ -2963,7 +4270,7 @@ BOOL is_8_3( char *fname, BOOL check_case );
void reset_mangled_cache( void );
BOOL check_mangled_cache( char *s );
void mangle_name_83( char *s);
-BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum);
+BOOL name_map_mangle(char *OutName, BOOL need83, int snum);
/*The following definitions come from smbd/message.c */
@@ -2989,7 +4296,6 @@ BOOL disk_quotas(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT
/*The following definitions come from smbd/nttrans.c */
void fail_next_srvsvc_open(void);
-BOOL should_fail_next_srvsvc_open(const char *pipename);
int reply_ntcreate_and_X(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize);
int reply_ntcancel(connection_struct *conn,
@@ -2997,36 +4303,30 @@ int reply_ntcancel(connection_struct *conn,
int reply_nttranss(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize);
void remove_pending_change_notify_requests_by_fid(files_struct *fsp);
-void remove_pending_change_notify_requests_by_filename(files_struct *fsp);
-BOOL process_pending_change_notify_queue(time_t t);
-BOOL change_notifies_pending(void);
+void process_pending_change_notify_queue(time_t t);
int reply_nttrans(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize);
/*The following definitions come from smbd/open.c */
void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u);
-uint16 fd_attempt_close(files_struct *fsp, int *err_ret);
-void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
- mode_t mode,int oplock_request, int *Access,int *action);
-int open_file_stat(files_struct *fsp,connection_struct *conn,
- char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action);
+uint16 fd_attempt_close(files_struct *fsp);
+void open_file_shared(files_struct *fsp, connection_struct *conn,
+ char *fname, int share_mode, int ofun,
+ mode_t mode, int oplock_request, int *Access,
+ int *action);
int open_directory(files_struct *fsp,connection_struct *conn,
char *fname, int smb_ofun, mode_t unixmode, int *action);
BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op);
/*The following definitions come from smbd/oplock.c */
-int32 get_number_of_exclusive_open_oplocks(void);
BOOL setup_kernel_oplock_pipe(void);
BOOL open_oplock_ipc(void);
BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeout);
-BOOL set_file_oplock(files_struct *fsp, int oplock_type);
-void release_file_oplock(files_struct *fsp);
-BOOL remove_oplock(files_struct *fsp);
+BOOL set_file_oplock(files_struct *fsp);
int setup_oplock_select_set( fd_set *fds);
BOOL process_local_message(char *buffer, int buf_size);
-BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token);
BOOL request_oplock_break(share_mode_entry *share_entry,
SMB_DEV_T dev, SMB_INO_T inode);
BOOL attempt_close_oplocked_file(files_struct *fsp);
@@ -3034,40 +4334,23 @@ void check_kernel_oplocks(void);
/*The following definitions come from smbd/password.c */
-void generate_next_challenge(char *challenge);
-BOOL set_challenge(unsigned char *challenge);
-user_struct *get_valid_user_struct(uint16 vuid);
-void invalidate_vuid(uint16 vuid);
-char *validated_username(uint16 vuid);
-int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups);
-uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest);
void add_session_user(char *user);
-BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8);
-BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
- uchar lm_pass[24], uchar nt_pass[24]);
-BOOL pass_check_smb(char *user, char *domain,
- uchar *chal, uchar *lm_pwd, uchar *nt_pwd,
- struct passwd *pwd);
-BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd);
-BOOL user_ok(char *user,int snum);
-BOOL authorise_login(int snum,char *user,char *password, int pwlen,
- BOOL *guest,BOOL *force,uint16 vuid);
+BOOL password_ok(const char *orig_user, const char *domain,
+ const char *smb_apasswd, int smb_apasslen,
+ const char *smb_ntpasswd, int smb_ntpasslen,
+ struct passwd *pwd,
+ NET_USER_INFO_3 *info3);
+BOOL authorise_login(int snum, char *user, char *domain,
+ char *password, int pwlen,
+ BOOL *guest,BOOL *force,
+ const vuser_key *key);
BOOL check_hosts_equiv(char *user);
-struct cli_state *server_client(void);
-struct cli_state *server_cryptkey(void);
-BOOL server_validate(char *user, char *domain,
- char *pass, int passlen,
- char *ntpass, int ntpasslen);
-BOOL domain_client_validate( char *user, char *domain,
- char *smb_apasswd, int smb_apasslen,
- char *smb_ntpasswd, int smb_ntpasslen,
- BOOL *user_exists);
/*The following definitions come from smbd/pipes.c */
int reply_open_pipe_and_X(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize);
-int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize);
+int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize);
int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize);
int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize);
int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf);
@@ -3082,12 +4365,10 @@ void invalidate_read_prediction(int fd);
BOOL push_oplock_pending_smb_message(char *buf, int msg_len);
BOOL receive_next_smb(char *inbuf, int bufsize, int timeout);
-void respond_to_all_remaining_local_messages(void);
void process_smb(char *inbuf, char *outbuf);
char *smb_fn_name(int type);
void construct_reply_common(char *inbuf,char *outbuf);
int chain_reply(char *inbuf,char *outbuf,int size,int bufsize);
-void check_reload(int t);
void smbd_process(void);
/*The following definitions come from smbd/reply.c */
@@ -3114,23 +4395,23 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize);
int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length, int dum_buffsiz);
-int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
-int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
-int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
-int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize);
+int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,int dum_buffsize);
int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
-int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
-int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_exit(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
-int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
- int dum_buffsize);
+int reply_close(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_writeclose(connection_struct *conn,
- char *inbuf,char *outbuf, int size, int dum_buffsize);
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_lock(connection_struct *conn,
char *inbuf,char *outbuf, int length, int dum_buffsize);
-int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_tdis(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_echo(connection_struct *conn,
@@ -3143,7 +4424,6 @@ int reply_printqueue(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
-BOOL rmdir_internals(connection_struct *conn, char *directory);
int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int rename_internals(connection_struct *conn,
char *inbuf, char *outbuf, char *name,
@@ -3151,14 +4431,12 @@ int rename_internals(connection_struct *conn,
int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
-SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL *err);
-SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err);
int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize);
-int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
-int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
-int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize);
+int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
+int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
/*The following definitions come from smbd/server.c */
@@ -3169,7 +4447,10 @@ void exit_server(char *reason);
BOOL become_service(connection_struct *conn,BOOL do_chdir);
int find_service(char *service);
-connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode);
+connection_struct *make_connection(char *service,char *user,
+ char *domain,
+ char *password, int pwlen,
+ char *dev,uint16 vuid, int *ecode);
void close_cnum(connection_struct *conn, uint16 vuid);
/*The following definitions come from smbd/ssl.c */
@@ -3195,21 +4476,16 @@ int reply_trans2(connection_struct *conn,
/*The following definitions come from smbd/uid.c */
-void init_uid(void);
-BOOL become_guest(void);
BOOL become_user(connection_struct *conn, uint16 vuid);
+BOOL become_userk(connection_struct *conn, const vuser_key *key);
BOOL unbecome_user(void );
-BOOL become_authenticated_pipe_user(pipes_struct *p);
-BOOL unbecome_authenticated_pipe_user(pipes_struct *p);
-void become_root(BOOL save_dir) ;
-void unbecome_root(BOOL restore_dir);
/*The following definitions come from smbd/vfs-wrap.c */
int vfswrap_dummy_connect(struct vfs_connection_struct *conn, char *service,
char *user);
void vfswrap_dummy_disconnect(void);
-SMB_BIG_UINT vfswrap_disk_free(char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+SMB_BIG_UINT vfswrap_disk_free(char *path, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
DIR *vfswrap_opendir(char *fname);
struct dirent *vfswrap_readdir(DIR *dirp);
@@ -3222,11 +4498,13 @@ ssize_t vfswrap_read(int fd, char *data, size_t n);
ssize_t vfswrap_write(int fd, char *data, size_t n);
SMB_OFF_T vfswrap_lseek(int filedes, SMB_OFF_T offset, int whence);
int vfswrap_rename(char *old, char *new);
-void vfswrap_fsync(int fd);
+void vfswrap_sync_file(int fd);
int vfswrap_stat(char *fname, SMB_STRUCT_STAT *sbuf);
int vfswrap_fstat(int fd, SMB_STRUCT_STAT *sbuf);
int vfswrap_lstat(char *path,
SMB_STRUCT_STAT *sbuf);
+BOOL vfswrap_fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count,
+ int type);
int vfswrap_unlink(char *path);
int vfswrap_chmod(char *path, mode_t mode);
int vfswrap_utime(char *path, struct utimbuf *times);
@@ -3235,8 +4513,6 @@ int vfswrap_utime(char *path, struct utimbuf *times);
int vfs_init_default(connection_struct *conn);
BOOL vfs_init_custom(connection_struct *conn);
-BOOL vfs_directory_exist(connection_struct *conn, char *dname,
- SMB_STRUCT_STAT *st);
BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf);
ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N);
SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp,
@@ -3321,6 +4597,236 @@ int smbw_stat_printjob(struct smbw_server *srv,char *path,
int smbw_fstat(int fd, struct stat *st);
int smbw_stat(const char *fname, struct stat *st);
+/*The following definitions come from spoolssd/spoolssd.c */
+
+msrpc_service_fns *get_service_fns(void);
+
+/*The following definitions come from spoolssd/srv_spoolss_nt.c */
+
+uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
+
+ uint32 unknown0, uint32 cbbuf,
+ uint32 devmod, uint32 access_required,
+ uint32 unknown1, uint32 unknown2,
+ uint32 unknown3, uint32 unknown4,
+ uint32 unknown5, uint32 unknown6,
+ uint32 unknown7, uint32 unknown8,
+ uint32 unknown9, uint32 unknown10,
+ const UNISTR2 *station, const UNISTR2 *username,
+ POLICY_HND *handle);
+uint32 _spoolss_closeprinter(POLICY_HND *handle);
+uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename,
+ uint32 *type,
+ uint32 *size,
+ uint8 **data,
+ uint32 *numeric_data,
+ uint32 *needed);
+uint32 _spoolss_rffpcnex(const POLICY_HND *handle,
+ uint32 flags, uint32 options,
+ const UNISTR2 *localmachine,
+ uint32 printerlocal,
+ SPOOL_NOTIFY_OPTION *option);
+uint32 _spoolss_rfnpcnex( const POLICY_HND *handle,
+ uint32 change,
+ const SPOOL_NOTIFY_OPTION *option,
+ uint32 *count,
+ SPOOL_NOTIFY_INFO *info);
+uint32 _spoolss_enumprinters(
+ uint32 flags,
+ const UNISTR2 *servername,
+ uint32 level,
+ const BUFFER *buffer,
+ uint32 buf_size,
+ uint32 *offered,
+ uint32 *needed,
+ PRINTER_INFO_CTR *ctr,
+ uint32 *returned);
+uint32 _spoolss_getprinter( POLICY_HND *handle,
+ uint32 level,
+ PRINTER_INFO *ctr,
+ uint32 *offered,
+ uint32 *needed);
+uint32 _spoolss_getprinterdriver2( const POLICY_HND *handle,
+ const UNISTR2 *uni_arch,
+ uint32 level,
+ DRIVER_INFO *ctr,
+ uint32 *offered,
+ uint32 *needed);
+uint32 _spoolss_startpageprinter(const POLICY_HND *handle);
+uint32 _spoolss_endpageprinter(const POLICY_HND *handle);
+uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level,
+ DOC_INFO *docinfo, uint32 *jobid);
+uint32 _spoolss_enddocprinter(const POLICY_HND *handle);
+uint32 _spoolss_writeprinter( const POLICY_HND *handle,
+ uint32 buffer_size,
+ const uint8 *buffer,
+ uint32 *buffer_written);
+uint32 _spoolss_setprinter( const POLICY_HND *handle,
+ uint32 level,
+ const SPOOL_PRINTER_INFO_LEVEL *info,
+ const DEVICEMODE *devmode,
+ uint32 sec_buf_size,
+ const char *sec_buf,
+ uint32 command);
+uint32 _spoolss_fcpn( const POLICY_HND *handle);
+uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level,
+ const BUFFER *buffer,
+ uint32 buf_size);
+uint32 _spoolss_enumjobs( const POLICY_HND *handle,
+ uint32 reqfirstjob,
+ uint32 reqnumofjobs,
+ uint32 level,
+ JOB_INFO_CTR *ctr,
+ uint32 *buf_size,
+ uint32 *numofjobs);
+uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid);
+uint32 _spoolss_setjob( const POLICY_HND *handle,
+ uint32 jobid,
+ uint32 level,
+ JOB_INFO *ctr,
+ uint32 command);
+uint32 _spoolss_enumprinterdrivers( const UNISTR2 *name,
+ const UNISTR2 *environment,
+ uint32 level,
+ DRIVER_INFO *ctr,
+ uint32 *offered,
+ uint32 *numofdrivers);
+uint32 _spoolss_enumforms( const POLICY_HND *handle,
+ uint32 level,
+ FORM_1 **forms_1,
+ uint32 *offered,
+ uint32 *numofforms);
+uint32 _spoolss_enumports( const UNISTR2 *name,
+ uint32 level,
+ PORT_INFO_CTR *ctr,
+ uint32 *offered,
+ uint32 *numofports);
+uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name,
+ uint32 level,
+ const SPOOL_PRINTER_INFO_LEVEL *info,
+ uint32 unk0,
+ uint32 unk1,
+ uint32 unk2,
+ uint32 unk3,
+ uint32 user_level,
+ const SPOOL_USER_LEVEL *user,
+ POLICY_HND *handle);
+uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
+ uint32 level,
+ const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info);
+uint32 _spoolss_getprinterdriverdirectory( const UNISTR2 *name,
+ const UNISTR2 *uni_environment,
+ uint32 level,
+ DRIVER_DIRECTORY_CTR *ctr,
+ uint32 *offered);
+uint32 _spoolss_enumprinterdata(const POLICY_HND *handle,
+ uint32 idx,
+ uint32 *valuesize,
+ UNISTR *uni_value,
+ uint32 *realvaluesize,
+ uint32 *type,
+ uint32 *datasize,
+ uint8 **data,
+ uint32 *realdatasize);
+uint32 _spoolss_setprinterdata( const POLICY_HND *handle,
+ const UNISTR2 *value,
+ uint32 type,
+ uint32 max_len,
+ const uint8 *data,
+ uint32 real_len,
+ uint32 numeric_data);
+uint32 _spoolss_addform( const POLICY_HND *handle,
+ uint32 level,
+ const FORM *form);
+uint32 _spoolss_setform( const POLICY_HND *handle,
+ const UNISTR2 *uni_name,
+ uint32 level,
+ const FORM *form);
+uint32 _spoolss_enumprintprocessors(const UNISTR2 *name,
+ const UNISTR2 *environment,
+ uint32 level,
+ PRINTPROCESSOR_1 **info_1,
+ uint32 *offered,
+ uint32 *numofprintprocessors);
+uint32 _spoolss_enumprintmonitors( const UNISTR2 *name,
+ uint32 level,
+ PRINTMONITOR_1 **info_1,
+ uint32 *offered,
+ uint32 *numofprintmonitors);
+uint32 _spoolss_getjob( const POLICY_HND *handle,
+ uint32 jobid,
+ uint32 level,
+ PJOB_INFO *ctr,
+ uint32 *offered);
+
+/*The following definitions come from srvsvcd/srv_srvsvc_nt.c */
+
+uint32 _srv_net_remote_tod( UNISTR2 *srv_name, TIME_OF_DAY_INFO *tod );
+uint32 _srv_net_srv_get_info( UNISTR2 *srv_name, uint32 switch_value,
+ SRV_INFO_CTR *ctr);
+uint32 _srv_net_share_enum( const UNISTR2 *srv_name,
+ uint32 switch_value, SRV_SHARE_INFO_CTR *ctr,
+ uint32 preferred_len, ENUM_HND *enum_hnd,
+ uint32 *total_entries, uint32 share_level );
+uint32 _srv_net_sess_enum( const UNISTR2 *srv_name,
+ uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len, ENUM_HND *enum_hnd,
+ uint32 *total_entries, uint32 sess_level );
+uint32 _srv_net_conn_enum( const UNISTR2 *srv_name,
+ uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
+ uint32 preferred_len, ENUM_HND *enum_hnd,
+ uint32 *total_entries, uint32 conn_level );
+uint32 _srv_net_file_enum( const UNISTR2 *srv_name,
+ uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len, ENUM_HND *enum_hnd,
+ uint32 *total_entries, uint32 file_level );
+
+/*The following definitions come from srvsvcd/srvsvcd.c */
+
+msrpc_service_fns *get_service_fns(void);
+
+/*The following definitions come from svcctld/srv_svcctl_nt.c */
+
+uint32 _svc_close(POLICY_HND *pol);
+uint32 _svc_open_service(const POLICY_HND *scman_pol,
+ const UNISTR2* uni_svc_name,
+ uint32 des_access,
+ POLICY_HND *pol);
+uint32 _svc_stop_service(const POLICY_HND *pol,
+ uint32 unknown,
+ uint32 *unknown0,
+ uint32 *unknown1,
+ uint32 *unknown2,
+ uint32 *unknown3,
+ uint32 *unknown4,
+ uint32 *unknown5,
+ uint32 *unknown6);
+uint32 _svc_start_service(const POLICY_HND *pol,
+ uint32 argc,
+ uint32 argc2,
+ const UNISTR2 *argv);
+uint32 _svc_open_sc_man(const UNISTR2 *uni_srv_name,
+ const UNISTR2 *uni_db_name,
+ uint32 des_access,
+ POLICY_HND *pol);
+uint32 _svc_enum_svcs_status(const POLICY_HND *pol,
+ uint32 service_type,
+ uint32 service_state,
+ uint32 *buf_size,
+ ENUM_HND *resume_hnd,
+ ENUM_SRVC_STATUS *svcs,
+ uint32 *more_buf_size,
+ uint32 *num_svcs);
+uint32 _svc_query_disp_name(const POLICY_HND *scman_pol,
+ const UNISTR2 *uni_svc_name,
+ uint32 buf_size,
+ UNISTR2 *uni_disp_name,
+ uint32 *pbuf_size);
+
+/*The following definitions come from svcctld/svcctld.c */
+
+msrpc_service_fns *get_service_fns(void);
+
/*The following definitions come from tdb/tdb.c */
char *tdb_error(TDB_CONTEXT *tdb);
@@ -3340,22 +4846,15 @@ int tdb_writeunlock(TDB_CONTEXT *tdb);
int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key);
int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key);
-/*The following definitions come from utils/nbio.c */
+/*The following definitions come from utils/rpctorture.c */
-void nb_setup(struct cli_state *cli);
-void nb_unlink(char *fname);
-void nb_open(char *fname, int handle, int size);
-void nb_write(int handle, int size, int offset);
-void nb_read(int handle, int size, int offset);
-void nb_close(int handle);
-void nb_mkdir(char *fname);
-void nb_rmdir(char *fname);
-void nb_rename(char *old, char *new);
-void nb_stat(char *fname, int size);
-void nb_create(char *fname, int size);
+void run_enums_test(struct client_info *info, int argc, char *argv[]);
+void run_ntlogin_test(struct client_info *info, int argc, char *argv[]);
+BOOL do_random_rpc(struct cli_state *cli, uint16 nt_pipe_fnum, int max_len);
-/*The following definitions come from utils/torture.c */
+/*The following definitions come from utils/smbpasswd.c */
+int main(int argc, char **argv);
/*The following definitions come from web/cgi.c */
@@ -3389,4 +4888,27 @@ void status_page(void);
/*The following definitions come from web/swat.c */
+
+/*The following definitions come from winregd/srv_reg_nt.c */
+
+uint32 _reg_close(POLICY_HND * pol);
+uint32 _reg_open(POLICY_HND * pol, uint32 access_mask);
+uint32 _reg_open_entry(const POLICY_HND * pol, const UNISTR2 * uni_name,
+ uint32 unknown_0, uint32 access_mask,
+ POLICY_HND * entry_pol);
+uint32 _reg_info(POLICY_HND* pol, BUFFER2* buf, uint32* type);
+BOOL api_reg_rpc(rpcsrv_struct * p);
+
+/*The following definitions come from winregd/winregd.c */
+
+msrpc_service_fns *get_service_fns(void);
+
+/*The following definitions come from wkssvcd/srv_wkssvc_nt.c */
+
+uint32 _wks_query_info( const UNISTR2 *srv_name, uint16 switch_value,
+ WKS_INFO_100 *wks100);
+
+/*The following definitions come from wkssvcd/wkssvcd.c */
+
+msrpc_service_fns *get_service_fns(void);
#endif /* _PROTO_H_ */
diff --git a/source/include/rpc_atsvc.h b/source/include/rpc_atsvc.h
new file mode 100644
index 00000000000..2b983f438e5
--- /dev/null
+++ b/source/include/rpc_atsvc.h
@@ -0,0 +1,155 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Interface header: Scheduler service
+ Copyright (C) Matthew Chapman 1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+ Copyright (C) Andrew Tridgell 1992-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_ATSVC_H
+#define _RPC_ATSVC_H
+
+#define AT_ADD_JOB 0x00
+#define AT_DEL_JOB 0x01
+#define AT_ENUM_JOBS 0x02
+#define AT_QUERY_JOB 0x03
+
+
+#define JOB_PERIODIC 0x01
+#define JOB_EXEC_ERR 0x02
+#define JOB_RUNS_TODAY 0x04
+#define JOB_INCLUDE_TODAY 0x08
+#define JOB_NONINTERACTIVE 0x10
+
+/* AT_JOB_INFO */
+typedef struct at_job_info_info
+{
+ uint32 time; /* milliseconds after midnight */
+ uint32 monthdays; /* bitmask of days of month */
+ uint8 weekdays; /* bitmask of days of week */
+ uint8 flags; /* JOB_xx */
+
+ uint32 ptr_command;
+
+} AT_JOB_INFO;
+
+/* AT_Q_ADD_JOB */
+typedef struct q_at_add_job_info
+{
+ uint32 ptr_srv_name;
+ UNISTR2 uni_srv_name;
+
+ AT_JOB_INFO info;
+ UNISTR2 command;
+
+} AT_Q_ADD_JOB;
+
+/* AT_R_ADD_JOB */
+typedef struct r_at_add_job_info
+{
+ uint32 jobid;
+ uint32 status;
+
+} AT_R_ADD_JOB;
+
+
+/* AT_Q_DEL_JOB */
+typedef struct q_at_del_job_info
+{
+ uint32 ptr_srv_name;
+ UNISTR2 uni_srv_name;
+
+ uint32 min_jobid;
+ uint32 max_jobid;
+
+} AT_Q_DEL_JOB;
+
+/* AT_R_DEL_JOB */
+typedef struct r_at_del_job_info
+{
+ uint32 status;
+
+} AT_R_DEL_JOB;
+
+
+/* AT_Q_ENUM_JOBS */
+typedef struct q_at_enum_jobs_info
+{
+ uint32 ptr_srv_name;
+ UNISTR2 uni_srv_name;
+
+ uint32 unknown0; /* 0 */
+ uint32 unknown1; /* 0 */
+ uint32 max_len; /* preferred max length */
+
+ uint32 ptr_resume;
+ uint32 hnd_resume; /* resume handle */
+
+} AT_Q_ENUM_JOBS;
+
+/* AT_ENUM_INFO */
+typedef struct q_at_enum_info_info
+{
+ uint32 jobid;
+ AT_JOB_INFO info;
+
+} AT_ENUM_INFO;
+
+#define AT_MAX_JOBS 256
+
+/* AT_R_ENUM_JOBS */
+typedef struct r_at_enum_jobs_info
+{
+ uint32 num_entries; /* entries returned */
+ uint32 ptr_entries;
+ uint32 num_entries2;
+
+ AT_ENUM_INFO info[AT_MAX_JOBS];
+ UNISTR2 command[AT_MAX_JOBS];
+
+ uint32 total_entries; /* total entries */
+ uint32 ptr_resume;
+ uint32 hnd_resume; /* resume handle */
+
+ uint32 status;
+
+} AT_R_ENUM_JOBS;
+
+
+/* AT_Q_QUERY_JOB */
+typedef struct q_at_query_job_info
+{
+ uint32 ptr_srv_name;
+ UNISTR2 uni_srv_name;
+
+ uint32 jobid;
+
+} AT_Q_QUERY_JOB;
+
+/* AT_R_QUERY_JOB */
+typedef struct r_at_query_job_info
+{
+ uint32 ptr_info;
+ AT_JOB_INFO info;
+ UNISTR2 command;
+
+ uint32 status;
+
+} AT_R_QUERY_JOB;
+
+#endif /* _RPC_ATSVC_H */
diff --git a/source/include/rpc_brs.h b/source/include/rpc_brs.h
new file mode 100644
index 00000000000..36d89ec151c
--- /dev/null
+++ b/source/include/rpc_brs.h
@@ -0,0 +1,81 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_BRS_H /* _RPC_BRS_H */
+#define _RPC_BRS_H
+
+
+/* brssvc pipe */
+#define BRS_QUERY_INFO 0x02
+
+
+/* BRS_Q_QUERY_INFO - probably a capabilities request */
+typedef struct q_brs_query_info_info
+{
+ uint32 ptr_srv_name; /* pointer (to server name?) */
+ UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */
+
+ uint16 switch_value1; /* info level 100 (0x64) */
+ /* align */
+ uint16 switch_value2; /* info level 100 (0x64) */
+
+ uint32 ptr;
+ uint32 pad1;
+ uint32 pad2;
+
+} BRS_Q_QUERY_INFO;
+
+
+/* BRS_INFO_100 - level 100 info */
+typedef struct brs_info_100_info
+{
+ uint32 pad1;
+ uint32 ptr2;
+ uint32 pad2;
+ uint32 pad3;
+
+} BRS_INFO_100;
+
+
+/* BRS_R_QUERY_INFO - probably a capabilities request */
+typedef struct r_brs_query_info_info
+{
+ uint16 switch_value1; /* 100 (0x64) - switch value */
+ /* align */
+ uint16 switch_value2; /* info level 100 (0x64) */
+
+ /* for now, only level 100 is supported. this should be an enum container */
+ uint32 ptr_1; /* pointer 1 */
+
+ union
+ {
+ BRS_INFO_100 *brs100; /* browser info level 100 */
+ void *id;
+
+ } info;
+
+ uint32 status; /* return status */
+
+} BRS_R_QUERY_INFO;
+
+#endif /* _RPC_BRS_H */
+
diff --git a/source/include/rpc_client_proto.h b/source/include/rpc_client_proto.h
new file mode 100644
index 00000000000..140801c0475
--- /dev/null
+++ b/source/include/rpc_client_proto.h
@@ -0,0 +1,721 @@
+#ifndef _RPC_CLIENT_PROTO_H_
+#define _RPC_CLIENT_PROTO_H_
+/* This file is automatically generated with "make proto". DO NOT EDIT */
+
+
+/*The following definitions come from rpc_client/cli_atsvc.c */
+
+BOOL at_add_job(
+ char *srv_name, AT_JOB_INFO *info, char *command,
+ uint32 *jobid);
+BOOL at_del_job( char *srv_name, uint32 min_jobid, uint32 max_jobid);
+BOOL at_enum_jobs( char *srv_name, uint32 *num_jobs,
+ AT_ENUM_INFO *jobs, char ***commands);
+BOOL at_query_job(char *srv_name,
+ uint32 jobid, AT_JOB_INFO *job, fstring command);
+
+/*The following definitions come from rpc_client/cli_brs.c */
+
+BOOL brs_query_info( const char *srv_name, uint32 switch_value,
+ void *id);
+
+/*The following definitions come from rpc_client/cli_connect.c */
+
+void init_connections(void);
+void free_connections(void);
+void cli_connection_free(struct cli_connection *con);
+void cli_connection_unlink(struct cli_connection *con);
+BOOL cli_connection_init(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con);
+BOOL cli_connection_init_auth(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con,
+ cli_auth_fns * auth, void *auth_creds);
+BOOL cli_connection_getsrv(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con);
+BOOL cli_connection_get(const POLICY_HND * pol, struct cli_connection **con);
+BOOL cli_pol_link(POLICY_HND * to, const POLICY_HND * from);
+BOOL cli_get_usr_sesskey(const POLICY_HND * pol, uchar usr_sess_key[16]);
+BOOL cli_set_con_usr_sesskey(struct cli_connection *con,
+ const uchar usr_sess_key[16]);
+const vuser_key *cli_con_sec_ctx(struct cli_connection *con);
+struct cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con);
+void *cli_conn_get_auth_creds(struct cli_connection *con);
+void *cli_conn_get_auth_info(struct cli_connection *con);
+BOOL cli_conn_set_auth_info(struct cli_connection *con, void *auth_info);
+struct ntdom_info *cli_conn_get_ntinfo(struct cli_connection *con);
+BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16]);
+BOOL cli_con_get_srvname(struct cli_connection *con, char *srv_name);
+BOOL cli_get_sesskey(const POLICY_HND * pol, uchar sess_key[16]);
+BOOL cli_get_sesskey_srv(const char *srv_name, uchar sess_key[16]);
+void cli_con_gen_next_creds(struct cli_connection *con,
+ DOM_CRED * new_clnt_cred);
+void cli_con_get_cli_cred(struct cli_connection *con, DOM_CRED * clnt_cred);
+BOOL cli_con_deal_with_creds(struct cli_connection *con,
+ DOM_CRED * rcv_srv_cred);
+BOOL cli_con_set_creds(const char *srv_name, const uchar sess_key[16],
+ DOM_CRED * cred);
+BOOL rpc_hnd_pipe_req(const POLICY_HND * hnd, uint8 op_num,
+ prs_struct * data, prs_struct * rdata);
+BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
+ prs_struct * data, prs_struct * rdata);
+BOOL rpc_api_write(struct cli_connection *con, prs_struct * data);
+BOOL rpc_api_rcv_pdu(struct cli_connection *con, prs_struct * rdata);
+BOOL rpc_api_send_rcv_pdu(struct cli_connection *con, prs_struct * data,
+ prs_struct * rdata);
+BOOL set_policy_con(struct policy_cache *cache, POLICY_HND * hnd,
+ struct cli_connection *con,
+ void (*free_fn) (struct cli_connection *));
+BOOL get_policy_con(struct policy_cache *cache, const POLICY_HND * hnd,
+ struct cli_connection **con);
+
+/*The following definitions come from rpc_client/cli_eventlog.c */
+
+BOOL event_open(const char* srv_name, const char *log, POLICY_HND *hnd);
+BOOL event_close( POLICY_HND *hnd);
+BOOL event_numofeventlogrec( POLICY_HND *hnd, uint32 *number);
+BOOL event_readeventlog(POLICY_HND *hnd,
+ uint32 number, uint32 flags, uint32 offset,
+ uint32 *number_of_bytes, EVENTLOGRECORD *ev);
+
+/*The following definitions come from rpc_client/cli_login.c */
+
+uint32 cli_nt_setup_creds(const char *srv_name,
+ const char *domain,
+ const char *myhostname,
+ const char *trust_acct,
+ const uchar trust_pwd[16], uint16 sec_chan);
+BOOL cli_nt_srv_pwset(const char *srv_name, const char *myhostname,
+ const char *trust_acct,
+ const uchar * new_hashof_trust_pwd, uint16 sec_chan);
+BOOL cli_nt_login_general(const char *srv_name, const char *myhostname,
+ const char *domain, const char *username,
+ uint32 luid_low,
+ const char *general,
+ NET_ID_INFO_CTR * ctr, NET_USER_INFO_3 * user_info3);
+BOOL cli_nt_login_interactive(const char *srv_name, const char *myhostname,
+ const char *domain, const char *username,
+ uint32 luid_low,
+ const uchar * lm_owf_user_pwd,
+ const uchar * nt_owf_user_pwd,
+ NET_ID_INFO_CTR * ctr,
+ NET_USER_INFO_3 * user_info3);
+BOOL cli_nt_login_network(const char *srv_name, const char *myhostname,
+ const char *domain, const char *username,
+ uint32 luid_low, const char lm_chal[8],
+ const char *lm_chal_resp,
+ int lm_chal_len,
+ const char *nt_chal_resp,
+ int nt_chal_len,
+ NET_ID_INFO_CTR * ctr, NET_USER_INFO_3 * user_info3);
+BOOL cli_nt_logoff(const char *srv_name, const char *myhostname,
+ NET_ID_INFO_CTR * ctr);
+BOOL net_sam_sync(const char *srv_name,
+ const char *domain,
+ const char *myhostname,
+ const char *trust_acct,
+ uchar trust_passwd[16],
+ SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS],
+ SAM_DELTA_CTR deltas[MAX_SAM_DELTAS], uint32 * num_deltas);
+
+/*The following definitions come from rpc_client/cli_lsarpc.c */
+
+BOOL get_domain_sids(const char *domain, DOM_SID * sid3, DOM_SID * sid5);
+BOOL get_trust_sid_and_domain(const char *myname, char *server,
+ DOM_SID * sid, char *domain, size_t len);
+BOOL lsa_open_policy(const char *system_name, POLICY_HND *hnd,
+ BOOL sec_qos, uint32 des_access);
+BOOL lsa_open_policy2(const char *system_name, POLICY_HND *hnd,
+ BOOL sec_qos, uint32 des_access);
+BOOL lsa_create_secret(const POLICY_HND *hnd,
+ const char *secret_name,
+ uint32 des_access, POLICY_HND *hnd_secret);
+BOOL lsa_open_secret(const POLICY_HND *hnd,
+ const char *secret_name,
+ uint32 des_access, POLICY_HND *hnd_secret);
+uint32 lsa_set_secret(POLICY_HND *hnd, const STRING2 * secret);
+BOOL lsa_query_secret(POLICY_HND *hnd, STRING2 * secret, NTTIME * last_update);
+BOOL lsa_lookup_names(POLICY_HND *hnd,
+ int num_names,
+ char **names,
+ DOM_SID ** sids, uint32 ** types, int *num_sids);
+BOOL lsa_lookup_sids(POLICY_HND *hnd,
+ int num_sids,
+ DOM_SID ** sids,
+ char ***names, uint32 ** types, int *num_names);
+BOOL lsa_query_sec_obj(const POLICY_HND *hnd, uint32 sec_info,
+ SEC_DESC_BUF *sec_buf);
+BOOL lsa_query_info_pol(POLICY_HND *hnd, uint16 info_class,
+ fstring domain_name, DOM_SID * domain_sid);
+BOOL lsa_enum_trust_dom(POLICY_HND *hnd, uint32 * enum_ctx,
+ uint32 * num_doms, char ***names, DOM_SID *** sids);
+BOOL lsa_close(POLICY_HND *hnd);
+
+/*The following definitions come from rpc_client/cli_netlogon.c */
+
+void gen_next_creds( struct ntdom_info *nt, DOM_CRED *new_clnt_cred);
+BOOL cli_net_logon_ctrl2(const char* srv_name, uint32 status_level);
+uint32 cli_net_auth2(const char *srv_name,
+ const char *trust_acct,
+ const char *acct_name,
+ uint16 sec_chan,
+ uint32 *neg_flags, DOM_CHAL *srv_chal);
+uint32 cli_net_req_chal( const char *srv_name, const char* myhostname,
+ DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
+BOOL cli_net_srv_pwset(const char* srv_name,
+ const char* myhostname,
+ const char* trust_acct,
+ const uint8 hashed_trust_pwd[16],
+ uint16 sec_chan_type);
+uint32 cli_net_sam_logon(const char* srv_name, const char* myhostname,
+ NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3);
+BOOL cli_net_sam_logoff(const char* srv_name, const char* myhostname,
+ NET_ID_INFO_CTR *ctr);
+BOOL cli_net_sam_sync( const char* srv_name, const char* myhostname,
+ uint32 database_id,
+ uint32 *num_deltas,
+ SAM_DELTA_HDR *hdr_deltas,
+ SAM_DELTA_CTR *deltas);
+
+/*The following definitions come from rpc_client/cli_pipe.c */
+
+BOOL create_rpc_request(prs_struct * rhdr, uint16 vuid,
+ uint8 op_num, uint8 flags, int data_len, int auth_len);
+BOOL rpc_api_pipe_req(struct cli_connection *con, uint8 opnum,
+ prs_struct * data, prs_struct * rdata);
+BOOL cli_send_and_rcv_pdu_trans(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu);
+BOOL cli_send_and_rcv_pdu_rw(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu);
+BOOL cli_send_and_rcv_pdu(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu);
+BOOL cli_rcv_pdu(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum, prs_struct *rdata);
+BOOL rpc_pipe_bind(struct cli_connection *con,
+ const char *pipe_name,
+ RPC_IFACE * abstract, RPC_IFACE * transfer);
+void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs);
+BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name,
+ uint16 * fnum);
+void cli_nt_session_close(struct cli_state *cli, uint16 fnum);
+
+/*The following definitions come from rpc_client/cli_pipe_netsec.c */
+
+
+/*The following definitions come from rpc_client/cli_pipe_noauth.c */
+
+
+/*The following definitions come from rpc_client/cli_pipe_ntlmssp.c */
+
+
+/*The following definitions come from rpc_client/cli_reg.c */
+
+BOOL reg_connect( const char* srv_name,
+ const char *full_keyname,
+ char *key_name,
+ uint32 access_mask,
+ POLICY_HND *reg_hnd);
+BOOL reg_open_hkcr( struct cli_connection *con,
+ uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd);
+BOOL reg_open_hklm( struct cli_connection *con,
+ uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd);
+BOOL reg_open_hku( struct cli_connection *con,
+ uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd);
+BOOL reg_flush_key( POLICY_HND *hnd);
+BOOL reg_query_key( POLICY_HND *hnd,
+ char *key_class, uint32 *class_len,
+ uint32 *num_subkeys, uint32 *max_subkeylen,
+ uint32 *max_subkeysize, uint32 *num_values,
+ uint32 *max_valnamelen, uint32 *max_valbufsize,
+ uint32 *sec_desc, NTTIME *mod_time);
+BOOL reg_unknown_1a( POLICY_HND *hnd, uint32 *unk);
+BOOL reg_query_info( POLICY_HND *hnd,
+ const char* val_name,
+ uint32 *type, BUFFER2 *buffer);
+BOOL reg_set_key_sec( POLICY_HND *hnd,
+ uint32 sec_info,
+ uint32 sec_buf_size, SEC_DESC *sec_buf);
+BOOL reg_get_key_sec( POLICY_HND *hnd,
+ uint32 sec_info,
+ uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf);
+BOOL reg_delete_val( POLICY_HND *hnd, char *val_name);
+BOOL reg_delete_key( POLICY_HND *hnd, char *key_name);
+BOOL reg_create_key( POLICY_HND *hnd,
+ char *key_name, char *key_class,
+ SEC_ACCESS *sam_access,
+ POLICY_HND *key);
+BOOL reg_enum_key( POLICY_HND *hnd,
+ int key_index, char *key_name,
+ uint32 *unk_1, uint32 *unk_2,
+ time_t *mod_time);
+BOOL reg_create_val( POLICY_HND *hnd,
+ char *val_name, uint32 type, BUFFER3 *data);
+BOOL reg_enum_val( POLICY_HND *hnd,
+ int val_index, int max_valnamelen, int max_valbufsize,
+ fstring val_name,
+ uint32 *val_type, BUFFER2 *value);
+BOOL reg_open_entry( POLICY_HND *hnd,
+ char *key_name, uint32 unk_0,
+ POLICY_HND *key_hnd);
+BOOL reg_close( POLICY_HND *hnd);
+BOOL reg_shutdown(const char *srv_name,
+ const char *msg, uint32 timeout, uint16 flags);
+
+/*The following definitions come from rpc_client/cli_samr.c */
+
+BOOL samr_chgpasswd_user( struct cli_connection *con,
+ const char *srv_name, const char *user_name,
+ const char nt_newpass[516], const uchar nt_oldhash[16],
+ const char lm_newpass[516], const uchar lm_oldhash[16]);
+BOOL samr_get_dom_pwinfo(struct cli_connection *con, const char *srv_name);
+BOOL samr_query_dom_info( POLICY_HND *domain_pol, uint16 switch_value,
+ SAM_UNK_CTR *ctr);
+uint32 samr_enum_domains( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_domains);
+uint32 samr_enum_dom_groups( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_groups);
+uint32 samr_enum_dom_aliases( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_aliases);
+uint32 samr_enum_dom_users( POLICY_HND *pol, uint32 *start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_users);
+BOOL samr_connect( const char *srv_name, uint32 access_mask,
+ POLICY_HND *connect_pol);
+BOOL samr_query_sec_obj( const POLICY_HND *pol,
+ uint32 type,
+ SEC_DESC_BUF *buf);
+BOOL samr_open_user( const POLICY_HND *pol,
+ uint32 unk_0, uint32 rid,
+ POLICY_HND *user_pol);
+BOOL samr_open_alias( const POLICY_HND *domain_pol,
+ uint32 flags, uint32 rid,
+ POLICY_HND *alias_pol);
+BOOL samr_del_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid);
+BOOL samr_add_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid);
+BOOL samr_delete_dom_alias( POLICY_HND *alias_pol);
+uint32 samr_create_dom_user( POLICY_HND *domain_pol, const char *acct_name,
+ uint32 unk_0, uint32 unk_1,
+ POLICY_HND *user_pol, uint32 *rid);
+BOOL samr_create_dom_alias( POLICY_HND *domain_pol, const char *acct_name,
+ POLICY_HND *alias_pol, uint32 *rid);
+BOOL samr_query_aliasinfo( POLICY_HND *alias_pol, uint16 switch_value,
+ ALIAS_INFO_CTR *ctr);
+BOOL samr_set_aliasinfo( POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr);
+BOOL samr_open_group( const POLICY_HND *domain_pol,
+ uint32 flags, uint32 rid,
+ POLICY_HND *group_pol);
+BOOL samr_del_groupmem( POLICY_HND *group_pol, uint32 rid);
+BOOL samr_add_groupmem( POLICY_HND *group_pol, uint32 rid);
+BOOL samr_delete_dom_user( POLICY_HND *user_pol);
+BOOL samr_delete_dom_group( POLICY_HND *group_pol);
+BOOL samr_create_dom_group( POLICY_HND *domain_pol, const char *acct_name,
+ POLICY_HND *group_pol, uint32 *rid);
+BOOL samr_set_groupinfo( POLICY_HND *group_pol, GROUP_INFO_CTR *ctr);
+BOOL samr_unknown_2d( const POLICY_HND *domain_pol,
+ const DOM_SID *sid);
+BOOL samr_open_domain( const POLICY_HND *connect_pol,
+ uint32 ace_perms,
+ const DOM_SID *sid,
+ POLICY_HND *domain_pol);
+BOOL samr_query_lookup_domain( POLICY_HND *pol, const char *dom_name,
+ DOM_SID *dom_sid);
+BOOL samr_query_lookup_names(const POLICY_HND *pol, uint32 flags,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids, uint32 **types);
+BOOL samr_query_lookup_rids( const POLICY_HND *pol, uint32 flags,
+ uint32 num_rids, const uint32 *rids,
+ uint32 *num_names,
+ char ***names,
+ uint32 **type);
+BOOL samr_query_aliasmem( const POLICY_HND *alias_pol,
+ uint32 *num_mem, DOM_SID2 *sid);
+BOOL samr_query_useraliases( const POLICY_HND *pol,
+ uint32 *ptr_sid, DOM_SID2 *sid,
+ uint32 *num_aliases, uint32 **rid);
+BOOL samr_query_groupmem( POLICY_HND *group_pol,
+ uint32 *num_mem, uint32 **rid, uint32 **attr);
+BOOL samr_query_usergroups( POLICY_HND *pol, uint32 *num_groups,
+ DOM_GID **gid);
+BOOL samr_query_groupinfo( POLICY_HND *pol,
+ uint16 switch_value, GROUP_INFO_CTR* ctr);
+BOOL samr_set_userinfo2( POLICY_HND *pol, uint16 switch_value,
+ void* usr);
+BOOL samr_set_userinfo( POLICY_HND *pol, uint16 switch_value, void* usr);
+BOOL samr_query_userinfo( POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+BOOL samr_close( POLICY_HND *hnd);
+BOOL samr_query_dispinfo( POLICY_HND *pol_domain, uint16 level,
+ uint32 *num_entries,
+ SAM_DISPINFO_CTR *ctr);
+
+/*The following definitions come from rpc_client/cli_spoolss.c */
+
+BOOL spoolss_enum_printers(uint32 flags, const char *srv_name,
+ uint32 level,
+ uint32 *count,
+ void ***printers);
+uint32 spoolss_enum_jobs( const POLICY_HND *hnd,
+ uint32 firstjob,
+ uint32 numofjobs,
+ uint32 level,
+ uint32 *buf_size,
+ uint32 *count,
+ void ***jobs);
+BOOL spoolss_open_printer_ex( const char *printername,
+ uint32 cbbuf, uint32 devmod, uint32 des_access,
+ const char *station, const char *username,
+ POLICY_HND *hnd);
+BOOL spoolss_closeprinter(POLICY_HND *hnd);
+
+/*The following definitions come from rpc_client/cli_srvsvc.c */
+
+BOOL srv_net_srv_tprt_enum(
+ const char *srv_name,
+ uint32 switch_value, SRV_TPRT_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_net_srv_conn_enum( char *srv_name, char *qual_name,
+ uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_net_srv_sess_enum( char *srv_name, char *qual_name, char *user_name,
+ uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_net_srv_share_enum( char *srv_name,
+ uint32 switch_value, SRV_SHARE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_net_srv_share_get_info(const char *srv_name,
+ const char *share_name,
+ uint32 info_level);
+BOOL srv_net_srv_file_enum( char *srv_name, char *qual_name, uint32 file_id,
+ uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_net_srv_get_info( char *srv_name, uint32 switch_value,
+ SRV_INFO_CTR *ctr);
+BOOL srv_net_remote_tod( char *srv_name, TIME_OF_DAY_INFO *tod);
+
+/*The following definitions come from rpc_client/cli_svcctl.c */
+
+BOOL svc_open_sc_man( const char *srv_name, char *db_name,
+ uint32 des_access,
+ POLICY_HND *hnd);
+BOOL svc_open_service( POLICY_HND *scm_hnd,
+ const char *srv_name,
+ uint32 des_access,
+ POLICY_HND *hnd);
+BOOL svc_enum_svcs( POLICY_HND *hnd,
+ uint32 services_type, uint32 services_state,
+ uint32 *buf_size, uint32 *resume_hnd,
+ uint32 *dos_error,
+ ENUM_SRVC_STATUS **svcs, uint32 *num_svcs);
+BOOL svc_stop_service( POLICY_HND *hnd,
+ uint32 unknown);
+BOOL svc_start_service( POLICY_HND *hnd,
+ uint32 argc,
+ char **argv);
+BOOL svc_query_svc_cfg( POLICY_HND *hnd,
+ QUERY_SERVICE_CONFIG *cfg,
+ uint32 *buf_size);
+BOOL svc_close(POLICY_HND *hnd);
+BOOL svc_change_svc_cfg( POLICY_HND *hnd,
+ uint32 service_type, uint32 start_type,
+ uint32 unknown_0,
+ uint32 error_control,
+ char* bin_path_name, char* load_order_grp,
+ uint32 tag_id,
+ char* dependencies, char* service_start_name,
+ char* password,
+ char* disp_name);
+
+/*The following definitions come from rpc_client/cli_use.c */
+
+void init_cli_use(void);
+void free_cli_use(void);
+struct cli_state *cli_net_use_add(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL redir, BOOL reuse, BOOL *is_new);
+BOOL cli_net_use_del(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL force_close, BOOL *connection_closed);
+void cli_net_use_enum(uint32 * num_cons, struct use_info ***use);
+void cli_use_wait_keyboard(void);
+
+/*The following definitions come from rpc_client/cli_wkssvc.c */
+
+BOOL wks_query_info( char *srv_name, uint32 switch_value,
+ WKS_INFO_100 *wks100);
+
+/*The following definitions come from rpc_client/msrpc_lsarpc.c */
+
+uint32 lookup_lsa_names(const char *srv_name,
+ uint32 num_names, char **names,
+ uint32 * num_sids, DOM_SID ** sids, uint32 ** types);
+uint32 lookup_lsa_name(const char *domain,
+ char *name, DOM_SID * sid, uint32 * type);
+uint32 lookup_lsa_sid(const char *domain,
+ DOM_SID * sid, char *name, uint32 * type);
+BOOL msrpc_lsa_create_secret(const char *srv_name, const char *secret_name,
+ uint32 access_rights);
+void secret_store_data(STRING2 * secret, const char* data, int len);
+void secret_store_data2(STRING2 * secret, const char* data, int len);
+BOOL msrpc_lsa_set_secret(const char *srv_name,
+ const char *secret_name, const char *data, int len);
+BOOL msrpc_lsa_query_secret(const char *srv_name,
+ const char *secret_name,
+ STRING2 * secret, NTTIME * last_update);
+BOOL secret_get_data(const STRING2 *secret, uchar *data, uint32 *len);
+BOOL msrpc_lsa_query_trust_passwd(const char *srv_name,
+ const char *secret_name,
+ uchar trust_passwd[16],
+ NTTIME * last_update);
+
+/*The following definitions come from rpc_client/msrpc_netlogon.c */
+
+BOOL modify_trust_password(const char *domain, const char *srv_name,
+ const uchar orig_trust_passwd_hash[16],
+ const uchar new_trust_passwd_hash[16],
+ uint16 sec_chan);
+uint32 check_domain_security(const char *orig_user, const char *domain,
+ const uchar * challenge,
+ const char *smb_apasswd, int smb_apasslen,
+ const char *smb_ntpasswd, int smb_ntpasslen,
+ NET_USER_INFO_3 * info3);
+
+/*The following definitions come from rpc_client/msrpc_samr.c */
+
+uint32 lookup_sam_domainname(const char *srv_name,
+ const char *domain, DOM_SID *sid);
+uint32 lookup_sam_names(const char *domain, const DOM_SID *sid,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids, uint32 **types);
+uint32 lookup_sam_name(const char *domain, DOM_SID *sid,
+ char *name, uint32 *rid, uint32 *type);
+uint32 lookup_sam_rid(const char *domain, DOM_SID *sid,
+ uint32 rid, char *name, uint32 *type);
+BOOL req_user_info( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid, uint16 info_level,
+ USER_INFO_FN(usr_inf));
+uint32 sam_query_usergroups( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid,
+ const char *user_name,
+ uint32 *num_groups,
+ DOM_GID **gid,
+ char ***name,
+ uint32 **type,
+ USER_MEM_FN(usr_mem));
+void msrpc_sam_user( const POLICY_HND *pol_dom, const POLICY_HND *pol_blt,
+ const char* domain,
+ const DOM_SID *sid1,
+ const DOM_SID *blt_sid1,
+ uint32 user_rid, uint16 info_level,
+ char *user_name,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn));
+BOOL msrpc_sam_query_user( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid,
+ char *user_name,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn));
+int msrpc_sam_enum_users( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn));
+BOOL sam_query_dominfo(const char* srv_name,
+ const DOM_SID *sid1,
+ uint32 switch_value, SAM_UNK_CTR *ctr);
+BOOL query_aliasinfo( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ ALIAS_INFO_FN(grp_inf));
+BOOL sam_query_aliasmem(const char *srv_name,
+ const POLICY_HND *pol_dom,
+ uint32 alias_rid,
+ uint32 *num_names,
+ DOM_SID ***sids,
+ char ***name,
+ uint32 **type);
+BOOL req_aliasmem_info(const char* srv_name,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ const char *alias_name,
+ ALIAS_MEM_FN(als_mem));
+BOOL sam_query_groupmem( const POLICY_HND *pol_dom,
+ uint32 group_rid,
+ uint32 *num_names,
+ uint32 **rid_mem,
+ char ***name,
+ uint32 **type);
+BOOL query_groupinfo( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ GROUP_INFO_FN(grp_inf));
+BOOL req_groupmem_info( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ const char *group_name,
+ GROUP_MEM_FN(grp_mem));
+uint32 msrpc_sam_get_first_domain( const char* srv_name,
+ char *dom_name,
+ DOM_SID *dom_sid);
+uint32 msrpc_sam_enum_domains( const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ DOMAIN_FN(dom_fn),
+ DOMAIN_INFO_FN(dom_inf_fn));
+uint32 msrpc_sam_enum_groups( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ GROUP_FN(grp_fn),
+ GROUP_INFO_FN(grp_inf_fn),
+ GROUP_MEM_FN(grp_mem_fn));
+uint32 msrpc_sam_enum_aliases( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ ALIAS_FN(als_fn),
+ ALIAS_INFO_FN(als_inf_fn),
+ ALIAS_MEM_FN(als_mem_fn));
+BOOL create_samr_domain_user( POLICY_HND *pol_dom,
+ char *acct_name, uint16 acb_info,
+ const char* password, int plen,
+ uint32 *rid);
+BOOL create_samr_domain_alias( POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid);
+BOOL create_samr_domain_group( POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid);
+BOOL get_samr_query_usergroups( const POLICY_HND *pol_open_domain,
+ uint32 user_rid,
+ uint32 *num_groups, DOM_GID **gid);
+BOOL delete_samr_dom_group( POLICY_HND *pol_open_domain,
+ uint32 group_rid);
+BOOL get_samr_query_groupmem(
+ const POLICY_HND *pol_open_domain,
+ uint32 group_rid, uint32 *num_mem,
+ uint32 **rid, uint32 **attr);
+BOOL delete_samr_dom_alias(
+ POLICY_HND *pol_open_domain,
+ uint32 alias_rid);
+BOOL get_samr_query_aliasmem(
+ const POLICY_HND *pol_open_domain,
+ uint32 alias_rid, uint32 *num_mem, DOM_SID2 *sid);
+BOOL set_samr_set_userinfo2(
+ POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, void *usr);
+BOOL set_samr_set_userinfo( const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, void *usr);
+BOOL get_samr_query_userinfo( const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, SAM_USERINFO_CTR *ctr);
+BOOL get_samr_query_groupinfo(
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 group_rid, GROUP_INFO_CTR *ctr);
+BOOL get_samr_query_aliasinfo(
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 alias_rid, ALIAS_INFO_CTR *ctr);
+BOOL msrpc_sam_create_dom_user(const char* srv_name, DOM_SID *sid1,
+ char *acct_name, uint16 acb_info,
+ const char *password, int plen,
+ uint32 *rid);
+BOOL msrpc_sam_query_dispinfo(const char* srv_name, const char* domain,
+ DOM_SID *sid1,
+ uint16 switch_value,
+ uint32 *num_entries, SAM_DISPINFO_CTR *ctr,
+ DISP_FN(disp_fn));
+BOOL msrpc_sam_ntchange_pwd(const char* srv_name,
+ const char* domain,
+ const char *ntuser,
+ const uchar lm_oldhash[16],
+ const uchar nt_oldhash[16],
+ const char* new_passwd);
+BOOL msrpc_sam_ntpasswd_set(const char* srv_name, const char *user,
+ struct ntuser_creds *samr_creds,
+ const uchar lm_newpass[516],
+ const uchar lm_hshhash[16],
+ const uchar nt_newpass[516],
+ const uchar nt_hshhash[16]);
+BOOL msrpc_sam_query_userinfo(const char* srv_name, const DOM_SID *sid,
+ const char *user_name, uint16 info_level,
+ SAM_USERINFO_CTR *ctr);
+
+/*The following definitions come from rpc_client/ncacn_np_use.c */
+
+BOOL ncacn_np_establish_connection(struct ncacn_np *cli,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ const char *pipe_name, BOOL redir,
+ BOOL reuse);
+void init_ncacn_np_use(void);
+void free_ncacn_np_use(void);
+struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
+ const vuser_key * key);
+struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
+ const vuser_key * key,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ BOOL redir,
+ BOOL reuse, BOOL *is_new_connection);
+BOOL ncacn_np_use_del(const char *pipe_name,
+ const vuser_key * key,
+ BOOL force_close, BOOL *connection_closed);
+void ncacn_np_use_enum(uint32 * num_cons, struct use_info ***use);
+
+/*The following definitions come from rpc_client/ncalrpc_l_use.c */
+
+void init_ncalrpc_use(void);
+void free_ncalrpc_use(void);
+struct msrpc_local *ncalrpc_l_use_add(const char *pipe_name,
+ const vuser_key * key,
+ BOOL redir, BOOL reuse, BOOL *is_new);
+BOOL ncalrpc_l_use_del(const char *pipe_name,
+ const vuser_key * key,
+ BOOL force_close, BOOL *connection_closed);
+void ncalrpc_l_use_enum(uint32 * num_cons, struct use_info ***use);
+void ncalrpc_use_wait_keyboard(void);
+#endif /* _RPC_CLIENT_PROTO_H_ */
diff --git a/source/include/rpc_creds.h b/source/include/rpc_creds.h
index 3247e1efdff..2b897da6791 100644
--- a/source/include/rpc_creds.h
+++ b/source/include/rpc_creds.h
@@ -38,7 +38,7 @@ typedef struct unixuser_creds
fstring user_name;
fstring requested_name;
fstring real_name;
- BOOL guest;
+ uint32 guest;
} CREDS_UNIX;
@@ -46,19 +46,11 @@ typedef struct unixsec_creds
{
uint32 uid;
uint32 gid;
- int num_grps;
+ uint32 num_grps;
uint32 *grps;
} CREDS_UNIX_SEC;
-typedef struct ntsec_creds
-{
- DOM_SID sid;
- uint32 num_grps;
- uint32 *grp_rids;
-
-} CREDS_NT_SEC;
-
typedef struct user_creds
{
BOOL reuse;
@@ -67,23 +59,28 @@ typedef struct user_creds
uint32 ptr_uxc;
uint32 ptr_nts;
uint32 ptr_uxs;
- uint32 ptr_ssk;
CREDS_NT ntc;
CREDS_UNIX uxc;
- CREDS_NT_SEC nts;
+ NET_USER_INFO_3 nts;
CREDS_UNIX_SEC uxs;
- uchar usr_sess_key[16];
-
} CREDS_HYBRID;
+typedef struct smbd_creds
+{
+ CREDS_HYBRID cred;
+ CREDS_SUBST smbd;
+
+} CREDS_SMBD;
+
typedef struct cred_command
{
uint16 version;
uint16 command;
- uint32 pid; /* unique process id */
+
+ vuser_key key;
fstring name;
diff --git a/source/include/rpc_dce.h b/source/include/rpc_dce.h
index 19527ca6e2e..2f996efd3e8 100644
--- a/source/include/rpc_dce.h
+++ b/source/include/rpc_dce.h
@@ -2,9 +2,9 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Paul Ashton 1997
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Paul Ashton 1997-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,89 +24,35 @@
#ifndef _DCE_RPC_H /* _DCE_RPC_H */
#define _DCE_RPC_H
-#include "rpc_misc.h" /* this only pulls in STRHDR */
-
-
/* DCE/RPC packet types */
enum RPC_PKT_TYPE
{
- RPC_REQUEST = 0x00,
- RPC_RESPONSE = 0x02,
- RPC_FAULT = 0x03,
- RPC_BIND = 0x0B,
- RPC_BINDACK = 0x0C,
- RPC_BINDNACK = 0x0D,
- RPC_ALTCONT = 0x0E,
+ RPC_REQUEST = 0x00,
+ RPC_RESPONSE = 0x02,
+ RPC_FAULT = 0x03,
+ RPC_BIND = 0x0B,
+ RPC_BINDACK = 0x0C,
+ RPC_BINDNACK = 0x0D,
+ RPC_ALTCONT = 0x0E,
RPC_ALTCONTRESP = 0x0F,
- RPC_BINDRESP = 0x10 /* not the real name! this is undocumented! */
+ RPC_BINDRESP = 0x10 /* not the real name! this is undocumented! */
};
/* DCE/RPC flags */
#define RPC_FLG_FIRST 0x01
#define RPC_FLG_LAST 0x02
+#define RPC_FLG_NOCALL 0x20
-/* NTLMSSP message types */
-enum NTLM_MESSAGE_TYPE
-{
- NTLMSSP_NEGOTIATE = 1,
- NTLMSSP_CHALLENGE = 2,
- NTLMSSP_AUTH = 3,
- NTLMSSP_UNKNOWN = 4
-};
-
-/* NTLMSSP negotiation flags */
-#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
-#define NTLMSSP_NEGOTIATE_OEM 0x00000002
-#define NTLMSSP_REQUEST_TARGET 0x00000004
-#define NTLMSSP_NEGOTIATE_SIGN 0x00000010
-#define NTLMSSP_NEGOTIATE_SEAL 0x00000020
-#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
-#define NTLMSSP_NEGOTIATE_NTLM 0x00000200
-#define NTLMSSP_NEGOTIATE_00001000 0x00001000
-#define NTLMSSP_NEGOTIATE_00002000 0x00002000
-#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
-#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
-#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
-#define NTLMSSP_NEGOTIATE_128 0x20000000
-#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
-
-#define SMBD_NTLMSSP_NEG_FLAGS 0x000082b1
-
-/* NTLMSSP signature version */
-#define NTLMSSP_SIGN_VERSION 0x01
-
-/* NTLMSSP auth type and level. */
-#define NTLMSSP_AUTH_TYPE 0xa
-#define NTLMSSP_AUTH_LEVEL 0x6
-
-/* Maximum PDU fragment size. */
-#define MAX_PDU_FRAG_LEN 0x1630
-
-/*
- * Actual structure of a DCE UUID
- */
-
-typedef struct rpc_uuid
-{
- uint32 time_low;
- uint16 time_mid;
- uint16 time_hi_and_version;
- uint8 remaining[8];
-} RPC_UUID;
-
-#define RPC_UUID_LEN 16
/* RPC_IFACE */
typedef struct rpc_iface_info
{
- RPC_UUID uuid; /* 16 bytes of rpc interface identification */
+ uint8 data[16]; /* 16 bytes of rpc interface identification */
uint32 version; /* the interface version number */
} RPC_IFACE;
-#define RPC_IFACE_LEN (RPC_UUID_LEN + 4)
-
struct pipe_id_info
{
/* the names appear not to matter: the syntaxes _do_ matter */
@@ -125,16 +71,14 @@ typedef struct rpc_hdr_info
uint8 minor; /* 0 - RPC minor version */
uint8 pkt_type; /* RPC_PKT_TYPE - RPC response packet */
uint8 flags; /* DCE/RPC flags */
- uint8 pack_type[4]; /* 0x1000 0000 - little-endian packed data representation */
+ uint8 pack_type[4]; /* 0x10 00 00 00 - packed data representation */
uint16 frag_len; /* fragment length - data size (bytes) inc header and tail. */
uint16 auth_len; /* 0 - authentication length */
uint32 call_id; /* call identifier. matches 12th uint32 of incoming RPC data. */
} RPC_HDR;
-#define RPC_HEADER_LEN 16
-
-/* RPC_HDR_REQ - ms request rpc header */
+/* RPC_HDR_REQ - request rpc header */
typedef struct rpc_hdr_req_info
{
uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
@@ -143,9 +87,7 @@ typedef struct rpc_hdr_req_info
} RPC_HDR_REQ;
-#define RPC_HDR_REQ_LEN 8
-
-/* RPC_HDR_RESP - ms response rpc header */
+/* RPC_HDR_RESP - response rpc header */
typedef struct rpc_hdr_resp_info
{
uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */
@@ -155,7 +97,20 @@ typedef struct rpc_hdr_resp_info
} RPC_HDR_RESP;
-#define RPC_HDR_RESP_LEN 8
+/* RPC_HDR_FAULT - fault rpc header */
+typedef struct rpc_hdr_fault_info
+{
+ uint32 status;
+ uint32 reserved; /* 0x0000 0000 */
+
+} RPC_HDR_FAULT;
+
+/* RPC_HDR_NACK - nack rpc header */
+typedef struct rpc_hdr_nack_info
+{
+ uint16 rej_code;
+
+} RPC_HDR_NACK;
/* this seems to be the same string name depending on the name of the pipe,
* but is more likely to be linked to the interface name
@@ -181,8 +136,6 @@ typedef struct rpc_hdr_bba_info
} RPC_HDR_BBA;
-#define RPC_HDR_BBA_LEN 8
-
/* RPC_HDR_AUTHA */
typedef struct rpc_hdr_autha_info
{
@@ -198,8 +151,6 @@ typedef struct rpc_hdr_autha_info
} RPC_HDR_AUTHA;
-#define RPC_HDR_AUTHA_LEN 12
-
/* RPC_HDR_AUTH */
typedef struct rpc_hdr_auth_info
{
@@ -212,9 +163,15 @@ typedef struct rpc_hdr_auth_info
} RPC_HDR_AUTH;
-#define RPC_HDR_AUTH_LEN 8
+/* RPC_AUTH_VERIFIER */
+typedef struct rpc_auth_ntlmssp_info
+{
+ fstring signature; /* authentication type */
+ uint32 msg_type; /* message type (1,2,3) */
+
+} RPC_AUTH_VERIFIER;
-/* RPC_BIND_REQ - ms req bind */
+/* RPC_BIND_REQ - req bind */
typedef struct rpc_bind_req_info
{
RPC_HDR_BBA bba;
@@ -228,13 +185,6 @@ typedef struct rpc_bind_req_info
} RPC_HDR_RB;
-/*
- * The following length is 8 bytes RPC_HDR_BBA_LEN, 8 bytes internals
- * (with 3 bytes padding), + 2 x RPC_IFACE_LEN bytes for RPC_IFACE structs.
- */
-
-#define RPC_HDR_RB_LEN (RPC_HDR_BBA_LEN + 8 + (2*RPC_IFACE_LEN))
-
/* RPC_RESULTS - can only cope with one reason, right now... */
typedef struct rpc_results_info
{
@@ -260,75 +210,5 @@ typedef struct rpc_hdr_ba_info
} RPC_HDR_BA;
-/* RPC_AUTH_VERIFIER */
-typedef struct rpc_auth_verif_info
-{
- fstring signature; /* "NTLMSSP" */
- uint32 msg_type; /* NTLMSSP_MESSAGE_TYPE (1,2,3) */
-
-} RPC_AUTH_VERIFIER;
-
-/* this is TEMPORARILY coded up as a specific structure */
-/* this structure comes after the bind request */
-/* RPC_AUTH_NTLMSSP_NEG */
-typedef struct rpc_auth_ntlmssp_neg_info
-{
- uint32 neg_flgs; /* 0x0000 b2b3 */
-
- STRHDR hdr_myname; /* offset is against START of this structure */
- STRHDR hdr_domain; /* offset is against START of this structure */
-
- fstring myname; /* calling workstation's name */
- fstring domain; /* calling workstations's domain */
-
-} RPC_AUTH_NTLMSSP_NEG;
-
-/* this is TEMPORARILY coded up as a specific structure */
-/* this structure comes after the bind acknowledgement */
-/* RPC_AUTH_NTLMSSP_CHAL */
-typedef struct rpc_auth_ntlmssp_chal_info
-{
- uint32 unknown_1; /* 0x0000 0000 */
- uint32 unknown_2; /* 0x0000 0028 */
- uint32 neg_flags; /* 0x0000 82b1 */
-
- uint8 challenge[8]; /* ntlm challenge */
- uint8 reserved [8]; /* zeros */
-
-} RPC_AUTH_NTLMSSP_CHAL;
-
-
-/* RPC_AUTH_NTLMSSP_RESP */
-typedef struct rpc_auth_ntlmssp_resp_info
-{
- STRHDR hdr_lm_resp; /* 24 byte response */
- STRHDR hdr_nt_resp; /* 24 byte response */
- STRHDR hdr_domain;
- STRHDR hdr_usr;
- STRHDR hdr_wks;
- STRHDR hdr_sess_key; /* NULL unless negotiated */
- uint32 neg_flags; /* 0x0000 82b1 */
-
- fstring sess_key;
- fstring wks;
- fstring user;
- fstring domain;
- fstring nt_resp;
- fstring lm_resp;
-
-} RPC_AUTH_NTLMSSP_RESP;
-
-/* attached to the end of encrypted rpc requests and responses */
-/* RPC_AUTH_NTLMSSP_CHK */
-typedef struct rpc_auth_ntlmssp_chk_info
-{
- uint32 ver; /* 0x0000 0001 */
- uint32 reserved;
- uint32 crc32; /* checksum using 0xEDB8 8320 as a polynomial */
- uint32 seq_num;
-
-} RPC_AUTH_NTLMSSP_CHK;
-
-#define RPC_AUTH_NTLMSSP_CHK_LEN 16
-
#endif /* _DCE_RPC_H */
+
diff --git a/source/include/rpc_eventlog.h b/source/include/rpc_eventlog.h
new file mode 100644
index 00000000000..d8021035f7c
--- /dev/null
+++ b/source/include/rpc_eventlog.h
@@ -0,0 +1,133 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Interface header: Scheduler service
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+ Copyright (C) Andrew Tridgell 1992-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_EVENTLOG_H
+#define _RPC_EVENTLOG_H
+
+#define EVENTLOG_OPEN 0x07
+#define EVENTLOG_CLOSE 0x02
+#define EVENTLOG_NUMOFEVENTLOGRECORDS 0x04
+#define EVENTLOG_READEVENTLOG 0x0a
+
+#define EVENTLOG_READ_SEQUENTIAL 0x01
+#define EVENTLOG_READ_SEEK 0x02
+#define EVENTLOG_READ_FORWARD 0x04
+#define EVENTLOG_READ_BACKWARD 0x08
+
+#define EVENTLOG_OK 0X00
+#define EVENTLOG_ERROR 0x01
+#define EVENTLOG_WARNING 0x02
+#define EVENTLOG_INFORMATION 0x04
+#define EVENTLOG_AUDIT_OK 0x08
+#define EVENTLOG_AUDIT_ERROR 0x10
+
+typedef struct eventlogrecord
+{
+ uint32 size;
+ uint32 reserved;
+ uint32 recordnumber;
+ uint32 creationtime;
+ uint32 writetime;
+ uint32 eventnumber;
+ uint16 eventtype;
+ uint16 num_of_strings;
+ uint16 category;
+ uint16 reserved_flag;
+ uint32 closingrecord;
+ uint32 stringoffset;
+ uint32 sid_length;
+ uint32 sid_offset;
+ uint32 data_length;
+ uint32 data_offset;
+ UNISTR sourcename;
+ UNISTR computername;
+ UNISTR sid;
+ UNISTR strings;
+ UNISTR data;
+ uint32 size2;
+} EVENTLOGRECORD;
+
+typedef struct eventlog_q_open
+{
+ uint32 ptr0;
+
+ uint16 unk0;
+ uint16 unk1;
+
+ UNIHDR hdr_source;
+ UNISTR2 uni_source;
+
+ UNIHDR hdr_unk;
+ UNISTR2 uni_unk;
+
+ uint32 unk6; /* one of these is an access mask! */
+ uint32 unk7; /* one of these is an access mask! */
+
+} EVENTLOG_Q_OPEN;
+
+typedef struct eventlog_r_open
+{
+ POLICY_HND pol;
+ uint32 status;
+
+} EVENTLOG_R_OPEN;
+
+typedef struct eventlog_q_close
+{
+ POLICY_HND pol;
+} EVENTLOG_Q_CLOSE;
+
+typedef struct eventlog_r_close
+{
+ POLICY_HND pol;
+ uint32 status;
+} EVENTLOG_R_CLOSE;
+
+typedef struct eventlog_q_numofeventlogrec
+{
+ POLICY_HND pol;
+} EVENTLOG_Q_NUMOFEVENTLOGREC;
+
+typedef struct eventlog_r_numofeventlogrec
+{
+ uint32 number;
+ uint32 status;
+} EVENTLOG_R_NUMOFEVENTLOGREC;
+
+typedef struct eventlog_q_readeventlog
+{
+ POLICY_HND pol;
+ uint32 flags;
+ uint32 offset;
+ uint32 number_of_bytes;
+} EVENTLOG_Q_READEVENTLOG;
+
+typedef struct eventlog_r_readeventlog
+{
+ uint32 number_of_bytes;
+ EVENTLOGRECORD *event;
+ uint32 sent_size;
+ uint32 real_size;
+ uint32 status;
+} EVENTLOG_R_READEVENTLOG;
+
+#endif /* _RPC_EVENTLOG_H */
diff --git a/source/include/rpc_lsa.h b/source/include/rpc_lsa.h
index c7fe77021b0..090e2254017 100644
--- a/source/include/rpc_lsa.h
+++ b/source/include/rpc_lsa.h
@@ -38,20 +38,69 @@ enum SID_NAME_USE
SID_NAME_UNKNOWN = 8 /* oops. */
};
+/* LSA ACE permissions */
+
+#define POLICY_VIEW_LOCAL_INFORMATION 0x00000001
+#define POLICY_VIEW_AUDIT_INFORMATION 0x00000002
+#define POLICY_GET_PRIVATE_INFORMATION 0x00000004
+#define POLICY_TRUST_ADMIN 0x00000008
+#define POLICY_CREATE_ACCOUNT 0x00000010
+#define POLICY_CREATE_SECRET 0x00000020
+#define POLICY_CREATE_PRIVILEGE 0x00000040
+#define POLICY_SET_DEFAULT_QUOTA_LIMITS 0x00000080
+#define POLICY_SET_AUDIT_REQUIREMENTS 0x00000100
+#define POLICY_AUDIT_LOG_ADMIN 0x00000200
+#define POLICY_SERVER_ADMIN 0x00000400
+#define POLICY_LOOKUP_NAMES 0x00000800
+
+#define POLICY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\
+ POLICY_VIEW_LOCAL_INFORMATION |\
+ POLICY_VIEW_AUDIT_INFORMATION |\
+ POLICY_GET_PRIVATE_INFORMATION |\
+ POLICY_TRUST_ADMIN |\
+ POLICY_CREATE_ACCOUNT |\
+ POLICY_CREATE_SECRET |\
+ POLICY_CREATE_PRIVILEGE |\
+ POLICY_SET_DEFAULT_QUOTA_LIMITS |\
+ POLICY_SET_AUDIT_REQUIREMENTS |\
+ POLICY_AUDIT_LOG_ADMIN |\
+ POLICY_SERVER_ADMIN |\
+ POLICY_LOOKUP_NAMES )
+
+
+#define POLICY_READ (STANDARD_RIGHTS_READ |\
+ POLICY_VIEW_AUDIT_INFORMATION |\
+ POLICY_GET_PRIVATE_INFORMATION)
+
+#define POLICY_WRITE (STANDARD_RIGHTS_WRITE |\
+ POLICY_TRUST_ADMIN |\
+ POLICY_CREATE_ACCOUNT |\
+ POLICY_CREATE_SECRET |\
+ POLICY_CREATE_PRIVILEGE |\
+ POLICY_SET_DEFAULT_QUOTA_LIMITS |\
+ POLICY_SET_AUDIT_REQUIREMENTS |\
+ POLICY_AUDIT_LOG_ADMIN |\
+ POLICY_SERVER_ADMIN)
+
+#define POLICY_EXECUTE (STANDARD_RIGHTS_EXECUTE |\
+ POLICY_VIEW_LOCAL_INFORMATION |\
+ POLICY_LOOKUP_NAMES )
+
/* ntlsa pipe */
#define LSA_CLOSE 0x00
+#define LSA_OPENPOLICY 0x06
#define LSA_QUERYINFOPOLICY 0x07
+#define LSA_QUERYSECOBJECT 0x03
#define LSA_ENUMTRUSTDOM 0x0d
#define LSA_LOOKUPNAMES 0x0e
#define LSA_LOOKUPSIDS 0x0f
-#define LSA_OPENPOLICY 0x06
+#define LSA_CREATESECRET 0x10
+#define LSA_OPENSECRET 0x1c
+#define LSA_SETSECRET 0x1d
+#define LSA_QUERYSECRET 0x1e
#define LSA_OPENPOLICY2 0x2c
-#define LSA_OPENSECRET 0x1C
-
-/* XXXX these are here to get a compile! */
-#define LSA_LOOKUPRIDS 0xFD
-#define LSA_MAX_GROUPS 96
+#define LSA_MAX_GROUPS 32
#define LSA_MAX_SIDS 32
/* DOM_QUERY - info class 3 and 5 LSA Query response */
@@ -96,7 +145,7 @@ typedef struct obj_attr_info
typedef struct lsa_q_open_pol_info
{
uint32 ptr; /* undocumented buffer pointer */
- uint16 system_name; /* 0x5c - system name */
+ uint16 system_name; /* system name BUG!!! (should be \\server!) */
LSA_OBJ_ATTR attr ; /* object attributes */
uint32 des_access; /* desired access attributes */
@@ -130,40 +179,159 @@ typedef struct lsa_r_open_pol2_info
} LSA_R_OPEN_POL2;
+/* LSA_Q_QUERY_SEC_OBJ - LSA query security */
+typedef struct lsa_query_sec_obj_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 sec_info;
+
+} LSA_Q_QUERY_SEC_OBJ;
+
+/* LSA_R_QUERY_SEC_OBJ - probably an open */
+typedef struct r_lsa_query_sec_obj_info
+{
+ uint32 ptr;
+ SEC_DESC_BUF buf;
+
+ uint32 status; /* return status */
+
+} LSA_R_QUERY_SEC_OBJ;
+
/* LSA_Q_QUERY_INFO - LSA query info policy */
typedef struct lsa_query_info
{
POLICY_HND pol; /* policy handle */
- uint16 info_class; /* info class */
+ uint16 info_class; /* info class */
} LSA_Q_QUERY_INFO;
/* LSA_R_QUERY_INFO - response to LSA query info policy */
typedef struct lsa_r_query_info
{
- uint32 undoc_buffer; /* undocumented buffer pointer */
- uint16 info_class; /* info class (same as info class in request) */
+ uint32 undoc_buffer; /* undocumented buffer pointer */
+ uint16 info_class; /* info class (same as info class in request) */
union
- {
- DOM_QUERY_3 id3;
+ {
+ DOM_QUERY_3 id3;
DOM_QUERY_5 id5;
- } dom;
+ } dom;
uint32 status; /* return code */
} LSA_R_QUERY_INFO;
+/* LSA_Q_CREATE_SECRET - LSA Create Secret */
+typedef struct lsa_q_create_secret_info
+{
+ POLICY_HND pol;
+ UNIHDR hdr_secret;
+ UNISTR2 uni_secret;
+
+ uint32 des_access; /* desired access attributes */
+
+} LSA_Q_CREATE_SECRET;
+
+/* LSA_R_CREATE_SECRET - response to LSA Open Secret */
+typedef struct lsa_r_create_secret_info
+{
+ POLICY_HND pol;
+ uint32 status;
+
+} LSA_R_CREATE_SECRET;
+
+/* LSA_Q_OPEN_SECRET - LSA Open Secret */
+typedef struct lsa_q_open_secret_info
+{
+ POLICY_HND pol;
+ UNIHDR hdr_secret;
+ UNISTR2 uni_secret;
+
+ uint32 des_access; /* desired access attributes */
+
+} LSA_Q_OPEN_SECRET;
+
+/* LSA_R_OPEN_SECRET - response to LSA Open Secret */
+typedef struct lsa_r_open_secret_info
+{
+ POLICY_HND pol;
+ uint32 status;
+
+} LSA_R_OPEN_SECRET;
+
+typedef struct lsa_secret_value_info
+{
+ uint32 ptr_secret;
+ STRHDR2 hdr_secret;
+ STRING2 enc_secret; /* encrypted, see nt_encrypt_string2 */
+
+} LSA_SECRET_VALUE;
+
+typedef struct lsa_secret_info_info
+{
+ uint32 ptr_value;
+ LSA_SECRET_VALUE value;
+
+ uint32 ptr_update;
+ NTTIME last_update; /* N.B. 64-bit alignment? */
+
+} LSA_SECRET_INFO;
+
+/* LSA_SECRET - LSA Secret */
+typedef struct lsa_q_secret_info
+{
+ LSA_SECRET_INFO curinfo;
+ LSA_SECRET_INFO oldinfo;
+
+} LSA_SECRET;
+
+/* LSA_Q_QUERY_SECRET - LSA Query Secret */
+typedef struct lsa_q_query_secret_info
+{
+ POLICY_HND pol;
+
+ LSA_SECRET sec;
+
+} LSA_Q_QUERY_SECRET;
+
+/* LSA_R_QUERY_SECRET - response to LSA Query Secret */
+typedef struct lsa_r_query_secret_info
+{
+ LSA_SECRET sec;
+
+ uint32 status;
+
+} LSA_R_QUERY_SECRET;
+
+/* LSA_Q_SET_SECRET - LSA Set Secret */
+typedef struct lsa_q_set_secret_info
+{
+ POLICY_HND pol;
+
+ LSA_SECRET_VALUE value;
+ uint32 unknown;
+
+} LSA_Q_SET_SECRET;
+
+/* LSA_R_SET_SECRET - response to LSA Set Secret */
+typedef struct lsa_r_set_secret_info
+{
+ uint32 status;
+
+} LSA_R_SET_SECRET;
+
/* LSA_Q_ENUM_TRUST_DOM - LSA enumerate trusted domains */
typedef struct lsa_enum_trust_dom_info
{
POLICY_HND pol; /* policy handle */
- uint32 enum_context; /* enumeration context handle */
- uint32 preferred_len; /* preferred maximum length */
+ uint32 enum_context; /* enumeration context handle */
+ uint32 preferred_len; /* preferred maximum length */
} LSA_Q_ENUM_TRUST_DOM;
+#define MAX_TRUSTED_DOMS 10
+
/* LSA_R_ENUM_TRUST_DOM - response to LSA enumerate trusted domains */
typedef struct lsa_r_enum_trust_dom_info
{
@@ -172,12 +340,12 @@ typedef struct lsa_r_enum_trust_dom_info
uint32 ptr_enum_domains; /* buffer pointer to num domains */
/* this lot is only added if ptr_enum_domains is non-NULL */
- uint32 num_domains2; /* number of domains */
- UNIHDR2 hdr_domain_name;
- UNISTR2 uni_domain_name;
- DOM_SID2 other_domain_sid;
+ uint32 num_domains2; /* number of domains */
+ UNIHDR2 *hdr_domain_name;
+ UNISTR2 *uni_domain_name;
+ DOM_SID2 *domain_sid;
- uint32 status; /* return code */
+ uint32 status; /* return code */
} LSA_R_ENUM_TRUST_DOM;
@@ -198,7 +366,7 @@ typedef struct lsa_r_close_info
} LSA_R_CLOSE;
-#define MAX_REF_DOMAINS 32
+#define MAX_REF_DOMAINS 10
/* DOM_TRUST_HDR */
typedef struct dom_trust_hdr
@@ -219,13 +387,13 @@ typedef struct dom_trust_info
/* DOM_R_REF */
typedef struct dom_ref_info
{
- uint32 num_ref_doms_1; /* num referenced domains */
- uint32 ptr_ref_dom; /* pointer to referenced domains */
- uint32 max_entries; /* 32 - max number of entries */
- uint32 num_ref_doms_2; /* num referenced domains */
+ uint32 num_ref_doms_1; /* num referenced domains */
+ uint32 ptr_ref_dom; /* pointer to referenced domains */
+ uint32 max_entries; /* 32 - max number of entries */
+ uint32 num_ref_doms_2; /* num referenced domains */
- DOM_TRUST_HDR hdr_ref_dom[MAX_REF_DOMAINS]; /* referenced domains */
- DOM_TRUST_INFO ref_dom [MAX_REF_DOMAINS]; /* referenced domains */
+ DOM_TRUST_HDR hdr_ref_dom[MAX_REF_DOMAINS]; /* referenced domains */
+ DOM_TRUST_INFO ref_dom [MAX_REF_DOMAINS]; /* referenced domains */
} DOM_R_REF;
@@ -290,19 +458,20 @@ typedef struct lsa_r_lookup_sids
} LSA_R_LOOKUP_SIDS;
+
/* LSA_Q_LOOKUP_NAMES - LSA Lookup NAMEs */
typedef struct lsa_q_lookup_names
{
- POLICY_HND pol; /* policy handle */
- uint32 num_entries;
- uint32 num_entries2;
- UNIHDR hdr_name[MAX_LOOKUP_SIDS]; /* name buffer pointers */
- UNISTR2 uni_name[MAX_LOOKUP_SIDS]; /* names to be looked up */
+ POLICY_HND pol; /* policy handle */
+ uint32 num_entries;
+ uint32 num_entries2;
+ UNIHDR hdr_name[MAX_LOOKUP_SIDS]; /* name buffer pointers */
+ UNISTR2 uni_name[MAX_LOOKUP_SIDS]; /* names to be looked up */
- uint32 num_trans_entries;
- uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */
- uint32 lookup_level;
- uint32 mapped_count;
+ uint32 num_trans_entries;
+ uint32 ptr_trans_sids; /* undocumented domain SID buffer pointer */
+ uint32 lookup_level;
+ uint32 mapped_count;
} LSA_Q_LOOKUP_NAMES;
@@ -314,14 +483,15 @@ typedef struct lsa_r_lookup_names
uint32 num_entries;
uint32 ptr_entries;
- uint32 num_entries2;
+ uint32 num_entries2;
DOM_RID2 *dom_rid; /* domain RIDs being looked up */
- uint32 mapped_count;
+ uint32 mapped_count;
uint32 status; /* return code */
} LSA_R_LOOKUP_NAMES;
+
#endif /* _RPC_LSA_H */
diff --git a/source/include/rpc_misc.h b/source/include/rpc_misc.h
index e96d6d4527c..ed8cbd96bb4 100644
--- a/source/include/rpc_misc.h
+++ b/source/include/rpc_misc.h
@@ -24,6 +24,111 @@
#ifndef _RPC_MISC_H /* _RPC_MISC_H */
#define _RPC_MISC_H
+/*
+ * macros to wrap prs_xxxx routines.
+ */
+#define prs_uint8(name, ps, depth, data8) \
+ if (!_prs_uint8(name, ps, depth, data8)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_uint16(name, ps, depth, data16) \
+ if (!_prs_uint16(name, ps, depth, data16)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_hash1(x_ps, x_offset, x_sess_key) \
+ if (!_prs_hash1(x_ps, x_offset, x_sess_key)) \
+ {\
+ x_ps->offset = 0;\
+ return False;\
+ }
+#define prs_uint32(name, ps, depth, data32) \
+ if (!_prs_uint32(name, ps, depth, data32)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_uint8s(charmode, name, ps, depth, data8s, len) \
+ if (!_prs_uint8s(charmode, name, ps, depth, data8s, len)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_uint16s(charmode, name, ps, depth, data16s, len) \
+ if (!_prs_uint16s(charmode, name, ps, depth, data16s, len)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_uint32s(charmode, name, ps, depth, data32s, len) \
+ if (!_prs_uint32s(charmode, name, ps, depth, data32s, len)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_buffer2(charmode, name, ps, depth, str) \
+ if (!_prs_buffer2(charmode, name, ps, depth, str)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_string2(charmode, name, ps, depth, str) \
+ if (!_prs_string2(charmode, name, ps, depth, str)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_unistr2(charmode, name, ps, depth, str) \
+ if (!_prs_unistr2(charmode, name, ps, depth, str)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_unistr3(charmode, name, str, ps, depth) \
+ if (!_prs_unistr3(charmode, name, str, ps, depth)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_unistr(name, ps, depth, str) \
+ if (!_prs_unistr(name, ps, depth, str)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_string(name, ps, depth, str, len, max_buf_size) \
+ if (!_prs_string(name, ps, depth, str, len, max_buf_size)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_uint16_pre(x_name, x_ps, x_depth, x_data16, x_offset) \
+ if (!_prs_uint16_pre(x_name, x_ps, x_depth, x_data16, x_offset)) \
+ {\
+ x_ps->offset = 0;\
+ return False;\
+ }
+#define prs_uint16_post(name, ps, depth, data16, ptr_uint16, data_size) \
+ if (!_prs_uint16_post(name, ps, depth, data16, ptr_uint16, data_size)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
+#define prs_uint32_pre(x_name, x_ps, x_depth, x_data32, x_offset) \
+ if (!_prs_uint32_pre(x_name, x_ps, x_depth, x_data32, x_offset)) \
+ {\
+ x_ps->offset = 0;\
+ return False;\
+ }
+#define prs_uint32_post(name, ps, depth, data32, ptr_uint32, data_size) \
+ if (!_prs_uint32_post(name, ps, depth, data32, ptr_uint32, data_size)) \
+ {\
+ ps->offset = 0;\
+ return False;\
+ }
#include "rpc_dce.h"
@@ -43,12 +148,10 @@
#define BUILTIN_ALIAS_RID_USERS (0x00000221L)
#define BUILTIN_ALIAS_RID_GUESTS (0x00000222L)
#define BUILTIN_ALIAS_RID_POWER_USERS (0x00000223L)
-
#define BUILTIN_ALIAS_RID_ACCOUNT_OPS (0x00000224L)
#define BUILTIN_ALIAS_RID_SYSTEM_OPS (0x00000225L)
#define BUILTIN_ALIAS_RID_PRINT_OPS (0x00000226L)
#define BUILTIN_ALIAS_RID_BACKUP_OPS (0x00000227L)
-
#define BUILTIN_ALIAS_RID_REPLICATOR (0x00000228L)
/*
@@ -56,13 +159,23 @@
* NT RIDS.
*/
-/* Take the bottom bit. */
-#define RID_TYPE_MASK 1
-#define RID_MULTIPLIER 2
+/* Take the bottom bits. */
+#define RID_TYPE_MASK 2
+#define RID_MULTIPLIER 4
+
+/* The three common types. */
+#define RID_TYPE_USER 0
+#define RID_TYPE_GROUP 1
+#define RID_TYPE_ALIAS 2
+
+/* BIGINT - NT-style 64-bit integer */
+typedef struct bigint_info
+{
+ uint32 low;
+ uint32 high;
+
+} BIGINT;
-/* The two common types. */
-#define USER_RID_TYPE 0
-#define GROUP_RID_TYPE 1
/* ENUM_HND */
typedef struct enum_hnd_info
@@ -97,6 +210,15 @@ typedef struct header_info
} STRHDR;
+/* STRHDR2 - string header, 32-bit lengths */
+typedef struct header2_info
+{
+ uint32 str_str_len;
+ uint32 str_max_len;
+ uint32 buffer;
+
+} STRHDR2;
+
/* UNIHDR - unicode string header */
typedef struct unihdr_info
{
@@ -122,8 +244,8 @@ typedef struct unihdr2_info
/* UNISTR - unicode string size and buffer */
typedef struct unistr_info
{
- /* unicode characters. ***MUST*** be little-endian. ***MUST*** be null-terminated */
- uint16 buffer[MAX_UNISTRLEN];
+ uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. ***MUST*** be null-terminated */
+
} UNISTR;
/* BUFHDR - buffer header */
@@ -134,6 +256,15 @@ typedef struct bufhdr_info
} BUFHDR;
+/* BUFHDR2 - another buffer header, with info level */
+typedef struct bufhdr2_info
+{
+ uint32 info_level;
+ uint32 length; /* uint8 chars */
+ uint32 buffer;
+
+} BUFHDR2;
+
/* BUFFER2 - unicode string, size (in uint8 ascii chars) and buffer */
/* pathetic. some stupid team of \PIPE\winreg writers got the concept */
/* of a unicode string different from the other \PIPE\ writers */
@@ -142,8 +273,7 @@ typedef struct buffer2_info
uint32 buf_max_len;
uint32 undoc;
uint32 buf_len;
- /* unicode characters. ***MUST*** be little-endian. **NOT** necessarily null-terminated */
- uint16 buffer[MAX_UNISTRLEN];
+ uint8 buffer[MAX_UNISTRLEN];
} BUFFER2;
@@ -156,6 +286,14 @@ typedef struct buffer3_info
} BUFFER3;
+/* BUFFER4 - simple length and buffer */
+typedef struct buffer4_info
+{
+ uint32 buf_len;
+ uint8 buffer[MAX_BUFFERLEN];
+
+} BUFFER4;
+
/* BUFFER5 */
typedef struct buffer5_info
{
@@ -169,8 +307,7 @@ typedef struct unistr2_info
uint32 uni_max_len;
uint32 undoc;
uint32 uni_str_len;
- /* unicode characters. ***MUST*** be little-endian. **NOT** necessarily null-terminated */
- uint16 buffer[MAX_UNISTRLEN];
+ uint16 buffer[MAX_UNISTRLEN]; /* unicode characters. **NOT** necessarily null-terminated */
} UNISTR2;
@@ -213,15 +350,6 @@ typedef struct domrid3_info
} DOM_RID3;
-/* DOM_RID4 - rid + user attributes */
-typedef struct domrid4_info
-{
- uint32 unknown;
- uint16 attr;
- uint32 rid; /* user RID */
-
-} DOM_RID4;
-
/* DOM_CLNT_SRV - client / server names */
typedef struct clnt_srv_info
{
@@ -294,3 +422,4 @@ typedef struct lsa_policy_info
} POLICY_HND;
#endif /* _RPC_MISC_H */
+
diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h
index 06caa53f4de..2f9a909459f 100644
--- a/source/include/rpc_netlogon.h
+++ b/source/include/rpc_netlogon.h
@@ -30,48 +30,23 @@
#define NET_SRVPWSET 0x06
#define NET_SAMLOGON 0x02
#define NET_SAMLOGOFF 0x03
+#define NET_AUTH 0x05
#define NET_AUTH2 0x0f
#define NET_LOGON_CTRL2 0x0e
#define NET_TRUST_DOM_LIST 0x13
+#define NET_SAM_SYNC 0x10
+#define NET_SAM_DELTAS 0x07
+
/* Secure Channel types. used in NetrServerAuthenticate negotiation */
#define SEC_CHAN_WKSTA 2
#define SEC_CHAN_DOMAIN 4
+#define SEC_CHAN_BDC 6
-#if 0
-/* JRATEST.... */
-/* NET_USER_INFO_2 */
-typedef struct net_user_info_2
-{
- uint32 ptr_user_info;
-
- NTTIME logon_time; /* logon time */
- NTTIME logoff_time; /* logoff time */
- NTTIME kickoff_time; /* kickoff time */
- NTTIME pass_last_set_time; /* password last set time */
- NTTIME pass_can_change_time; /* password can change time */
- NTTIME pass_must_change_time; /* password must change time */
-
-....
- uint32 user_id; /* User ID */
- uint32 group_id; /* Group ID */
-....
- uint32 num_groups2; /* num groups */
- DOM_GID gids[LSA_MAX_GROUPS]; /* group info */
-
- UNIHDR hdr_logon_srv; /* logon server unicode string header */
- UNISTR2 uni_logon_dom; /* logon domain unicode string */
- DOM_SID2 dom_sid;
-} NET_USER_INFO_2;
-/* ! JRATEST.... */
-#endif
-
/* NET_USER_INFO_3 */
typedef struct net_user_info_3
{
- uint32 ptr_user_info;
-
NTTIME logon_time; /* logon time */
NTTIME logoff_time; /* logoff time */
NTTIME kickoff_time; /* kickoff time */
@@ -84,7 +59,7 @@ typedef struct net_user_info_3
UNIHDR hdr_logon_script; /* logon script unicode string header */
UNIHDR hdr_profile_path; /* profile path unicode string header */
UNIHDR hdr_home_dir; /* home directory unicode string header */
- UNIHDR hdr_dir_drive; /* home directory drive unicode string header */
+ UNIHDR hdr_dir_drive; /* home drive unicode string header */
uint16 logon_count; /* logon count */
uint16 bad_pw_count; /* bad password count */
@@ -95,13 +70,13 @@ typedef struct net_user_info_3
uint32 buffer_groups; /* undocumented buffer pointer to groups. */
uint32 user_flgs; /* user flags */
- uint8 user_sess_key[16]; /* unused user session key */
+ uint8 user_sess_key[16]; /* user session key */
UNIHDR hdr_logon_srv; /* logon server unicode string header */
UNIHDR hdr_logon_dom; /* logon domain unicode string header */
uint32 buffer_dom_id; /* undocumented logon domain id pointer */
- uint8 padding[40]; /* unused padding bytes. expansion room */
+ uint8 padding[40]; /* expansion room */
uint32 num_other_sids; /* 0 - num_sids */
uint32 buffer_other_sids; /* NULL - undocumented pointer to SIDs. */
@@ -122,6 +97,8 @@ typedef struct net_user_info_3
DOM_SID2 dom_sid; /* domain SID */
DOM_SID2 other_sids[LSA_MAX_SIDS]; /* undocumented - domain SIDs */
+ uint32 auth_resp; /* 1 - Authoritative response */
+
} NET_USER_INFO_3;
@@ -176,6 +153,14 @@ typedef struct netlogon_3_info
} NETLOGON_INFO_3;
+/* NETLOGON_INFO - union of all status info */
+typedef union netlogon_info
+{
+ NETLOGON_INFO_1 info1;
+ NETLOGON_INFO_2 info2;
+ NETLOGON_INFO_3 info3;
+} NETLOGON_INFO;
+
/*******************************************************
Logon Control Response
@@ -188,13 +173,7 @@ typedef struct net_r_logon_ctrl2_info
uint32 switch_value; /* 0x1, 0x3 */
uint32 ptr;
- union
- {
- NETLOGON_INFO_1 info1;
- NETLOGON_INFO_2 info2;
- NETLOGON_INFO_3 info3;
-
- } logon;
+ NETLOGON_INFO logon;
uint32 status; /* return code */
@@ -215,7 +194,7 @@ typedef struct net_q_trust_dom_info
/* NET_R_TRUST_DOM_LIST - response to LSA Trusted Domains */
typedef struct net_r_trust_dom_info
{
- UNISTR2 uni_trust_dom_name[MAX_TRUST_DOMS];
+ BUFFER2 uni_trust_dom_name;
uint32 status; /* return code */
@@ -250,7 +229,23 @@ typedef struct net_r_req_chal_info
} NET_R_REQ_CHAL;
+/* NET_Q_AUTH */
+typedef struct net_q_auth_info
+{
+ DOM_LOG_INFO clnt_id; /* client identification info */
+ DOM_CHAL clnt_chal; /* client-calculated credentials */
+
+
+} NET_Q_AUTH;
+
+/* NET_R_AUTH */
+typedef struct net_r_auth_info
+{
+ DOM_CHAL srv_chal; /* server-calculated credentials */
+
+ uint32 status; /* return code */
+} NET_R_AUTH;
/* NET_Q_AUTH_2 */
typedef struct net_q_auth2_info
@@ -262,7 +257,6 @@ typedef struct net_q_auth2_info
} NET_Q_AUTH_2;
-
/* NET_R_AUTH_2 */
typedef struct net_r_auth2_info
{
@@ -273,7 +267,6 @@ typedef struct net_r_auth2_info
} NET_R_AUTH_2;
-
/* NET_Q_SRV_PWSET */
typedef struct net_q_srv_pwset_info
{
@@ -291,15 +284,33 @@ typedef struct net_r_srv_pwset_info
} NET_R_SRV_PWSET;
+/* NET_ID_INFO_4 */
+typedef struct net_network_info_4
+{
+ uint32 ptr_id_info4; /* pointer to id_info_2 */
+ UNIHDR hdr_domain_name; /* domain name unicode header */
+ uint32 param_ctrl; /* param control (0x2) */
+ BIGINT logon_id; /* logon ID */
+ UNIHDR hdr_user_name; /* user name unicode header */
+ UNIHDR hdr_wksta_name; /* wksta name unicode header */
+ STRHDR hdr_general; /* general response */
+
+ UNISTR2 uni_domain_name; /* domain name unicode string */
+ UNISTR2 uni_user_name; /* user name unicode string */
+ UNISTR2 uni_wksta_name; /* workgroup name unicode string */
+ STRING2 str_general; /* general response */
+
+} NET_ID_INFO_4;
+
/* NET_ID_INFO_2 */
typedef struct net_network_info_2
{
uint32 ptr_id_info2; /* pointer to id_info_2 */
UNIHDR hdr_domain_name; /* domain name unicode header */
uint32 param_ctrl; /* param control (0x2) */
- DOM_LOGON_ID logon_id; /* logon ID */
+ BIGINT logon_id; /* logon ID */
UNIHDR hdr_user_name; /* user name unicode header */
- UNIHDR hdr_wksta_name; /* workstation name unicode header */
+ UNIHDR hdr_wksta_name; /* wksta name unicode header */
uint8 lm_chal[8]; /* lan manager 8 byte challenge */
STRHDR hdr_nt_chal_resp; /* nt challenge response */
STRHDR hdr_lm_chal_resp; /* lm challenge response */
@@ -318,9 +329,9 @@ typedef struct id_info_1
uint32 ptr_id_info1; /* pointer to id_info_1 */
UNIHDR hdr_domain_name; /* domain name unicode header */
uint32 param_ctrl; /* param control */
- DOM_LOGON_ID logon_id; /* logon ID */
+ BIGINT logon_id; /* logon ID */
UNIHDR hdr_user_name; /* user name unicode header */
- UNIHDR hdr_wksta_name; /* workstation name unicode header */
+ UNIHDR hdr_wksta_name; /* wksta name unicode header */
OWF_INFO lm_owf; /* LM OWF Password */
OWF_INFO nt_owf; /* NT OWF Password */
UNISTR2 uni_domain_name; /* domain name unicode string */
@@ -330,7 +341,8 @@ typedef struct id_info_1
} NET_ID_INFO_1;
#define INTERACTIVE_LOGON_TYPE 1
-#define NET_LOGON_TYPE 2
+#define NETWORK_LOGON_TYPE 2
+#define GENERAL_LOGON_TYPE 4
/* NET_ID_INFO_CTR */
typedef struct net_id_info_ctr_info
@@ -340,7 +352,8 @@ typedef struct net_id_info_ctr_info
union
{
NET_ID_INFO_1 id1; /* auth-level 1 - interactive user login */
- NET_ID_INFO_2 id2; /* auth-level 2 - workstation referred login */
+ NET_ID_INFO_2 id2; /* auth-level 2 - network login */
+ NET_ID_INFO_4 id4; /* auth-level 4 - general login */
} auth;
@@ -360,7 +373,7 @@ typedef struct sam_info
/* NET_Q_SAM_LOGON */
typedef struct net_q_sam_logon_info
{
- DOM_SAM_INFO sam_id;
+ DOM_SAM_INFO sam_id;
uint16 validation_level;
} NET_Q_SAM_LOGON;
@@ -372,9 +385,9 @@ typedef struct net_r_sam_logon_info
DOM_CRED srv_creds; /* server credentials. server time stamp appears to be ignored. */
uint16 switch_value; /* 3 - indicates type of USER INFO */
- NET_USER_INFO_3 *user;
+ uint32 ptr_user_info;
- uint32 auth_resp; /* 1 - Authoritative response; 0 - Non-Auth? */
+ NET_USER_INFO_3 *user;
uint32 status; /* return code */
@@ -399,5 +412,270 @@ typedef struct net_r_sam_logoff_info
} NET_R_SAM_LOGOFF;
+/* NET_Q_SAM_SYNC */
+typedef struct net_q_sam_sync_info
+{
+ UNISTR2 uni_srv_name; /* \\PDC */
+ UNISTR2 uni_cli_name; /* BDC */
+ DOM_CRED cli_creds;
+ DOM_CRED ret_creds;
+
+ uint32 database_id;
+ uint32 restart_state;
+ uint32 sync_context;
+
+ uint32 max_size; /* preferred maximum length */
+
+} NET_Q_SAM_SYNC;
+
+#define MAX_GROUP_MEM 256
+#define MAX_SAM_DELTAS 256
+
+/* SAM_DELTA_HDR */
+typedef struct sam_delta_hdr_info
+{
+ uint16 type; /* type of structure attached, see below */
+ uint16 type2;
+ uint32 target_rid;
+
+ uint32 type3;
+ uint32 ptr_delta;
+
+} SAM_DELTA_HDR;
+
+/* SAM_DOMAIN_INFO (0x1) */
+typedef struct sam_domain_info_info
+{
+ UNIHDR hdr_dom_name;
+ UNIHDR hdr_oem_info;
+
+ BIGINT force_logoff;
+ uint16 min_pwd_len;
+ uint16 pwd_history_len;
+ BIGINT max_pwd_age;
+ BIGINT min_pwd_age;
+ BIGINT dom_mod_count;
+ NTTIME creation_time;
+
+ BUFHDR2 hdr_sec_desc; /* security descriptor */
+ UNIHDR hdr_unknown;
+ uint8 reserved[40];
+
+ UNISTR2 uni_dom_name;
+ UNISTR2 buf_oem_info; /* never seen */
+
+ BUFFER4 buf_sec_desc;
+ UNISTR2 buf_unknown;
+
+} SAM_DOMAIN_INFO;
+
+/* SAM_GROUP_INFO (0x2) */
+typedef struct sam_group_info_info
+{
+ UNIHDR hdr_grp_name;
+ DOM_GID gid;
+ UNIHDR hdr_grp_desc;
+ BUFHDR2 hdr_sec_desc; /* security descriptor */
+ uint8 reserved[48];
+
+ UNISTR2 uni_grp_name;
+ UNISTR2 uni_grp_desc;
+ BUFFER4 buf_sec_desc;
+
+} SAM_GROUP_INFO;
+
+/* SAM_PWD */
+typedef struct sam_passwd_info
+{
+ /* this structure probably contains password history */
+ /* this is probably a count of lm/nt pairs */
+ uint32 unk_0; /* 0x0000 0002 */
+
+ UNIHDR hdr_lm_pwd;
+ uint8 buf_lm_pwd[16];
+
+ UNIHDR hdr_nt_pwd;
+ uint8 buf_nt_pwd[16];
+
+ UNIHDR hdr_empty_lm;
+ UNIHDR hdr_empty_nt;
+
+} SAM_PWD;
+
+/* SAM_ACCOUNT_INFO (0x5) */
+typedef struct sam_account_info_info
+{
+ UNIHDR hdr_acct_name;
+ UNIHDR hdr_full_name;
+
+ uint32 user_rid;
+ uint32 group_rid;
+
+ UNIHDR hdr_home_dir;
+ UNIHDR hdr_dir_drive;
+ UNIHDR hdr_logon_script;
+ UNIHDR hdr_acct_desc;
+ UNIHDR hdr_workstations;
+
+ NTTIME logon_time;
+ NTTIME logoff_time;
+
+ uint32 logon_divs; /* 0xA8 */
+ uint32 ptr_logon_hrs;
+
+ uint16 bad_pwd_count;
+ uint16 logon_count;
+ NTTIME pwd_last_set_time;
+ NTTIME acct_expiry_time;
+
+ uint32 acb_info;
+ uint8 nt_pwd[16];
+ uint8 lm_pwd[16];
+ uint8 nt_pwd_present;
+ uint8 lm_pwd_present;
+ uint8 pwd_expired;
+
+ UNIHDR hdr_comment;
+ UNIHDR hdr_parameters;
+ uint16 country;
+ uint16 codepage;
+
+ BUFHDR2 hdr_sec_desc; /* security descriptor */
+
+ UNIHDR hdr_profile;
+ UNIHDR hdr_reserved[3]; /* space for more strings */
+ uint32 dw_reserved[4]; /* space for more data - first two seem to
+ be an NTTIME */
+
+ UNISTR2 uni_acct_name;
+ UNISTR2 uni_full_name;
+ UNISTR2 uni_home_dir;
+ UNISTR2 uni_dir_drive;
+ UNISTR2 uni_logon_script;
+ UNISTR2 uni_acct_desc;
+ UNISTR2 uni_workstations;
+
+ uint32 unknown1; /* 0x4EC */
+ uint32 unknown2; /* 0 */
+
+ BUFFER4 buf_logon_hrs;
+ UNISTR2 uni_comment;
+ UNISTR2 uni_parameters;
+ SAM_PWD pass;
+ BUFFER4 buf_sec_desc;
+ UNISTR2 uni_profile;
+
+} SAM_ACCOUNT_INFO;
+
+/* SAM_GROUP_MEM_INFO (0x8) */
+typedef struct sam_group_mem_info_info
+{
+ uint32 ptr_rids;
+ uint32 ptr_attribs;
+ uint32 num_members;
+ uint8 unknown[16];
+
+ uint32 num_members2;
+ uint32 rids[MAX_GROUP_MEM];
+
+ uint32 num_members3;
+ uint32 attribs[MAX_GROUP_MEM];
+
+} SAM_GROUP_MEM_INFO;
+
+/* SAM_ALIAS_INFO (0x9) */
+typedef struct sam_alias_info_info
+{
+ UNIHDR hdr_als_name;
+ uint32 als_rid;
+ BUFHDR2 hdr_sec_desc; /* security descriptor */
+ UNIHDR hdr_als_desc;
+ uint8 reserved[40];
+
+ UNISTR2 uni_als_name;
+ BUFFER4 buf_sec_desc;
+ UNISTR2 uni_als_desc;
+
+} SAM_ALIAS_INFO;
+
+/* SAM_ALIAS_MEM_INFO (0xC) */
+typedef struct sam_alias_mem_info_info
+{
+ uint32 num_members;
+ uint32 ptr_members;
+ uint8 unknown[16];
+
+ uint32 num_sids;
+ uint32 ptr_sids[MAX_GROUP_MEM];
+ DOM_SID2 sids[MAX_GROUP_MEM];
+
+} SAM_ALIAS_MEM_INFO;
+
+/* SAM_DELTA_CTR */
+typedef union sam_delta_ctr_info
+{
+ SAM_DOMAIN_INFO domain_info ;
+ SAM_GROUP_INFO group_info ;
+ SAM_ACCOUNT_INFO account_info;
+ SAM_GROUP_MEM_INFO grp_mem_info;
+ SAM_ALIAS_INFO alias_info ;
+ SAM_ALIAS_MEM_INFO als_mem_info;
+
+} SAM_DELTA_CTR;
+
+/* NET_R_SAM_SYNC */
+typedef struct net_r_sam_sync_info
+{
+ DOM_CRED srv_creds;
+
+ uint32 sync_context;
+
+ uint32 ptr_deltas;
+ uint32 num_deltas;
+ uint32 ptr_deltas2;
+ uint32 num_deltas2;
+
+ SAM_DELTA_HDR *hdr_deltas;
+ SAM_DELTA_CTR *deltas;
+
+ uint32 status;
+
+} NET_R_SAM_SYNC;
+
+
+/* NET_Q_SAM_DELTAS */
+typedef struct net_q_sam_deltas_info
+{
+ UNISTR2 uni_srv_name;
+ UNISTR2 uni_cli_name;
+ DOM_CRED cli_creds;
+ DOM_CRED ret_creds;
+
+ uint32 database_id;
+ BIGINT dom_mod_count; /* domain mod count at last sync */
+
+ uint32 max_size; /* preferred maximum length */
+
+} NET_Q_SAM_DELTAS;
+
+/* NET_R_SAM_DELTAS */
+typedef struct net_r_sam_deltas_info
+{
+ DOM_CRED srv_creds;
+
+ BIGINT dom_mod_count; /* new domain mod count */
+
+ uint32 num_deltas;
+ uint32 ptr_deltas;
+ uint32 num_deltas2;
+
+ SAM_DELTA_HDR *hdr_deltas;
+ SAM_DELTA_CTR *deltas;
+
+ uint32 status;
+
+} NET_R_SAM_DELTAS;
+
+
#endif /* _RPC_NETLOGON_H */
diff --git a/source/include/rpc_netsec.h b/source/include/rpc_netsec.h
new file mode 100644
index 00000000000..62158a66d14
--- /dev/null
+++ b/source/include/rpc_netsec.h
@@ -0,0 +1,61 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_NETSEC_H /* RPC_NETSEC_H */
+#define RPC_NETSEC_H
+
+#include "rpc_misc.h" /* this only pulls in STRHDR */
+
+/* this is TEMPORARILY coded up as a specific structure */
+/* this structure comes after the bind request */
+/* RPC_AUTH_NETSEC_NEG */
+typedef struct rpc_auth_netsec_neg_info
+{
+ fstring domain; /* calling workstations's domain */
+ fstring myname; /* calling workstation's name */
+
+} RPC_AUTH_NETSEC_NEG;
+
+
+/* RPC_AUTH_NETSEC_RESP */
+typedef struct rpc_auth_netsec_resp_info
+{
+ uint32 flags; /* 0x0500 0000 */
+
+} RPC_AUTH_NETSEC_RESP;
+
+#define NETSEC_SIGNATURE \
+ { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 }
+
+/* attached to the end of encrypted rpc requests and responses */
+/* RPC_AUTH_NETSEC_CHK */
+typedef struct rpc_auth_netsec_chk_info
+{
+ uint8 sig [8]; /* 77 00 7a 00 ff ff 00 00 */
+ uint8 data1[8];
+ uint8 data3[8]; /* verifier, seq num */
+ uint8 data8[8]; /* random 8-byte nonce */
+
+} RPC_AUTH_NETSEC_CHK;
+
+#endif /* RPC_NETSEC_H */
+
diff --git a/source/include/rpc_ntlmssp.h b/source/include/rpc_ntlmssp.h
new file mode 100644
index 00000000000..7660c623b25
--- /dev/null
+++ b/source/include/rpc_ntlmssp.h
@@ -0,0 +1,121 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_NTLMSSP_H /* RPC_NTLMSSP_H */
+#define RPC_NTLMSSP_H
+
+#include "rpc_misc.h" /* this only pulls in STRHDR */
+
+/* NTLMSSP message types */
+enum NTLM_MESSAGE_TYPE
+{
+ NTLMSSP_NEGOTIATE = 1,
+ NTLMSSP_CHALLENGE = 2,
+ NTLMSSP_AUTH = 3,
+ NTLMSSP_UNKNOWN = 4
+};
+
+/* NTLMSSP negotiation flags */
+#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
+#define NTLMSSP_NEGOTIATE_OEM 0x00000002
+#define NTLMSSP_REQUEST_TARGET 0x00000004
+#define NTLMSSP_NEGOTIATE_SIGN 0x00000010
+#define NTLMSSP_NEGOTIATE_SEAL 0x00000020
+#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
+#define NTLMSSP_NEGOTIATE_00000100 0x00000100
+#define NTLMSSP_NEGOTIATE_NTLM 0x00000200
+#define NTLMSSP_NEGOTIATE_00000400 0x00000400
+#define NTLMSSP_NEGOTIATE_00001000 0x00001000
+#define NTLMSSP_NEGOTIATE_00002000 0x00002000
+#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
+#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
+#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
+#define NTLMSSP_NEGOTIATE_128 0x20000000
+#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
+
+/* NTLMSSP signature version */
+#define NTLMSSP_SIGN_VERSION 0x01
+
+/* this is TEMPORARILY coded up as a specific structure */
+/* this structure comes after the bind request */
+/* RPC_AUTH_NTLMSSP_NEG */
+typedef struct rpc_auth_ntlmssp_neg_info
+{
+ uint32 neg_flgs; /* 0x0000 b2b3 */
+
+ STRHDR hdr_myname; /* offset is against START of this structure */
+ STRHDR hdr_domain; /* offset is against START of this structure */
+
+ fstring myname; /* calling workstation's name */
+ fstring domain; /* calling workstations's domain */
+
+} RPC_AUTH_NTLMSSP_NEG;
+
+/* this is TEMPORARILY coded up as a specific structure */
+/* this structure comes after the bind acknowledgement */
+/* RPC_AUTH_NTLMSSP_CHAL */
+typedef struct rpc_auth_ntlmssp_chal_info
+{
+ uint32 unknown_1; /* 0x0000 0000 */
+ uint32 unknown_2; /* 0x0000 0028 */
+ uint32 neg_flags; /* 0x0000 82b1 */
+
+ uint8 challenge[8]; /* ntlm challenge */
+ uint8 reserved [8]; /* zeros */
+
+} RPC_AUTH_NTLMSSP_CHAL;
+
+
+/* RPC_AUTH_NTLMSSP_RESP */
+typedef struct rpc_auth_ntlmssp_resp_info
+{
+ STRHDR hdr_lm_resp; /* LM response (NULL or 24 bytes) */
+ STRHDR hdr_nt_resp; /* NT response (NULL, 24 or variable-length) */
+ STRHDR hdr_domain;
+ STRHDR hdr_usr;
+ STRHDR hdr_wks;
+ STRHDR hdr_sess_key; /* NULL unless negotiated */
+ uint32 neg_flags; /* 0x0000 82b1 */
+
+ fstring sess_key;
+ fstring wks;
+ fstring user;
+ fstring domain;
+ fstring nt_resp;
+ fstring lm_resp;
+
+} RPC_AUTH_NTLMSSP_RESP;
+
+
+/* attached to the end of encrypted rpc requests and responses */
+/* RPC_AUTH_NTLMSSP_CHK */
+typedef struct rpc_auth_ntlmssp_chk_info
+{
+ uint32 ver; /* 0x0000 0001 */
+ uint32 reserved;
+ uint32 crc32; /* checksum using 0xEDB8 8320 as a polynomial */
+ uint32 seq_num;
+
+} RPC_AUTH_NTLMSSP_CHK;
+
+#endif /* RPC_NTLMSSP_H */
+
diff --git a/source/include/rpc_parse.h b/source/include/rpc_parse.h
new file mode 100644
index 00000000000..bdfde919c49
--- /dev/null
+++ b/source/include/rpc_parse.h
@@ -0,0 +1,33 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Elrond 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_PARSE_H
+#define _RPC_PARSE_H
+
+/* different dce/rpc pipes */
+#include "rpc_reg.h"
+#include "rpc_brs.h"
+
+#include "rpc_parse_proto.h"
+
+#endif /* _RPC_PARSE_H */
diff --git a/source/include/rpc_parse_proto.h b/source/include/rpc_parse_proto.h
new file mode 100644
index 00000000000..fe2df3aeefd
--- /dev/null
+++ b/source/include/rpc_parse_proto.h
@@ -0,0 +1,1095 @@
+#ifndef _RPC_PARSE_PROTO_H_
+#define _RPC_PARSE_PROTO_H_
+/* This file is automatically generated with "make proto". DO NOT EDIT */
+
+
+/*The following definitions come from lib/msrpc-client.c */
+
+BOOL receive_msrpc(int fd, prs_struct * data, unsigned int timeout);
+BOOL msrpc_send(int fd, prs_struct * ps);
+BOOL msrpc_receive(int fd, prs_struct * ps);
+BOOL ncalrpc_l_connect(struct msrpc_local *msrpc, const char *pipe_name);
+void ncalrpc_l_close_socket(struct msrpc_local *msrpc);
+void ncalrpc_l_sockopt(struct msrpc_local *msrpc, char *options);
+BOOL ncalrpc_l_connect_auth(struct msrpc_local *msrpc,
+ const vuser_key * key, const char *pipename);
+struct msrpc_local *ncalrpc_l_initialise(struct msrpc_local *msrpc,
+ const vuser_key * key);
+void ncalrpc_l_shutdown(struct msrpc_local *msrpc);
+BOOL ncalrpc_l_establish_connection(struct msrpc_local *msrpc,
+ const char *pipe_name);
+
+/*The following definitions come from rpc_parse/parse_at.c */
+
+BOOL make_at_q_add_job(AT_Q_ADD_JOB *q_a, char *server,
+ AT_JOB_INFO *info, char *command);
+BOOL at_io_job_info(char *desc, AT_JOB_INFO *info, prs_struct *ps, int depth);
+BOOL at_io_q_add_job(char *desc, AT_Q_ADD_JOB *q_a, prs_struct *ps, int depth);
+BOOL at_io_r_add_job(char *desc, AT_R_ADD_JOB *r_a, prs_struct *ps, int depth);
+BOOL make_at_q_del_job(AT_Q_DEL_JOB *q_a, char *server, uint32 min_jobid,
+ uint32 max_jobid);
+BOOL at_io_q_del_job(char *desc, AT_Q_DEL_JOB *q_d, prs_struct *ps, int depth);
+BOOL at_io_r_del_job(char *desc, AT_R_DEL_JOB *r_d, prs_struct *ps, int depth);
+BOOL make_at_q_enum_jobs(AT_Q_ENUM_JOBS *q_e, char *server);
+BOOL at_io_q_enum_jobs(char *desc, AT_Q_ENUM_JOBS *q_e, prs_struct *ps, int depth);
+BOOL at_io_r_enum_jobs(char *desc, AT_R_ENUM_JOBS *r_e, prs_struct *ps, int depth);
+BOOL make_at_q_query_job(AT_Q_QUERY_JOB *q_q, char *server, uint32 jobid);
+BOOL at_io_q_query_job(char *desc, AT_Q_QUERY_JOB *q_q, prs_struct *ps, int depth);
+BOOL at_io_r_query_job(char *desc, AT_R_QUERY_JOB *r_q, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_brs.c */
+
+BOOL make_brs_q_query_info(BRS_Q_QUERY_INFO *q_u,
+ const char *server, uint16 switch_value) ;
+BOOL brs_io_q_query_info(char *desc, BRS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth);
+BOOL make_brs_info_100(BRS_INFO_100 *inf);
+BOOL make_brs_r_query_info(BRS_R_QUERY_INFO *r_u,
+ uint32 switch_value, void *inf,
+ int status) ;
+BOOL brs_io_r_query_info(char *desc, BRS_R_QUERY_INFO *r_u, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_eventlog.c */
+
+BOOL make_eventlog_q_open(EVENTLOG_Q_OPEN *q_u, const char *journal, char *unk);
+BOOL eventlog_io_q_open(char *desc, EVENTLOG_Q_OPEN *q_u, prs_struct *ps, int depth);
+BOOL eventlog_io_r_open(char *desc, EVENTLOG_R_OPEN *r_u, prs_struct *ps, int depth);
+BOOL make_eventlog_q_close(EVENTLOG_Q_CLOSE *q_u, POLICY_HND *pol);
+BOOL eventlog_io_q_close(char *desc, EVENTLOG_Q_CLOSE *q_u, prs_struct *ps, int depth);
+BOOL eventlog_io_r_close(char *desc, EVENTLOG_R_CLOSE *r_u, prs_struct *ps, int depth);
+BOOL make_eventlog_q_numofeventlogrec(EVENTLOG_Q_NUMOFEVENTLOGREC *q_u, POLICY_HND *pol);
+BOOL eventlog_io_q_numofeventlogrec(char *desc,EVENTLOG_Q_NUMOFEVENTLOGREC *q_u, prs_struct *ps, int depth);
+BOOL eventlog_io_r_numofeventlogrec(char *desc, EVENTLOG_R_NUMOFEVENTLOGREC *r_u, prs_struct *ps, int depth);
+BOOL make_eventlog_q_readeventlog(EVENTLOG_Q_READEVENTLOG *q_u, POLICY_HND *pol,
+ uint32 flags, uint32 offset, uint32 number_of_bytes);
+BOOL eventlog_io_q_readeventlog(char *desc, EVENTLOG_Q_READEVENTLOG *q_u, prs_struct *ps, int depth);
+BOOL eventlog_io_r_readeventlog(char *desc, EVENTLOG_R_READEVENTLOG *r_u, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_lsa.c */
+
+BOOL make_lsa_trans_name(LSA_TRANS_NAME * trn, UNISTR2 * uni_name,
+ uint32 sid_name_use, char *name, uint32 idx);
+int make_dom_ref_uni(DOM_R_REF * ref, const UNISTR2 * uni_domname,
+ const DOM_SID * dom_sid);
+int make_dom_ref(DOM_R_REF * ref, const char *domname,
+ const DOM_SID * dom_sid);
+BOOL make_lsa_sec_qos(LSA_SEC_QOS * qos, uint16 imp_lev, uint8 ctxt,
+ uint8 eff, uint32 unknown);
+BOOL make_lsa_obj_attr(LSA_OBJ_ATTR * attr, uint32 attributes,
+ LSA_SEC_QOS * qos);
+BOOL make_q_open_pol(LSA_Q_OPEN_POL * r_q, uint16 system_name,
+ uint32 attributes,
+ uint32 desired_access, LSA_SEC_QOS * qos);
+BOOL lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL * r_q, prs_struct * ps,
+ int depth);
+BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL * r_p, prs_struct * ps,
+ int depth);
+BOOL make_q_open_pol2(LSA_Q_OPEN_POL2 * r_q, const char *server_name,
+ uint32 attributes,
+ uint32 desired_access, LSA_SEC_QOS * qos);
+BOOL lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 * r_q, prs_struct * ps,
+ int depth);
+BOOL lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 * r_p, prs_struct * ps,
+ int depth);
+BOOL make_q_query_sec_obj(LSA_Q_QUERY_SEC_OBJ * q_q, const POLICY_HND *hnd,
+ uint32 sec_info);
+BOOL lsa_io_q_query_sec_obj(char *desc, LSA_Q_QUERY_SEC_OBJ * q_q, prs_struct * ps,
+ int depth);
+BOOL lsa_io_r_query_sec_obj(char *desc, LSA_R_QUERY_SEC_OBJ *r_u, prs_struct *ps, int depth);
+BOOL make_q_query(LSA_Q_QUERY_INFO * q_q, POLICY_HND *hnd, uint16 info_class);
+BOOL lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO * q_q, prs_struct * ps,
+ int depth);
+BOOL make_q_create_secret(LSA_Q_CREATE_SECRET * q_o,
+ const POLICY_HND *pol_hnd, const char *secret_name,
+ uint32 desired_access);
+BOOL lsa_io_q_create_secret(char *desc, LSA_Q_CREATE_SECRET * q_o,
+ prs_struct * ps, int depth);
+BOOL lsa_io_r_create_secret(char *desc, LSA_R_CREATE_SECRET * r_o,
+ prs_struct * ps, int depth);
+BOOL make_q_open_secret(LSA_Q_OPEN_SECRET * q_o, const POLICY_HND *pol_hnd,
+ const char *secret_name, uint32 desired_access);
+BOOL lsa_io_q_open_secret(char *desc, LSA_Q_OPEN_SECRET * q_o,
+ prs_struct * ps, int depth);
+BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET * r_o,
+ prs_struct * ps, int depth);
+BOOL lsa_io_secret_value(char *desc, LSA_SECRET_VALUE * value,
+ prs_struct * ps, int depth);
+BOOL lsa_io_secret_info(char *desc, LSA_SECRET_INFO * info, prs_struct * ps,
+ int depth);
+BOOL lsa_io_secret(char *desc, LSA_SECRET * q_q, prs_struct * ps, int depth);
+BOOL make_q_query_secret(LSA_Q_QUERY_SECRET * q_q, POLICY_HND *pol,
+ const STRING2 *secret, const NTTIME * update);
+BOOL lsa_io_q_query_secret(char *desc, LSA_Q_QUERY_SECRET * q_q,
+ prs_struct * ps, int depth);
+BOOL lsa_io_r_query_secret(char *desc, LSA_R_QUERY_SECRET * r_q,
+ prs_struct * ps, int depth);
+BOOL lsa_io_q_set_secret(char *desc, LSA_Q_SET_SECRET * q_q, prs_struct * ps,
+ int depth);
+BOOL lsa_io_r_set_secret(char *desc, LSA_R_SET_SECRET * r_q, prs_struct * ps,
+ int depth);
+BOOL make_q_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM * q_e,
+ POLICY_HND *pol,
+ uint32 enum_context, uint32 preferred_len);
+BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM * q_e,
+ prs_struct * ps, int depth);
+BOOL make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM * r_e, int32 enum_context,
+ uint32 num_domains,
+ UNISTR2 * domain_names, DOM_SID ** domain_sids,
+ uint32 status);
+BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM * r_e,
+ prs_struct * ps, int depth);
+void lsa_free_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM * r_e);
+BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO * r_q, prs_struct * ps,
+ int depth);
+BOOL make_lsa_sid_enum(LSA_SID_ENUM * sen, uint32 num_entries,
+ DOM_SID ** sids);
+BOOL make_q_lookup_sids(LSA_Q_LOOKUP_SIDS * q_l, POLICY_HND *hnd,
+ int num_sids, DOM_SID ** sids, uint16 level);
+BOOL lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS * q_s,
+ prs_struct * ps, int depth);
+BOOL lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS * r_s,
+ prs_struct * ps, int depth);
+BOOL make_q_lookup_names(LSA_Q_LOOKUP_NAMES * q_l, POLICY_HND *hnd,
+ uint32 num_names, char **names);
+BOOL lsa_io_q_lookup_names(char *desc, LSA_Q_LOOKUP_NAMES * q_r,
+ prs_struct * ps, int depth);
+BOOL lsa_io_r_lookup_names(char *desc, LSA_R_LOOKUP_NAMES * r_r,
+ prs_struct * ps, int depth);
+BOOL make_lsa_q_close(LSA_Q_CLOSE * q_c, POLICY_HND *hnd);
+BOOL lsa_io_q_close(char *desc, LSA_Q_CLOSE * q_c, prs_struct * ps, int depth);
+BOOL lsa_io_r_close(char *desc, LSA_R_CLOSE * r_c, prs_struct * ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_netsec.c */
+
+BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH *rai);
+BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
+ fstring domain,
+ fstring myname);
+BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG *neg, prs_struct *ps, int depth);
+BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP *rsp, uint32 flags);
+BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP *rsp, prs_struct *ps, int depth);
+BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk);
+BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk,
+ const uchar sig[8],
+ const uchar data1[8],
+ const uchar data3[8],
+ const uchar data8[8]);
+BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK *chk, prs_struct *ps, int depth);
+BOOL netsec_encode(struct netsec_auth_struct *a,
+ RPC_AUTH_NETSEC_CHK *verf,
+ char *data, size_t data_len);
+BOOL netsec_decode(struct netsec_auth_struct *a,
+ RPC_AUTH_NETSEC_CHK *verf,
+ char *data, size_t data_len);
+
+/*The following definitions come from rpc_parse/parse_reg.c */
+
+BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
+ uint16 unknown_0, uint32 level);
+BOOL reg_io_q_open_hkcr(char *desc, REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_open_hkcr(char *desc, REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
+ uint16 unknown_0, uint32 access_mask);
+BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol);
+BOOL reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
+ char *key_name, char *key_class,
+ SEC_ACCESS *sam_access,
+ SEC_DESC_BUF *sec_buf,
+ int sec_len, SEC_DESC *sec);
+BOOL reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_create_key(char *desc, REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
+ char *name);
+BOOL reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
+ char *name);
+BOOL reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
+ uint32 max_class_len);
+BOOL reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd);
+BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
+ uint16 unknown_0, uint32 level);
+BOOL reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd);
+BOOL reg_io_q_close(char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int depth);
+BOOL reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth);
+BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol,
+ uint32 sec_info,
+ uint32 buf_len, SEC_DESC *sec_desc);
+BOOL reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth);
+BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol,
+ uint32 sec_info,
+ uint32 buf_len, SEC_DESC_BUF *sec_buf);
+BOOL reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
+BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth);
+BOOL make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, const char *val_name,
+ uint8 major, uint8 minor);
+BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth);
+BOOL make_reg_r_info(REG_R_INFO *r_r,
+ uint32 *type, BUFFER2 *buf,
+ uint32 status);
+BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
+ uint32 val_idx, uint32 max_val_len,
+ uint32 max_buf_len);
+BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth);
+BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth);
+BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
+ char *val_name, uint32 type,
+ BUFFER3 *val);
+BOOL reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth);
+BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth);
+BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx);
+BOOL reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth);
+BOOL reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth);
+BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
+ char *key_name, uint32 access_mask);
+BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth);
+BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
+ POLICY_HND *pol, uint32 status);
+BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth);
+BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN *q_i,
+ const char *msg, uint32 timeout, uint16 flags);
+BOOL reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN *q_q, prs_struct *ps, int depth);
+BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN *r_q, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_rpc.c */
+
+BOOL make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
+ uint32 call_id, int data_len, int auth_len);
+BOOL smb_io_rpc_hdr(char *desc, RPC_HDR *rpc, prs_struct *ps, int depth);
+BOOL is_complete_pdu(prs_struct *ps);
+BOOL smb_io_rpc_hdr_nack(char *desc, RPC_HDR_NACK *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_fault(char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_rb(RPC_HDR_RB *rpc,
+ uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
+ uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
+ RPC_IFACE *abstract, RPC_IFACE *transfer);
+BOOL smb_io_rpc_hdr_rb(char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_ba(RPC_HDR_BA *rpc,
+ uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
+ const char *pipe_addr,
+ uint8 num_results, uint16 result, uint16 reason,
+ RPC_IFACE *transfer);
+BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 vuid,
+ uint16 opnum);
+BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
+ uint16 max_tsize, uint16 max_rsize,
+ uint8 auth_type, uint8 auth_level,
+ uint8 stub_type_len);
+BOOL smb_io_rpc_hdr_autha(char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_auth(RPC_HDR_AUTH *rai,
+ uint8 auth_type, uint8 auth_level,
+ uint8 stub_type_len,
+ uint32 ptr);
+BOOL smb_io_rpc_hdr_auth(char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, int depth);
+BOOL make_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
+ char *signature, uint32 msg_type);
+BOOL smb_io_rpc_auth_verifier(char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth);
+BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
+ char *signature, uint32 msg_type);
+
+/*The following definitions come from rpc_parse/parse_samr.c */
+
+BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd);
+BOOL samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u,
+ POLICY_HND *pol, const char *dom_name);
+BOOL samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN *r_u,
+ DOM_SID *dom_sid, uint32 status);
+BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D *q_u,
+ const POLICY_HND *dom_pol,
+ const DOM_SID *sid);
+BOOL samr_io_q_unknown_2d(char *desc, SAMR_Q_UNKNOWN_2D *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_unknown_2d(char *desc, SAMR_R_UNKNOWN_2D *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
+ const POLICY_HND *connect_pol, uint32 flags,
+ const DOM_SID *sid);
+BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO *q_u, POLICY_HND *user_pol);
+BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *q_u, uint32 status);
+BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ *q_u,
+ const POLICY_HND *user_pol, uint32 sec_info);
+BOOL samr_io_q_query_sec_obj(char *desc, SAMR_Q_QUERY_SEC_OBJ *q_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value);
+BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *ps, int depth);
+BOOL make_unk_info3(SAM_UNK_INFO_3 *u_3);
+BOOL make_unk_info6(SAM_UNK_INFO_6 *u_6);
+BOOL make_unk_info7(SAM_UNK_INFO_7 *u_7);
+BOOL make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server);
+BOOL make_unk_info1(SAM_UNK_INFO_1 *u_1);
+BOOL make_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u,
+ uint16 switch_value, SAM_UNK_CTR *ctr,
+ uint32 status);
+BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO *r_u, prs_struct *ps, int depth);
+BOOL samr_io_r_query_sec_obj(char *desc, SAMR_R_QUERY_SEC_OBJ *r_u, prs_struct *ps, int depth);
+BOOL make_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid);
+BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
+ uint32 start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size);
+BOOL samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
+ uint32 next_idx,
+ uint32 num_sam_entries);
+BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
+ uint16 switch_level, uint32 start_idx,
+ uint32 max_entries);
+BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth);
+BOOL make_sam_dispinfo_1(SAM_DISPINFO_1 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
+BOOL make_sam_dispinfo_2(SAM_DISPINFO_2 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
+BOOL make_sam_dispinfo_3(SAM_DISPINFO_3 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ DOMAIN_GRP *grp);
+BOOL make_sam_dispinfo_4(SAM_DISPINFO_4 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
+BOOL make_sam_dispinfo_5(SAM_DISPINFO_5 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ DOMAIN_GRP *grp);
+BOOL make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
+ uint32 num_entries, uint32 data_size,
+ uint16 switch_level, SAM_DISPINFO_CTR *ctr,
+ uint32 status);
+BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_open_group(SAMR_Q_OPEN_GROUP *q_c,
+ const POLICY_HND *hnd,
+ uint32 access_mask, uint32 rid);
+BOOL samr_io_q_open_group(char *desc, SAMR_Q_OPEN_GROUP *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_open_group(char *desc, SAMR_R_OPEN_GROUP *r_u, prs_struct *ps, int depth);
+BOOL make_samr_group_info1(GROUP_INFO1 *gr1,
+ char *acct_name, char *acct_desc,
+ uint32 num_members);
+BOOL samr_io_group_info1(char *desc, GROUP_INFO1 *gr1, prs_struct *ps, int depth);
+BOOL make_samr_group_info4(GROUP_INFO4 *gr4, const char *acct_desc);
+BOOL samr_io_group_info4(char *desc, GROUP_INFO4 *gr4, prs_struct *ps, int depth);
+BOOL samr_group_info_ctr(char *desc, GROUP_INFO_CTR *ctr, prs_struct *ps, int depth);
+BOOL make_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP *q_e,
+ POLICY_HND *pol,
+ const char *acct_desc);
+BOOL samr_io_q_create_dom_group(char *desc, SAMR_Q_CREATE_DOM_GROUP *q_e, prs_struct *ps, int depth);
+BOOL samr_io_r_create_dom_group(char *desc, SAMR_R_CREATE_DOM_GROUP *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP *q_c, POLICY_HND *hnd);
+BOOL samr_io_q_delete_dom_group(char *desc, SAMR_Q_DELETE_DOM_GROUP *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_delete_dom_group(char *desc, SAMR_R_DELETE_DOM_GROUP *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM *q_e,
+ POLICY_HND *pol,
+ uint32 rid);
+BOOL samr_io_q_del_groupmem(char *desc, SAMR_Q_DEL_GROUPMEM *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM *r_u, POLICY_HND *pol,
+ uint32 status);
+BOOL samr_io_r_del_groupmem(char *desc, SAMR_R_DEL_GROUPMEM *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM *q_e,
+ POLICY_HND *pol,
+ uint32 rid);
+BOOL samr_io_q_add_groupmem(char *desc, SAMR_Q_ADD_GROUPMEM *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM *r_u, POLICY_HND *pol,
+ uint32 status);
+BOOL samr_io_r_add_groupmem(char *desc, SAMR_R_ADD_GROUPMEM *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO *q_e,
+ POLICY_HND *pol, GROUP_INFO_CTR *ctr);
+BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO *r_u,
+ uint32 status);
+BOOL samr_io_r_set_groupinfo(char *desc, SAMR_R_SET_GROUPINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_e,
+ POLICY_HND *pol,
+ uint16 switch_level);
+BOOL samr_io_q_query_groupinfo(char *desc, SAMR_Q_QUERY_GROUPINFO *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO *r_u, GROUP_INFO_CTR *ctr,
+ uint32 status);
+BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM *q_c, POLICY_HND *hnd);
+BOOL samr_io_q_query_groupmem(char *desc, SAMR_Q_QUERY_GROUPMEM *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM *r_u,
+ uint32 num_entries, uint32 *rid, uint32 *attr, uint32 status);
+BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM *r_u, prs_struct *ps, int depth);
+void samr_free_r_query_groupmem(SAMR_R_QUERY_GROUPMEM *r_u);
+BOOL make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
+ POLICY_HND *hnd);
+BOOL samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
+ uint32 num_gids, DOM_GID *gid, uint32 status);
+BOOL samr_io_gids(char *desc, uint32 *num_gids, DOM_GID **gid, prs_struct *ps, int depth);
+BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS *q_e, POLICY_HND *pol,
+ uint32 start_idx, uint32 size);
+BOOL samr_io_q_enum_domains(char *desc, SAMR_Q_ENUM_DOMAINS *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS *r_u,
+ uint32 next_idx, uint32 num_sam_entries);
+BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
+ uint32 start_idx, uint32 size);
+BOOL samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
+ uint32 next_idx, uint32 num_sam_entries);
+BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol,
+ uint32 start_idx, uint32 size);
+BOOL samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
+ uint32 next_idx,
+ uint32 num_sam_entries);
+BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth);
+BOOL make_samr_alias_info3(ALIAS_INFO3 *al3, const char *acct_desc);
+BOOL samr_io_alias_info3(char *desc, ALIAS_INFO3 *al3, prs_struct *ps, int depth);
+BOOL samr_alias_info_ctr(char *desc, ALIAS_INFO_CTR *ctr, prs_struct *ps, int depth);
+BOOL make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
+ POLICY_HND *pol,
+ uint16 switch_level);
+BOOL samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u, ALIAS_INFO_CTR *ctr,
+ uint32 status);
+BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO *q_u, POLICY_HND *hnd,
+ ALIAS_INFO_CTR *ctr);
+BOOL samr_io_q_set_aliasinfo(char *desc, SAMR_Q_SET_ALIASINFO *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_set_aliasinfo(char *desc, SAMR_R_SET_ALIASINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
+ const POLICY_HND *hnd,
+ uint32 *ptr_sid, DOM_SID2 *sid);
+BOOL samr_io_q_query_useraliases(char *desc, SAMR_Q_QUERY_USERALIASES *q_u, prs_struct *ps, int depth);
+void samr_free_q_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u);
+BOOL make_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES *r_u,
+ uint32 num_rids, uint32 *rid, uint32 status);
+BOOL samr_io_rids(char *desc, uint32 *num_rids, uint32 **rid, prs_struct *ps, int depth);
+BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u, const POLICY_HND *pol,
+ uint32 unknown_0, uint32 rid);
+BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
+ const POLICY_HND *pol, uint32 flags,
+ uint32 num_rids, const uint32 *rid);
+BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS *q_u, prs_struct *ps, int depth);
+void samr_free_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u);
+BOOL make_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u,
+ uint32 num_names, UNIHDR *hdr_name, UNISTR2 *uni_name,
+ uint32 *type);
+BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS *r_u, prs_struct *ps, int depth);
+void samr_free_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u);
+BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS *q_u, POLICY_HND *hnd);
+BOOL samr_io_q_delete_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_delete_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u, POLICY_HND *hnd,
+ const char *acct_desc);
+BOOL samr_io_q_create_dom_alias(char *desc, SAMR_Q_CREATE_DOM_ALIAS *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_create_dom_alias(char *desc, SAMR_R_CREATE_DOM_ALIAS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u, POLICY_HND *hnd,
+ DOM_SID *sid);
+BOOL samr_io_q_add_aliasmem(char *desc, SAMR_Q_ADD_ALIASMEM *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM *q_u, POLICY_HND *hnd,
+ DOM_SID *sid);
+BOOL samr_io_q_del_aliasmem(char *desc, SAMR_Q_DEL_ALIASMEM *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_del_aliasmem(char *desc, SAMR_R_DEL_ALIASMEM *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS *q_c, POLICY_HND *hnd);
+BOOL samr_io_q_delete_dom_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS *r_u,
+ uint32 status);
+BOOL samr_io_r_delete_dom_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_c,
+ const POLICY_HND *hnd);
+BOOL samr_io_q_query_aliasmem(char *desc, SAMR_Q_QUERY_ALIASMEM *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM *r_u,
+ uint32 num_sids, DOM_SID2 *sid, uint32 status);
+BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
+ const POLICY_HND *pol, uint32 flags,
+ uint32 num_names, char **name);
+BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth);
+void samr_free_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_l);
+BOOL make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
+ uint32 num_rids,
+ const uint32 *rid, const uint32 *type,
+ uint32 status);
+BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth);
+void samr_free_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_l);
+BOOL make_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER *q_c, POLICY_HND *hnd);
+BOOL samr_io_q_delete_dom_user(char *desc, SAMR_Q_DELETE_DOM_USER *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_delete_dom_user(char *desc, SAMR_R_DELETE_DOM_USER *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
+ const POLICY_HND *pol,
+ uint32 access_mask, uint32 rid);
+BOOL samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_create_user(SAMR_Q_CREATE_USER *q_u,
+ POLICY_HND *pol,
+ const char *name,
+ uint16 acb_info, uint32 access_mask);
+BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
+ POLICY_HND *hnd, uint16 switch_value);
+BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth);
+BOOL make_sam_user_info12(SAM_USER_INFO_12 *usr,
+ uint16 acb_info,
+ const uint8 lm_pwd[16],
+ const uint8 nt_pwd[16]);
+BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 *u, prs_struct *ps, int depth);
+BOOL make_sam_user_info10(SAM_USER_INFO_10 *usr,
+ uint32 acb_info);
+BOOL sam_io_user_info10(char *desc, SAM_USER_INFO_10 *usr, prs_struct *ps, int depth);
+BOOL make_sam_user_info11(SAM_USER_INFO_11 *usr,
+ NTTIME *expiry,
+ char *mach_acct,
+ uint32 rid_user,
+ uint32 rid_group,
+ uint16 acct_ctrl);
+BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int depth);
+BOOL make_sam_user_info24(SAM_USER_INFO_24 *usr,
+ const char newpass[516], uint16 passlen);
+BOOL make_sam_user_info23W(SAM_USER_INFO_23 *usr,
+
+ const NTTIME *logon_time, /* all zeros */
+ const NTTIME *logoff_time, /* all zeros */
+ const NTTIME *kickoff_time, /* all zeros */
+ const NTTIME *pass_last_set_time, /* all zeros */
+ const NTTIME *pass_can_change_time, /* all zeros */
+ const NTTIME *pass_must_change_time, /* all zeros */
+
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *desc,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial,
+
+ uint32 user_rid, /* 0x0000 0000 */
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS *hrs,
+ uint32 unknown_5,
+ char newpass[516]
+#if 0
+ , uint32 unknown_6
+#endif
+ );
+BOOL make_sam_user_info23A(SAM_USER_INFO_23 *usr,
+
+ NTTIME *logon_time, /* all zeros */
+ NTTIME *logoff_time, /* all zeros */
+ NTTIME *kickoff_time, /* all zeros */
+ NTTIME *pass_last_set_time, /* all zeros */
+ NTTIME *pass_can_change_time, /* all zeros */
+ NTTIME *pass_must_change_time, /* all zeros */
+
+ char *user_name, /* NULL */
+ char *full_name,
+ char *home_dir,
+ char *dir_drive,
+ char *log_scr,
+ char *prof_path,
+ char *desc,
+ char *wkstas,
+ char *unk_str,
+ char *mung_dial,
+
+ uint32 user_rid, /* 0x0000 0000 */
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS *hrs,
+ uint32 unknown_5,
+ char newpass[516]
+#if 0
+ , uint32 unknown_6
+#endif
+ );
+BOOL make_sam_user_info21W(SAM_USER_INFO_21 *usr,
+
+ const NTTIME *logon_time,
+ const NTTIME *logoff_time,
+ const NTTIME *kickoff_time,
+ const NTTIME *pass_last_set_time,
+ const NTTIME *pass_can_change_time,
+ const NTTIME *pass_must_change_time,
+
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *desc,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial,
+
+ const uchar lm_pwd[16],
+ const uchar nt_pwd[16],
+
+ uint32 user_rid,
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ const LOGON_HRS *hrs,
+ uint32 unknown_5,
+ uint32 unknown_6);
+BOOL make_sam_user_info21A(SAM_USER_INFO_21 *usr,
+
+ NTTIME *logon_time,
+ NTTIME *logoff_time,
+ NTTIME *kickoff_time,
+ NTTIME *pass_last_set_time,
+ NTTIME *pass_can_change_time,
+ NTTIME *pass_must_change_time,
+
+ char *user_name,
+ char *full_name,
+ char *home_dir,
+ char *dir_drive,
+ char *log_scr,
+ char *prof_path,
+ char *desc,
+ char *wkstas,
+ char *unk_str,
+ char *mung_dial,
+
+ uint32 user_rid,
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS *hrs,
+ uint32 unknown_5,
+ uint32 unknown_6);
+BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *ps, int depth);
+uint32 make_samr_userinfo_ctr_usr21(SAM_USERINFO_CTR *ctr,
+ uint16 switch_value,
+ const SAM_USER_INFO_21 *usr);
+BOOL make_samr_userinfo_ctr(SAM_USERINFO_CTR *ctr, const uchar *sess_key,
+ uint16 switch_value, void *info);
+BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR *ctr, prs_struct *ps, int depth);
+void free_samr_userinfo_ctr(SAM_USERINFO_CTR *ctr);
+BOOL make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
+ SAM_USERINFO_CTR *ctr, uint32 status);
+BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
+ POLICY_HND *hnd,
+ uint16 switch_value, void *info);
+BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps, int depth);
+void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u);
+BOOL make_samr_r_set_userinfo(SAMR_R_SET_USERINFO *r_u, uint32 status);
+BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
+ POLICY_HND *hnd,
+ uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, prs_struct *ps, int depth);
+void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u);
+BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 *r_u,
+ uint32 status);
+BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_connect(SAMR_Q_CONNECT *q_u,
+ const char *srv_name, uint32 access_mask);
+BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u);
+BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_get_dom_pwinfo(SAMR_Q_GET_DOM_PWINFO *q_u, const char *srv_name);
+BOOL samr_io_q_get_dom_pwinfo(char *desc, SAMR_Q_GET_DOM_PWINFO *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_get_dom_pwinfo(char *desc, SAMR_R_GET_DOM_PWINFO *r_u, prs_struct *ps, int depth);
+BOOL make_enc_passwd(SAMR_ENC_PASSWD *pwd, const char pass[512]);
+BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth);
+BOOL make_enc_hash(SAMR_ENC_HASH *hsh, const uchar hash[16]);
+BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth);
+BOOL make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+ const char *dest_host, const char *user_name,
+ const char nt_newpass[516],
+ const uchar nt_oldhash[16],
+ const char lm_newpass[516],
+ const uchar lm_oldhash[16]);
+BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status);
+BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_sec.c */
+
+BOOL make_sec_access(SEC_ACCESS *t, uint32 mask);
+BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth);
+BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag);
+BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth);
+BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace);
+void free_sec_acl(SEC_ACL *t);
+BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth);
+int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
+ DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL *sacl, SEC_ACL *dacl);
+void free_sec_desc(SEC_DESC *t);
+BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth);
+BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data);
+void free_sec_desc_buf(SEC_DESC_BUF *buf);
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_spoolss.c */
+
+BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime);
+BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
+ prs_struct *ps, int depth);
+BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
+ const char *printername,
+ uint32 cbbuf, uint32 devmod, uint32 des_access,
+ const char *station,
+ const char *username);
+BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
+ POLICY_HND *handle,
+ char *valuename,
+ uint32 size);
+BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd);
+BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u,
+ prs_struct *ps, int depth);
+BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u,
+ prs_struct *ps, int depth);
+BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u,
+ prs_struct *ps, int depth);
+BOOL spoolss_io_r_rfnpcnex(char *desc,
+ SPOOL_R_RFNPCNEX *r_u,
+ prs_struct *ps, int depth);
+BOOL spoolss_io_free_buffer(BUFFER *buffer);
+BOOL spoolss_io_q_getprinterdriver2(char *desc,
+ SPOOL_Q_GETPRINTERDRIVER2 *q_u,
+ prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u,
+ prs_struct *ps, int depth);
+BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u,
+ uint32 flags,
+ const char* servername,
+ uint32 level,
+ uint32 size);
+BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u,
+ prs_struct *ps, int depth);
+void free_r_enumprinters(SPOOL_R_ENUMPRINTERS *r_u);
+BOOL spoolss_io_r_enumprinters(char *desc,
+ SPOOL_R_ENUMPRINTERS *r_u,
+ prs_struct *ps, int depth);
+BOOL spoolss_io_r_getprinter(char *desc,
+ SPOOL_R_GETPRINTER *r_u,
+ prs_struct *ps, int depth);
+BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u,
+ POLICY_HND *hnd,
+ uint32 level,
+ uint32 buf_size);
+BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u,
+ prs_struct *ps, int depth);
+BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth);
+void free_job_info_ctr(JOB_INFO_CTR *ctr, uint32 level, uint32 numofjobs);
+void free_r_enumjobs(SPOOL_R_ENUMJOBS *r_u);
+BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth);
+BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
+ uint32 firstjob,
+ uint32 numofjobs,
+ uint32 level,
+ uint32 buf_size);
+BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth);
+void free_spoolss_r_enumdrivers(SPOOL_R_ENUMPRINTERDRIVERS *r_u);
+BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth);
+void spoolss_free_r_enumforms(SPOOL_R_ENUMFORMS *r_u);
+BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth);
+void spoolss_free_r_enumports(SPOOL_R_ENUMPORTS *r_u);
+BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth);
+BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, prs_struct *ps, int depth);
+BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth);
+BOOL spool_io_user_level_1(char *desc, SPOOL_USER_LEVEL_1 **q_u, prs_struct *ps, int depth);
+BOOL spool_io_user_level(char *desc, SPOOL_USER_LEVEL *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth);
+BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u,
+ prs_struct *ps, int depth);
+BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar);
+BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth);
+BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth);
+BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth);
+BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
+ NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc);
+BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
+ NT_PRINTER_INFO_LEVEL_2 **asc);
+BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth);
+BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
+ uint32 type, const uint8 *data, uint32 len);
+BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth);
+BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth);
+void free_spoolss_r_getjob(SPOOL_R_GETJOB *r_u);
+BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth);
+void free_devmode(DEVICEMODE *devmode);
+void free_printer_info_2(PRINTER_INFO_2 *printer);
+void free_print2_array(uint32 num_entries, PRINTER_INFO_2 **entries);
+PRINTER_INFO_2 *add_print2_to_array(uint32 *len, PRINTER_INFO_2 ***array,
+ const PRINTER_INFO_2 *prt);
+void free_print1_array(uint32 num_entries, PRINTER_INFO_1 **entries);
+PRINTER_INFO_1 *add_print1_to_array(uint32 *len, PRINTER_INFO_1 ***array,
+ const PRINTER_INFO_1 *prt);
+void free_job1_array(uint32 num_entries, JOB_INFO_1 **entries);
+JOB_INFO_1 *add_job1_to_array(uint32 *len, JOB_INFO_1 ***array,
+ const JOB_INFO_1 *job);
+void free_job_info_2(JOB_INFO_2 *job);
+void free_job2_array(uint32 num_entries, JOB_INFO_2 **entries);
+JOB_INFO_2 *add_job2_to_array(uint32 *len, JOB_INFO_2 ***array,
+ const JOB_INFO_2 *job);
+
+/*The following definitions come from rpc_parse/parse_srv.c */
+
+BOOL make_srv_share_info1_str(SH_INFO_1_STR *sh1,
+ const char *net_name, const char *remark);
+BOOL make_srv_share_info1(SH_INFO_1 *sh1,
+ const char *net_name, uint32 type,
+ const char *remark);
+BOOL make_srv_share_info2_str(SH_INFO_2_STR *sh2,
+ const char *net_name, const char *remark,
+ const char *path, const char *pass);
+BOOL make_srv_share_info2(SH_INFO_2 *sh2,
+ const char *net_name, uint32 type,
+ const char *remark,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ const char *path, const char *pass);
+void srv_free_srv_share_ctr(SRV_SHARE_INFO_CTR *ctr);
+BOOL make_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
+ const char *srv_name,
+ uint32 share_level, SRV_SHARE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_io_q_net_share_enum(char *desc, SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth);
+BOOL make_srv_q_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n,
+ const UNISTR2 *srv_name,
+ const UNISTR2 *share_name,
+ uint32 info_level);
+BOOL srv_io_q_net_share_get_info(char *desc, SRV_Q_NET_SHARE_GET_INFO *q_n,
+ prs_struct *ps, int depth);
+BOOL make_srv_r_net_share_get_info(SRV_R_NET_SHARE_GET_INFO *r_n,
+ uint32 info_level,
+ SHARE_INFO_CTR *ctr,
+ uint32 status);
+BOOL srv_io_r_net_share_get_info(char *desc, SRV_R_NET_SHARE_GET_INFO *r_n,
+ prs_struct *ps, int depth);
+BOOL make_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name);
+BOOL make_srv_sess_info0(SESS_INFO_0 *ss0, char *name);
+BOOL make_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user);
+BOOL make_srv_sess_info1(SESS_INFO_1 *ss1,
+ char *name, char *user,
+ uint32 num_opens, uint32 open_time, uint32 idle_time,
+ uint32 user_flags);
+BOOL make_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
+ const char *srv_name, const char *qual_name,
+ char *user_name,
+ uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_io_q_net_sess_enum(char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_sess_enum(char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth);
+BOOL make_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id);
+BOOL make_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name);
+BOOL make_srv_conn_info1(CONN_INFO_1 *ss1,
+ uint32 id, uint32 type,
+ uint32 num_opens, uint32 num_users, uint32 open_time,
+ char *usr_name, char *net_name);
+BOOL make_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
+ const char *srv_name, const char *qual_name,
+ uint32 conn_level, SRV_CONN_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_io_q_net_conn_enum(char *desc, SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_conn_enum(char *desc, SRV_R_NET_CONN_ENUM *r_n, prs_struct *ps, int depth);
+BOOL make_srv_tprt_info0_str(TPRT_INFO_0_STR *tp0,
+ char *trans_name,
+ char *trans_addr, uint32 trans_addr_len,
+ char *addr_name);
+BOOL make_srv_tprt_info0(TPRT_INFO_0 *tp0,
+ uint32 num_vcs, uint32 trans_addr_len,
+ char *trans_name, char *trans_addr,
+ char *addr_name);
+void free_srv_tprt_info_0(SRV_TPRT_INFO_0 *tp0);
+void free_srv_tprt_ctr(SRV_TPRT_INFO_CTR *ctr);
+BOOL make_srv_q_net_tprt_enum(SRV_Q_NET_TPRT_ENUM *q_n,
+ const char *srv_name,
+ uint32 tprt_level, SRV_TPRT_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_io_q_net_tprt_enum(char *desc, SRV_Q_NET_TPRT_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_tprt_enum(char *desc, SRV_R_NET_TPRT_ENUM *r_n, prs_struct *ps, int depth);
+BOOL make_srv_file_info3_str(FILE_INFO_3_STR *fi3,
+ const char *path_name, const char *user_name);
+BOOL make_srv_file_info3(FILE_INFO_3 *fl3,
+ uint32 id, uint32 perms, uint32 num_locks,
+ const char *path_name, const char *user_name);
+void srv_free_srv_file_ctr(SRV_FILE_INFO_CTR *ctr);
+BOOL make_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
+ const char *srv_name, const char *qual_name,
+ uint32 file_id,
+ uint32 file_level, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd);
+BOOL srv_io_q_net_file_enum(char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth);
+BOOL srv_io_r_net_file_enum(char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth);
+BOOL make_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
+ char *server_name, uint32 switch_value);
+BOOL srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth);
+BOOL make_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
+ uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status);
+BOOL srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth);
+BOOL make_srv_q_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_t, char *server_name);
+BOOL srv_io_q_net_remote_tod(char *desc, SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth);
+BOOL make_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
+ uint32 hours, uint32 mins, uint32 secs, uint32 hunds,
+ uint32 zone, uint32 tintervals, uint32 day,
+ uint32 month, uint32 year, uint32 weekday);
+BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_svc.c */
+
+BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u,
+ const char *server, const char *database,
+ uint32 des_access);
+BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, int depth);
+BOOL svc_io_r_open_sc_man(char *desc, SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, int depth);
+BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE *q_u,
+ POLICY_HND *hnd,
+ const char *server,
+ uint32 des_access);
+BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps, int depth);
+BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth);
+BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE *q_c, POLICY_HND *hnd,
+ uint32 unk);
+BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE *q_s, prs_struct *ps, int depth);
+BOOL svc_io_r_stop_service(char *desc, SVC_R_STOP_SERVICE *r_s, prs_struct *ps, int depth);
+BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd,
+ uint32 argc,
+ char **argv);
+BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps, int depth);
+BOOL svc_io_r_start_service(char *desc, SVC_R_START_SERVICE *r_s, prs_struct *ps, int depth);
+BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG *q_u,
+ uint32 service_type, uint32 start_type,
+ uint32 error_control,
+ char* bin_path_name, char* load_order_grp,
+ uint32 tag_id,
+ char* dependencies, char* service_start_name,
+ char* disp_name);
+BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG *q_u, prs_struct *ps, int depth);
+BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd,
+ uint32 service_type, uint32 service_state,
+ uint32 buf_size, uint32 resume_hnd );
+BOOL svc_io_q_enum_svcs_status(char *desc, SVC_Q_ENUM_SVCS_STATUS *q_u, prs_struct *ps, int depth);
+BOOL make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS *r_c,
+ ENUM_SRVC_STATUS *svcs, uint32 more_buf_size,
+ uint32 num_svcs, ENUM_HND *resume_hnd,
+ uint32 dos_status);
+BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_struct *ps, int depth);
+BOOL svc_io_svc_status(char *desc, SVC_STATUS *svc, prs_struct *ps, int depth);
+BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG *q_c, POLICY_HND *hnd,
+ uint32 buf_size);
+BOOL svc_io_q_query_svc_config(char *desc, SVC_Q_QUERY_SVC_CONFIG *q_u, prs_struct *ps, int depth);
+BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c,
+ QUERY_SERVICE_CONFIG *cfg,
+ uint32 buf_size);
+BOOL svc_io_r_query_svc_config(char *desc, SVC_R_QUERY_SVC_CONFIG *r_u, prs_struct *ps, int depth);
+BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME *q_u, prs_struct *ps, int depth);
+BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME *r_u, prs_struct *ps, int depth);
+BOOL make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd);
+BOOL svc_io_q_close(char *desc, SVC_Q_CLOSE *q_u, prs_struct *ps, int depth);
+BOOL svc_io_r_close(char *desc, SVC_R_CLOSE *r_u, prs_struct *ps, int depth);
+BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG *q_u, POLICY_HND *hnd,
+ uint32 service_type, uint32 start_type,
+ uint32 unknown_0,
+ uint32 error_control,
+ char* bin_path_name, char* load_order_grp,
+ uint32 tag_id,
+ char* dependencies, char* service_start_name,
+ char* password,
+ char* disp_name);
+BOOL svc_io_q_change_svc_config(char *desc, SVC_Q_CHANGE_SVC_CONFIG *q_u, prs_struct *ps, int depth);
+BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG *r_c,
+ uint32 unknown_0, uint32 status);
+BOOL svc_io_r_change_svc_config(char *desc, SVC_R_CHANGE_SVC_CONFIG *r_u, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_wks.c */
+
+BOOL make_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
+ char *server, uint16 switch_value) ;
+BOOL wks_io_q_query_info(char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth);
+BOOL make_wks_info_100(WKS_INFO_100 *inf,
+ uint32 platform_id, uint32 ver_major, uint32 ver_minor,
+ char *my_name, char *domain_name);
+BOOL make_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
+ uint32 switch_value, WKS_INFO_100 *wks100,
+ int status) ;
+BOOL wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth);
+#endif /* _RPC_PARSE_PROTO_H_ */
diff --git a/source/include/rpc_reg.h b/source/include/rpc_reg.h
index 77660525888..87c614ee873 100644
--- a/source/include/rpc_reg.h
+++ b/source/include/rpc_reg.h
@@ -26,6 +26,7 @@
/* winreg pipe defines */
+#define REG_OPEN_HKCR 0x00
#define REG_OPEN_HKLM 0x02
#define REG_OPEN_HKU 0x04
#define REG_FLUSH_KEY 0x0B
@@ -42,22 +43,44 @@
#define REG_OPEN_ENTRY 0x0f
#define REG_INFO 0x11
#define REG_CLOSE 0x05
+#define REG_SHUTDOWN 0x18
-#define HKEY_LOCAL_MACHINE 0x80000000
+#define HKEY_CLASSES_ROOT 0x80000000
+#define HKEY_CURRENT_USER 0x80000001
+#define HKEY_LOCAL_MACHINE 0x80000002
#define HKEY_USERS 0x80000003
+/* REG_Q_OPEN_HKCR */
+typedef struct q_reg_open_hkcr_info
+{
+ uint32 ptr;
+ uint16 unknown_0; /* 0x5428 - 16 bit unknown */
+ uint16 unknown_1; /* random. changes */
+ uint32 level; /* 0x0200 0000 */
+
+} REG_Q_OPEN_HKCR;
+
+/* REG_R_OPEN_HKCR */
+typedef struct r_reg_open_hkcr_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} REG_R_OPEN_HKCR;
+
+
/* REG_Q_OPEN_HKLM */
-typedef struct q_reg_open_policy_info
+typedef struct q_reg_open_hklm_info
{
uint32 ptr;
uint16 unknown_0; /* 0xE084 - 16 bit unknown */
uint16 unknown_1; /* random. changes */
- uint32 level; /* 0x0000 0002 - 32 bit unknown */
+ uint32 access_mask; /* 0x0000 0002 - 32 bit unknown */
} REG_Q_OPEN_HKLM ;
/* REG_R_OPEN_HKLM */
-typedef struct r_reg_open_policy_info
+typedef struct r_reg_open_hklm_info
{
POLICY_HND pol; /* policy handle */
uint32 status; /* return status */
@@ -66,7 +89,7 @@ typedef struct r_reg_open_policy_info
/* REG_Q_OPEN_HKU */
-typedef struct q_reg_open_unk4_info
+typedef struct q_reg_open_hku_info
{
uint32 ptr;
uint16 unknown_0; /* 0xE084 - 16 bit unknown */
@@ -76,7 +99,7 @@ typedef struct q_reg_open_unk4_info
} REG_Q_OPEN_HKU;
/* REG_R_OPEN_HKU */
-typedef struct r_reg_open_unk4_info
+typedef struct r_reg_open_hku_info
{
POLICY_HND pol; /* policy handle */
uint32 status; /* return status */
@@ -136,8 +159,6 @@ typedef struct q_reg_get_key_sec_info
/* REG_R_GET_KEY_SEC */
typedef struct r_reg_get_key_sec_info
{
- uint32 sec_info; /* xxxx_SECURITY_INFORMATION */
-
uint32 ptr; /* pointer */
BUFHDR hdr_sec; /* header for security data */
SEC_DESC_BUF *data; /* security data */
@@ -398,39 +419,37 @@ typedef struct q_reg_info_info
{
POLICY_HND pol; /* policy handle */
- UNIHDR hdr_type; /* unicode product type header */
- UNISTR2 uni_type; /* unicode product type - "ProductType" */
+ UNIHDR hdr_val; /* unicode product type header */
+ UNISTR2 uni_val; /* unicode product type - "ProductType" */
- uint32 ptr1; /* pointer */
- NTTIME time; /* current time? */
- uint8 major_version1; /* 0x4 - os major version? */
- uint8 minor_version1; /* 0x1 - os minor version? */
- uint8 pad1[10]; /* padding - zeros */
+ uint32 ptr_type; /* pointer */
+ uint32 type; /* type of buffer */
- uint32 ptr2; /* pointer */
- uint8 major_version2; /* 0x4 - os major version? */
- uint8 minor_version2; /* 0x1 - os minor version? */
- uint8 pad2[2]; /* padding - zeros */
+ uint32 ptr_uni_type; /* pointer to o/s type */
+ BUFFER2 uni_type; /* unicode string o/s type - "LanmanNT" */
- uint32 ptr3; /* pointer */
- uint32 unknown; /* 0x0000 0000 */
+ uint32 ptr_max_len; /* pointer to unknown_0 */
+ uint32 buf_max_len; /* 0x12 */
+
+ uint32 ptr_len; /* pointer to unknown_1 */
+ uint32 buf_len; /* 0x12 */
} REG_Q_INFO;
/* REG_R_INFO */
typedef struct r_reg_info_info
{
- uint32 ptr1; /* buffer pointer */
- uint32 level; /* 0x1 - info level? */
+ uint32 ptr_type; /* buffer pointer */
+ uint32 *type; /* 0x1 - info level? */
- uint32 ptr_type; /* pointer to o/s type */
- BUFFER2 uni_type; /* unicode string o/s type - "LanmanNT" */
+ uint32 ptr_uni_type; /* pointer to o/s type */
+ BUFFER2 *uni_type; /* unicode string o/s type - "LanmanNT" */
- uint32 ptr2; /* pointer to unknown_0 */
- uint32 unknown_0; /* 0x12 */
+ uint32 ptr_max_len; /* pointer to unknown_0 */
+ uint32 buf_max_len; /* 0x12 */
- uint32 ptr3; /* pointer to unknown_1 */
- uint32 unknown_1; /* 0x12 */
+ uint32 ptr_len; /* pointer to unknown_1 */
+ uint32 buf_len; /* 0x12 */
uint32 status; /* return status */
@@ -446,7 +465,7 @@ typedef struct q_reg_open_entry_info
UNISTR2 uni_name; /* unicode registry string name */
uint32 unknown_0; /* 32 bit unknown - 0x0000 0000 */
- uint32 unknown_1; /* 32 bit unknown - 0x0200 0000 */
+ uint32 access_mask; /* 32 bit unknown - 0x0200 0000 */
} REG_Q_OPEN_ENTRY;
@@ -461,6 +480,26 @@ typedef struct r_reg_open_entry_info
} REG_R_OPEN_ENTRY;
+/* REG_Q_SHUTDOWN */
+typedef struct q_reg_shutdown_info
+{
+ uint32 ptr_0;
+ uint32 ptr_1;
+ uint32 ptr_2;
+ UNIHDR hdr_msg; /* shutdown message */
+ UNISTR2 uni_msg;
+ uint32 timeout; /* seconds */
+ uint16 flags;
+
+} REG_Q_SHUTDOWN;
+
+/* REG_R_SHUTDOWN */
+typedef struct r_reg_shutdown_info
+{
+ uint32 status; /* return status */
+
+} REG_R_SHUTDOWN;
+
#endif /* _RPC_REG_H */
diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index 26dd2bf4476..3ae3f5ae404 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -2,9 +2,9 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Paul Ashton 1997
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1998
+ Copyright (C) Paul Ashton 1997-1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -32,18 +32,18 @@
the following information comes from a QuickView on samsrv.dll,
and gives an idea of exactly what is needed:
-SamrAddMemberToAlias
-SamrAddMemberToGroup
+x SamrAddMemberToAlias
+x SamrAddMemberToGroup
SamrAddMultipleMembersToAlias
-SamrChangePasswordUser
+x SamrChangePasswordUser
x SamrCloseHandle
x SamrConnect
-SamrCreateAliasInDomain
-SamrCreateGroupInDomain
-SamrCreateUserInDomain
-SamrDeleteAlias
+x SamrCreateAliasInDomain
+x SamrCreateGroupInDomain
+x SamrCreateUserInDomain
+? SamrDeleteAlias
SamrDeleteGroup
-SamrDeleteUser
+x SamrDeleteUser
x SamrEnumerateAliasesInDomain
SamrEnumerateDomainsInSamServer
x SamrEnumerateGroupsInDomain
@@ -54,21 +54,21 @@ SamrLookupDomainInSamServer
x SamrLookupNamesInDomain
x SamrOpenAlias
x SamrOpenDomain
-SamrOpenGroup
+x SamrOpenGroup
x SamrOpenUser
x SamrQueryDisplayInformation
x SamrQueryInformationAlias
SamrQueryInformationDomain
? SamrQueryInformationUser
-SamrQuerySecurityObject
+x SamrQuerySecurityObject
SamrRemoveMemberFromAlias
SamrRemoveMemberFromForiegnDomain
SamrRemoveMemberFromGroup
SamrRemoveMultipleMembersFromAlias
-SamrSetInformationAlias
+x SamrSetInformationAlias
SamrSetInformationDomain
-SamrSetInformationGroup
-SamrSetInformationUser
+x SamrSetInformationGroup
+x SamrSetInformationUser
SamrSetMemberAttributesOfGroup
SamrSetSecurityObject
SamrShutdownSamServer
@@ -77,30 +77,73 @@ SamrTestPrivateFunctionsUser
********************************************************************/
+#define SAMR_CONNECT_ANON 0x00
#define SAMR_CLOSE_HND 0x01
+#define SAMR_UNKNOWN_2 0x02 /* set sec object? */
+#define SAMR_QUERY_SEC_OBJECT 0x03
+
+#define SAMR_UNKNOWN_4 0x04 /* profile info? */
+#define SAMR_LOOKUP_DOMAIN 0x05
+#define SAMR_ENUM_DOMAINS 0x06
#define SAMR_OPEN_DOMAIN 0x07
#define SAMR_QUERY_DOMAIN_INFO 0x08
-#define SAMR_LOOKUP_IDS 0x10
+
+#define SAMR_CREATE_DOM_GROUP 0x0a
+#define SAMR_ENUM_DOM_GROUPS 0x0b
+#define SAMR_ENUM_DOM_USERS 0x0d
+#define SAMR_CREATE_DOM_ALIAS 0x0e
+#define SAMR_ENUM_DOM_ALIASES 0x0f
+#define SAMR_QUERY_USERALIASES 0x10
+
#define SAMR_LOOKUP_NAMES 0x11
-#define SAMR_UNKNOWN_3 0x03
-#define SAMR_QUERY_DISPINFO 0x28
+#define SAMR_LOOKUP_RIDS 0x12
+
+#define SAMR_OPEN_GROUP 0x13
+#define SAMR_QUERY_GROUPINFO 0x14
+#define SAMR_SET_GROUPINFO 0x15
+#define SAMR_ADD_GROUPMEM 0x16
+#define SAMR_DELETE_DOM_GROUP 0x17
+#define SAMR_DEL_GROUPMEM 0x18
+#define SAMR_QUERY_GROUPMEM 0x19
+#define SAMR_UNKNOWN_1A 0x1a
+
+#define SAMR_OPEN_ALIAS 0x1b
+#define SAMR_QUERY_ALIASINFO 0x1c
+#define SAMR_SET_ALIASINFO 0x1d
+#define SAMR_DELETE_DOM_ALIAS 0x1e
+#define SAMR_ADD_ALIASMEM 0x1f
+#define SAMR_DEL_ALIASMEM 0x20
+#define SAMR_QUERY_ALIASMEM 0x21
+
#define SAMR_OPEN_USER 0x22
+#define SAMR_DELETE_DOM_USER 0x23
#define SAMR_QUERY_USERINFO 0x24
+#define SAMR_SET_USERINFO2 0x25
#define SAMR_QUERY_USERGROUPS 0x27
-#define SAMR_UNKNOWN_12 0x12
-#define SAMR_UNKNOWN_21 0x21
-#define SAMR_UNKNOWN_2C 0x2c
-#define SAMR_UNKNOWN_32 0x32
-#define SAMR_UNKNOWN_34 0x34
+
+#define SAMR_QUERY_DISPINFO 0x28
+#define SAMR_UNKNOWN_29 0x29
+#define SAMR_UNKNOWN_2a 0x2a
+#define SAMR_UNKNOWN_2b 0x2b
+#define SAMR_GET_USRDOM_PWINFO 0x2c
+#define SAMR_UNKNOWN_2D 0x2d
+#define SAMR_UNKNOWN_2e 0x2e
+#define SAMR_UNKNOWN_2f 0x2f
+#define SAMR_QUERY_DISPINFO3 0x30 /* Alias for SAMR_QUERY_DISPINFO
+ with info level 3 */
+#define SAMR_UNKNOWN_31 0x31
+#define SAMR_CREATE_USER 0x32
+#define SAMR_QUERY_DISPINFO4 0x33 /* Alias for SAMR_QUERY_DISPINFO
+ with info level 4 */
+#define SAMR_ADDMULTI_ALIASMEM 0x34
+
+#define SAMR_UNKNOWN_35 0x35
+#define SAMR_UNKNOWN_36 0x36
#define SAMR_CHGPASSWD_USER 0x37
-#define SAMR_UNKNOWN_38 0x38
+#define SAMR_GET_DOM_PWINFO 0x38
#define SAMR_CONNECT 0x39
-#define SAMR_CONNECT_ANON 0x00
-#define SAMR_OPEN_ALIAS 0x1b
-#define SAMR_QUERY_ALIASINFO 0x1c
-#define SAMR_ENUM_DOM_USERS 0x0d
-#define SAMR_ENUM_DOM_ALIASES 0x0f
-#define SAMR_ENUM_DOM_GROUPS 0x30
+#define SAMR_SET_USERINFO 0x3A
+
typedef struct logon_hours_info
@@ -110,6 +153,78 @@ typedef struct logon_hours_info
} LOGON_HRS;
+/* SAM_USER_INFO_23 */
+typedef struct sam_user_info_23
+{
+ /* TIMES MAY NOT IN RIGHT ORDER!!!! */
+ NTTIME logon_time; /* logon time */
+ NTTIME logoff_time; /* logoff time */
+ NTTIME kickoff_time; /* kickoff time */
+ NTTIME pass_last_set_time; /* password last set time */
+ NTTIME pass_can_change_time; /* password can change time */
+ NTTIME pass_must_change_time; /* password must change time */
+
+ UNIHDR hdr_user_name; /* NULL - user name unicode string header */
+ UNIHDR hdr_full_name; /* user's full name unicode string header */
+ UNIHDR hdr_home_dir; /* home directory unicode string header */
+ UNIHDR hdr_dir_drive; /* home drive unicode string header */
+ UNIHDR hdr_logon_script; /* logon script unicode string header */
+ UNIHDR hdr_profile_path; /* profile path unicode string header */
+ UNIHDR hdr_acct_desc ; /* user description */
+ UNIHDR hdr_workstations; /* comma-separated workstations user can log in from */
+ UNIHDR hdr_unknown_str ; /* don't know what this is, yet. */
+ UNIHDR hdr_munged_dial ; /* munged path name and dial-back tel number */
+
+ uint8 lm_pwd[16]; /* lm user passwords */
+ uint8 nt_pwd[16]; /* nt user passwords */
+
+ uint32 user_rid; /* Primary User ID */
+ uint32 group_rid; /* Primary Group ID */
+
+ uint16 acb_info; /* account info (ACB_xxxx bit-mask) */
+ /* uint8 pad[2] */
+
+ uint32 unknown_3; /* 0x09f8 27fa */
+
+ uint16 logon_divs; /* 0x0000 00a8 which is 168 which is num hrs in a week */
+ /* uint8 pad[2] */
+ uint32 ptr_logon_hrs; /* pointer to logon hours */
+
+ uint8 padding1[8];
+
+ uint32 unknown_5; /* 0x0001 0000 */
+
+ uint8 pass[516];
+
+ UNISTR2 uni_user_name; /* NULL - username unicode string */
+ UNISTR2 uni_full_name; /* user's full name unicode string */
+ UNISTR2 uni_home_dir; /* home directory unicode string */
+ UNISTR2 uni_dir_drive; /* home directory drive unicode string */
+ UNISTR2 uni_logon_script; /* logon script unicode string */
+ UNISTR2 uni_profile_path; /* profile path unicode string */
+ UNISTR2 uni_acct_desc ; /* user description unicode string */
+ UNISTR2 uni_workstations; /* login from workstations unicode string */
+ UNISTR2 uni_unknown_str ; /* don't know what this is, yet. */
+ UNISTR2 uni_munged_dial ; /* munged path name and dial-back tel no */
+
+#if 0
+ uint32 unknown_6; /* 0x0000 04ec */
+ uint32 padding4;
+#endif
+
+ LOGON_HRS logon_hrs;
+
+} SAM_USER_INFO_23;
+
+/* SAM_USER_INFO_24 */
+typedef struct sam_user_info_24
+{
+ uint8 pass[516];
+ uint16 unk_0;
+
+} SAM_USER_INFO_24;
+
+
/* SAM_USER_INFO_21 */
typedef struct sam_user_info_21
{
@@ -169,6 +284,16 @@ typedef struct sam_user_info_21
} SAM_USER_INFO_21;
+/* SAM_USER_INFO_12 */
+typedef struct sam_user_info_12
+{
+ uint16 acb_info; /* account control bits */
+
+ uint8 lm_pwd[16]; /* lm user passwords */
+ uint8 nt_pwd[16]; /* nt user passwords */
+
+} SAM_USER_INFO_12;
+
/* SAM_USER_INFO_11 */
typedef struct sam_user_info_11
{
@@ -228,113 +353,59 @@ typedef struct q_samr_close_hnd_info
/* SAMR_R_CLOSE_HND - probably a policy handle close */
typedef struct r_samr_close_hnd_info
{
- POLICY_HND pol; /* policy handle */
+ POLICY_HND pol; /* policy handle */
uint32 status; /* return status */
} SAMR_R_CLOSE_HND;
/****************************************************************************
-SAMR_Q_UNKNOWN_2C - a "set user info" occurs just after this
+SAMR_Q_GET_USRDOM_PWINFO - a "set user info" occurs just after this
*****************************************************************************/
-/* SAMR_Q_UNKNOWN_2C */
-typedef struct q_samr_unknown_2c_info
+/* SAMR_Q_GET_USRDOM_PWINFO */
+typedef struct q_samr_usrdom_pwinfo_info
{
POLICY_HND user_pol; /* policy handle */
-} SAMR_Q_UNKNOWN_2C;
+} SAMR_Q_GET_USRDOM_PWINFO;
/****************************************************************************
-SAMR_R_UNKNOWN_2C - a "set user info" occurs just after this
+SAMR_R_GET_USRDOM_PWINFO - a "set user info" occurs just after this
*****************************************************************************/
-/* SAMR_R_UNKNOWN_2C */
-typedef struct r_samr_unknown_2c_info
+/* SAMR_R_GET_USRDOM_PWINFO */
+typedef struct r_samr_usrdom_pwinfo_info
{
uint32 unknown_0; /* 0x0016 0000 */
uint32 unknown_1; /* 0x0000 0000 */
uint32 status;
-} SAMR_R_UNKNOWN_2C;
+} SAMR_R_GET_USRDOM_PWINFO;
/****************************************************************************
-SAMR_Q_UNKNOWN_3 - info level 4. returns SIDs.
+SAMR_Q_QUERY_SEC_OBJ - info level 4. returns SIDs.
*****************************************************************************/
-/* SAMR_Q_UNKNOWN_3 - probably get domain info... */
-typedef struct q_samr_unknown_3_info
+/* SAMR_Q_QUERY_SEC_OBJ - probably get domain info... */
+typedef struct q_samr_query_sec_obj_info
{
POLICY_HND user_pol; /* policy handle */
- uint16 switch_value; /* 0x0000 0004 */
- /* uint8 pad[2] */
-
-} SAMR_Q_UNKNOWN_3;
-
-/* DOM_SID3 example:
- 0x14 0x035b 0x0002 S-1-1
- 0x18 0x07ff 0x000f S-1-5-20-DOMAIN_ALIAS_RID_ADMINS
- 0x18 0x07ff 0x000f S-1-5-20-DOMAIN_ALIAS_RID_ACCOUNT_OPS
- 0x24 0x0044 0x0002 S-1-5-21-nnn-nnn-nnn-0x03f1
- */
-
-/* DOM_SID3 example:
- 0x24 0x0044 0x0002 S-1-5-21-nnn-nnn-nnn-0x03ee
- 0x18 0x07ff 0x000f S-1-5-20-DOMAIN_ALIAS_RID_ADMINS
- 0x14 0x035b 0x0002 S-1-1
- */
-
-/* DOM_SID3 - security id */
-typedef struct sid_info_3
-{
- uint16 len; /* length, bytes, including length of len :-) */
- /* uint8 pad[2]; */
-
- DOM_SID sid;
-
-} DOM_SID3;
-
-
-#define MAX_SAM_SIDS 15
-
-/* SAM_SID_STUFF */
-typedef struct sid_stuff_info
-{
- uint16 unknown_2; /* 0x0001 */
- uint16 unknown_3; /* 0x8004 */
-
- uint8 padding1[8];
-
- uint32 unknown_4; /* 0x0000 0014 */
- uint32 unknown_5; /* 0x0000 0014 */
-
- uint16 unknown_6; /* 0x0002 */
- uint16 unknown_7; /* 0x5800 */
-
- uint32 num_sids;
-
- uint16 padding2;
+ uint32 sec_info; /* xxxx_SECURITY_INFORMATION 0x0000 0004 */
- DOM_SID3 sid[MAX_SAM_SIDS];
+} SAMR_Q_QUERY_SEC_OBJ;
-} SAM_SID_STUFF;
-
-/* SAMR_R_UNKNOWN_3 - probably an open */
-typedef struct r_samr_unknown_3_info
+/* SAMR_R_QUERY_SEC_OBJ - probably an open */
+typedef struct r_samr_query_sec_obj_info
{
- uint32 ptr_0;
- uint32 sid_stuff_len0;
-
- uint32 ptr_1;
- uint32 sid_stuff_len1;
-
- SAM_SID_STUFF sid_stuff;
+ uint32 ptr;
+ SEC_DESC_BUF buf;
uint32 status; /* return status */
-} SAMR_R_UNKNOWN_3;
+} SAMR_R_QUERY_SEC_OBJ;
/****************************************************************************
@@ -345,11 +416,33 @@ SAMR_Q_QUERY_DOMAIN_INFO - probably a query on domain group info.
typedef struct q_samr_query_domain_info
{
POLICY_HND domain_pol; /* policy handle */
- uint16 switch_value; /* 0x0002 */
+ uint16 switch_value; /* 0x0002, 0x0001 */
} SAMR_Q_QUERY_DOMAIN_INFO;
-typedef struct sam_unkown_info_2_info
+typedef struct sam_unknown_info_3_info
+{
+ uint32 unknown_0; /* 0x0000 0000 */
+ uint32 unknown_1; /* 0x8000 0000 */
+
+} SAM_UNK_INFO_3;
+
+typedef struct sam_unknown_info_6_info
+{
+ uint32 unknown_0; /* 0x0000 0000 */
+
+ uint32 ptr_0; /* pointer to unknown structure */
+ uint8 padding[12]; /* 12 bytes zeros */
+
+} SAM_UNK_INFO_6;
+
+typedef struct sam_unknown_info_7_info
+{
+ uint16 unknown_0; /* 0x0003 */
+
+} SAM_UNK_INFO_7;
+
+typedef struct sam_unknown_info_2_inf
{
uint32 unknown_0; /* 0x0000 0000 */
uint32 unknown_1; /* 0x8000 0000 */
@@ -380,12 +473,24 @@ typedef struct sam_unkown_info_2_info
} SAM_UNK_INFO_2;
+typedef struct sam_unknown_info_1_inf
+{
+ uint8 padding[12]; /* 12 bytes zeros */
+ uint32 unknown_1; /* 0x8000 0000 */
+ uint32 unknown_2; /* 0x0000 0000 */
+
+} SAM_UNK_INFO_1;
+
typedef struct sam_unknown_ctr_info
{
union
{
+ SAM_UNK_INFO_1 inf1;
SAM_UNK_INFO_2 inf2;
+ SAM_UNK_INFO_3 inf3;
+ SAM_UNK_INFO_6 inf6;
+ SAM_UNK_INFO_7 inf7;
} info;
@@ -405,6 +510,28 @@ typedef struct r_samr_query_domain_info
} SAMR_R_QUERY_DOMAIN_INFO;
+/* SAMR_Q_LOOKUP_DOMAIN - obtain SID for a local domain */
+typedef struct q_samr_lookup_domain_info
+{
+ POLICY_HND connect_pol;
+
+ UNIHDR hdr_domain;
+ UNISTR2 uni_domain;
+
+} SAMR_Q_LOOKUP_DOMAIN;
+
+
+/* SAMR_R_LOOKUP_DOMAIN */
+typedef struct r_samr_lookup_domain_info
+{
+ uint32 ptr_sid;
+ DOM_SID2 dom_sid;
+
+ uint32 status;
+
+} SAMR_R_LOOKUP_DOMAIN;
+
+
/****************************************************************************
SAMR_Q_OPEN_DOMAIN - unknown_0 values seen associated with SIDs:
@@ -416,7 +543,7 @@ SAMR_Q_OPEN_DOMAIN - unknown_0 values seen associated with SIDs:
typedef struct q_samr_open_domain_info
{
POLICY_HND connect_pol; /* policy handle */
- uint32 rid; /* 0x2000 0000; 0x0000 0211; 0x0000 0280; 0x0000 0200 - a RID? */
+ uint32 flags; /* 0x2000 0000; 0x0000 0211; 0x0000 0280; 0x0000 0200 - flags? */
DOM_SID2 dom_sid; /* domain SID */
} SAMR_Q_OPEN_DOMAIN;
@@ -430,7 +557,6 @@ typedef struct r_samr_open_domain_info
} SAMR_R_OPEN_DOMAIN;
-
#define MAX_SAM_ENTRIES 250
typedef struct samr_entry_info
@@ -440,13 +566,43 @@ typedef struct samr_entry_info
} SAM_ENTRY;
+
+/* SAMR_Q_ENUM_DOMAINS - SAM rids and names */
+typedef struct q_samr_enum_domains_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint32 start_idx; /* enumeration handle */
+ uint32 max_size; /* 0x0000 ffff */
+
+} SAMR_Q_ENUM_DOMAINS;
+
+/* SAMR_R_ENUM_DOMAINS - SAM rids and Domain names */
+typedef struct r_samr_enum_domains_info
+{
+ uint32 next_idx; /* next starting index required for enum */
+ uint32 ptr_entries1;
+
+ uint32 num_entries2;
+ uint32 ptr_entries2;
+
+ uint32 num_entries3;
+
+ SAM_ENTRY *sam;
+ UNISTR2 *uni_dom_name;
+
+ uint32 num_entries4;
+
+ uint32 status;
+
+} SAMR_R_ENUM_DOMAINS;
+
/* SAMR_Q_ENUM_DOM_USERS - SAM rids and names */
typedef struct q_samr_enum_dom_users_info
{
POLICY_HND pol; /* policy handle */
- uint16 req_num_entries; /* number of values (0 indicates unlimited?) */
- uint16 unknown_0; /* enumeration context? */
+ uint32 start_idx; /* number of values (0 indicates unlimited?) */
uint16 acb_mask; /* 0x0000 indicates all */
uint16 unknown_1; /* 0x0000 */
@@ -458,17 +614,16 @@ typedef struct q_samr_enum_dom_users_info
/* SAMR_R_ENUM_DOM_USERS - SAM rids and names */
typedef struct r_samr_enum_dom_users_info
{
- uint16 total_num_entries; /* number of entries that match without the acb mask */
- uint16 unknown_0; /* same as unknown_0 (enum context?) in request */
- uint32 ptr_entries1; /* actual number of entries to follow, having masked some out */
+ uint32 next_idx; /* next starting index required for enum */
+ uint32 ptr_entries1;
uint32 num_entries2;
uint32 ptr_entries2;
uint32 num_entries3;
- SAM_ENTRY sam[MAX_SAM_ENTRIES];
- UNISTR2 uni_acct_name[MAX_SAM_ENTRIES];
+ SAM_ENTRY *sam;
+ UNISTR2 *uni_acct_name;
uint32 num_entries4;
@@ -477,37 +632,15 @@ typedef struct r_samr_enum_dom_users_info
} SAMR_R_ENUM_DOM_USERS;
-typedef struct samr_entry_info3
-{
- uint32 grp_idx;
-
- uint32 rid_grp;
- uint32 attr;
-
- UNIHDR hdr_grp_name;
- UNIHDR hdr_grp_desc;
-
-} SAM_ENTRY3;
-
-typedef struct samr_str_entry_info3
-{
- UNISTR2 uni_grp_name;
- UNISTR2 uni_grp_desc;
-
-} SAM_STR3;
-
/* SAMR_Q_ENUM_DOM_GROUPS - SAM rids and names */
typedef struct q_samr_enum_dom_groups_info
{
POLICY_HND pol; /* policy handle */
- /* these are possibly an enumeration context handle... */
- uint16 switch_level; /* 0x0003 */
- uint16 unknown_0; /* 0x0000 */
- uint32 start_idx; /* presumably the start enumeration index */
- uint32 unknown_1; /* 0x0000 07d0 */
+ /* this is possibly an enumeration context handle... */
+ uint32 start_idx; /* 0x0000 0000 */
- uint32 max_size; /* 0x0000 7fff */
+ uint32 max_size; /* 0x0000 ffff */
} SAMR_Q_ENUM_DOM_GROUPS;
@@ -515,49 +648,50 @@ typedef struct q_samr_enum_dom_groups_info
/* SAMR_R_ENUM_DOM_GROUPS - SAM rids and names */
typedef struct r_samr_enum_dom_groups_info
{
- uint32 unknown_0; /* 0x0000 0492 or 0x0000 00be */
- uint32 unknown_1; /* 0x0000 049a or 0x0000 00be */
- uint32 switch_level; /* 0x0000 0003 */
-
- uint32 num_entries;
- uint32 ptr_entries;
+ uint32 next_idx;
+ uint32 ptr_entries1;
uint32 num_entries2;
+ uint32 ptr_entries2;
- SAM_ENTRY3 sam[MAX_SAM_ENTRIES];
- SAM_STR3 str[MAX_SAM_ENTRIES];
+ uint32 num_entries3;
+
+ SAM_ENTRY *sam;
+ UNISTR2 *uni_grp_name;
+
+ uint32 num_entries4;
uint32 status;
} SAMR_R_ENUM_DOM_GROUPS;
-
/* SAMR_Q_ENUM_DOM_ALIASES - SAM rids and names */
typedef struct q_samr_enum_dom_aliases_info
{
POLICY_HND pol; /* policy handle */
/* this is possibly an enumeration context handle... */
- uint32 unknown_0; /* 0x0000 0000 */
+ uint32 start_idx; /* 0x0000 0000 */
uint32 max_size; /* 0x0000 ffff */
} SAMR_Q_ENUM_DOM_ALIASES;
+
/* SAMR_R_ENUM_DOM_ALIASES - SAM rids and names */
typedef struct r_samr_enum_dom_aliases_info
{
- uint32 num_entries;
- uint32 ptr_entries;
+ uint32 next_idx;
+ uint32 ptr_entries1;
uint32 num_entries2;
uint32 ptr_entries2;
uint32 num_entries3;
- SAM_ENTRY sam[MAX_SAM_ENTRIES];
- UNISTR2 uni_grp_name[MAX_SAM_ENTRIES];
+ SAM_ENTRY *sam;
+ UNISTR2 *uni_grp_name;
uint32 num_entries4;
@@ -566,20 +700,7 @@ typedef struct r_samr_enum_dom_aliases_info
} SAMR_R_ENUM_DOM_ALIASES;
-
-/* SAMR_Q_QUERY_DISPINFO - SAM rids, names and descriptions */
-typedef struct q_samr_query_disp_info
-{
- POLICY_HND pol; /* policy handle */
-
- uint16 switch_level; /* 0x0001 and 0x0002 seen */
- uint16 unknown_0; /* 0x0000 and 0x2000 seen */
- uint32 start_idx; /* presumably the start enumeration index */
- uint32 unknown_1; /* 0x0000 07d0, 0x0000 0400 and 0x0000 0200 seen */
-
- uint32 max_size; /* 0x0000 7fff, 0x0000 7ffe and 0x0000 3fff seen*/
-
-} SAMR_Q_QUERY_DISPINFO;
+/* -- Level 1 Display Info - User Information -- */
typedef struct samr_entry_info1
{
@@ -605,15 +726,13 @@ typedef struct samr_str_entry_info1
typedef struct sam_entry_info_1
{
- uint32 num_entries;
- uint32 ptr_entries;
- uint32 num_entries2;
-
SAM_ENTRY1 sam[MAX_SAM_ENTRIES];
SAM_STR1 str[MAX_SAM_ENTRIES];
+} SAM_DISPINFO_1;
-} SAM_INFO_1;
+
+/* -- Level 2 Display Info - Trust Account Information -- */
typedef struct samr_entry_info2
{
@@ -637,45 +756,293 @@ typedef struct samr_str_entry_info2
typedef struct sam_entry_info_2
{
- uint32 num_entries;
- uint32 ptr_entries;
- uint32 num_entries2;
-
SAM_ENTRY2 sam[MAX_SAM_ENTRIES];
SAM_STR2 str[MAX_SAM_ENTRIES];
-} SAM_INFO_2;
+} SAM_DISPINFO_2;
+
+
+/* -- Level 3 Display Info - Domain Group Information -- */
+
+typedef struct samr_entry_info3
+{
+ uint32 grp_idx;
+
+ uint32 rid_grp;
+ uint32 attr; /* SE_GROUP_xxx, usually 7 */
+
+ UNIHDR hdr_grp_name;
+ UNIHDR hdr_grp_desc;
+
+} SAM_ENTRY3;
+
+typedef struct samr_str_entry_info3
+{
+ UNISTR2 uni_grp_name;
+ UNISTR2 uni_grp_desc;
+
+} SAM_STR3;
+
+typedef struct sam_entry_info_3
+{
+ SAM_ENTRY3 sam[MAX_SAM_ENTRIES];
+ SAM_STR3 str[MAX_SAM_ENTRIES];
+
+} SAM_DISPINFO_3;
+
+
+/* -- Level 4 Display Info - User List (ASCII) -- */
+
+typedef struct samr_entry_info4
+{
+ uint32 user_idx;
+ STRHDR hdr_acct_name;
+
+} SAM_ENTRY4;
-typedef struct sam_info_ctr_info
+typedef struct samr_str_entry_info4
+{
+ STRING2 acct_name;
+
+} SAM_STR4;
+
+typedef struct sam_entry_info_4
+{
+ SAM_ENTRY4 sam[MAX_SAM_ENTRIES];
+ SAM_STR4 str[MAX_SAM_ENTRIES];
+
+} SAM_DISPINFO_4;
+
+
+/* -- Level 5 Display Info - Group List (ASCII) -- */
+
+typedef struct samr_entry_info5
+{
+ uint32 grp_idx;
+ STRHDR hdr_grp_name;
+
+} SAM_ENTRY5;
+
+typedef struct samr_str_entry_info5
+{
+ STRING2 grp_name;
+
+} SAM_STR5;
+
+typedef struct sam_entry_info_5
+{
+ SAM_ENTRY5 sam[MAX_SAM_ENTRIES];
+ SAM_STR5 str[MAX_SAM_ENTRIES];
+
+} SAM_DISPINFO_5;
+
+
+typedef struct sam_dispinfo_ctr_info
{
union
{
- SAM_INFO_1 *info1; /* server info */
- SAM_INFO_2 *info2; /* user info */
+ SAM_DISPINFO_1 *info1; /* users/names/descriptions */
+ SAM_DISPINFO_2 *info2; /* trust accounts */
+ SAM_DISPINFO_3 *info3; /* domain groups/descriptions */
+ SAM_DISPINFO_4 *info4; /* user list (ASCII) - used by Win95 */
+ SAM_DISPINFO_5 *info5; /* group list (ASCII) */
void *info; /* allows assignment without typecasting, */
} sam;
-} SAM_INFO_CTR;
+} SAM_DISPINFO_CTR;
+
+
+/* SAMR_Q_QUERY_DISPINFO - SAM rids, names and descriptions */
+typedef struct q_samr_query_disp_info
+{
+ POLICY_HND domain_pol;
+
+ uint16 switch_level; /* see SAM_DISPINFO_CTR above */
+ /* align */
+
+ uint32 start_idx; /* start enumeration index */
+ uint32 max_entries; /* maximum number of entries to return */
+ uint32 max_size; /* recommended data size; if exceeded server
+ should return STATUS_MORE_ENTRIES */
+
+} SAMR_Q_QUERY_DISPINFO;
+
-/* SAMR_R_QUERY_DISPINFO - SAM rids, names and descriptions */
+/* SAMR_R_QUERY_DISPINFO */
typedef struct r_samr_query_dispinfo_info
{
- uint32 unknown_0; /* container length? 0x0000 0492 or 0x0000 00be */
- uint32 unknown_1; /* container length? 0x0000 049a or 0x0000 00be */
- uint16 switch_level; /* 0x0001 or 0x0002 */
- /*uint8 pad[2] */
+ uint32 total_size; /* total data size for all matching entries
+ (0 = uncalculated) */
+ uint32 data_size; /* actual data size returned = size of SAM_ENTRY
+ structures + total length of strings */
+
+ uint16 switch_level; /* see SAM_DISPINFO_CTR above */
+ /* align */
+
+ uint32 num_entries; /* number of entries returned */
+ uint32 ptr_entries;
+ uint32 num_entries2;
- SAM_INFO_CTR *ctr;
+ SAM_DISPINFO_CTR *ctr;
uint32 status;
} SAMR_R_QUERY_DISPINFO;
+/* SAMR_Q_DELETE_DOM_GROUP - delete domain group */
+typedef struct q_samr_delete_dom_group_info
+{
+ POLICY_HND group_pol; /* policy handle */
+
+} SAMR_Q_DELETE_DOM_GROUP;
+
+
+/* SAMR_R_DELETE_DOM_GROUP - delete domain group */
+typedef struct r_samr_delete_dom_group_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} SAMR_R_DELETE_DOM_GROUP;
+
+
+/* SAMR_Q_CREATE_DOM_GROUP - SAM create group */
+typedef struct q_samr_create_dom_group_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ UNIHDR hdr_acct_desc;
+ UNISTR2 uni_acct_desc;
+
+ uint32 access_mask;
+
+} SAMR_Q_CREATE_DOM_GROUP;
+
+/* SAMR_R_CREATE_DOM_GROUP - SAM create group */
+typedef struct r_samr_create_dom_group_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint32 rid;
+ uint32 status;
+
+} SAMR_R_CREATE_DOM_GROUP;
+
+/* SAMR_Q_QUERY_GROUPINFO - SAM Group Info */
+typedef struct q_samr_query_group_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint16 switch_level; /* 0x0001 seen */
+
+} SAMR_Q_QUERY_GROUPINFO;
+
+typedef struct samr_group_info1
+{
+ UNIHDR hdr_acct_name;
+
+ uint32 unknown_1; /* 0x0000 0003 - number of group members? */
+ uint32 num_members; /* 0x0000 0001 - number of group members? */
+
+ UNIHDR hdr_acct_desc;
+
+ UNISTR2 uni_acct_name;
+ UNISTR2 uni_acct_desc;
+
+} GROUP_INFO1;
+
+typedef struct samr_group_info4
+{
+ UNIHDR hdr_acct_desc;
+ UNISTR2 uni_acct_desc;
+
+} GROUP_INFO4;
+
+/* GROUP_INFO_CTR */
+typedef struct group_info_ctr
+{
+ uint16 switch_value1;
+ uint16 switch_value2;
+
+ union
+ {
+ GROUP_INFO4 info4;
+ GROUP_INFO1 info1;
+
+ } group;
+
+} GROUP_INFO_CTR;
+
+/* SAMR_R_QUERY_GROUPINFO - SAM Group Info */
+typedef struct r_samr_query_groupinfo_info
+{
+ uint32 ptr;
+ GROUP_INFO_CTR *ctr;
+
+ uint32 status;
+
+} SAMR_R_QUERY_GROUPINFO;
+
+
+/* SAMR_Q_SET_GROUPINFO - SAM Group Info */
+typedef struct q_samr_set_group_info
+{
+ POLICY_HND pol; /* policy handle */
+ GROUP_INFO_CTR *ctr;
+
+} SAMR_Q_SET_GROUPINFO;
+
+/* SAMR_R_SET_GROUPINFO - SAM Group Info */
+typedef struct r_samr_set_group_info
+{
+ uint32 status;
+
+} SAMR_R_SET_GROUPINFO;
+
+
+/* SAMR_Q_DELETE_DOM_ALIAS - delete domain alias */
+typedef struct q_samr_delete_dom_alias_info
+{
+ POLICY_HND alias_pol; /* policy handle */
+
+} SAMR_Q_DELETE_DOM_ALIAS;
+
+
+/* SAMR_R_DELETE_DOM_ALIAS - delete domain alias */
+typedef struct r_samr_delete_dom_alias_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} SAMR_R_DELETE_DOM_ALIAS;
+
+
+/* SAMR_Q_CREATE_DOM_ALIAS - SAM create alias */
+typedef struct q_samr_create_dom_alias_info
+{
+ POLICY_HND dom_pol; /* policy handle */
+
+ UNIHDR hdr_acct_desc;
+ UNISTR2 uni_acct_desc;
+
+ uint32 access_mask; /* 0x001f000f */
+
+} SAMR_Q_CREATE_DOM_ALIAS;
+
+/* SAMR_R_CREATE_DOM_ALIAS - SAM create alias */
+typedef struct r_samr_create_dom_alias_info
+{
+ POLICY_HND alias_pol; /* policy handle */
+
+ uint32 rid;
+ uint32 status;
+
+} SAMR_R_CREATE_DOM_ALIAS;
/* SAMR_Q_QUERY_ALIASINFO - SAM Alias Info */
-typedef struct q_samr_enum_alias_info
+typedef struct q_samr_query_alias_info
{
POLICY_HND pol; /* policy handle */
@@ -690,12 +1057,11 @@ typedef struct samr_alias_info3
} ALIAS_INFO3;
-/* SAMR_R_QUERY_ALIASINFO - SAM rids, names and descriptions */
-typedef struct r_samr_query_aliasinfo_info
+/* ALIAS_INFO_CTR */
+typedef struct alias_info_ctr
{
- uint32 ptr;
- uint16 switch_value; /* 0x0003 */
- /* uint8[2] padding */
+ uint16 switch_value1;
+ uint16 switch_value2;
union
{
@@ -703,11 +1069,35 @@ typedef struct r_samr_query_aliasinfo_info
} alias;
+} ALIAS_INFO_CTR;
+
+/* SAMR_R_QUERY_ALIASINFO - SAM alias info */
+typedef struct r_samr_query_aliasinfo_info
+{
+ uint32 ptr;
+ ALIAS_INFO_CTR *ctr;
+
uint32 status;
} SAMR_R_QUERY_ALIASINFO;
+/* SAMR_Q_SET_ALIASINFO - SAM Alias Info */
+typedef struct q_samr_set_alias_info
+{
+ POLICY_HND alias_pol; /* policy handle */
+ ALIAS_INFO_CTR *ctr;
+
+} SAMR_Q_SET_ALIASINFO;
+
+/* SAMR_R_SET_ALIASINFO - SAM alias info */
+typedef struct r_samr_set_aliasinfo_info
+{
+ uint32 status;
+
+} SAMR_R_SET_ALIASINFO;
+
+
/* SAMR_Q_QUERY_USERGROUPS - */
typedef struct q_samr_query_usergroup_info
{
@@ -729,6 +1119,59 @@ typedef struct r_samr_query_usergroup_info
} SAMR_R_QUERY_USERGROUPS;
+/* SAM_USERINFO_CTR - sam user info */
+typedef struct sam_userinfo_ctr_info
+{
+ uint16 switch_value;
+
+ union
+ {
+ SAM_USER_INFO_10 *id10; /* auth-level 0x10 */
+ SAM_USER_INFO_11 *id11; /* auth-level 0x11 */
+ SAM_USER_INFO_12 *id12; /* auth-level 0x12 */
+ SAM_USER_INFO_21 *id21; /* auth-level 21 */
+ SAM_USER_INFO_23 *id23; /* auth-level 0x17 */
+ SAM_USER_INFO_24 *id24; /* auth-level 0x18 */
+ void* id; /* to make typecasting easy */
+
+ } info;
+
+} SAM_USERINFO_CTR;
+
+
+/* SAMR_Q_SET_USERINFO2 - set sam info */
+typedef struct q_samr_set_user_info2
+{
+ POLICY_HND pol; /* policy handle associated with user */
+ uint16 switch_value; /* 0x0010 */
+
+ SAM_USERINFO_CTR *ctr;
+
+} SAMR_Q_SET_USERINFO2;
+
+/* SAMR_R_SET_USERINFO2 - set sam info */
+typedef struct r_samr_set_user_info2
+{
+ uint32 status; /* return status */
+
+} SAMR_R_SET_USERINFO2;
+
+/* SAMR_Q_SET_USERINFO - set sam info */
+typedef struct q_samr_set_user_info
+{
+ POLICY_HND pol; /* policy handle associated with user */
+ uint16 switch_value;
+ SAM_USERINFO_CTR *ctr;
+
+} SAMR_Q_SET_USERINFO;
+
+/* SAMR_R_SET_USERINFO - set sam info */
+typedef struct r_samr_set_user_info
+{
+ uint32 status; /* return status */
+
+} SAMR_R_SET_USERINFO;
+
/* SAMR_Q_QUERY_USERINFO - probably a get sam info */
typedef struct q_samr_query_user_info
@@ -742,17 +1185,7 @@ typedef struct q_samr_query_user_info
typedef struct r_samr_query_user_info
{
uint32 ptr; /* pointer */
- uint16 switch_value; /* 0x0015, 0x0011 or 0x0010 - same as in query */
- /* uint8[2] padding. */
-
- union
- {
- SAM_USER_INFO_10 *id10; /* auth-level 0x10 */
- SAM_USER_INFO_11 *id11; /* auth-level 0x11 */
- SAM_USER_INFO_21 *id21; /* auth-level 21 */
- void* id; /* to make typecasting easy */
-
- } info;
+ SAM_USERINFO_CTR *ctr;
uint32 status; /* return status */
@@ -760,39 +1193,40 @@ typedef struct r_samr_query_user_info
/****************************************************************************
-SAMR_Q_LOOKUP_IDS - do a conversion from name to RID.
+SAMR_Q_QUERY_USERALIASES - do a conversion from name to RID.
the policy handle allocated by an "samr open secret" call is associated
with a SID. this policy handle is what is queried here, *not* the SID
itself. the response to the lookup rids is relative to this SID.
*****************************************************************************/
-/* SAMR_Q_LOOKUP_IDS */
-typedef struct q_samr_lookup_ids_info
+/* SAMR_Q_QUERY_USERALIASES */
+typedef struct q_samr_query_useraliases_info
{
- POLICY_HND pol; /* policy handle */
+ POLICY_HND pol; /* policy handle */
uint32 num_sids1; /* number of rids being looked up */
uint32 ptr; /* buffer pointer */
uint32 num_sids2; /* number of rids being looked up */
- uint32 ptr_sid[MAX_LOOKUP_SIDS]; /* pointers to sids to be looked up */
- DOM_SID2 sid [MAX_LOOKUP_SIDS]; /* sids to be looked up. */
+ uint32 *ptr_sid; /* pointers to sids to be looked up */
+ DOM_SID2 *sid ; /* sids to be looked up. */
-} SAMR_Q_LOOKUP_IDS;
+} SAMR_Q_QUERY_USERALIASES;
-/* SAMR_R_LOOKUP_IDS */
-typedef struct r_samr_lookup_ids_info
+/* SAMR_R_QUERY_USERALIASES */
+typedef struct r_samr_query_useraliases_info
{
uint32 num_entries;
uint32 ptr; /* undocumented buffer pointer */
uint32 num_entries2;
- uint32 rid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
+ uint32 *rid; /* domain RIDs being looked up */
uint32 status; /* return code */
-} SAMR_R_LOOKUP_IDS;
+} SAMR_R_QUERY_USERALIASES;
+
/****************************************************************************
SAMR_Q_LOOKUP_NAMES - do a conversion from Names to RIDs+types.
@@ -812,6 +1246,7 @@ typedef struct q_samr_lookup_names_info
} SAMR_Q_LOOKUP_NAMES;
+
/* SAMR_R_LOOKUP_NAMES */
typedef struct r_samr_lookup_names_info
{
@@ -819,70 +1254,69 @@ typedef struct r_samr_lookup_names_info
uint32 ptr_rids; /* pointer to aliases */
uint32 num_rids2; /* number of aliases being looked up */
- uint32 rid[MAX_LOOKUP_SIDS]; /* rids */
+ uint32 *rids; /* rids */
uint32 num_types1; /* number of users in aliases being looked up */
uint32 ptr_types; /* pointer to users in aliases */
uint32 num_types2; /* number of users in aliases being looked up */
- uint32 type[MAX_LOOKUP_SIDS]; /* SID_ENUM type */
+ uint32 *types; /* SID_ENUM type */
uint32 status; /* return code */
} SAMR_R_LOOKUP_NAMES;
+
/****************************************************************************
-SAMR_Q_UNKNOWN_12 - do a conversion from RID groups to something.
+SAMR_Q_LOOKUP_RIDS - do a conversion from RID groups to something.
called to resolve domain RID groups.
*****************************************************************************/
-/* SAMR_Q_UNKNOWN_12 */
-typedef struct q_samr_unknown_12_info
+/* SAMR_Q_LOOKUP_RIDS */
+typedef struct q_samr_lookup_rids_info
{
- POLICY_HND pol; /* policy handle */
+ POLICY_HND pol; /* policy handle */
- uint32 num_gids1; /* number of rids being looked up */
- uint32 rid; /* 0x0000 03e8 - RID of the server doing the query? */
+ uint32 num_rids1; /* number of rids being looked up */
+ uint32 flags; /* 0x0000 03e8 - unknown */
uint32 ptr; /* 0x0000 0000 - 32 bit unknown */
- uint32 num_gids2; /* number of rids being looked up */
+ uint32 num_rids2; /* number of rids being looked up */
- uint32 gid[MAX_LOOKUP_SIDS]; /* domain RIDs being looked up */
+ uint32 *rid; /* domain RIDs being looked up */
-} SAMR_Q_UNKNOWN_12;
+} SAMR_Q_LOOKUP_RIDS;
/****************************************************************************
-SAMR_R_UNKNOWN_12 - do a conversion from group RID to names
+SAMR_R_LOOKUP_RIDS - do a conversion from group RID to names
*****************************************************************************/
-/* SAMR_R_UNKNOWN_12 */
-typedef struct r_samr_unknown_12_info
+/* SAMR_R_LOOKUP_RIDS */
+typedef struct r_samr_lookup_rids_info
{
- POLICY_HND pol; /* policy handle */
+ uint32 num_names1; /* number of aliases being looked up */
+ uint32 ptr_names; /* pointer to aliases */
+ uint32 num_names2; /* number of aliases being looked up */
- uint32 num_aliases1; /* number of aliases being looked up */
- uint32 ptr_aliases; /* pointer to aliases */
- uint32 num_aliases2; /* number of aliases being looked up */
+ UNIHDR *hdr_name; /* unicode account name header */
+ UNISTR2 *uni_name; /* unicode account name string */
- UNIHDR hdr_als_name[MAX_LOOKUP_SIDS]; /* unicode account name header */
- UNISTR2 uni_als_name[MAX_LOOKUP_SIDS]; /* unicode account name string */
-
- uint32 num_als_usrs1; /* number of users in aliases being looked up */
- uint32 ptr_als_usrs; /* pointer to users in aliases */
- uint32 num_als_usrs2; /* number of users in aliases being looked up */
+ uint32 num_types1; /* number of users in aliases being looked up */
+ uint32 ptr_types; /* pointer to users in aliases */
+ uint32 num_types2; /* number of users in aliases being looked up */
- uint32 num_als_usrs[MAX_LOOKUP_SIDS]; /* number of users per group */
+ uint32 *type; /* SID_ENUM type */
uint32 status;
-} SAMR_R_UNKNOWN_12;
+} SAMR_R_LOOKUP_RIDS;
/* SAMR_Q_OPEN_USER - probably an open */
typedef struct q_samr_open_user_info
{
- POLICY_HND domain_pol; /* policy handle */
- uint32 unknown_0; /* 32 bit unknown - 0x02011b */
+ POLICY_HND domain_pol; /* policy handle */
+ uint32 access_mask; /* 32 bit unknown - 0x02011b */
uint32 user_rid; /* user RID */
} SAMR_Q_OPEN_USER;
@@ -891,64 +1325,203 @@ typedef struct q_samr_open_user_info
/* SAMR_R_OPEN_USER - probably an open */
typedef struct r_samr_open_user_info
{
- POLICY_HND user_pol; /* policy handle associated with unknown id */
+ POLICY_HND user_pol; /* policy handle associated with unknown id */
uint32 status; /* return status */
} SAMR_R_OPEN_USER;
-/* SAMR_Q_UNKNOWN_13 - probably an open alias in domain */
-typedef struct q_samr_unknown_13_info
+/* SAMR_Q_CREATE_USER - probably a create */
+typedef struct q_samr_create_user_info
+{
+ POLICY_HND domain_pol; /* policy handle */
+
+ UNIHDR hdr_name; /* unicode account name header */
+ UNISTR2 uni_name; /* unicode account name */
+
+ uint16 acb_info; /* account control info */
+ uint32 access_mask; /* 0xe005 00b0 */
+
+} SAMR_Q_CREATE_USER;
+
+
+/* SAMR_R_CREATE_USER - probably a create */
+typedef struct r_samr_create_user_info
+{
+ POLICY_HND user_pol; /* policy handle associated with user */
+
+ uint32 unknown_0; /* 0x0007 03ff */
+ uint32 user_rid; /* user RID */
+ uint32 status; /* return status */
+
+} SAMR_R_CREATE_USER;
+
+
+/* SAMR_Q_DELETE_DOM_USER - delete domain user */
+typedef struct q_samr_delete_dom_user_info
+{
+ POLICY_HND user_pol; /* policy handle */
+
+} SAMR_Q_DELETE_DOM_USER;
+
+
+/* SAMR_R_DELETE_DOM_USER - delete domain user */
+typedef struct r_samr_delete_dom_user_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} SAMR_R_DELETE_DOM_USER;
+
+
+/* SAMR_Q_QUERY_GROUPMEM - query group members */
+typedef struct q_samr_query_groupmem_info
+{
+ POLICY_HND group_pol; /* policy handle */
+
+} SAMR_Q_QUERY_GROUPMEM;
+
+
+/* SAMR_R_QUERY_GROUPMEM - query group members */
+typedef struct r_samr_query_groupmem_info
+{
+ uint32 ptr;
+ uint32 num_entries;
+
+ uint32 ptr_rids;
+ uint32 ptr_attrs;
+
+ uint32 num_rids;
+ uint32 *rid;
+
+ uint32 num_attrs;
+ uint32 *attr;
+
+ uint32 status;
+
+} SAMR_R_QUERY_GROUPMEM;
+
+
+/* SAMR_Q_DEL_GROUPMEM - probably an del group member */
+typedef struct q_samr_del_group_mem_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint32 rid; /* rid */
+
+} SAMR_Q_DEL_GROUPMEM;
+
+
+/* SAMR_R_DEL_GROUPMEM - probably an del group member */
+typedef struct r_samr_del_group_mem_info
+{
+ uint32 status; /* return status */
+
+} SAMR_R_DEL_GROUPMEM;
+
+
+/* SAMR_Q_ADD_GROUPMEM - probably an add group member */
+typedef struct q_samr_add_group_mem_info
+{
+ POLICY_HND pol; /* policy handle */
+
+ uint32 rid; /* rid */
+ uint32 unknown; /* 0x0000 0005 */
+
+} SAMR_Q_ADD_GROUPMEM;
+
+
+/* SAMR_R_ADD_GROUPMEM - probably an add group member */
+typedef struct r_samr_add_group_mem_info
+{
+ uint32 status; /* return status */
+
+} SAMR_R_ADD_GROUPMEM;
+
+
+/* SAMR_Q_OPEN_GROUP - probably an open */
+typedef struct q_samr_open_group_info
+{
+ POLICY_HND domain_pol; /* policy handle */
+ uint32 access_mask; /* 0x0000 0001, 0x0000 0003, 0x0000 001f */
+ uint32 rid_group; /* rid */
+
+} SAMR_Q_OPEN_GROUP;
+
+
+/* SAMR_R_OPEN_GROUP - probably an open */
+typedef struct r_samr_open_group_info
+{
+ POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
+
+} SAMR_R_OPEN_GROUP;
+
+
+/* SAMR_Q_QUERY_ALIASMEM - query alias members */
+typedef struct q_samr_query_aliasmem_info
+{
+ POLICY_HND alias_pol; /* policy handle */
+
+} SAMR_Q_QUERY_ALIASMEM;
+
+
+/* SAMR_R_QUERY_ALIASMEM - query alias members */
+typedef struct r_samr_query_aliasmem_info
{
- POLICY_HND alias_pol; /* policy handle */
+ uint32 num_sids;
+ uint32 ptr;
+ uint32 num_sids1;
+
+ DOM_SID2 *sid;
- uint16 unknown_1; /* 16 bit unknown - 0x0200 */
- uint16 unknown_2; /* 16 bit unknown - 0x0000 */
+ uint32 status;
-} SAMR_Q_UNKNOWN_13;
+} SAMR_R_QUERY_ALIASMEM;
-/* SAMR_Q_UNKNOWN_21 - probably an open group in domain */
-typedef struct q_samr_unknown_21_info
+/* SAMR_Q_ADD_ALIASMEM - add alias member */
+typedef struct q_samr_add_alias_mem_info
{
- POLICY_HND group_pol; /* policy handle */
+ POLICY_HND alias_pol; /* policy handle */
- uint16 unknown_1; /* 16 bit unknown - 0x0477 */
- uint16 unknown_2; /* 16 bit unknown - 0x0000 */
+ DOM_SID2 sid; /* member sid to be added to the alias */
-} SAMR_Q_UNKNOWN_21;
+} SAMR_Q_ADD_ALIASMEM;
-/* SAMR_Q_UNKNOWN_32 - probably a "create SAM entry" */
-typedef struct q_samr_unknown_32_info
+/* SAMR_R_ADD_ALIASMEM - add alias member */
+typedef struct r_samr_add_alias_mem_info
{
- POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
- UNIHDR hdr_mach_acct; /* unicode machine account name header */
- UNISTR2 uni_mach_acct; /* unicode machine account name */
+} SAMR_R_ADD_ALIASMEM;
- uint32 acct_ctrl; /* 32 bit ACB_XXXX */
- uint16 unknown_1; /* 16 bit unknown - 0x00B0 */
- uint16 unknown_2; /* 16 bit unknown - 0xe005 */
-} SAMR_Q_UNKNOWN_32;
+/* SAMR_Q_DEL_ALIASMEM - add an add alias member */
+typedef struct q_samr_del_alias_mem_info
+{
+ POLICY_HND alias_pol; /* policy handle */
+
+ DOM_SID2 sid; /* member sid to be added to alias */
+} SAMR_Q_DEL_ALIASMEM;
-/* SAMR_R_UNKNOWN_32 - probably a "create SAM entry" */
-typedef struct r_samr_unknown_32_info
+
+/* SAMR_R_DEL_ALIASMEM - delete alias member */
+typedef struct r_samr_del_alias_mem_info
{
- POLICY_HND pol; /* policy handle */
+ uint32 status; /* return status */
- /* rid4.unknown - fail: 0030 success: 0x03ff */
- DOM_RID4 rid4; /* rid and attributes */
+} SAMR_R_DEL_ALIASMEM;
- uint32 status; /* return status - fail: 0xC000 0099: user exists */
-} SAMR_R_UNKNOWN_32;
/* SAMR_Q_OPEN_ALIAS - probably an open */
typedef struct q_samr_open_alias_info
{
+ POLICY_HND dom_pol;
+
uint32 unknown_0; /* 0x0000 0008 */
uint32 rid_alias; /* rid */
@@ -970,7 +1543,7 @@ typedef struct q_samr_connect_anon_info
uint32 ptr; /* ptr? */
uint16 unknown_0; /* 0x005c */
uint16 unknown_1; /* 0x0001 */
- uint32 unknown_2; /* 0x0000 0020 */
+ uint32 access_mask;
} SAMR_Q_CONNECT_ANON;
@@ -988,7 +1561,7 @@ typedef struct q_samr_connect_info
uint32 ptr_srv_name; /* pointer (to server name?) */
UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */
- uint32 unknown_0; /* 32 bit unknown */
+ uint32 access_mask;
} SAMR_Q_CONNECT;
@@ -1001,24 +1574,24 @@ typedef struct r_samr_connect_info
} SAMR_R_CONNECT;
-/* SAMR_Q_UNKNOWN_38 */
-typedef struct q_samr_unknown_38
+/* SAMR_Q_GET_DOM_PWINFO */
+typedef struct q_samr_get_dom_pwinfo
{
uint32 ptr;
UNIHDR hdr_srv_name;
UNISTR2 uni_srv_name;
-} SAMR_Q_UNKNOWN_38;
+} SAMR_Q_GET_DOM_PWINFO;
-/* SAMR_R_UNKNOWN_38 */
-typedef struct r_samr_unknown_38
+/* SAMR_R_GET_DOM_PWINFO */
+typedef struct r_samr_get_dom_pwinfo
{
uint16 unk_0;
uint16 unk_1;
uint16 unk_2;
- uint32 status; /* return status */
+ uint32 status;
-} SAMR_R_UNKNOWN_38;
+} SAMR_R_GET_DOM_PWINFO;
/* SAMR_ENC_PASSWD */
typedef struct enc_passwd_info
@@ -1064,5 +1637,22 @@ typedef struct r_samr_chgpasswd_user_info
} SAMR_R_CHGPASSWD_USER;
+
+/* SAMR_Q_UNKNOWN_2D */
+typedef struct q_samr_unknown_2d_info
+{
+ POLICY_HND dom_pol; /* policy handle */
+ DOM_SID2 sid; /* SID */
+
+} SAMR_Q_UNKNOWN_2D;
+
+
+/* SAMR_R_UNKNOWN_2D - probably an open */
+typedef struct r_samr_unknown_2d_info
+{
+ uint32 status; /* return status */
+
+} SAMR_R_UNKNOWN_2D;
+
#endif /* _RPC_SAMR_H */
diff --git a/source/include/rpc_secdes.h b/source/include/rpc_secdes.h
index f497c25db64..53719538fa5 100644
--- a/source/include/rpc_secdes.h
+++ b/source/include/rpc_secdes.h
@@ -2,9 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Paul Ashton 1997
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -37,6 +36,7 @@
#define SEC_RIGHTS_READ 0x00020019
#define SEC_RIGHTS_FULL_CONTROL 0x000f003f
+#define SEC_RIGHTS_MAXIMUM_ALLOWED 0x02000000
#define SEC_ACE_TYPE_ACCESS_ALLOWED 0x0
@@ -88,16 +88,21 @@ typedef struct security_ace_info
} SEC_ACE;
+
+#define MAX_SEC_ACES 16
+
/* SEC_ACL */
typedef struct security_acl_info
{
uint16 revision; /* 0x0002 */
uint16 size; /* size in bytes of the entire ACL structure */
uint32 num_aces; /* number of Access Control Entries */
- SEC_ACE *ace_list;
+
+ SEC_ACE *ace;
} SEC_ACL;
+
/* SEC_DESC */
typedef struct security_descriptor_info
{
diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h
index b5aa50ecba6..22f4359812a 100755
--- a/source/include/rpc_spoolss.h
+++ b/source/include/rpc_spoolss.h
@@ -2,9 +2,9 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-2000,
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
- Copyright (C) Jean Francois Micouleau 1998-2000.
+ Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1998
+ Copyright (C) Jean Francois Micouleau 1998-1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -68,6 +68,7 @@
*/
/* those are implemented */
+
#define SPOOLSS_ENUMPRINTERS 0x00
#define SPOOLSS_SETJOB 0x02
#define SPOOLSS_GETJOB 0x03
@@ -94,7 +95,7 @@
#define SPOOLSS_ENUMFORMS 0x22
#define SPOOLSS_ENUMPORTS 0x23
#define SPOOLSS_ENUMMONITORS 0x24
-#define SPOOLSS_ENUMPRINTPROCDATATYPES 0x33
+#define SPOOLSS_ENUMPRINTPROCESSORDATATYPES 0x33
#define SPOOLSS_GETPRINTERDRIVER2 0x35
/* find close printer notification */
#define SPOOLSS_FCPN 0x38
@@ -106,6 +107,7 @@
#define SPOOLSS_ADDPRINTEREX 0x46
#define SPOOLSS_ENUMPRINTERDATA 0x48
+
#define SERVER_ACCESS_ADMINISTER 0x00000001
#define SERVER_ACCESS_ENUMERATE 0x00000002
@@ -185,9 +187,6 @@
#define JOB_NOTIFY_TYPE 0x01
#define MAX_PRINTER_NOTIFY 26
-#define MAX_JOB_NOTIFY 24
-
-#define MAX_NOTIFY_TYPE_FOR_NOW 26
#define PRINTER_NOTIFY_SERVER_NAME 0x00
#define PRINTER_NOTIFY_PRINTER_NAME 0x01
@@ -216,6 +215,8 @@
#define PRINTER_NOTIFY_TOTAL_BYTES 0x18
#define PRINTER_NOTIFY_BYTES_PRINTED 0x19
+#define MAX_JOB_NOTIFY 24
+
#define JOB_NOTIFY_PRINTER_NAME 0x00
#define JOB_NOTIFY_MACHINE_NAME 0x01
#define JOB_NOTIFY_PORT_NAME 0x02
@@ -241,57 +242,6 @@
#define JOB_NOTIFY_TOTAL_BYTES 0x16
#define JOB_NOTIFY_BYTES_PRINTED 0x17
-#define PRINTER_CHANGE_ADD_PRINTER 0x00000001
-#define PRINTER_CHANGE_SET_PRINTER 0x00000002
-#define PRINTER_CHANGE_DELETE_PRINTER 0x00000004
-#define PRINTER_CHANGE_FAILED_CONNECTION_PRINTER 0x00000008
-#define PRINTER_CHANGE_PRINTER (PRINTER_CHANGE_ADD_PRINTER | \
- PRINTER_CHANGE_SET_PRINTER | \
- PRINTER_CHANGE_DELETE_PRINTER | \
- PRINTER_CHANGE_FAILED_CONNECTION_PRINTER )
-
-#define PRINTER_CHANGE_ADD_JOB 0x00000100
-#define PRINTER_CHANGE_SET_JOB 0x00000200
-#define PRINTER_CHANGE_DELETE_JOB 0x00000400
-#define PRINTER_CHANGE_WRITE_JOB 0x00000800
-#define PRINTER_CHANGE_JOB (PRINTER_CHANGE_ADD_JOB | \
- PRINTER_CHANGE_SET_JOB | \
- PRINTER_CHANGE_DELETE_JOB | \
- PRINTER_CHANGE_WRITE_JOB )
-
-#define PRINTER_CHANGE_ADD_FORM 0x00010000
-#define PRINTER_CHANGE_SET_FORM 0x00020000
-#define PRINTER_CHANGE_DELETE_FORM 0x00040000
-#define PRINTER_CHANGE_FORM (PRINTER_CHANGE_ADD_FORM | \
- PRINTER_CHANGE_SET_FORM | \
- PRINTER_CHANGE_DELETE_FORM )
-
-#define PRINTER_CHANGE_ADD_PORT 0x00100000
-#define PRINTER_CHANGE_CONFIGURE_PORT 0x00200000
-#define PRINTER_CHANGE_DELETE_PORT 0x00400000
-#define PRINTER_CHANGE_PORT (PRINTER_CHANGE_ADD_PORT | \
- PRINTER_CHANGE_CONFIGURE_PORT | \
- PRINTER_CHANGE_DELETE_PORT )
-
-#define PRINTER_CHANGE_ADD_PRINT_PROCESSOR 0x01000000
-#define PRINTER_CHANGE_DELETE_PRINT_PROCESSOR 0x04000000
-#define PRINTER_CHANGE_PRINT_PROCESSOR (PRINTER_CHANGE_ADD_PRINT_PROCESSOR | \
- PRINTER_CHANGE_DELETE_PRINT_PROCESSOR )
-
-#define PRINTER_CHANGE_ADD_PRINTER_DRIVER 0x10000000
-#define PRINTER_CHANGE_SET_PRINTER_DRIVER 0x20000000
-#define PRINTER_CHANGE_DELETE_PRINTER_DRIVER 0x40000000
-#define PRINTER_CHANGE_PRINTER_DRIVER (PRINTER_CHANGE_ADD_PRINTER_DRIVER | \
- PRINTER_CHANGE_SET_PRINTER_DRIVER | \
- PRINTER_CHANGE_DELETE_PRINTER_DRIVER )
-
-#define PRINTER_CHANGE_TIMEOUT 0x80000000
-#define PRINTER_CHANGE_ALL (PRINTER_CHANGE_JOB | \
- PRINTER_CHANGE_FORM | \
- PRINTER_CHANGE_PORT | \
- PRINTER_CHANGE_PRINT_PROCESSOR | \
- PRINTER_CHANGE_PRINTER_DRIVER )
-
/*
* The printer attributes.
* I #defined all of them (grabbed form MSDN)
@@ -322,7 +272,6 @@
#define MIN_PRIORITY 1
#define DEF_PRIORITY 1
-/* the flags of the query */
#define PRINTER_ENUM_DEFAULT 0x00000001
#define PRINTER_ENUM_LOCAL 0x00000002
#define PRINTER_ENUM_CONNECTIONS 0x00000004
@@ -332,9 +281,9 @@
#define PRINTER_ENUM_SHARED 0x00000020
#define PRINTER_ENUM_NETWORK 0x00000040
-/* the flags of each printers */
#define PRINTER_ENUM_EXPAND 0x00004000
#define PRINTER_ENUM_CONTAINER 0x00008000
+
#define PRINTER_ENUM_ICONMASK 0x00ff0000
#define PRINTER_ENUM_ICON1 0x00010000
#define PRINTER_ENUM_ICON2 0x00020000
@@ -345,29 +294,33 @@
#define PRINTER_ENUM_ICON7 0x00400000
#define PRINTER_ENUM_ICON8 0x00800000
-#define POLICY_HND_SIZE 20
-
-/* this struct is undocumented */
-/* thanks to the ddk ... */
-typedef struct spool_user_1
+typedef struct
{
- uint32 size;
- uint32 client_name_ptr;
- uint32 user_name_ptr;
- uint32 build;
- uint32 major;
- uint32 minor;
- uint32 processor;
- UNISTR2 client_name;
- UNISTR2 user_name;
-} SPOOL_USER_1;
+ char name[100];
+ uint32 flag;
+ uint32 width;
+ uint32 length;
+ uint32 left;
+ uint32 top;
+ uint32 right;
+ uint32 bottom;
+} nt_forms_struct;
-typedef struct spool_user_ctr_info
+typedef struct
{
- uint32 level;
- uint32 ptr;
- SPOOL_USER_1 user1;
-} SPOOL_USER_CTR;
+ char name[100];
+ char architecture[100];
+ uint32 version;
+ char default_form[30];
+ uint32 color_flag;
+ char driver[100];
+ char datafile[100];
+ char configfile[100];
+ char helpfile[100];
+ char monitor[100];
+ char monitor_name[100];
+ char **dependant;
+} nt_drivers_struct;
typedef struct devicemode
{
@@ -406,34 +359,170 @@ typedef struct devicemode
uint32 panningwidth;
uint32 panningheight;
uint8 *private;
-} DEVICEMODE;
+} DEVICEMODE;
-typedef struct _devmode_cont
+typedef struct devicemode_container
{
- uint32 size;
- uint32 devmode_ptr;
- DEVICEMODE *devmode;
-} DEVMODE_CTR;
+ DEVICEMODE *dm;
+ uint8 *buffer;
+ uint32 size_of_buffer;
+} DEVICEMODE_CONTAINER;
+
+#define ORIENTATION 0x00000001L
+#define PAPERSIZE 0x00000002L
+#define PAPERLENGTH 0x00000004L
+#define PAPERWIDTH 0x00000008L
+#define SCALE 0x00000010L
+#define COPIES 0x00000100L
+#define DEFAULTSOURCE 0x00000200L
+#define PRINTQUALITY 0x00000400L
+#define COLOR 0x00000800L
+#define DUPLEX 0x00001000L
+#define YRESOLUTION 0x00002000L
+#define TTOPTION 0x00004000L
+#define COLLATE 0x00008000L
+#define FORMNAME 0x00010000L
+#define LOGPIXELS 0x00020000L
+#define BITSPERPEL 0x00040000L
+#define PELSWIDTH 0x00080000L
+#define PELSHEIGHT 0x00100000L
+#define DISPLAYFLAGS 0x00200000L
+#define DISPLAYFREQUENCY 0x00400000L
+#define PANNINGWIDTH 0x00800000L
+#define PANNINGHEIGHT 0x01000000L
+
+#define ORIENT_PORTRAIT 1
+#define ORIENT_LANDSCAPE 2
+
+#define PAPER_FIRST PAPER_LETTER
+#define PAPER_LETTER 1 /* Letter 8 1/2 x 11 in */
+#define PAPER_LETTERSMALL 2 /* Letter Small 8 1/2 x 11 in */
+#define PAPER_TABLOID 3 /* Tabloid 11 x 17 in */
+#define PAPER_LEDGER 4 /* Ledger 17 x 11 in */
+#define PAPER_LEGAL 5 /* Legal 8 1/2 x 14 in */
+#define PAPER_STATEMENT 6 /* Statement 5 1/2 x 8 1/2 in */
+#define PAPER_EXECUTIVE 7 /* Executive 7 1/4 x 10 1/2 in */
+#define PAPER_A3 8 /* A3 297 x 420 mm */
+#define PAPER_A4 9 /* A4 210 x 297 mm */
+#define PAPER_A4SMALL 10 /* A4 Small 210 x 297 mm */
+#define PAPER_A5 11 /* A5 148 x 210 mm */
+#define PAPER_B4 12 /* B4 (JIS) 250 x 354 */
+#define PAPER_B5 13 /* B5 (JIS) 182 x 257 mm */
+#define PAPER_FOLIO 14 /* Folio 8 1/2 x 13 in */
+#define PAPER_QUARTO 15 /* Quarto 215 x 275 mm */
+#define PAPER_10X14 16 /* 10x14 in */
+#define PAPER_11X17 17 /* 11x17 in */
+#define PAPER_NOTE 18 /* Note 8 1/2 x 11 in */
+#define PAPER_ENV_9 19 /* Envelope #9 3 7/8 x 8 7/8 */
+#define PAPER_ENV_10 20 /* Envelope #10 4 1/8 x 9 1/2 */
+#define PAPER_ENV_11 21 /* Envelope #11 4 1/2 x 10 3/8 */
+#define PAPER_ENV_12 22 /* Envelope #12 4 \276 x 11 */
+#define PAPER_ENV_14 23 /* Envelope #14 5 x 11 1/2 */
+#define PAPER_CSHEET 24 /* C size sheet */
+#define PAPER_DSHEET 25 /* D size sheet */
+#define PAPER_ESHEET 26 /* E size sheet */
+#define PAPER_ENV_DL 27 /* Envelope DL 110 x 220mm */
+#define PAPER_ENV_C5 28 /* Envelope C5 162 x 229 mm */
+#define PAPER_ENV_C3 29 /* Envelope C3 324 x 458 mm */
+#define PAPER_ENV_C4 30 /* Envelope C4 229 x 324 mm */
+#define PAPER_ENV_C6 31 /* Envelope C6 114 x 162 mm */
+#define PAPER_ENV_C65 32 /* Envelope C65 114 x 229 mm */
+#define PAPER_ENV_B4 33 /* Envelope B4 250 x 353 mm */
+#define PAPER_ENV_B5 34 /* Envelope B5 176 x 250 mm */
+#define PAPER_ENV_B6 35 /* Envelope B6 176 x 125 mm */
+#define PAPER_ENV_ITALY 36 /* Envelope 110 x 230 mm */
+#define PAPER_ENV_MONARCH 37 /* Envelope Monarch 3.875 x 7.5 in */
+#define PAPER_ENV_PERSONAL 38 /* 6 3/4 Envelope 3 5/8 x 6 1/2 in */
+#define PAPER_FANFOLD_US 39 /* US Std Fanfold 14 7/8 x 11 in */
+#define PAPER_FANFOLD_STD_GERMAN 40 /* German Std Fanfold 8 1/2 x 12 in */
+#define PAPER_FANFOLD_LGL_GERMAN 41 /* German Legal Fanfold 8 1/2 x 13 in */
+
+#define PAPER_LAST PAPER_FANFOLD_LGL_GERMAN
+#define PAPER_USER 256
+
+#define BIN_FIRST BIN_UPPER
+#define BIN_UPPER 1
+#define BIN_ONLYONE 1
+#define BIN_LOWER 2
+#define BIN_MIDDLE 3
+#define BIN_MANUAL 4
+#define BIN_ENVELOPE 5
+#define BIN_ENVMANUAL 6
+#define BIN_AUTO 7
+#define BIN_TRACTOR 8
+#define BIN_SMALLFMT 9
+#define BIN_LARGEFMT 10
+#define BIN_LARGECAPACITY 11
+#define BIN_CASSETTE 14
+#define BIN_FORMSOURCE 15
+#define BIN_LAST BIN_FORMSOURCE
+
+#define BIN_USER 256 /* device specific bins start here */
+
+#define RES_DRAFT (-1)
+#define RES_LOW (-2)
+#define RES_MEDIUM (-3)
+#define RES_HIGH (-4)
+
+#define COLOR_MONOCHROME 1
+#define COLOR_COLOR 2
+
+#define DUP_SIMPLEX 1
+#define DUP_VERTICAL 2
+#define DUP_HORIZONTAL 3
+
+#define TT_BITMAP 1 /* print TT fonts as graphics */
+#define TT_DOWNLOAD 2 /* download TT fonts as soft fonts */
+#define TT_SUBDEV 3 /* substitute device fonts for TT fonts */
+
+#define COLLATE_FALSE 0
+#define COLLATE_TRUE 1
-typedef struct _printer_default
+typedef struct s_header_type
{
- uint32 datatype_ptr;
- UNISTR2 datatype;
- DEVMODE_CTR devmode_cont;
- uint32 access_required;
-} PRINTER_DEFAULT;
+ uint32 type;
+ union
+ {
+ uint32 value;
+ UNISTR string;
+ } data;
+} HEADER_TYPE;
+
+typedef struct s_buffer
+{
+ uint32 ptr;
+ uint32 size;
+ uint32 count;
+ uint8 *data;
+ HEADER_TYPE *header;
+} BUFFER;
+
/* SPOOL_Q_OPEN_PRINTER_EX request to open a printer */
typedef struct spool_q_open_printer_ex
{
- uint32 printername_ptr;
+ uint32 ptr;
UNISTR2 printername;
- PRINTER_DEFAULT printer_default;
- uint32 user_switch;
- SPOOL_USER_CTR user_ctr;
+ uint32 unknown0;
+ uint32 cbbuf;
+ uint32 devmod;
+ uint32 access_required;
+ uint32 unknown1; /* 0x0000 0001 */
+ uint32 unknown2; /* 0x0000 0001 */
+ uint32 unknown3; /* ??? pointer? */
+ uint32 unknown4; /* 0x0000 001c */
+ uint32 unknown5; /* ??? e.g 0xb94dd0 */
+ uint32 unknown6; /* ??? pointer? */
+ uint32 unknown7; /* 0x0000 0565 */
+ uint32 unknown8; /* 0x0000 0002 */
+ uint32 unknown9; /* 0x0000 0000 */
+ uint32 unknown10; /* 0x0000 0000 */
+ UNISTR2 station;
+ UNISTR2 username;
+
} SPOOL_Q_OPEN_PRINTER_EX;
-/* SPOOL_R_OPEN_PRINTER_EX reply to an open printer */
+/* SPOOL_Q_OPEN_PRINTER_EX reply to an open printer */
typedef struct spool_r_open_printer_ex
{
POLICY_HND handle; /* handle used along all transactions (20*uint8) */
@@ -441,50 +530,11 @@ typedef struct spool_r_open_printer_ex
} SPOOL_R_OPEN_PRINTER_EX;
-typedef struct spool_notify_option_type
-{
- uint16 type;
- uint16 reserved0;
- uint32 reserved1;
- uint32 reserved2;
- uint32 count;
- uint32 fields_ptr;
- uint32 count2;
- uint16 fields[MAX_NOTIFY_TYPE_FOR_NOW];
-} SPOOL_NOTIFY_OPTION_TYPE;
-
-typedef struct spool_notify_option_type_ctr
-{
- uint32 count;
- SPOOL_NOTIFY_OPTION_TYPE *type;
-} SPOOL_NOTIFY_OPTION_TYPE_CTR;
-
-
-
-typedef struct s_header_type
-{
- uint32 type;
- union
- {
- uint32 value;
- UNISTR string;
- } data;
-} HEADER_TYPE;
-
-typedef struct new_buffer
-{
- uint32 ptr;
- uint32 size;
- prs_struct prs;
- uint32 struct_start;
- uint32 string_at_end;
-} NEW_BUFFER;
-
typedef struct spool_q_getprinterdata
{
POLICY_HND handle;
- UNISTR2 valuename;
- uint32 size;
+ UNISTR2 valuename;
+ uint32 size;
} SPOOL_Q_GETPRINTERDATA;
typedef struct spool_r_getprinterdata
@@ -492,6 +542,7 @@ typedef struct spool_r_getprinterdata
uint32 type;
uint32 size;
uint8 *data;
+ uint32 numeric_data;
uint32 needed;
uint32 status;
} SPOOL_R_GETPRINTERDATA;
@@ -585,13 +636,22 @@ typedef struct spool_r_writeprinter
uint32 status;
} SPOOL_R_WRITEPRINTER;
+typedef struct spool_notify_option_type
+{
+ uint16 type;
+ uint16 reserved0;
+ uint32 reserved1;
+ uint32 reserved2;
+ uint32 count;
+ uint16 fields[16];
+} SPOOL_NOTIFY_OPTION_TYPE;
+
typedef struct spool_notify_option
{
uint32 version;
- uint32 flags;
+ uint32 reserved;
uint32 count;
- uint32 option_type_ptr;
- SPOOL_NOTIFY_OPTION_TYPE_CTR ctr;
+ SPOOL_NOTIFY_OPTION_TYPE type[16]; /* totally arbitrary !!! */
} SPOOL_NOTIFY_OPTION;
typedef struct spool_notify_info_data
@@ -618,7 +678,10 @@ typedef struct spool_notify_info
uint32 version;
uint32 flags;
uint32 count;
- SPOOL_NOTIFY_INFO_DATA *data;
+ SPOOL_NOTIFY_INFO_DATA data[26*16];
+ /* 26 differents data types */
+ /* so size it for 16 printers at max */
+ /* jfmxxxx: Have to make it dynamic !!!*/
} SPOOL_NOTIFY_INFO;
/* If the struct name looks obscure, yes it is ! */
@@ -628,11 +691,9 @@ typedef struct spoolss_q_rffpcnex
POLICY_HND handle;
uint32 flags;
uint32 options;
- uint32 localmachine_ptr;
UNISTR2 localmachine;
uint32 printerlocal;
- uint32 option_ptr;
- SPOOL_NOTIFY_OPTION *option;
+ SPOOL_NOTIFY_OPTION option;
} SPOOL_Q_RFFPCNEX;
typedef struct spool_r_rffpcnex
@@ -645,15 +706,15 @@ typedef struct spool_q_rfnpcnex
{
POLICY_HND handle;
uint32 change;
- uint32 option_ptr;
- SPOOL_NOTIFY_OPTION *option;
+ SPOOL_NOTIFY_OPTION option;
} SPOOL_Q_RFNPCNEX;
typedef struct spool_r_rfnpcnex
{
- uint32 info_ptr;
+ uint32 count;
SPOOL_NOTIFY_INFO info;
uint32 status;
+
} SPOOL_R_RFNPCNEX;
/* Find Close Printer Notify */
@@ -738,11 +799,10 @@ typedef struct printer_info_2
typedef struct spool_q_enumprinters
{
uint32 flags;
- uint32 servername_ptr;
UNISTR2 servername;
uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
+ BUFFER buffer;
+ uint32 buf_size;
} SPOOL_Q_ENUMPRINTERS;
typedef struct printer_info_ctr_info
@@ -757,10 +817,14 @@ typedef struct printer_info_ctr_info
typedef struct spool_r_enumprinters
{
- NEW_BUFFER *buffer;
+ uint32 offered; /* number of bytes offered */
uint32 needed; /* bytes needed */
+ uint32 level;
+ UNISTR servername;
+ PRINTER_INFO_CTR ctr;
uint32 returned; /* number of printers */
uint32 status;
+
} SPOOL_R_ENUMPRINTERS;
@@ -768,8 +832,9 @@ typedef struct spool_q_getprinter
{
POLICY_HND handle;
uint32 level;
- NEW_BUFFER *buffer;
+ uint8* buffer;
uint32 offered;
+
} SPOOL_Q_GETPRINTER;
typedef struct printer_info_info
@@ -780,11 +845,17 @@ typedef struct printer_info_info
PRINTER_INFO_2 *info2;
void *info;
} printer;
+
} PRINTER_INFO;
typedef struct spool_r_getprinter
{
- NEW_BUFFER *buffer;
+ POLICY_HND handle;
+ uint32 level;
+
+ PRINTER_INFO ctr;
+
+ uint32 offered;
uint32 needed;
uint32 status;
@@ -799,6 +870,17 @@ struct s_notify_info_data_table
void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer);
};
+typedef struct spool_q_getprinterdriver2
+{
+ POLICY_HND handle;
+ UNISTR2 architecture;
+ uint32 level;
+ BUFFER buffer;
+ uint32 buf_size;
+ uint32 unknown;
+
+} SPOOL_Q_GETPRINTERDRIVER2;
+
typedef struct driver_info_1
{
UNISTR name;
@@ -838,26 +920,16 @@ typedef struct driver_info_info
} DRIVER_INFO;
-typedef struct spool_q_getprinterdriver2
-{
- POLICY_HND handle;
- uint32 architecture_ptr;
- UNISTR2 architecture;
- uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
- uint32 unknown;
-} SPOOL_Q_GETPRINTERDRIVER2;
-
typedef struct spool_r_getprinterdriver2
{
- NEW_BUFFER *buffer;
+ uint32 level;
+ DRIVER_INFO ctr;
uint32 needed;
- uint32 unknown0;
- uint32 unknown1;
+ uint32 offered;
+ uint32 returned;
uint32 status;
-} SPOOL_R_GETPRINTERDRIVER2;
+} SPOOL_R_GETPRINTERDRIVER2;
typedef struct add_jobinfo_1
{
@@ -870,8 +942,8 @@ typedef struct spool_q_addjob
{
POLICY_HND handle;
uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
+ BUFFER buffer;
+ uint32 buf_size;
} SPOOL_Q_ADDJOB;
typedef struct spool_r_addjob
@@ -947,8 +1019,9 @@ typedef struct spool_q_enumjobs
uint32 firstjob;
uint32 numofjobs;
uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
+ BUFFER buffer;
+ uint32 buf_size;
+
} SPOOL_Q_ENUMJOBS;
typedef struct job_info_ctr_info
@@ -963,10 +1036,12 @@ typedef struct job_info_ctr_info
typedef struct spool_r_enumjobs
{
- NEW_BUFFER *buffer;
- uint32 needed;
- uint32 returned;
+ uint32 level;
+ uint32 offered;
+ JOB_INFO_CTR ctr;
+ uint32 numofjobs;
uint32 status;
+
} SPOOL_R_ENUMJOBS;
typedef struct spool_q_schedulejob
@@ -996,11 +1071,10 @@ typedef struct s_port_info_2
typedef struct spool_q_enumports
{
- uint32 name_ptr;
UNISTR2 name;
uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
+ BUFFER buffer;
+ uint32 buf_size;
} SPOOL_Q_ENUMPORTS;
typedef struct port_info_ctr_info
@@ -1014,10 +1088,12 @@ typedef struct port_info_ctr_info
typedef struct spool_r_enumports
{
- NEW_BUFFER *buffer;
- uint32 needed; /* bytes needed */
- uint32 returned; /* number of printers */
+ uint32 level;
+ PORT_INFO_CTR ctr;
+ uint32 offered;
+ uint32 numofports;
uint32 status;
+
} SPOOL_R_ENUMPORTS;
#define JOB_CONTROL_PAUSE 1
@@ -1053,21 +1129,22 @@ typedef struct spool_r_setjob
typedef struct spool_q_enumprinterdrivers
{
- uint32 name_ptr;
UNISTR2 name;
- uint32 environment_ptr;
UNISTR2 environment;
uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
+ BUFFER buffer;
+ uint32 buf_size;
+
} SPOOL_Q_ENUMPRINTERDRIVERS;
typedef struct spool_r_enumprinterdrivers
{
- NEW_BUFFER *buffer;
- uint32 needed;
- uint32 returned;
+ uint32 level;
+ DRIVER_INFO ctr;
+ uint32 offered;
+ uint32 numofdrivers;
uint32 status;
+
} SPOOL_R_ENUMPRINTERDRIVERS;
typedef struct spool_form_1
@@ -1085,15 +1162,16 @@ typedef struct spool_form_1
typedef struct spool_q_enumforms
{
POLICY_HND handle;
- uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
+ uint32 level;
+ BUFFER buffer;
+ uint32 buf_size;
} SPOOL_Q_ENUMFORMS;
typedef struct spool_r_enumforms
{
- NEW_BUFFER *buffer;
- uint32 needed;
+ uint32 level;
+ FORM_1 *forms_1;
+ uint32 offered;
uint32 numofforms;
uint32 status;
} SPOOL_R_ENUMFORMS;
@@ -1138,8 +1216,6 @@ typedef struct spool_printer_info_level_2
typedef struct spool_printer_info_level
{
- uint32 level;
- uint32 info_ptr;
SPOOL_PRINTER_INFO_LEVEL_2 *info_2;
} SPOOL_PRINTER_INFO_LEVEL;
@@ -1171,8 +1247,6 @@ typedef struct spool_printer_driver_info_level_3
typedef struct spool_printer_driver_info_level
{
- uint32 level;
- uint32 ptr;
SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *info_3;
} SPOOL_PRINTER_DRIVER_INFO_LEVEL;
@@ -1202,7 +1276,8 @@ typedef struct spool_q_setprinter
POLICY_HND handle;
uint32 level;
SPOOL_PRINTER_INFO_LEVEL info;
- DEVMODE_CTR devmode_ctr;
+
+ DEVICEMODE *devmode;
/* lkclXXXX jean-francois, see SEC_DESC_BUF code */
struct
@@ -1238,10 +1313,8 @@ typedef struct spool_r_addprinter
uint32 status;
} SPOOL_R_ADDPRINTER;
-
typedef struct spool_q_addprinterex
{
- uint32 server_name_ptr;
UNISTR2 server_name;
uint32 level;
SPOOL_PRINTER_INFO_LEVEL info;
@@ -1249,20 +1322,19 @@ typedef struct spool_q_addprinterex
uint32 unk1;
uint32 unk2;
uint32 unk3;
- uint32 user_switch;
- SPOOL_USER_CTR user_ctr;
+ uint32 user_level;
+ SPOOL_USER_LEVEL user;
} SPOOL_Q_ADDPRINTEREX;
+
typedef struct spool_r_addprinterex
{
POLICY_HND handle;
uint32 status;
} SPOOL_R_ADDPRINTEREX;
-
typedef struct spool_q_addprinterdriver
{
- uint32 server_name_ptr;
UNISTR2 server_name;
uint32 level;
SPOOL_PRINTER_DRIVER_INFO_LEVEL info;
@@ -1273,10 +1345,19 @@ typedef struct spool_r_addprinterdriver
uint32 status;
} SPOOL_R_ADDPRINTERDRIVER;
+typedef struct spool_q_getprinterdriverdirectory
+{
+ UNISTR2 name;
+ UNISTR2 environment;
+ uint32 level;
+ BUFFER buffer;
+ uint32 buf_size;
+} SPOOL_Q_GETPRINTERDRIVERDIR;
typedef struct driver_directory_1
{
UNISTR name;
+
} DRIVER_DIRECTORY_1 ;
typedef struct driver_info_ctr_info
@@ -1284,35 +1365,25 @@ typedef struct driver_info_ctr_info
union {
DRIVER_DIRECTORY_1 info_1;
} driver;
+
} DRIVER_DIRECTORY_CTR;
-typedef struct spool_q_getprinterdriverdirectory
+typedef struct spool_r_getprinterdriverdirectory
{
- uint32 name_ptr;
- UNISTR2 name;
- uint32 environment_ptr;
- UNISTR2 environment;
uint32 level;
- NEW_BUFFER *buffer;
+ DRIVER_DIRECTORY_CTR ctr;
uint32 offered;
-} SPOOL_Q_GETPRINTERDRIVERDIR;
-
-typedef struct spool_r_getprinterdriverdirectory
-{
- NEW_BUFFER *buffer;
- uint32 needed;
uint32 status;
+
} SPOOL_R_GETPRINTERDRIVERDIR;
typedef struct spool_q_enumprintprocessors
{
- uint32 name_ptr;
UNISTR2 name;
- uint32 environment_ptr;
UNISTR2 environment;
uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
+ BUFFER buffer;
+ uint32 buf_size;
} SPOOL_Q_ENUMPRINTPROCESSORS;
typedef struct printprocessor_1
@@ -1322,66 +1393,58 @@ typedef struct printprocessor_1
typedef struct spool_r_enumprintprocessors
{
- NEW_BUFFER *buffer;
- uint32 needed;
- uint32 returned;
+ uint32 level;
+ PRINTPROCESSOR_1 *info_1;
+ uint32 offered;
+ uint32 numofprintprocessors;
uint32 status;
} SPOOL_R_ENUMPRINTPROCESSORS;
-typedef struct spool_q_enumprintprocdatatypes
+typedef struct spool_q_enumprintprocessordatatypes
{
- uint32 name_ptr;
UNISTR2 name;
- uint32 processor_ptr;
- UNISTR2 processor;
+ UNISTR2 printprocessor;
uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
-} SPOOL_Q_ENUMPRINTPROCDATATYPES;
+ BUFFER buffer;
+ uint32 buf_size;
+} SPOOL_Q_ENUMPRINTPROCESSORDATATYPES;
typedef struct ppdatatype_1
{
UNISTR name;
-} PRINTPROCDATATYPE_1;
+} PPDATATYPE_1;
-typedef struct spool_r_enumprintprocdatatypes
+typedef struct spool_r_enumprintprocessordatatypes
{
- NEW_BUFFER *buffer;
- uint32 needed;
- uint32 returned;
+ uint32 level;
+ PPDATATYPE_1 *info_1;
+ uint32 offered;
+ uint32 numofppdatatypes;
uint32 status;
-} SPOOL_R_ENUMPRINTPROCDATATYPES;
-
-typedef struct printmonitor_1
-{
- UNISTR name;
-} PRINTMONITOR_1;
-
-typedef struct printmonitor_2
-{
- UNISTR name;
- UNISTR environment;
- UNISTR dll_name;
-} PRINTMONITOR_2;
+} SPOOL_R_ENUMPRINTPROCESSORDATATYPES;
typedef struct spool_q_enumprintmonitors
{
- uint32 name_ptr;
UNISTR2 name;
uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
+ BUFFER buffer;
+ uint32 buf_size;
} SPOOL_Q_ENUMPRINTMONITORS;
+typedef struct printmonitor_1
+{
+ UNISTR name;
+} PRINTMONITOR_1;
+
typedef struct spool_r_enumprintmonitors
{
- NEW_BUFFER *buffer;
- uint32 needed;
- uint32 returned;
+ uint32 level;
+ PRINTMONITOR_1 *info_1;
+ uint32 offered;
+ uint32 numofprintmonitors;
uint32 status;
} SPOOL_R_ENUMPRINTMONITORS;
-
typedef struct spool_q_enumprinterdata
{
POLICY_HND handle;
@@ -1393,7 +1456,7 @@ typedef struct spool_q_enumprinterdata
typedef struct spool_r_enumprinterdata
{
uint32 valuesize;
- uint16 *value;
+ UNISTR value;
uint32 realvaluesize;
uint32 type;
uint32 datasize;
@@ -1463,8 +1526,9 @@ typedef struct spool_q_getjob
POLICY_HND handle;
uint32 jobid;
uint32 level;
- NEW_BUFFER *buffer;
- uint32 offered;
+ BUFFER buffer;
+ uint32 buf_size;
+
} SPOOL_Q_GETJOB;
typedef struct pjob_info_info
@@ -1479,8 +1543,9 @@ typedef struct pjob_info_info
typedef struct spool_r_getjob
{
- NEW_BUFFER *buffer;
- uint32 needed;
+ uint32 level;
+ PJOB_INFO ctr;
+ uint32 offered;
uint32 status;
} SPOOL_R_GETJOB;
@@ -1489,3 +1554,4 @@ typedef struct spool_r_getjob
#endif /* _RPC_SPOOLSS_H */
+
diff --git a/source/include/rpc_srvsvc.h b/source/include/rpc_srvsvc.h
index 78949a7a7d9..f6ad15386a1 100644
--- a/source/include/rpc_srvsvc.h
+++ b/source/include/rpc_srvsvc.h
@@ -26,14 +26,17 @@
/* srvsvc pipe */
-#define SRV_NETCONNENUM 0x08
-#define SRV_NETFILEENUM 0x09
-#define SRV_NETSESSENUM 0x0c
-#define SRV_NETSHAREENUM 0x0f
-#define SRV_NET_SHARE_GET_INFO 0x10
-#define SRV_NET_SRV_GET_INFO 0x15
-#define SRV_NET_SRV_SET_INFO 0x16
-#define SRV_NET_REMOTE_TOD 0x1c
+#define SRV_NETCONNENUM 0x08
+#define SRV_NETFILEENUM 0x09
+#define SRV_NETSESSENUM 0x0c
+#define SRV_NETSHAREENUM 0x0f
+#define SRV_NETSHAREGETINFO 0x10
+#define SRV_NETSHAREDEL 0x12
+#define SRV_NETTRANSPORTENUM 0x1a
+#define SRV_NET_SRV_GET_INFO 0x15
+#define SRV_NET_SRV_SET_INFO 0x16
+#define SRV_NET_REMOTE_TOD 0x1c
+#define SRV_NETSHAREENUM2 0x24
/* SESS_INFO_0 (pointers to level 0 session info strings) */
typedef struct ptr_sess_info0
@@ -104,11 +107,11 @@ typedef struct srv_sess_info_ctr_info
uint32 switch_value; /* switch value */
uint32 ptr_sess_ctr; /* pointer to sess info union */
union
- {
+ {
SRV_SESS_INFO_0 info0; /* session info level 0 */
SRV_SESS_INFO_1 info1; /* session info level 1 */
- } sess;
+ } sess;
} SRV_SESS_INFO_CTR;
@@ -122,6 +125,9 @@ typedef struct q_net_sess_enum_info
uint32 ptr_qual_name; /* pointer (to qualifier name) */
UNISTR2 uni_qual_name; /* qualifier name "\\qualifier" */
+ uint32 ptr_user_name; /* pointer (to user name) */
+ UNISTR2 uni_user_name; /* user name */
+
uint32 sess_level; /* session level */
SRV_SESS_INFO_CTR *ctr;
@@ -207,11 +213,11 @@ typedef struct srv_conn_info_ctr_info
uint32 switch_value; /* switch value */
uint32 ptr_conn_ctr; /* pointer to conn info union */
union
- {
+ {
SRV_CONN_INFO_0 info0; /* connection info level 0 */
SRV_CONN_INFO_1 info1; /* connection info level 1 */
- } conn;
+ } conn;
} SRV_CONN_INFO_CTR;
@@ -248,6 +254,89 @@ typedef struct r_net_conn_enum_info
} SRV_R_NET_CONN_ENUM;
+/* oops - this is going to take up a *massive* amount of stack. */
+/* the UNISTR2s already have 1024 uint16 chars in them... */
+#define MAX_TPRT_ENTRIES 32
+
+/* TPRT_INFO_0 (pointers to level 0 transport info strings) */
+typedef struct ptr_tprt_info0
+{
+ uint32 num_vcs; /* number of clients using transport */
+ uint32 ptr_trans_name; /* pointer to transport name. */
+ uint32 ptr_trans_addr; /* pointer to transport address */
+ uint32 trans_addr_len; /* length of transport address */
+ uint32 ptr_addr_name; /* pointer to network address name. */
+
+} TPRT_INFO_0;
+
+/* TPRT_INFO_0_STR (level 0 transport info strings) */
+typedef struct str_tprt_info0
+{
+ UNISTR2 uni_trans_name; /* unicode string of transport */
+ BUFFER4 buf_trans_addr; /* buffer for transport address */
+ UNISTR2 uni_addr_name; /* unicode string of network address */
+
+} TPRT_INFO_0_STR;
+
+/* SRV_TPRT_INFO_0 */
+typedef struct srv_tprt_info_0_info
+{
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_tprt_info; /* Buffer */
+ uint32 num_entries_read2; /* EntriesRead */
+
+ TPRT_INFO_0 *info_0; /* transport entry pointers */
+ TPRT_INFO_0_STR *info_0_str; /* transport entry strings */
+
+} SRV_TPRT_INFO_0;
+
+/* SRV_TPRT_INFO_CTR */
+typedef struct srv_tprt_info_ctr_info
+{
+ uint32 switch_value; /* switch value */
+ uint32 ptr_tprt_ctr; /* pointer to tprt info union */
+ union
+ {
+ SRV_TPRT_INFO_0 info0; /* transport info level 0 */
+
+ } tprt;
+
+} SRV_TPRT_INFO_CTR;
+
+
+/* SRV_Q_NET_TPRT_ENUM */
+typedef struct q_net_tprt_enum_info
+{
+ uint32 ptr_srv_name; /* pointer (to server name) */
+ UNISTR2 uni_srv_name; /* server name "\\server" */
+
+ uint32 tprt_level; /* transport level */
+
+ SRV_TPRT_INFO_CTR *ctr;
+
+ uint32 preferred_len; /* preferred maximum length (0xffff ffff) */
+ ENUM_HND enum_hnd;
+
+} SRV_Q_NET_TPRT_ENUM;
+
+/* SRV_R_NET_TPRT_ENUM */
+typedef struct r_net_tprt_enum_info
+{
+ uint32 tprt_level; /* share level */
+
+ SRV_TPRT_INFO_CTR *ctr;
+
+ uint32 total_entries; /* total number of entries */
+ ENUM_HND enum_hnd;
+
+ uint32 status; /* return status */
+
+} SRV_R_NET_TPRT_ENUM;
+
+/* oops - this is going to take up a *massive* amount of stack. */
+/* the UNISTR2s already have 1024 uint16 chars in them... */
+#define MAX_SHARE_ENTRIES 128
+
/* SH_INFO_1 (pointers to level 1 share info strings) */
typedef struct ptr_share_info1
{
@@ -268,8 +357,12 @@ typedef struct str_share_info1
/* SRV_SHARE_INFO_1 */
typedef struct share_info_1_info
{
- SH_INFO_1 info_1;
- SH_INFO_1_STR info_1_str;
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_share_info; /* Buffer */
+ uint32 num_entries_read2; /* EntriesRead */
+
+ SH_INFO_1 **info_1; /* share entry pointers */
+ SH_INFO_1_STR **info_1_str; /* share entry strings */
} SRV_SHARE_INFO_1;
@@ -297,29 +390,57 @@ typedef struct str_share_info2
} SH_INFO_2_STR;
+
+typedef struct _sh_info_502_hdr
+{
+ SH_INFO_2 info2_hdr;
+ uint32 sd_size; /* how useless... */
+ uint32 sd_ptr; /* for sd? */
+} SH_INFO_502_HDR;
+
+typedef struct _sh_info_502_data
+{
+ SH_INFO_2_STR info2_str;
+
+ uint32 sd_size2;
+ SEC_DESC sd; /* security descriptor */
+} SH_INFO_502_DATA;
+
+/* SHARE_INFO_502 (level 502 share info) */
+typedef struct _share_info_502
+{
+ SH_INFO_502_HDR info502_hdr;
+ SH_INFO_502_DATA info502_data;
+} SHARE_INFO_502;
+
+
+typedef union _share_info_ctr
+{
+ SHARE_INFO_502 info502;
+} SHARE_INFO_CTR;
+
+
/* SRV_SHARE_INFO_2 */
typedef struct share_info_2_info
{
- SH_INFO_2 info_2;
- SH_INFO_2_STR info_2_str;
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_share_info; /* Buffer */
+ uint32 num_entries_read2; /* EntriesRead */
+
+ SH_INFO_2 **info_2; /* share entry pointers */
+ SH_INFO_2_STR **info_2_str; /* share entry strings */
} SRV_SHARE_INFO_2;
/* SRV_SHARE_INFO_CTR */
-typedef struct srv_share_info_ctr_info
+typedef struct srv_share_info_1_info
{
- uint32 info_level;
- uint32 switch_value;
- uint32 ptr_share_info;
-
- uint32 num_entries;
- uint32 ptr_entries;
- uint32 num_entries2;
-
- union {
- SRV_SHARE_INFO_1 *info1; /* share info level 1 */
- SRV_SHARE_INFO_2 *info2; /* share info level 2 */
- void *info;
+ uint32 switch_value; /* switch value */
+ uint32 ptr_share_ctr; /* pointer to share info union */
+ union
+ {
+ SRV_SHARE_INFO_1 info1; /* share info level 1 */
+ SRV_SHARE_INFO_2 info2; /* share info level 2 */
} share;
@@ -331,7 +452,9 @@ typedef struct q_net_share_enum_info
uint32 ptr_srv_name; /* pointer (to server name?) */
UNISTR2 uni_srv_name; /* server name */
- SRV_SHARE_INFO_CTR ctr; /* share info container */
+ uint32 share_level; /* share level */
+
+ SRV_SHARE_INFO_CTR *ctr; /* share info container */
uint32 preferred_len; /* preferred maximum length (0xffff ffff) */
@@ -339,11 +462,11 @@ typedef struct q_net_share_enum_info
} SRV_Q_NET_SHARE_ENUM;
-
/* SRV_R_NET_SHARE_ENUM */
typedef struct r_net_share_enum_info
{
- SRV_SHARE_INFO_CTR ctr; /* share info container */
+ uint32 share_level; /* share level */
+ SRV_SHARE_INFO_CTR *ctr; /* share info container */
uint32 total_entries; /* total number of entries */
ENUM_HND enum_hnd;
@@ -354,30 +477,23 @@ typedef struct r_net_share_enum_info
/* SRV_Q_NET_SHARE_GET_INFO */
-typedef struct q_net_share_get_info_info
+typedef struct q_net_share_get_info
{
- uint32 ptr_srv_name;
- UNISTR2 uni_srv_name;
-
- UNISTR2 uni_share_name;
- uint32 info_level;
+ uint32 ptr_srv_name; /* pointer (to server name?) */
+ UNISTR2 uni_srv_name; /* server name */
+ UNISTR2 share_name;
+ uint32 info_level;
} SRV_Q_NET_SHARE_GET_INFO;
/* SRV_R_NET_SHARE_GET_INFO */
-typedef struct r_net_share_get_info_info
+typedef struct r_net_share_get_info
{
- uint32 switch_value;
- uint32 ptr_share_ctr;
-
- union {
- SRV_SHARE_INFO_1 info1;
- SRV_SHARE_INFO_2 info2;
-
- } share;
+ uint32 info_level;
+ uint32 info_ptr;
+ SHARE_INFO_CTR info;
uint32 status;
-
} SRV_R_NET_SHARE_GET_INFO;
@@ -407,13 +523,13 @@ typedef struct str_file_info3_info
/* SRV_FILE_INFO_3 */
typedef struct srv_file_info_3
{
- uint32 num_entries_read; /* EntriesRead */
- uint32 ptr_file_info; /* Buffer */
+ uint32 num_entries_read; /* EntriesRead */
+ uint32 ptr_file_info; /* Buffer */
- uint32 num_entries_read2; /* EntriesRead */
+ uint32 num_entries_read2; /* EntriesRead */
- FILE_INFO_3 info_3 [MAX_FILE_ENTRIES]; /* file entry details */
- FILE_INFO_3_STR info_3_str[MAX_FILE_ENTRIES]; /* file entry strings */
+ FILE_INFO_3 **info_3; /* file entry details */
+ FILE_INFO_3_STR **info_3_str; /* file entry strings */
} SRV_FILE_INFO_3;
@@ -423,10 +539,10 @@ typedef struct srv_file_info_3_info
uint32 switch_value; /* switch value */
uint32 ptr_file_ctr; /* pointer to file info union */
union
- {
+ {
SRV_FILE_INFO_3 info3; /* file info with 0 entries */
- } file;
+ } file;
} SRV_FILE_INFO_CTR;
@@ -440,6 +556,8 @@ typedef struct q_net_file_enum_info
uint32 ptr_qual_name; /* pointer (to qualifier name) */
UNISTR2 uni_qual_name; /* qualifier name "\\qualifier" */
+ uint32 file_id; /* file id */
+
uint32 file_level; /* file level */
SRV_FILE_INFO_CTR *ctr;
@@ -509,11 +627,11 @@ typedef struct srv_info_ctr_info
uint32 switch_value; /* switch value */
uint32 ptr_srv_ctr; /* pointer to server info */
union
- {
+ {
SRV_INFO_102 sv102; /* server info level 102 */
SRV_INFO_101 sv101; /* server info level 101 */
- } srv;
+ } srv;
} SRV_INFO_CTR;
@@ -594,3 +712,4 @@ typedef struct r_net_remote_tod
#endif /* _RPC_SRVSVC_H */
+
diff --git a/source/include/rpc_svcctl.h b/source/include/rpc_svcctl.h
new file mode 100644
index 00000000000..90b7a129164
--- /dev/null
+++ b/source/include/rpc_svcctl.h
@@ -0,0 +1,290 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Paul Ashton 1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _RPC_SVCCTL_H /* _RPC_SVCCTL_H */
+#define _RPC_SVCCTL_H
+
+
+/* svcctl pipe */
+#define SVC_OPEN_SC_MAN 0x0f
+#define SVC_ENUM_SVCS_STATUS 0x0e
+#define SVC_QUERY_SVC_CONFIG 0x11
+#define SVC_QUERY_DISP_NAME 0x14
+#define SVC_CHANGE_SVC_CONFIG 0x0b
+#define SVC_OPEN_SERVICE 0x10
+#define SVC_START_SERVICE 0x13
+#define SVC_STOP_SERVICE 0x01
+#define SVC_CLOSE 0x00
+
+/* SVC_Q_START_SERVICE */
+#define MAX_SVC_ARGS 10
+/* SVC_Q_ENUM_SVCS_STATUS */
+#define MAX_SERVICES 50
+
+/* SVC_Q_OPEN_SC_MAN */
+typedef struct q_svc_open_sc_man_info
+{
+ uint32 ptr_srv_name; /* pointer (to server name?) */
+ UNISTR2 uni_srv_name; /* unicode server name starting with '\\' */
+
+ uint32 ptr_db_name; /* pointer (to database name?) */
+ UNISTR2 uni_db_name; /* unicode database name */
+
+ uint32 des_access; /* 0x80000004 - SC_MANAGER_xxxx */
+
+} SVC_Q_OPEN_SC_MAN;
+
+/* SVC_R_OPEN_SC_MAN */
+typedef struct r_svc_open_sc_man_info
+{
+ POLICY_HND pol;
+ uint32 status; /* return status */
+
+} SVC_R_OPEN_SC_MAN;
+
+/* SVC_Q_OPEN_SERVICE */
+typedef struct q_svc_open_service_info
+{
+ POLICY_HND scman_pol;
+ UNISTR2 uni_svc_name; /* unicode service name */
+ uint32 des_access; /* 0x8000 0001 */
+
+} SVC_Q_OPEN_SERVICE;
+
+/* SVC_R_OPEN_SERVICE */
+typedef struct r_svc_open_service_info
+{
+ POLICY_HND pol;
+ uint32 status; /* return status */
+
+} SVC_R_OPEN_SERVICE;
+
+/* SVC_Q_STOP_SERVICE */
+typedef struct q_svc_stop_service_info
+{
+ POLICY_HND pol;
+
+ uint32 unknown;
+
+} SVC_Q_STOP_SERVICE;
+
+/* SVC_R_STOP_SERVICE */
+typedef struct r_svc_stop_service_info
+{
+ uint32 unknown0; /* 0x00000020 */
+ uint32 unknown1; /* 0x00000001 */
+ uint32 unknown2; /* 0x00000001 */
+ uint32 unknown3; /* 0x00000000 */
+ uint32 unknown4; /* 0x00000000 */
+ uint32 unknown5; /* 0x00000000 */
+ uint32 unknown6; /* 0x00000000 */
+ uint32 status;
+
+} SVC_R_STOP_SERVICE;
+
+/* SVC_Q_START_SERVICE */
+typedef struct q_svc_start_service_info
+{
+ POLICY_HND pol;
+
+ uint32 argc;
+ uint32 ptr_args;
+ uint32 argc2;
+ uint32 ptr_argv[MAX_SVC_ARGS];
+ UNISTR2 argv[MAX_SVC_ARGS];
+
+} SVC_Q_START_SERVICE;
+
+/* SVC_R_START_SERVICE */
+typedef struct r_svc_start_service_info
+{
+ uint32 status;
+
+} SVC_R_START_SERVICE;
+
+
+/* QUERY_SERVICE_CONFIG */
+typedef struct query_service_config_info
+{
+ uint32 service_type;
+ uint32 start_type;
+ uint32 error_control;
+ uint32 ptr_bin_path_name;
+ uint32 ptr_load_order_grp;
+ uint32 tag_id;
+ uint32 ptr_dependencies;
+ uint32 ptr_service_start_name;
+ uint32 ptr_display_name;
+
+ UNISTR2 uni_bin_path_name;
+ UNISTR2 uni_load_order_grp;
+ UNISTR2 uni_dependencies;
+ UNISTR2 uni_service_start_name;
+ UNISTR2 uni_display_name;
+
+} QUERY_SERVICE_CONFIG;
+
+/* SVC_STATUS */
+typedef struct svc_status_info
+{
+ uint32 svc_type;
+ uint32 current_state;
+ uint32 controls_accepted;
+ uint32 win32_exit_code;
+ uint32 svc_specific_exit_code;
+ uint32 check_point;
+ uint32 wait_hint;
+
+} SVC_STATUS;
+
+/* ENUM_SRVC_STATUS */
+typedef struct enum_svc_status_info
+{
+ UNISTR uni_srvc_name;
+ UNISTR uni_disp_name;
+ SVC_STATUS status;
+
+} ENUM_SRVC_STATUS;
+
+/* SVC_Q_ENUM_SVCS_STATUS */
+typedef struct q_svc_enum_svcs_status_info
+{
+ POLICY_HND pol;
+ uint32 service_type; /* 0x00000030 - win32 | 0x0000000b - driver */
+ uint32 service_state; /* 0x00000003 - state_all */
+ uint32 buf_size; /* max service buffer size */
+ ENUM_HND resume_hnd; /* resume handle */
+
+} SVC_Q_ENUM_SVCS_STATUS;
+
+/* SVC_R_ENUM_SVCS_STATUS */
+typedef struct r_svc_enum_svcs_status_info
+{
+ uint32 buf_size; /* service buffer size */
+ ENUM_SRVC_STATUS *svcs;
+ uint32 more_buf_size;
+ uint32 num_svcs;
+ ENUM_HND resume_hnd; /* resume handle */
+ uint32 dos_status; /* return status, DOS error code (wow!) */
+
+} SVC_R_ENUM_SVCS_STATUS;
+
+
+/* SVC_Q_QUERY_SVC_CONFIG */
+typedef struct q_svc_query_svc_cfg_info
+{
+ POLICY_HND pol;
+ uint32 buf_size;
+
+} SVC_Q_QUERY_SVC_CONFIG;
+
+
+/* SVC_R_QUERY_SVC_CONFIG */
+typedef struct r_svc_query_svc_cfg_info
+{
+ QUERY_SERVICE_CONFIG *cfg;
+ uint32 buf_size;
+ uint32 status; /* return status */
+
+} SVC_R_QUERY_SVC_CONFIG;
+
+
+/* SVC_Q_QUERY_DISP_NAME */
+typedef struct q_svc_query_disp_name_info
+{
+ POLICY_HND scman_pol;
+ UNISTR2 uni_svc_name;
+ uint32 buf_size;
+
+} SVC_Q_QUERY_DISP_NAME;
+
+
+/* SVC_R_QUERY_DISP_NAME */
+typedef struct r_svc_query_disp_name_info
+{
+ UNISTR2 uni_disp_name;
+ uint32 buf_size;
+ uint32 status;
+
+} SVC_R_QUERY_DISP_NAME;
+
+
+/* SVC_Q_CLOSE */
+typedef struct q_svc_close_info
+{
+ POLICY_HND pol;
+
+} SVC_Q_CLOSE;
+
+
+
+/* SVC_R_CLOSE */
+typedef struct r_svc_close_info
+{
+ POLICY_HND pol;
+ uint32 status; /* return status */
+
+} SVC_R_CLOSE;
+
+/* SVC_Q_CHANGE_SVC_CONFIG */
+typedef struct q_svc_change_svc_cfg_info
+{
+ POLICY_HND pol;
+ uint32 service_type;
+ uint32 start_type;
+ uint32 unknown_0;
+ uint32 error_control;
+
+ uint32 ptr_bin_path_name;
+ UNISTR2 uni_bin_path_name;
+
+ uint32 ptr_load_order_grp;
+ UNISTR2 uni_load_order_grp;
+
+ uint32 tag_id;
+
+ uint32 ptr_dependencies;
+ UNISTR2 uni_dependencies;
+
+ uint32 ptr_service_start_name;
+ UNISTR2 uni_service_start_name;
+
+ uint32 ptr_password;
+ STRING2 str_password;
+
+ uint32 ptr_display_name;
+ UNISTR2 uni_display_name;
+
+} SVC_Q_CHANGE_SVC_CONFIG;
+
+/* SVC_R_CHANGE_SVC_CONFIG */
+typedef struct r_svc_change_svc_cfg_info
+{
+ uint32 unknown_0; /* */
+ uint32 status; /* return status */
+
+} SVC_R_CHANGE_SVC_CONFIG;
+
+
+#endif /* _RPC_SVCCTL_H */
+
diff --git a/source/include/rpcclient.h b/source/include/rpcclient.h
index dc2be5d2b85..2aeb8366811 100644
--- a/source/include/rpcclient.h
+++ b/source/include/rpcclient.h
@@ -24,6 +24,8 @@
#ifndef _RPCCLIENT_H
#define _RPCCLIENT_H
+#define report fprintf
+
struct tar_client_info
{
int blocksize;
@@ -57,14 +59,8 @@ struct nt_client_info
NET_ID_INFO_CTR ctr;
NET_USER_INFO_3 user_info3;
- /************** \PIPE\winreg stuff ********************/
-
- POLICY_HND reg_pol_connect;
-
/************** \PIPE\lsarpc stuff ********************/
- POLICY_HND lsa_info_pol;
-
/* domain member */
DOM_SID level3_sid;
DOM_SID level5_sid;
@@ -73,52 +69,33 @@ struct nt_client_info
fstring level3_dom;
fstring level5_dom;
- /************** \PIPE\samr stuff ********************/
-
- POLICY_HND samr_pol_connect;
- POLICY_HND samr_pol_open_domain;
- POLICY_HND samr_pol_open_user;
-
- struct acct_info *sam;
- int num_sam_entries;
};
struct client_info
{
struct in_addr dest_ip;
fstring dest_host;
- fstring query_host;
- uint8 name_type;
fstring myhostname;
- fstring mach_acct;
-
- pstring cur_dir;
- pstring base_dir;
- pstring file_sel;
-
- fstring service;
- fstring share;
- fstring svc_type;
-
- time_t newer_than;
- int archive_level;
- int dir_total;
- int put_total_time_ms;
- int put_total_size;
- int get_total_time_ms;
- int get_total_size;
- int print_mode;
- BOOL translation;
- BOOL recurse_dir;
- BOOL prompt;
- BOOL lowercase;
- BOOL abort_mget;
struct tar_client_info tar;
struct nt_client_info dom;
+
+ BOOL reuse;
};
enum action_type {ACTION_HEADER, ACTION_ENUMERATE, ACTION_FOOTER};
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+struct command_set
+{
+ char *name;
+ void (*fn)(struct client_info*, int, char*[]);
+ char *description;
+ char* (*compl_args[2])(char*, int);
+
+};
+
#endif /* _RPCCLIENT_H */
diff --git a/source/include/safe_string.h b/source/include/safe_string.h
index 2c3d2eda01f..3b2f2c32d6d 100644
--- a/source/include/safe_string.h
+++ b/source/include/safe_string.h
@@ -42,9 +42,4 @@
#define fstrcpy(d,s) safe_strcpy((d),(s),sizeof(fstring)-1)
#define fstrcat(d,s) safe_strcat((d),(s),sizeof(fstring)-1)
-#define wpstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wpstring))
-#define wpstrcat(d,s) safe_strcat_w((d),(s),sizeof(wpstring))
-#define wfstrcpy(d,s) safe_strcpy_w((d),(s),sizeof(wfstring))
-#define wfstrcat(d,s) safe_strcat_w((d),(s),sizeof(wfstring))
-
#endif
diff --git a/source/include/sam.h b/source/include/sam.h
new file mode 100644
index 00000000000..c91acf33335
--- /dev/null
+++ b/source/include/sam.h
@@ -0,0 +1,58 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ LDAP and NTDS prototypes &c
+
+ Copyright (C) Luke Howard 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* groupType */
+
+typedef enum
+{
+ NTDS_GROUP_TYPE_BUILTIN_GROUP = 0x00000001, /* ??? */
+ NTDS_GROUP_TYPE_GLOBAL_GROUP = 0x00000002,
+ NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP = 0x00000004,
+ NTDS_GROUP_TYPE_UNIVERSAL_GROUP = 0x00000008,
+ NTDS_GROUP_TYPE_SECURITY_ENABLED = 0x80000000
+} NTDS_GROUP_TYPE_ENUM;
+
+/* userAccountFlags */
+
+typedef enum
+{
+ NTDS_UF_SCRIPT = 0x00000001,
+ NTDS_UF_ACCOUNTDISABLE = 0x00000002,
+ NTDS_UF_HOMEDIR_REQUIRED = 0x00000003,
+ NTDS_UF_LOCKOUT = 0x00000010,
+ NTDS_UF_PASSWD_NOTREQD = 0x00000020,
+ NTDS_UF_PASSWD_CANT_CHANGE = 0x00000040,
+ NTDS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0x00000080,
+ NTDS_UF_TEMP_DUPLICATE_ACCOUNT = 0x00000100,
+ NTDS_UF_NORMAL_ACCOUNT = 0x00000200,
+ NTDS_UF_INTERDOMAIN_TRUST_ACCOUNT = 0x00000800,
+ NTDS_UF_WORKSTATION_TRUST_ACCOUNT = 0x00001000,
+ NTDS_UF_SERVER_TRUST_ACCOUNT = 0x00002000,
+ NTDS_UF_DONT_EXPIRE_PASSWD = 0x00010000,
+ NTDS_UF_MNS_LOGON_ACCOUNT = 0x00020000,
+ NTDS_UF_SMARTCARD_REQUIRED = 0x00040000,
+ NTDS_UF_TRUSTED_FOR_DELEGATION = 0x00080000,
+ NTDS_UF_NOT_DELEGATED = 0x00100000,
+ NTDS_UF_USE_DES_KEY_ONLY = 0x00200000,
+ NTDS_UF_DONT_REQUIRE_PREAUTH = 0x00400000
+} NTDS_USER_FLAG_ENUM;
+
diff --git a/source/include/sids.h b/source/include/sids.h
new file mode 100644
index 00000000000..f4a8d83b680
--- /dev/null
+++ b/source/include/sids.h
@@ -0,0 +1,39 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB parameters and setup
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Elrond 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _SIDS_H
+#define _SIDS_H
+
+extern DOM_SID global_sam_sid;
+extern fstring global_sam_name;
+
+extern DOM_SID global_member_sid;
+
+extern DOM_SID global_sid_S_1_5_20; /* local well-known domain */
+extern DOM_SID global_sid_S_1_1; /* Global Domain */
+extern DOM_SID global_sid_S_1_1_0; /* everyone */
+extern DOM_SID global_sid_S_1_3; /* Creator Owner */
+extern DOM_SID global_sid_S_1_5; /* NT Authority */
+extern DOM_SID global_sid_system; /* SYSTEM */
+
+#endif /* _SIDS_H */
diff --git a/source/include/smb.h b/source/include/smb.h
index 54fb4d5cc7c..1c80fa80d20 100644
--- a/source/include/smb.h
+++ b/source/include/smb.h
@@ -2,10 +2,10 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) John H Terpstra 1996-1998
- Copyright (C) Luke Kenneth Casson Leighton 1996-1998
- Copyright (C) Paul Ashton 1998
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) John H Terpstra 1996-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Paul Ashton 1998-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,19 +25,24 @@
#ifndef _SMB_H
#define _SMB_H
+#include "md5.h"
+#include "hmacmd5.h"
+
#define BUFFER_SIZE (0xFFFF)
#define SAFETY_MARGIN 1024
#define NMB_PORT 137
#define DGRAM_PORT 138
#define SMB_PORT 139
+#define SMB_PORT2 445
#define False (0)
#define True (1)
+#define Auto (2)
#ifndef _BOOL
typedef int BOOL;
-#define _BOOL /* So we don't typedef BOOL again in vfs.h */
+#define _BOOL /* So we don't typedef BOOL again in vfs.h */
#endif
/* limiting size of ipc replies */
@@ -53,7 +58,8 @@ typedef int BOOL;
#define SMB_SECONDARY_WAIT (60*1000)
/* Debugging stuff */
-#include "debug.h"
+
+#include <debug.h>
/* this defines the error codes that receive_smb can put in smb_read_error */
#define READ_TIMEOUT 1
@@ -136,243 +142,255 @@ implemented */
#define STYPE_PRINTQ 1 /* Spooler queue */
#define STYPE_DEVICE 2 /* Serial device */
#define STYPE_IPC 3 /* Interprocess communication (IPC) */
-#define STYPE_HIDDEN 0x80000000 /* share is a hidden one (ends with $) */
+#define STYPE_HIDDEN 0x80000000 /* share is a hidden one (ends with $) */
/* SMB X/Open error codes for the ERRDOS error class */
-#define ERRbadfunc 1 /* Invalid function (or system call) */
-#define ERRbadfile 2 /* File not found (pathname error) */
-#define ERRbadpath 3 /* Directory not found */
-#define ERRnofids 4 /* Too many open files */
-#define ERRnoaccess 5 /* Access denied */
-#define ERRbadfid 6 /* Invalid fid */
-#define ERRnomem 8 /* Out of memory */
-#define ERRbadmem 9 /* Invalid memory block address */
-#define ERRbadenv 10 /* Invalid environment */
-#define ERRbadaccess 12 /* Invalid open mode */
-#define ERRbaddata 13 /* Invalid data (only from ioctl call) */
-#define ERRres 14 /* reserved */
-#define ERRbaddrive 15 /* Invalid drive */
-#define ERRremcd 16 /* Attempt to delete current directory */
-#define ERRdiffdevice 17 /* rename/move across different filesystems */
-#define ERRnofiles 18 /* no more files found in file search */
-#define ERRbadshare 32 /* Share mode on file conflict with open mode */
-#define ERRlock 33 /* Lock request conflicts with existing lock */
-#define ERRunsup 50 /* Request unsupported, returned by Win 95, RJS 20Jun98 */
-#define ERRnosuchshare 67 /* You specified an invalid share name */
-#define ERRfilexists 80 /* File in operation already exists */
-#define ERRcannotopen 110 /* Cannot open the file specified */
+#define ERRbadfunc 1 /* Invalid function (or system call) */
+#define ERRbadfile 2 /* File not found (pathname error) */
+#define ERRbadpath 3 /* Directory not found */
+#define ERRnofids 4 /* Too many open files */
+#define ERRnoaccess 5 /* Access denied */
+#define ERRbadfid 6 /* Invalid fid */
+#define ERRnomem 8 /* Out of memory */
+#define ERRbadmem 9 /* Invalid memory block address */
+#define ERRbadenv 10 /* Invalid environment */
+#define ERRbadaccess 12 /* Invalid open mode */
+#define ERRbaddata 13 /* Invalid data (only from ioctl call) */
+#define ERRres 14 /* reserved */
+#define ERRbaddrive 15 /* Invalid drive */
+#define ERRremcd 16 /* Attempt to delete current directory */
+#define ERRdiffdevice 17 /* rename/move across different filesystems */
+#define ERRnofiles 18 /* no more files found in file search */
+#define ERRbadshare 32 /* Share mode on file conflict with open mode */
+#define ERRlock 33 /* Lock request conflicts with existing lock */
+#define ERRunsup 50 /* Request unsupported, returned by Win 95, RJS 20Jun98 */
+#define ERRfilexists 80 /* File in operation already exists */
+#define ERRcannotopen 110 /* Cannot open the file specified */
#define ERRunknownlevel 124
#define ERRrename 183
-#define ERRbadpipe 230 /* Named pipe invalid */
-#define ERRpipebusy 231 /* All instances of pipe are busy */
-#define ERRpipeclosing 232 /* named pipe close in progress */
-#define ERRnotconnected 233 /* No process on other end of named pipe */
-#define ERRmoredata 234 /* More data to be returned */
-#define ERRbaddirectory 267 /* Invalid directory name in a path. */
-#define ERROR_EAS_DIDNT_FIT 275 /* Extended attributes didn't fit */
-#define ERROR_EAS_NOT_SUPPORTED 282 /* Extended attributes not supported */
-#define ERROR_NOTIFY_ENUM_DIR 1022 /* Buffer too small to return change notify. */
+#define ERRbadpipe 230 /* Named pipe invalid */
+#define ERRpipebusy 231 /* All instances of pipe are busy */
+#define ERRpipeclosing 232 /* named pipe close in progress */
+#define ERRnotconnected 233 /* No process on other end of named pipe */
+#define ERRmoredata 234 /* More data to be returned */
+#define ERRbaddirectory 267 /* Invalid directory name in a path. */
+#define ERROR_EAS_DIDNT_FIT 275 /* Extended attributes didn't fit */
+#define ERROR_EAS_NOT_SUPPORTED 282 /* Extended attributes not supported */
+#define ERROR_NOTIFY_ENUM_DIR 1022 /* Buffer too small to return change notify. */
#define ERRunknownipc 2142
/* here's a special one from observing NT */
-#define ERRnoipc 66 /* don't support ipc */
+#define ERRnoipc 66 /* don't support ipc */
/* Error codes for the ERRSRV class */
-#define ERRerror 1 /* Non specific error code */
-#define ERRbadpw 2 /* Bad password */
-#define ERRbadtype 3 /* reserved */
-#define ERRaccess 4 /* No permissions to do the requested operation */
-#define ERRinvnid 5 /* tid invalid */
-#define ERRinvnetname 6 /* Invalid servername */
-#define ERRinvdevice 7 /* Invalid device */
-#define ERRqfull 49 /* Print queue full */
-#define ERRqtoobig 50 /* Queued item too big */
-#define ERRinvpfid 52 /* Invalid print file in smb_fid */
-#define ERRsmbcmd 64 /* Unrecognised command */
-#define ERRsrverror 65 /* smb server internal error */
-#define ERRfilespecs 67 /* fid and pathname invalid combination */
-#define ERRbadlink 68 /* reserved */
-#define ERRbadpermits 69 /* Access specified for a file is not valid */
-#define ERRbadpid 70 /* reserved */
-#define ERRsetattrmode 71 /* attribute mode invalid */
-#define ERRpaused 81 /* Message server paused */
-#define ERRmsgoff 82 /* Not receiving messages */
-#define ERRnoroom 83 /* No room for message */
-#define ERRrmuns 87 /* too many remote usernames */
-#define ERRtimeout 88 /* operation timed out */
-#define ERRnoresource 89 /* No resources currently available for request. */
-#define ERRtoomanyuids 90 /* too many userids */
-#define ERRbaduid 91 /* bad userid */
-#define ERRuseMPX 250 /* temporarily unable to use raw mode, use MPX mode */
-#define ERRuseSTD 251 /* temporarily unable to use raw mode, use standard mode */
-#define ERRcontMPX 252 /* resume MPX mode */
-#define ERRbadPW /* reserved */
+#define ERRerror 1 /* Non specific error code */
+#define ERRbadpw 2 /* Bad password */
+#define ERRbadtype 3 /* reserved */
+#define ERRaccess 4 /* No permissions to do the requested operation */
+#define ERRinvnid 5 /* tid invalid */
+#define ERRinvnetname 6 /* Invalid servername */
+#define ERRinvdevice 7 /* Invalid device */
+#define ERRqfull 49 /* Print queue full */
+#define ERRqtoobig 50 /* Queued item too big */
+#define ERRinvpfid 52 /* Invalid print file in smb_fid */
+#define ERRsmbcmd 64 /* Unrecognised command */
+#define ERRsrverror 65 /* smb server internal error */
+#define ERRfilespecs 67 /* fid and pathname invalid combination */
+#define ERRbadlink 68 /* reserved */
+#define ERRbadpermits 69 /* Access specified for a file is not valid */
+#define ERRbadpid 70 /* reserved */
+#define ERRsetattrmode 71 /* attribute mode invalid */
+#define ERRpaused 81 /* Message server paused */
+#define ERRmsgoff 82 /* Not receiving messages */
+#define ERRnoroom 83 /* No room for message */
+#define ERRrmuns 87 /* too many remote usernames */
+#define ERRtimeout 88 /* operation timed out */
+#define ERRnoresource 89 /* No resources currently available for request. */
+#define ERRtoomanyuids 90 /* too many userids */
+#define ERRbaduid 91 /* bad userid */
+#define ERRuseMPX 250 /* temporarily unable to use raw mode, use MPX mode */
+#define ERRuseSTD 251 /* temporarily unable to use raw mode, use standard mode */
+#define ERRcontMPX 252 /* resume MPX mode */
+#define ERRbadPW /* reserved */
#define ERRnosupport 0xFFFF
-#define ERRunknownsmb 22 /* from NT 3.5 response */
+#define ERRunknownsmb 22 /* from NT 3.5 response */
/* Error codes for the ERRHRD class */
-#define ERRnowrite 19 /* read only media */
-#define ERRbadunit 20 /* Unknown device */
-#define ERRnotready 21 /* Drive not ready */
-#define ERRbadcmd 22 /* Unknown command */
-#define ERRdata 23 /* Data (CRC) error */
-#define ERRbadreq 24 /* Bad request structure length */
+#define ERRnowrite 19 /* read only media */
+#define ERRbadunit 20 /* Unknown device */
+#define ERRnotready 21 /* Drive not ready */
+#define ERRbadcmd 22 /* Unknown command */
+#define ERRdata 23 /* Data (CRC) error */
+#define ERRbadreq 24 /* Bad request structure length */
#define ERRseek 25
#define ERRbadmedia 26
#define ERRbadsector 27
#define ERRnopaper 28
-#define ERRwrite 29 /* write fault */
-#define ERRread 30 /* read fault */
-#define ERRgeneral 31 /* General hardware failure */
+#define ERRwrite 29 /* write fault */
+#define ERRread 30 /* read fault */
+#define ERRgeneral 31 /* General hardware failure */
#define ERRwrongdisk 34
#define ERRFCBunavail 35
-#define ERRsharebufexc 36 /* share buffer exceeded */
+#define ERRsharebufexc 36 /* share buffer exceeded */
#define ERRdiskfull 39
#ifndef _PSTRING
-
#define PSTRING_LEN 1024
#define FSTRING_LEN 128
typedef char pstring[PSTRING_LEN];
typedef char fstring[FSTRING_LEN];
-
#define _PSTRING
-
#endif
-/*
- * SMB UCS2 (16-bit unicode) internal type.
- */
-
-typedef uint16 smb_ucs2_t;
-
-/* ucs2 string types. */
-typedef smb_ucs2_t wpstring[1024];
-typedef smb_ucs2_t wfstring[128];
-
/* pipe string names */
#define PIPE_LANMAN "\\PIPE\\LANMAN"
+#define PIPE_BROWSER "\\PIPE\\browser"
#define PIPE_SRVSVC "\\PIPE\\srvsvc"
#define PIPE_SAMR "\\PIPE\\samr"
#define PIPE_WINREG "\\PIPE\\winreg"
#define PIPE_WKSSVC "\\PIPE\\wkssvc"
#define PIPE_NETLOGON "\\PIPE\\NETLOGON"
+#define PIPE_SVCCTL "\\PIPE\\svcctl"
#define PIPE_NTLSA "\\PIPE\\ntlsa"
#define PIPE_NTSVCS "\\PIPE\\ntsvcs"
#define PIPE_LSASS "\\PIPE\\lsass"
#define PIPE_LSARPC "\\PIPE\\lsarpc"
+#define PIPE_EPMAPPER "\\PIPE\\epmapper"
+#define PIPE_ATSVC "\\PIPE\\atsvc"
#define PIPE_SPOOLSS "\\PIPE\\spoolss"
+#define PIPE_EVENTLOG "\\PIPE\\EVENTLOG"
/* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */
typedef struct nttime_info
{
- uint32 low;
- uint32 high;
+ uint32 low;
+ uint32 high;
-} NTTIME;
+}
+NTTIME;
/* Allowable account control bits */
-#define ACB_DISABLED 0x0001 /* 1 = User account disabled */
-#define ACB_HOMDIRREQ 0x0002 /* 1 = Home directory required */
-#define ACB_PWNOTREQ 0x0004 /* 1 = User password not required */
-#define ACB_TEMPDUP 0x0008 /* 1 = Temporary duplicate account */
-#define ACB_NORMAL 0x0010 /* 1 = Normal user account */
-#define ACB_MNS 0x0020 /* 1 = MNS logon user account */
-#define ACB_DOMTRUST 0x0040 /* 1 = Interdomain trust account */
-#define ACB_WSTRUST 0x0080 /* 1 = Workstation trust account */
-#define ACB_SVRTRUST 0x0100 /* 1 = Server trust account */
-#define ACB_PWNOEXP 0x0200 /* 1 = User password does not expire */
-#define ACB_AUTOLOCK 0x0400 /* 1 = Account auto locked */
-
+#define ACB_DISABLED 0x0001 /* 1 = User account disabled */
+#define ACB_HOMDIRREQ 0x0002 /* 1 = Home directory required */
+#define ACB_PWNOTREQ 0x0004 /* 1 = User password not required */
+#define ACB_TEMPDUP 0x0008 /* 1 = Temporary duplicate account */
+#define ACB_NORMAL 0x0010 /* 1 = Normal user account */
+#define ACB_MNS 0x0020 /* 1 = MNS logon user account */
+#define ACB_DOMTRUST 0x0040 /* 1 = Interdomain trust account */
+#define ACB_WSTRUST 0x0080 /* 1 = Workstation trust account */
+#define ACB_SVRTRUST 0x0100 /* 1 = Server trust account */
+#define ACB_PWNOEXP 0x0200 /* 1 = User password does not expire */
+#define ACB_AUTOLOCK 0x0400 /* 1 = Account auto locked */
+#define ACB_PWLOCK 0x0800 /* 1 = Password is locked and connot be changed remotely */
+
#define MAX_HOURS_LEN 32
struct sam_passwd
{
- time_t logon_time; /* logon time */
- time_t logoff_time; /* logoff time */
- time_t kickoff_time; /* kickoff time */
- time_t pass_last_set_time; /* password last set time */
- time_t pass_can_change_time; /* password can change time */
- time_t pass_must_change_time; /* password must change time */
-
- char *smb_name; /* username string */
- char *full_name; /* user's full name string */
- char *home_dir; /* home directory string */
- char *dir_drive; /* home directory drive string */
- char *logon_script; /* logon script string */
- char *profile_path; /* profile path string */
- char *acct_desc ; /* user description string */
- char *workstations; /* login from workstations string */
- char *unknown_str ; /* don't know what this is, yet. */
- char *munged_dial ; /* munged path name and dial-back tel number */
-
- uid_t smb_userid; /* this is actually the unix uid_t */
- gid_t smb_grpid; /* this is actually the unix gid_t */
- uint32 user_rid; /* Primary User ID */
- uint32 group_rid; /* Primary Group ID */
-
- unsigned char *smb_passwd; /* Null if no password */
- unsigned char *smb_nt_passwd; /* Null if no password */
-
- uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
- uint32 unknown_3; /* 0x00ff ffff */
-
- uint16 logon_divs; /* 168 - number of hours in a week */
- uint32 hours_len; /* normally 21 bytes */
+ NTTIME logon_time; /* logon time */
+ NTTIME logoff_time; /* logoff time */
+ NTTIME kickoff_time; /* kickoff time */
+ NTTIME pass_last_set_time; /* password last set time */
+ NTTIME pass_can_change_time; /* password can change time */
+ NTTIME pass_must_change_time; /* password must change time */
+
+ char *unix_name; /* unix username string */
+ char *nt_name; /* nt username string */
+ char *full_name; /* user's full name string */
+ char *home_dir; /* home directory string */
+ char *dir_drive; /* home directory drive string */
+ char *logon_script; /* logon script string */
+ char *profile_path; /* profile path string */
+ char *acct_desc; /* user description string */
+ char *workstations; /* login from workstations string */
+ char *unknown_str; /* don't know what this is, yet. */
+ char *munged_dial; /* munged path name and dial-back tel number */
+
+ uid_t unix_uid; /* this is actually the unix uid_t */
+ gid_t unix_gid; /* this is actually the unix gid_t */
+ uint32 user_rid; /* Primary User ID */
+ uint32 group_rid; /* Primary Group ID */
+
+ unsigned char *smb_passwd; /* Null if no password */
+ unsigned char *smb_nt_passwd; /* Null if no password */
+
+ uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
+ uint32 unknown_3; /* 0x00ff ffff */
+
+ uint16 logon_divs; /* 168 - number of hours in a week */
+ uint32 hours_len; /* normally 21 bytes */
uint8 hours[MAX_HOURS_LEN];
- uint32 unknown_5; /* 0x0002 0000 */
- uint32 unknown_6; /* 0x0000 04ec */
+ uint32 unknown_5; /* 0x0002 0000 */
+ uint32 unknown_6; /* 0x0000 04ec */
};
struct smb_passwd
{
- uid_t smb_userid; /* this is actually the unix uid_t */
- char *smb_name; /* username string */
+ uid_t unix_uid; /* unix userid */
+ char *unix_name; /* unix username string */
+
+ uint32 user_rid; /* Primary User ID */
+ char *nt_name; /* unix username string */
- unsigned char *smb_passwd; /* Null if no password */
- unsigned char *smb_nt_passwd; /* Null if no password */
+ unsigned char *smb_passwd; /* Null if no password */
+ unsigned char *smb_nt_passwd; /* Null if no password */
- uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
- time_t pass_last_set_time; /* password last set time */
+ uint16 acct_ctrl; /* account info (ACB_xxxx bit-mask) */
+ time_t pass_last_set_time; /* password last set time */
};
struct sam_disp_info
{
- uint32 user_rid; /* Primary User ID */
- char *smb_name; /* username string */
- char *full_name; /* user's full name string */
+ uint32 user_rid; /* Primary User ID */
+ char *nt_name; /* username string */
+ char *full_name; /* user's full name string */
};
-struct use_info
-{
- BOOL connected;
- char *srv_name;
- char *user_name;
- char *domain;
-};
-
-#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
+#define MAXSUBAUTHS 15 /* max sub authorities in a SID */
/* DOM_SID - security id */
typedef struct sid_info
{
- uint8 sid_rev_num; /* SID revision number */
- uint8 num_auths; /* number of sub-authorities */
- uint8 id_auth[6]; /* Identifier Authority */
- /*
- * Note that the values in these uint32's are in *native* byteorder,
- * not neccessarily little-endian...... JRA.
- */
- uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */
+ uint8 sid_rev_num; /* SID revision number */
+ uint8 num_auths; /* number of sub-authorities */
+ uint8 id_auth[6]; /* Identifier Authority */
+ /*
+ * Note that the values in these uint32's are in *native* byteorder,
+ * not neccessarily little-endian...... JRA.
+ */
+ uint32 sub_auths[MAXSUBAUTHS]; /* pointer to sub-authorities. */
+
+}
+DOM_SID;
+
+
+typedef struct group_name_info
+{
+ char *nt_name;
+ char *nt_domain;
+ char *unix_name;
-} DOM_SID;
+ DOM_SID sid;
+ uint32 type;
+ uint32 unix_id;
+
+} DOM_NAME_MAP;
+
+/* map either local aliases, domain groups or builtin aliases */
+typedef enum
+{
+ DOM_MAP_LOCAL,
+ DOM_MAP_DOMAIN,
+ DOM_MAP_USER
+}
+DOM_MAP_TYPE;
/*** query a local group, get a list of these: shows who is in that group ***/
@@ -380,9 +398,9 @@ typedef struct sid_info
/* local group member info */
typedef struct local_grp_member_info
{
- DOM_SID sid ; /* matches with name */
- uint8 sid_use; /* usr=1 grp=2 dom=3 alias=4 wkng=5 del=6 inv=7 unk=8 */
- fstring name ; /* matches with sid: must be of the form "DOMAIN\account" */
+ DOM_SID sid; /* matches with name */
+ uint8 sid_use; /* usr=1 grp=2 dom=3 alias=4 wkng=5 del=6 inv=7 unk=8 */
+ fstring name; /* matches with sid: must be of the form "DOMAIN\account" */
} LOCAL_GRP_MEMBER;
@@ -393,70 +411,67 @@ typedef struct local_grp_info
{
fstring name;
fstring comment;
+ uint32 rid; /* alias rid */
} LOCAL_GRP;
-/*** enumerate these to get list of domain groups ***/
+/*** query a domain group, get a list of these: shows who is in that group ***/
-/* domain group member info */
-typedef struct domain_grp_info
+/* domain group info */
+typedef struct domain_grp_member_info
{
fstring name;
- fstring comment;
- uint32 rid; /* group rid */
- uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */
+ uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */
+ uint32 rid; /* rid of domain group member */
+ uint8 sid_use; /* usr=1 grp=2 dom=3 alias=4 wkng=5 del=6 inv=7 unk=8 */
-} DOMAIN_GRP;
+} DOMAIN_GRP_MEMBER;
-/*** query a domain group, get a list of these: shows who is in that group ***/
+/*** enumerate these to get list of domain groups ***/
-/* domain group info */
-typedef struct domain_grp_member_info
+/* domain group member info */
+typedef struct domain_grp_info
{
fstring name;
- uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */
+ fstring comment;
+ uint32 rid; /* group rid */
+ uint8 attr; /* attributes forced to be set to 0x7: SE_GROUP_xxx */
-} DOMAIN_GRP_MEMBER;
+} DOMAIN_GRP;
/* DOM_CHAL - challenge info */
typedef struct chal_info
{
- uchar data[8]; /* credentials */
-} DOM_CHAL;
+ uchar data[8]; /* credentials */
+}
+DOM_CHAL;
/* 32 bit time (sec) since 01jan1970 - cifs6.txt, section 3.5, page 30 */
typedef struct time_info
{
- uint32 time;
-} UTIME;
+ uint32 time;
+}
+UTIME;
/* DOM_CREDs - timestamped client or server credentials */
typedef struct cred_info
-{
- DOM_CHAL challenge; /* credentials */
- UTIME timestamp; /* credential time-stamp */
-} DOM_CRED;
+{
+ DOM_CHAL challenge; /* credentials */
+ UTIME timestamp; /* credential time-stamp */
+}
+DOM_CRED;
/* Structure used when SMBwritebmpx is active */
typedef struct
{
- size_t wr_total_written; /* So we know when to discard this */
- int32 wr_timeout;
- int32 wr_errclass;
- int32 wr_error; /* Cached errors */
- BOOL wr_mode; /* write through mode) */
- BOOL wr_discard; /* discard all further data */
+ size_t wr_total_written; /* So we know when to discard this */
+ int32 wr_timeout;
+ int32 wr_errclass;
+ int32 wr_error; /* Cached errors */
+ BOOL wr_mode; /* write through mode) */
+ BOOL wr_discard; /* discard all further data */
} write_bmpx_struct;
-typedef struct write_cache
-{
- SMB_OFF_T file_size;
- SMB_OFF_T offset;
- size_t alloc_size;
- size_t data_size;
- char *data;
-} write_cache;
-
/*
* Structure used to indirect fd's from the files_struct.
* Needed as POSIX locking is based on file and process, not
@@ -488,22 +503,21 @@ typedef struct files_struct
SMB_OFF_T size;
mode_t mode;
uint16 vuid;
+ char *mmap_ptr;
+ SMB_OFF_T mmap_size;
write_bmpx_struct *wbmpx_ptr;
- write_cache *wcp;
struct timeval open_time;
- int share_mode;
+ int share_mode;
time_t pending_modtime;
- int oplock_type;
- int sent_oplock_break;
BOOL open;
BOOL can_lock;
BOOL can_read;
BOOL can_write;
BOOL print_file;
BOOL modified;
+ BOOL granted_oplock;
+ BOOL sent_oplock_break;
BOOL is_directory;
- BOOL directory_delete_on_close;
- BOOL stat_open;
char *fsp_name;
} files_struct;
@@ -514,29 +528,34 @@ typedef struct files_struct
typedef struct
{
- time_t modify_time;
- time_t status_time;
-} dir_status_struct;
+ time_t modify_time;
+ time_t status_time;
+}
+dir_status_struct;
-struct uid_cache {
- int entries;
- uid_t list[UID_CACHE_SIZE];
+struct uid_cache
+{
+ int entries;
+ uid_t list[UID_CACHE_SIZE];
};
typedef struct
{
- char *name;
- BOOL is_wild;
+ char *name;
+ BOOL is_wild;
} name_compare_entry;
/* Include VFS stuff */
#include "vfs.h"
+
+#include "vagent.h"
+
typedef struct connection_struct
{
struct connection_struct *next, *prev;
- unsigned cnum; /* an index passed over the wire */
+ unsigned cnum; /* an index passed over the wire */
int service;
BOOL force_user;
struct uid_cache uid_cache;
@@ -548,127 +567,85 @@ typedef struct connection_struct
char *dirpath;
char *connectpath;
char *origpath;
+ struct vfs_ops vfs_ops; /* Filesystem operations */
+ struct vfs_connection_struct *vfs_conn;
- struct vfs_ops vfs_ops; /* Filesystem operations */
- struct vfs_connection_struct *vfs_conn; /* VFS specific connection stuff */
-
- char *user; /* name of user who *opened* this connection */
- uid_t uid; /* uid of user who *opened* this connection */
- gid_t gid; /* gid of user who *opened* this connection */
- char client_address[18]; /* String version of client IP address. */
+ char *user; /* name of user who *opened* this connection */
- uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */
-
- /* following groups stuff added by ih */
+ uid_t uid; /* uid of user who *opened* this connection */
+ gid_t gid; /* gid of user who *opened* this connection */
+ char client_address[18]; /* string version of client ip address */
/* This groups info is valid for the user that *opened* the connection */
int ngroups;
gid_t *groups;
-
- time_t lastused;
- BOOL used;
- int num_files_open;
- name_compare_entry *hide_list; /* Per-share list of files to return as hidden. */
- name_compare_entry *veto_list; /* Per-share list of files to veto (never show). */
- name_compare_entry *veto_oplock_list; /* Per-share list of files to refuse oplocks on. */
-} connection_struct;
+ uint16 vuid; /* vuid of user who *opened* this connection, or UID_FIELD_INVALID */
-struct current_user
-{
- connection_struct *conn;
- uint16 vuid;
- uid_t uid;
- gid_t gid;
- int ngroups;
- gid_t *groups;
-};
+ pid_t smbd_pid; /* smbd process id of user that *opened* this connection */
-/*
- * Reasons for cache flush.
- */
+ /* following groups stuff added by ih */
-#define NUM_FLUSH_REASONS 8 /* Keep this in sync with the enum below. */
-enum flush_reason_enum { SEEK_FLUSH, READ_FLUSH, WRITE_FLUSH, READRAW_FLUSH,
- OPLOCK_RELEASE_FLUSH, CLOSE_FLUSH, SYNC_FLUSH, SIZECHANGE_FLUSH };
+ time_t lastused;
+ BOOL used;
+ int num_files_open;
+ name_compare_entry *hide_list; /* Per-share list of files to return as hidden. */
+ name_compare_entry *veto_list; /* Per-share list of files to veto (never show). */
+ name_compare_entry *veto_oplock_list; /* Per-share list of files to refuse oplocks on. */
-/* Defines for the sent_oplock_break field above. */
-#define NO_BREAK_SENT 0
-#define EXCLUSIVE_BREAK_SENT 1
-#define LEVEL_II_BREAK_SENT 2
+} connection_struct;
/* Domain controller authentication protocol info */
struct dcinfo
{
- DOM_CHAL clnt_chal; /* Initial challenge received from client */
- DOM_CHAL srv_chal; /* Initial server challenge */
- DOM_CRED clnt_cred; /* Last client credential */
- DOM_CRED srv_cred; /* Last server credential */
+ DOM_CHAL clnt_chal; /* Initial challenge received from client */
+ DOM_CHAL srv_chal; /* Initial server challenge */
+ DOM_CRED clnt_cred; /* Last client credential */
+ DOM_CRED srv_cred; /* Last server credential */
- uchar sess_key[8]; /* Session key */
- uchar md4pw[16]; /* md4(machine password) */
+ uchar sess_key[8]; /* Session key */
+ uchar md4pw[16]; /* md4(machine password) */
};
-typedef struct
-{
- uid_t uid; /* uid of a validated user */
- gid_t gid; /* gid of a validated user */
-
- fstring requested_name; /* user name from the client */
- fstring name; /* unix user name of a validated user */
- fstring real_name; /* to store real name from password file - simeon */
- BOOL guest;
-
- /* following groups stuff added by ih */
- /* This groups info is needed for when we become_user() for this uid */
- int n_groups;
- gid_t *groups;
-
- int n_sids;
- int *sids;
-
- /* per-user authentication information on NT RPCs */
- struct dcinfo dc;
-
-} user_struct;
-
-enum {LPQ_QUEUED,LPQ_PAUSED,LPQ_SPOOLING,LPQ_PRINTING};
+enum
+{ LPQ_QUEUED, LPQ_PAUSED, LPQ_SPOOLING, LPQ_PRINTING };
typedef struct
{
- int job;
- int size;
- int status;
- int priority;
- time_t time;
- char user[30];
- char file[100];
+ int job;
+ int size;
+ int status;
+ int priority;
+ time_t time;
+ char user[30];
+ char file[100];
} print_queue_struct;
-enum {LPSTAT_OK, LPSTAT_STOPPED, LPSTAT_ERROR};
+enum
+{ LPSTAT_OK, LPSTAT_STOPPED, LPSTAT_ERROR };
typedef struct
{
- fstring message;
- int status;
-} print_status_struct;
+ fstring message;
+ int status;
+} print_status_struct;
/* used for server information: client, nameserv and ipc */
struct server_info_struct
{
- fstring name;
- uint32 type;
- fstring comment;
- fstring domain; /* used ONLY in ipc.c NOT namework.c */
- BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
+ fstring name;
+ uint32 type;
+ fstring comment;
+ fstring domain; /* used ONLY in ipc.c NOT namework.c */
+ BOOL server_added; /* used ONLY in ipc.c NOT namework.c */
};
/* used for network interfaces */
struct interface
{
- struct interface *next, *prev;
+ struct interface *next;
struct in_addr ip;
struct in_addr bcast;
struct in_addr nmask;
@@ -677,47 +654,47 @@ struct interface
/* struct returned by get_share_modes */
typedef struct
{
- pid_t pid;
- uint16 op_port;
- uint16 op_type;
- int share_mode;
- struct timeval time;
-} share_mode_entry;
-
-
-#define SHAREMODE_FN_CAST() \
- void (*)(share_mode_entry *, char*)
+ int pid;
+ uint16 op_port;
+ uint16 op_type;
+ int share_mode;
+ struct timeval time;
+}
+share_mode_entry;
-#define SHAREMODE_FN(fn) \
- void (*fn)(share_mode_entry *, char*)
/* each implementation of the share mode code needs
to support the following operations */
-struct share_ops {
- BOOL (*stop_mgmt)(void);
- BOOL (*lock_entry)(connection_struct *, SMB_DEV_T , SMB_INO_T , int *);
- BOOL (*unlock_entry)(connection_struct *, SMB_DEV_T , SMB_INO_T , int );
- int (*get_entries)(connection_struct *, int , SMB_DEV_T , SMB_INO_T , share_mode_entry **);
- void (*del_entry)(int , files_struct *);
- BOOL (*set_entry)(int, files_struct *, uint16 , uint16 );
- BOOL (*mod_entry)(int, files_struct *, void (*)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *), void *);
- int (*forall)(void (*)(share_mode_entry *, char *));
- void (*status)(FILE *);
+struct share_ops
+{
+ BOOL (*stop_mgmt) (void);
+ BOOL (*lock_entry) (connection_struct *, SMB_DEV_T, SMB_INO_T, int *);
+ BOOL (*unlock_entry) (connection_struct *, SMB_DEV_T, SMB_INO_T, int);
+ int (*get_entries) (connection_struct *, int, SMB_DEV_T, SMB_INO_T,
+ share_mode_entry **);
+ void (*del_entry) (int, files_struct *);
+ BOOL (*set_entry) (int, files_struct *, uint16, uint16);
+ BOOL (*mod_entry) (int, files_struct *,
+ void (*)(share_mode_entry *, SMB_DEV_T, SMB_INO_T,
+ void *), void *);
+ int (*forall) (void (*)(share_mode_entry *, char *));
+ void (*status) (FILE *);
};
/* each implementation of the shared memory code needs
to support the following operations */
-struct shmem_ops {
- BOOL (*shm_close)( void );
- int (*shm_alloc)(int );
- BOOL (*shm_free)(int );
- int (*get_userdef_off)(void);
- void *(*offset2addr)(int );
- int (*addr2offset)(void *addr);
- BOOL (*lock_hash_entry)(unsigned int);
- BOOL (*unlock_hash_entry)( unsigned int );
- BOOL (*get_usage)(int *,int *,int *);
- unsigned (*hash_size)(void);
+struct shmem_ops
+{
+ BOOL (*shm_close) (void);
+ int (*shm_alloc) (int);
+ BOOL (*shm_free) (int);
+ int (*get_userdef_off) (void);
+ void *(*offset2addr) (int);
+ int (*addr2offset) (void *addr);
+ BOOL (*lock_hash_entry) (unsigned int);
+ BOOL (*unlock_hash_entry) (unsigned int);
+ BOOL (*get_usage) (int *, int *, int *);
+ unsigned (*hash_size) (void);
};
/*
@@ -725,84 +702,245 @@ struct shmem_ops {
* to support the following operations.
*/
-struct passdb_ops {
- /*
- * Password database ops.
- */
- void *(*startsmbpwent)(BOOL);
- void (*endsmbpwent)(void *);
- SMB_BIG_UINT (*getsmbpwpos)(void *);
- BOOL (*setsmbpwpos)(void *, SMB_BIG_UINT);
-
- /*
- * smb password database query functions.
- */
- struct smb_passwd *(*getsmbpwnam)(char *);
- struct smb_passwd *(*getsmbpwuid)(uid_t);
- struct smb_passwd *(*getsmbpwrid)(uint32);
- struct smb_passwd *(*getsmbpwent)(void *);
-
- /*
- * smb password database modification functions.
- */
- BOOL (*add_smbpwd_entry)(struct smb_passwd *);
- BOOL (*mod_smbpwd_entry)(struct smb_passwd *, BOOL);
- BOOL (*del_smbpwd_entry)(const char *);
-
- /*
- * Functions that manupulate a struct sam_passwd.
- */
- struct sam_passwd *(*getsam21pwent)(void *);
-
- /*
- * sam password database query functions.
- */
- struct sam_passwd *(*getsam21pwnam)(char *);
- struct sam_passwd *(*getsam21pwuid)(uid_t);
- struct sam_passwd *(*getsam21pwrid)(uint32);
-
- /*
- * sam password database modification functions.
- */
- BOOL (*add_sam21pwd_entry)(struct sam_passwd *);
- BOOL (*mod_sam21pwd_entry)(struct sam_passwd *, BOOL);
-
- /*
- * sam query display info functions.
- */
- struct sam_disp_info *(*getsamdispnam)(char *);
- struct sam_disp_info *(*getsamdisprid)(uint32);
- struct sam_disp_info *(*getsamdispent)(void *);
+struct smb_passdb_ops
+{
+ /*
+ * Password database operations.
+ */
+ void *(*startsmbpwent) (BOOL);
+ void (*endsmbpwent) (void *);
+ SMB_BIG_UINT(*getsmbpwpos) (void *);
+ BOOL (*setsmbpwpos) (void *, SMB_BIG_UINT);
+
+ /*
+ * smb password database query functions.
+ */
+ struct smb_passwd *(*getsmbpwnam) (const char *);
+ struct smb_passwd *(*getsmbpwuid) (uid_t);
+ struct smb_passwd *(*getsmbpwent) (void *);
+
+ /*
+ * smb password database modification functions.
+ */
+ BOOL (*add_smbpwd_entry) (struct smb_passwd *);
+ BOOL (*mod_smbpwd_entry) (struct smb_passwd *, BOOL);
#if 0
- /*
- * password checking functions
- */
- struct smb_passwd *(*smb_password_chal )(char *username, char lm_pass[24], char nt_pass[24], char chal[8]);
- struct smb_passwd *(*smb_password_check )(char *username, char lm_hash[16], char nt_hash[16]);
- struct passwd *(*unix_password_check)(char *username, char *pass, int pass_len);
+ /*
+ * password checking functions
+ */
+ struct smb_passwd *(*smb_password_chal) (const char *username,
+ const char lm_pass[24],
+ const char nt_pass[24],
+ char chal[8]);
+ struct smb_passwd *(*smb_password_check) (const char *username,
+ const char lm_hash[16],
+ const char nt_hash[16]);
+ struct passwd *(*unix_password_check) (const char *username,
+ const char *pass,
+ int pass_len);
#endif
};
/*
- * Flags for local user manipulation.
+ * Each implementation of the password database code needs
+ * to support the following operations.
+ */
+
+struct sam_passdb_ops
+{
+ /*
+ * Password database operations.
+ */
+ void *(*startsam21pwent) (BOOL);
+ void (*endsam21pwent) (void *);
+ SMB_BIG_UINT(*getsam21pwpos) (void *);
+ BOOL (*setsam21pwpos) (void *, SMB_BIG_UINT);
+
+ /*
+ * sam password database query functions.
+ */
+ struct sam_passwd *(*getsam21pwntnam) (const char *);
+ struct sam_passwd *(*getsam21pwuid) (uid_t);
+ struct sam_passwd *(*getsam21pwrid) (uint32);
+ struct sam_passwd *(*getsam21pwent) (void *);
+
+ /*
+ * sam password database modification functions.
+ */
+ BOOL (*add_sam21pwd_entry) (struct sam_passwd *);
+ BOOL (*mod_sam21pwd_entry) (struct sam_passwd *, BOOL);
+
+ /*
+ * sam query display info functions.
+ */
+ struct sam_disp_info *(*getsamdispntnam) (const char *);
+ struct sam_disp_info *(*getsamdisprid) (uint32);
+ struct sam_disp_info *(*getsamdispent) (void *);
+
+};
+
+/*
+ * Each implementation of the passgrp database code needs
+ * to support the following operations.
*/
-#define LOCAL_ADD_USER 0x1
-#define LOCAL_DELETE_USER 0x2
-#define LOCAL_DISABLE_USER 0x4
-#define LOCAL_ENABLE_USER 0x8
-#define LOCAL_TRUST_ACCOUNT 0x10
-#define LOCAL_SET_NO_PASSWORD 0x20
+struct passgrp_ops
+{
+ /*
+ * Password group database ops.
+ */
+ void *(*startsmbgrpent) (BOOL);
+ void (*endsmbgrpent) (void *);
+ SMB_BIG_UINT(*getsmbgrppos) (void *);
+ BOOL (*setsmbgrppos) (void *, SMB_BIG_UINT);
+
+ /*
+ * smb passgrp database query functions, by user attributes.
+ */
+ struct smb_passwd *(*getsmbgrpntnam) (const char *, uint32 **, int *,
+ uint32 **, int *);
+ struct smb_passwd *(*getsmbgrpuid) (uid_t, uint32 **, int *,
+ uint32 **, int *);
+ struct smb_passwd *(*getsmbgrprid) (uint32, uint32 **, int *,
+ uint32 **, int *);
+ struct smb_passwd *(*getsmbgrpent) (void *, uint32 **, int *,
+ uint32 **, int *);
+};
+
+/*
+ * Each implementation of the group database code needs
+ * to support the following operations.
+ *
+ * This allows enumeration, modification and addition of groups. there
+ * is _no_ deletion of groups: you can only modify them to a status of
+ * "deleted" (this by the way is a requirement of c2 rating)
+ */
+
+struct groupdb_ops
+{
+ /*
+ * Group database ops.
+ */
+ void *(*startgroupent) (BOOL);
+ void (*endgroupent) (void *);
+ SMB_BIG_UINT(*getgrouppos) (void *);
+ BOOL (*setgrouppos) (void *, SMB_BIG_UINT);
+
+ /*
+ * group database query functions.
+ */
+ DOMAIN_GRP *(*getgroupntnam) (const char *, DOMAIN_GRP_MEMBER **,
+ int *);
+ DOMAIN_GRP *(*getgroupgid) (gid_t, DOMAIN_GRP_MEMBER **, int *);
+ DOMAIN_GRP *(*getgrouprid) (uint32, DOMAIN_GRP_MEMBER **, int *);
+ DOMAIN_GRP *(*getgroupent) (void *, DOMAIN_GRP_MEMBER **, int *);
+
+ /*
+ * group database modification functions.
+ */
+ BOOL (*add_group_entry) (DOMAIN_GRP *);
+ BOOL (*mod_group_entry) (DOMAIN_GRP *);
+ BOOL (*del_group_entry) (uint32);
+
+ BOOL (*add_group_member) (uint32, uint32);
+ BOOL (*del_group_member) (uint32, uint32);
+
+ /*
+ * user group functions
+ */
+ BOOL (*getusergroupsntnam) (const char *, DOMAIN_GRP **, int *);
+};
+
+/*
+ * Each implementation of the alias database code needs
+ * to support the following operations.
+ *
+ * This allows enumeration, modification and addition of aliases. there
+ * is _no_ deletion of aliases: you can only modify them to a status of
+ * "deleted" (this by the way is a requirement of c2 rating)
+ */
+
+struct aliasdb_ops
+{
+ /*
+ * Alias database ops.
+ */
+ void *(*startaliasent) (BOOL);
+ void (*endaliasent) (void *);
+ SMB_BIG_UINT(*getaliaspos) (void *);
+ BOOL (*setaliaspos) (void *, SMB_BIG_UINT);
+
+ /*
+ * alias database query functions.
+ */
+ LOCAL_GRP *(*getaliasntnam) (const char *, LOCAL_GRP_MEMBER **,
+ int *);
+ LOCAL_GRP *(*getaliasgid) (gid_t, LOCAL_GRP_MEMBER **, int *);
+ LOCAL_GRP *(*getaliasrid) (uint32, LOCAL_GRP_MEMBER **, int *);
+ LOCAL_GRP *(*getaliasent) (void *, LOCAL_GRP_MEMBER **, int *);
+
+ /*
+ * alias database modification functions.
+ */
+ BOOL (*add_alias_entry) (LOCAL_GRP *);
+ BOOL (*mod_alias_entry) (LOCAL_GRP *);
+ BOOL (*del_alias_entry) (uint32);
+
+ BOOL (*add_alias_member) (uint32, const DOM_SID *);
+ BOOL (*del_alias_member) (uint32, const DOM_SID *);
+
+ /*
+ * user alias functions
+ */
+ BOOL (*getuseraliasntnam) (const char *, LOCAL_GRP **, int *);
+};
+
+/* this is used for smbstatus */
+
+struct connect_record
+{
+ int magic;
+ int pid;
+ int cnum;
+ uid_t uid;
+ gid_t gid;
+ char name[24];
+ char addr[24];
+ char machine[128];
+ time_t start;
+};
+
+/* This is used by smbclient to send it to a smbfs mount point */
+struct connection_options
+{
+ int protocol;
+ /* Connection-Options */
+ uint32 max_xmit;
+ uint16 server_vuid;
+ uint16 tid;
+ /* The following are LANMAN 1.0 options */
+ uint16 sec_mode;
+ uint16 max_mux;
+ uint16 max_vcs;
+ uint16 rawmode;
+ uint32 sesskey;
+ /* The following are NT LM 0.12 options */
+ uint32 maxraw;
+ uint32 capabilities;
+ uint16 serverzone;
+};
/* key and data in the connections database - used in smbstatus and smbd */
-struct connections_key {
+struct connections_key
+{
pid_t pid;
int cnum;
fstring name;
};
-struct connections_data {
+struct connections_data
+{
int magic;
pid_t pid;
int cnum;
@@ -816,58 +954,52 @@ struct connections_data {
/* key and data records in the tdb locking database */
-struct locking_key {
+struct locking_key
+{
SMB_DEV_T dev;
SMB_INO_T inode;
};
-struct locking_data {
+struct locking_data
+{
int num_share_mode_entries;
/* the following two entries are implicit
share_mode_entry modes[num_share_mode_entries];
- char file_name[];
- */
+ char file_name[];
+ */
};
-
/* the following are used by loadparm for option lists */
typedef enum
{
- P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
- P_STRING,P_USTRING,P_GSTRING,P_UGSTRING,P_ENUM,P_SEP
-} parm_type;
+ P_BOOL, P_BOOLREV, P_CHAR, P_INTEGER, P_OCTAL,
+ P_STRING, P_USTRING, P_GSTRING, P_UGSTRING, P_ENUM, P_PTR, P_SEP
+}
+parm_type;
typedef enum
{
- P_LOCAL,P_GLOBAL,P_SEPARATOR,P_NONE
-} parm_class;
-
-/* passed to br lock code */
-enum brl_type {READ_LOCK, WRITE_LOCK};
+ P_LOCAL, P_GLOBAL, P_SEPARATOR, P_NONE
+}
+parm_class;
-struct enum_list {
+struct enum_list
+{
int value;
char *name;
};
-#define BRLOCK_FN_CAST() \
- void (*)(SMB_DEV_T dev, SMB_INO_T ino, int pid, \
- enum brl_type lock_type, \
- br_off start, br_off size)
-#define BRLOCK_FN(fn) \
- void (*fn)(SMB_DEV_T dev, SMB_INO_T ino, int pid, \
- enum brl_type lock_type, \
- br_off start, br_off size)
struct parm_struct
{
char *label;
parm_type type;
parm_class class;
void *ptr;
- BOOL (*special)(char *, char **);
+ BOOL (*special) (char *, char **);
struct enum_list *enum_list;
unsigned flags;
- union {
+ union
+ {
BOOL bvalue;
int ivalue;
char *svalue;
@@ -875,18 +1007,17 @@ struct parm_struct
} def;
};
-struct bitmap {
+struct bitmap
+{
uint32 *b;
int n;
};
-#define FLAG_BASIC 0x01 /* fundamental options */
-#define FLAG_SHARE 0x02 /* file sharing options */
-#define FLAG_PRINT 0x04 /* printing options */
-#define FLAG_GLOBAL 0x08 /* local options that should be globally settable in SWAT */
-#define FLAG_DEPRECATED 0x10 /* options that should no longer be used */
-#define FLAG_HIDE 0x20 /* options that should be hidden in SWAT */
-#define FLAG_DOS_STRING 0x40 /* convert from UNIX to DOS codepage when reading this string. */
+#define FLAG_BASIC 1 /* fundamental options */
+#define FLAG_HIDE 2 /* options that should be hidden in SWAT */
+#define FLAG_PRINT 4 /* printing options */
+#define FLAG_GLOBAL 8 /* local options that should be globally settable in SWAT */
+#define FLAG_DEPRECATED 0x10 /* options that should no longer be used */
#ifndef LOCKING_VERSION
#define LOCKING_VERSION 4
@@ -940,91 +1071,91 @@ struct bitmap {
#define FLAG_REPLY 0x80
/* the complete */
-#define SMBmkdir 0x00 /* create directory */
-#define SMBrmdir 0x01 /* delete directory */
-#define SMBopen 0x02 /* open file */
-#define SMBcreate 0x03 /* create file */
-#define SMBclose 0x04 /* close file */
-#define SMBflush 0x05 /* flush file */
-#define SMBunlink 0x06 /* delete file */
-#define SMBmv 0x07 /* rename file */
-#define SMBgetatr 0x08 /* get file attributes */
-#define SMBsetatr 0x09 /* set file attributes */
-#define SMBread 0x0A /* read from file */
-#define SMBwrite 0x0B /* write to file */
-#define SMBlock 0x0C /* lock byte range */
-#define SMBunlock 0x0D /* unlock byte range */
-#define SMBctemp 0x0E /* create temporary file */
-#define SMBmknew 0x0F /* make new file */
-#define SMBchkpth 0x10 /* check directory path */
-#define SMBexit 0x11 /* process exit */
-#define SMBlseek 0x12 /* seek */
-#define SMBtcon 0x70 /* tree connect */
-#define SMBtconX 0x75 /* tree connect and X*/
-#define SMBtdis 0x71 /* tree disconnect */
-#define SMBnegprot 0x72 /* negotiate protocol */
-#define SMBdskattr 0x80 /* get disk attributes */
-#define SMBsearch 0x81 /* search directory */
-#define SMBsplopen 0xC0 /* open print spool file */
-#define SMBsplwr 0xC1 /* write to print spool file */
-#define SMBsplclose 0xC2 /* close print spool file */
-#define SMBsplretq 0xC3 /* return print queue */
-#define SMBsends 0xD0 /* send single block message */
-#define SMBsendb 0xD1 /* send broadcast message */
-#define SMBfwdname 0xD2 /* forward user name */
-#define SMBcancelf 0xD3 /* cancel forward */
-#define SMBgetmac 0xD4 /* get machine name */
-#define SMBsendstrt 0xD5 /* send start of multi-block message */
-#define SMBsendend 0xD6 /* send end of multi-block message */
-#define SMBsendtxt 0xD7 /* send text of multi-block message */
+#define SMBmkdir 0x00 /* create directory */
+#define SMBrmdir 0x01 /* delete directory */
+#define SMBopen 0x02 /* open file */
+#define SMBcreate 0x03 /* create file */
+#define SMBclose 0x04 /* close file */
+#define SMBflush 0x05 /* flush file */
+#define SMBunlink 0x06 /* delete file */
+#define SMBmv 0x07 /* rename file */
+#define SMBgetatr 0x08 /* get file attributes */
+#define SMBsetatr 0x09 /* set file attributes */
+#define SMBread 0x0A /* read from file */
+#define SMBwrite 0x0B /* write to file */
+#define SMBlock 0x0C /* lock byte range */
+#define SMBunlock 0x0D /* unlock byte range */
+#define SMBctemp 0x0E /* create temporary file */
+#define SMBmknew 0x0F /* make new file */
+#define SMBchkpth 0x10 /* check directory path */
+#define SMBexit 0x11 /* process exit */
+#define SMBlseek 0x12 /* seek */
+#define SMBtcon 0x70 /* tree connect */
+#define SMBtconX 0x75 /* tree connect and X */
+#define SMBtdis 0x71 /* tree disconnect */
+#define SMBnegprot 0x72 /* negotiate protocol */
+#define SMBdskattr 0x80 /* get disk attributes */
+#define SMBsearch 0x81 /* search directory */
+#define SMBsplopen 0xC0 /* open print spool file */
+#define SMBsplwr 0xC1 /* write to print spool file */
+#define SMBsplclose 0xC2 /* close print spool file */
+#define SMBsplretq 0xC3 /* return print queue */
+#define SMBsends 0xD0 /* send single block message */
+#define SMBsendb 0xD1 /* send broadcast message */
+#define SMBfwdname 0xD2 /* forward user name */
+#define SMBcancelf 0xD3 /* cancel forward */
+#define SMBgetmac 0xD4 /* get machine name */
+#define SMBsendstrt 0xD5 /* send start of multi-block message */
+#define SMBsendend 0xD6 /* send end of multi-block message */
+#define SMBsendtxt 0xD7 /* send text of multi-block message */
/* Core+ protocol */
-#define SMBlockread 0x13 /* Lock a range and read */
-#define SMBwriteunlock 0x14 /* Unlock a range then write */
-#define SMBreadbraw 0x1a /* read a block of data with no smb header */
-#define SMBwritebraw 0x1d /* write a block of data with no smb header */
-#define SMBwritec 0x20 /* secondary write request */
-#define SMBwriteclose 0x2c /* write a file then close it */
+#define SMBlockread 0x13 /* Lock a range and read */
+#define SMBwriteunlock 0x14 /* Unlock a range then write */
+#define SMBreadbraw 0x1a /* read a block of data with no smb header */
+#define SMBwritebraw 0x1d /* write a block of data with no smb header */
+#define SMBwritec 0x20 /* secondary write request */
+#define SMBwriteclose 0x2c /* write a file then close it */
/* dos extended protocol */
-#define SMBreadBraw 0x1A /* read block raw */
-#define SMBreadBmpx 0x1B /* read block multiplexed */
-#define SMBreadBs 0x1C /* read block (secondary response) */
-#define SMBwriteBraw 0x1D /* write block raw */
-#define SMBwriteBmpx 0x1E /* write block multiplexed */
-#define SMBwriteBs 0x1F /* write block (secondary request) */
-#define SMBwriteC 0x20 /* write complete response */
-#define SMBsetattrE 0x22 /* set file attributes expanded */
-#define SMBgetattrE 0x23 /* get file attributes expanded */
-#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */
-#define SMBtrans 0x25 /* transaction - name, bytes in/out */
-#define SMBtranss 0x26 /* transaction (secondary request/response) */
-#define SMBioctl 0x27 /* IOCTL */
-#define SMBioctls 0x28 /* IOCTL (secondary request/response) */
-#define SMBcopy 0x29 /* copy */
-#define SMBmove 0x2A /* move */
-#define SMBecho 0x2B /* echo */
-#define SMBopenX 0x2D /* open and X */
-#define SMBreadX 0x2E /* read and X */
-#define SMBwriteX 0x2F /* write and X */
-#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */
-#define SMBffirst 0x82 /* find first */
-#define SMBfunique 0x83 /* find unique */
-#define SMBfclose 0x84 /* find close */
-#define SMBinvalid 0xFE /* invalid command */
+#define SMBreadBraw 0x1A /* read block raw */
+#define SMBreadBmpx 0x1B /* read block multiplexed */
+#define SMBreadBs 0x1C /* read block (secondary response) */
+#define SMBwriteBraw 0x1D /* write block raw */
+#define SMBwriteBmpx 0x1E /* write block multiplexed */
+#define SMBwriteBs 0x1F /* write block (secondary request) */
+#define SMBwriteC 0x20 /* write complete response */
+#define SMBsetattrE 0x22 /* set file attributes expanded */
+#define SMBgetattrE 0x23 /* get file attributes expanded */
+#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */
+#define SMBtrans 0x25 /* transaction - name, bytes in/out */
+#define SMBtranss 0x26 /* transaction (secondary request/response) */
+#define SMBioctl 0x27 /* IOCTL */
+#define SMBioctls 0x28 /* IOCTL (secondary request/response) */
+#define SMBcopy 0x29 /* copy */
+#define SMBmove 0x2A /* move */
+#define SMBecho 0x2B /* echo */
+#define SMBopenX 0x2D /* open and X */
+#define SMBreadX 0x2E /* read and X */
+#define SMBwriteX 0x2F /* write and X */
+#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */
+#define SMBffirst 0x82 /* find first */
+#define SMBfunique 0x83 /* find unique */
+#define SMBfclose 0x84 /* find close */
+#define SMBinvalid 0xFE /* invalid command */
/* Extended 2.0 protocol */
-#define SMBtrans2 0x32 /* TRANS2 protocol set */
-#define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */
-#define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */
-#define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */
-#define SMBulogoffX 0x74 /* user logoff */
+#define SMBtrans2 0x32 /* TRANS2 protocol set */
+#define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */
+#define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */
+#define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */
+#define SMBulogoffX 0x74 /* user logoff */
/* NT SMB extensions. */
-#define SMBnttrans 0xA0 /* NT transact */
-#define SMBnttranss 0xA1 /* NT transact secondary */
-#define SMBntcreateX 0xA2 /* NT create and X */
-#define SMBntcancel 0xA4 /* NT cancel */
+#define SMBnttrans 0xA0 /* NT transact */
+#define SMBnttranss 0xA1 /* NT transact secondary */
+#define SMBntcreateX 0xA2 /* NT create and X */
+#define SMBntcancel 0xA4 /* NT cancel */
/* These are the TRANS2 sub commands */
#define TRANSACT2_OPEN 0
@@ -1046,15 +1177,13 @@ struct bitmap {
#define TRANSACT2_REPORT_DFS_INCONSISTANCY 0x11
/* These are the NT transact sub commands. */
-#define NT_TRANSACT_CREATE 1
-#define NT_TRANSACT_IOCTL 2
-#define NT_TRANSACT_SET_SECURITY_DESC 3
-#define NT_TRANSACT_NOTIFY_CHANGE 4
-#define NT_TRANSACT_RENAME 5
-#define NT_TRANSACT_QUERY_SECURITY_DESC 6
-
-/* Relevant IOCTL codes */
-#define IOCTL_QUERY_JOB_INFO 0x530060
+#define NT_TRANSACT_CREATE 1
+#define NT_TRANSACT_IOCTL 2
+#define NT_TRANSACT_SET_SECURITY_DESC 3
+#define NT_TRANSACT_NOTIFY_CHANGE 4
+#define NT_TRANSACT_RENAME 5
+#define NT_TRANSACT_QUERY_SECURITY_DESC 6
+#define NT_TRANSACT_GET_DFS_REFERRAL 0x10
/* these are the trans2 sub fields for primary requests */
#define smb_tpscnt smb_vwv0
@@ -1157,8 +1286,6 @@ struct bitmap {
#define FILE_READ_ATTRIBUTES 0x080
#define FILE_WRITE_ATTRIBUTES 0x100
-#define FILE_ALL_ATTRIBUTES 0x1FF
-
/* Generic access masks & rights. */
#define SPECIFIC_RIGHTS_MASK 0x00FFFFL
#define STANDARD_RIGHTS_MASK 0xFF0000L
@@ -1167,31 +1294,7 @@ struct bitmap {
#define WRITE_DAC_ACCESS (1L<<18)
#define WRITE_OWNER_ACCESS (1L<<19)
#define SYNCHRONIZE_ACCESS (1L<<20)
-
#define SYSTEM_SECURITY_ACCESS (1L<<24)
-#define GENERIC_ALL_ACCESS (1<<28)
-#define GENERIC_EXECUTE_ACCESS (1<<29)
-#define GENERIC_WRITE_ACCESS (1<<30)
-#define GENERIC_READ_ACCESS (((unsigned)1)<<31)
-
-#define FILE_ALL_STANDARD_ACCESS 0x1F0000
-
-/* Mapping of access rights to UNIX perms. */
-#if 0 /* Don't use all here... JRA. */
-#define UNIX_ACCESS_RWX (FILE_ALL_ATTRIBUTES|FILE_ALL_STANDARD_ACCESS)
-#else
-#define UNIX_ACCESS_RWX (UNIX_ACCESS_R|UNIX_ACCESS_W|UNIX_ACCESS_X)
-#endif
-
-#define UNIX_ACCESS_R (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\
- FILE_READ_ATTRIBUTES|FILE_READ_EA|FILE_READ_DATA)
-#define UNIX_ACCESS_W (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\
- FILE_WRITE_ATTRIBUTES|FILE_WRITE_EA|\
- FILE_APPEND_DATA|FILE_WRITE_DATA)
-#define UNIX_ACCESS_X (READ_CONTROL_ACCESS|SYNCHRONIZE_ACCESS|\
- FILE_EXECUTE|FILE_READ_ATTRIBUTES)
-
-#define UNIX_ACCESS_NONE (WRITE_OWNER_ACCESS)
/* Flags field. */
#define REQUEST_OPLOCK 2
@@ -1199,7 +1302,7 @@ struct bitmap {
#define OPEN_DIRECTORY 8
/* ShareAccess field. */
-#define FILE_SHARE_NONE 0 /* Cannot be used in bitmask. */
+#define FILE_SHARE_NONE 0 /* Cannot be used in bitmask. */
#define FILE_SHARE_READ 1
#define FILE_SHARE_WRITE 2
#define FILE_SHARE_DELETE 4
@@ -1259,17 +1362,10 @@ struct bitmap {
#define RENAME_REPLACE_IF_EXISTS 1
/* Filesystem Attributes. */
-#define FILE_CASE_SENSITIVE_SEARCH 0x01
-#define FILE_CASE_PRESERVED_NAMES 0x02
-#define FILE_UNICODE_ON_DISK 0x04
-/* According to cifs9f, this is 4, not 8 */
-/* Acconding to testing, this actually sets the security attribute! */
-#define FILE_PERSISTENT_ACLS 0x08
-/* These entries added from cifs9f --tsb */
-#define FILE_FILE_COMPRESSION 0x08
-#define FILE_VOLUME_QUOTAS 0x10
-#define FILE_DEVICE_IS_MOUNTED 0x20
-#define FILE_VOLUME_IS_COMPRESSED 0x8000
+#define FILE_CASE_SENSITIVE_SEARCH 0x1
+#define FILE_CASE_PRESERVED_NAMES 0x2
+#define FILE_UNICODE_ON_DISK 0x4
+#define FILE_PERISITANT_ACLS 0x8
/* ChangeNotify flags. */
#define FILE_NOTIFY_CHANGE_FILE_NAME 0x001
@@ -1285,23 +1381,19 @@ struct bitmap {
/* where to find the base of the SMB packet proper */
#define smb_base(buf) (((char *)(buf))+4)
-/* we don't allow server strings to be longer than 48 characters as
- otherwise NT will not honour the announce packets */
-#define MAX_SERVER_STRING_LENGTH 48
-
-#define SMB_SUCCESS 0 /* The request was successful. */
-#define ERRDOS 0x01 /* Error is from the core DOS operating system set. */
-#define ERRSRV 0x02 /* Error is generated by the server network file manager.*/
-#define ERRHRD 0x03 /* Error is an hardware error. */
-#define ERRCMD 0xFF /* Command was not in the "SMB" format. */
+#define SMB_SUCCESS 0 /* The request was successful. */
+#define ERRDOS 0x01 /* Error is from the core DOS operating system set. */
+#define ERRSRV 0x02 /* Error is generated by the server network file manager. */
+#define ERRHRD 0x03 /* Error is an hardware error. */
+#define ERRCMD 0xFF /* Command was not in the "SMB" format. */
#ifdef HAVE_STDARG_H
int slprintf(char *str, int n, char *format, ...)
#ifdef __GNUC__
- __attribute__ ((format (printf, 3, 4)))
+ __attribute__ ((format(printf, 3, 4)))
#endif
-;
+ ;
#else
int slprintf();
#endif
@@ -1325,7 +1417,7 @@ char *strdup(char *s);
/* Some POSIX definitions for those without */
-
+
#ifndef S_IFDIR
#define S_IFDIR 0x4000
#endif
@@ -1333,40 +1425,40 @@ char *strdup(char *s);
#define S_ISDIR(mode) ((mode & 0xF000) == S_IFDIR)
#endif
#ifndef S_IRWXU
-#define S_IRWXU 00700 /* read, write, execute: owner */
+#define S_IRWXU 00700 /* read, write, execute: owner */
#endif
#ifndef S_IRUSR
-#define S_IRUSR 00400 /* read permission: owner */
+#define S_IRUSR 00400 /* read permission: owner */
#endif
#ifndef S_IWUSR
-#define S_IWUSR 00200 /* write permission: owner */
+#define S_IWUSR 00200 /* write permission: owner */
#endif
#ifndef S_IXUSR
-#define S_IXUSR 00100 /* execute permission: owner */
+#define S_IXUSR 00100 /* execute permission: owner */
#endif
#ifndef S_IRWXG
-#define S_IRWXG 00070 /* read, write, execute: group */
+#define S_IRWXG 00070 /* read, write, execute: group */
#endif
#ifndef S_IRGRP
-#define S_IRGRP 00040 /* read permission: group */
+#define S_IRGRP 00040 /* read permission: group */
#endif
#ifndef S_IWGRP
-#define S_IWGRP 00020 /* write permission: group */
+#define S_IWGRP 00020 /* write permission: group */
#endif
#ifndef S_IXGRP
-#define S_IXGRP 00010 /* execute permission: group */
+#define S_IXGRP 00010 /* execute permission: group */
#endif
#ifndef S_IRWXO
-#define S_IRWXO 00007 /* read, write, execute: other */
+#define S_IRWXO 00007 /* read, write, execute: other */
#endif
#ifndef S_IROTH
-#define S_IROTH 00004 /* read permission: other */
+#define S_IROTH 00004 /* read permission: other */
#endif
#ifndef S_IWOTH
-#define S_IWOTH 00002 /* write permission: other */
+#define S_IWOTH 00002 /* write permission: other */
#endif
#ifndef S_IXOTH
-#define S_IXOTH 00001 /* execute permission: other */
+#define S_IXOTH 00001 /* execute permission: other */
#endif
@@ -1394,10 +1486,10 @@ char *strdup(char *s);
#define SV_TYPE_SERVER_OSF 0x00100000
#define SV_TYPE_SERVER_VMS 0x00200000
#define SV_TYPE_WIN95_PLUS 0x00400000
-#define SV_TYPE_ALTERNATE_XPORT 0x20000000
-#define SV_TYPE_LOCAL_LIST_ONLY 0x40000000
+#define SV_TYPE_ALTERNATE_XPORT 0x20000000
+#define SV_TYPE_LOCAL_LIST_ONLY 0x40000000
#define SV_TYPE_DOMAIN_ENUM 0x80000000
-#define SV_TYPE_ALL 0xFFFFFFFF
+#define SV_TYPE_ALL 0xFFFFFFFF
/* what server type are we currently - JHT Says we ARE 4.20 */
/* this was set by JHT in liaison with Jeremy Allison early 1997 */
@@ -1409,56 +1501,76 @@ char *strdup(char *s);
/* Version 4.20 - To indicate that nmbd and browsing now works better */
#define DEFAULT_MAJOR_VERSION 0x04
-#define DEFAULT_MINOR_VERSION 0x02
+#define DEFAULT_MINOR_VERSION 0x00
/* Browser Election Values */
#define BROWSER_ELECTION_VERSION 0x010f
#define BROWSER_CONSTANT 0xaa55
/* NT Flags2 bits - cifs6.txt section 3.1.2 */
-
+
#define FLAGS2_LONG_PATH_COMPONENTS 0x0001
#define FLAGS2_EXTENDED_ATTRIBUTES 0x0002
+#define FLAGS2_EXT_SEC 0x0800
#define FLAGS2_DFS_PATHNAMES 0x1000
#define FLAGS2_READ_PERMIT_NO_EXECUTE 0x2000
-#define FLAGS2_32_BIT_ERROR_CODES 0x4000
+#define FLAGS2_32_BIT_ERROR_CODES 0x4000
#define FLAGS2_UNICODE_STRINGS 0x8000
/* Capabilities. see ftp.microsoft.com/developr/drg/cifs/cifs/cifs4.txt */
-#define CAP_RAW_MODE 0x0001
-#define CAP_MPX_MODE 0x0002
-#define CAP_UNICODE 0x0004
-#define CAP_LARGE_FILES 0x0008
-#define CAP_NT_SMBS 0x0010
-#define CAP_RPC_REMOTE_APIS 0x0020
-#define CAP_STATUS32 0x0040
-#define CAP_LEVEL_II_OPLOCKS 0x0080
-#define CAP_LOCK_AND_READ 0x0100
-#define CAP_NT_FIND 0x0200
-#define CAP_DFS 0x1000
-#define CAP_LARGE_READX 0x4000
+#define CAP_RAW_MODE 0x00000001
+#define CAP_MPX_MODE 0x00000002
+#define CAP_UNICODE 0x00000004
+#define CAP_LARGE_FILES 0x00000008
+#define CAP_NT_SMBS 0x00000010
+#define CAP_RPC_REMOTE_APIS 0x00000020
+#define CAP_STATUS32 0x00000040
+#define CAP_LEVEL_II_OPLOCKS 0x00000080
+#define CAP_LOCK_AND_READ 0x00000100
+#define CAP_NT_FIND 0x00000200
+#define CAP_DFS 0x00001000
+#define CAP_LARGE_READX 0x00004000
+#define CAP_EXTENDED_SECURITY 0x80000000
/* protocol types. It assumes that higher protocols include lower protocols
as subsets */
-enum protocol_types {PROTOCOL_NONE,PROTOCOL_CORE,PROTOCOL_COREPLUS,PROTOCOL_LANMAN1,PROTOCOL_LANMAN2,PROTOCOL_NT1};
+enum protocol_types
+{ PROTOCOL_NONE, PROTOCOL_CORE, PROTOCOL_COREPLUS, PROTOCOL_LANMAN1,
+ PROTOCOL_LANMAN2, PROTOCOL_NT1
+};
/* security levels */
-enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER,SEC_DOMAIN};
+enum security_types
+{ SEC_SHARE, SEC_USER, SEC_SERVER, SEC_DOMAIN };
+
+/* server roles */
+enum server_types
+{
+ ROLE_DOMAIN_NONE,
+ ROLE_DOMAIN_MEMBER,
+ ROLE_DOMAIN_BDC,
+ ROLE_DOMAIN_PDC
+};
/* printing types */
-enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,
- PRINT_QNX,PRINT_PLP,PRINT_LPRNG,PRINT_SOFTQ,PRINT_CUPS};
+enum printing_types
+{ PRINT_BSD, PRINT_SYSV, PRINT_AIX, PRINT_HPUX,
+ PRINT_QNX, PRINT_PLP, PRINT_LPRNG, PRINT_SOFTQ
+};
/* Remote architectures we know about. */
-enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_WIN2K, RA_SAMBA};
+enum remote_arch_types
+{ RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_SAMBA };
/* case handling */
-enum case_handling {CASE_LOWER,CASE_UPPER};
+enum case_handling
+{ CASE_LOWER, CASE_UPPER };
#ifdef WITH_SSL
/* SSL version options */
-enum ssl_version_enum {SMB_SSL_V2,SMB_SSL_V3,SMB_SSL_V23,SMB_SSL_TLS1};
+enum ssl_version_enum
+{ SMB_SSL_V2, SMB_SSL_V3, SMB_SSL_V23, SMB_SSL_TLS1 };
#endif /* WITH_SSL */
/*
@@ -1467,7 +1579,7 @@ enum ssl_version_enum {SMB_SSL_V2,SMB_SSL_V3,SMB_SSL_V23,SMB_SSL_TLS1};
*/
#define UID_FIELD_INVALID 0
-#define VUID_OFFSET 100 /* Amount to bias returned vuid numbers */
+#define VUID_OFFSET 100 /* Amount to bias returned vuid numbers */
/* Defines needed for multi-codepage support. */
#define MSDOS_LATIN_1_CODEPAGE 850
@@ -1488,11 +1600,6 @@ enum ssl_version_enum {SMB_SSL_V2,SMB_SSL_V3,SMB_SSL_V23,SMB_SSL_TLS1};
#define DEFAULT_CLIENT_CODE_PAGE MSDOS_LATIN_1_CODEPAGE
#endif /* KANJI */
-/* Global val set if multibyte codepage. */
-extern int global_is_multibyte_codepage;
-
-#define get_character_len(x) (global_is_multibyte_codepage ? skip_multibyte_char((x)) : 0)
-
/*
* Size of buffer to use when moving files across filesystems.
*/
@@ -1505,11 +1612,6 @@ extern int unix_ERR_class;
extern int unix_ERR_code;
/*
- * Used in chaining code.
- */
-extern int chain_size;
-
-/*
* Map the Core and Extended Oplock requesst bits down
* to common bits (EXCLUSIVE_OPLOCK & BATCH_OPLOCK).
*/
@@ -1553,15 +1655,6 @@ extern int chain_size;
#define EXTENDED_OPLOCK_GRANTED (1<<15)
/*
- * Return values for oplock types.
- */
-
-#define NO_OPLOCK_RETURN 0
-#define EXCLUSIVE_OPLOCK_RETURN 1
-#define BATCH_OPLOCK_RETURN 2
-#define LEVEL_II_OPLOCK_RETURN 3
-
-/*
* Loopback command offsets.
*/
@@ -1573,9 +1666,8 @@ extern int chain_size;
/*
* Oplock break command code to send over the udp socket.
- * The same message is sent for both exlusive and level II breaks.
*
- * The form of this is :
+ * Form of this is :
*
* 0 2 6 10 14 14+devsize 14+devsize+inodesize
* +----+--------+--------+--------+-------+--------+
@@ -1585,14 +1677,12 @@ extern int chain_size;
#define OPLOCK_BREAK_CMD 0x1
#define OPLOCK_BREAK_PID_OFFSET 2
-#define OPLOCK_BREAK_SEC_OFFSET (OPLOCK_BREAK_PID_OFFSET + sizeof(pid_t))
-#define OPLOCK_BREAK_USEC_OFFSET (OPLOCK_BREAK_SEC_OFFSET + sizeof(time_t))
-#define OPLOCK_BREAK_DEV_OFFSET (OPLOCK_BREAK_USEC_OFFSET + sizeof(long))
+#define OPLOCK_BREAK_SEC_OFFSET 6
+#define OPLOCK_BREAK_USEC_OFFSET 10
+#define OPLOCK_BREAK_DEV_OFFSET 14
#define OPLOCK_BREAK_INODE_OFFSET (OPLOCK_BREAK_DEV_OFFSET + sizeof(SMB_DEV_T))
#define OPLOCK_BREAK_MSG_LEN (OPLOCK_BREAK_INODE_OFFSET + sizeof(SMB_INO_T))
-#define LEVEL_II_OPLOCK_BREAK_CMD 0x3
-
/*
* Capabilities abstracted for different systems.
*/
@@ -1623,19 +1713,116 @@ extern int chain_size;
#include "smb_macros.h"
#include "nt_printing.h"
+
+typedef struct
+{
+ uint32 pid;
+ uint16 vuid;
+
+}
+vuser_key;
+
+struct use_info
+{
+ BOOL connected;
+ char *srv_name;
+ vuser_key key;
+ char *user_name;
+ char *domain;
+};
+
#include "ntdomain.h"
+typedef struct
+{
+ uid_t uid; /* uid of a validated user */
+ gid_t gid; /* gid of a validated user */
+
+ fstring requested_name; /* user name from the client */
+ fstring name; /* unix user name of a validated user */
+ fstring real_name; /* to store real name from password file - simeon */
+ BOOL guest;
+
+ /* following groups stuff added by ih */
+ /* This groups info is needed for when we become_user() for this uid */
+ int n_groups;
+ gid_t *groups;
+
+ NET_USER_INFO_3 usr;
+
+} user_struct;
+
+struct current_user
+{
+ connection_struct *conn;
+ vuser_key key;
+ uid_t uid;
+ gid_t gid;
+ int ngroups;
+ gid_t *groups;
+};
+
/* A netbios name structure. */
-struct nmb_name {
- char name[17];
- char scope[64];
- unsigned int name_type;
+struct nmb_name
+{
+ char name[17];
+ char scope[64];
+ unsigned int name_type;
+};
+
+
+#include "dfs.h"
+
+/*
+ * Size of new password account encoding string. DO NOT CHANGE.
+ */
+
+#define NEW_PW_FORMAT_SPACE_PADDED_LEN 14
+
+/*
+ Do you want session setups at user level security with a invalid
+ password to be rejected or allowed in as guest? WinNT rejects them
+ but it can be a pain as it means "net view" needs to use a password
+
+ You have 3 choices in the setting of map_to_guest:
+
+ "NEVER_MAP_TO_GUEST" means session setups with an invalid password
+ are rejected. This is the default.
+
+ "MAP_TO_GUEST_ON_BAD_USER" means session setups with an invalid password
+ are rejected, unless the username does not exist, in which case it
+ is treated as a guest login
+
+ "MAP_TO_GUEST_ON_BAD_PASSWORD" means session setups with an invalid password
+ are treated as a guest login
+
+ Note that map_to_guest only has an effect in user or server
+ level security.
+*/
+
+#define NEVER_MAP_TO_GUEST 0
+#define MAP_TO_GUEST_ON_BAD_USER 1
+#define MAP_TO_GUEST_ON_BAD_PASSWORD 2
+
+/* associate bit field or enumeration field with a string */
+struct field_info
+{
+ uint32 bits;
+ char *str;
};
#define AGENT_CMD_CON 0
#define AGENT_CMD_CON_ANON 2
#define AGENT_CMD_CON_REUSE 1
+#define MAX_MAX_MUX_LIMIT 16
+
+struct nmb_state
+{
+ struct in_addr ip;
+ int port;
+};
+
struct pwd_info
{
BOOL null_pwd;
@@ -1654,71 +1841,86 @@ struct pwd_info
uchar lm_cli_chal[8];
uchar nt_cli_chal[128];
size_t nt_cli_chal_len;
-
- uchar sess_key[16];
};
+typedef struct subst_creds
+{
+ uid_t uid;
+ fstring nt_username;
+ fstring client_addr;
+ fstring local_machine;
+ fstring client_name;
+ fstring remote_proto;
+ fstring remote_arch;
+ fstring myhostname;
+ fstring remote_machine;
+
+} CREDS_SUBST;
+
#include "rpc_creds.h"
struct ntdom_info
{
- unsigned char sess_key[16]; /* Current session key. */
- unsigned char ntlmssp_hash[258]; /* ntlmssp data. */
- uint32 ntlmssp_cli_flgs; /* ntlmssp client flags */
- uint32 ntlmssp_srv_flgs; /* ntlmssp server flags */
- uint32 ntlmssp_seq_num; /* ntlmssp sequence number */
- DOM_CRED clnt_cred; /* Client credential. */
+ unsigned char usr_sess_key[16]; /* Current user session key. */
+ uint32 ntlmssp_cli_flgs; /* ntlmssp client flags */
+ uint32 ntlmssp_srv_flgs; /* ntlmssp server flags */
+
+ unsigned char sess_key[16]; /* Client NETLOGON session key. */
+ DOM_CRED clnt_cred; /* Client NETLOGON credential. */
int max_recv_frag;
int max_xmit_frag;
+
+ vuser_key key;
};
-struct msrpc_state
+struct msrpc_local
{
fstring pipe_name;
- struct user_creds usr;
struct ntdom_info nt;
+#if 0
+ cli_auth_fns *auth;
+ void *auth_info;
+#endif
int fd;
BOOL redirect;
BOOL initialised;
char *inbuf;
char *outbuf;
-
- uint32 pid;
};
-#include "client.h"
-#include "rpcclient.h"
-/*
- * Size of new password account encoding string. DO NOT CHANGE.
- */
-
-#define NEW_PW_FORMAT_SPACE_PADDED_LEN 14
-
-/*
- Do you want session setups at user level security with a invalid
- password to be rejected or allowed in as guest? WinNT rejects them
- but it can be a pain as it means "net view" needs to use a password
+struct ncacn_np
+{
+ fstring pipe_name;
+ struct cli_state *smb;
+ uint16 fnum;
+ BOOL redirect;
+ BOOL initialised;
+};
- You have 3 choices in the setting of map_to_guest:
+typedef struct netsec_creds
+{
+ fstring domain;
+ fstring myname;
- "NEVER_MAP_TO_GUEST" means session setups with an invalid password
- are rejected. This is the default.
+ uchar sess_key[16]; /* NETLOGON session key */
- "MAP_TO_GUEST_ON_BAD_USER" means session setups with an invalid password
- are rejected, unless the username does not exist, in which case it
- is treated as a guest login
+} netsec_creds;
- "MAP_TO_GUEST_ON_BAD_PASSWORD" means session setups with an invalid password
- are treated as a guest login
+struct policy;
+struct bitmap;
- Note that map_to_guest only has an effect in user or server
- level security.
-*/
+typedef struct policy_cache
+{
+ struct policy *Policy;
+ struct bitmap *bmap;
+}
+policy_cache;
-#define NEVER_MAP_TO_GUEST 0
-#define MAP_TO_GUEST_ON_BAD_USER 1
-#define MAP_TO_GUEST_ON_BAD_PASSWORD 2
+#include "client.h"
+#include "rpcclient.h"
#endif /* _SMB_H */
+
+/* _SMB_H */
diff --git a/source/include/smb_macros.h b/source/include/smb_macros.h
index 8fb1fdbb716..e2c512fb9c1 100644
--- a/source/include/smb_macros.h
+++ b/source/include/smb_macros.h
@@ -37,10 +37,10 @@
/* for readability... */
#define IS_DOS_READONLY(test_mode) (((test_mode) & aRONLY) != 0)
-#define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
-#define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
-#define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
-#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
+#define IS_DOS_DIR(test_mode) (((test_mode) & aDIR) != 0)
+#define IS_DOS_ARCHIVE(test_mode) (((test_mode) & aARCH) != 0)
+#define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0)
+#define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0)
/* memory-allocation-helpers (idea and names from glib) */
#define g_new(type, count) \
@@ -56,9 +56,6 @@
/* zero a structure given a pointer to the structure */
#define ZERO_STRUCTP(x) { if ((x) != NULL) memset((char *)(x), 0, sizeof(*(x))); }
-/* zero a structure given a pointer to the structure - no zero check */
-#define ZERO_STRUCTPN(x) memset((char *)(x), 0, sizeof(*(x)))
-
/* zero an array - note that sizeof(array) must work - ie. it must not be a
pointer */
#define ZERO_ARRAY(x) memset((char *)(x), 0, sizeof(x))
@@ -162,75 +159,4 @@
#define SMB_ROUNDUP(x,g) (((x)+((g)-1))&~((g)-1))
-/* Extra macros added by Ying Chen at IBM - speed increase by inlining. */
-#define smb_buf(buf) (buf + smb_size + CVAL(buf,smb_wct)*2)
-#define smb_buflen(buf) (SVAL(buf,smb_vwv0 + (int)CVAL(buf, smb_wct)*2))
-
-/* Note that chain_size must be available as an extern int to this macro. */
-#define smb_offset(p,buf) (PTR_DIFF(p,buf+4) + chain_size)
-
-#define smb_len(buf) (PVAL(buf,3)|(PVAL(buf,2)<<8)|((PVAL(buf,1)&1)<<16))
-#define _smb_setlen(buf,len) buf[0] = 0; buf[1] = (len&0x10000)>>16; \
- buf[2] = (len&0xFF00)>>8; buf[3] = len&0xFF;
-
-/*********************************************************
-* Routine to check if a given string matches exactly.
-* Case can be significant or not.
-**********************************************************/
-
-#define exact_match(str, regexp, case_sig) \
- ((case_sig?strcmp(str,regexp):strcasecmp(str,regexp)) == 0)
-
-/*******************************************************************
-find the difference in milliseconds between two struct timeval
-values
-********************************************************************/
-
-#define TvalDiff(tvalold,tvalnew) \
- (((tvalnew)->tv_sec - (tvalold)->tv_sec)*1000 + \
- ((int)(tvalnew)->tv_usec - (int)(tvalold)->tv_usec)/1000)
-
-/****************************************************************************
-true if two IP addresses are equal
-****************************************************************************/
-
-#define ip_equal(ip1,ip2) ((ip1).s_addr == (ip2).s_addr)
-
-/*****************************************************************
- splits out the last subkey of a key
- *****************************************************************/
-
-#define reg_get_subkey(full_keyname, key_name, subkey_name) \
- split_at_last_component(full_keyname, key_name, '\\', subkey_name)
-
-/****************************************************************************
- Used by dptr_zero.
-****************************************************************************/
-
-#define DPTR_MASK ((uint32)(((uint32)1)<<31))
-
-/****************************************************************************
- Return True if the offset is at zero.
-****************************************************************************/
-
-#define dptr_zero(buf) ((IVAL(buf,1)&~DPTR_MASK) == 0)
-
-/*******************************************************************
-copy an IP address from one buffer to another
-********************************************************************/
-
-#define putip(dest,src) memcpy(dest,src,4)
-
-/****************************************************************************
- Make a filename into unix format.
-****************************************************************************/
-
-#define unix_format(fname) string_replace(fname,'\\','/')
-
-/****************************************************************************
- Make a file into DOS format.
-****************************************************************************/
-
-#define dos_format(fname) string_replace(fname,'/','\\')
-
#endif /* _SMB_MACROS_H */
diff --git a/source/include/stamp-h.in b/source/include/stamp-h.in
index c9061b3ad3d..0991b0da282 100644
--- a/source/include/stamp-h.in
+++ b/source/include/stamp-h.in
@@ -1 +1 @@
-Sun Jul 18 20:32:29 UTC 1999
+Mon Jan 24 20:30:59 UTC 2000
diff --git a/source/include/trans2.h b/source/include/trans2.h
index bbe796b7425..634244a1932 100644
--- a/source/include/trans2.h
+++ b/source/include/trans2.h
@@ -239,26 +239,6 @@ Byte offset Type name description
#define DIRLEN_GUESS (45+MAX(l1_achName,l2_achName))
-/*
- * DeviceType and Characteristics returned in a
- * SMB_QUERY_FS_DEVICE_INFO call.
- */
-
-#define DEVICETYPE_CD_ROM 0x2
-#define DEVICETYPE_CD_ROM_FILE_SYSTEM 0x3
-#define DEVICETYPE_DISK 0x7
-#define DEVICETYPE_DISK_FILE_SYSTEM 0x8
-#define DEVICETYPE_FILE_SYSTEM 0x9
-
-/* Characteristics. */
-#define TYPE_REMOVABLE_MEDIA 0x1
-#define TYPE_READ_ONLY_DEVICE 0x2
-#define TYPE_FLOPPY 0x4
-#define TYPE_WORM 0x8
-#define TYPE_REMOTE 0x10
-#define TYPE_MOUNTED 0x20
-#define TYPE_VIRTUAL 0x40
-
#endif
diff --git a/source/include/ustring.h b/source/include/ustring.h
new file mode 100644
index 00000000000..2b0177ead21
--- /dev/null
+++ b/source/include/ustring.h
@@ -0,0 +1,68 @@
+/*
+ Dynamic Unicode Strings
+ Copyright (C) Elrond 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _USTRING_H
+#define _USTRING_H
+
+/*
+ * dynamic Unicode strings
+ *
+ * these are length oriented, but also have
+ * a terminating NUL.
+ *
+ * NUL-chars in the middle are okay and allowed
+ *
+ * if you modify these directly:
+ * - alloc must always be >= len + 1
+ * (so the final NUL fits)
+ * call ustring_grow(str, new_alloc) if neccessary
+ * - always keep len correct
+ * - always keep a NUL-char at the end
+ * (i.e. str->str[str->len] = 0)
+ *
+ */
+
+typedef struct
+{
+ size_t len;
+ uint16 *str;
+ size_t alloc; /* always >= len + 1 */
+} UString;
+
+
+UString *ustring_new (const char *init);
+void ustring_free (UString *str);
+UString *ustring_grow (UString *str, size_t new_alloc);
+UString *ustring_shrink (UString *str);
+UString *ustring_assign (UString *str,
+ const uint16 *src, size_t len);
+UString *ustring_assign_ascii (UString *str,
+ const char *src, size_t len);
+UString *ustring_assign_ascii_str (UString *str, const char *src);
+UString *ustring_dup (const UString *str);
+int ustring_compare (const UString *a, const UString *b);
+int ustring_compare_case (const UString *a, const UString *b);
+UString *ustring_append_c (UString *str, uint16 c);
+UString *ustring_sync_len (UString *str);
+UString *ustring_upper (UString *str);
+UString *ustring_lower (UString *str);
+BOOL ustring_equal (const UString *s1, const UString *s2);
+
+
+#endif /* _USTRING_H */
diff --git a/source/include/vagent.h b/source/include/vagent.h
new file mode 100644
index 00000000000..c8b85181e4e
--- /dev/null
+++ b/source/include/vagent.h
@@ -0,0 +1,51 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Vagent structures and parameters
+ Copyright (C) Luke Kenneth Casson Leighton 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _VAGENT_H
+#define _VAGENT_H
+
+/* Vagent operations structure */
+
+struct sock_redir
+{
+ int c;
+ int s;
+ int c_id;
+ int s_id;
+ void *n;
+};
+
+struct vagent_ops
+{
+ void (*free_sock)(void* sock);
+ int (*get_agent_sock)(char* id);
+
+ BOOL (*process_cli_sock)(struct sock_redir **socks, uint32 num_socks,
+ struct sock_redir *sock);
+ BOOL (*process_srv_sock)(struct sock_redir **socks, uint32 num_socks,
+ int fd);
+
+ char* id;
+ struct sock_redir **socks;
+ uint32 num_socks;
+};
+
+#endif /* _VAGENT_H */
diff --git a/source/include/version.h b/source/include/version.h
index 1595f4f9228..ad344ea6d43 100644
--- a/source/include/version.h
+++ b/source/include/version.h
@@ -1 +1 @@
-#define VERSION "pre-3.0.0"
+#define VERSION "TNG-prealpha"
diff --git a/source/include/vfs.h b/source/include/vfs.h
index 885e7d486b2..d4ca8823ca1 100644
--- a/source/include/vfs.h
+++ b/source/include/vfs.h
@@ -75,10 +75,6 @@ struct vfs_connection_struct {
BOOL read_only;
BOOL admin_user;
- /* Handle on dlopen() call */
-
- void *dl_handle;
-
/* Paths */
pstring dirpath;
@@ -110,7 +106,7 @@ struct vfs_ops {
int (*connect)(struct vfs_connection_struct *conn, char *service,
char *user);
void (*disconnect)(void);
- SMB_BIG_UINT (*disk_free)(char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+ SMB_BIG_UINT (*disk_free)(char *path, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize);
/* Directory operations */
@@ -129,15 +125,18 @@ struct vfs_ops {
ssize_t (*write)(int fd, char *data, size_t n);
SMB_OFF_T (*lseek)(int filedes, SMB_OFF_T offset, int whence);
int (*rename)(char *old, char *new);
- void (*fsync)(int fd);
+ void (*sync)(int fd);
int (*stat)(char *fname, SMB_STRUCT_STAT *sbuf);
int (*fstat)(int fd, SMB_STRUCT_STAT *sbuf);
int (*lstat)(char *path, SMB_STRUCT_STAT *sbuf);
+ BOOL (*lock)(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
int (*unlink)(char *path);
int (*chmod)(char *path, mode_t mode);
int (*utime)(char *path, struct utimbuf *times);
};
+/* VFS options for configuration file */
+
struct vfs_options {
struct vfs_options *prev, *next;
char *name;
diff --git a/source/include/winbindd_proto.h b/source/include/winbindd_proto.h
new file mode 100644
index 00000000000..0ad5fd1746b
--- /dev/null
+++ b/source/include/winbindd_proto.h
@@ -0,0 +1,2628 @@
+#ifndef _WINBINDD_PROTO_H_
+#define _WINBINDD_PROTO_H_
+/* This file is automatically generated with "make proto". DO NOT EDIT */
+
+
+/*The following definitions come from lib/access.c */
+
+BOOL allow_access(char *deny_list,char *allow_list,
+ char *cname,char *caddr);
+BOOL check_access(int sock, char *allow_list, char *deny_list);
+
+/*The following definitions come from lib/bitmap.c */
+
+struct bitmap *bitmap_allocate(int n);
+BOOL bitmap_set(struct bitmap *bm, unsigned i);
+BOOL bitmap_clear(struct bitmap *bm, unsigned i);
+BOOL bitmap_query(struct bitmap *bm, unsigned i);
+int bitmap_find(struct bitmap *bm, unsigned ofs);
+
+/*The following definitions come from lib/charcnv.c */
+
+char *unix2dos_format(char *str,BOOL overwrite);
+char *dos2unix_format(char *str, BOOL overwrite);
+void interpret_character_set(char *str);
+
+/*The following definitions come from lib/charset.c */
+
+void charset_initialise(void);
+void codepage_initialise(int client_codepage);
+void add_char_string(char *s);
+
+/*The following definitions come from lib/crc32.c */
+
+uint32 crc32_calc_buffer( uint32 count, char *buffer);
+
+/*The following definitions come from lib/debug.c */
+
+BOOL dbg_interactive(void);
+void sig_usr2( int sig );
+void sig_usr1( int sig );
+void setup_logging( char *pname, BOOL interactive );
+void reopen_logs( void );
+void force_check_log_size( void );
+void dbgflush( void );
+BOOL dbghdr( int level, char *file, char *func, int line );
+dbg_Token dbg_char2token( dbg_Token *state, int c );
+
+/*The following definitions come from lib/doscalls.c */
+
+int dos_unlink(char *fname);
+int dos_open(char *fname,int flags,mode_t mode);
+DIR *dos_opendir(char *dname);
+char *dos_readdirname(DIR *p);
+int dos_stat(char *fname,SMB_STRUCT_STAT *sbuf);
+int dos_lstat(char *fname,SMB_STRUCT_STAT *sbuf);
+int dos_mkdir(char *dname,mode_t mode);
+int dos_rmdir(char *dname);
+int dos_chdir(char *dname);
+int dos_utime(char *fname,struct utimbuf *times);
+int copy_reg(char *source, const char *dest);
+int dos_rename(char *from, char *to);
+int dos_chmod(char *fname,mode_t mode);
+char *dos_getwd(char *unix_path);
+BOOL dos_file_exist(char *fname,SMB_STRUCT_STAT *sbuf);
+BOOL dos_directory_exist(char *dname,SMB_STRUCT_STAT *st);
+time_t dos_file_modtime(char *fname);
+SMB_OFF_T dos_file_size(char *file_name);
+int dos_ChDir(char *path);
+char *dos_GetWd(char *path);
+
+/*The following definitions come from lib/fault.c */
+
+void fault_setup(void (*fn)(void *));
+
+/*The following definitions come from lib/genrand.c */
+
+void generate_random_buffer( unsigned char *out, int len, BOOL re_seed);
+
+/*The following definitions come from lib/getsmbpass.c */
+
+char *getsmbpass(char *prompt) ;
+
+/*The following definitions come from lib/hmacmd5.c */
+
+void hmac_md5_init_rfc2104(uchar* key, int key_len, HMACMD5Context *ctx);
+void hmac_md5_init_limK_to_64(const uchar* key, int key_len,
+ HMACMD5Context *ctx);
+void hmac_md5_update(const uchar* text, int text_len, HMACMD5Context *ctx);
+void hmac_md5_final(uchar *digest, HMACMD5Context *ctx);
+void hmac_md5( uchar key[16], uchar* data, int data_len, uchar* digest);
+
+/*The following definitions come from lib/interface.c */
+
+void load_interfaces(void);
+void iface_set_default(char *ip,char *bcast,char *nmask);
+BOOL ismyip(struct in_addr ip);
+BOOL is_local_net(struct in_addr from);
+int iface_count(void);
+BOOL we_are_multihomed(void);
+struct interface *get_interface(int n);
+struct in_addr *iface_n_ip(int n);
+unsigned iface_hash(void);
+struct in_addr *iface_bcast(struct in_addr ip);
+struct in_addr *iface_ip(struct in_addr ip);
+
+/*The following definitions come from lib/kanji.c */
+
+void interpret_coding_system(char *str);
+BOOL is_multibyte_codepage(void);
+void initialize_multibyte_vectors( int client_codepage);
+
+/*The following definitions come from lib/md4.c */
+
+void mdfour(unsigned char *out, const unsigned char *in, int n);
+
+/*The following definitions come from lib/md5.c */
+
+void MD5Init(struct MD5Context *ctx);
+void MD5Update(struct MD5Context *ctx, uchar const *buf, unsigned len);
+void MD5Final(uchar digest[16], struct MD5Context *ctx);
+void MD5Transform(uint32 buf[4], const uchar inext[64]);
+
+/*The following definitions come from lib/msrpc-client.c */
+
+BOOL receive_msrpc(int fd, prs_struct * data, unsigned int timeout);
+BOOL msrpc_send(int fd, prs_struct * ps);
+BOOL msrpc_receive(int fd, prs_struct * ps);
+BOOL ncalrpc_l_connect(struct msrpc_local *msrpc, const char *pipe_name);
+void ncalrpc_l_close_socket(struct msrpc_local *msrpc);
+void ncalrpc_l_sockopt(struct msrpc_local *msrpc, char *options);
+BOOL ncalrpc_l_connect_auth(struct msrpc_local *msrpc,
+ const vuser_key * key, const char *pipename);
+struct msrpc_local *ncalrpc_l_initialise(struct msrpc_local *msrpc,
+ const vuser_key * key);
+void ncalrpc_l_shutdown(struct msrpc_local *msrpc);
+BOOL ncalrpc_l_establish_connection(struct msrpc_local *msrpc,
+ const char *pipe_name);
+
+/*The following definitions come from lib/msrpc_use.c */
+
+
+/*The following definitions come from lib/netmask.c */
+
+int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask);
+
+/*The following definitions come from lib/pidfile.c */
+
+pid_t pidfile_pid(char *name);
+void pidfile_create(char *name);
+
+/*The following definitions come from lib/replace.c */
+
+char *rep_inet_ntoa(struct in_addr ip);
+
+/*The following definitions come from lib/set_vuid.c */
+
+void init_vuid(void);
+BOOL become_vuser(const vuser_key *k);
+BOOL unbecome_vuser(void);
+
+/*The following definitions come from lib/sids.c */
+
+struct sid_map* add_sidmap_to_array(uint32 *len, struct sid_map ***array,
+ const struct sid_map *name);
+void get_sam_domain_name(void);
+BOOL get_member_domain_sid(void);
+void generate_wellknown_sids(void);
+BOOL create_sidmap_table(void);
+BOOL generate_sam_sid(char *domain_name, DOM_SID *sid);
+BOOL pwdb_initialise(BOOL is_server);
+BOOL map_domain_name_to_sid(DOM_SID *sid, char **nt_domain);
+BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain);
+BOOL map_domain_sid_to_any_dc(DOM_SID *sid, char *dc_name);
+BOOL split_domain_name(const char *fullname, char *domain, char *name);
+BOOL enumtrustdoms(char ***doms, uint32 *num_entries);
+BOOL enumdomains(char ***doms, uint32 *num_entries);
+
+/*The following definitions come from lib/signal.c */
+
+void BlockSignals(BOOL block,int signum);
+void CatchSignal(int signum,void (*handler)(int ));
+void CatchChild(void);
+void CatchChildLeaveStatus(void);
+
+/*The following definitions come from lib/slprintf.c */
+
+int vslprintf(char *str, int n, char *format, va_list ap);
+
+/*The following definitions come from lib/smbrun.c */
+
+int smbrun(char *cmd,char *outfile,BOOL shared);
+
+/*The following definitions come from lib/snprintf.c */
+
+
+/*The following definitions come from lib/stub_uid.c */
+
+void become_root(BOOL save_dir);
+void unbecome_root(BOOL restore_dir);
+const vuser_key *get_sec_ctx(void);
+
+/*The following definitions come from lib/surs.c */
+
+BOOL surs_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id, BOOL create);
+BOOL surs_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid, BOOL create);
+
+/*The following definitions come from lib/sursalgdomonly.c */
+
+BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id,
+ BOOL create);
+BOOL surs_algdomonly_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid,
+ BOOL create);
+
+/*The following definitions come from lib/sursalgnt5ldap.c */
+
+BOOL surs_nt5ldap_sam_sid_to_unixid(LDAPDB *hds, DOM_SID * sid, uint32 type,
+ uint32 * id, BOOL create);
+BOOL surs_nt5ldap_unixid_to_sam_sid(LDAPDB *hds, uint32 id, uint32 type,
+ DOM_SID * sid, BOOL create);
+
+/*The following definitions come from lib/surstdb.c */
+
+BOOL surs_tdb_sam_sid_to_unixid(DOM_SID * sid, uint32 type, uint32 * id,
+ BOOL create);
+BOOL surs_tdb_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID * sid,
+ BOOL create);
+
+/*The following definitions come from lib/system.c */
+
+int sys_select(int maxfd, fd_set *fds, fd_set *w_fds, struct timeval *tval);
+int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval);
+int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf);
+int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf);
+int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf);
+int sys_ftruncate(int fd, SMB_OFF_T offset);
+SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence);
+int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence);
+SMB_OFF_T sys_ftell(FILE *fp);
+int sys_creat(const char *path, mode_t mode);
+int sys_open(const char *path, int oflag, mode_t mode);
+FILE *sys_fopen(const char *path, const char *type);
+void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, SMB_OFF_T offset);
+int sys_waitpid(pid_t pid,int *status,int options);
+char *sys_getwd(char *s);
+int sys_chown(const char *fname,uid_t uid,gid_t gid);
+int sys_chroot(const char *dname);
+struct hostent *sys_gethostbyname(const char *name);
+BOOL set_process_capability( uint32 cap_flag, BOOL enable );
+BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable );
+long sys_random(void);
+void sys_srandom(unsigned int seed);
+int sys_getgroups(int setlen, gid_t *gidset);
+struct passwd *copy_passwd_struct(struct passwd *pass);
+struct passwd *sys_getpwnam(const char *name);
+struct passwd *sys_getpwuid(uid_t uid);
+
+/*The following definitions come from lib/time.c */
+
+void GetTimeOfDay(struct timeval *tval);
+void TimeInit(void);
+int TimeDiff(time_t t);
+struct tm *LocalTime(time_t *t);
+time_t nt_time_to_unix(const NTTIME *nt);
+time_t interpret_long_date(char *p);
+void unix_to_nt_time(NTTIME *nt, time_t t);
+void init_nt_time(NTTIME *nt);
+void put_long_date(char *p,time_t t);
+BOOL null_mtime(time_t mtime);
+void put_dos_date(char *buf,int offset,time_t unixdate);
+void put_dos_date2(char *buf,int offset,time_t unixdate);
+void put_dos_date3(char *buf,int offset,time_t unixdate);
+time_t make_unix_date(void *date_ptr);
+time_t make_unix_date2(void *date_ptr);
+time_t make_unix_date3(void *date_ptr);
+char *http_timestring(time_t t);
+char *timestring(void );
+time_t get_create_time(SMB_STRUCT_STAT *st,BOOL fake_dirs);
+
+/*The following definitions come from lib/ufc.c */
+
+char *ufc_crypt(char *key,char *salt);
+
+/*The following definitions come from lib/username.c */
+
+struct passwd *hashed_getpwnam(const char *name);
+char *uidtoname(uid_t uid);
+char *get_unixhome_dir(char *user);
+BOOL map_username(char *user);
+const struct passwd *Get_Pwnam(char *user,BOOL allow_change);
+BOOL user_ok(char *user,int snum);
+BOOL user_in_list(char *user,char *list);
+
+/*The following definitions come from lib/util.c */
+
+BOOL init_myworkgroup(void);
+char *tmpdir(void);
+BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t * groups);
+uint32 get_number(const char *tmp);
+char *Atoic(char *p, int *n, char *c);
+uint32 *add_num_to_list(uint32 ** num, int *count, int val);
+char *get_numlist(char *p, uint32 ** num, int *count);
+void putip(void *dest, void *src);
+BOOL file_exist(char *fname, SMB_STRUCT_STAT * sbuf);
+int file_rename(char *from, char *to);
+time_t file_modtime(char *fname);
+BOOL directory_exist(char *dname, SMB_STRUCT_STAT * st);
+SMB_OFF_T file_size(char *file_name);
+char *attrib_string(uint16 mode);
+void unix_format(char *fname);
+void dos_format(char *fname);
+void show_msg(char *buf);
+int smb_len(char *buf);
+void _smb_setlen(char *buf, int len);
+void smb_setlen(char *buf, int len);
+int set_message(char *buf, int num_words, int num_bytes, BOOL zero);
+int smb_buflen(char *buf);
+char *smb_buf(char *buf);
+int smb_offset(char *p, char *buf);
+void dos_clean_name(char *s);
+void make_dir_struct(char *buf, char *mask, char *fname, SMB_OFF_T size,
+ int mode, time_t date);
+void close_low_fds(void);
+int set_blocking(int fd, BOOL set);
+int TvalDiff(struct timeval *tvalold, struct timeval *tvalnew);
+SMB_OFF_T transfer_file(int infd, int outfd, SMB_OFF_T n, char *header,
+ int headlen, int align);
+void msleep(int t);
+BOOL get_file_match(const char *dirname, const char *regexp,
+ uint32 * total, char ***list);
+BOOL do_match(char *str, const char *regexp, int case_sig);
+BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2);
+void become_daemon(void);
+BOOL yesno(char *p);
+int set_filelen(int fd, SMB_OFF_T len);
+void *Realloc(void *p, size_t size);
+void safe_free(void *p);
+BOOL get_myname(char *my_name, struct in_addr *ip);
+BOOL ip_equal(struct in_addr ip1, struct in_addr ip2);
+int interpret_protocol(char *str, int def);
+uint32 interpret_addr(char *str);
+struct in_addr *interpret_addr2(char *str);
+BOOL zero_ip(struct in_addr ip);
+BOOL matchname(char *remotehost, struct in_addr addr);
+void standard_sub_basic(char *str);
+void standard_sub_vuser(const user_struct * vuser, char *str);
+void standard_sub(connection_struct * conn, user_struct * vuser, char *str);
+BOOL same_net(struct in_addr ip1, struct in_addr ip2, struct in_addr mask);
+struct hostent *Get_Hostbyname(const char *name);
+BOOL process_exists(int pid);
+int get_unixgroups(const char *user, uid_t uid, gid_t gid, int *p_ngroups,
+ gid_t ** p_groups);
+BOOL get_unix_grps(int *p_ngroups, struct group **p_groups);
+void free_unix_grps(int ngroups, struct group *p_groups);
+char *gidtoname(gid_t gid);
+BOOL nametogid(const char *name, gid_t * gid);
+BOOL nametouid(const char *name, uid_t * uid);
+void smb_panic(char *why);
+char *readdirname(DIR * p);
+BOOL is_in_path(char *name, name_compare_entry * namelist);
+void set_namearray(name_compare_entry ** ppname_array, char *namelist);
+void free_namearray(name_compare_entry * name_array);
+BOOL is_myname(char *s);
+void set_remote_arch(enum remote_arch_types type);
+enum remote_arch_types get_remote_arch(void);
+char *align4(char *q, char *base);
+char *align2(char *q, char *base);
+void out_ascii(FILE * f, const uchar * buf, int len);
+void out_struct(FILE * f, const char *buf1, int len, int per_line);
+void out_data(FILE * f, const char *buf1, int len, int per_line);
+void print_asc(int level, uchar const *buf, int len);
+void dump_data(int level, const char *buf1, int len);
+void dump_data_pw(const char *msg, const uchar * data, size_t len);
+char *tab_depth(int depth);
+int str_checksum(const char *s);
+void zero_free(void *p, size_t size);
+int set_maxfiles(int requested_max);
+void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name);
+BOOL reg_split_key(const char *full_keyname, uint32 * reg_type,
+ char *key_name);
+char *get_trusted_serverlist(const char *domain);
+uint16 pwdb_acct_ctrl_from_ad(NTDS_USER_FLAG_ENUM adac);
+char *pwdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length);
+uint16 pwdb_decode_acct_ctrl(const char *p);
+time_t pwdb_get_time_last_changed(const char *p);
+time_t pwdb_get_last_set_time(const char *p);
+void pwdb_set_logon_time(char *p, int max_len, time_t t);
+void pwdb_set_logoff_time(char *p, int max_len, time_t t);
+void pwdb_set_kickoff_time(char *p, int max_len, time_t t);
+void pwdb_set_can_change_time(char *p, int max_len, time_t t);
+void pwdb_set_time_last_changed(char *p, int max_len, time_t t);
+void pwdb_set_must_change_time(char *p, int max_len, time_t t);
+void pwdb_set_last_set_time(char *p, int max_len, time_t t);
+void pwdb_sethexpwd(char *p, const uchar * pwd, uint16 acct_ctrl);
+BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 * acct_ctrl);
+void *memdup(const void *p, size_t size);
+char *passdb_path(char *name);
+char *lock_path(char *name);
+const char *get_sid_name_use_str(uint32 sid_name_use);
+
+/*The following definitions come from lib/util_array.c */
+
+void free_void_array(uint32 num_entries, void **entries,
+ void(free_item)(void*));
+void* add_copy_to_array(uint32 *len, void ***array, const void *item,
+ void*(item_dup)(const void*), BOOL alloc_anyway);
+void* add_item_to_array(uint32 *len, void ***array, void *item);
+void free_use_info_array(uint32 num_entries, struct use_info **entries);
+struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array,
+ const struct use_info *name);
+void free_char_array(uint32 num_entries, char **entries);
+char* add_chars_to_array(uint32 *len, char ***array, const char *name);
+void free_uint32_array(uint32 num_entries, uint32 **entries);
+uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name);
+void free_unistr_array(uint32 num_entries, UNISTR2 **entries);
+UNISTR2* add_unistr_to_array(uint32 *len, UNISTR2 ***array, UNISTR2 *name);
+void free_sid_array(uint32 num_entries, DOM_SID **entries);
+DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid);
+
+/*The following definitions come from lib/util_file.c */
+
+BOOL do_file_lock(int fd, int waitsecs, int type);
+BOOL file_lock(int fd, int type, int secs, int *plock_depth);
+BOOL file_unlock(int fd, int *plock_depth);
+BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type);
+void *startfileent(char *pfile, char *s_readbuf, int bufsize,
+ int *file_lock_depth, BOOL update);
+void endfileent(void *vp, int *file_lock_depth);
+SMB_BIG_UINT getfilepwpos(void *vp);
+BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok);
+int getfileline(void *vp, char *linebuf, int linebuf_size);
+char *fgets_slash(char *s2,int maxlen,FILE *f);
+BOOL file_modified(const char *filename, time_t *lastmodified);
+void *open_file_if_modified(const char *filename, char *mode, time_t *lastmodified);
+
+/*The following definitions come from lib/util_hnd.c */
+
+struct policy_cache *get_global_hnd_cache(void);
+struct policy_cache *init_policy_cache(int num_pol_hnds);
+void free_policy_cache(struct policy_cache *cache);
+BOOL policy_hnd_set_name(struct policy_cache *cache,
+ POLICY_HND *hnd, const char *name);
+const char *policy_hnd_get_name(struct policy_cache *cache,
+ const POLICY_HND *hnd);
+BOOL dup_policy_hnd(struct policy_cache *cache,
+ POLICY_HND *hnd,
+ const POLICY_HND *from);
+BOOL register_policy_hnd(struct policy_cache *cache,
+ const vuser_key *key,
+ POLICY_HND *hnd,
+ uint32 access_mask);
+BOOL open_policy_hnd(struct policy_cache *cache,
+ const vuser_key *key,
+ POLICY_HND *hnd,
+ uint32 access_mask);
+BOOL open_policy_hnd_link(struct policy_cache *cache,
+ const POLICY_HND *parent_hnd,
+ POLICY_HND *hnd,
+ uint32 access_mask);
+int find_policy_by_hnd(struct policy_cache *cache, const POLICY_HND *hnd);
+BOOL set_policy_state(struct policy_cache *cache, POLICY_HND *hnd,
+ void(*fn)(void*), void *dev);
+void *get_policy_state_info(struct policy_cache *cache, const POLICY_HND *hnd);
+BOOL policy_hnd_set_state_type(struct policy_cache *cache,
+ POLICY_HND *hnd, int type);
+int policy_hnd_get_state_type(struct policy_cache *cache,
+ const POLICY_HND *hnd);
+BOOL policy_hnd_check_state_type(struct policy_cache *cache,
+ const POLICY_HND *hnd, int type);
+BOOL close_policy_hnd(struct policy_cache *cache, POLICY_HND *hnd);
+BOOL policy_link_key(struct policy_cache *cache, const POLICY_HND *hnd,
+ POLICY_HND *to);
+const vuser_key *get_policy_vuser_key(struct policy_cache *cache,
+ const POLICY_HND *hnd);
+BOOL pol_get_usr_sesskey(struct policy_cache *cache, const POLICY_HND *hnd,
+ uchar usr_sess_key[16]);
+
+/*The following definitions come from lib/util_seaccess.c */
+
+BOOL se_access_check(const SEC_DESC * sd, const NET_USER_INFO_3 * user,
+ uint32 acc_req, uint32 prev_grant_acc,
+ uint32 * acc_grant,
+ uint32 * status);
+
+/*The following definitions come from lib/util_sec.c */
+
+void gain_root_privilege(void);
+void gain_root_group_privilege(void);
+void set_effective_uid(uid_t uid);
+void set_effective_gid(gid_t gid);
+void save_re_uid(void);
+void restore_re_uid(void);
+int set_re_uid(void);
+void become_user_permanently(uid_t uid, gid_t gid);
+
+/*The following definitions come from lib/util_sid.c */
+
+char *sid_to_string(pstring sidstr_out, const DOM_SID *sid);
+BOOL string_to_sid(DOM_SID *sidout, const char *sidstr);
+BOOL sid_append_rid(DOM_SID *sid, uint32 rid);
+BOOL sid_split_rid(DOM_SID *sid, uint32 *rid);
+void sid_copy(DOM_SID *sid1, const DOM_SID *sid2);
+BOOL sid_front_equal(const DOM_SID *sid1, const DOM_SID *sid2);
+BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2);
+int sid_size(const DOM_SID *sid);
+DOM_SID *sid_dup(const DOM_SID *src);
+BOOL read_sid(char *domain_name, DOM_SID *sid);
+BOOL write_sid(char *domain_name, DOM_SID *sid);
+BOOL create_new_sid(DOM_SID *sid);
+
+/*The following definitions come from lib/util_sock.c */
+
+BOOL is_a_socket(int fd);
+void set_socket_options(int fd, char *options);
+void close_sockets(void );
+ssize_t write_socket(int fd,char *buf,size_t len);
+ssize_t read_udp_socket(int fd,char *buf,size_t len);
+ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out);
+BOOL send_keepalive(int client);
+ssize_t read_data(int fd,char *buffer,size_t N);
+ssize_t write_data(int fd,char *buffer,size_t N);
+ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout);
+BOOL receive_smb(int fd,char *buffer, unsigned int timeout);
+BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout);
+BOOL send_smb(int fd,char *buffer);
+BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type);
+int open_socket_in(int type, int port, int dlevel,uint32 socket_addr,
+ BOOL rebind);
+int open_socket_out(int type, struct in_addr *addr, int port ,int timeout);
+void set_client_connection_name(const char* name, int fd);
+void set_client_connection_addr(const char* addr, int fd);
+char *client_connection_name(void);
+char *client_connection_addr(void);
+void reset_globals_after_fork(void);
+char *client_name(int fd);
+char *client_addr(int fd);
+int open_pipe_sock(char *path);
+int create_pipe_socket(char *dir, int dir_perms,
+ char *path, int path_perms);
+
+/*The following definitions come from lib/util_str.c */
+
+void set_first_token(char *ptr);
+BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize);
+char **toktocliplist(int *ctok, char *sep);
+int StrCaseCmp(const char *s, const char *t);
+int StrnCaseCmp(const char *s, const char *t, size_t n);
+BOOL strequal(const char *s1, const char *s2);
+BOOL strnequal(const char *s1,const char *s2,size_t n);
+BOOL strcsequal(const char *s1,const char *s2);
+void strlower(char *s);
+void strupper(char *s);
+void strnorm(char *s);
+BOOL strisnormal(char *s);
+void string_replace(char *s,char oldc,char newc);
+char *skip_string(char *buf,size_t n);
+size_t str_charnum(const char *s);
+BOOL trim_string(char *s,const char *front,const char *back);
+BOOL strhasupper(const char *s);
+BOOL strhaslower(const char *s);
+size_t count_chars(const char *s,char c);
+char *safe_strcpy(char *dest,const char *src, size_t maxlength);
+char *safe_strcat(char *dest, const char *src, size_t maxlength);
+char *StrCpy(char *dest,const char *src);
+char *StrnCpy(char *dest,const char *src,size_t n);
+char *strncpyn(char *dest, char *src,size_t n, char c);
+size_t strhex_to_str(char *p, size_t len, const char *strhex);
+BOOL in_list(char *s,char *list,BOOL casesensitive);
+BOOL string_init(char **dest,const char *src);
+void string_free(char **s);
+BOOL string_set(char **dest,const char *src);
+void string_sub(char *s,const char *pattern,const char *insert);
+void all_string_sub(char *s,const char *pattern,const char *insert, size_t len);
+void split_at_first_component(char *path, char *front, char sep, char *back);
+void split_at_last_component(char *path, char *front, char sep, char *back);
+char *bit_field_to_str(uint32 type, struct field_info *bs);
+char *enum_field_to_str(uint32 type, struct field_info *bs, BOOL first_default);
+
+/*The following definitions come from lib/util_unistr.c */
+
+char *ascii_to_unibuf(char *dest, const char *src, int maxlen);
+const char* unibuf_to_ascii(char *dest, const char *src, int maxlen);
+void ascii_to_unistr(uint16 *dest, const char *src, int maxlen);
+void unistr_to_ascii(char *dest, const uint16 *src, int len);
+char *unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen);
+char *skip_unibuf(char *srcbuf, int len);
+char *uni_strncpy(char *destbuf, const char *srcbuf, int len);
+uint32 buffer2_to_uint32(const BUFFER2 *str);
+void buffer2_to_multistr(char *dest, const BUFFER2 *str, size_t maxlen);
+void buffer4_to_str(char *dest, const BUFFER4 *str, size_t maxlen);
+UNISTR2 *unistr2_new(const char *init);
+UNISTR2 *unistr2_assign(UNISTR2 *str, const uint16 *src, size_t len);
+UNISTR2 *unistr2_assign_ascii(UNISTR2 *str, const char *buf, int len);
+UNISTR2 *unistr2_assign_ascii_str(UNISTR2 *str, const char *buf);
+UNISTR2 *unistr2_grow(UNISTR2 *str, size_t new_size);
+BOOL unistr2upper(UNISTR2 *str, const UNISTR2 *from);
+BOOL copy_unistr2(UNISTR2 *str, const UNISTR2 *from);
+UNISTR2 *unistr2_dup(const UNISTR2 *name);
+void unistr2_free(UNISTR2 *name);
+int StrCaseCmpW(const UNISTR2 *ws, const UNISTR2 *wt);
+BOOL unistr2equal(const UNISTR2 *s1, const UNISTR2 *s2);
+
+/*The following definitions come from lib/vagent.c */
+
+void init_sock_redir(struct vagent_ops*va);
+void free_sock_redir(struct vagent_ops*va);
+void start_agent(struct vagent_ops *va);
+
+/*The following definitions come from lib/vuser.c */
+
+BOOL is_valid_user_struct(const vuser_key * key);
+user_struct *get_valid_user_struct(const vuser_key * key);
+void invalidate_vuid(vuser_key * key);
+BOOL validated_username(vuser_key * key, char *name, size_t len);
+uint16 create_vuid(pid_t pid,
+ uid_t uid, gid_t gid,
+ int n_groups, gid_t * groups,
+ const char *unix_name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+uint16 register_vuid(pid_t pid, uid_t uid, gid_t gid,
+ const char *unix_name,
+ const char *requested_name,
+ BOOL guest, const NET_USER_INFO_3 * info3);
+BOOL check_vuser_ok(struct uid_cache *cache, user_struct * vuser, int snum);
+
+/*The following definitions come from lib/vuser_db.c */
+
+BOOL tdb_delete_vuid( const vuser_key *uk);
+BOOL tdb_lookup_vuid( const vuser_key *uk, user_struct **usr);
+BOOL tdb_store_vuid( const vuser_key *uk, user_struct *usr);
+BOOL vuid_init_db(void);
+
+/*The following definitions come from libsmb/clientgen.c */
+
+int cli_set_port(struct cli_state *cli, int port);
+char *cli_errstr(struct cli_state *cli);
+void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len);
+BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen);
+void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen);
+BOOL cli_send_trans(struct cli_state *cli, int trans,
+ char *name, int pipe_name_len,
+ int fid, int flags,
+ uint16 *setup, int lsetup, int msetup,
+ char *param, int lparam, int mparam,
+ char *data, int ldata, int mdata);
+BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len,
+ uint16 *setup, uint32 setup_count, uint32 max_setup_count,
+ char *params, uint32 param_count, uint32 max_param_count,
+ char *data, uint32 data_count, uint32 max_data_count,
+ char **rparam, uint32 *rparam_count,
+ char **rdata, uint32 *rdata_count);
+BOOL cli_api(struct cli_state *cli,
+ char *param, int prcnt, int mprcnt,
+ char *data, int drcnt, int mdrcnt,
+ char **rparam, int *rprcnt,
+ char **rdata, int *rdrcnt);
+BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation);
+BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *));
+BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
+ void (*fn)(const char *, uint32, const char *));
+BOOL cli_session_setup_x(struct cli_state *cli,
+ char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *user_domain);
+BOOL cli_session_setup(struct cli_state *cli,
+ char *myhostname, char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *user_domain);
+BOOL cli_ulogoff(struct cli_state *cli);
+BOOL cli_send_tconX(struct cli_state *cli,
+ char *share, char *dev, char *pass, int passlen);
+BOOL cli_tdis(struct cli_state *cli);
+BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst);
+BOOL cli_unlink(struct cli_state *cli, char *fname);
+BOOL cli_mkdir(struct cli_state *cli, char *dname);
+BOOL cli_rmdir(struct cli_state *cli, char *dname);
+int cli_nt_create(struct cli_state *cli, const char *fname);
+int cli_open(struct cli_state *cli, const char *fname,
+ int flags, int share_mode);
+BOOL cli_close(struct cli_state *cli, int fnum);
+BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
+BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout);
+size_t cli_read_one(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size);
+size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size, BOOL overlap);
+ssize_t cli_write(struct cli_state *cli,
+ int fnum, uint16 write_mode,
+ char *buf, off_t offset, size_t size, size_t bytes_left);
+BOOL cli_getattrE(struct cli_state *cli, int fd,
+ uint16 *attr, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time);
+BOOL cli_getatr(struct cli_state *cli, char *fname,
+ uint16 *attr, size_t *size, time_t *t);
+BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t);
+BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ size_t *size, uint16 *mode);
+BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ time_t *w_time, size_t *size, uint16 *mode,
+ SMB_INO_T *ino);
+BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
+ uint16 *mode, size_t *size,
+ time_t *c_time, time_t *a_time, time_t *m_time,
+ time_t *w_time, SMB_INO_T *ino);
+int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
+ void (*fn)(file_info *, const char *));
+BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password,
+ const char *old_password);
+BOOL cli_negprot(struct cli_state *cli);
+BOOL cli_session_request(struct cli_state *cli,
+ struct nmb_name *calling, struct nmb_name *called);
+BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip);
+void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr);
+struct cli_state *cli_initialise(struct cli_state *cli);
+void cli_close_socket(struct cli_state *cli);
+void cli_shutdown(struct cli_state *cli);
+int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num);
+void cli_sockopt(struct cli_state *cli, char *options);
+uint16 cli_setpid(struct cli_state *cli, uint16 pid);
+BOOL cli_reestablish_connection(struct cli_state *cli);
+BOOL cli_establish_connection(struct cli_state *cli,
+ const char *dest_host, struct in_addr *dest_ip,
+ struct nmb_name *calling, struct nmb_name *called,
+ char *service, char *service_type,
+ BOOL do_shutdown, BOOL do_tcon);
+BOOL cli_connect_auth(struct cli_state *cli,
+ const char* desthost,
+ struct in_addr *dest_ip,
+ const struct ntuser_creds *usr);
+BOOL cli_connect_servers_auth(struct cli_state *cli,
+ char *p,
+ const struct ntuser_creds *usr);
+BOOL cli_connect_serverlist(struct cli_state *cli, char *p);
+int cli_printjob_del(struct cli_state *cli, int job);
+int cli_print_queue(struct cli_state *cli,
+ void (*fn)(struct print_job_info *));
+BOOL cli_chkpath(struct cli_state *cli, char *path);
+BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
+ int *grp);
+BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp);
+BOOL cli_message_end(struct cli_state *cli, int grp);
+BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail);
+BOOL get_any_dc_name(const char *domain, char *srv_name);
+
+/*The following definitions come from libsmb/credentials.c */
+
+char *credstr(const uchar *cred);
+void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, const char *pass,
+ uchar session_key[8]);
+void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp,
+ DOM_CHAL *cred);
+int cred_assert(const DOM_CHAL *cred, uchar session_key[8],
+ DOM_CHAL *stored_cred, UTIME timestamp);
+BOOL clnt_deal_with_creds(uchar sess_key[8],
+ DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred);
+BOOL deal_with_creds(uchar sess_key[8],
+ DOM_CRED *sto_clnt_cred,
+ const DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred);
+
+/*The following definitions come from libsmb/namequery.c */
+
+BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
+ struct in_addr to_ip,char *master,char *rname,
+ void (*fn)(struct packet_struct *));
+struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse,
+ struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *));
+FILE *startlmhosts(char *fname);
+BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr);
+void endlmhosts(FILE *fp);
+BOOL is_ip_address(const char *name);
+BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type);
+BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
+ struct in_addr *ip);
+BOOL find_master_ip(char *group, struct in_addr *master_ip);
+
+/*The following definitions come from libsmb/nmblib.c */
+
+void debug_nmb_packet(struct packet_struct *p);
+char *nmb_namestr(struct nmb_name *n);
+void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len);
+struct packet_struct *copy_packet(struct packet_struct *packet);
+void free_packet(struct packet_struct *packet);
+struct packet_struct *read_packet(int fd,enum packet_type packet_type);
+void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope );
+BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2);
+BOOL send_packet(struct packet_struct *p);
+struct packet_struct *receive_packet(int fd,enum packet_type type,int t);
+void sort_query_replies(char *data, int n, struct in_addr ip);
+BOOL read_nmb_sock(int c, struct nmb_state *con);
+int get_nmb_sock(void);
+char *dns_to_netbios_name(char *dns_name);
+int name_mangle( char *In, char *Out, char name_type );
+int name_extract(char *buf,int ofs,char *name);
+int name_len(char *s1);
+
+/*The following definitions come from libsmb/nterr.c */
+
+BOOL get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len);
+const char *get_nt_error_msg(uint32 nt_code);
+
+/*The following definitions come from libsmb/pwd_cache.c */
+
+void pwd_init(struct pwd_info *pwd);
+BOOL pwd_is_nullpwd(const struct pwd_info *pwd);
+void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key);
+BOOL pwd_compare(const struct pwd_info *_pwd1, const struct pwd_info *_pwd2);
+void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt);
+void pwd_set_nullpwd(struct pwd_info *pwd);
+void pwd_set_cleartext(struct pwd_info *pwd, char *clr);
+void pwd_get_cleartext(struct pwd_info *pwd, char *clr);
+void pwd_set_lm_nt_16(struct pwd_info *pwd,
+ const uchar lm_pwd[16],
+ const uchar nt_pwd[16]);
+void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]);
+void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr);
+void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
+ const char *user, const char *server, const char *domain,
+ uchar sess_key[16]);
+void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
+ uchar sess_key[16]);
+void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
+ uchar *nt_owf, size_t *nt_owf_len);
+
+/*The following definitions come from libsmb/smbdes.c */
+
+void smbhash(uchar *out, const uchar *in, const uchar *key, int forw);
+void E_P16(uchar *p14,uchar *p16);
+void E_P24(const uchar *p21, const uchar *c8, uchar *p24);
+void D_P16(const uchar *p14, const uchar *in, uchar *out);
+void E_old_pw_hash( const uchar *p14, const uchar *in, uchar *out);
+void cred_hash1(uchar *out, const uchar *in, const uchar *key);
+void cred_hash2(uchar *out,uchar *in,uchar *key);
+void cred_hash3(uchar *out, const uchar *in,uchar *key, int forw);
+void SamOEMhash( uchar *data, const uchar *key, int val);
+void sam_pwd_hash(uint32 rid, const uchar *in, uchar *out, int forw);
+
+/*The following definitions come from libsmb/smbencrypt.c */
+
+void SMBencrypt(uchar * pwrd, uchar * c8, uchar * p24);
+void SMBNTencrypt(uchar * pwrd, uchar * c8, uchar * p24);
+void E_md4hash(uchar * pwrd, uchar * p16);
+void lm_owf_genW(const UNISTR2 * pwd, uchar p16[16]);
+void lm_owf_gen(const char *pwd, uchar p16[16]);
+void nt_owf_genW(const UNISTR2 * pwd, uchar nt_p16[16]);
+void nt_owf_gen(const char *pwd, uchar nt_p16[16]);
+void nt_lm_owf_genW(const UNISTR2 * pwd, uchar nt_p16[16], uchar lm_p16[16]);
+void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16]);
+void SMBOWFencrypt(const uchar pwrd[16], const uchar * c8, uchar p24[24]);
+void SMBOWFencrypt_ntv2(const uchar kr[16],
+ const uchar * srv_chal, int srv_chal_len,
+ const uchar * cli_chal, int cli_chal_len,
+ char resp_buf[16]);
+void SMBsesskeygen_ntv2(const uchar kr[16],
+ const uchar * nt_resp, char sess_key[16]);
+void SMBsesskeygen_ntv1(const uchar kr[16],
+ const uchar * nt_resp, char sess_key[16]);
+void SMBgenclientchals(char *lm_cli_chal,
+ char *nt_cli_chal, int *nt_cli_chal_len,
+ const char *srv, const char *dom);
+void ntv2_owf_gen(const uchar owf[16],
+ const char *user_n, const char *domain_n, uchar kr_buf[16]);
+void NTLMSSPOWFencrypt(const uchar pwrd[8], const uchar * ntlmchalresp,
+ uchar p24[24]);
+BOOL make_oem_passwd_hash(uchar data[516],
+ const char *pwrd, int new_pw_len,
+ const uchar old_pw_hash[16], BOOL unicode);
+BOOL nt_encrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
+BOOL nt_decrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key);
+void create_ntlmssp_resp(struct pwd_info *pwd,
+ char *domain, char *user_name, char *my_name,
+ uint32 ntlmssp_cli_flgs, prs_struct * auth_resp);
+BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
+ int new_pwrd_size, uint32 * new_pw_len);
+BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
+ int new_pw_len, BOOL nt_pass_set);
+
+/*The following definitions come from libsmb/smberr.c */
+
+char *smb_err_msg(uint8 class, uint32 num);
+BOOL smb_safe_err_msg(uint8 class, uint32 num, char *ret, size_t len);
+BOOL smb_safe_errstr(char *inbuf, char *msg, size_t len);
+char *smb_errstr(char *inbuf);
+
+/*The following definitions come from nsswitch/winbindd.c */
+
+void exit_server(char *reason);
+int winbind_get_domain_sid(char *system_name, fstring domain_name,
+ DOM_SID *domain_sid);
+int winbind_lookup_by_name(char *system_name, DOM_SID *level5_sid,
+ fstring name, DOM_SID *sid,
+ enum SID_NAME_USE *type);
+int winbind_lookup_by_sid(char *system_name, DOM_SID *level5_sid,
+ DOM_SID *sid, char *name,
+ enum SID_NAME_USE *type);
+int winbind_lookup_userinfo(char *system_name, DOM_SID *level5_sid,
+ uint32 user_rid, SAM_USERINFO_CTR *info);
+int winbind_lookup_groupinfo(char *system_name, DOM_SID *level5_sid,
+ uint32 group_rid, GROUP_INFO_CTR *info);
+int create_winbind_socket(void);
+int main(int argc, char **argv);
+
+/*The following definitions come from nsswitch/winbindd_group.c */
+
+void winbindd_getgrnam_from_group(DOM_SID *domain_sid,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
+void winbindd_getgrnam_from_gid(DOM_SID *domain_sid,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
+
+/*The following definitions come from nsswitch/winbindd_surs.c */
+
+BOOL winbindd_surs_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id);
+BOOL winbindd_surs_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid,
+ BOOL create);
+
+/*The following definitions come from nsswitch/winbindd_user.c */
+
+void winbindd_getpwnam_from_user(DOM_SID *domain_sid,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
+void winbindd_getpwnam_from_uid(DOM_SID *domain_sid,
+ struct winbindd_request *request,
+ struct winbindd_response *response);
+
+/*The following definitions come from param/loadparm.c */
+
+struct vfs_options *lp_vfsoptions(int i) ;
+char *lp_logfile(void);
+char *lp_smbrun(void);
+char *lp_configfile(void);
+char *lp_smb_passwd_file(void);
+char *lp_sam_directory(void);
+char *lp_smb_passgrp_file(void);
+char *lp_smb_group_file(void);
+char *lp_smb_alias_file(void);
+char *lp_serverstring(void);
+char *lp_printcapname(void);
+char *lp_lockdir(void);
+char *lp_rootdir(void);
+char *lp_defaultservice(void);
+char *lp_msg_command(void);
+char *lp_hosts_equiv(void);
+char *lp_auto_services(void);
+char *lp_passwd_program(void);
+char *lp_passwd_chat(void);
+char *lp_passwordserver(void);
+char *lp_name_resolve_order(void);
+char *lp_workgroup(void);
+char *lp_trusted_domains(void);
+char *lp_trusting_domains(void);
+char *lp_username_map(void);
+char *lp_aliasname_map(void);
+char *lp_groupname_map(void);
+char *lp_builtinname_map(void);
+char *lp_builtinrid_file(void);
+char *lp_ntusrname_map(void);
+char *lp_remote_announce(void);
+char *lp_remote_browse_sync(void);
+char *lp_wins_server(void);
+char *lp_interfaces(void);
+char *lp_socket_address(void);
+char *lp_nis_home_map_name(void);
+char *lp_netbios_aliases(void);
+char *lp_driverfile(void);
+char *lp_panic_action(void);
+char *lp_nt_forms(void);
+char *lp_nt_drivers_file(void);
+char *lp_dfs_map(void);
+char *lp_ldap_server(void);
+char *lp_ldap_suffix(void);
+char *lp_ldap_bind_as(void);
+char *lp_ldap_passwd_file(void);
+char *lp_ldap_url(void);
+char *lp_ldap_realm(void);
+char *lp_ldap_computers_subcontext(void);
+char *lp_ldap_users_subcontext(void);
+char *lp_ldap_builtin_subcontext(void);
+int lp_ssl_version(void);
+char *lp_ssl_hosts(void);
+char *lp_ssl_hosts_resign(void);
+char *lp_ssl_cacertdir(void);
+char *lp_ssl_cacertfile(void);
+char *lp_ssl_cert(void);
+char *lp_ssl_privkey(void);
+char *lp_ssl_client_cert(void);
+char *lp_ssl_client_privkey(void);
+char *lp_ssl_ciphers(void);
+BOOL lp_ssl_enabled(void);
+BOOL lp_ssl_reqClientCert(void);
+BOOL lp_ssl_reqServerCert(void);
+BOOL lp_ssl_compatibility(void);
+BOOL lp_dns_proxy(void);
+BOOL lp_wins_support(void);
+BOOL lp_we_are_a_wins_server(void);
+BOOL lp_wins_proxy(void);
+BOOL lp_local_master(void);
+BOOL lp_domain_logons(void);
+BOOL lp_load_printers(void);
+BOOL lp_use_rhosts(void);
+BOOL lp_readprediction(void);
+BOOL lp_readbmpx(void);
+BOOL lp_readraw(void);
+BOOL lp_writeraw(void);
+BOOL lp_null_passwords(void);
+BOOL lp_strip_dot(void);
+BOOL lp_encrypted_passwords(void);
+BOOL lp_update_encrypted(void);
+BOOL lp_client_ntlmv2(void);
+BOOL lp_server_ntlmv2(void);
+BOOL lp_client_schannel(void);
+BOOL lp_server_schannel(void);
+BOOL lp_syslog_only(void);
+BOOL lp_timestamp_logs(void);
+BOOL lp_browse_list(void);
+BOOL lp_unix_realname(void);
+BOOL lp_nis_home_map(void);
+BOOL lp_bind_interfaces_only(void);
+BOOL lp_unix_password_sync(void);
+BOOL lp_passwd_chat_debug(void);
+BOOL lp_ole_locking_compat(void);
+BOOL lp_nt_smb_support(void);
+BOOL lp_nt_pipe_support(void);
+BOOL lp_stat_cache(void);
+int lp_os_level(void);
+int lp_max_ttl(void);
+int lp_max_wins_ttl(void);
+int lp_min_wins_ttl(void);
+int lp_max_log_size(void);
+int lp_max_open_files(void);
+int lp_maxxmit(void);
+int lp_maxmux(void);
+int lp_passwordlevel(void);
+int lp_usernamelevel(void);
+int lp_readsize(void);
+int lp_shmem_size(void);
+int lp_deadtime(void);
+int lp_maxprotocol(void);
+int lp_security(void);
+int lp_maxdisksize(void);
+int lp_lpqcachetime(void);
+int lp_syslog(void);
+int lp_client_code_page(void);
+int lp_lm_announce(void);
+int lp_lm_interval(void);
+int lp_machine_password_timeout(void);
+int lp_change_notify_timeout(void);
+int lp_stat_cache_size(void);
+int lp_map_to_guest(void);
+int lp_ldap_port(void);
+int lp_ldap_protocol_version(void);
+char *lp_logon_script(const user_struct* );
+char *lp_logon_path(const user_struct* );
+char *lp_logon_drive(const user_struct* );
+char *lp_logon_home(const user_struct* );
+char *lp_preexec(int );
+char *lp_postexec(int );
+char *lp_rootpreexec(int );
+char *lp_rootpostexec(int );
+char *lp_servicename(int );
+char *lp_pathname(int );
+char *lp_dontdescend(int );
+char *lp_username(int );
+char *lp_guestaccount(int );
+char *lp_invalid_users(int );
+char *lp_valid_users(int );
+char *lp_admin_users(int );
+char *lp_printcommand(int );
+char *lp_lpqcommand(int );
+char *lp_lprmcommand(int );
+char *lp_lppausecommand(int );
+char *lp_lpresumecommand(int );
+char *lp_queuepausecommand(int );
+char *lp_queueresumecommand(int );
+char *lp_printername(int );
+char *lp_printerdriver(int );
+char *lp_hostsallow(int );
+char *lp_hostsdeny(int );
+char *lp_magicscript(int );
+char *lp_magicoutput(int );
+char *lp_comment(int );
+char *lp_force_user(int );
+char *lp_force_group(int );
+char *lp_readlist(int );
+char *lp_writelist(int );
+char *lp_fstype(int );
+char *lp_vfsobj(int );
+char *lp_mangled_map(int );
+char *lp_veto_files(int );
+char *lp_hide_files(int );
+char *lp_veto_oplocks(int );
+char *lp_driverlocation(int );
+BOOL lp_revalidate(int );
+BOOL lp_casesensitive(int );
+BOOL lp_preservecase(int );
+BOOL lp_shortpreservecase(int );
+BOOL lp_casemangle(int );
+BOOL lp_status(int );
+BOOL lp_hide_dot_files(int );
+BOOL lp_browseable(int );
+BOOL lp_readonly(int );
+BOOL lp_no_set_dir(int );
+BOOL lp_guest_ok(int );
+BOOL lp_guest_only(int );
+BOOL lp_print_ok(int );
+BOOL lp_postscript(int );
+BOOL lp_map_hidden(int );
+BOOL lp_map_archive(int );
+BOOL lp_locking(int );
+BOOL lp_strict_locking(int );
+BOOL lp_share_modes(int );
+BOOL lp_oplocks(int );
+BOOL lp_onlyuser(int );
+BOOL lp_manglednames(int );
+BOOL lp_widelinks(int );
+BOOL lp_symlinks(int );
+BOOL lp_syncalways(int );
+BOOL lp_strict_sync(int );
+BOOL lp_map_system(int );
+BOOL lp_delete_readonly(int );
+BOOL lp_fake_oplocks(int );
+BOOL lp_recursive_veto_delete(int );
+BOOL lp_dos_filetimes(int );
+BOOL lp_dos_filetime_resolution(int );
+BOOL lp_fake_dir_create_times(int );
+BOOL lp_blocking_locks(int );
+int lp_create_mode(int );
+int lp_force_create_mode(int );
+int lp_dir_mode(int );
+int lp_force_dir_mode(int );
+int lp_max_connections(int );
+int lp_defaultcase(int );
+int lp_minprintspace(int );
+int lp_printing(int );
+char lp_magicchar(int );
+char *lp_mysql_host(void);
+char *lp_mysql_user(void);
+char *lp_mysql_passfile(void);
+char *lp_mysql_db(void);
+char *lp_mysql_table(void);
+BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir);
+int lp_add_service(char *pszService, int iDefaultService);
+BOOL lp_add_printer(char *pszPrintername, int iDefaultService);
+BOOL lp_file_list_changed(void);
+void *lp_local_ptr(int snum, void *ptr);
+BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue);
+BOOL lp_is_default(int snum, struct parm_struct *parm);
+struct parm_struct *lp_next_parameter(int snum, int *i, int allparameters);
+BOOL lp_snum_ok(int iService);
+void lp_add_one_printer(char *name,char *comment);
+BOOL lp_loaded(void);
+void lp_killunused(BOOL (*snumused)(int ));
+BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc);
+int lp_numservices(void);
+void lp_dump(FILE *f, BOOL show_defaults);
+int lp_servicenumber(char *pszServiceName);
+char *volume_label(int snum);
+void lp_remove_service(int snum);
+void lp_copy_service(int snum, char *new_name);
+int lp_default_server_announce(void);
+int lp_major_announce_version(void);
+int lp_minor_announce_version(void);
+void lp_set_name_resolve_order(char *new_order);
+void lp_set_kernel_oplocks(BOOL val);
+BOOL lp_kernel_oplocks(void);
+int lp_server_role(void);
+BOOL lp_domain_master(void);
+BOOL lp_preferred_master(void);
+
+/*The following definitions come from param/params.c */
+
+BOOL pm_process( char *FileName,
+ BOOL (*sfunc)(char *),
+ BOOL (*pfunc)(char *, char *) );
+
+/*The following definitions come from rpc_client/cli_connect.c */
+
+void init_connections(void);
+void free_connections(void);
+void cli_connection_free(struct cli_connection *con);
+void cli_connection_unlink(struct cli_connection *con);
+BOOL cli_connection_init(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con);
+BOOL cli_connection_init_auth(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con,
+ cli_auth_fns * auth, void *auth_creds);
+BOOL cli_connection_getsrv(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con);
+BOOL cli_connection_get(const POLICY_HND * pol, struct cli_connection **con);
+BOOL cli_pol_link(POLICY_HND * to, const POLICY_HND * from);
+BOOL cli_get_usr_sesskey(const POLICY_HND * pol, uchar usr_sess_key[16]);
+BOOL cli_set_con_usr_sesskey(struct cli_connection *con,
+ const uchar usr_sess_key[16]);
+const vuser_key *cli_con_sec_ctx(struct cli_connection *con);
+struct cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con);
+void *cli_conn_get_auth_creds(struct cli_connection *con);
+void *cli_conn_get_auth_info(struct cli_connection *con);
+BOOL cli_conn_set_auth_info(struct cli_connection *con, void *auth_info);
+struct ntdom_info *cli_conn_get_ntinfo(struct cli_connection *con);
+BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16]);
+BOOL cli_con_get_srvname(struct cli_connection *con, char *srv_name);
+BOOL cli_get_sesskey(const POLICY_HND * pol, uchar sess_key[16]);
+BOOL cli_get_sesskey_srv(const char *srv_name, uchar sess_key[16]);
+void cli_con_gen_next_creds(struct cli_connection *con,
+ DOM_CRED * new_clnt_cred);
+void cli_con_get_cli_cred(struct cli_connection *con, DOM_CRED * clnt_cred);
+BOOL cli_con_deal_with_creds(struct cli_connection *con,
+ DOM_CRED * rcv_srv_cred);
+BOOL cli_con_set_creds(const char *srv_name, const uchar sess_key[16],
+ DOM_CRED * cred);
+BOOL rpc_hnd_pipe_req(const POLICY_HND * hnd, uint8 op_num,
+ prs_struct * data, prs_struct * rdata);
+BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
+ prs_struct * data, prs_struct * rdata);
+BOOL rpc_api_write(struct cli_connection *con, prs_struct * data);
+BOOL rpc_api_rcv_pdu(struct cli_connection *con, prs_struct * rdata);
+BOOL rpc_api_send_rcv_pdu(struct cli_connection *con, prs_struct * data,
+ prs_struct * rdata);
+BOOL set_policy_con(struct policy_cache *cache, POLICY_HND * hnd,
+ struct cli_connection *con,
+ void (*free_fn) (struct cli_connection *));
+BOOL get_policy_con(struct policy_cache *cache, const POLICY_HND * hnd,
+ struct cli_connection **con);
+
+/*The following definitions come from rpc_client/cli_lsarpc.c */
+
+BOOL get_domain_sids(const char *domain, DOM_SID * sid3, DOM_SID * sid5);
+BOOL get_trust_sid_and_domain(const char *myname, char *server,
+ DOM_SID * sid, char *domain, size_t len);
+BOOL lsa_open_policy(const char *system_name, POLICY_HND *hnd,
+ BOOL sec_qos, uint32 des_access);
+BOOL lsa_open_policy2(const char *system_name, POLICY_HND *hnd,
+ BOOL sec_qos, uint32 des_access);
+BOOL lsa_create_secret(const POLICY_HND *hnd,
+ const char *secret_name,
+ uint32 des_access, POLICY_HND *hnd_secret);
+BOOL lsa_open_secret(const POLICY_HND *hnd,
+ const char *secret_name,
+ uint32 des_access, POLICY_HND *hnd_secret);
+uint32 lsa_set_secret(POLICY_HND *hnd, const STRING2 * secret);
+BOOL lsa_query_secret(POLICY_HND *hnd, STRING2 * secret, NTTIME * last_update);
+BOOL lsa_lookup_names(POLICY_HND *hnd,
+ int num_names,
+ char **names,
+ DOM_SID ** sids, uint32 ** types, int *num_sids);
+BOOL lsa_lookup_sids(POLICY_HND *hnd,
+ int num_sids,
+ DOM_SID ** sids,
+ char ***names, uint32 ** types, int *num_names);
+BOOL lsa_query_sec_obj(const POLICY_HND *hnd, uint32 sec_info,
+ SEC_DESC_BUF *sec_buf);
+BOOL lsa_query_info_pol(POLICY_HND *hnd, uint16 info_class,
+ fstring domain_name, DOM_SID * domain_sid);
+BOOL lsa_enum_trust_dom(POLICY_HND *hnd, uint32 * enum_ctx,
+ uint32 * num_doms, char ***names, DOM_SID *** sids);
+BOOL lsa_close(POLICY_HND *hnd);
+
+/*The following definitions come from rpc_client/cli_netlogon.c */
+
+void gen_next_creds( struct ntdom_info *nt, DOM_CRED *new_clnt_cred);
+BOOL cli_net_logon_ctrl2(const char* srv_name, uint32 status_level);
+uint32 cli_net_auth2(const char *srv_name,
+ const char *trust_acct,
+ const char *acct_name,
+ uint16 sec_chan,
+ uint32 *neg_flags, DOM_CHAL *srv_chal);
+uint32 cli_net_req_chal( const char *srv_name, const char* myhostname,
+ DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal);
+BOOL cli_net_srv_pwset(const char* srv_name,
+ const char* myhostname,
+ const char* trust_acct,
+ const uint8 hashed_trust_pwd[16],
+ uint16 sec_chan_type);
+uint32 cli_net_sam_logon(const char* srv_name, const char* myhostname,
+ NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3);
+BOOL cli_net_sam_logoff(const char* srv_name, const char* myhostname,
+ NET_ID_INFO_CTR *ctr);
+BOOL cli_net_sam_sync( const char* srv_name, const char* myhostname,
+ uint32 database_id,
+ uint32 *num_deltas,
+ SAM_DELTA_HDR *hdr_deltas,
+ SAM_DELTA_CTR *deltas);
+
+/*The following definitions come from rpc_client/cli_pipe.c */
+
+BOOL create_rpc_request(prs_struct * rhdr, uint16 vuid,
+ uint8 op_num, uint8 flags, int data_len, int auth_len);
+BOOL rpc_api_pipe_req(struct cli_connection *con, uint8 opnum,
+ prs_struct * data, prs_struct * rdata);
+BOOL cli_send_and_rcv_pdu_trans(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu);
+BOOL cli_send_and_rcv_pdu_rw(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu);
+BOOL cli_send_and_rcv_pdu(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu);
+BOOL cli_rcv_pdu(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum, prs_struct *rdata);
+BOOL rpc_pipe_bind(struct cli_connection *con,
+ const char *pipe_name,
+ RPC_IFACE * abstract, RPC_IFACE * transfer);
+void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs);
+BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name,
+ uint16 * fnum);
+void cli_nt_session_close(struct cli_state *cli, uint16 fnum);
+
+/*The following definitions come from rpc_client/cli_pipe_noauth.c */
+
+
+/*The following definitions come from rpc_client/cli_pipe_ntlmssp.c */
+
+
+/*The following definitions come from rpc_client/cli_samr.c */
+
+BOOL samr_chgpasswd_user( struct cli_connection *con,
+ const char *srv_name, const char *user_name,
+ const char nt_newpass[516], const uchar nt_oldhash[16],
+ const char lm_newpass[516], const uchar lm_oldhash[16]);
+BOOL samr_get_dom_pwinfo(struct cli_connection *con, const char *srv_name);
+BOOL samr_query_dom_info( POLICY_HND *domain_pol, uint16 switch_value,
+ SAM_UNK_CTR *ctr);
+uint32 samr_enum_domains( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_domains);
+uint32 samr_enum_dom_groups( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_groups);
+uint32 samr_enum_dom_aliases( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_aliases);
+uint32 samr_enum_dom_users( POLICY_HND *pol, uint32 *start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_users);
+BOOL samr_connect( const char *srv_name, uint32 access_mask,
+ POLICY_HND *connect_pol);
+BOOL samr_query_sec_obj( const POLICY_HND *pol,
+ uint32 type,
+ SEC_DESC_BUF *buf);
+BOOL samr_open_user( const POLICY_HND *pol,
+ uint32 unk_0, uint32 rid,
+ POLICY_HND *user_pol);
+BOOL samr_open_alias( const POLICY_HND *domain_pol,
+ uint32 flags, uint32 rid,
+ POLICY_HND *alias_pol);
+BOOL samr_del_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid);
+BOOL samr_add_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid);
+BOOL samr_delete_dom_alias( POLICY_HND *alias_pol);
+uint32 samr_create_dom_user( POLICY_HND *domain_pol, const char *acct_name,
+ uint32 unk_0, uint32 unk_1,
+ POLICY_HND *user_pol, uint32 *rid);
+BOOL samr_create_dom_alias( POLICY_HND *domain_pol, const char *acct_name,
+ POLICY_HND *alias_pol, uint32 *rid);
+BOOL samr_query_aliasinfo( POLICY_HND *alias_pol, uint16 switch_value,
+ ALIAS_INFO_CTR *ctr);
+BOOL samr_set_aliasinfo( POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr);
+BOOL samr_open_group( const POLICY_HND *domain_pol,
+ uint32 flags, uint32 rid,
+ POLICY_HND *group_pol);
+BOOL samr_del_groupmem( POLICY_HND *group_pol, uint32 rid);
+BOOL samr_add_groupmem( POLICY_HND *group_pol, uint32 rid);
+BOOL samr_delete_dom_user( POLICY_HND *user_pol);
+BOOL samr_delete_dom_group( POLICY_HND *group_pol);
+BOOL samr_create_dom_group( POLICY_HND *domain_pol, const char *acct_name,
+ POLICY_HND *group_pol, uint32 *rid);
+BOOL samr_set_groupinfo( POLICY_HND *group_pol, GROUP_INFO_CTR *ctr);
+BOOL samr_unknown_2d( const POLICY_HND *domain_pol,
+ const DOM_SID *sid);
+BOOL samr_open_domain( const POLICY_HND *connect_pol,
+ uint32 ace_perms,
+ const DOM_SID *sid,
+ POLICY_HND *domain_pol);
+BOOL samr_query_lookup_domain( POLICY_HND *pol, const char *dom_name,
+ DOM_SID *dom_sid);
+BOOL samr_query_lookup_names(const POLICY_HND *pol, uint32 flags,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids, uint32 **types);
+BOOL samr_query_lookup_rids( const POLICY_HND *pol, uint32 flags,
+ uint32 num_rids, const uint32 *rids,
+ uint32 *num_names,
+ char ***names,
+ uint32 **type);
+BOOL samr_query_aliasmem( const POLICY_HND *alias_pol,
+ uint32 *num_mem, DOM_SID2 *sid);
+BOOL samr_query_useraliases( const POLICY_HND *pol,
+ uint32 *ptr_sid, DOM_SID2 *sid,
+ uint32 *num_aliases, uint32 **rid);
+BOOL samr_query_groupmem( POLICY_HND *group_pol,
+ uint32 *num_mem, uint32 **rid, uint32 **attr);
+BOOL samr_query_usergroups( POLICY_HND *pol, uint32 *num_groups,
+ DOM_GID **gid);
+BOOL samr_query_groupinfo( POLICY_HND *pol,
+ uint16 switch_value, GROUP_INFO_CTR* ctr);
+BOOL samr_set_userinfo2( POLICY_HND *pol, uint16 switch_value,
+ void* usr);
+BOOL samr_set_userinfo( POLICY_HND *pol, uint16 switch_value, void* usr);
+BOOL samr_query_userinfo( POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+BOOL samr_close( POLICY_HND *hnd);
+BOOL samr_query_dispinfo( POLICY_HND *pol_domain, uint16 level,
+ uint32 *num_entries,
+ SAM_DISPINFO_CTR *ctr);
+
+/*The following definitions come from rpc_client/cli_use.c */
+
+void init_cli_use(void);
+void free_cli_use(void);
+struct cli_state *cli_net_use_add(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL redir, BOOL reuse, BOOL *is_new);
+BOOL cli_net_use_del(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL force_close, BOOL *connection_closed);
+void cli_net_use_enum(uint32 * num_cons, struct use_info ***use);
+void cli_use_wait_keyboard(void);
+
+/*The following definitions come from rpc_client/msrpc_samr.c */
+
+uint32 lookup_sam_domainname(const char *srv_name,
+ const char *domain, DOM_SID *sid);
+uint32 lookup_sam_names(const char *domain, const DOM_SID *sid,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids, uint32 **types);
+uint32 lookup_sam_name(const char *domain, DOM_SID *sid,
+ char *name, uint32 *rid, uint32 *type);
+uint32 lookup_sam_rid(const char *domain, DOM_SID *sid,
+ uint32 rid, char *name, uint32 *type);
+BOOL req_user_info( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid, uint16 info_level,
+ USER_INFO_FN(usr_inf));
+uint32 sam_query_usergroups( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid,
+ const char *user_name,
+ uint32 *num_groups,
+ DOM_GID **gid,
+ char ***name,
+ uint32 **type,
+ USER_MEM_FN(usr_mem));
+void msrpc_sam_user( const POLICY_HND *pol_dom, const POLICY_HND *pol_blt,
+ const char* domain,
+ const DOM_SID *sid1,
+ const DOM_SID *blt_sid1,
+ uint32 user_rid, uint16 info_level,
+ char *user_name,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn));
+BOOL msrpc_sam_query_user( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid,
+ char *user_name,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn));
+int msrpc_sam_enum_users( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn));
+BOOL sam_query_dominfo(const char* srv_name,
+ const DOM_SID *sid1,
+ uint32 switch_value, SAM_UNK_CTR *ctr);
+BOOL query_aliasinfo( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ ALIAS_INFO_FN(grp_inf));
+BOOL sam_query_aliasmem(const char *srv_name,
+ const POLICY_HND *pol_dom,
+ uint32 alias_rid,
+ uint32 *num_names,
+ DOM_SID ***sids,
+ char ***name,
+ uint32 **type);
+BOOL req_aliasmem_info(const char* srv_name,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ const char *alias_name,
+ ALIAS_MEM_FN(als_mem));
+BOOL sam_query_groupmem( const POLICY_HND *pol_dom,
+ uint32 group_rid,
+ uint32 *num_names,
+ uint32 **rid_mem,
+ char ***name,
+ uint32 **type);
+BOOL query_groupinfo( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ GROUP_INFO_FN(grp_inf));
+BOOL req_groupmem_info( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ const char *group_name,
+ GROUP_MEM_FN(grp_mem));
+uint32 msrpc_sam_get_first_domain( const char* srv_name,
+ char *dom_name,
+ DOM_SID *dom_sid);
+uint32 msrpc_sam_enum_domains( const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ DOMAIN_FN(dom_fn),
+ DOMAIN_INFO_FN(dom_inf_fn));
+uint32 msrpc_sam_enum_groups( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ GROUP_FN(grp_fn),
+ GROUP_INFO_FN(grp_inf_fn),
+ GROUP_MEM_FN(grp_mem_fn));
+uint32 msrpc_sam_enum_aliases( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ ALIAS_FN(als_fn),
+ ALIAS_INFO_FN(als_inf_fn),
+ ALIAS_MEM_FN(als_mem_fn));
+BOOL create_samr_domain_user( POLICY_HND *pol_dom,
+ char *acct_name, uint16 acb_info,
+ const char* password, int plen,
+ uint32 *rid);
+BOOL create_samr_domain_alias( POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid);
+BOOL create_samr_domain_group( POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid);
+BOOL get_samr_query_usergroups( const POLICY_HND *pol_open_domain,
+ uint32 user_rid,
+ uint32 *num_groups, DOM_GID **gid);
+BOOL delete_samr_dom_group( POLICY_HND *pol_open_domain,
+ uint32 group_rid);
+BOOL get_samr_query_groupmem(
+ const POLICY_HND *pol_open_domain,
+ uint32 group_rid, uint32 *num_mem,
+ uint32 **rid, uint32 **attr);
+BOOL delete_samr_dom_alias(
+ POLICY_HND *pol_open_domain,
+ uint32 alias_rid);
+BOOL get_samr_query_aliasmem(
+ const POLICY_HND *pol_open_domain,
+ uint32 alias_rid, uint32 *num_mem, DOM_SID2 *sid);
+BOOL set_samr_set_userinfo2(
+ POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, void *usr);
+BOOL set_samr_set_userinfo( const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, void *usr);
+BOOL get_samr_query_userinfo( const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, SAM_USERINFO_CTR *ctr);
+BOOL get_samr_query_groupinfo(
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 group_rid, GROUP_INFO_CTR *ctr);
+BOOL get_samr_query_aliasinfo(
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 alias_rid, ALIAS_INFO_CTR *ctr);
+BOOL msrpc_sam_create_dom_user(const char* srv_name, DOM_SID *sid1,
+ char *acct_name, uint16 acb_info,
+ const char *password, int plen,
+ uint32 *rid);
+BOOL msrpc_sam_query_dispinfo(const char* srv_name, const char* domain,
+ DOM_SID *sid1,
+ uint16 switch_value,
+ uint32 *num_entries, SAM_DISPINFO_CTR *ctr,
+ DISP_FN(disp_fn));
+BOOL msrpc_sam_ntchange_pwd(const char* srv_name,
+ const char* domain,
+ const char *ntuser,
+ const uchar lm_oldhash[16],
+ const uchar nt_oldhash[16],
+ const char* new_passwd);
+BOOL msrpc_sam_ntpasswd_set(const char* srv_name, const char *user,
+ struct ntuser_creds *samr_creds,
+ const uchar lm_newpass[516],
+ const uchar lm_hshhash[16],
+ const uchar nt_newpass[516],
+ const uchar nt_hshhash[16]);
+BOOL msrpc_sam_query_userinfo(const char* srv_name, const DOM_SID *sid,
+ const char *user_name, uint16 info_level,
+ SAM_USERINFO_CTR *ctr);
+
+/*The following definitions come from rpc_client/ncacn_np_use.c */
+
+BOOL ncacn_np_establish_connection(struct ncacn_np *cli,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ const char *pipe_name, BOOL redir,
+ BOOL reuse);
+void init_ncacn_np_use(void);
+void free_ncacn_np_use(void);
+struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
+ const vuser_key * key);
+struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
+ const vuser_key * key,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ BOOL redir,
+ BOOL reuse, BOOL *is_new_connection);
+BOOL ncacn_np_use_del(const char *pipe_name,
+ const vuser_key * key,
+ BOOL force_close, BOOL *connection_closed);
+void ncacn_np_use_enum(uint32 * num_cons, struct use_info ***use);
+
+/*The following definitions come from rpc_client/ncalrpc_l_use.c */
+
+void init_ncalrpc_use(void);
+void free_ncalrpc_use(void);
+struct msrpc_local *ncalrpc_l_use_add(const char *pipe_name,
+ const vuser_key * key,
+ BOOL redir, BOOL reuse, BOOL *is_new);
+BOOL ncalrpc_l_use_del(const char *pipe_name,
+ const vuser_key * key,
+ BOOL force_close, BOOL *connection_closed);
+void ncalrpc_l_use_enum(uint32 * num_cons, struct use_info ***use);
+void ncalrpc_use_wait_keyboard(void);
+
+/*The following definitions come from rpc_parse/parse_creds.c */
+
+BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name,
+ const char* requested_name,
+ const char* real_name,
+ BOOL guest);
+BOOL creds_io_unix(char *desc, CREDS_UNIX *r_u, prs_struct *ps, int depth);
+void creds_free_unix(CREDS_UNIX *r_u);
+BOOL make_creds_unix_sec(CREDS_UNIX_SEC *r_u,
+ uint32 uid, uint32 gid, uint32 num_grps, gid_t *grps);
+BOOL creds_io_unix_sec(char *desc, CREDS_UNIX_SEC *r_u, prs_struct *ps, int depth);
+void creds_free_unix_sec(CREDS_UNIX_SEC *r_u);
+BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth);
+BOOL creds_io_nt(char *desc, CREDS_NT *r_u, prs_struct *ps, int depth);
+void creds_free_nt(CREDS_NT *r_u);
+BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth);
+void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from);
+void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from);
+void copy_nt_creds(struct ntuser_creds *to,
+ const struct ntuser_creds *from);
+void copy_user_creds(struct user_creds *to,
+ const struct user_creds *from);
+void free_user_creds(struct user_creds *creds);
+BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth);
+BOOL create_ntuser_creds( prs_struct *ps,
+ const char* name,
+ uint16 version, uint16 command,
+ const vuser_key *key,
+ const struct ntuser_creds *ntu,
+ BOOL reuse);
+BOOL create_user_creds( prs_struct *ps,
+ const char* name,
+ uint16 version, uint16 command,
+ const vuser_key *key,
+ const struct user_creds *usr);
+
+/*The following definitions come from rpc_parse/parse_lsa.c */
+
+BOOL make_lsa_trans_name(LSA_TRANS_NAME * trn, UNISTR2 * uni_name,
+ uint32 sid_name_use, char *name, uint32 idx);
+int make_dom_ref_uni(DOM_R_REF * ref, const UNISTR2 * uni_domname,
+ const DOM_SID * dom_sid);
+int make_dom_ref(DOM_R_REF * ref, const char *domname,
+ const DOM_SID * dom_sid);
+BOOL make_lsa_sec_qos(LSA_SEC_QOS * qos, uint16 imp_lev, uint8 ctxt,
+ uint8 eff, uint32 unknown);
+BOOL make_lsa_obj_attr(LSA_OBJ_ATTR * attr, uint32 attributes,
+ LSA_SEC_QOS * qos);
+BOOL make_q_open_pol(LSA_Q_OPEN_POL * r_q, uint16 system_name,
+ uint32 attributes,
+ uint32 desired_access, LSA_SEC_QOS * qos);
+BOOL lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL * r_q, prs_struct * ps,
+ int depth);
+BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL * r_p, prs_struct * ps,
+ int depth);
+BOOL make_q_open_pol2(LSA_Q_OPEN_POL2 * r_q, const char *server_name,
+ uint32 attributes,
+ uint32 desired_access, LSA_SEC_QOS * qos);
+BOOL lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 * r_q, prs_struct * ps,
+ int depth);
+BOOL lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 * r_p, prs_struct * ps,
+ int depth);
+BOOL make_q_query_sec_obj(LSA_Q_QUERY_SEC_OBJ * q_q, const POLICY_HND *hnd,
+ uint32 sec_info);
+BOOL lsa_io_q_query_sec_obj(char *desc, LSA_Q_QUERY_SEC_OBJ * q_q, prs_struct * ps,
+ int depth);
+BOOL lsa_io_r_query_sec_obj(char *desc, LSA_R_QUERY_SEC_OBJ *r_u, prs_struct *ps, int depth);
+BOOL make_q_query(LSA_Q_QUERY_INFO * q_q, POLICY_HND *hnd, uint16 info_class);
+BOOL lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO * q_q, prs_struct * ps,
+ int depth);
+BOOL make_q_create_secret(LSA_Q_CREATE_SECRET * q_o,
+ const POLICY_HND *pol_hnd, const char *secret_name,
+ uint32 desired_access);
+BOOL lsa_io_q_create_secret(char *desc, LSA_Q_CREATE_SECRET * q_o,
+ prs_struct * ps, int depth);
+BOOL lsa_io_r_create_secret(char *desc, LSA_R_CREATE_SECRET * r_o,
+ prs_struct * ps, int depth);
+BOOL make_q_open_secret(LSA_Q_OPEN_SECRET * q_o, const POLICY_HND *pol_hnd,
+ const char *secret_name, uint32 desired_access);
+BOOL lsa_io_q_open_secret(char *desc, LSA_Q_OPEN_SECRET * q_o,
+ prs_struct * ps, int depth);
+BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET * r_o,
+ prs_struct * ps, int depth);
+BOOL lsa_io_secret_value(char *desc, LSA_SECRET_VALUE * value,
+ prs_struct * ps, int depth);
+BOOL lsa_io_secret_info(char *desc, LSA_SECRET_INFO * info, prs_struct * ps,
+ int depth);
+BOOL lsa_io_secret(char *desc, LSA_SECRET * q_q, prs_struct * ps, int depth);
+BOOL make_q_query_secret(LSA_Q_QUERY_SECRET * q_q, POLICY_HND *pol,
+ const STRING2 *secret, const NTTIME * update);
+BOOL lsa_io_q_query_secret(char *desc, LSA_Q_QUERY_SECRET * q_q,
+ prs_struct * ps, int depth);
+BOOL lsa_io_r_query_secret(char *desc, LSA_R_QUERY_SECRET * r_q,
+ prs_struct * ps, int depth);
+BOOL lsa_io_q_set_secret(char *desc, LSA_Q_SET_SECRET * q_q, prs_struct * ps,
+ int depth);
+BOOL lsa_io_r_set_secret(char *desc, LSA_R_SET_SECRET * r_q, prs_struct * ps,
+ int depth);
+BOOL make_q_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM * q_e,
+ POLICY_HND *pol,
+ uint32 enum_context, uint32 preferred_len);
+BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM * q_e,
+ prs_struct * ps, int depth);
+BOOL make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM * r_e, int32 enum_context,
+ uint32 num_domains,
+ UNISTR2 * domain_names, DOM_SID ** domain_sids,
+ uint32 status);
+BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM * r_e,
+ prs_struct * ps, int depth);
+void lsa_free_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM * r_e);
+BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO * r_q, prs_struct * ps,
+ int depth);
+BOOL make_lsa_sid_enum(LSA_SID_ENUM * sen, uint32 num_entries,
+ DOM_SID ** sids);
+BOOL make_q_lookup_sids(LSA_Q_LOOKUP_SIDS * q_l, POLICY_HND *hnd,
+ int num_sids, DOM_SID ** sids, uint16 level);
+BOOL lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS * q_s,
+ prs_struct * ps, int depth);
+BOOL lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS * r_s,
+ prs_struct * ps, int depth);
+BOOL make_q_lookup_names(LSA_Q_LOOKUP_NAMES * q_l, POLICY_HND *hnd,
+ uint32 num_names, char **names);
+BOOL lsa_io_q_lookup_names(char *desc, LSA_Q_LOOKUP_NAMES * q_r,
+ prs_struct * ps, int depth);
+BOOL lsa_io_r_lookup_names(char *desc, LSA_R_LOOKUP_NAMES * r_r,
+ prs_struct * ps, int depth);
+BOOL make_lsa_q_close(LSA_Q_CLOSE * q_c, POLICY_HND *hnd);
+BOOL lsa_io_q_close(char *desc, LSA_Q_CLOSE * q_c, prs_struct * ps, int depth);
+BOOL lsa_io_r_close(char *desc, LSA_R_CLOSE * r_c, prs_struct * ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_misc.c */
+
+BOOL smb_io_bigint(char *desc, BIGINT *bigint, prs_struct *ps, int depth);
+BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth);
+BOOL smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth);
+uint32 get_enum_hnd(ENUM_HND *enh);
+BOOL make_enum_hnd(ENUM_HND *enh, uint32 hnd);
+BOOL smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth);
+BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth);
+BOOL make_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid);
+BOOL smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth);
+BOOL make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer);
+BOOL smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth);
+BOOL make_strhdr2(STRHDR2 *hdr, uint32 max_len, uint32 len, uint32 buffer);
+BOOL smb_io_strhdr2(char *desc, STRHDR2 *hdr, prs_struct *ps, int depth);
+BOOL make_uni_hdr(UNIHDR *hdr, int len);
+BOOL make_unihdr_from_unistr2(UNIHDR *hdr, const UNISTR2 *str);
+BOOL smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth);
+BOOL make_buf_hdr(BUFHDR *hdr, int max_len, int len);
+BOOL smb_io_hdrbuf_pre(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset);
+BOOL smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
+ uint32 ptr_hdrbuf, uint32 max_len, uint32 len);
+BOOL smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth);
+BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer);
+BOOL smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth);
+BOOL make_uni_hdr2(UNIHDR2 *hdr, int len);
+BOOL make_unihdr2_from_unistr2(UNIHDR2 *hdr, const UNISTR2 *str);
+BOOL smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth);
+BOOL make_unistr(UNISTR *str, char *buf);
+BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth);
+BOOL make_buffer3_uint32(BUFFER3 *str, uint32 val);
+BOOL make_buffer3_str(BUFFER3 *str, const char *buf, int len);
+BOOL make_buffer3_hex(BUFFER3 *str, char *buf);
+BOOL make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len);
+BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth);
+BOOL make_buffer4_str(BUFFER4 *str, const char *buf, int len);
+BOOL smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth);
+BOOL init_buffer5(BUFFER5 **str);
+BOOL clear_buffer5(BUFFER5 **str);
+BOOL make_buffer5(BUFFER5 *str, char *buf, int len);
+BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth);
+BOOL make_buffer2_multi(BUFFER2 *str, char *const* const buf, uint32 num);
+BOOL make_buffer2(BUFFER2 *str, const char *buf, int len);
+BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf);
+BOOL make_string2(STRING2 *str, const char *buf, int len);
+BOOL make_buf_string2(STRING2 *str, uint32 *ptr, const char *buf);
+BOOL smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_unistr2(UNISTR2 *str, const char *buf, int len);
+BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth);
+BOOL make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx);
+BOOL smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth);
+BOOL make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type);
+BOOL smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth);
+BOOL make_log_info(DOM_LOG_INFO *log,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name);
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth);
+BOOL smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth);
+BOOL smb_io_cred(char *desc, DOM_CRED *cred, prs_struct *ps, int depth);
+BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
+ const char *logon_srv, const char *comp_name,
+ DOM_CRED *clnt_cred);
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth);
+BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CRED *cred);
+BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth);
+BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16]);
+BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth);
+BOOL smb_io_gid(char *desc, DOM_GID *gid, prs_struct *ps, int depth);
+BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth);
+BOOL smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
+BOOL smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth);
+BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_net.c */
+
+BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l,
+ const char* srv_name,
+ uint32 function_code,
+ uint32 query_level,
+ uint32 switch_value);
+BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth);
+BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l,
+ uint32 switch_value,
+ NETLOGON_INFO *logon_info,
+ uint32 status);
+BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth);
+BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth);
+BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth);
+BOOL make_q_req_chal(NET_Q_REQ_CHAL *q_c,
+ const char *logon_srv, const char *logon_clnt,
+ DOM_CHAL *clnt_chal);
+BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth);
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth);
+BOOL make_q_auth(NET_Q_AUTH *q_a,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CHAL *clnt_chal);
+BOOL net_io_q_auth(char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth(char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth);
+BOOL make_q_auth_2(NET_Q_AUTH_2 *q_a,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CHAL *clnt_chal, uint32 clnt_flgs);
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth);
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth);
+BOOL make_q_srv_pwset(NET_Q_SRV_PWSET *q_s,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CRED *cred, char nt_cypher[16]);
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth);
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth);
+BOOL make_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low,
+ uint32 log_id_high,
+ const char *user_name,
+ const char *wksta_name,
+ const char sess_key[16],
+ const uchar lm_cypher[16],
+ const uchar nt_cypher[16]);
+BOOL make_id_info4(NET_ID_INFO_4 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const char *general);
+BOOL make_id_info2(NET_ID_INFO_2 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const uchar lm_challenge[8],
+ const uchar *lm_chal_resp,
+ int lm_chal_len,
+ const uchar *nt_chal_resp,
+ int nt_chal_len);
+BOOL make_sam_info(DOM_SAM_INFO *sam,
+ const char *logon_srv, const char *comp_name,
+ DOM_CRED *clnt_cred,
+ DOM_CRED *rtn_cred, uint16 logon_level,
+ NET_ID_INFO_CTR *ctr);
+BOOL make_net_user_info3W(NET_USER_INFO_3 *usr,
+
+ const NTTIME *logon_time,
+ const NTTIME *logoff_time,
+ const NTTIME *kickoff_time,
+ const NTTIME *pass_last_set_time,
+ const NTTIME *pass_can_change_time,
+ const NTTIME *pass_must_change_time,
+
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+
+ uint16 logon_count,
+ uint16 bad_pw_count,
+
+ uint32 user_id,
+ uint32 group_id,
+ uint32 num_groups,
+ const DOM_GID *gids,
+ uint32 user_flgs,
+
+ const char sess_key[16],
+
+ const UNISTR2 *logon_srv,
+ const UNISTR2 *logon_dom,
+
+ const char *padding,
+
+ const DOM_SID *dom_sid,
+ const char *other_sids);
+BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
+
+ NTTIME *logon_time,
+ NTTIME *logoff_time,
+ NTTIME *kickoff_time,
+ NTTIME *pass_last_set_time,
+ NTTIME *pass_can_change_time,
+ NTTIME *pass_must_change_time,
+
+ char *user_name,
+ char *full_name,
+ char *logon_script,
+ char *profile_path,
+ char *home_dir,
+ char *dir_drive,
+
+ uint16 logon_count,
+ uint16 bad_pw_count,
+
+ uint32 user_id,
+ uint32 group_id,
+ uint32 num_groups,
+ DOM_GID *gids,
+ uint32 user_flgs,
+
+ char sess_key[16],
+
+ char *logon_srv,
+ char *logon_dom,
+
+ char *padding,
+
+ DOM_SID *dom_sid,
+ char *other_sids);
+BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth);
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth);
+BOOL make_r_sam_logon(NET_R_SAM_LOGON *r_s,
+ const DOM_CRED *srv_creds,
+ uint16 switch_value,
+ NET_USER_INFO_3 *user_info,
+ uint32 status);
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth);
+BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth);
+BOOL make_r_sam_logoff(NET_R_SAM_LOGOFF *r_s,
+ const DOM_CRED *srv_cred,
+ uint32 status);
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth);
+BOOL make_q_sam_sync(NET_Q_SAM_SYNC *q_s,
+ const char *srv_name,
+ const char *cli_name,
+ DOM_CRED *cli_creds, uint32 database_id);
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC *q_s, prs_struct *ps, int depth);
+BOOL make_sam_delta_hdr(SAM_DELTA_HDR *delta, uint16 type, uint32 rid);
+BOOL make_sam_account_info(SAM_ACCOUNT_INFO *info,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ uint32 user_rid, uint32 group_rid,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *desc,
+ uint32 acb_info,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial);
+BOOL make_r_sam_sync(NET_R_SAM_SYNC *r_s,
+ const DOM_CRED *srv_cred,
+ uint32 sync_context,
+ uint32 num_deltas,
+ uint32 num_deltas2,
+ SAM_DELTA_HDR *hdr_deltas,
+ SAM_DELTA_CTR *deltas,
+ uint32 status);
+BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
+ NET_R_SAM_SYNC *r_s, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_ntlmssp.c */
+
+BOOL rpc_hdr_ntlmssp_auth_chk(RPC_HDR_AUTH *rai);
+BOOL make_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
+ uint32 neg_flgs,
+ fstring myname, fstring domain);
+BOOL smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth);
+BOOL make_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
+ uint32 neg_flags,
+ uint8 challenge[8]);
+BOOL smb_io_rpc_auth_ntlmssp_chal(char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth);
+BOOL make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
+ uchar lm_resp[24],
+ uchar *nt_resp, size_t nt_len,
+ char *domain, char *user, char *wks,
+ uint32 neg_flags);
+BOOL smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth);
+BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_num);
+BOOL make_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
+ uint32 ver, uint32 crc32, uint32 seq_num);
+BOOL smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_prs.c */
+
+void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name);
+void prs_debug_out(const prs_struct *ps, char *msg, int level);
+void prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io);
+void prs_set_packtype(prs_struct *ps, const uint8 *pack_type);
+void prs_create(prs_struct *ps, char *data, uint32 size, uint8 align, BOOL io);
+BOOL prs_copy(prs_struct *ps, const prs_struct *from);
+BOOL prs_alloc_data(prs_struct *buf, int size);
+BOOL prs_buf_copy(char *copy_into, const prs_struct *buf,
+ uint32 offset, uint32 len);
+void prs_struct_free(prs_struct **buf);
+void prs_free_data(prs_struct *buf);
+BOOL prs_realloc_data(prs_struct *buf, size_t new_size);
+BOOL prs_grow_data(prs_struct *buf, BOOL io, int new_size, BOOL force_grow);
+uint32 prs_buf_len(const prs_struct *buf);
+char *prs_data(const prs_struct *buf, uint32 offset);
+void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next);
+void prs_align(prs_struct *ps);
+BOOL prs_grow(prs_struct *ps, uint32 new_size);
+BOOL prs_append_data(prs_struct *ps, const char *data, int len);
+BOOL prs_add_data(prs_struct *ps, const char *data, int len);
+BOOL _prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8);
+BOOL _prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16);
+BOOL _prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16]);
+BOOL _prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32);
+BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len);
+BOOL _prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len);
+BOOL _prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len);
+BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str);
+BOOL _prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str);
+BOOL _prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str);
+BOOL _prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth);
+BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str);
+BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size);
+BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
+BOOL _prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
+ uint32 ptr_uint16, uint32 start_offset);
+BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset);
+BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
+ uint32 ptr_uint32, uint32 data_size);
+int prs_tdb_delete(TDB_CONTEXT *tdb, prs_struct *pk);
+int prs_tdb_store(TDB_CONTEXT *tdb, int flgs, prs_struct *pk, prs_struct *pd);
+void prs_tdb_fetch(TDB_CONTEXT *tdb, prs_struct *pk, prs_struct *pd);
+
+/*The following definitions come from rpc_parse/parse_rpc.c */
+
+BOOL make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
+ uint32 call_id, int data_len, int auth_len);
+BOOL smb_io_rpc_hdr(char *desc, RPC_HDR *rpc, prs_struct *ps, int depth);
+BOOL is_complete_pdu(prs_struct *ps);
+BOOL smb_io_rpc_hdr_nack(char *desc, RPC_HDR_NACK *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_fault(char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_rb(RPC_HDR_RB *rpc,
+ uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
+ uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
+ RPC_IFACE *abstract, RPC_IFACE *transfer);
+BOOL smb_io_rpc_hdr_rb(char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_ba(RPC_HDR_BA *rpc,
+ uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
+ const char *pipe_addr,
+ uint8 num_results, uint16 result, uint16 reason,
+ RPC_IFACE *transfer);
+BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 vuid,
+ uint16 opnum);
+BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth);
+BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
+ uint16 max_tsize, uint16 max_rsize,
+ uint8 auth_type, uint8 auth_level,
+ uint8 stub_type_len);
+BOOL smb_io_rpc_hdr_autha(char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth);
+BOOL make_rpc_hdr_auth(RPC_HDR_AUTH *rai,
+ uint8 auth_type, uint8 auth_level,
+ uint8 stub_type_len,
+ uint32 ptr);
+BOOL smb_io_rpc_hdr_auth(char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, int depth);
+BOOL make_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
+ char *signature, uint32 msg_type);
+BOOL smb_io_rpc_auth_verifier(char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth);
+BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
+ char *signature, uint32 msg_type);
+
+/*The following definitions come from rpc_parse/parse_samr.c */
+
+BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd);
+BOOL samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u,
+ POLICY_HND *pol, const char *dom_name);
+BOOL samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN *r_u,
+ DOM_SID *dom_sid, uint32 status);
+BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D *q_u,
+ const POLICY_HND *dom_pol,
+ const DOM_SID *sid);
+BOOL samr_io_q_unknown_2d(char *desc, SAMR_Q_UNKNOWN_2D *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_unknown_2d(char *desc, SAMR_R_UNKNOWN_2D *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
+ const POLICY_HND *connect_pol, uint32 flags,
+ const DOM_SID *sid);
+BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO *q_u, POLICY_HND *user_pol);
+BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *q_u, uint32 status);
+BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ *q_u,
+ const POLICY_HND *user_pol, uint32 sec_info);
+BOOL samr_io_q_query_sec_obj(char *desc, SAMR_Q_QUERY_SEC_OBJ *q_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
+ POLICY_HND *domain_pol, uint16 switch_value);
+BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *ps, int depth);
+BOOL make_unk_info3(SAM_UNK_INFO_3 *u_3);
+BOOL make_unk_info6(SAM_UNK_INFO_6 *u_6);
+BOOL make_unk_info7(SAM_UNK_INFO_7 *u_7);
+BOOL make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server);
+BOOL make_unk_info1(SAM_UNK_INFO_1 *u_1);
+BOOL make_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u,
+ uint16 switch_value, SAM_UNK_CTR *ctr,
+ uint32 status);
+BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO *r_u, prs_struct *ps, int depth);
+BOOL samr_io_r_query_sec_obj(char *desc, SAMR_R_QUERY_SEC_OBJ *r_u, prs_struct *ps, int depth);
+BOOL make_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid);
+BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
+ uint32 start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size);
+BOOL samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
+ uint32 next_idx,
+ uint32 num_sam_entries);
+BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
+ uint16 switch_level, uint32 start_idx,
+ uint32 max_entries);
+BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth);
+BOOL make_sam_dispinfo_1(SAM_DISPINFO_1 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
+BOOL make_sam_dispinfo_2(SAM_DISPINFO_2 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
+BOOL make_sam_dispinfo_3(SAM_DISPINFO_3 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ DOMAIN_GRP *grp);
+BOOL make_sam_dispinfo_4(SAM_DISPINFO_4 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]);
+BOOL make_sam_dispinfo_5(SAM_DISPINFO_5 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ DOMAIN_GRP *grp);
+BOOL make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
+ uint32 num_entries, uint32 data_size,
+ uint16 switch_level, SAM_DISPINFO_CTR *ctr,
+ uint32 status);
+BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_open_group(SAMR_Q_OPEN_GROUP *q_c,
+ const POLICY_HND *hnd,
+ uint32 access_mask, uint32 rid);
+BOOL samr_io_q_open_group(char *desc, SAMR_Q_OPEN_GROUP *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_open_group(char *desc, SAMR_R_OPEN_GROUP *r_u, prs_struct *ps, int depth);
+BOOL make_samr_group_info1(GROUP_INFO1 *gr1,
+ char *acct_name, char *acct_desc,
+ uint32 num_members);
+BOOL samr_io_group_info1(char *desc, GROUP_INFO1 *gr1, prs_struct *ps, int depth);
+BOOL make_samr_group_info4(GROUP_INFO4 *gr4, const char *acct_desc);
+BOOL samr_io_group_info4(char *desc, GROUP_INFO4 *gr4, prs_struct *ps, int depth);
+BOOL samr_group_info_ctr(char *desc, GROUP_INFO_CTR *ctr, prs_struct *ps, int depth);
+BOOL make_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP *q_e,
+ POLICY_HND *pol,
+ const char *acct_desc);
+BOOL samr_io_q_create_dom_group(char *desc, SAMR_Q_CREATE_DOM_GROUP *q_e, prs_struct *ps, int depth);
+BOOL samr_io_r_create_dom_group(char *desc, SAMR_R_CREATE_DOM_GROUP *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP *q_c, POLICY_HND *hnd);
+BOOL samr_io_q_delete_dom_group(char *desc, SAMR_Q_DELETE_DOM_GROUP *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_delete_dom_group(char *desc, SAMR_R_DELETE_DOM_GROUP *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM *q_e,
+ POLICY_HND *pol,
+ uint32 rid);
+BOOL samr_io_q_del_groupmem(char *desc, SAMR_Q_DEL_GROUPMEM *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM *r_u, POLICY_HND *pol,
+ uint32 status);
+BOOL samr_io_r_del_groupmem(char *desc, SAMR_R_DEL_GROUPMEM *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM *q_e,
+ POLICY_HND *pol,
+ uint32 rid);
+BOOL samr_io_q_add_groupmem(char *desc, SAMR_Q_ADD_GROUPMEM *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM *r_u, POLICY_HND *pol,
+ uint32 status);
+BOOL samr_io_r_add_groupmem(char *desc, SAMR_R_ADD_GROUPMEM *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO *q_e,
+ POLICY_HND *pol, GROUP_INFO_CTR *ctr);
+BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO *r_u,
+ uint32 status);
+BOOL samr_io_r_set_groupinfo(char *desc, SAMR_R_SET_GROUPINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_e,
+ POLICY_HND *pol,
+ uint16 switch_level);
+BOOL samr_io_q_query_groupinfo(char *desc, SAMR_Q_QUERY_GROUPINFO *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO *r_u, GROUP_INFO_CTR *ctr,
+ uint32 status);
+BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM *q_c, POLICY_HND *hnd);
+BOOL samr_io_q_query_groupmem(char *desc, SAMR_Q_QUERY_GROUPMEM *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM *r_u,
+ uint32 num_entries, uint32 *rid, uint32 *attr, uint32 status);
+BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM *r_u, prs_struct *ps, int depth);
+void samr_free_r_query_groupmem(SAMR_R_QUERY_GROUPMEM *r_u);
+BOOL make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
+ POLICY_HND *hnd);
+BOOL samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
+ uint32 num_gids, DOM_GID *gid, uint32 status);
+BOOL samr_io_gids(char *desc, uint32 *num_gids, DOM_GID **gid, prs_struct *ps, int depth);
+BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS *q_e, POLICY_HND *pol,
+ uint32 start_idx, uint32 size);
+BOOL samr_io_q_enum_domains(char *desc, SAMR_Q_ENUM_DOMAINS *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS *r_u,
+ uint32 next_idx, uint32 num_sam_entries);
+BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
+ uint32 start_idx, uint32 size);
+BOOL samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
+ uint32 next_idx, uint32 num_sam_entries);
+BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol,
+ uint32 start_idx, uint32 size);
+BOOL samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
+ uint32 next_idx,
+ uint32 num_sam_entries);
+BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth);
+BOOL make_samr_alias_info3(ALIAS_INFO3 *al3, const char *acct_desc);
+BOOL samr_io_alias_info3(char *desc, ALIAS_INFO3 *al3, prs_struct *ps, int depth);
+BOOL samr_alias_info_ctr(char *desc, ALIAS_INFO_CTR *ctr, prs_struct *ps, int depth);
+BOOL make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
+ POLICY_HND *pol,
+ uint16 switch_level);
+BOOL samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps, int depth);
+BOOL make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u, ALIAS_INFO_CTR *ctr,
+ uint32 status);
+BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO *q_u, POLICY_HND *hnd,
+ ALIAS_INFO_CTR *ctr);
+BOOL samr_io_q_set_aliasinfo(char *desc, SAMR_Q_SET_ALIASINFO *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_set_aliasinfo(char *desc, SAMR_R_SET_ALIASINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
+ const POLICY_HND *hnd,
+ uint32 *ptr_sid, DOM_SID2 *sid);
+BOOL samr_io_q_query_useraliases(char *desc, SAMR_Q_QUERY_USERALIASES *q_u, prs_struct *ps, int depth);
+void samr_free_q_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u);
+BOOL make_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES *r_u,
+ uint32 num_rids, uint32 *rid, uint32 status);
+BOOL samr_io_rids(char *desc, uint32 *num_rids, uint32 **rid, prs_struct *ps, int depth);
+BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u, const POLICY_HND *pol,
+ uint32 unknown_0, uint32 rid);
+BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
+ const POLICY_HND *pol, uint32 flags,
+ uint32 num_rids, const uint32 *rid);
+BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS *q_u, prs_struct *ps, int depth);
+void samr_free_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u);
+BOOL make_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u,
+ uint32 num_names, UNIHDR *hdr_name, UNISTR2 *uni_name,
+ uint32 *type);
+BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS *r_u, prs_struct *ps, int depth);
+void samr_free_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u);
+BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS *q_u, POLICY_HND *hnd);
+BOOL samr_io_q_delete_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_delete_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u, POLICY_HND *hnd,
+ const char *acct_desc);
+BOOL samr_io_q_create_dom_alias(char *desc, SAMR_Q_CREATE_DOM_ALIAS *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_create_dom_alias(char *desc, SAMR_R_CREATE_DOM_ALIAS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u, POLICY_HND *hnd,
+ DOM_SID *sid);
+BOOL samr_io_q_add_aliasmem(char *desc, SAMR_Q_ADD_ALIASMEM *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM *q_u, POLICY_HND *hnd,
+ DOM_SID *sid);
+BOOL samr_io_q_del_aliasmem(char *desc, SAMR_Q_DEL_ALIASMEM *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_del_aliasmem(char *desc, SAMR_R_DEL_ALIASMEM *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS *q_c, POLICY_HND *hnd);
+BOOL samr_io_q_delete_dom_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS *r_u,
+ uint32 status);
+BOOL samr_io_r_delete_dom_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_c,
+ const POLICY_HND *hnd);
+BOOL samr_io_q_query_aliasmem(char *desc, SAMR_Q_QUERY_ALIASMEM *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM *r_u,
+ uint32 num_sids, DOM_SID2 *sid, uint32 status);
+BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
+ const POLICY_HND *pol, uint32 flags,
+ uint32 num_names, char **name);
+BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth);
+void samr_free_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_l);
+BOOL make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
+ uint32 num_rids,
+ const uint32 *rid, const uint32 *type,
+ uint32 status);
+BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth);
+void samr_free_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_l);
+BOOL make_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER *q_c, POLICY_HND *hnd);
+BOOL samr_io_q_delete_dom_user(char *desc, SAMR_Q_DELETE_DOM_USER *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_delete_dom_user(char *desc, SAMR_R_DELETE_DOM_USER *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
+ const POLICY_HND *pol,
+ uint32 access_mask, uint32 rid);
+BOOL samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_create_user(SAMR_Q_CREATE_USER *q_u,
+ POLICY_HND *pol,
+ const char *name,
+ uint16 acb_info, uint32 access_mask);
+BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
+ POLICY_HND *hnd, uint16 switch_value);
+BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth);
+BOOL make_sam_user_info12(SAM_USER_INFO_12 *usr,
+ uint16 acb_info,
+ const uint8 lm_pwd[16],
+ const uint8 nt_pwd[16]);
+BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 *u, prs_struct *ps, int depth);
+BOOL make_sam_user_info10(SAM_USER_INFO_10 *usr,
+ uint32 acb_info);
+BOOL sam_io_user_info10(char *desc, SAM_USER_INFO_10 *usr, prs_struct *ps, int depth);
+BOOL make_sam_user_info11(SAM_USER_INFO_11 *usr,
+ NTTIME *expiry,
+ char *mach_acct,
+ uint32 rid_user,
+ uint32 rid_group,
+ uint16 acct_ctrl);
+BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int depth);
+BOOL make_sam_user_info24(SAM_USER_INFO_24 *usr,
+ const char newpass[516], uint16 passlen);
+BOOL make_sam_user_info23W(SAM_USER_INFO_23 *usr,
+
+ const NTTIME *logon_time, /* all zeros */
+ const NTTIME *logoff_time, /* all zeros */
+ const NTTIME *kickoff_time, /* all zeros */
+ const NTTIME *pass_last_set_time, /* all zeros */
+ const NTTIME *pass_can_change_time, /* all zeros */
+ const NTTIME *pass_must_change_time, /* all zeros */
+
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *desc,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial,
+
+ uint32 user_rid, /* 0x0000 0000 */
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS *hrs,
+ uint32 unknown_5,
+ char newpass[516]
+#if 0
+ , uint32 unknown_6
+#endif
+ );
+BOOL make_sam_user_info23A(SAM_USER_INFO_23 *usr,
+
+ NTTIME *logon_time, /* all zeros */
+ NTTIME *logoff_time, /* all zeros */
+ NTTIME *kickoff_time, /* all zeros */
+ NTTIME *pass_last_set_time, /* all zeros */
+ NTTIME *pass_can_change_time, /* all zeros */
+ NTTIME *pass_must_change_time, /* all zeros */
+
+ char *user_name, /* NULL */
+ char *full_name,
+ char *home_dir,
+ char *dir_drive,
+ char *log_scr,
+ char *prof_path,
+ char *desc,
+ char *wkstas,
+ char *unk_str,
+ char *mung_dial,
+
+ uint32 user_rid, /* 0x0000 0000 */
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS *hrs,
+ uint32 unknown_5,
+ char newpass[516]
+#if 0
+ , uint32 unknown_6
+#endif
+ );
+BOOL make_sam_user_info21W(SAM_USER_INFO_21 *usr,
+
+ const NTTIME *logon_time,
+ const NTTIME *logoff_time,
+ const NTTIME *kickoff_time,
+ const NTTIME *pass_last_set_time,
+ const NTTIME *pass_can_change_time,
+ const NTTIME *pass_must_change_time,
+
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *desc,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial,
+
+ const uchar lm_pwd[16],
+ const uchar nt_pwd[16],
+
+ uint32 user_rid,
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ const LOGON_HRS *hrs,
+ uint32 unknown_5,
+ uint32 unknown_6);
+BOOL make_sam_user_info21A(SAM_USER_INFO_21 *usr,
+
+ NTTIME *logon_time,
+ NTTIME *logoff_time,
+ NTTIME *kickoff_time,
+ NTTIME *pass_last_set_time,
+ NTTIME *pass_can_change_time,
+ NTTIME *pass_must_change_time,
+
+ char *user_name,
+ char *full_name,
+ char *home_dir,
+ char *dir_drive,
+ char *log_scr,
+ char *prof_path,
+ char *desc,
+ char *wkstas,
+ char *unk_str,
+ char *mung_dial,
+
+ uint32 user_rid,
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS *hrs,
+ uint32 unknown_5,
+ uint32 unknown_6);
+BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *ps, int depth);
+uint32 make_samr_userinfo_ctr_usr21(SAM_USERINFO_CTR *ctr,
+ uint16 switch_value,
+ const SAM_USER_INFO_21 *usr);
+BOOL make_samr_userinfo_ctr(SAM_USERINFO_CTR *ctr, const uchar *sess_key,
+ uint16 switch_value, void *info);
+BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR *ctr, prs_struct *ps, int depth);
+void free_samr_userinfo_ctr(SAM_USERINFO_CTR *ctr);
+BOOL make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
+ SAM_USERINFO_CTR *ctr, uint32 status);
+BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
+ POLICY_HND *hnd,
+ uint16 switch_value, void *info);
+BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps, int depth);
+void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u);
+BOOL make_samr_r_set_userinfo(SAMR_R_SET_USERINFO *r_u, uint32 status);
+BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
+ POLICY_HND *hnd,
+ uint16 switch_value,
+ SAM_USERINFO_CTR *ctr);
+BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, prs_struct *ps, int depth);
+void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u);
+BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 *r_u,
+ uint32 status);
+BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_connect(SAMR_Q_CONNECT *q_u,
+ const char *srv_name, uint32 access_mask);
+BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u);
+BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth);
+BOOL make_samr_q_get_dom_pwinfo(SAMR_Q_GET_DOM_PWINFO *q_u, const char *srv_name);
+BOOL samr_io_q_get_dom_pwinfo(char *desc, SAMR_Q_GET_DOM_PWINFO *q_u, prs_struct *ps, int depth);
+BOOL samr_io_r_get_dom_pwinfo(char *desc, SAMR_R_GET_DOM_PWINFO *r_u, prs_struct *ps, int depth);
+BOOL make_enc_passwd(SAMR_ENC_PASSWD *pwd, const char pass[512]);
+BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth);
+BOOL make_enc_hash(SAMR_ENC_HASH *hsh, const uchar hash[16]);
+BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth);
+BOOL make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+ const char *dest_host, const char *user_name,
+ const char nt_newpass[516],
+ const uchar nt_oldhash[16],
+ const char lm_newpass[516],
+ const uchar lm_oldhash[16]);
+BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth);
+BOOL make_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status);
+BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_sec.c */
+
+BOOL make_sec_access(SEC_ACCESS *t, uint32 mask);
+BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth);
+BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag);
+BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth);
+BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace);
+void free_sec_acl(SEC_ACL *t);
+BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth);
+int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
+ DOM_SID *owner_sid, DOM_SID *grp_sid,
+ SEC_ACL *sacl, SEC_ACL *dacl);
+void free_sec_desc(SEC_DESC *t);
+BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth);
+BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data);
+void free_sec_desc_buf(SEC_DESC_BUF *buf);
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth);
+
+/*The following definitions come from rpc_parse/parse_vuid.c */
+
+BOOL vuid_io_key(char *desc, vuser_key * r_u, prs_struct * ps, int depth);
+BOOL make_vuid_user_struct(user_struct * r_u,
+ uid_t uid, gid_t gid,
+ const char *name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest,
+ uint32 n_groups, const gid_t * groups,
+ const NET_USER_INFO_3 * usr);
+BOOL vuid_io_user_struct(char *desc, user_struct * r_u, prs_struct * ps,
+ int depth);
+void vuid_free_user_struct(user_struct * r_u);
+
+/*The following definitions come from tdb/tdb.c */
+
+char *tdb_error(TDB_CONTEXT *tdb);
+int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf);
+TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void* state), void* state);
+TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb);
+TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag);
+TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
+ int open_flags, mode_t mode);
+int tdb_close(TDB_CONTEXT *tdb);
+int tdb_writelock(TDB_CONTEXT *tdb);
+int tdb_writeunlock(TDB_CONTEXT *tdb);
+int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key);
+int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key);
+#endif /* _WINBINDD_PROTO_H_ */
diff --git a/source/lib/.cvsignore b/source/lib/.cvsignore
index 07da2225c72..1ab6832045e 100644
--- a/source/lib/.cvsignore
+++ b/source/lib/.cvsignore
@@ -1,3 +1,3 @@
-*.po
+*.[pl]o
*.po32
diff --git a/source/lib/access.c b/source/lib/access.c
index 01f559750fa..0fa383d84a5 100644
--- a/source/lib/access.c
+++ b/source/lib/access.c
@@ -38,14 +38,12 @@ static int masked_match(char *tok, char *slash, char *s)
}
/* string_match - match string against token */
-static int string_match(char *tok,char *s, char *invalid_char)
+static int string_match(char *tok,char *s)
{
- size_t tok_len;
- size_t str_len;
+ int tok_len;
+ int str_len;
char *cut;
- *invalid_char = '\0';
-
/* Return True if a token has the magic value "ALL". Return
* FAIL if the token is "FAIL". If the token starts with a "."
* (domain name), return True if it matches the last fields of
@@ -110,10 +108,6 @@ static int string_match(char *tok,char *s, char *invalid_char)
} else if ((cut = strchr(tok, '/')) != 0) { /* netnumber/netmask */
if (isdigit((int)s[0]) && masked_match(tok, cut, s))
return (True);
- } else if (strchr(tok, '*') != 0) {
- *invalid_char = '*';
- } else if (strchr(tok, '?') != 0) {
- *invalid_char = '?';
}
return (False);
}
@@ -124,26 +118,15 @@ static int client_match(char *tok,char *item)
{
char **client = (char **)item;
int match;
- char invalid_char = '\0';
/*
* Try to match the address first. If that fails, try to match the host
* name if available.
*/
- if ((match = string_match(tok, client[1], &invalid_char)) == 0) {
- if(invalid_char)
- DEBUG(0,("client_match: address match failing due to invalid character '%c' found in \
-token '%s' in an allow/deny hosts line.\n", invalid_char, tok ));
-
- if (client[0][0] != 0)
- match = string_match(tok, client[0], &invalid_char);
-
- if(invalid_char)
- DEBUG(0,("client_match: address match failing due to invalid character '%c' found in \
-token '%s' in an allow/deny hosts line.\n", invalid_char, tok ));
- }
-
+ if ((match = string_match(tok, client[1])) == 0)
+ if (client[0][0] != 0)
+ match = string_match(tok, client[0]);
return (match);
}
@@ -201,15 +184,6 @@ BOOL allow_access(char *deny_list,char *allow_list,
client[0] = cname;
client[1] = caddr;
- /* if it is loopback then always allow unless specifically denied */
- if (strcmp(caddr, "127.0.0.1") == 0) {
- if (deny_list &&
- list_match(deny_list,(char *)client,client_match)) {
- return False;
- }
- return True;
- }
-
/* if theres no deny list and no allow list then allow access */
if ((!deny_list || *deny_list == 0) &&
(!allow_list || *allow_list == 0)) {
diff --git a/source/lib/bitmap.c b/source/lib/bitmap.c
index 1813d63ff77..93c821c5285 100644
--- a/source/lib/bitmap.c
+++ b/source/lib/bitmap.c
@@ -35,10 +35,10 @@ struct bitmap *bitmap_allocate(int n)
struct bitmap *bm;
bm = (struct bitmap *)malloc(sizeof(*bm));
+ bm->n = n;
if (!bm) return NULL;
- bm->n = n;
bm->b = (uint32 *)malloc(sizeof(bm->b[0])*(n+31)/32);
if (!bm->b) {
free(bm);
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index 2916f0cedab..29ef72d7ac3 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -23,7 +23,7 @@
#define CTRLZ 26
extern int DEBUGLEVEL;
-static char cvtbuf[sizeof(pstring)];
+static char cvtbuf[1024];
static BOOL mapsinited = 0;
@@ -39,7 +39,7 @@ static void initmaps(void) {
mapsinited = True;
}
-static void update_map(char *str) {
+static void update_map(char * str) {
char *p;
for (p = str; *p; p++) {
@@ -51,55 +51,47 @@ static void update_map(char *str) {
}
}
-static void setupmaps(void)
-{
+static void init_iso8859_1(void) {
+
int i;
if (!mapsinited) initmaps();
/* Do not map undefined characters to some accidental code */
- for (i = 128; i < 256; i++)
+ for (i = 128; i < 256; i++)
{
unix2dos[i] = CTRLZ;
dos2unix[i] = CTRLZ;
}
-}
-static void init_iso8859_1(int codepage) {
+/* MSDOS Code Page 850 -> ISO-8859 */
+update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365");
+update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
+update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372");
+update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
+update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
+update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
+update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
+update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
+update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
+update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
+update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
+update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
- setupmaps();
-
- if (codepage == 437) {
- /* MSDOS Code Page 437 -> ISO-8859-1 */
- update_map("\xA1\xAD\xA2\x98\xA3\x9C\xA4\xED\xA5\x9D\xA6\xB3\xA7\xEE");
- update_map("\xAA\xA6\xAB\xAE\xAC\xAA\xAE\xE9\xAF\xC4");
- update_map("\xB0\xF8\xB1\xF1\xB2\xFD\xB5\xE6\xB7\xFA\xBA\xA7\xBC\xAC\xBD\xAB\xBF\xA8");
- update_map("\xC0\x85\xC1\xA0\xC2\x83\xC4\x8E\xC5\x8F\xC6\x92\xC7\x80\xC8\x8A");
- update_map("\xC9\x90\xCA\x88\xCB\x89\xCC\x8D\xCD\xA1\xCE\x8C\xCF\x8B");
- update_map("\xD1\xA5\xD2\x96\xD3\xA2\xD4\x93\xD6\x99\xD9\x97\xDA\xA3\xDB\x96\xDC\x9A\xDF\xE1");
- update_map("\xE0\x85\xE1\xA0\xE2\x83\xE4\x84\xE5\x86\xE6\x91\xE7\x87\xE8\x8A\xE9\x82\xEA\x88\xEB\x89\xEC\x8D\xED\xA1\xEE\x8C\xEF\x8B");
- update_map("\xF0\xEB\xF1\xA4\xF2\x95\xF3\xA2\xF4\x93\xF6\x94\xF7\xF6\xF8\xED\xF9\x97\xFA\xA3\xFB\x96\xFC\x81\xFF\x98");
- } else {
- /* MSDOS Code Page 850 -> ISO-8859-1 */
- update_map("\240\377\241\255\242\275\243\234\244\317\245\276\246\335\247\365");
- update_map("\250\371\251\270\252\246\253\256\254\252\255\360\256\251\257\356");
- update_map("\260\370\261\361\262\375\263\374\264\357\265\346\266\364\267\372");
- update_map("\270\367\271\373\272\247\273\257\274\254\275\253\276\363\277\250");
- update_map("\300\267\301\265\302\266\303\307\304\216\305\217\306\222\307\200");
- update_map("\310\324\311\220\312\322\313\323\314\336\315\326\316\327\317\330");
- update_map("\320\321\321\245\322\343\323\340\324\342\325\345\326\231\327\236");
- update_map("\330\235\331\353\332\351\333\352\334\232\335\355\336\350\337\341");
- update_map("\340\205\341\240\342\203\343\306\344\204\345\206\346\221\347\207");
- update_map("\350\212\351\202\352\210\353\211\354\215\355\241\356\214\357\213");
- update_map("\360\320\361\244\362\225\363\242\364\223\365\344\366\224\367\366");
- update_map("\370\233\371\227\372\243\373\226\374\201\375\354\376\347\377\230");
- }
}
/* Init for eastern european languages. */
static void init_iso8859_2(void) {
- setupmaps();
+ int i;
+ if (!mapsinited) initmaps();
+
+ /* Do not map undefined characters to some accidental code */
+ for (i = 128; i < 256; i++)
+ {
+ unix2dos[i] = CTRLZ;
+ dos2unix[i] = CTRLZ;
+ }
/*
* Tranlation table created by Petr Hubeny <psh@capitol.cz>
@@ -108,7 +100,6 @@ static void init_iso8859_2(void) {
*/
/* MSDOS Code Page 852 -> ISO-8859-2 */
-update_map("\240\377"); /* Fix for non-breaking space */
update_map("\241\244\242\364\243\235\244\317\245\225\246\227\247\365");
update_map("\250\371\251\346\252\270\253\233\254\215\256\246\257\275");
update_map("\261\245\262\362\263\210\264\357\265\226\266\230\267\363");
@@ -129,48 +120,36 @@ update_map("\370\375\371\205\372\243\373\373\374\201\375\354\376\356\377\372");
static void init_iso8859_5(void)
{
- setupmaps();
+ int i;
+ if (!mapsinited) initmaps();
+
+ /* Do not map undefined characters to some accidental code */
+ for (i = 128; i < 256; i++)
+ {
+ unix2dos[i] = CTRLZ;
+ dos2unix[i] = CTRLZ;
+ }
/* MSDOS Code Page 866 -> ISO8859-5 */
-update_map("\260\200\261\201\262\202\263\203\264\204\265\205\266\206\267\207");
-update_map("\270\210\271\211\272\212\273\213\274\214\275\215\276\216\277\217");
-update_map("\300\220\301\221\302\222\303\223\304\224\305\225\306\226\307\227");
-update_map("\310\230\311\231\312\232\313\233\314\234\315\235\316\236\317\237");
-update_map("\320\240\321\241\322\242\323\243\324\244\325\245\326\246\327\247");
-update_map("\330\250\331\251\332\252\333\253\334\254\335\255\336\256\337\257");
+update_map("\200\260\201\261\202\262\203\263\204\264\205\265\206\266\207\267");
+update_map("\210\270\211\271\212\272\213\273\214\274\215\275\216\276\217\277");
+update_map("\220\300\221\301\222\302\223\303\224\304\225\305\226\306\227\307");
+update_map("\230\310\231\311\232\312\233\313\234\314\235\315\236\316\237\317");
+update_map("\240\320\241\321\242\322\243\323\244\324\245\325\246\326\247\327");
+update_map("\250\330\251\331\252\332\253\333\254\334\255\335\256\336\257\337");
update_map("\340\340\341\341\342\342\343\343\344\344\345\345\346\346\347\347");
update_map("\350\350\351\351\352\352\353\353\354\354\355\355\356\356\357\357");
-update_map("\241\360\361\361\244\362\364\363\247\364\367\365\256\366\376\367");
-update_map("\360\374\240\377");
-}
-
-/* Added by Antonios Kavarnos (Antonios.Kavarnos@softlab.ece.ntua.gr */
-
-static void init_iso8859_7(void)
-{
- setupmaps();
-
-/* MSDOS Code Page 737 -> ISO-8859-7 (Greek-Hellenic) */
-
-update_map("\301\200\302\201\303\202\304\203\305\204\306\205\307\206");
-update_map("\310\207\311\210\312\211\313\212\314\213\315\214\316\215\317\216");
-update_map("\320\217\321\220\323\221\324\222\325\223\326\224\327\225");
-update_map("\330\226\331\227");
-update_map("\341\230\342\231\343\232\344\233\345\234\346\235\347\236");
-update_map("\350\237\351\240\352\241\353\242\354\243\355\244\356\245\357\246");
-update_map("\360\247\361\250\362\252\363\251\364\253\365\254\366\255\367\256");
-update_map("\370\257\371\340");
-update_map("\332\364\333\365\334\341\335\342\336\343\337\345");
-update_map("\372\344\373\350\374\346\375\347\376\351");
-update_map("\266\352");
-update_map("\270\353\271\354\272\355\274\356\276\357\277\360");
+update_map("\360\241\361\361\362\244\363\364\364\247\365\367\366\256\367\376");
+update_map("\374\360\377\240");
}
/* Init for russian language (koi8) */
static void init_koi8_r(void)
{
- setupmaps();
+ if (!mapsinited) initmaps();
+
+ /* There aren't undefined characters between 128 and 255 */
/* MSDOS Code Page 866 -> KOI8-R */
update_map("\200\304\201\263\202\332\203\277\204\300\205\331\206\303\207\264");
@@ -191,49 +170,24 @@ update_map("\360\217\361\237\362\220\363\221\364\222\365\223\366\206\367\202");
update_map("\370\234\371\233\372\207\373\230\374\235\375\231\376\227\377\232");
}
-
-/* Init for ROMAN-8 (HP-UX) */
-
-static void init_roman8(void) {
-
- setupmaps();
-
-/* MSDOS Code Page 850 -> ROMAN8 */
-update_map("\240\377\241\267\242\266\243\324\244\322\245\323\246\327\247\330");
-update_map("\250\357\253\371\255\353\256\352\257\234");
-update_map("\260\356\261\355\262\354\263\370\264\200\265\207\266\245\267\244");
-update_map("\270\255\271\250\272\317\273\234\274\276\275\365\276\237\277\275");
-update_map("\300\203\301\210\302\223\303\226\304\240\305\202\306\242\307\243");
-update_map("\310\205\311\212\312\225\313\227\314\204\315\211\316\224\317\201");
-update_map("\320\217\321\214\322\235\323\222\324\206\325\241\326\233\327\221");
-update_map("\330\216\331\215\332\231\333\232\334\220\335\213\336\341\337\342");
-update_map("\340\265\341\307\342\306\343\321\344\320\345\326\346\336\347\340");
-update_map("\350\343\351\345\352\344\355\351\357\230");
-update_map("\360\350\361\347\362\372\363\346\364\364\365\363\366\360\367\254");
-update_map("\370\253\371\246\372\247\373\256\374\376\375\257\376\361");
-}
-
/*
* Convert unix to dos
*/
char *unix2dos_format(char *str,BOOL overwrite)
{
- char *p;
- char *dp;
-
- if (!mapsinited)
- initmaps();
-
- if (overwrite) {
- for (p = str; *p; p++)
- *p = unix2dos[(unsigned char)*p];
- return str;
- } else {
- for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
- *dp = unix2dos[(unsigned char)*p];
- *dp = 0;
- return cvtbuf;
- }
+ char *p;
+ char *dp;
+
+ if (!mapsinited) initmaps();
+
+ if (overwrite) {
+ for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p];
+ return str;
+ } else {
+ for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = unix2dos[(unsigned char)*p];
+ *dp = 0;
+ return cvtbuf;
+ }
}
/*
@@ -241,45 +195,36 @@ char *unix2dos_format(char *str,BOOL overwrite)
*/
char *dos2unix_format(char *str, BOOL overwrite)
{
- char *p;
- char *dp;
-
- if (!mapsinited)
- initmaps();
-
- if (overwrite) {
- for (p = str; *p; p++)
- *p = dos2unix[(unsigned char)*p];
- return str;
- } else {
- for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
- *dp = dos2unix[(unsigned char)*p];
- *dp = 0;
- return cvtbuf;
- }
+ char *p;
+ char *dp;
+
+ if (!mapsinited) initmaps();
+
+ if (overwrite) {
+ for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p];
+ return str;
+ } else {
+ for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = dos2unix[(unsigned char)*p];
+ *dp = 0;
+ return cvtbuf;
+ }
}
/*
* Interpret character set.
*/
-void interpret_character_set(char *str, int codepage)
+void interpret_character_set(char *str)
{
if (strequal (str, "iso8859-1")) {
- init_iso8859_1(codepage);
+ init_iso8859_1();
} else if (strequal (str, "iso8859-2")) {
init_iso8859_2();
} else if (strequal (str, "iso8859-5")) {
init_iso8859_5();
- } else if (strequal (str, "iso8859-7")) {
- init_iso8859_7();
} else if (strequal (str, "koi8-r")) {
init_koi8_r();
- } else if (strequal (str, "roman8")) {
- init_roman8();
} else {
DEBUG(0,("unrecognized character set %s\n", str));
}
-
- load_unix_unicode_map(str);
}
diff --git a/source/lib/charset.c b/source/lib/charset.c
index 6e5a4b48cba..8a245713584 100644
--- a/source/lib/charset.c
+++ b/source/lib/charset.c
@@ -371,8 +371,6 @@ for code page %d failed. Using default client codepage 850\n",
add_dos_char(cp[i][0], (BOOL)cp[i][2], cp[i][1], (BOOL)cp[i][3]);
}
- /* Try and load the unicode map. */
- load_dos_unicode_map(client_codepage);
}
/*******************************************************************
diff --git a/source/lib/cmd_interp.c b/source/lib/cmd_interp.c
new file mode 100644
index 00000000000..7084c29d451
--- /dev/null
+++ b/source/lib/cmd_interp.c
@@ -0,0 +1,1502 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+#ifndef REGISTER
+#define REGISTER 0
+#endif
+
+extern pstring debugf;
+extern pstring scope;
+extern pstring global_myname;
+
+extern pstring user_socket_options;
+
+
+extern int DEBUGLEVEL;
+
+
+#define CNV_LANG(s) dos2unix_format(s,False)
+#define CNV_INPUT(s) unix2dos_format(s,True)
+
+static int process_tok(fstring tok);
+static void cmd_help(struct client_info *info, int argc, char *argv[]);
+static void cmd_quit(struct client_info *info, int argc, char *argv[]);
+static void cmd_set(struct client_info *info, int argc, char *argv[]);
+static void cmd_use(struct client_info *info, int argc, char *argv[]);
+
+static struct user_creds usr;
+
+struct client_info cli_info;
+
+char **cmd_argv = NULL;
+uint32 cmd_argc = 0;
+
+FILE *out_hnd;
+
+
+static void cmd_set_free(struct command_set *item)
+{
+ if (item != NULL)
+ {
+ safe_free(item->name);
+ }
+ safe_free(item);
+}
+
+static struct command_set *cmd_set_dup(const struct command_set *from)
+{
+ if (from != NULL)
+ {
+ struct command_set *copy =
+ (struct command_set
+ *)malloc(sizeof(struct command_set));
+ if (copy != NULL)
+ {
+ memcpy(copy, from, sizeof(struct command_set));
+ if (from->name != NULL)
+ {
+ copy->name = strdup(from->name);
+ }
+ }
+ return copy;
+ }
+ return NULL;
+}
+
+void free_cmd_set_array(uint32 num_entries, struct command_set **entries)
+{
+ void (*fn) (void *) = (void (*)(void *))&cmd_set_free;
+ free_void_array(num_entries, (void **)entries, *fn);
+}
+
+struct command_set *add_cmd_set_to_array(uint32 * len,
+ struct command_set ***array,
+ const struct command_set *cmd)
+{
+ void *(*fn) (const void *) = (void *(*)(const void *))&cmd_set_dup;
+ return (struct command_set *)add_copy_to_array(len,
+ (void ***)array,
+ (const void *)cmd, *fn,
+ False);
+
+}
+
+static struct command_set **commands = NULL;
+static uint32 num_commands = 0;
+
+/****************************************************************************
+ add in individual command-sets.
+ ****************************************************************************/
+void add_command_set(const struct command_set *cmds)
+{
+ while (cmds->fn != NULL)
+ {
+ add_cmd_set_to_array(&num_commands, &commands, cmds);
+ cmds++;
+ }
+}
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+static struct command_set general_commands[] = {
+ /*
+ * maintenance
+ */
+
+ {
+ "set",
+ cmd_set,
+ "run rpcclient inside rpcclient (change options etc.)",
+ {NULL, NULL}
+ },
+
+ {
+ "use",
+ cmd_use,
+ "net use and net view",
+ {NULL, NULL}
+ },
+ /*
+ * bye bye
+ */
+
+ {
+ "quit",
+ cmd_quit,
+ "logoff the server",
+ {NULL, NULL}
+ },
+ {
+ "q",
+ cmd_quit,
+ "logoff the server",
+ {NULL, NULL}
+ },
+ {
+ "exit",
+ cmd_quit,
+ "logoff the server",
+ {NULL, NULL}
+ },
+ {
+ "bye",
+ cmd_quit,
+ "logoff the server",
+ {NULL, NULL}
+ },
+
+ /*
+ * eek!
+ */
+
+ {
+ "help",
+ cmd_help,
+ "[command] give help on a command",
+ {NULL, NULL}
+ },
+ {
+ "?",
+ cmd_help,
+ "[command] give help on a command",
+ {NULL, NULL}
+ },
+
+ /*
+ * shell
+ */
+
+ {
+ "!",
+ NULL,
+ "run a shell command on the local system",
+ {NULL, NULL}
+ },
+
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
+ }
+};
+
+
+/****************************************************************************
+do a (presumably graceful) quit...
+****************************************************************************/
+static void cmd_quit(struct client_info *info, int argc, char *argv[])
+{
+#ifdef MEM_MAN
+ {
+ extern FILE *dbf;
+ smb_mem_write_status(dbf);
+ smb_mem_write_errors(dbf);
+ smb_mem_write_verbose(dbf);
+ dbgflush();
+ }
+#endif
+ free_connections();
+ exit(0);
+}
+
+/****************************************************************************
+help
+****************************************************************************/
+static void cmd_help(struct client_info *info, int argc, char *argv[])
+{
+ int i = 0, j = 0;
+
+ if (argc > 1)
+ {
+ if ((i = process_tok(argv[1])) >= 0)
+ {
+ fprintf(out_hnd, "HELP %s:\n\t%s\n\n",
+ commands[i]->name, commands[i]->description);
+ }
+ }
+ else
+ {
+ for (i = 0; i < num_commands; i++)
+ {
+ fprintf(out_hnd, "%-15s", commands[i]->name);
+ j++;
+ if (j == 5)
+ {
+ fprintf(out_hnd, "\n");
+ j = 0;
+ }
+ }
+ if (j != 0)
+ {
+ fprintf(out_hnd, "\n");
+ }
+ }
+}
+
+/*******************************************************************
+ lookup a command string in the list of commands, including
+ abbreviations
+ ******************************************************************/
+static int process_tok(char *tok)
+{
+ int i = 0, matches = 0;
+ int cmd = 0;
+ int tok_len = strlen(tok);
+
+ for (i = 0; i < num_commands; i++)
+ {
+ if (strequal(commands[i]->name, tok))
+ {
+ matches = 1;
+ cmd = i;
+ break;
+ }
+ else if (strnequal(commands[i]->name, tok, tok_len))
+ {
+ matches++;
+ cmd = i;
+ }
+ }
+
+ if (matches == 0)
+ return (-1);
+ else if (matches == 1)
+ return (cmd);
+ else
+ return (-2);
+}
+
+/****************************************************************************
+ turn command line into command argument array
+****************************************************************************/
+static BOOL get_cmd_args(char *line)
+{
+ char *ptr = line;
+ pstring tok;
+ cmd_argc = 0;
+ cmd_argv = NULL;
+
+ /* get the first part of the command */
+ if (!next_token(&ptr, tok, NULL, sizeof(tok)))
+ {
+ return False;
+ }
+
+ do
+ {
+ add_chars_to_array(&cmd_argc, &cmd_argv, tok);
+
+ }
+ while (next_token(NULL, tok, NULL, sizeof(tok)));
+
+ return True;
+}
+
+/* command options mask */
+static uint32 cmd_set_options = 0xffffffff;
+
+/****************************************************************************
+ process commands from the client
+****************************************************************************/
+static BOOL do_command(struct client_info *info, char *line)
+{
+ int i;
+
+ if (!get_cmd_args(line))
+ return False;
+
+ if (cmd_argc == 0)
+ {
+ return False;
+ }
+
+ cmd_set_options = 0x0;
+
+ if ((i = process_tok(cmd_argv[0])) >= 0)
+ {
+ int argc = (int)cmd_argc;
+ char **argv = cmd_argv;
+ optind = 0;
+
+ commands[i]->fn(info, argc, argv);
+ }
+ else if (i == -2)
+ {
+ fprintf(out_hnd, "%s: command abbreviation ambiguous\n",
+ CNV_LANG(cmd_argv[0]));
+ }
+ else
+ {
+ fprintf(out_hnd, "%s: command not found\n",
+ CNV_LANG(cmd_argv[0]));
+ }
+
+ free_char_array(cmd_argc, cmd_argv);
+
+ return True;
+}
+
+
+/****************************************************************************
+ process commands from the client
+****************************************************************************/
+static BOOL process(struct client_info *info, char *cmd_str)
+{
+ pstring line;
+ char *cmd = cmd_str;
+
+ if (cmd != NULL)
+ {
+ while (cmd[0] != '\0')
+ {
+ char *p;
+
+ if ((p = strchr(cmd, ';')) == 0)
+ {
+ strncpy(line, cmd, 999);
+ line[1000] = '\0';
+ cmd += strlen(cmd);
+ }
+ else
+ {
+ if (p - cmd > 999)
+ p = cmd + 999;
+ strncpy(line, cmd, p - cmd);
+ line[p - cmd] = '\0';
+ cmd = p + 1;
+ }
+
+ /* input language code to internal one */
+ CNV_INPUT(line);
+
+ if (!do_command(info, line))
+ continue;
+ }
+ }
+ else
+ while (!feof(stdin))
+ {
+#ifdef HAVE_LIBREADLINE
+ char *ret_line;
+#endif
+ pstring pline;
+ BOOL at_sym = False;
+ pline[0] = 0;
+ safe_strcat(pline, "[", sizeof(pline) - 1);
+ if (usr.ntc.domain[0] != 0)
+ {
+ safe_strcat(pline, usr.ntc.domain,
+ sizeof(pline) - 1);
+ safe_strcat(pline, "\\", sizeof(pline) - 1);
+ at_sym = True;
+ }
+ if (usr.ntc.user_name[0] != 0)
+ {
+ safe_strcat(pline, usr.ntc.user_name,
+ sizeof(pline) - 1);
+ at_sym = True;
+ }
+ if (at_sym)
+ {
+ safe_strcat(pline, "@", sizeof(pline) - 1);
+ }
+
+ safe_strcat(pline, cli_info.dest_host,
+ sizeof(pline) - 1);
+ safe_strcat(pline, "]$ ", sizeof(pline) - 1);
+
+#ifndef HAVE_LIBREADLINE
+
+ /* display a prompt */
+ fprintf(out_hnd, "%s", CNV_LANG(pline));
+ fflush(out_hnd);
+
+ cli_use_wait_keyboard();
+
+ /* and get a response */
+ if (!fgets(line, 1000, stdin))
+ {
+ break;
+ }
+
+#else /* HAVE_LIBREADLINE */
+
+ if (!(ret_line = readline(pline)))
+ break;
+ safe_free(ret_line);
+
+ /* Copy read line to samba buffer */
+
+ pstrcpy(line, rl_line_buffer);
+
+ /* Add to history */
+
+ if (strlen(line) > 0)
+ add_history(line);
+#endif
+ /* input language code to internal one */
+ CNV_INPUT(line);
+
+ /* special case - first char is ! */
+ if (*line == '!')
+ {
+ system(line + 1);
+ continue;
+ }
+
+ fprintf(out_hnd, "%s\n", line);
+
+ if (!do_command(info, line))
+ continue;
+ }
+
+ return (True);
+}
+
+/****************************************************************************
+usage on the program
+****************************************************************************/
+static void usage(char *pname)
+{
+ fprintf(out_hnd,
+ "Usage: %s [\\server] [password] [-U user] -[W domain] [-l log] ",
+ pname);
+
+ fprintf(out_hnd, "\nVersion %s\n", VERSION);
+ fprintf(out_hnd, "\t-d debuglevel set the debuglevel\n");
+ fprintf(out_hnd,
+ "\t-S <\\>server Server to connect to (\\. or . for localhost)\n");
+ fprintf(out_hnd,
+ "\t-l log basename. Basename for log/debug files\n");
+ fprintf(out_hnd,
+ "\t-n netbios name. Use this name as my netbios name\n");
+ fprintf(out_hnd,
+ "\t-N don't ask for a password\n");
+ fprintf(out_hnd,
+ "\t-m max protocol set the max protocol level\n");
+ fprintf(out_hnd,
+ "\t-I dest IP use this IP to connect to\n");
+ fprintf(out_hnd,
+ "\t-E write messages to stderr instead of stdout\n");
+ fprintf(out_hnd,
+ "\t-U username set the network username\n");
+ fprintf(out_hnd,
+ "\t-U username%%pass set the network username and password\n");
+ fprintf(out_hnd, "\t-W domain set the domain name\n");
+ fprintf(out_hnd,
+ "\t-c 'command string' execute semicolon separated commands\n");
+ fprintf(out_hnd,
+ "\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
+ fprintf(out_hnd, "\n");
+}
+
+#ifdef HAVE_LIBREADLINE
+
+/****************************************************************************
+GNU readline completion functions
+****************************************************************************/
+
+
+char *complete_samenum_usr(char *text, int state)
+{
+ static uint32 i = 0;
+ static uint32 num_usrs = 0;
+ static struct acct_info *sam = NULL;
+
+ if (state == 0)
+ {
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+ sid_copy(&sid1, &cli_info.dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, cli_info.dom.level5_dom);
+
+ if (sid1.num_auths == 0)
+ {
+ return NULL;
+ }
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli_info.dest_host);
+ strupper(srv_name);
+
+ free(sam);
+ sam = NULL;
+ num_usrs = 0;
+
+ /* Iterate all users */
+ if (msrpc_sam_enum_users(srv_name, domain, &sid1,
+ &sam, &num_usrs,
+ NULL, NULL, NULL, NULL) == 0)
+ {
+ return NULL;
+ }
+
+ i = 0;
+ }
+
+ for (; i < num_usrs; i++)
+ {
+ char *usr_name = sam[i].acct_name;
+ if (text == NULL || text[0] == 0 ||
+ strnequal(text, usr_name, strlen(text)))
+ {
+ char *name = strdup(usr_name);
+ i++;
+ return name;
+ }
+ }
+
+ return NULL;
+}
+
+char *complete_samenum_als(char *text, int state)
+{
+ static uint32 i = 0;
+ static uint32 num_als = 0;
+ static struct acct_info *sam = NULL;
+
+ if (state == 0)
+ {
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+ sid_copy(&sid1, &cli_info.dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, cli_info.dom.level5_dom);
+
+ if (sid1.num_auths == 0)
+ {
+ return NULL;
+ }
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli_info.dest_host);
+ strupper(srv_name);
+
+ free(sam);
+ sam = NULL;
+ num_als = 0;
+
+ /* Iterate all aliases */
+ if (msrpc_sam_enum_aliases(srv_name, domain, &sid1,
+ &sam, &num_als,
+ NULL, NULL, NULL) == 0)
+ {
+ return NULL;
+ }
+
+ i = 0;
+ }
+
+ for (; i < num_als; i++)
+ {
+ char *als_name = sam[i].acct_name;
+ if (text == NULL || text[0] == 0 ||
+ strnequal(text, als_name, strlen(text)))
+ {
+ char *name = strdup(als_name);
+ i++;
+ return name;
+ }
+ }
+
+ return NULL;
+}
+
+char *complete_samenum_grp(char *text, int state)
+{
+ static uint32 i = 0;
+ static uint32 num_grps = 0;
+ static struct acct_info *sam = NULL;
+
+ if (state == 0)
+ {
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+ sid_copy(&sid1, &cli_info.dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, cli_info.dom.level5_dom);
+
+ if (sid1.num_auths == 0)
+ {
+ return NULL;
+ }
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli_info.dest_host);
+ strupper(srv_name);
+
+ free(sam);
+ sam = NULL;
+ num_grps = 0;
+
+ /* Iterate all groups */
+ if (msrpc_sam_enum_groups(srv_name,
+ domain, &sid1,
+ &sam, &num_grps,
+ NULL, NULL, NULL) == 0)
+ {
+ return NULL;
+ }
+
+ i = 0;
+ }
+
+ for (; i < num_grps; i++)
+ {
+ char *grp_name = sam[i].acct_name;
+ if (text == NULL || text[0] == 0 ||
+ strnequal(text, grp_name, strlen(text)))
+ {
+ char *name = strdup(grp_name);
+ i++;
+ return name;
+ }
+ }
+
+ return NULL;
+}
+
+/* Complete an rpcclient command */
+
+static char *complete_cmd(char *text, int state)
+{
+ static int cmd_index;
+ char *name;
+
+ /* Initialise */
+
+ if (state == 0)
+ {
+ cmd_index = 0;
+ }
+
+ /* Return the next name which partially matches the list of commands */
+
+ while ((cmd_index < num_commands)
+ && (strlen(name = commands[cmd_index++]->name) > 0))
+ {
+ if (strncmp(name, text, strlen(text)) == 0)
+ {
+ return strdup(name);
+ }
+ }
+
+ return NULL;
+}
+
+/* Main completion function */
+
+static char **completion_fn(char *text, int start, int end)
+{
+ pstring cmd_partial;
+ int cmd_index;
+ int num_words;
+
+ int i;
+ char lastch = ' ';
+
+ (void)get_cmd_args(rl_line_buffer);
+
+ safe_strcpy(cmd_partial, rl_line_buffer,
+ MAX(sizeof(cmd_partial), end) - 1);
+
+ /* Complete rpcclient command */
+
+ if (start == 0)
+ {
+ return completion_matches(text, complete_cmd);
+ }
+
+ /* Count # of words in command */
+
+ num_words = 0;
+ for (i = 0; i <= end; i++)
+ {
+ if ((rl_line_buffer[i] != ' ') && (lastch == ' '))
+ {
+ num_words++;
+ }
+ lastch = rl_line_buffer[i];
+ }
+
+ if (rl_line_buffer[end] == ' ')
+ num_words++;
+
+ /* Work out which command we are completing for */
+
+ for (cmd_index = 0; cmd_index < num_commands; cmd_index++)
+ {
+
+ /* Check each command in array */
+
+ if (strncmp(rl_line_buffer, commands[cmd_index]->name,
+ strlen(commands[cmd_index]->name)) == 0)
+ {
+
+ /* Call appropriate completion function */
+
+ if (num_words == 2 || num_words == 3)
+ {
+ char *(*fn) (char *, int);
+ fn =
+ commands[cmd_index]->compl_args
+ [num_words - 2];
+ if (fn != NULL)
+ {
+ return completion_matches(text, fn);
+ }
+ }
+ }
+ }
+
+ /* Eeek! */
+
+ return NULL;
+}
+
+/* To avoid filename completion being activated when no valid
+ completions are found, we assign this stub completion function
+ to the rl_completion_entry_function variable. */
+
+static char *complete_cmd_null(char *text, int state)
+{
+ return NULL;
+}
+
+#else
+
+char *complete_samenum_usr(char *text, int state)
+{
+ return NULL;
+}
+char *complete_samenum_als(char *text, int state)
+{
+ return NULL;
+}
+char *complete_samenum_grp(char *text, int state)
+{
+ return NULL;
+}
+
+#endif /* HAVE_LIBREADLINE */
+
+static void set_user_password(struct ntuser_creds *u,
+ BOOL got_pass, char *password)
+{
+ /* set the password cache info */
+ if (got_pass)
+ {
+ if (password == NULL)
+ {
+ DEBUG(10, ("set_user_password: NULL pwd\n"));
+ pwd_set_nullpwd(&(u->pwd));
+ }
+ else
+ {
+ /* generate 16 byte hashes */
+ DEBUG(10, ("set_user_password: generate\n"));
+ pwd_make_lm_nt_16(&(u->pwd), password);
+ }
+ }
+ else
+ {
+ DEBUG(10, ("set_user_password: read\n"));
+ pwd_read(&(u->pwd), "Enter Password:", True);
+ }
+}
+
+static void cmd_use(struct client_info *info, int argc, char *argv[])
+{
+ int opt;
+ BOOL net_use = False;
+ BOOL net_use_add = True;
+ BOOL force_close = False;
+ struct ntuser_creds u;
+ fstring dest_host;
+ fstring srv_name;
+ BOOL null_pwd = False;
+ BOOL got_pwd = False;
+ pstring password;
+ extern struct user_creds *usr_creds;
+
+ if (usr_creds != NULL)
+ {
+ copy_nt_creds(&u, &usr_creds->ntc);
+ }
+ else
+ {
+ copy_nt_creds(&u, NULL);
+ }
+
+ pstrcpy(dest_host, cli_info.dest_host);
+ pstrcpy(u.user_name, optarg);
+ info->reuse = False;
+
+ if (argc <= 1)
+ {
+ report(out_hnd,
+ "net [\\\\Server] [-U user%%pass] [-W domain] [-d] [-f]\n");
+ report(out_hnd, " -d Deletes a connection\n");
+ report(out_hnd, " -f Forcibly deletes a connection\n");
+ report(out_hnd, "net -u Shows all connections\n");
+ }
+
+ if (argc > 1 && (*argv[1] != '-'))
+ {
+ if (strnequal("\\\\", argv[1], 2) ||
+ strnequal("//", argv[1], 2))
+ {
+ pstrcpy(dest_host, argv[1] + 2);
+ }
+ argc--;
+ argv++;
+ }
+
+ while ((opt = getopt(argc, argv, "udU:W:")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'u':
+ {
+ net_use = True;
+ break;
+ }
+
+ case 'U':
+ {
+ char *lp;
+ pstrcpy(u.user_name, optarg);
+ if ((lp = strchr(u.user_name, '%')))
+ {
+ *lp = 0;
+ pstrcpy(password, lp + 1);
+ memset(strchr(optarg, '%') + 1, 'X',
+ strlen(password));
+ got_pwd = True;
+ }
+ if (u.user_name[0] == 0 && password[0] == 0)
+ {
+ null_pwd = True;
+ }
+ break;
+ }
+
+ case 'N':
+ {
+ null_pwd = True;
+ }
+ case 'W':
+ {
+ pstrcpy(u.domain, optarg);
+ break;
+ }
+
+ case 'd':
+ {
+ net_use_add = False;
+ break;
+ }
+
+ case 'f':
+ {
+ force_close = True;
+ break;
+ }
+
+ default:
+ {
+ report(out_hnd,
+ "net -S \\server [-U user%%pass] [-W domain] [-d] [-f]\n");
+ report(out_hnd, "net -u\n");
+ break;
+ }
+ }
+ }
+
+ if (strnequal("\\\\", dest_host, 2))
+ {
+ fstrcpy(srv_name, dest_host);
+ }
+ else
+ {
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, dest_host);
+ }
+ strupper(srv_name);
+
+ if (net_use)
+ {
+ int i;
+ uint32 num_uses;
+ struct use_info **use;
+ cli_net_use_enum(&num_uses, &use);
+
+ if (num_uses == 0)
+ {
+ report(out_hnd, "No connections\n");
+ }
+ else
+ {
+ report(out_hnd, "Connections:\n");
+
+ for (i = 0; i < num_uses; i++)
+ {
+ if (use[i] != NULL && use[i]->connected)
+ {
+ report(out_hnd, "Server:\t%s\t",
+ use[i]->srv_name);
+ report(out_hnd, "Key:\t[%d,%x]\t",
+ use[i]->key.pid,
+ use[i]->key.vuid);
+ report(out_hnd, "User:\t%s\t",
+ use[i]->user_name);
+ report(out_hnd, "Domain:\t%s\n",
+ use[i]->domain);
+ }
+ }
+ }
+ }
+ else if (net_use_add)
+ {
+ BOOL isnew;
+ if (null_pwd)
+ {
+ set_user_password(&u, True, NULL);
+ }
+ else
+ {
+ set_user_password(&u, got_pwd, password);
+ }
+
+ /* paranoia: destroy the local copy of the password */
+ bzero(password, sizeof(password));
+
+ report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
+ srv_name, u.user_name, u.domain);
+ report(out_hnd, "Connection:\t");
+
+ if (cli_net_use_add
+ (srv_name, &u, True, info->reuse, &isnew) != NULL)
+ {
+ report(out_hnd, "OK\n");
+ }
+ else
+ {
+ report(out_hnd, "FAILED\n");
+ }
+ }
+ else
+ {
+ BOOL closed;
+ report(out_hnd, "Server:\t%s:\tUser:\t%s\tDomain:\t%s\n",
+ srv_name, u.user_name, u.domain);
+ report(out_hnd, "Connection:\t");
+
+ if (!cli_net_use_del(srv_name, &u, force_close, &closed))
+ {
+ report(out_hnd, ": Does not exist\n");
+ }
+ else if (force_close && closed)
+ {
+ report(out_hnd, ": Forcibly terminated\n");
+ }
+ else if (closed)
+ {
+ report(out_hnd, ": Terminated\n");
+ }
+ else
+ {
+ report(out_hnd, ": Unlinked\n");
+ }
+ }
+
+ usr_creds = NULL;
+
+ /* paranoia: destroy the local copy of the password */
+ bzero(password, sizeof(password));
+}
+
+#define CMD_STR 0x1
+#define CMD_DBF 0x2
+#define CMD_SVC 0x4
+#define CMD_TERM 0x8
+#define CMD_PASS 0x10
+#define CMD_USER 0x20
+#define CMD_NOPW 0x40
+#define CMD_DBLV 0x80
+#define CMD_HELP 0x100
+#define CMD_SOCK 0x200
+#define CMD_IFACE 0x400
+#define CMD_DOM 0x800
+#define CMD_IP 0x1000
+#define CMD_HOST 0x2000
+#define CMD_NAME 0x4000
+#define CMD_DBG 0x8000
+#define CMD_SCOPE 0x10000
+#define CMD_INTER 0x20000
+
+static void cmd_set(struct client_info *info, int argc, char *argv[])
+{
+ BOOL interactive = True;
+ char *cmd_str = NULL;
+ int opt;
+ extern FILE *dbf;
+ extern char *optarg;
+ static pstring servicesf = CONFIGFILE;
+ pstring term_code;
+ pstring password; /* local copy only, if one is entered */
+ extern struct user_creds *usr_creds;
+
+ fstring srv_name;
+
+ password[0] = 0;
+ usr_creds = &usr;
+ info->reuse = False;
+#ifdef KANJI
+ pstrcpy(term_code, KANJI);
+#else /* KANJI */
+ *term_code = 0;
+#endif /* KANJI */
+
+ if (argc > 1 && (*argv[1] != '-'))
+ {
+ if (strnequal("\\\\", argv[1], 2) ||
+ strnequal("//", argv[1], 2))
+ {
+ cmd_set_options |= CMD_HOST;
+ pstrcpy(cli_info.dest_host, argv[1] + 2);
+ strupper(cli_info.dest_host);
+ }
+ argc--;
+ argv++;
+ }
+ if (argc > 1 && (*argv[1] != '-'))
+ {
+ cmd_set_options |= CMD_PASS;
+ pstrcpy(password, argv[1]);
+ memset(argv[1], 'X', strlen(argv[1]));
+ argc--;
+ argv++;
+ }
+
+ while ((opt = getopt(argc, argv,
+ "Rs:B:O:M:S:i:Nn:d:l:hI:EB:U:L:t:m:W:T:D:c:")) !=
+ EOF)
+ {
+ switch (opt)
+ {
+ case 'R':
+ {
+ info->reuse = True;
+ break;
+ }
+
+ case 'm':
+ {
+ /* FIXME ... max_protocol seems to be funny here */
+
+ int max_protocol = 0;
+ max_protocol =
+ interpret_protocol(optarg,
+ max_protocol);
+ fprintf(stderr,
+ "max protocol not currently supported\n");
+ break;
+ }
+
+ case 'O':
+ {
+ cmd_set_options |= CMD_SOCK;
+ pstrcpy(user_socket_options, optarg);
+ break;
+ }
+
+ case 'S':
+ {
+ cmd_set_options |= CMD_HOST;
+ pstrcpy(cli_info.dest_host, optarg);
+ strupper(cli_info.dest_host);
+ break;
+ }
+
+ case 'B':
+ {
+ cmd_set_options |= CMD_IFACE;
+ iface_set_default(NULL, optarg, NULL);
+ break;
+ }
+
+ case 'i':
+ {
+ cmd_set_options |= CMD_SCOPE;
+ pstrcpy(scope, optarg);
+ break;
+ }
+
+ case 'U':
+ {
+ char *lp;
+ cmd_set_options |= CMD_USER;
+ pstrcpy(usr.ntc.user_name, optarg);
+ if ((lp = strchr(usr.ntc.user_name, '%')))
+ {
+ *lp = 0;
+ pstrcpy(password, lp + 1);
+ cmd_set_options |= CMD_PASS;
+ memset(strchr(optarg, '%') + 1, 'X',
+ strlen(password));
+ }
+ if (usr.ntc.user_name[0] == 0
+ && password[0] == 0)
+ {
+ cmd_set_options |= CMD_NOPW;
+ }
+ break;
+ }
+
+ case 'W':
+ {
+ cmd_set_options |= CMD_DOM;
+ pstrcpy(usr.ntc.domain, optarg);
+ break;
+ }
+
+ case 'E':
+ {
+ cmd_set_options |= CMD_DBG;
+ dbf = stderr;
+ break;
+ }
+
+ case 'I':
+ {
+ cmd_set_options |= CMD_IP;
+ cli_info.dest_ip = *interpret_addr2(optarg);
+ if (zero_ip(cli_info.dest_ip))
+ {
+ free_connections();
+ exit(1);
+ }
+ break;
+ }
+
+ case 'n':
+ {
+ cmd_set_options |= CMD_NAME;
+ fstrcpy(global_myname, optarg);
+ break;
+ }
+
+ case 'N':
+ {
+ cmd_set_options |= CMD_NOPW | CMD_PASS;
+ break;
+ }
+
+ case 'd':
+ {
+ cmd_set_options |= CMD_DBLV;
+ if (*optarg == 'A')
+ DEBUGLEVEL = 10000;
+ else
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ }
+
+ case 'l':
+ {
+ cmd_set_options |= CMD_INTER;
+ slprintf(debugf, sizeof(debugf) - 1,
+ "%s.client", optarg);
+ interactive = False;
+ break;
+ }
+
+ case 'c':
+ {
+ cmd_set_options |= CMD_STR | CMD_PASS;
+ cmd_str = optarg;
+ break;
+ }
+
+ case 'h':
+ {
+ cmd_set_options |= CMD_HELP;
+ usage(argv[0]);
+ break;
+ }
+
+ case 's':
+ {
+ cmd_set_options |= CMD_SVC;
+ pstrcpy(servicesf, optarg);
+ break;
+ }
+
+ case 't':
+ {
+ cmd_set_options |= CMD_TERM;
+ pstrcpy(term_code, optarg);
+ break;
+ }
+
+ default:
+ {
+ cmd_set_options |= CMD_HELP;
+ usage(argv[0]);
+ break;
+ }
+ }
+ }
+
+ if (IS_BITS_SET_ALL(cmd_set_options, CMD_INTER))
+ {
+ setup_logging(debugf, interactive);
+ reopen_logs();
+ }
+
+ strupper(global_myname);
+ fstrcpy(cli_info.myhostname, global_myname);
+
+ if (IS_BITS_SET_ALL(cmd_set_options, CMD_SVC))
+ {
+ if (!lp_load(servicesf, True, False, False))
+ {
+ fprintf(stderr,
+ "Can't load %s - run testparm to debug it\n",
+ servicesf);
+ }
+
+ }
+
+ if (IS_BITS_SET_ALL(cmd_set_options, CMD_INTER))
+ {
+ load_interfaces();
+ }
+
+ DEBUG(10, ("cmd_set: options: %x\n", cmd_set_options));
+
+ if (IS_BITS_SET_ALL(cmd_set_options, CMD_HELP))
+ {
+ return;
+ }
+
+ if (IS_BITS_SET_ALL(cmd_set_options, CMD_NOPW))
+ {
+ set_user_password(&usr.ntc, True, NULL);
+ }
+ else
+ {
+ set_user_password(&usr.ntc,
+ IS_BITS_SET_ALL(cmd_set_options, CMD_PASS),
+ password);
+ }
+
+ /* paranoia: destroy the local copy of the password */
+ bzero(password, sizeof(password));
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli_info.dest_host);
+ strupper(srv_name);
+
+ if (!strequal(srv_name, "\\\\."))
+ {
+ BOOL isnew;
+ cli_net_use_add(srv_name, &usr.ntc, True, False, &isnew);
+ }
+ if (cmd_str != NULL)
+ {
+ process(&cli_info, cmd_str);
+ }
+ usr_creds = NULL;
+}
+
+static void read_user_env(struct ntuser_creds *u)
+{
+ pstring password;
+
+ password[0] = 0;
+
+ if (getenv("USER"))
+ {
+ char *p;
+ pstrcpy(u->user_name, getenv("USER"));
+
+ /* modification to support userid%passwd syntax in the USER var
+ 25.Aug.97, jdblair@uab.edu */
+
+ if ((p = strchr(u->user_name, '%')))
+ {
+ *p = 0;
+ pstrcpy(password, p + 1);
+ memset(strchr(getenv("USER"), '%') + 1, 'X',
+ strlen(password));
+ }
+ strupper(u->user_name);
+ }
+
+ /* modification to support PASSWD environmental var
+ 25.Aug.97, jdblair@uab.edu */
+ if (getenv("PASSWD"))
+ {
+ pstrcpy(password, getenv("PASSWD"));
+ }
+
+ if (*u->user_name == 0 && getenv("LOGNAME"))
+ {
+ pstrcpy(u->user_name, getenv("LOGNAME"));
+ strupper(u->user_name);
+ }
+
+ set_user_password(u, True, password);
+
+ /* paranoia: destroy the local copy of the password */
+ bzero(password, sizeof(password));
+}
+
+void readline_init(void)
+{
+#ifdef HAVE_LIBREADLINE
+
+ /* Initialise GNU Readline */
+
+ rl_readline_name = "rpcclient";
+ rl_attempted_completion_function = completion_fn;
+ rl_completion_entry_function = (Function *) complete_cmd_null;
+
+ /* Initialise history list */
+
+ using_history();
+
+#else
+ int x;
+ x = 0; /* stop compiler warnings */
+#endif /* HAVE_LIBREADLINE */
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+int command_main(int argc, char *argv[])
+{
+ extern struct user_creds *usr_creds;
+ mode_t myumask = 0755;
+ char progname[255], path[255], *s;
+
+ DEBUGLEVEL = 2;
+
+ add_command_set(general_commands);
+
+ copy_user_creds(&usr, NULL);
+
+ usr_creds = &usr;
+ usr.ptr_ntc = 1;
+
+ out_hnd = stdout;
+
+ strncpy(path, argv[0], 255);
+ for (s = strtok(path, "/"); s; s = strtok(NULL, "/"))
+ fstrcpy(progname, s);
+
+ slprintf(debugf, sizeof(debugf) - 1,
+ "%s/log.%s", LOGFILEBASE, progname);
+
+ pstrcpy(usr.ntc.domain, "");
+ pstrcpy(usr.ntc.user_name, "");
+
+ pstrcpy(cli_info.myhostname, "");
+ pstrcpy(cli_info.dest_host, "");
+ cli_info.dest_ip.s_addr = 0;
+
+ ZERO_STRUCT(cli_info.dom.level3_sid);
+ ZERO_STRUCT(cli_info.dom.level5_sid);
+ fstrcpy(cli_info.dom.level3_dom, "");
+ fstrcpy(cli_info.dom.level5_dom, "");
+
+ readline_init();
+ TimeInit();
+ charset_initialise();
+ init_connections();
+
+ myumask = umask(0);
+ umask(myumask);
+
+ if (!get_myname(global_myname, NULL))
+ {
+ fprintf(stderr, "Failed to get my hostname.\n");
+ }
+
+ if (argc < 2)
+ {
+ usage(argv[0]);
+ free_connections();
+ exit(1);
+ }
+
+ read_user_env(&usr.ntc);
+
+ cmd_set_options &= ~CMD_HELP;
+ cmd_set_options &= ~CMD_NOPW;
+ cmd_set_options &= ~CMD_USER;
+ cmd_set_options &= ~CMD_PASS;
+
+ codepage_initialise(lp_client_code_page());
+
+ cmd_set(&cli_info, argc, argv);
+
+ if (IS_BITS_SET_ALL(cmd_set_options, CMD_HELP))
+ {
+ free_connections();
+ exit(0);
+ }
+
+ DEBUG(3, ("%s client started (version %s)\n", timestring(), VERSION));
+
+ process(&cli_info, NULL);
+
+ free_connections();
+
+ free_cmd_set_array(num_commands, commands);
+ num_commands = 0;
+ commands = NULL;
+
+ return (0);
+}
diff --git a/source/lib/crc32.c b/source/lib/crc32.c
index 16b337c764b..052fce205da 100644
--- a/source/lib/crc32.c
+++ b/source/lib/crc32.c
@@ -9,7 +9,7 @@
#include "includes.h"
extern int DEBUGLEVEL;
-static unsigned long CRCTable[256] =
+static const unsigned long CRCTable[256] =
{
0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,
0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,
@@ -56,12 +56,14 @@ static unsigned long CRCTable[256] =
0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D
};
-uint32 crc32_calc_buffer( char *buffer, uint32 count)
+uint32 crc32_calc_buffer( uint32 count, char *buffer)
{
uint32 crc=0xffffffff;
- int i;
+ uint32 i;
for(i=0;i<count;i++)
+ {
crc = (crc>>8) ^ CRCTable[(buffer[i] ^ crc) & 0xff];
+ }
crc^=0xffffffff;
DEBUG(10,("crc32_calc_buffer: %x\n", crc));
dump_data(100, buffer, count);
diff --git a/source/lib/debug.c b/source/lib/debug.c
index c88f4e1a41f..ab11d81a212 100644
--- a/source/lib/debug.c
+++ b/source/lib/debug.c
@@ -75,6 +75,7 @@
* debugf - Debug file name.
* append_log - If True, then the output file will be opened in append
* mode.
+ * timestamp_log -
* DEBUGLEVEL - System-wide debug message limit. Messages with message-
* levels higher than DEBUGLEVEL will not be processed.
*/
@@ -82,6 +83,7 @@
FILE *dbf = NULL;
pstring debugf = "";
BOOL append_log = False;
+BOOL timestamp_log = True;
int DEBUGLEVEL = 1;
@@ -112,40 +114,51 @@ static int debug_count = 0;
static int syslog_level = 0;
#endif
static pstring format_bufr = { '\0' };
-static size_t format_pos = 0;
+static int format_pos = 0;
/* -------------------------------------------------------------------------- **
* Functions...
*/
-#if defined(SIGUSR2)
+/* ************************************************************************** **
+ * tells us if interactive logging was requested
+ * ************************************************************************** **
+ */
+BOOL dbg_interactive(void)
+{
+ return stdout_logging;
+}
+
+#if defined(SIGUSR2) && !defined(MEM_MAN)
/* ************************************************************************** **
* catch a sigusr2 - decrease the debug log level.
* ************************************************************************** **
*/
void sig_usr2( int sig )
{
+ BlockSignals( True, SIGUSR2 );
+
DEBUGLEVEL--;
if( DEBUGLEVEL < 0 )
DEBUGLEVEL = 0;
DEBUG( 0, ( "Got SIGUSR2; set debug level to %d.\n", DEBUGLEVEL ) );
-#if !defined(HAVE_SIGACTION)
+ BlockSignals( False, SIGUSR2 );
CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
-#endif
} /* sig_usr2 */
#endif /* SIGUSR2 */
-#if defined(SIGUSR1)
+#if defined(SIGUSR1) && !defined(MEM_MAN)
/* ************************************************************************** **
* catch a sigusr1 - increase the debug log level.
* ************************************************************************** **
*/
void sig_usr1( int sig )
{
+ BlockSignals( True, SIGUSR1 );
DEBUGLEVEL++;
@@ -154,9 +167,8 @@ void sig_usr1( int sig )
DEBUG( 0, ( "Got SIGUSR1; set debug level to %d.\n", DEBUGLEVEL ) );
-#if !defined(HAVE_SIGACTION)
+ BlockSignals( False, SIGUSR1 );
CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
-#endif
} /* sig_usr1 */
#endif /* SIGUSR1 */
@@ -248,11 +260,11 @@ void force_check_log_size( void )
* ************************************************************************** **
*/
static void check_log_size( void )
-{
+ {
int maxlog;
SMB_STRUCT_STAT st;
- if( debug_count++ < 100 || geteuid() != 0 )
+ if( debug_count++ < 100 || getuid() != 0 )
return;
maxlog = lp_max_log_size() * 1024;
@@ -264,7 +276,7 @@ static void check_log_size( void )
(void)fclose( dbf );
dbf = NULL;
reopen_logs();
- if( dbf && get_file_size( debugf ) > maxlog )
+ if( dbf && file_size( debugf ) > maxlog )
{
pstring name;
@@ -275,23 +287,8 @@ static void check_log_size( void )
reopen_logs();
}
}
- /*
- * Here's where we need to panic if dbf == NULL..
- */
- if(dbf == NULL) {
- dbf = sys_fopen( "/dev/console", "w" );
- if(dbf) {
- DEBUG(0,("check_log_size: open of debug file %s failed - using console.\n",
- debugf ));
- } else {
- /*
- * We cannot continue without a debug file handle.
- */
- abort();
- }
- }
debug_count = 0;
-} /* check_log_size */
+ } /* check_log_size */
/* ************************************************************************** **
* Write an debug message on the debugfile.
@@ -318,8 +315,7 @@ va_dcl
va_start( ap );
format_str = va_arg( ap, char * );
#endif
- if(dbf)
- (void)vfprintf( dbf, format_str, ap );
+ (void)vfprintf( dbf, format_str, ap );
va_end( ap );
errno = old_errno;
return( 0 );
@@ -386,8 +382,6 @@ va_dcl
}
#endif
- check_log_size();
-
#ifdef WITH_SYSLOG
if( !lp_syslog_only() )
#endif
@@ -398,13 +392,13 @@ va_dcl
va_start( ap );
format_str = va_arg( ap, char * );
#endif
- if(dbf)
- (void)vfprintf( dbf, format_str, ap );
+ (void)vfprintf( dbf, format_str, ap );
va_end( ap );
- if(dbf)
- (void)fflush( dbf );
+ (void)fflush( dbf );
}
+ check_log_size();
+
errno = old_errno;
return( 0 );
@@ -445,8 +439,8 @@ static void bufr_print( void )
*/
static void format_debug_text( char *msg )
{
- size_t i;
- BOOL timestamp = (!stdout_logging && (lp_timestamp_logs() ||
+ int i;
+ BOOL timestamp = (timestamp_log && !stdout_logging && (lp_timestamp_logs() ||
!(lp_loaded())));
for( i = 0; msg[i]; i++ )
@@ -491,8 +485,7 @@ static void format_debug_text( char *msg )
void dbgflush( void )
{
bufr_print();
- if(dbf)
- (void)fflush( dbf );
+ (void)fflush( dbf );
} /* dbgflush */
/* ************************************************************************** **
@@ -517,13 +510,10 @@ void dbgflush( void )
*
* ************************************************************************** **
*/
-
BOOL dbghdr( int level, char *file, char *func, int line )
-{
- /* Ensure we don't lose any real errno value. */
- int old_errno = errno;
-
- if( format_pos ) {
+ {
+ if( format_pos )
+ {
/* This is a fudge. If there is stuff sitting in the format_bufr, then
* the *right* thing to do is to call
* format_debug_text( "\n" );
@@ -534,7 +524,7 @@ BOOL dbghdr( int level, char *file, char *func, int line )
* that a new header is *not* desired.
*/
return( True );
- }
+ }
#ifdef WITH_SYSLOG
/* Set syslog_level. */
@@ -548,32 +538,15 @@ BOOL dbghdr( int level, char *file, char *func, int line )
/* Print the header if timestamps are turned on. If parameters are
* not yet loaded, then default to timestamps on.
*/
- if( lp_timestamp_logs() || !(lp_loaded()) ) {
- char header_str[200];
-
- header_str[0] = '\0';
-
- if( lp_debug_pid())
- slprintf(header_str,sizeof(header_str)-1,", pid=%u",(unsigned int)getpid());
-
- if( lp_debug_uid()) {
- size_t hs_len = strlen(header_str);
- slprintf(header_str + hs_len,
- sizeof(header_str) - 1 - hs_len,
- ", effective(%u, %u), real(%u, %u)",
- (unsigned int)geteuid(), (unsigned int)getegid(),
- (unsigned int)getuid(), (unsigned int)getgid());
- }
-
+ if( timestamp_log && (lp_timestamp_logs() || !(lp_loaded()) ))
+ {
/* Print it all out at once to prevent split syslog output. */
- (void)Debug1( "[%s, %d%s] %s:%s(%d)\n",
- timestring(lp_debug_hires_timestamp()), level,
- header_str, file, func, line );
- }
+ (void)Debug1( "[%s, %d] %s:%s(%d)\n",
+ timestring(), level, file, func, line );
+ }
- errno = old_errno;
return( True );
-}
+ } /* dbghdr */
/* ************************************************************************** **
* Add text to the body of the "current" debug message via the format buffer.
@@ -623,4 +596,163 @@ BOOL dbghdr( int level, char *file, char *func, int line )
#endif
+dbg_Token dbg_char2token( dbg_Token *state, int c )
+ /* ************************************************************************ **
+ * Parse input one character at a time.
+ *
+ * Input: state - A pointer to a token variable. This is used to
+ * maintain the parser state between calls. For
+ * each input stream, you should set up a separate
+ * state variable and initialize it to dbg_null.
+ * Pass a pointer to it into this function with each
+ * character in the input stream. See dbg_test()
+ * for an example.
+ * c - The "current" character in the input stream.
+ *
+ * Output: A token.
+ * The token value will change when delimiters are found,
+ * which indicate a transition between syntactical objects.
+ * Possible return values are:
+ *
+ * dbg_null - The input character was an end-of-line.
+ * This resets the parser to its initial state
+ * in preparation for parsing the next line.
+ * dbg_eof - Same as dbg_null, except that the character
+ * was an end-of-file.
+ * dbg_ignore - Returned for whitespace and delimiters.
+ * These lexical tokens are only of interest
+ * to the parser.
+ * dbg_header - Indicates the start of a header line. The
+ * input character was '[' and was the first on
+ * the line.
+ * dbg_timestamp - Indicates that the input character was part
+ * of a header timestamp.
+ * dbg_level - Indicates that the input character was part
+ * of the debug-level value in the header.
+ * dbg_sourcefile - Indicates that the input character was part
+ * of the sourcefile name in the header.
+ * dbg_function - Indicates that the input character was part
+ * of the function name in the header.
+ * dbg_lineno - Indicates that the input character was part
+ * of the DEBUG call line number in the header.
+ * dbg_message - Indicates that the input character was part
+ * of the DEBUG message text.
+ *
+ * ************************************************************************ **
+ */
+ {
+ /* The terminating characters that we see will greatly depend upon
+ * how they are read. For example, if gets() is used instead of
+ * fgets(), then we will not see newline characters. A lot also
+ * depends on the calling function, which may handle terminators
+ * itself.
+ *
+ * '\n', '\0', and EOF are all considered line terminators. The
+ * dbg_eof token is sent back if an EOF is encountered.
+ *
+ * Warning: only allow the '\0' character to be sent if you are
+ * using gets() to read whole lines (thus replacing '\n'
+ * with '\0'). Sending '\0' at the wrong time will mess
+ * up the parsing.
+ */
+ switch( c )
+ {
+ case EOF:
+ *state = dbg_null; /* Set state to null (initial state) so */
+ return( dbg_eof ); /* that we can restart with new input. */
+ case '\n':
+ case '\0':
+ *state = dbg_null; /* A newline or eoln resets to the null state. */
+ return( dbg_null );
+ }
+
+ /* When within the body of the message, only a line terminator
+ * can cause a change of state. We've already checked for line
+ * terminators, so if the current state is dbg_msgtxt, simply
+ * return that as our current token.
+ */
+ if( dbg_message == *state )
+ return( dbg_message );
+
+ /* If we are at the start of a new line, and the input character
+ * is an opening bracket, then the line is a header line, otherwise
+ * it's a message body line.
+ */
+ if( dbg_null == *state )
+ {
+ if( '[' == c )
+ {
+ *state = dbg_timestamp;
+ return( dbg_header );
+ }
+ *state = dbg_message;
+ return( dbg_message );
+ }
+
+ /* We've taken care of terminators, text blocks and new lines.
+ * The remaining possibilities are all within the header line
+ * itself.
+ */
+
+ /* Within the header line, whitespace can be ignored *except*
+ * within the timestamp.
+ */
+ if( isspace( c ) )
+ {
+ /* Fudge. The timestamp may contain space characters. */
+ if( (' ' == c) && (dbg_timestamp == *state) )
+ return( dbg_timestamp );
+ /* Otherwise, ignore whitespace. */
+ return( dbg_ignore );
+ }
+
+ /* Okay, at this point we know we're somewhere in the header.
+ * Valid header *states* are: dbg_timestamp, dbg_level,
+ * dbg_sourcefile, dbg_function, and dbg_lineno.
+ */
+ switch( c )
+ {
+ case ',':
+ if( dbg_timestamp == *state )
+ {
+ *state = dbg_level;
+ return( dbg_ignore );
+ }
+ break;
+ case ']':
+ if( dbg_level == *state )
+ {
+ *state = dbg_sourcefile;
+ return( dbg_ignore );
+ }
+ break;
+ case ':':
+ if( dbg_sourcefile == *state )
+ {
+ *state = dbg_function;
+ return( dbg_ignore );
+ }
+ break;
+ case '(':
+ if( dbg_function == *state )
+ {
+ *state = dbg_lineno;
+ return( dbg_ignore );
+ }
+ break;
+ case ')':
+ if( dbg_lineno == *state )
+ {
+ *state = dbg_null;
+ return( dbg_ignore );
+ }
+ break;
+ }
+
+ /* If the previous block did not result in a state change, then
+ * return the current state as the current token.
+ */
+ return( *state );
+ } /* dbg_char2token */
+
/* ************************************************************************** */
diff --git a/source/lib/domain_namemap.c b/source/lib/domain_namemap.c
index 988f5e5d659..7d23c29a31a 100644
--- a/source/lib/domain_namemap.c
+++ b/source/lib/domain_namemap.c
@@ -2,7 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
Groupname handling
- Copyright (C) Jeremy Allison 1998.
+ Copyright (C) Jeremy Allison 1998-2000.
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -47,178 +48,11 @@
#include "includes.h"
+#include "sids.h"
+
extern int DEBUGLEVEL;
extern fstring global_myworkgroup;
-extern DOM_SID global_member_sid;
-extern fstring global_sam_name;
-extern DOM_SID global_sam_sid;
-extern DOM_SID global_sid_S_1_5_20;
-
-/*******************************************************************
- converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static uid_t pwdb_user_rid_to_uid(uint32 user_rid)
-{
- return ((user_rid & (~RID_TYPE_USER))- 1000)/RID_MULTIPLIER;
-}
-
-/*******************************************************************
- converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static uint32 pwdb_group_rid_to_gid(uint32 group_rid)
-{
- return ((group_rid & (~RID_TYPE_GROUP))- 1000)/RID_MULTIPLIER;
-}
-
-/*******************************************************************
- converts NT Alias RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static uint32 pwdb_alias_rid_to_gid(uint32 alias_rid)
-{
- return ((alias_rid & (~RID_TYPE_ALIAS))- 1000)/RID_MULTIPLIER;
-}
-
-/*******************************************************************
- converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static uint32 pwdb_gid_to_group_rid(uint32 gid)
-{
- uint32 grp_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_GROUP);
- return grp_rid;
-}
-
-/******************************************************************
- converts UNIX gid to an NT Alias RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static uint32 pwdb_gid_to_alias_rid(uint32 gid)
-{
- uint32 alias_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_ALIAS);
- return alias_rid;
-}
-
-/*******************************************************************
- converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static uint32 pwdb_uid_to_user_rid(uint32 uid)
-{
- uint32 user_rid = ((((uid)*RID_MULTIPLIER) + 1000) | RID_TYPE_USER);
- return user_rid;
-}
-
-/******************************************************************
- converts SID + SID_NAME_USE type to a UNIX id. the Domain SID is,
- and can only be, our own SID.
- ********************************************************************/
-static BOOL pwdb_sam_sid_to_unixid(DOM_SID *sid, uint8 type, uint32 *id)
-{
- DOM_SID tmp_sid;
- uint32 rid;
-
- sid_copy(&tmp_sid, sid);
- sid_split_rid(&tmp_sid, &rid);
- if (!sid_equal(&global_sam_sid, &tmp_sid))
- {
- return False;
- }
-
- switch (type)
- {
- case SID_NAME_USER:
- {
- *id = pwdb_user_rid_to_uid(rid);
- return True;
- }
- case SID_NAME_ALIAS:
- {
- *id = pwdb_alias_rid_to_gid(rid);
- return True;
- }
- case SID_NAME_DOM_GRP:
- case SID_NAME_WKN_GRP:
- {
- *id = pwdb_group_rid_to_gid(rid);
- return True;
- }
- }
- return False;
-}
-
-/******************************************************************
- converts UNIX gid + SID_NAME_USE type to a SID. the Domain SID is,
- and can only be, our own SID.
- ********************************************************************/
-static BOOL pwdb_unixid_to_sam_sid(uint32 id, uint8 type, DOM_SID *sid)
-{
- sid_copy(sid, &global_sam_sid);
- switch (type)
- {
- case SID_NAME_USER:
- {
- sid_append_rid(sid, pwdb_uid_to_user_rid(id));
- return True;
- }
- case SID_NAME_ALIAS:
- {
- sid_append_rid(sid, pwdb_gid_to_alias_rid(id));
- return True;
- }
- case SID_NAME_DOM_GRP:
- case SID_NAME_WKN_GRP:
- {
- sid_append_rid(sid, pwdb_gid_to_group_rid(id));
- return True;
- }
- }
- return False;
-}
-
-/*******************************************************************
- Decides if a RID is a well known RID.
- ********************************************************************/
-static BOOL pwdb_rid_is_well_known(uint32 rid)
-{
- return (rid < 1000);
-}
-
-/*******************************************************************
- determines a rid's type. NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-static uint32 pwdb_rid_type(uint32 rid)
-{
- /* lkcl i understand that NT attaches an enumeration to a RID
- * such that it can be identified as either a user, group etc
- * type: SID_ENUM_TYPE.
- */
- if (pwdb_rid_is_well_known(rid))
- {
- /*
- * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
- * and DOMAIN_USER_RID_GUEST.
- */
- if (rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
- {
- return RID_TYPE_USER;
- }
- if (DOMAIN_GROUP_RID_ADMINS <= rid && rid <= DOMAIN_GROUP_RID_GUESTS)
- {
- return RID_TYPE_GROUP;
- }
- if (BUILTIN_ALIAS_RID_ADMINS <= rid && rid <= BUILTIN_ALIAS_RID_REPLICATOR)
- {
- return RID_TYPE_ALIAS;
- }
- }
- return (rid & RID_TYPE_MASK);
-}
-
-/*******************************************************************
- checks whether rid is a user rid. NOTE: THIS IS SOMETHING SPECIFIC TO SAMBA
- ********************************************************************/
-BOOL pwdb_rid_is_user(uint32 rid)
-{
- return pwdb_rid_type(rid) == RID_TYPE_USER;
-}
/**************************************************************************
Groupname map functionality. The code loads a groupname map file and
@@ -342,7 +176,7 @@ static BOOL make_mydomain_sid(DOM_NAME_MAP *grp, DOM_MAP_TYPE type)
}
}
- ret = pwdb_unixid_to_sam_sid(grp->unix_id, grp->type, &grp->sid);
+ ret = surs_unixid_to_sam_sid(grp->unix_id, grp->type, &grp->sid, False);
}
sid_to_string(sid_str, &grp->sid);
@@ -877,25 +711,21 @@ BOOL lookupsmbpwnam(const char *unix_usr_name, DOM_NAME_MAP *grp)
/************************************************************************
Routine to look up a remote nt name
*************************************************************************/
-static BOOL lookup_remote_ntname(const char *ntname, DOM_SID *sid, uint8 *type)
+static BOOL lookup_remote_ntname(const char *ntname, DOM_SID *sid, uint32 *type)
{
struct cli_state cli;
POLICY_HND lsa_pol;
fstring srv_name;
- extern struct ntuser_creds *usr_creds;
- struct ntuser_creds usr;
+ extern struct user_creds *usr_creds;
BOOL res3 = True;
BOOL res4 = True;
uint32 num_sids;
DOM_SID *sids;
- uint8 *types;
+ uint32 *types;
char *names[1];
- usr_creds = &usr;
-
- ZERO_STRUCT(usr);
- pwd_set_nullpwd(&usr.pwd);
+ usr_creds = NULL;
DEBUG(5,("lookup_remote_ntname: %s\n", ntname));
@@ -912,7 +742,7 @@ static BOOL lookup_remote_ntname(const char *ntname, DOM_SID *sid, uint8 *type)
/* lookup domain controller; receive a policy handle */
res3 = res3 ? lsa_open_policy( srv_name,
- &lsa_pol, True) : False;
+ &lsa_pol, True, 0x02000000) : False;
/* send lsa lookup sids call */
res4 = res3 ? lsa_lookup_names( &lsa_pol,
@@ -946,7 +776,7 @@ static BOOL lookup_remote_ntname(const char *ntname, DOM_SID *sid, uint8 *type)
/************************************************************************
Routine to look up a remote nt name
*************************************************************************/
-static BOOL get_sid_and_type(const char *fullntname, uint8 expected_type,
+static BOOL get_sid_and_type(const char *fullntname, uint32 expected_type,
DOM_NAME_MAP *gmep)
{
/*
@@ -977,7 +807,7 @@ static BOOL get_sid_and_type(const char *fullntname, uint8 expected_type,
{
return False;
}
- if (!pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid))
+ if (!surs_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid, False))
{
return False;
}
@@ -985,14 +815,6 @@ static BOOL get_sid_and_type(const char *fullntname, uint8 expected_type,
return True;
}
-/*
- * used by lookup functions below
- */
-
-static fstring nt_name;
-static fstring unix_name;
-static fstring nt_domain;
-
/*************************************************************************
looks up a uid, returns User Information.
*************************************************************************/
@@ -1003,10 +825,12 @@ BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep)
{
return True;
}
-#if 0
if (lp_server_role() != ROLE_DOMAIN_NONE)
-#endif
{
+ static fstring nt_name;
+ static fstring unix_name;
+ static fstring nt_domain;
+
gmep->nt_name = nt_name;
gmep->unix_name = unix_name;
gmep->nt_domain = nt_domain;
@@ -1040,7 +864,7 @@ BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep)
*/
gmep->nt_domain = global_sam_name;
- pwdb_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid);
+ surs_unixid_to_sam_sid(gmep->unix_id, gmep->type, &gmep->sid, False);
return True;
}
@@ -1055,6 +879,10 @@ BOOL lookupsmbpwuid(uid_t uid, DOM_NAME_MAP *gmep)
*************************************************************************/
BOOL lookupsmbpwntnam(const char *fullntname, DOM_NAME_MAP *gmep)
{
+ static fstring nt_name;
+ static fstring unix_name;
+ static fstring nt_domain;
+
DEBUG(10,("lookupsmbpwntnam: nt user name %s\n", fullntname));
if (!split_domain_name(fullntname, nt_domain, nt_name))
@@ -1111,6 +939,10 @@ BOOL lookupsmbpwsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
}
if (lp_server_role() != ROLE_DOMAIN_NONE)
{
+ static fstring nt_name;
+ static fstring unix_name;
+ static fstring nt_domain;
+
gmep->nt_name = nt_name;
gmep->unix_name = unix_name;
gmep->nt_domain = nt_domain;
@@ -1137,7 +969,7 @@ BOOL lookupsmbpwsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
gmep->type = SID_NAME_USER;
sid_copy(&gmep->sid, sid);
- if (!pwdb_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id))
+ if (!surs_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id, False))
{
return False;
}
@@ -1189,6 +1021,10 @@ BOOL lookupsmbgrpsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
}
if (lp_server_role() != ROLE_DOMAIN_NONE)
{
+ static fstring nt_name;
+ static fstring unix_name;
+ static fstring nt_domain;
+
gmep->nt_name = nt_name;
gmep->unix_name = unix_name;
gmep->nt_domain = nt_domain;
@@ -1230,7 +1066,7 @@ BOOL lookupsmbgrpsid(DOM_SID *sid, DOM_NAME_MAP *gmep)
}
sid_copy(&gmep->sid, sid);
- if (!pwdb_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id))
+ if (!surs_sam_sid_to_unixid(&gmep->sid, gmep->type, &gmep->unix_id, False))
{
return False;
}
@@ -1261,6 +1097,10 @@ BOOL lookupsmbgrpgid(gid_t gid, DOM_NAME_MAP *gmep)
}
if (lp_server_role() != ROLE_DOMAIN_NONE)
{
+ static fstring nt_name;
+ static fstring unix_name;
+ static fstring nt_domain;
+
gmep->nt_name = nt_name;
gmep->unix_name = unix_name;
gmep->nt_domain = nt_domain;
@@ -1305,6 +1145,7 @@ BOOL lookupsmbgrpgid(gid_t gid, DOM_NAME_MAP *gmep)
/* ... as a DOMAIN group. */
gmep->type = SID_NAME_DOM_GRP;
}
+ fstrcpy(gmep->nt_domain, global_sam_name);
fstrcpy(gmep->nt_name, gidtoname(gid));
fstrcpy(gmep->unix_name, gmep->nt_name);
@@ -1315,3 +1156,64 @@ BOOL lookupsmbgrpgid(gid_t gid, DOM_NAME_MAP *gmep)
return False;
}
+
+/****************************************************************************
+ does _both_ nt->unix and unix->unix username remappings.
+****************************************************************************/
+const struct passwd *map_nt_and_unix_username(const char *domain,
+ const char *ntuser,
+ char *unix_user, char *nt_user)
+{
+ DOM_NAME_MAP gmep;
+ fstring nt_username;
+
+ if (nt_user == NULL)
+ {
+ nt_user = nt_username;
+ }
+
+ memset(nt_user, 0, sizeof(nt_user));
+ if (domain != NULL)
+ {
+ slprintf(nt_user, sizeof(fstring), "%s\\%s",
+ domain, ntuser);
+ }
+ else
+ {
+ fstrcpy(nt_user, ntuser);
+ }
+
+#if 1
+
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
+
+ if (lp_server_role() != ROLE_DOMAIN_NONE)
+ {
+ if (lookupsmbpwntnam(nt_user, &gmep))
+ {
+ fstrcpy(unix_user, gmep.unix_name);
+ }
+ }
+#else
+ DEBUG(1,("map_nt_and_unix_username: NT->Unix map DISABLED\n"));
+
+ /* assume unix name is same as nt name */
+ fstrcpy(unix_user, ntuser);
+#endif
+
+ /*
+ * Pass the user through the unix -> unix user mapping
+ * function.
+ */
+
+ (void)map_username(unix_user);
+
+ /*
+ * Do any UNIX username case mangling.
+ */
+ return Get_Pwnam( unix_user, True);
+}
+
diff --git a/source/lib/doscalls.c b/source/lib/doscalls.c
index 2bd68d30974..2098b5e3508 100644
--- a/source/lib/doscalls.c
+++ b/source/lib/doscalls.c
@@ -82,15 +82,6 @@ char *dos_readdirname(DIR *p)
#endif
/*******************************************************************
- A chown() wrapper that calls dos_to_unix.
-********************************************************************/
-
-int dos_chown(char *fname, uid_t uid, gid_t gid)
-{
- return(sys_chown(dos_to_unix(fname,False),uid,gid));
-}
-
-/*******************************************************************
A stat() wrapper that calls dos_to_unix.
********************************************************************/
@@ -109,20 +100,14 @@ int dos_lstat(char *fname,SMB_STRUCT_STAT *sbuf)
}
/*******************************************************************
- Mkdir() that calls dos_to_unix.
- Cope with UNIXes that don't allow high order mode bits on mkdir.
- Patch from gcarter@lanier.com.
- Don't use this call unless you really want to access a file on
- disk. Use the vfs_ops.mkdir() function instead.
+ Mkdir() that calls dos_to_unix. Don't use this call unless you
+ really want to access a file on disk. Use the vfs_ops.mkdir()
+ function instead.
********************************************************************/
int dos_mkdir(char *dname,mode_t mode)
{
- int ret = mkdir(dos_to_unix(dname,False),mode);
- if(!ret)
- return(dos_chmod(dname,mode));
- else
- return ret;
+ return(mkdir(dos_to_unix(dname,False),mode));
}
/*******************************************************************
@@ -258,19 +243,11 @@ int copy_reg(char *source, const char *dest)
int dos_rename(char *from, char *to)
{
- int rcode;
pstring zfrom, zto;
pstrcpy (zfrom, dos_to_unix (from, False));
pstrcpy (zto, dos_to_unix (to, False));
- rcode = rename (zfrom, zto);
-
- if (errno == EXDEV)
- {
- /* Rename across filesystems needed. */
- rcode = copy_reg (zfrom, zto);
- }
- return rcode;
+ return file_rename(zfrom, zto);
}
/*******************************************************************
@@ -331,7 +308,7 @@ time_t dos_file_modtime(char *fname)
SMB_OFF_T dos_file_size(char *file_name)
{
- return get_file_size(dos_to_unix(file_name, False));
+ return file_size(dos_to_unix(file_name, False));
}
/*******************************************************************
@@ -417,7 +394,7 @@ char *dos_GetWd(char *path)
getwd_cache_init = True;
for (i=0;i<MAX_GETWDCACHE;i++)
{
- string_set(&ino_list[i].dos_path,"");
+ string_init(&ino_list[i].dos_path,"");
ino_list[i].valid = False;
}
}
@@ -427,7 +404,7 @@ char *dos_GetWd(char *path)
if (sys_stat(".",&st) == -1)
{
- DEBUG(0,("Very strange, couldn't stat \".\" path=%s\n", path));
+ DEBUG(0,("Very strange, couldn't stat \".\"\n"));
return(dos_getwd(path));
}
diff --git a/source/lib/fault.c b/source/lib/fault.c
index 6effaf7d7c6..fecd152f351 100644
--- a/source/lib/fault.c
+++ b/source/lib/fault.c
@@ -41,7 +41,8 @@ static void fault_report(int sig)
DEBUG(0,("INTERNAL ERROR: Signal %d in pid %d (%s)",sig,(int)getpid(),VERSION));
DEBUG(0,("\nPlease read the file BUGS.txt in the distribution\n"));
DEBUG(0,("===============================================================\n"));
-
+
+ sleep(10);
smb_panic("internal error");
if (cont_fn) {
@@ -52,6 +53,9 @@ static void fault_report(int sig)
#ifdef SIGBUS
CatchSignal(SIGBUS,SIGNAL_CAST SIG_DFL);
#endif
+#ifdef SIGILL
+ CatchSignal(SIGILL, SIGNAL_CAST SIG_DFL);
+#endif
return; /* this should cause a core dump */
}
exit(1);
@@ -78,6 +82,9 @@ void fault_setup(void (*fn)(void *))
#ifdef SIGBUS
CatchSignal(SIGBUS,SIGNAL_CAST sig_fault);
#endif
+#ifdef SIGILL
+ CatchSignal(SIGILL,SIGNAL_CAST sig_fault);
+#endif
}
diff --git a/source/lib/genrand.c b/source/lib/genrand.c
index a9698d4cd1b..ab0dadebcf2 100644
--- a/source/lib/genrand.c
+++ b/source/lib/genrand.c
@@ -58,8 +58,8 @@ static void do_dirrand(char *name, unsigned char *buf, int buf_len)
{
DIR *dp = opendir(name);
pstring fullname;
- int len_left;
- int fullname_len;
+ size_t len_left;
+ size_t fullname_len;
char *pos;
pstrcpy(fullname, name);
@@ -150,7 +150,7 @@ static uint32 do_reseed(unsigned char *md4_outbuf)
/* add in the root encrypted password. On any system where security is taken
seriously this will be secret */
- pw = sys_getpwnam("root");
+ pw = getpwnam("root");
if (pw && pw->pw_passwd) {
int i;
unsigned char md4_tmp[16];
diff --git a/source/lib/hmacmd5.c b/source/lib/hmacmd5.c
new file mode 100644
index 00000000000..4e1cd3c9fda
--- /dev/null
+++ b/source/lib/hmacmd5.c
@@ -0,0 +1,136 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Interface header: Scheduler service
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Andrew Tridgell 1992-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* taken direct from rfc2104 implementation and modified for suitable use
+ * for ntlmv2.
+ */
+
+#include "includes.h"
+
+/***********************************************************************
+ the rfc 2104 version of hmac_md5 initialisation.
+***********************************************************************/
+void hmac_md5_init_rfc2104(uchar* key, int key_len, HMACMD5Context *ctx)
+{
+ int i;
+
+ /* if key is longer than 64 bytes reset it to key=MD5(key) */
+ if (key_len > 64)
+ {
+ uchar tk[16];
+ struct MD5Context tctx;
+
+ MD5Init(&tctx);
+ MD5Update(&tctx, key, key_len);
+ MD5Final(tk, &tctx);
+
+ key = tk;
+ key_len = 16;
+ }
+
+ /* start out by storing key in pads */
+ bzero( ctx->k_ipad, sizeof ctx->k_ipad);
+ bzero( ctx->k_opad, sizeof ctx->k_opad);
+ bcopy( key, ctx->k_ipad, key_len);
+ bcopy( key, ctx->k_opad, key_len);
+
+ /* XOR key with ipad and opad values */
+ for (i=0; i<64; i++)
+ {
+ ctx->k_ipad[i] ^= 0x36;
+ ctx->k_opad[i] ^= 0x5c;
+ }
+
+ MD5Init(&ctx->ctx);
+ MD5Update(&ctx->ctx, ctx->k_ipad, 64);
+}
+
+/***********************************************************************
+ the microsoft version of hmac_md5 initialisation.
+***********************************************************************/
+void hmac_md5_init_limK_to_64(const uchar* key, int key_len,
+ HMACMD5Context *ctx)
+{
+ int i;
+
+ /* if key is longer than 64 bytes truncate it */
+ if (key_len > 64)
+ {
+ key_len = 64;
+ }
+
+ /* start out by storing key in pads */
+ bzero( ctx->k_ipad, sizeof ctx->k_ipad);
+ bzero( ctx->k_opad, sizeof ctx->k_opad);
+ bcopy( key, ctx->k_ipad, key_len);
+ bcopy( key, ctx->k_opad, key_len);
+
+ /* XOR key with ipad and opad values */
+ for (i=0; i<64; i++)
+ {
+ ctx->k_ipad[i] ^= 0x36;
+ ctx->k_opad[i] ^= 0x5c;
+ }
+
+ MD5Init(&ctx->ctx);
+ MD5Update(&ctx->ctx, ctx->k_ipad, 64);
+}
+
+/***********************************************************************
+ update hmac_md5 "inner" buffer
+***********************************************************************/
+void hmac_md5_update(const uchar* text, int text_len, HMACMD5Context *ctx)
+{
+ MD5Update(&ctx->ctx, text, text_len); /* then text of datagram */
+}
+
+/***********************************************************************
+ finish off hmac_md5 "inner" buffer and generate outer one.
+***********************************************************************/
+void hmac_md5_final(uchar *digest, HMACMD5Context *ctx)
+
+{
+ struct MD5Context ctx_o;
+
+ MD5Final(digest, &ctx->ctx);
+
+ MD5Init(&ctx_o);
+ MD5Update(&ctx_o, ctx->k_opad, 64);
+ MD5Update(&ctx_o, digest, 16);
+ MD5Final(digest, &ctx_o);
+}
+
+/***********************************************************
+ single function to calculate an HMAC MD5 digest from data.
+ use the microsoft hmacmd5 init method because the key is 16 bytes.
+************************************************************/
+void hmac_md5( uchar key[16], uchar* data, int data_len, uchar* digest)
+{
+ HMACMD5Context ctx;
+ hmac_md5_init_limK_to_64(key, 16, &ctx);
+ if (data_len != 0)
+ {
+ hmac_md5_update(data, data_len, &ctx);
+ }
+ hmac_md5_final(digest, &ctx);
+}
+
diff --git a/source/lib/interface.c b/source/lib/interface.c
index 92664279599..65d276021ce 100644
--- a/source/lib/interface.c
+++ b/source/lib/interface.c
@@ -21,225 +21,230 @@
#include "includes.h"
-#define MAX_INTERFACES 128
-
-static struct iface_struct *probed_ifaces;
-static int total_probed;
-
extern int DEBUGLEVEL;
struct in_addr ipzero;
struct in_addr allones_ip;
struct in_addr loopback_ip;
+static struct in_addr default_ip;
+static struct in_addr default_bcast;
+static struct in_addr default_nmask;
+static BOOL got_ip=False;
+static BOOL got_bcast=False;
+static BOOL got_nmask=False;
static struct interface *local_interfaces = NULL;
+struct interface *last_iface;
+
#define ALLONES ((uint32)0xFFFFFFFF)
#define MKBCADDR(_IP, _NM) ((_IP & _NM) | (_NM ^ ALLONES))
-#define MKNETADDR(_IP, _NM) (_IP & _NM)
-
/****************************************************************************
-Try and find an interface that matches an ip. If we cannot, return NULL
- **************************************************************************/
-static struct interface *iface_find(struct in_addr ip)
+calculate the default netmask for an address
+****************************************************************************/
+static void default_netmask(struct in_addr *inm, struct in_addr *iad)
{
- struct interface *i;
- if (zero_ip(ip)) return local_interfaces;
-
- for (i=local_interfaces;i;i=i->next)
- if (same_net(i->ip,ip,i->nmask)) return i;
-
- return NULL;
+ /*
+ ** Guess a netmask based on the class of the IP address given.
+ */
+ switch((ntohl(iad->s_addr) & 0xE0000000)) {
+ case 0x00000000: /* Class A addr */
+ case 0x20000000:
+ case 0x40000000:
+ case 0x60000000:
+ inm->s_addr = htonl(0xFF000000);
+ break;
+
+ case 0x80000000: /* Class B addr */
+ case 0xA0000000:
+ inm->s_addr = htonl(0xFFFF0000);
+ break;
+
+ case 0xC0000000: /* Class C addr */
+ inm->s_addr = htonl(0xFFFFFF00);
+ break;
+
+ default: /* ??? */
+ inm->s_addr = htonl(0xFFFFFFF0);
+ }
}
/****************************************************************************
-add an interface to the linked list of interfaces
+ get the broadcast address for our address
+(troyer@saifr00.ateng.az.honeywell.com)
****************************************************************************/
-static void add_interface(struct in_addr ip, struct in_addr nmask)
-{
- struct interface *iface;
- if (iface_find(ip)) {
- DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip)));
- return;
+static void get_broadcast(struct in_addr *if_ipaddr,
+ struct in_addr *if_bcast,
+ struct in_addr *if_nmask)
+{
+ uint32 nm;
+ short onbc;
+ short offbc;
+
+ /* get a default netmask and broadcast */
+ default_netmask(if_nmask, if_ipaddr);
+
+ get_netmask(if_ipaddr, if_nmask);
+
+ /* sanity check on the netmask */
+ nm = ntohl(if_nmask->s_addr);
+ onbc = 0;
+ offbc = 0;
+ while((onbc + offbc) < 32) {
+ if(nm & 0x80000000) {
+ onbc++;
+ if(offbc) {
+ /* already found an off bit, so mask
+ is wrong */
+ onbc = 34;
+ }
+ } else {
+ offbc++;
+ }
+ nm <<= 1;
}
-
- if (ip_equal(nmask, allones_ip)) {
- DEBUG(3,("not adding non-broadcast interface %s\n",inet_ntoa(ip)));
- return;
+ if ((onbc < 8)||(onbc == 34)) {
+ DEBUG(0,("Impossible netmask %s - using defaults\n",
+ inet_ntoa(*if_nmask)));
+ default_netmask(if_nmask, if_ipaddr);
}
- iface = (struct interface *)malloc(sizeof(*iface));
- if (!iface) return;
-
- ZERO_STRUCTPN(iface);
-
- iface->ip = ip;
- iface->nmask = nmask;
- iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
-
- DLIST_ADD(local_interfaces, iface);
-
- DEBUG(2,("added interface ip=%s ",inet_ntoa(iface->ip)));
- DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
- DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
+ /* derive the broadcast assuming a 1's broadcast, as this is what
+ all MS operating systems do, we have to comply even if the unix
+ box is setup differently */
+ if_bcast->s_addr = MKBCADDR(if_ipaddr->s_addr, if_nmask->s_addr);
+
+ DEBUG(4,("Derived broadcast address %s\n", inet_ntoa(*if_bcast)));
}
/****************************************************************************
-interpret a single element from a interfaces= config line
-
-This handles the following different forms:
-
-1) wildcard interface name
-2) DNS name
-3) IP/masklen
-4) ip/mask
-5) bcast/mask
+load a list of network interfaces
****************************************************************************/
-static void interpret_interface(char *token)
+static void interpret_interfaces(char *s, struct interface **interfaces,
+ char *description)
{
- struct in_addr ip, nmask;
- char *p;
- int i, added=0;
-
- ip = ipzero;
- nmask = ipzero;
-
- /* first check if it is an interface name */
- for (i=0;i<total_probed;i++) {
- if (fnmatch(token, probed_ifaces[i].name, 0) == 0) {
- add_interface(probed_ifaces[i].ip,
- probed_ifaces[i].netmask);
- added = 1;
- }
- }
- if (added) return;
-
- /* maybe it is a DNS name */
- p = strchr(token,'/');
- if (!p) {
- ip = *interpret_addr2(token);
- for (i=0;i<total_probed;i++) {
- if (ip.s_addr == probed_ifaces[i].ip.s_addr &&
- !ip_equal(allones_ip, probed_ifaces[i].netmask)) {
- add_interface(probed_ifaces[i].ip,
- probed_ifaces[i].netmask);
- return;
- }
- }
- DEBUG(2,("can't determine netmask for %s\n", token));
- return;
- }
-
- /* parse it into an IP address/netmasklength pair */
- *p++ = 0;
-
- ip = *interpret_addr2(token);
-
- if (strlen(p) > 2) {
- nmask = *interpret_addr2(p);
- } else {
- nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
- }
-
- /* maybe the first component was a broadcast address */
- if (ip.s_addr == MKBCADDR(ip.s_addr, nmask.s_addr) ||
- ip.s_addr == MKNETADDR(ip.s_addr, nmask.s_addr)) {
- for (i=0;i<total_probed;i++) {
- if (same_net(ip, probed_ifaces[i].ip, nmask)) {
- add_interface(probed_ifaces[i].ip, nmask);
- return;
- }
- }
- DEBUG(2,("Can't determine ip for broadcast address %s\n", token));
- return;
- }
-
- add_interface(ip, nmask);
+ char *ptr;
+ fstring token;
+ struct interface *iface;
+ struct in_addr ip;
+
+ ptr = s;
+ ipzero = *interpret_addr2("0.0.0.0");
+ allones_ip = *interpret_addr2("255.255.255.255");
+ loopback_ip = *interpret_addr2("127.0.0.1");
+
+ while (next_token(&ptr,token,NULL,sizeof(token))) {
+ /* parse it into an IP address/netmasklength pair */
+ char *p = strchr(token,'/');
+ if (p) *p++ = 0;
+
+ ip = *interpret_addr2(token);
+
+ /* maybe we already have it listed */
+ {
+ struct interface *i;
+ for (i=(*interfaces);i;i=i->next)
+ if (ip_equal(ip,i->ip)) break;
+ if (i) continue;
+ }
+
+ iface = (struct interface *)malloc(sizeof(*iface));
+ if (!iface) return;
+
+ iface->ip = ip;
+
+ if (p) {
+ if (strlen(p) > 2)
+ iface->nmask = *interpret_addr2(p);
+ else
+ iface->nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES));
+ } else {
+ default_netmask(&iface->nmask,&iface->ip);
+ }
+ iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
+ iface->next = NULL;
+
+ if (!(*interfaces)) {
+ (*interfaces) = iface;
+ } else {
+ last_iface->next = iface;
+ }
+ last_iface = iface;
+ DEBUG(2,("Added %s ip=%s ",description,inet_ntoa(iface->ip)));
+ DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
+ DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
+ }
+
+ if (*interfaces) return;
+
+ /* setup a default interface */
+ iface = (struct interface *)malloc(sizeof(*iface));
+ if (!iface) return;
+
+ iface->next = NULL;
+
+ if (got_ip) {
+ iface->ip = default_ip;
+ } else {
+ get_myname(NULL,&iface->ip);
+ }
+
+ if (got_bcast) {
+ iface->bcast = default_bcast;
+ } else {
+ get_broadcast(&iface->ip,&iface->bcast,&iface->nmask);
+ }
+
+ if (got_nmask) {
+ iface->nmask = default_nmask;
+ iface->bcast.s_addr = MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr);
+ }
+
+ if (iface->bcast.s_addr != MKBCADDR(iface->ip.s_addr, iface->nmask.s_addr)) {
+ DEBUG(2,("Warning: inconsistant interface %s\n",inet_ntoa(iface->ip)));
+ }
+
+ iface->next = NULL;
+ (*interfaces) = last_iface = iface;
+
+ DEBUG(2,("Added interface ip=%s ",inet_ntoa(iface->ip)));
+ DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast)));
+ DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask)));
}
/****************************************************************************
-load the list of network interfaces
+load the remote and local interfaces
****************************************************************************/
void load_interfaces(void)
{
- char *ptr;
- fstring token;
- int i;
- struct iface_struct ifaces[MAX_INTERFACES];
-
- ptr = lp_interfaces();
-
- ipzero = *interpret_addr2("0.0.0.0");
- allones_ip = *interpret_addr2("255.255.255.255");
- loopback_ip = *interpret_addr2("127.0.0.1");
-
- if (probed_ifaces) {
- free(probed_ifaces);
- probed_ifaces = NULL;
- }
-
- /* dump the current interfaces if any */
- while (local_interfaces) {
- struct interface *iface = local_interfaces;
- DLIST_REMOVE(local_interfaces, local_interfaces);
- ZERO_STRUCTPN(iface);
- free(iface);
- }
-
- /* probe the kernel for interfaces */
- total_probed = get_interfaces(ifaces, MAX_INTERFACES);
-
- if (total_probed > 0) {
- probed_ifaces = memdup(ifaces, sizeof(ifaces[0])*total_probed);
- }
-
- /* if we don't have a interfaces line then use all broadcast capable
- interfaces except loopback */
- if (!ptr || !*ptr) {
- if (total_probed <= 0) {
- DEBUG(0,("ERROR: Could not determine network interfaces, you must use a interfaces config line\n"));
- exit(1);
- }
- for (i=0;i<total_probed;i++) {
- if (probed_ifaces[i].netmask.s_addr != allones_ip.s_addr &&
- probed_ifaces[i].ip.s_addr != loopback_ip.s_addr) {
- add_interface(probed_ifaces[i].ip,
- probed_ifaces[i].netmask);
- }
- }
- return;
- }
-
- while (next_token(&ptr,token,NULL,sizeof(token))) {
- interpret_interface(token);
- }
-
- if (!local_interfaces) {
- DEBUG(0,("WARNING: no network interfaces found\n"));
- }
+ /* add the machine's interfaces to local interface structure*/
+ interpret_interfaces(lp_interfaces(), &local_interfaces,"interface");
}
/****************************************************************************
-return True if the list of probed interfaces has changed
-****************************************************************************/
-BOOL interfaces_changed(void)
+ override the defaults
+ **************************************************************************/
+void iface_set_default(char *ip,char *bcast,char *nmask)
{
- int n;
- struct iface_struct ifaces[MAX_INTERFACES];
-
- n = get_interfaces(ifaces, MAX_INTERFACES);
-
- if (n != total_probed ||
- memcmp(ifaces, probed_ifaces, sizeof(ifaces[0])*n)) {
- return True;
- }
-
- return False;
+ if (ip) {
+ got_ip = True;
+ default_ip = *interpret_addr2(ip);
+ }
+
+ if (bcast) {
+ got_bcast = True;
+ default_bcast = *interpret_addr2(bcast);
+ }
+
+ if (nmask) {
+ got_nmask = True;
+ default_nmask = *interpret_addr2(nmask);
+ }
}
@@ -248,10 +253,10 @@ BOOL interfaces_changed(void)
**************************************************************************/
BOOL ismyip(struct in_addr ip)
{
- struct interface *i;
- for (i=local_interfaces;i;i=i->next)
- if (ip_equal(i->ip,ip)) return True;
- return False;
+ struct interface *i;
+ for (i=local_interfaces;i;i=i->next)
+ if (ip_equal(i->ip,ip)) return True;
+ return False;
}
/****************************************************************************
@@ -259,13 +264,11 @@ BOOL ismyip(struct in_addr ip)
**************************************************************************/
BOOL is_local_net(struct in_addr from)
{
- struct interface *i;
- for (i=local_interfaces;i;i=i->next) {
- if((from.s_addr & i->nmask.s_addr) ==
- (i->ip.s_addr & i->nmask.s_addr))
- return True;
- }
- return False;
+ struct interface *i;
+ for (i=local_interfaces;i;i=i->next)
+ if((from.s_addr & i->nmask.s_addr) == (i->ip.s_addr & i->nmask.s_addr))
+ return True;
+ return False;
}
/****************************************************************************
@@ -273,12 +276,12 @@ BOOL is_local_net(struct in_addr from)
**************************************************************************/
int iface_count(void)
{
- int ret = 0;
- struct interface *i;
+ int ret = 0;
+ struct interface *i;
- for (i=local_interfaces;i;i=i->next)
- ret++;
- return ret;
+ for (i=local_interfaces;i;i=i->next)
+ ret++;
+ return ret;
}
/****************************************************************************
@@ -286,12 +289,12 @@ int iface_count(void)
**************************************************************************/
BOOL we_are_multihomed(void)
{
- static int multi = -1;
+ static int multi = -1;
- if(multi == -1)
- multi = (iface_count() > 1 ? True : False);
-
- return multi;
+ if(multi == -1)
+ multi = (iface_count() > 1 ? True : False);
+
+ return multi;
}
/****************************************************************************
@@ -299,13 +302,13 @@ BOOL we_are_multihomed(void)
**************************************************************************/
struct interface *get_interface(int n)
{
- struct interface *i;
+ struct interface *i;
- for (i=local_interfaces;i && n;i=i->next)
- n--;
+ for (i=local_interfaces;i && n;i=i->next)
+ n--;
- if (i) return i;
- return NULL;
+ if (i) return i;
+ return NULL;
}
/****************************************************************************
@@ -313,27 +316,27 @@ struct interface *get_interface(int n)
**************************************************************************/
struct in_addr *iface_n_ip(int n)
{
- struct interface *i;
+ struct interface *i;
- for (i=local_interfaces;i && n;i=i->next)
- n--;
+ for (i=local_interfaces;i && n;i=i->next)
+ n--;
- if (i) return &i->ip;
- return NULL;
+ if (i) return &i->ip;
+ return NULL;
}
/****************************************************************************
- return bcast of the Nth interface
+Try and find an interface that matches an ip. If we cannot, return NULL
**************************************************************************/
-struct in_addr *iface_n_bcast(int n)
+static struct interface *iface_find(struct in_addr ip)
{
- struct interface *i;
-
- for (i=local_interfaces;i && n;i=i->next)
- n--;
+ struct interface *i;
+ if (zero_ip(ip)) return local_interfaces;
- if (i) return &i->bcast;
- return NULL;
+ for (i=local_interfaces;i;i=i->next)
+ if (same_net(i->ip,ip,i->nmask)) return i;
+
+ return NULL;
}
@@ -365,12 +368,15 @@ unsigned iface_hash(void)
struct in_addr *iface_bcast(struct in_addr ip)
{
- struct interface *i = iface_find(ip);
- return(i ? &i->bcast : &local_interfaces->bcast);
+ struct interface *i = iface_find(ip);
+ return(i ? &i->bcast : &local_interfaces->bcast);
}
struct in_addr *iface_ip(struct in_addr ip)
{
- struct interface *i = iface_find(ip);
- return(i ? &i->ip : &local_interfaces->ip);
+ struct interface *i = iface_find(ip);
+ return(i ? &i->ip : &local_interfaces->ip);
}
+
+
+
diff --git a/source/lib/kanji.c b/source/lib/kanji.c
index 43b22c19cce..871a4a059c8 100644
--- a/source/lib/kanji.c
+++ b/source/lib/kanji.c
@@ -80,8 +80,6 @@ int (*is_multibyte_char_1)(char) = is_kanji_multibyte_char_1;
#endif /* KANJI */
-BOOL global_is_multibyte_codepage = False;
-
/* jis si/so sequence */
static char jis_kso = JIS_KSO;
static char jis_ksi = JIS_KSI;
@@ -379,7 +377,7 @@ static size_t skip_generic_multibyte_char(char c)
********************************************************************/
/* convesion buffer */
-static char cvtbuf[2*sizeof(pstring)];
+static char cvtbuf[1024];
/*******************************************************************
EUC <-> SJIS
@@ -414,7 +412,7 @@ static char *sj_to_euc(char *from, BOOL overwrite)
char *save;
save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
+ for (out = cvtbuf; *from;) {
if (is_shift_jis (*from)) {
int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
@@ -447,7 +445,7 @@ static char *euc_to_sj(char *from, BOOL overwrite)
char *save;
save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
+ for (out = cvtbuf; *from; ) {
if (is_euc (*from)) {
int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
*out++ = (code >> 8) & 0xff;
@@ -498,51 +496,48 @@ static int jis2sjis(int hi, int lo)
static char *jis8_to_sj(char *from, BOOL overwrite)
{
- char *out;
- int shifted;
- char *save;
+ char *out;
+ int shifted;
+ char *save;
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
- if (is_esc (*from)) {
- if (is_so1 (from[1]) && is_so2 (from[2])) {
- shifted = _KJ_KANJI;
- from += 3;
- } else if (is_si1 (from[1]) && is_si2 (from[2])) {
- shifted = _KJ_ROMAN;
- from += 3;
- } else { /* sequence error */
- goto normal;
- }
+ shifted = _KJ_ROMAN;
+ save = (char *) from;
+ for (out = cvtbuf; *from;) {
+ if (is_esc (*from)) {
+ if (is_so1 (from[1]) && is_so2 (from[2])) {
+ shifted = _KJ_KANJI;
+ from += 3;
+ } else if (is_si1 (from[1]) && is_si2 (from[2])) {
+ shifted = _KJ_ROMAN;
+ from += 3;
+ } else { /* sequence error */
+ goto normal;
+ }
+ } else {
+ normal:
+ switch (shifted) {
+ default:
+ case _KJ_ROMAN:
+ *out++ = *from++;
+ break;
+ case _KJ_KANJI:
+ {
+ int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code;
+ from += 2;
+ }
+ break;
+ }
+ }
+ }
+ *out = 0;
+ if (overwrite) {
+ pstrcpy (save, (char *) cvtbuf);
+ return save;
} else {
-
-normal:
-
- switch (shifted) {
- default:
- case _KJ_ROMAN:
- *out++ = *from++;
- break;
- case _KJ_KANJI:
- {
- int code = jis2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
- break;
- }
- }
+ return cvtbuf;
}
- }
-
- *out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
}
/*******************************************************************
@@ -552,55 +547,54 @@ normal:
static char *sj_to_jis8(char *from, BOOL overwrite)
{
- char *out;
- int shifted;
- char *save;
+ char *out;
+ int shifted;
+ char *save;
- shifted = _KJ_ROMAN;
- save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
- if (is_shift_jis (*from)) {
- int code;
- switch (shifted) {
- case _KJ_ROMAN: /* to KANJI */
- *out++ = jis_esc;
- *out++ = jis_so1;
- *out++ = jis_kso;
- shifted = _KJ_KANJI;
- break;
- }
- code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
- *out++ = (code >> 8) & 0xff;
- *out++ = code;
- from += 2;
+ shifted = _KJ_ROMAN;
+ save = (char *) from;
+ for (out = cvtbuf; *from; ) {
+ if (is_shift_jis (*from)) {
+ int code;
+ switch (shifted) {
+ case _KJ_ROMAN: /* to KANJI */
+ *out++ = jis_esc;
+ *out++ = jis_so1;
+ *out++ = jis_kso;
+ shifted = _KJ_KANJI;
+ break;
+ }
+ code = sjis2jis ((int) from[0] & 0xff, (int) from[1] & 0xff);
+ *out++ = (code >> 8) & 0xff;
+ *out++ = code;
+ from += 2;
+ } else {
+ switch (shifted) {
+ case _KJ_KANJI: /* to ROMAN/KANA */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_ksi;
+ shifted = _KJ_ROMAN;
+ break;
+ }
+ *out++ = *from++;
+ }
+ }
+ switch (shifted) {
+ case _KJ_KANJI: /* to ROMAN/KANA */
+ *out++ = jis_esc;
+ *out++ = jis_si1;
+ *out++ = jis_ksi;
+ shifted = _KJ_ROMAN;
+ break;
+ }
+ *out = 0;
+ if (overwrite) {
+ pstrcpy (save, (char *) cvtbuf);
+ return save;
} else {
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN/KANA */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- shifted = _KJ_ROMAN;
- break;
- }
- *out++ = *from++;
+ return cvtbuf;
}
- }
-
- switch (shifted) {
- case _KJ_KANJI: /* to ROMAN/KANA */
- *out++ = jis_esc;
- *out++ = jis_si1;
- *out++ = jis_ksi;
- shifted = _KJ_ROMAN;
- break;
- }
- *out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
}
/*******************************************************************
@@ -615,7 +609,7 @@ static char *jis7_to_sj(char *from, BOOL overwrite)
shifted = _KJ_ROMAN;
save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
+ for (out = cvtbuf; *from;) {
if (is_esc (*from)) {
if (is_so1 (from[1]) && is_so2 (from[2])) {
shifted = _KJ_KANJI;
@@ -674,7 +668,7 @@ static char *sj_to_jis7(char *from, BOOL overwrite)
shifted = _KJ_ROMAN;
save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
+ for (out = cvtbuf; *from; ) {
if (is_shift_jis (*from)) {
int code;
switch (shifted) {
@@ -742,7 +736,6 @@ static char *sj_to_jis7(char *from, BOOL overwrite)
Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes
return converted buffer
********************************************************************/
-
static char *junet_to_sj(char *from, BOOL overwrite)
{
char *out;
@@ -751,7 +744,7 @@ static char *junet_to_sj(char *from, BOOL overwrite)
shifted = _KJ_ROMAN;
save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
+ for (out = cvtbuf; *from;) {
if (is_esc (*from)) {
if (is_so1 (from[1]) && is_so2 (from[2])) {
shifted = _KJ_KANJI;
@@ -807,7 +800,7 @@ static char *sj_to_junet(char *from, BOOL overwrite)
shifted = _KJ_ROMAN;
save = (char *) from;
- for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
+ for (out = cvtbuf; *from; ) {
if (is_shift_jis (*from)) {
int code;
switch (shifted) {
@@ -874,7 +867,7 @@ static char *hex_to_sj(char *from, BOOL overwrite)
sp = (char *) from;
dp = cvtbuf;
- while (*sp && (dp - cvtbuf < sizeof(cvtbuf)-3)) {
+ while (*sp) {
if (*sp == hex_tag && isxdigit((int)sp[1]) && isxdigit((int)sp[2])) {
*dp++ = (hex2bin (sp[1])<<4) | (hex2bin (sp[2]));
sp += 3;
@@ -899,7 +892,7 @@ static char *sj_to_hex(char *from, BOOL overwrite)
sp = (unsigned char*) from;
dp = (unsigned char*) cvtbuf;
- while (*sp && (((char *)dp)- cvtbuf < sizeof(cvtbuf)-7)) {
+ while (*sp) {
if (is_kana(*sp)) {
*dp++ = hex_tag;
*dp++ = bin2hex (((*sp)>>4)&0x0f);
@@ -936,7 +929,7 @@ static char *cap_to_sj(char *from, BOOL overwrite)
sp = (char *) from;
dp = cvtbuf;
- while (*sp && (dp- cvtbuf < sizeof(cvtbuf)-2)) {
+ while (*sp) {
/*
* The only change between this and hex_to_sj is here. sj_to_cap only
* translates characters greater or equal to 0x80 - make sure that here
@@ -967,7 +960,7 @@ static char *sj_to_cap(char *from, BOOL overwrite)
sp = (unsigned char*) from;
dp = (unsigned char*) cvtbuf;
- while (*sp && (((char *)dp) - cvtbuf < sizeof(cvtbuf)-4)) {
+ while (*sp) {
if (*sp >= 0x80) {
*dp++ = hex_tag;
*dp++ = bin2hex (((*sp)>>4)&0x0f);
@@ -1165,6 +1158,17 @@ static BOOL not_multibyte_char_1(char c)
}
/*******************************************************************
+ Function to determine if we are in a multibyte code page.
+*******************************************************************/
+
+static BOOL is_multibyte_codepage_val = False;
+
+BOOL is_multibyte_codepage(void)
+{
+ return is_multibyte_codepage_val;
+}
+
+/*******************************************************************
Setup the function pointers for the functions that are replaced
when multi-byte codepages are used.
@@ -1184,7 +1188,7 @@ void initialize_multibyte_vectors( int client_codepage)
multibyte_strtok = sj_strtok;
_skip_multibyte_char = skip_kanji_multibyte_char;
is_multibyte_char_1 = is_kanji_multibyte_char_1;
- global_is_multibyte_codepage = True;
+ is_multibyte_codepage_val = True;
break;
case HANGUL_CODEPAGE:
multibyte_strchr = generic_multibyte_strchr;
@@ -1193,7 +1197,7 @@ void initialize_multibyte_vectors( int client_codepage)
multibyte_strtok = generic_multibyte_strtok;
_skip_multibyte_char = skip_generic_multibyte_char;
is_multibyte_char_1 = hangul_is_multibyte_char_1;
- global_is_multibyte_codepage = True;
+ is_multibyte_codepage_val = True;
break;
case BIG5_CODEPAGE:
multibyte_strchr = generic_multibyte_strchr;
@@ -1202,7 +1206,7 @@ void initialize_multibyte_vectors( int client_codepage)
multibyte_strtok = generic_multibyte_strtok;
_skip_multibyte_char = skip_generic_multibyte_char;
is_multibyte_char_1 = big5_is_multibyte_char_1;
- global_is_multibyte_codepage = True;
+ is_multibyte_codepage_val = True;
break;
case SIMPLIFIED_CHINESE_CODEPAGE:
multibyte_strchr = generic_multibyte_strchr;
@@ -1211,7 +1215,7 @@ void initialize_multibyte_vectors( int client_codepage)
multibyte_strtok = generic_multibyte_strtok;
_skip_multibyte_char = skip_generic_multibyte_char;
is_multibyte_char_1 = simpch_is_multibyte_char_1;
- global_is_multibyte_codepage = True;
+ is_multibyte_codepage_val = True;
break;
/*
* Single char size code page.
@@ -1223,7 +1227,7 @@ void initialize_multibyte_vectors( int client_codepage)
multibyte_strtok = (char *(*)(char *, const char *)) strtok;
_skip_multibyte_char = skip_non_multibyte_char;
is_multibyte_char_1 = not_multibyte_char_1;
- global_is_multibyte_codepage = False;
+ is_multibyte_codepage_val = False;
break;
}
}
diff --git a/source/lib/md4.c b/source/lib/md4.c
index 30f2b6b8c6b..56c9e02ffbe 100644
--- a/source/lib/md4.c
+++ b/source/lib/md4.c
@@ -101,7 +101,7 @@ static void mdfour64(uint32 *M)
X[j] = 0;
}
-static void copy64(uint32 *M, unsigned char *in)
+static void copy64(uint32 *M, const unsigned char *in)
{
int i;
@@ -119,7 +119,7 @@ static void copy4(unsigned char *out,uint32 x)
}
/* produce a md4 message digest from data of length n bytes */
-void mdfour(unsigned char *out, unsigned char *in, int n)
+void mdfour(unsigned char *out, const unsigned char *in, int n)
{
unsigned char buf[128];
uint32 M[16];
diff --git a/source/lib/md5.c b/source/lib/md5.c
new file mode 100644
index 00000000000..cff7bef034b
--- /dev/null
+++ b/source/lib/md5.c
@@ -0,0 +1,315 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Copyright (C) Andrew Tridgell 1992-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* This code has been heavily hacked by Tatu Ylonen <ylo@cs.hut.fi> to
+ make it compile on machines like Cray that don't have a 32 bit integer
+ type. */
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include "includes.h"
+
+#ifndef _GETPUT_H
+/*
+
+getput.h
+
+Author: Tatu Ylonen <ylo@cs.hut.fi>
+
+Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ All rights reserved
+
+Created: Wed Jun 28 22:36:30 1995 ylo
+
+Macros for storing and retrieving data in msb first and lsb first order.
+
+*/
+
+/*------------ macros for storing/extracting msb first words -------------*/
+
+#define GET_32BIT(cp) (((uint32)(uchar)(cp)[0] << 24) | \
+ ((uint32)(uchar)(cp)[1] << 16) | \
+ ((uint32)(uchar)(cp)[2] << 8) | \
+ ((uint32)(uchar)(cp)[3]))
+
+#define GET_16BIT(cp) (((uint32)(uchar)(cp)[0] << 8) | \
+ ((uint32)(uchar)(cp)[1]))
+
+#define PUT_32BIT(cp, value) do { \
+ (cp)[0] = (value) >> 24; \
+ (cp)[1] = (value) >> 16; \
+ (cp)[2] = (value) >> 8; \
+ (cp)[3] = (value); } while (0)
+
+#define PUT_16BIT(cp, value) do { \
+ (cp)[0] = (value) >> 8; \
+ (cp)[1] = (value); } while (0)
+
+/*------------ macros for storing/extracting lsb first words -------------*/
+
+#define GET_32BIT_LSB_FIRST(cp) \
+ (((uint32)(uchar)(cp)[0]) | \
+ ((uint32)(uchar)(cp)[1] << 8) | \
+ ((uint32)(uchar)(cp)[2] << 16) | \
+ ((uint32)(uchar)(cp)[3] << 24))
+
+#define GET_16BIT_LSB_FIRST(cp) \
+ (((uint32)(uchar)(cp)[0]) | \
+ ((uint32)(uchar)(cp)[1] << 8))
+
+#define PUT_32BIT_LSB_FIRST(cp, value) do { \
+ (cp)[0] = (value); \
+ (cp)[1] = (value) >> 8; \
+ (cp)[2] = (value) >> 16; \
+ (cp)[3] = (value) >> 24; } while (0)
+
+#define PUT_16BIT_LSB_FIRST(cp, value) do { \
+ (cp)[0] = (value); \
+ (cp)[1] = (value) >> 8; } while (0)
+
+#endif /* _GETPUT_H */
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Init(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Update(struct MD5Context *ctx, uchar const *buf, unsigned len)
+{
+ uint32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = (t + ((uint32)len << 3)) & 0xffffffff) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ uchar *p = ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ MD5Transform(ctx->buf, ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ MD5Transform(ctx->buf, ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Final(uchar digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ uchar *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ MD5Transform(ctx->buf, ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+
+ /* Append length in bits and transform */
+ PUT_32BIT_LSB_FIRST(ctx->in + 56, ctx->bits[0]);
+ PUT_32BIT_LSB_FIRST(ctx->in + 60, ctx->bits[1]);
+
+ MD5Transform(ctx->buf, ctx->in);
+ PUT_32BIT_LSB_FIRST(digest, ctx->buf[0]);
+ PUT_32BIT_LSB_FIRST(digest + 4, ctx->buf[1]);
+ PUT_32BIT_LSB_FIRST(digest + 8, ctx->buf[2]);
+ PUT_32BIT_LSB_FIRST(digest + 12, ctx->buf[3]);
+ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Transform(uint32 buf[4], const uchar inext[64])
+{
+ register uint32 a, b, c, d, i;
+ uint32 in[16];
+
+ for (i = 0; i < 16; i++)
+ in[i] = GET_32BIT_LSB_FIRST(inext + 4 * i);
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+#endif
diff --git a/source/lib/membuffer.c b/source/lib/membuffer.c
new file mode 100644
index 00000000000..fc4a88aeadf
--- /dev/null
+++ b/source/lib/membuffer.c
@@ -0,0 +1,393 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba memory buffer functions
+ Copyright (C) Andrew Tridgell 1992-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*******************************************************************
+ *
+ * Description: memory buffer / stream management.
+ * Author : Luke K C Leighton
+ * Created : Dec 1997
+ *
+
+ * this module is intended for use in streaming data in and out of
+ * buffers. it is intended that a single data stream be subdivided
+ * into manageable sections.
+
+ * for example, an rpc header contains a length field, but until the
+ * data has been created, the length is unknown. using this module,
+ * the header section can be tacked onto the front of the data memory
+ * list once the size of the data section preceding it is known.
+
+ * the "margin" can be used to over-run and retrospectively lengthen
+ * the buffer. this is to save time in some of the loops, where it is
+ * not particularly desirable to realloc data by 1, 2 or 4 bytes
+ * repetitively...
+
+ * each memory buffer contains a start and end offset. the end of
+ * one buffer should equal to the start of the next in the chain.
+ * (end - start = len, instead of end - start + 1 = len)
+
+ * the debug log levels are very high in some of the routines: you
+ * have no idea how boring it gets staring at debug output from these
+
+ ********************************************************************/
+
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ initialise a memory buffer.
+ ********************************************************************/
+void mem_init(struct mem_buf *buf, int margin)
+{
+ buf->struct_start = 0xfefefefe;
+ buf->dynamic = True;
+ buf->data = NULL;
+ buf->data_size = 0;
+ buf->data_used = 0;
+
+ buf->margin = margin;
+
+ buf->next = NULL;
+
+ buf->offset.start = 0;
+ buf->offset.end = 0x0;
+ buf->struct_end = 0xdcdcdcdc;
+ CHECK_STRUCT(buf);
+}
+
+/*******************************************************************
+ initialise a memory buffer.
+
+ dynamic indicates memory has been dynamically allocated.
+ if mem_free is called, the memory will be freed.
+ ********************************************************************/
+void mem_create(struct mem_buf *buf, char *data, int offset, int size, int margin, BOOL dynamic)
+{
+ buf->struct_start = 0xfefefefe;
+ buf->dynamic = dynamic;
+ buf->data = data;
+ buf->data_size = size;
+ buf->data_used = size;
+
+ buf->margin = margin;
+
+ buf->next = NULL;
+
+ buf->offset.start = offset;
+ buf->offset.end = offset + size;
+ buf->struct_end = 0xdcdcdcdc;
+ CHECK_STRUCT(buf);
+}
+
+/*******************************************************************
+ allocate a memory buffer. assume it's empty
+ ********************************************************************/
+BOOL mem_alloc_data(struct mem_buf *buf, int size)
+{
+ CHECK_STRUCT(buf);
+ if (!buf->dynamic)
+ {
+ DEBUG(3,("mem_alloc_data: warning - memory buffer type is set to static\n"));
+ }
+
+ buf->data_size = size + buf->margin;
+ buf->data_used = size;
+
+ buf->data = (char*)malloc(buf->data_size);
+
+ if (buf->data == NULL && size != 0)
+ {
+ DEBUG(3,("mem_alloc: could not malloc size %d\n",
+ buf->data_size));
+ mem_init(buf, buf->margin);
+
+ return False;
+ }
+
+ bzero(buf->data, buf->data_size);
+ buf->offset.end = buf->offset.start + size;
+
+ CHECK_STRUCT(buf);
+ return True;
+}
+
+/*******************************************************************
+ search for a memory buffer that falls within the specified offset
+ ********************************************************************/
+static struct mem_buf *mem_find(struct mem_buf *buf, uint32 offset)
+{
+ struct mem_buf *f;
+ if (buf == NULL) return False;
+
+ f = buf;
+
+ CHECK_STRUCT(f);
+ DEBUG(200,("mem_find: data[%d..%d] offset: %d\n",
+ f->offset.start, f->offset.end, offset));
+
+ while (f != NULL && offset >= f->offset.end)
+ {
+ DEBUG(200,("mem_find: next[%d..%d]\n",
+ f->offset.start, f->offset.end));
+
+ f = f->next;
+ }
+
+ if (f != NULL)
+ {
+ DEBUG(200,("mem_find: found data[%d..%d]\n",
+ f->offset.start, f->offset.end));
+ }
+
+ return f;
+}
+
+/*******************************************************************
+ allocates a memory buffer structure
+ ********************************************************************/
+BOOL mem_buf_copy(char *copy_into, struct mem_buf *buf,
+ uint32 offset, uint32 len)
+{
+ uint32 end = offset + len;
+ char *q = NULL;
+ uint32 data_len = mem_buf_len(buf);
+ uint32 start_offset = offset;
+ struct mem_buf *bcp = buf;
+
+ if (buf == NULL || copy_into == NULL) return False;
+
+ CHECK_STRUCT(buf);
+ DEBUG(200,("mem_buf_copy: data[%d..%d] offset %d len %d\n",
+ buf->offset.start, data_len, offset, len));
+
+ /* there's probably an off-by-one bug, here, and i haven't even tested the code :-) */
+ while (offset < end && ((q = mem_data(bcp, offset)) != NULL))
+ {
+ uint32 copy_len;
+ bcp = mem_find(bcp, offset);
+ copy_len = bcp->offset.end - offset;
+
+ DEBUG(200,("\tdata[%d..%d] - offset %d len %d\n",
+ bcp->offset.start, bcp->offset.end,
+ offset, copy_len));
+
+ memcpy(copy_into, q, copy_len);
+
+ offset += copy_len;
+ copy_into += copy_len;
+ }
+
+ if (bcp != NULL)
+ {
+ DEBUG(200,("mem_buf_copy: copied %d bytes\n", offset - start_offset));
+ }
+ else
+ {
+ DEBUG(200,("mem_buf_copy: failed\n"));
+ }
+
+ return buf != NULL;
+}
+
+/*******************************************************************
+ allocates a memory buffer structure
+ ********************************************************************/
+BOOL mem_buf_init(struct mem_buf **buf, uint32 margin)
+{
+ if (buf == NULL) return False;
+
+ if ((*buf) == NULL)
+ {
+ (*buf) = (struct mem_buf*)malloc(sizeof(**buf));
+ if ((*buf) != NULL)
+ {
+ mem_init((*buf), margin);
+ return True;
+ }
+ }
+ else
+ {
+ CHECK_STRUCT(*buf);
+ (*buf)->margin = margin;
+ return True;
+ }
+ return False;
+}
+
+/*******************************************************************
+ frees up a memory buffer.
+ ********************************************************************/
+void mem_buf_free(struct mem_buf **buf)
+{
+ if (buf == NULL) return;
+ if ((*buf) == NULL) return;
+
+ CHECK_STRUCT(*buf);
+ mem_free_data(*buf); /* delete memory data */
+ free(*buf); /* delete item */
+ (*buf) = NULL;
+}
+
+/*******************************************************************
+ frees a memory buffer chain. assumes that all items are malloced.
+ ********************************************************************/
+static void mem_free_chain(struct mem_buf **buf)
+{
+ if (buf == NULL) return;
+ if ((*buf) == NULL) return;
+
+ CHECK_STRUCT(*buf);
+ if ((*buf)->next != NULL)
+ {
+ mem_free_chain(&((*buf)->next)); /* delete all other items in chain */
+ }
+ mem_buf_free(buf);
+}
+
+/*******************************************************************
+ frees a memory buffer.
+ ********************************************************************/
+void mem_free_data(struct mem_buf *buf)
+{
+ if (buf == NULL) return;
+
+ if (buf->data != NULL && buf->dynamic)
+ {
+ CHECK_STRUCT(buf);
+ free(buf->data); /* delete data in this structure */
+ buf->data = NULL;
+ }
+ mem_init(buf, buf->margin);
+}
+
+/*******************************************************************
+ reallocate a memory buffer, including a safety margin
+ ********************************************************************/
+BOOL mem_realloc_data(struct mem_buf *buf, size_t new_size)
+{
+ char *new_data;
+
+ CHECK_STRUCT(buf);
+ if (!buf->dynamic)
+ {
+ DEBUG(3,("mem_realloc_data: memory buffer has not been dynamically allocated!\n"));
+ sleep(30);
+ return False;
+ }
+
+ if (new_size == 0)
+ {
+ mem_free_data(buf);
+ return True;
+ }
+
+ new_data = (char*)Realloc(buf->data, new_size + buf->margin);
+
+ if (new_data != NULL)
+ {
+ buf->data = new_data;
+ buf->data_size = new_size + buf->margin;
+ buf->data_used = new_size;
+ }
+ else if (buf->data_size <= new_size)
+ {
+ DEBUG(3,("mem_realloc: warning - could not realloc to %d(+%d)\n",
+ new_size, buf->margin));
+
+ buf->data_used = new_size;
+ }
+ else
+ {
+ DEBUG(3,("mem_realloc: error - could not realloc to %d\n",
+ new_size));
+
+ mem_free_data(buf);
+ return False;
+ }
+
+ buf->offset.end = buf->offset.start + new_size;
+
+ DEBUG(150,("mem_realloc_data: size: %d start: %d end: %d\n",
+ new_size, buf->offset.start, buf->offset.end));
+ return True;
+}
+
+/*******************************************************************
+ reallocate a memory buffer, retrospectively :-)
+ ********************************************************************/
+BOOL mem_grow_data(struct mem_buf **buf, BOOL io, int new_size, BOOL force_grow)
+{
+ if (buf == NULL || ((*buf) == NULL))
+ {
+ return False;
+ }
+
+ CHECK_STRUCT(*buf);
+
+ if (new_size + (*buf)->margin >= (*buf)->data_size)
+ {
+ if (!io || force_grow)
+ {
+ /* writing or forge realloc */
+ return mem_realloc_data((*buf), new_size);
+ }
+ else
+ {
+ }
+ }
+ return True;
+}
+
+
+/*******************************************************************
+ add up the lengths of all sections.
+ ********************************************************************/
+uint32 mem_buf_len(struct mem_buf *buf)
+{
+ int len = 0;
+ CHECK_STRUCT(buf);
+ while (buf != NULL)
+ {
+ len += buf->offset.end - buf->offset.start;
+ buf = buf->next;
+ }
+ return len;
+}
+
+
+/*******************************************************************
+ return the memory location specified by offset. may return NULL.
+ ********************************************************************/
+char *mem_data(struct mem_buf *buf, uint32 offset)
+{
+ CHECK_STRUCT(buf);
+ buf = mem_find(buf, offset);
+ if (buf != NULL)
+ {
+ return &(buf->data[offset - buf->offset.start]);
+ }
+ return NULL;
+}
+
+
diff --git a/source/lib/msrpc-agent.c b/source/lib/msrpc-agent.c
new file mode 100644
index 00000000000..1dfbe2b4023
--- /dev/null
+++ b/source/lib/msrpc-agent.c
@@ -0,0 +1,247 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2
+ SMB agent/socket plugin
+ Copyright (C) Andrew Tridgell 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "smb.h"
+
+extern int DEBUGLEVEL;
+
+static char packet[BUFFER_SIZE];
+
+/****************************************************************************
+terminate sockent connection
+****************************************************************************/
+static void free_sock(void *sock)
+{
+ if (sock != NULL)
+ {
+ struct msrpc_local *n = (struct msrpc_local*)sock;
+ msrpc_use_del(n->pipe_name, False, NULL);
+ }
+}
+
+static struct msrpc_local *init_client_connection(int c)
+{
+ pstring buf;
+ fstring pipe_name;
+ int rl;
+ uint32 len;
+ BOOL new_con = False;
+ struct msrpc_local *n = NULL;
+
+ CREDS_CMD cmd;
+ prs_struct ps;
+
+ ZERO_STRUCT(cmd);
+
+ DEBUG(10,("init_client_connection: first request\n"));
+
+ rl = read(c, &buf, sizeof(len));
+
+ if (rl != sizeof(len))
+ {
+ DEBUG(0,("Unable to read length\n"));
+ dump_data(0, buf, sizeof(len));
+ return NULL;
+ }
+
+ len = IVAL(buf, 0);
+
+ if (len > sizeof(buf))
+ {
+ DEBUG(0,("length %d too long\n", len));
+ return NULL;
+ }
+
+ rl = read(c, buf, len);
+
+ if (rl < 0)
+ {
+ DEBUG(0,("Unable to read from connection\n"));
+ return NULL;
+ }
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, buf, rl);
+#endif
+
+ /* make a static data parsing structure from the api_fd_reply data */
+ prs_create(&ps, buf, len, 4, True);
+
+ if (!creds_io_cmd("creds", &cmd, &ps, 0))
+ {
+ DEBUG(0,("Unable to parse credentials\n"));
+ prs_free_data(&ps);
+ return NULL;
+ }
+
+ prs_free_data(&ps);
+
+ if (ps.offset != rl)
+ {
+ DEBUG(0,("Buffer size %d %d!\n", ps.offset, rl));
+ return NULL;
+ }
+
+ switch (cmd.command)
+ {
+ case AGENT_CMD_CON:
+ case AGENT_CMD_CON_ANON:
+ {
+ new_con = True;
+ break;
+ }
+ case AGENT_CMD_CON_REUSE:
+ {
+ new_con = True;
+ break;
+ }
+ default:
+ {
+ DEBUG(0,("unknown command %d\n", cmd.command));
+ return NULL;
+ }
+ }
+
+ if (new_con)
+ {
+ uint32 status = 0;
+ n = msrpc_use_add(pipe_name, &cmd.key, False);
+
+ if (n == NULL)
+ {
+ DEBUG(0,("Unable to connect to %s\n", pipe_name));
+ status = 0x1;
+ }
+ else
+ {
+ fstrcpy(n->pipe_name, pipe_name);
+ }
+
+ if (write(c, &status, sizeof(status)) != sizeof(status))
+ {
+ DEBUG(0,("Could not write connection down pipe.\n"));
+ if (n != NULL)
+ {
+ msrpc_use_del(pipe_name, False, NULL);
+ n = NULL;
+ }
+ }
+ }
+ return n;
+}
+
+static BOOL process_cli_sock(struct sock_redir **socks, uint32 num_socks,
+ struct sock_redir *sock)
+{
+ struct msrpc_local *n = (struct msrpc_local*)sock->n;
+ if (n == NULL)
+ {
+ n = init_client_connection(sock->c);
+ if (n == NULL)
+ {
+ return False;
+ }
+ sock->n = (void*)n;
+ sock->s = n->fd;
+ }
+ else
+ {
+ if (!receive_smb(sock->c, packet, 0))
+ {
+ DEBUG(0,("client closed connection\n"));
+ return False;
+ }
+
+ if (!send_smb(sock->s, packet))
+ {
+ DEBUG(0,("server is dead\n"));
+ return False;
+ }
+ }
+ return True;
+}
+
+static BOOL process_srv_sock(struct sock_redir **socks, uint32 num_socks,
+ int fd)
+{
+ int i;
+ if (!receive_smb(fd, packet, 0))
+ {
+ DEBUG(0,("server closed connection\n"));
+ return False;
+ }
+
+ DEBUG(10,("process_srv_sock:\tfd:\t%d\n", fd));
+
+ for (i = 0; i < num_socks; i++)
+ {
+ struct msrpc_local *n;
+ if (socks[i] == NULL || socks[i]->n == NULL)
+ {
+ continue;
+ }
+ n = (struct msrpc_local*)socks[i]->n;
+ DEBUG(10,("list:\tfd:\t%d\n",
+ socks[i]->s));
+ if (!send_smb(socks[i]->c, packet))
+ {
+ DEBUG(0,("client is dead\n"));
+ return False;
+ }
+ return True;
+ }
+ return False;
+}
+
+static int get_agent_sock(char *pipe_name)
+{
+ fstring path;
+ fstring dir;
+
+ slprintf(dir, sizeof(dir)-1, "/tmp/.msrpc/.%s", pipe_name);
+ slprintf(path, sizeof(path)-1, "%s/agent", dir);
+
+ return create_pipe_socket(dir, S_IRUSR|S_IWUSR|S_IXUSR, path, 0);
+}
+
+void start_msrpc_agent(char *pipe_name)
+{
+ struct vagent_ops va =
+ {
+ free_sock,
+ get_agent_sock,
+ process_cli_sock,
+ process_srv_sock,
+ NULL,
+ NULL,
+ 0
+ };
+
+ if (fork() == 0)
+ {
+ /* child */
+ va.id = pipe_name;
+ start_agent(&va);
+ }
+}
+
diff --git a/source/lib/msrpc-client.c b/source/lib/msrpc-client.c
index 60924ed81c5..72e21339950 100644
--- a/source/lib/msrpc-client.c
+++ b/source/lib/msrpc-client.c
@@ -23,6 +23,7 @@
#define NO_SYSLOG
#include "includes.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
@@ -30,101 +31,119 @@ extern int DEBUGLEVEL;
read an msrpc pdu from a fd.
The timeout is in milliseconds.
****************************************************************************/
-BOOL receive_msrpc(int fd, prs_struct *data, unsigned int timeout)
+BOOL receive_msrpc(int fd, prs_struct * data, unsigned int timeout)
{
- BOOL ok;
- size_t len;
- RPC_HDR hdr;
+ BOOL ok;
+ size_t len;
+ RPC_HDR hdr;
- prs_init(data, 0, 4, True);
+ prs_init(data, 16, 4, True);
- ok = prs_read(data, fd, 16, timeout);
+ if (timeout > 0)
+ {
+ ok = (read_with_timeout(fd, data->data, 16, 16, timeout) ==
+ 16);
+ }
+ else
+ {
+ ok = (read_data(fd, data->data, 16) == 16);
+ }
if (!ok)
{
- prs_mem_free(data);
+ prs_free_data(data);
return False;
}
if (!smb_io_rpc_hdr("hdr", &hdr, data, 0))
{
- prs_mem_free(data);
+ prs_free_data(data);
return False;
}
len = hdr.frag_len - 16;
if (len > 0)
{
- ok = prs_read(data, fd, hdr.frag_len, 0);
- if (!ok)
+ size_t ret;
+ prs_realloc_data(data, hdr.frag_len);
+ ret = read_data(fd, data->data + 16, len);
+ if (ret != len)
{
- prs_mem_free(data);
+ prs_free_data(data);
return False;
}
- data->data_offset = hdr.frag_len;
+ data->start = 0;
+ data->offset = hdr.frag_len;
+ data->end = hdr.frag_len;
return True;
}
- prs_mem_free(data);
+ prs_free_data(data);
return False;
}
/****************************************************************************
send an smb to a fd and re-establish if necessary
****************************************************************************/
-BOOL msrpc_send(int fd, prs_struct *ps)
+BOOL msrpc_send(int fd, prs_struct * ps)
{
- size_t len = ps != NULL ? ps->buffer_size : 0;
- size_t nwritten=0;
+ size_t len = ps != NULL ? prs_buf_len(ps) : 0;
+ size_t nwritten = 0;
ssize_t ret;
- char *outbuf = ps->data_p;
+ char *outbuf = (ps != NULL ? ps->data : NULL);
- DEBUG(10,("msrpc_send_prs: data: %p len %d\n", outbuf, len));
+ DEBUG(10, ("ncalrpc_l_send_prs: data: %p len %d\n", outbuf, len));
dbgflush();
+ if (outbuf == NULL)
+ {
+ return True;
+ }
dump_data(10, outbuf, len);
while (nwritten < len)
{
- ret = write_socket(fd,outbuf+nwritten,len - nwritten);
+ ret = write_socket(fd, outbuf + nwritten, len - nwritten);
if (ret <= 0)
{
- DEBUG(0,("Error writing %d msrpc bytes. %d.\n",
- len,ret));
- prs_mem_free(ps);
+ DEBUG(0, ("Error writing %d msrpc bytes. %d.\n",
+ len, ret));
+ prs_free_data(ps);
return False;
}
nwritten += ret;
}
-
- prs_mem_free(ps);
+
+ prs_free_data(ps);
return True;
}
/****************************************************************************
receive msrpc packet
****************************************************************************/
-BOOL msrpc_receive(int fd, prs_struct *ps)
+BOOL msrpc_receive(int fd, prs_struct * ps)
{
int len;
- DEBUG(10,("msrpc_receive: %d\n", __LINE__));
+ DEBUG(10, ("ncalrpc_l_receive: %d\n", __LINE__));
if (!receive_msrpc(fd, ps, 0))
{
return False;
}
- len = ps->buffer_size;
+ len = prs_buf_len(ps);
- if (ps->data_p == NULL || len <= 0)
+ if (ps->data == NULL || len <= 0)
{
return False;
}
- dump_data(10, ps->data_p, len);
+ dump_data(10, ps->data, len);
- DEBUG(10,("msrpc_receive: len %d\n", len));
+ DEBUG(10, ("ncalrpc_l_receive: len %d\n", len));
+
+ prs_debug_out(ps, "ncalrpc_l_receive_prs", 200);
return True;
}
@@ -132,13 +151,13 @@ BOOL msrpc_receive(int fd, prs_struct *ps)
/****************************************************************************
open the msrpcent sockets
****************************************************************************/
-BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name)
+BOOL ncalrpc_l_connect(struct msrpc_local *msrpc, const char *pipe_name)
{
fstring path;
- slprintf(path, sizeof(path)-1, "%s/.msrpc/%s", LOCKDIR, pipe_name);
+ slprintf(path, sizeof(path) - 1, "%s/.msrpc/%s", LOCKDIR, pipe_name);
fstrcpy(msrpc->pipe_name, pipe_name);
-
+
msrpc->fd = open_pipe_sock(path);
if (msrpc->fd == -1)
@@ -151,19 +170,11 @@ BOOL msrpc_connect(struct msrpc_state *msrpc, const char *pipe_name)
/****************************************************************************
-initialise a msrpcent structure
-****************************************************************************/
-void msrpc_init_creds(struct msrpc_state *msrpc, const struct user_creds *usr)
-{
- copy_user_creds(&msrpc->usr, usr);
-}
-
-/****************************************************************************
close the socket descriptor
****************************************************************************/
-void msrpc_close_socket(struct msrpc_state *msrpc)
+void ncalrpc_l_close_socket(struct msrpc_local *msrpc)
{
- if (msrpc->fd != -1)
+ if (msrpc->fd != -1)
{
close(msrpc->fd);
}
@@ -174,66 +185,64 @@ void msrpc_close_socket(struct msrpc_state *msrpc)
/****************************************************************************
set socket options on a open connection
****************************************************************************/
-void msrpc_sockopt(struct msrpc_state *msrpc, char *options)
+void ncalrpc_l_sockopt(struct msrpc_local *msrpc, char *options)
{
set_socket_options(msrpc->fd, options);
}
-static BOOL msrpc_authenticate(struct msrpc_state *msrpc,
- const struct user_creds *usr)
+static BOOL ncalrpc_l_authenticate(struct msrpc_local *msrpc)
{
- struct msrpc_state msrpc_redir;
-
int sock = msrpc->fd;
+ uint32 len;
char *data;
prs_struct ps;
- uint32 len;
+
char *in = msrpc->inbuf;
char *out = msrpc->outbuf;
+
uint16 command;
- command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON;
+ command = AGENT_CMD_CON;
if (!create_user_creds(&ps, msrpc->pipe_name, 0x0, command,
- msrpc->pid, usr))
+ &msrpc->nt.key, NULL))
{
- DEBUG(0,("could not parse credentials\n"));
+ DEBUG(0, ("could not parse credentials\n"));
close(sock);
return False;
}
- len = ps.data_offset;
- data = ps.data_p;
+ len = ps.offset;
+ data = prs_data(&ps, 0);
SIVAL(data, 0, len);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("data len: %d\n", len));
+ DEBUG(100, ("data len: %d\n", len));
dump_data(100, data, len);
#endif
if (write(sock, data, len) <= 0)
{
- DEBUG(0,("write failed\n"));
+ DEBUG(0, ("write failed\n"));
return False;
}
-
if (msrpc->redirect)
{
+ struct msrpc_local msrpc_redir;
len = read(sock, &msrpc_redir, sizeof(msrpc_redir));
if (len != sizeof(msrpc_redir))
{
- DEBUG(0,("read failed\n"));
+ DEBUG(0, ("read failed\n"));
return False;
}
-
+
memcpy(msrpc, &msrpc_redir, sizeof(msrpc_redir));
msrpc->inbuf = in;
msrpc->outbuf = out;
msrpc->fd = sock;
- msrpc->usr.reuse = False;
}
else
{
@@ -245,14 +254,13 @@ static BOOL msrpc_authenticate(struct msrpc_state *msrpc,
return True;
}
-static BOOL msrpc_init_redirect(struct msrpc_state *msrpc,
- const char* pipe_name,
- const struct user_creds *usr)
+static BOOL ncalrpc_l_init_redirect(struct msrpc_local *msrpc,
+ const char *pipe_name)
{
int sock;
fstring path;
- slprintf(path, sizeof(path)-1, "/tmp/.msrpc/.%s/agent", pipe_name);
+ slprintf(path, sizeof(path) - 1, "/tmp/.msrpc/.%s/agent", pipe_name);
sock = open_pipe_sock(path);
@@ -263,9 +271,9 @@ static BOOL msrpc_init_redirect(struct msrpc_state *msrpc,
msrpc->fd = sock;
- if (!msrpc_authenticate(msrpc, usr))
+ if (!ncalrpc_l_authenticate(msrpc))
{
- DEBUG(0,("authenticate failed\n"));
+ DEBUG(0, ("authenticate failed\n"));
close(msrpc->fd);
msrpc->fd = -1;
return False;
@@ -274,23 +282,19 @@ static BOOL msrpc_init_redirect(struct msrpc_state *msrpc,
return True;
}
-BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
- uint32 pid,
- const char* pipename,
- const struct user_creds *usr)
+BOOL ncalrpc_l_connect_auth(struct msrpc_local *msrpc,
+ const vuser_key * key, const char *pipename)
{
ZERO_STRUCTP(msrpc);
- if (!msrpc_initialise(msrpc, pid))
+ if (!ncalrpc_l_initialise(msrpc, key))
{
- DEBUG(0,("unable to initialise msrpcent connection.\n"));
+ DEBUG(0, ("unable to initialise ncalrpc_l connection.\n"));
return False;
}
- msrpc_init_creds(msrpc, usr);
-
- if (!msrpc_establish_connection(msrpc, pipename))
+ if (!ncalrpc_l_establish_connection(msrpc, pipename))
{
- msrpc_shutdown(msrpc);
+ ncalrpc_l_shutdown(msrpc);
return False;
}
@@ -300,32 +304,52 @@ BOOL msrpc_connect_auth(struct msrpc_state *msrpc,
/****************************************************************************
initialise a msrpcent structure
****************************************************************************/
-struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc, uint32 pid)
+struct msrpc_local *ncalrpc_l_initialise(struct msrpc_local *msrpc,
+ const vuser_key * key)
{
- if (!msrpc) {
- msrpc = (struct msrpc_state *)malloc(sizeof(*msrpc));
+ if (!msrpc)
+ {
+ msrpc = (struct msrpc_local *)malloc(sizeof(*msrpc));
if (!msrpc)
return NULL;
ZERO_STRUCTP(msrpc);
}
- if (msrpc->initialised) {
- msrpc_shutdown(msrpc);
+ if (msrpc->initialised)
+ {
+ ncalrpc_l_shutdown(msrpc);
}
ZERO_STRUCTP(msrpc);
msrpc->fd = -1;
- msrpc->outbuf = (char *)malloc(CLI_BUFFER_SIZE+4);
- msrpc->inbuf = (char *)malloc(CLI_BUFFER_SIZE+4);
+ msrpc->outbuf = (char *)malloc(CLI_BUFFER_SIZE + 4);
+ msrpc->inbuf = (char *)malloc(CLI_BUFFER_SIZE + 4);
if (!msrpc->outbuf || !msrpc->inbuf)
{
return False;
}
msrpc->initialised = 1;
- msrpc_init_creds(msrpc, NULL);
- msrpc->pid = pid;
+
+ if (key != NULL)
+ {
+ msrpc->nt.key = *key;
+ }
+ else
+ {
+ NET_USER_INFO_3 usr;
+ uid_t uid = getuid();
+ gid_t gid = getgid();
+ char *name = uidtoname(uid);
+
+ ZERO_STRUCT(usr);
+
+ msrpc->nt.key.pid = getpid();
+ msrpc->nt.key.vuid = register_vuid(msrpc->nt.key.pid,
+ uid, gid,
+ name, name, False, &usr);
+ }
return msrpc;
}
@@ -334,9 +358,9 @@ struct msrpc_state *msrpc_initialise(struct msrpc_state *msrpc, uint32 pid)
/****************************************************************************
shutdown a msrpcent structure
****************************************************************************/
-void msrpc_shutdown(struct msrpc_state *msrpc)
+void ncalrpc_l_shutdown(struct msrpc_local *msrpc)
{
- DEBUG(10,("msrpc_shutdown\n"));
+ DEBUG(10, ("msrpc_shutdown\n"));
if (msrpc->outbuf)
{
free(msrpc->outbuf);
@@ -345,54 +369,61 @@ void msrpc_shutdown(struct msrpc_state *msrpc)
{
free(msrpc->inbuf);
}
- msrpc_close_socket(msrpc);
+ ncalrpc_l_close_socket(msrpc);
memset(msrpc, 0, sizeof(*msrpc));
}
/****************************************************************************
establishes a connection right up to doing tconX, reading in a password.
****************************************************************************/
-BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
- const char *pipe_name)
+BOOL ncalrpc_l_establish_connection(struct msrpc_local *msrpc,
+ const char *pipe_name)
{
- DEBUG(5,("msrpc_establish_connection: connecting to %s (%s) - %s\n",
- pipe_name,
- msrpc->usr.ntc.user_name, msrpc->usr.ntc.domain));
+ if (strnequal("\\PIPE\\", pipe_name, 6))
+ {
+ pipe_name = &pipe_name[6];
+ }
+
+ DEBUG(5, ("ncalrpc_l_establish_connection: connecting to %s\n",
+ pipe_name));
/* establish connection */
- if ((!msrpc->initialised))
+ if (!msrpc->initialised)
{
return False;
}
if (msrpc->fd == -1 && msrpc->redirect)
{
- if (msrpc_init_redirect(msrpc, pipe_name, &msrpc->usr))
+ if (ncalrpc_l_init_redirect(msrpc, pipe_name))
{
- DEBUG(10,("msrpc_establish_connection: redirected OK\n"));
+ DEBUG(10,
+ ("ncalrpc_l_establish_connection: redirected OK\n"));
return True;
}
else
{
- DEBUG(10,("redirect FAILED\n"));
- return False;
+ DEBUG(10,
+ ("redirect failed, attempt direct connection\n"));
+ msrpc->redirect = False;
}
}
if (msrpc->fd == -1)
{
- if (!msrpc_connect(msrpc, pipe_name))
+ if (!ncalrpc_l_connect(msrpc, pipe_name))
{
- DEBUG(1,("msrpc_establish_connection: failed %s)\n",
- pipe_name));
-
+ DEBUG(1,
+ ("ncalrpc_l_establish_connection: failed %s)\n",
+ pipe_name));
+
return False;
}
}
- if (!msrpc_authenticate(msrpc, &msrpc->usr))
+ if (!ncalrpc_l_authenticate(msrpc))
{
- DEBUG(0,("authenticate failed\n"));
+ DEBUG(0, ("authenticate failed\n"));
close(msrpc->fd);
msrpc->fd = -1;
return False;
@@ -400,4 +431,3 @@ BOOL msrpc_establish_connection(struct msrpc_state *msrpc,
return True;
}
-
diff --git a/source/lib/msrpc_use.c b/source/lib/msrpc_use.c
index 1d0df1872fb..7111d255114 100644
--- a/source/lib/msrpc_use.c
+++ b/source/lib/msrpc_use.c
@@ -1,329 +1 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- SMB client generic functions
- Copyright (C) Andrew Tridgell 1994-1999
- Copyright (C) Luke Kenneth Casson Leighton 1996-1999
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define NO_SYSLOG
-
-#include "includes.h"
-#include "trans2.h"
-
-extern int DEBUGLEVEL;
-extern pstring global_myname;
-
-struct msrpc_use
-{
- struct msrpc_state *cli;
- uint32 num_users;
-};
-
-static struct msrpc_use **msrpcs = NULL;
-uint32 num_msrpcs = 0;
-
-/****************************************************************************
-terminate client connection
-****************************************************************************/
-static void msrpc_use_free(struct msrpc_use *cli)
-{
- if (cli->cli != NULL)
- {
- if (cli->cli->initialised)
- {
- msrpc_shutdown(cli->cli);
- }
- free(cli->cli);
- }
-
- free(cli);
-}
-
-/****************************************************************************
-free a client array
-****************************************************************************/
-static void free_msrpc_array(uint32 num_entries, struct msrpc_use **entries)
-{
- void(*fn)(void*) = (void(*)(void*))&msrpc_use_free;
- free_void_array(num_entries, (void**)entries, *fn);
-}
-
-/****************************************************************************
-add a client state to the array
-****************************************************************************/
-static struct msrpc_use* add_msrpc_to_array(uint32 *len,
- struct msrpc_use ***array,
- struct msrpc_use *cli)
-{
- int i;
- for (i = 0; i < num_msrpcs; i++)
- {
- if (msrpcs[i] == NULL)
- {
- msrpcs[i] = cli;
- return cli;
- }
- }
-
- return (struct msrpc_use*)add_item_to_array(len,
- (void***)array, (void*)cli);
-
-}
-
-/****************************************************************************
-initiate client array
-****************************************************************************/
-void init_msrpc_use(void)
-{
- msrpcs = NULL;
- num_msrpcs = 0;
-}
-
-/****************************************************************************
-terminate client array
-****************************************************************************/
-void free_msrpc_use(void)
-{
- free_msrpc_array(num_msrpcs, msrpcs);
- init_msrpc_use();
-}
-
-/****************************************************************************
-find client state. server name, user name, domain name and password must all
-match.
-****************************************************************************/
-static struct msrpc_use *msrpc_find(const char* pipe_name,
- const struct user_creds *usr_creds)
-{
- int i;
- struct user_creds null_usr;
-
- if (usr_creds == NULL)
- {
- copy_user_creds(&null_usr, usr_creds);
- usr_creds = &null_usr;
- }
-
- DEBUG(10,("msrpc_find: %s %s %s\n",
- pipe_name,
- usr_creds != NULL ? usr_creds->ntc.user_name : "null",
- usr_creds != NULL ? usr_creds->ntc.domain : "null"));
-
- for (i = 0; i < num_msrpcs; i++)
- {
- char *msrpc_name = NULL;
- struct msrpc_use *c = msrpcs[i];
-
- if (c == NULL) continue;
-
- msrpc_name = c->cli->pipe_name;
-
- DEBUG(10,("msrpc_find[%d]: %s %s %s\n",
- i, msrpc_name,
- c->cli->usr.ntc.user_name,
- c->cli->usr.ntc.domain));
-
- if (!strequal(msrpc_name, pipe_name))
- {
- continue;
- }
- if (!strequal(usr_creds->ntc.user_name, c->cli->usr.ntc.user_name))
- {
- continue;
- }
- if (!usr_creds->reuse &&
- !pwd_compare(&usr_creds->ntc.pwd, &c->cli->usr.ntc.pwd))
- {
- DEBUG(100,("password doesn't match\n"));
- continue;
- }
- if (usr_creds->ntc.domain[0] == 0)
- {
- return c;
- }
- if (strequal(usr_creds->ntc.domain, c->cli->usr.ntc.domain))
- {
- return c;
- }
- }
-
- return NULL;
-}
-
-/****************************************************************************
-create a new client state from user credentials
-****************************************************************************/
-static struct msrpc_use *msrpc_use_get(const char* pipe_name,
- uint32 pid,
- const struct user_creds *usr_creds)
-{
- struct msrpc_use *cli = (struct msrpc_use*)malloc(sizeof(*cli));
-
- if (cli == NULL)
- {
- return NULL;
- }
-
- memset(cli, 0, sizeof(*cli));
-
- cli->cli = msrpc_initialise(NULL, pid);
-
- if (cli->cli == NULL)
- {
- return NULL;
- }
-
- msrpc_init_creds(cli->cli, usr_creds);
-
- return cli;
-}
-
-/****************************************************************************
-init client state
-****************************************************************************/
-struct msrpc_state *msrpc_use_add(const char* pipe_name,
- uint32 pid,
- const struct user_creds *usr_creds,
- BOOL redir)
-{
- struct msrpc_use *cli;
- DEBUG(10,("msrpc_use_add: %s redir: %s\n", pipe_name, BOOLSTR(redir)));
-
- cli = msrpc_find(pipe_name, usr_creds);
-
- if (cli != NULL)
- {
- cli->num_users++;
- return cli->cli;
- }
-
- /* reuse an existing connection requested, and one was not found */
- if (usr_creds != NULL && usr_creds->reuse && !redir)
- {
- DEBUG(0,("msrpc_use_add: reuse requested, but one not found\n"));
- return False;
- }
-
- /*
- * allocate
- */
-
- cli = msrpc_use_get(pipe_name, pid, usr_creds);
- cli->cli->redirect = redir;
-
- if (!msrpc_establish_connection(cli->cli, pipe_name))
- {
- DEBUG(0,("msrpc_use_add: connection failed\n"));
- cli->cli = NULL;
- msrpc_use_free(cli);
- return NULL;
- }
-
- add_msrpc_to_array(&num_msrpcs, &msrpcs, cli);
- cli->num_users++;
-
- return cli->cli;
-}
-
-/****************************************************************************
-delete a client state
-****************************************************************************/
-BOOL msrpc_use_del(const char* pipe_name,
- const struct user_creds *usr_creds,
- BOOL force_close,
- BOOL *connection_closed)
-{
- int i;
-
- DEBUG(10,("msrpc_net_use_del: %s. force close: %s\n",
- pipe_name, BOOLSTR(force_close)));
-
- if (connection_closed != NULL)
- {
- *connection_closed = False;
- }
-
- for (i = 0; i < num_msrpcs; i++)
- {
- char *msrpc_name = NULL;
-
- if (msrpcs[i] == NULL) continue;
- if (msrpcs[i]->cli == NULL) continue;
-
- msrpc_name = msrpcs[i]->cli->pipe_name;
-
- if (!strequal(msrpc_name, pipe_name)) continue;
-
- if (strequal(usr_creds->ntc.user_name,
- msrpcs[i]->cli->usr.ntc.user_name) &&
- strequal(usr_creds->ntc.domain,
- msrpcs[i]->cli->usr.ntc.domain))
- {
- /* decrement number of users */
- msrpcs[i]->num_users--;
-
- DEBUG(10,("idx: %i num_users now: %d\n",
- i, msrpcs[i]->num_users));
-
- if (force_close || msrpcs[i]->num_users == 0)
- {
- msrpc_use_free(msrpcs[i]);
- msrpcs[i] = NULL;
- if (connection_closed != NULL)
- {
- *connection_closed = True;
- }
- }
- return True;
- }
- }
-
- return False;
-}
-
-/****************************************************************************
-enumerate client states
-****************************************************************************/
-void msrpc_net_use_enum(uint32 *num_cons, struct use_info ***use)
-{
- int i;
-
- *num_cons = 0;
- *use = NULL;
-
- for (i = 0; i < num_msrpcs; i++)
- {
- struct use_info item;
-
- ZERO_STRUCT(item);
-
- if (msrpcs[i] == NULL) continue;
-
- item.connected = msrpcs[i]->cli != NULL ? True : False;
-
- if (item.connected)
- {
- item.srv_name = msrpcs[i]->cli->pipe_name;
- item.user_name = msrpcs[i]->cli->usr.ntc.user_name;
- item.domain = msrpcs[i]->cli->usr.ntc.domain;
- }
-
- add_use_info_to_array(num_cons, use, &item);
- }
-}
-
+/* retired */
diff --git a/source/lib/netmask.c b/source/lib/netmask.c
new file mode 100644
index 00000000000..6d710583758
--- /dev/null
+++ b/source/lib/netmask.c
@@ -0,0 +1,358 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ code to query kernel netmask
+ Copyright (C) Andrew Tridgell 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+/* working out the netmask for an interface is an incredibly non-portable
+ thing. We have several possible implementations below, and autoconf
+ tries each of them to see what works
+
+ Note that this file does _not_ include includes.h. That is so this code
+ can be called directly from the autoconf tests. That also means
+ this code cannot use any of the normal Samba debug stuff or defines.
+ This is standalone code.
+
+*/
+
+#ifndef AUTOCONF
+#include "config.h"
+#endif
+
+#ifdef HAVE_NETMASK_IFCONF
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#ifndef SIOCGIFCONF
+#include <sys/sockio.h>
+#endif
+
+/*
+ * Prototype for gcc in fussy mode.
+ */
+
+int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask);
+
+/****************************************************************************
+ get the netmask address for a local interface
+****************************************************************************/
+int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask)
+{
+ struct ifconf ifc;
+ char buff[2048];
+ int fd, i, n;
+ struct ifreq *ifr=NULL;
+
+ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+#ifdef DEBUG
+ fprintf(stderr,"socket failed\n");
+#endif
+ return -1;
+ }
+
+ ifc.ifc_len = sizeof(buff);
+ ifc.ifc_buf = buff;
+ if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) {
+#ifdef DEBUG
+ fprintf(stderr,"SIOCGIFCONF failed\n");
+#endif
+ close(fd);
+ return -1;
+ }
+
+ ifr = ifc.ifc_req;
+
+ n = ifc.ifc_len / sizeof(struct ifreq);
+
+#ifdef DEBUG
+ fprintf(stderr,"%d interfaces - looking for %s\n",
+ n, inet_ntoa(*ipaddr));
+#endif
+
+ /* Loop through interfaces, looking for given IP address */
+ for (i=n-1;i>=0;i--) {
+ if (ioctl(fd, SIOCGIFADDR, &ifr[i]) != 0) {
+#ifdef DEBUG
+ fprintf(stderr,"SIOCGIFADDR failed\n");
+#endif
+ continue;
+ }
+
+#ifdef DEBUG
+ fprintf(stderr,"interface %s\n",
+ inet_ntoa((*(struct sockaddr_in *)&ifr[i].ifr_addr).sin_addr));
+#endif
+ if (ipaddr->s_addr !=
+ (*(struct sockaddr_in *)&ifr[i].ifr_addr).sin_addr.s_addr) {
+ continue;
+ }
+
+ if (ioctl(fd, SIOCGIFNETMASK, &ifr[i]) != 0) {
+#ifdef DEBUG
+ fprintf(stderr,"SIOCGIFNETMASK failed\n");
+#endif
+ close(fd);
+ return -1;
+ }
+ close(fd);
+ (*nmask) = ((struct sockaddr_in *)&ifr[i].ifr_addr)->sin_addr;
+#ifdef DEBUG
+ fprintf(stderr,"netmask %s\n", inet_ntoa(*nmask));
+#endif
+ return 0;
+ }
+
+#ifdef DEBUG
+ fprintf(stderr,"interface not found\n");
+#endif
+
+ close(fd);
+ return -1;
+}
+
+#elif defined(HAVE_NETMASK_IFREQ)
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#ifndef SIOCGIFCONF
+#include <sys/sockio.h>
+#endif
+
+#ifndef I_STR
+#include <sys/stropts.h>
+#endif
+
+
+/****************************************************************************
+this should cover most of the rest of systems
+****************************************************************************/
+ int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask)
+{
+ struct ifreq ifreq;
+ struct strioctl strioctl;
+ struct ifconf *ifc;
+ char buff[2048];
+ int fd, i, n;
+ struct ifreq *ifr=NULL;
+
+ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+#ifdef DEBUG
+ fprintf(stderr,"socket failed\n");
+#endif
+ return -1;
+ }
+
+ ifc = (struct ifconf *)buff;
+ ifc->ifc_len = BUFSIZ - sizeof(struct ifconf);
+ strioctl.ic_cmd = SIOCGIFCONF;
+ strioctl.ic_dp = (char *)ifc;
+ strioctl.ic_len = sizeof(buff);
+ if (ioctl(fd, I_STR, &strioctl) < 0) {
+#ifdef DEBUG
+ fprintf(stderr,"SIOCGIFCONF failed\n");
+#endif
+ close(fd);
+ return -1;
+ }
+
+ ifr = (struct ifreq *)ifc->ifc_req;
+
+ /* Loop through interfaces, looking for given IP address */
+ n = ifc->ifc_len / sizeof(struct ifreq);
+
+ for (i = 0; i<n; i++, ifr++) {
+#ifdef DEBUG
+ fprintf(stderr,"interface %s\n",
+ inet_ntoa((*(struct sockaddr_in *)&ifr->ifr_addr).sin_addr.s_addr));
+#endif
+ if (ipaddr->s_addr ==
+ (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
+ break;
+ }
+ }
+
+#ifdef DEBUG
+ if (i == n) {
+ fprintf(stderr,"interface not found\n");
+ close(fd);
+ return -1;
+ }
+#endif
+
+ ifreq = *ifr;
+
+ strioctl.ic_cmd = SIOCGIFNETMASK;
+ strioctl.ic_dp = (char *)&ifreq;
+ strioctl.ic_len = sizeof(struct ifreq);
+ if (ioctl(fd, I_STR, &strioctl) != 0) {
+#ifdef DEBUG
+ fprintf(stderr,"Failed SIOCGIFNETMASK\n");
+#endif
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+ *nmask = ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr;
+#ifdef DEBUG
+ fprintf(stderr,"netmask %s\n", inet_ntoa(*nmask));
+#endif
+ return 0;
+}
+
+#elif defined(HAVE_NETMASK_AIX)
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#ifndef SIOCGIFCONF
+#include <sys/sockio.h>
+#endif
+
+/****************************************************************************
+this one is for AIX
+****************************************************************************/
+ int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask)
+{
+ char buff[2048];
+ int fd, i, n;
+ struct ifconf ifc;
+ struct ifreq *ifr=NULL;
+
+ if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
+#ifdef DEBUG
+ fprintf(stderr,"socket failed\n");
+#endif
+ return -1;
+ }
+
+
+ ifc.ifc_len = sizeof(buff);
+ ifc.ifc_buf = buff;
+
+ if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) {
+#ifdef DEBUG
+ fprintf(stderr,"SIOCGIFCONF failed\n");
+#endif
+ close(fd);
+ return -1;
+ }
+
+ ifr = ifc.ifc_req;
+ /* Loop through interfaces, looking for given IP address */
+ i = ifc.ifc_len;
+ while (i > 0) {
+#ifdef DEBUG
+ fprintf(stderr,"interface %s\n",
+ inet_ntoa((*(struct sockaddr_in *)&ifr->ifr_addr).sin_addr));
+#endif
+ if (ipaddr->s_addr ==
+ (*(struct sockaddr_in *) &ifr->ifr_addr).sin_addr.s_addr) {
+ break;
+ }
+ i -= ifr->ifr_addr.sa_len + IFNAMSIZ;
+ ifr = (struct ifreq*) ((char*) ifr + ifr->ifr_addr.sa_len +
+ IFNAMSIZ);
+ }
+
+
+#ifdef DEBUG
+ if (i <= 0) {
+ fprintf(stderr,"interface not found\n");
+ close(fd);
+ return -1;
+ }
+#endif
+
+ if (ioctl(fd, SIOCGIFNETMASK, ifr) != 0) {
+#ifdef DEBUG
+ fprintf(stderr,"SIOCGIFNETMASK failed\n");
+#endif
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+
+ (*nmask) = ((struct sockaddr_in *)&ifr->ifr_addr)->sin_addr;
+#ifdef DEBUG
+ fprintf(stderr,"netmask %s\n", inet_ntoa(*nmask));
+#endif
+ return 0;
+}
+
+#else /* a dummy version */
+struct in_addr; /* it may not have been declared before */
+ int get_netmask(struct in_addr *ipaddr, struct in_addr *nmask)
+{
+ return -1;
+}
+#endif
+
+
+#ifdef AUTOCONF
+/* this is the autoconf driver to test get_netmask() */
+
+ main()
+{
+ char buf[1024];
+ struct hostent *hp;
+ struct in_addr ip, nmask;
+
+ if (gethostname(buf, sizeof(buf)-1) != 0) {
+ fprintf(stderr,"gethostname failed\n");
+ exit(1);
+ }
+
+ hp = gethostbyname(buf);
+
+ if (!hp) {
+ fprintf(stderr,"gethostbyname failed\n");
+ exit(1);
+ }
+
+ memcpy((char *)&ip, (char *)hp->h_addr, hp->h_length);
+
+ if (get_netmask(&ip, &nmask) == 0) exit(0);
+
+ fprintf(stderr,"get_netmask failed\n");
+ exit(1);
+}
+#endif
diff --git a/source/lib/passcheck.c b/source/lib/passcheck.c
new file mode 100644
index 00000000000..ee9e578f14a
--- /dev/null
+++ b/source/lib/passcheck.c
@@ -0,0 +1,200 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Password and authentication handling
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/****************************************************************************
+core of smb password checking routine.
+****************************************************************************/
+static BOOL smb_pwd_check_ntlmv1(const char *password,
+ const uchar *part_passwd,
+ const uchar *c8,
+ uchar user_sess_key[16])
+{
+ /* Finish the encryption of part_passwd. */
+ uchar p24[24];
+
+ if (part_passwd == NULL)
+ DEBUG(10,("No password set - allowing access\n"));
+ /* No password set - always true ! */
+ if (part_passwd == NULL)
+ return True;
+
+ SMBOWFencrypt(part_passwd, c8, p24);
+ if (user_sess_key != NULL)
+ {
+ SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key);
+ }
+
+#if DEBUG_PASSWORD
+ DEBUG(100,("Part password (P16) was |"));
+ dump_data(100, part_passwd, 16);
+ DEBUG(100,("Password from client was |"));
+ dump_data(100, password, 24);
+ DEBUG(100,("Given challenge was |"));
+ dump_data(100, c8, 8);
+ DEBUG(100,("Value from encryption was |"));
+ dump_data(100, p24, 24);
+#endif
+ return (memcmp(p24, password, 24) == 0);
+}
+
+/****************************************************************************
+core of smb password checking routine.
+****************************************************************************/
+static BOOL smb_pwd_check_ntlmv2(const char *password, size_t pwd_len,
+ uchar *part_passwd,
+ uchar const *c8,
+ const char *user, const char *domain,
+ char *user_sess_key)
+{
+ /* Finish the encryption of part_passwd. */
+ uchar kr[16];
+ uchar resp[16];
+
+ if (part_passwd == NULL)
+ {
+ DEBUG(10,("No password set - allowing access\n"));
+ }
+ /* No password set - always true ! */
+ if (part_passwd == NULL)
+ {
+ return True;
+ }
+
+ ntv2_owf_gen(part_passwd, user, domain, kr);
+ SMBOWFencrypt_ntv2(kr, c8, 8, password+16, pwd_len-16, resp);
+ if (user_sess_key != NULL)
+ {
+ SMBsesskeygen_ntv2(kr, resp, user_sess_key);
+ }
+
+#if DEBUG_PASSWORD
+ DEBUG(100,("Part password (P16) was |"));
+ dump_data(100, part_passwd, 16);
+ DEBUG(100,("Password from client was |"));
+ dump_data(100, password, pwd_len);
+ DEBUG(100,("Given challenge was |"));
+ dump_data(100, c8, 8);
+ DEBUG(100,("Value from encryption was |"));
+ dump_data(100, resp, 16);
+#endif
+
+ return (memcmp(resp, password, 16) == 0);
+}
+
+/****************************************************************************
+ Do a specific test for an smb password being correct, given a smb_password and
+ the lanman and NT responses.
+****************************************************************************/
+BOOL smb_password_ok(uint16 acct_ctrl,
+ uchar smb_passwd[16],
+ uchar smb_nt_passwd[16],
+ const uchar challenge[8],
+ const char *user, const char *domain,
+ const uchar *lm_pass, size_t lm_pwd_len,
+ const uchar *nt_pass, size_t nt_pwd_len,
+ uchar user_sess_key[16])
+{
+ DEBUG(4,("Checking SMB password for user %s\n", user));
+
+ dump_data_pw("lm password:\n", lm_pass, lm_pwd_len);
+ dump_data_pw("nt password:\n", nt_pass, nt_pwd_len);
+
+ if (acct_ctrl & ACB_DISABLED)
+ {
+ DEBUG(3,("account for user %s was disabled.\n", user));
+ return False;
+ }
+
+ if (challenge == NULL)
+ {
+ DEBUG(1,("no challenge available - password failed\n"));
+ return False;
+ }
+
+ if (smb_nt_passwd != NULL)
+ {
+ /* We have the NT MD4 hash challenge available - see if we can
+ use it (ie. does it exist in the smbpasswd file).
+ */
+ if (lp_server_ntlmv2() != False && nt_pwd_len > 24)
+ {
+ DEBUG(4,("smb_password_ok: Check NTLMv2 password\n"));
+ if (smb_pwd_check_ntlmv2(nt_pass, nt_pwd_len,
+ (uchar *)smb_nt_passwd,
+ challenge, user, domain,
+ user_sess_key))
+ {
+ return True;
+ }
+ }
+ if (lp_server_ntlmv2() != True && nt_pwd_len == 24)
+ {
+ DEBUG(4,("smb_password_ok: Check NT MD4 password\n"));
+ if (smb_pwd_check_ntlmv1((const char *)nt_pass,
+ (const uchar *)smb_nt_passwd,
+ challenge,
+ user_sess_key))
+ {
+ DEBUG(4,("NT MD4 password check succeeded\n"));
+ return True;
+ }
+ }
+ DEBUG(4,("NT MD4 password check failed\n"));
+ }
+
+ if (lp_server_ntlmv2() == True)
+ {
+ DEBUG(4,("Not checking LM MD4 password\n"));
+ return False;
+ }
+
+ /* Try against the lanman password. smb_passwd == NULL means
+ no password, allow access. */
+
+ DEBUG(4,("Checking LM MD4 password\n"));
+
+ if ((smb_passwd == NULL) &&
+ (acct_ctrl & ACB_PWNOTREQ))
+ {
+ DEBUG(4,("no password required for user %s\n", user));
+ return True;
+ }
+
+ if ((smb_passwd != NULL) &&
+ smb_pwd_check_ntlmv1((const char *)lm_pass,
+ (const uchar *)smb_passwd,
+ challenge, user_sess_key))
+ {
+ DEBUG(4,("LM MD4 password check succeeded\n"));
+ return(True);
+ }
+
+ DEBUG(4,("LM MD4 password check failed\n"));
+
+ return False;
+}
+
diff --git a/source/lib/pidfile.c b/source/lib/pidfile.c
index 726e8c1f21a..6fc64aafe2f 100644
--- a/source/lib/pidfile.c
+++ b/source/lib/pidfile.c
@@ -39,7 +39,7 @@ pid_t pidfile_pid(char *name)
slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
- fd = sys_open(pidFile, O_NONBLOCK | O_RDWR, 0644);
+ fd = open(pidFile, O_NONBLOCK | O_RDWR);
if (fd == -1) {
return 0;
}
@@ -52,7 +52,7 @@ pid_t pidfile_pid(char *name)
ret = atoi(pidstr);
- if (!process_exists((pid_t)ret)) {
+ if (!process_exists(ret)) {
goto ok;
}
@@ -76,14 +76,14 @@ void pidfile_create(char *name)
int fd;
char buf[20];
pstring pidFile;
- pid_t pid;
+ int pid;
slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
pid = pidfile_pid(name);
if (pid != 0) {
DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n",
- name, pidFile, (int)pid));
+ name, pidFile, pid));
exit(1);
}
@@ -109,3 +109,4 @@ void pidfile_create(char *name)
}
/* Leave pid file open & locked for the duration... */
}
+
diff --git a/source/lib/replace.c b/source/lib/replace.c
index 8d91c2d785c..c6a42594177 100644
--- a/source/lib/replace.c
+++ b/source/lib/replace.c
@@ -70,7 +70,7 @@ Corrections by richard.kettlewell@kewill.com
epoch = (t->tm_year - 70) * YEAR +
((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
- y = t->tm_year + 1900;
+ y = t->tm_year;
m = 0;
for(i = 0; i < t->tm_mon; i++) {
@@ -163,21 +163,16 @@ Corrections by richard.kettlewell@kewill.com
/* yikes! no SETGROUPS or INITGROUPS? how can this work? */
return(0);
#else /* HAVE_SETGROUPS */
- gid_t *grouplst = NULL;
- int max_gr = groups_max();
- int ret;
+ gid_t grouplst[NGROUPS_MAX];
int i,j;
struct group *g;
char *gr;
- if((grouplst = (gid_t *)malloc(sizeof(gid_t) * max_gr)) == NULL) {
- DEBUG(0,("initgroups: malloc fail !\n");
- return -1;
- }
-
+ setgrent();
grouplst[0] = id;
i = 1;
- while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
+ while (i < NGROUPS_MAX &&
+ ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
if (g->gr_gid == id)
continue;
j = 0;
@@ -193,9 +188,7 @@ Corrections by richard.kettlewell@kewill.com
}
}
endgrent();
- ret = sys_setgroups(i,grouplst);
- free((char *)grouplst);
- return ret;
+ return(setgroups(i,grouplst));
#endif /* HAVE_SETGROUPS */
}
#endif /* HAVE_INITGROUPS */
diff --git a/source/lib/set_uid.c b/source/lib/set_uid.c
new file mode 100644
index 00000000000..b42e4e08692
--- /dev/null
+++ b/source/lib/set_uid.c
@@ -0,0 +1,391 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ uid/user handling
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+static uid_t initial_uid;
+static gid_t initial_gid;
+
+/* what user is current? */
+extern struct current_user current_user;
+
+pstring OriginalDir;
+
+/****************************************************************************
+get the current security context vuid key
+****************************************************************************/
+const vuser_key *get_sec_ctx(void)
+{
+ if (current_user.key.vuid != UID_FIELD_INVALID)
+ {
+ return &current_user.key;
+ }
+ return NULL;
+}
+
+/****************************************************************************
+initialise the uid routines
+****************************************************************************/
+void init_uid(void)
+{
+ initial_uid = current_user.uid = geteuid();
+ initial_gid = current_user.gid = getegid();
+
+ if (initial_gid != 0 && initial_uid == 0) {
+#ifdef HAVE_SETRESUID
+ setresgid(0,0,0);
+#else
+ setgid(0);
+ setegid(0);
+#endif
+ }
+
+ initial_uid = geteuid();
+ initial_gid = getegid();
+
+ current_user.conn = NULL;
+ current_user.key.vuid = UID_FIELD_INVALID;
+
+ current_user.ngroups = 0;
+ current_user.groups = NULL;
+
+ dos_ChDir(OriginalDir);
+}
+
+
+/****************************************************************************
+ become the specified uid
+****************************************************************************/
+BOOL become_uid(uid_t uid)
+{
+ if (initial_uid != 0) {
+ return(True);
+ }
+
+ if (uid == (uid_t)-1 || ((sizeof(uid_t) == 2) && (uid == (uid_t)65535))) {
+ static int done;
+ if (!done) {
+ DEBUG(1,("WARNING: using uid %d is a security risk\n",(int)uid));
+ done=1;
+ }
+ }
+
+#ifdef HAVE_TRAPDOOR_UID
+#ifdef HAVE_SETUIDX
+ /* AIX3 has setuidx which is NOT a trapoor function (tridge) */
+ if (setuidx(ID_EFFECTIVE, uid) != 0) {
+ if (seteuid(uid) != 0) {
+ DEBUG(1,("Can't set uid %d (setuidx)\n", (int)uid));
+ return False;
+ }
+ }
+#endif
+#endif
+
+#ifdef HAVE_SETRESUID
+ if (setresuid(-1,uid,-1) != 0)
+#else
+ if ((seteuid(uid) != 0) &&
+ (setuid(uid) != 0))
+#endif
+ {
+ DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n",
+ (int)uid,(int)getuid(), (int)geteuid()));
+ if (uid > (uid_t)32000) {
+ DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n"));
+ }
+ return(False);
+ }
+
+ if (((uid == (uid_t)-1) || ((sizeof(uid_t) == 2) && (uid == 65535))) && (geteuid() != uid)) {
+ DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n"));
+ return(False);
+ }
+
+ current_user.uid = uid;
+
+#ifdef WITH_PROFILE
+ profile_p->uid_changes++;
+#endif
+
+ return(True);
+}
+
+
+/****************************************************************************
+ become the specified gid
+****************************************************************************/
+BOOL become_gid(gid_t gid)
+{
+ if (initial_uid != 0)
+ return(True);
+
+ if (gid == (gid_t)-1 || ((sizeof(gid_t) == 2) && (gid == (gid_t)65535))) {
+ DEBUG(1,("WARNING: using gid %d is a security risk\n",(int)gid));
+ }
+
+#ifdef HAVE_SETRESUID
+ if (setresgid(-1,gid,-1) != 0)
+#else
+ if (setgid(gid) != 0)
+#endif
+ {
+ DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n",
+ (int)gid,(int)getgid(),(int)getegid()));
+ if (gid > 32000) {
+ DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n"));
+ }
+ return(False);
+ }
+
+ current_user.gid = gid;
+
+ return(True);
+}
+
+/****************************************************************************
+ unbecome a user
+****************************************************************************/
+BOOL unbecome_to_initial_uid(void)
+{
+ dos_ChDir(OriginalDir);
+
+ if (initial_uid == 0)
+ {
+#ifdef HAVE_SETRESUID
+ setresuid(-1,getuid(),-1);
+ setresgid(-1,getgid(),-1);
+#else
+ if (seteuid(initial_uid) != 0)
+ setuid(initial_uid);
+ setgid(initial_gid);
+#endif
+ }
+
+#ifdef NO_EID
+ if (initial_uid == 0)
+ DEBUG(2,("Running with no EID\n"));
+ initial_uid = getuid();
+ initial_gid = getgid();
+#else
+ if (geteuid() != initial_uid) {
+ DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
+ initial_uid = geteuid();
+ }
+ if (getegid() != initial_gid) {
+ DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
+ initial_gid = getegid();
+ }
+#endif
+
+ current_user.uid = initial_uid;
+ current_user.gid = initial_gid;
+
+ if (dos_ChDir(OriginalDir) != 0)
+ DEBUG( 0, ( "chdir(%s) failed in unbecome_to_initial_uid\n", OriginalDir) );
+
+ DEBUG(5,("unbecome_to_initial_uid now uid=(%d,%d) gid=(%d,%d)\n",
+ (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
+
+ current_user.conn = NULL;
+ current_user.key.vuid = UID_FIELD_INVALID;
+
+ return(True);
+}
+
+/****************************************************************************
+ become the specified uid and gid
+****************************************************************************/
+BOOL become_id(uid_t uid,gid_t gid)
+{
+ return(become_gid(gid) && become_uid(uid));
+}
+
+/****************************************************************************
+ become the user of a connection number
+****************************************************************************/
+BOOL become_unix_sec_ctx(const vuser_key *k, connection_struct *conn,
+ uid_t new_uid, gid_t new_gid,
+ int n_groups, gid_t* groups)
+{
+ gid_t gid;
+ uid_t uid;
+
+ if (current_user.uid == new_uid &&
+ current_user.key.pid == k->pid &&
+ current_user.key.vuid == k->vuid)
+ {
+ DEBUG(4,("Skipping become_unix_sec_ctx - already user\n"));
+ return(True);
+ }
+
+ unbecome_to_initial_uid();
+
+ uid = new_uid;
+ gid = new_gid;
+ current_user.ngroups = n_groups;
+ current_user.groups = groups;
+
+ if (initial_uid == 0)
+ {
+ if (!become_gid(gid)) return(False);
+
+#ifdef HAVE_SETGROUPS
+ if (!(conn != NULL && conn->ipc))
+ {
+ /* groups stuff added by ih/wreu */
+ if (current_user.ngroups > 0)
+ {
+ if (setgroups(current_user.ngroups,
+ current_user.groups)<0) {
+ DEBUG(0,("setgroups call failed!\n"));
+ }
+ }
+ }
+#endif
+
+ if (conn == NULL)
+ {
+ if (!become_uid(uid)) return False;
+ }
+ else
+ {
+ if (!conn->admin_user && !become_uid(uid)) return False;
+ }
+ }
+
+ current_user.conn = conn;
+ current_user.key = *k;
+
+ DEBUG(5,("become_unix_sec_ctx uid=(%d,%d) gid=(%d,%d) vuser=(%d,%x)\n",
+ (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid(),
+ current_user.key.pid, current_user.key.vuid));
+
+ return(True);
+}
+
+/****************************************************************************
+become the guest user
+****************************************************************************/
+BOOL become_guest(void)
+{
+ BOOL ret;
+ const struct passwd *pass=NULL;
+
+ if (initial_uid != 0)
+ return(True);
+
+ if (!pass)
+ pass = Get_Pwnam(lp_guestaccount(-1),True);
+ if (!pass) return(False);
+
+#ifdef AIX
+ /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before setting IDs */
+ initgroups(pass->pw_name, (gid_t)pass->pw_gid);
+#endif
+
+ ret = become_id(pass->pw_uid,pass->pw_gid);
+
+ if (!ret) {
+ DEBUG(1,("Failed to become guest. Invalid guest account?\n"));
+ }
+
+ current_user.conn = NULL;
+ current_user.key.vuid = UID_FIELD_INVALID;
+
+ return(ret);
+}
+
+static struct current_user current_user_saved;
+static int become_root_depth = 0;
+static pstring become_root_dir;
+
+/****************************************************************************
+This is used when we need to do a privilaged operation (such as mucking
+with share mode files) and temporarily need root access to do it. This
+call should always be paired with an unbecome_root() call immediately
+after the operation
+
+Set save_dir if you also need to save/restore the CWD
+****************************************************************************/
+void become_root(BOOL save_dir)
+{
+ if (become_root_depth) {
+ DEBUG(0,("ERROR: become root depth is non zero\n"));
+ }
+ if (save_dir)
+ dos_GetWd(become_root_dir);
+
+ current_user_saved = current_user;
+ become_root_depth = 1;
+
+ become_uid(0);
+ become_gid(0);
+}
+
+/****************************************************************************
+When the privilaged operation is over call this
+
+Set save_dir if you also need to save/restore the CWD
+****************************************************************************/
+void unbecome_root(BOOL restore_dir)
+{
+ if (become_root_depth != 1) {
+ DEBUG(0,("ERROR: unbecome root depth is %d\n",
+ become_root_depth));
+ }
+
+ /* we might have done a become_user() while running as root,
+ if we have then become root again in order to become
+ non root! */
+ if (current_user.uid != 0) {
+ become_uid(0);
+ }
+
+ /* restore our gid first */
+ if (!become_gid(current_user_saved.gid)) {
+ DEBUG(0,("ERROR: Failed to restore gid\n"));
+ exit_server("Failed to restore gid");
+ }
+
+#ifdef HAVE_SETGROUPS
+ if (current_user_saved.ngroups > 0) {
+ if (setgroups(current_user_saved.ngroups,
+ current_user_saved.groups)<0)
+ DEBUG(0,("ERROR: setgroups call failed!\n"));
+ }
+#endif
+
+ /* now restore our uid */
+ if (!become_uid(current_user_saved.uid)) {
+ DEBUG(0,("ERROR: Failed to restore uid\n"));
+ exit_server("Failed to restore uid");
+ }
+
+ if (restore_dir)
+ dos_ChDir(become_root_dir);
+
+ current_user = current_user_saved;
+
+ become_root_depth = 0;
+}
diff --git a/source/lib/set_vuid.c b/source/lib/set_vuid.c
new file mode 100644
index 00000000000..593c5f2200c
--- /dev/null
+++ b/source/lib/set_vuid.c
@@ -0,0 +1,69 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ uid/user handling
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+static struct uid_cache vcache;
+
+void init_vuid(void)
+{
+ init_uid();
+ vcache.entries = 0;
+}
+
+/****************************************************************************
+ become the user of a connection number
+****************************************************************************/
+BOOL become_vuser(const vuser_key *k)
+{
+ user_struct *vuser;
+ BOOL ret;
+
+ unbecome_vuser();
+ vuser = get_valid_user_struct(k);
+
+ if (vuser == NULL)
+ {
+ return False;
+ }
+
+ if (!check_vuser_ok(&vcache, vuser, -1))
+ {
+ vuid_free_user_struct(vuser);
+ return False;
+ }
+
+ ret = become_unix_sec_ctx(k, NULL, vuser->uid, vuser->gid,
+ vuser->n_groups, vuser->groups);
+ vuid_free_user_struct(vuser);
+ return ret;
+}
+
+/****************************************************************************
+ unbecome a user
+****************************************************************************/
+BOOL unbecome_vuser(void)
+{
+ return unbecome_to_initial_uid();
+}
+
diff --git a/source/lib/sids.c b/source/lib/sids.c
new file mode 100644
index 00000000000..56d6a9c21d4
--- /dev/null
+++ b/source/lib/sids.c
@@ -0,0 +1,578 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "sids.h"
+
+
+extern int DEBUGLEVEL;
+extern pstring global_myname;
+
+/*
+ * This is set on startup - it defines the SID for this
+ * machine, and therefore the SAM database for which it is
+ * responsible.
+ */
+
+DOM_SID global_sam_sid;
+
+/*
+ * This is the name associated with the SAM database for
+ * which this machine is responsible. In the case of a PDC
+ * or PDC, this name is the same as the workgroup. In the
+ * case of "security = domain" mode, this is the same as
+ * the name of the server (global_myname).
+ */
+
+fstring global_sam_name;
+
+/*
+ * This is obtained on startup - it defines the SID for which
+ * this machine is a member. It is therefore only set, and
+ * used, in "security = domain" mode.
+ */
+
+DOM_SID global_member_sid;
+
+/*
+ * note the lack of a "global_member_name" - this is because
+ * this is the same as "global_myworkgroup".
+ */
+
+extern fstring global_myworkgroup;
+/* fstring global_member_dom_name; */
+
+/*
+ * some useful sids
+ */
+
+DOM_SID global_sid_S_1_5_20; /* local well-known domain */
+DOM_SID global_sid_S_1_1; /* Global Domain */
+DOM_SID global_sid_S_1_3; /* Creator Owner */
+DOM_SID global_sid_S_1_5; /* NT Authority */
+DOM_SID global_sid_system; /* NT System */
+DOM_SID global_sid_S_1_1_0; /* everyone */
+
+struct sid_map
+{
+ DOM_SID *sid;
+ char *name;
+
+};
+
+struct sid_map static_sid_name_map[] =
+{
+ { &global_sid_S_1_5_20, "BUILTIN" },
+ { &global_sid_S_1_1 , "Global Domain" },
+ { &global_sid_S_1_1_0 , "Everyone" },
+ { &global_sid_S_1_3 , "Creator Owner" },
+ { &global_sid_S_1_5 , "NT Authority" },
+ { &global_sid_system , "SYSTEM" },
+ { &global_sam_sid , global_sam_name },
+ { &global_member_sid , global_myworkgroup },
+ { NULL , NULL }
+};
+
+struct sid_map **sid_name_map = NULL;
+uint32 num_maps = 0;
+
+static struct sid_map *sid_map_dup(const struct sid_map *from)
+{
+ if (from != NULL)
+ {
+ struct sid_map *copy = (struct sid_map *)
+ malloc(sizeof(struct sid_map));
+ if (copy != NULL)
+ {
+ ZERO_STRUCTP(copy);
+ if (from->name != NULL)
+ {
+ copy->name = strdup(from->name );
+ }
+ if (from->sid != NULL)
+ {
+ copy->sid = sid_dup(from->sid);
+ }
+ }
+ return copy;
+ }
+ return NULL;
+}
+
+static void sid_map_free(struct sid_map *map)
+{
+ if (map->name != NULL)
+ {
+ free(map->name);
+ }
+ if (map->sid != NULL)
+ {
+ free(map->sid);
+ }
+ free(map);
+}
+
+/****************************************************************************
+free a sid map array
+****************************************************************************/
+static void free_sidmap_array(uint32 num_entries, struct sid_map **entries)
+{
+ void(*fn)(void*) = (void(*)(void*))&sid_map_free;
+ free_void_array(num_entries, (void**)entries, *fn);
+}
+
+/****************************************************************************
+add a sid map state to the array
+****************************************************************************/
+struct sid_map* add_sidmap_to_array(uint32 *len, struct sid_map ***array,
+ const struct sid_map *name)
+{
+ void*(*fn)(const void*) = (void*(*)(const void*))&sid_map_dup;
+ return (struct sid_map*)add_copy_to_array(len,
+ (void***)array, (const void*)name, *fn, False);
+
+}
+/****************************************************************************
+ sets up the name associated with the SAM database for which we are responsible
+****************************************************************************/
+void get_sam_domain_name(void)
+{
+
+ switch (lp_server_role())
+ {
+ case ROLE_DOMAIN_PDC:
+ case ROLE_DOMAIN_BDC:
+ {
+ /* we are PDC (or BDC) for a Domain */
+ fstrcpy(global_sam_name, lp_workgroup());
+ DEBUG(5,("get_sam_domain_name: PDC/BDC "));
+ break;
+ }
+ case ROLE_DOMAIN_MEMBER:
+ {
+ /* we are a "PDC", but FOR LOCAL SAM DATABASE ONLY */
+ fstrcpy(global_sam_name, global_myname);
+ DEBUG(5,("get_sam_domain_name: Dom-Mem"));
+ break;
+ }
+ default:
+ {
+ /* no domain role, probably due to "security = share" */
+ memset(global_sam_name, 0, sizeof(global_sam_name));
+ DEBUG(5,("get_sam_domain_name: no role"));
+ break;
+ }
+ }
+ DEBUG(5,("%s\n", global_sam_name));
+}
+
+/****************************************************************************
+ obtain the sid from the PDC.
+****************************************************************************/
+BOOL get_member_domain_sid(void)
+{
+ DEBUG(10,("get_member_domain_sid: "));
+ switch (lp_server_role())
+ {
+ case ROLE_DOMAIN_NONE:
+ {
+ ZERO_STRUCT(global_member_sid);
+ DEBUG(10,("none\n"));
+ return True;
+ }
+ case ROLE_DOMAIN_PDC:
+ {
+ fstring sidstr;
+ sid_copy(&global_member_sid, &global_sam_sid);
+ sid_to_string(sidstr, &global_member_sid);
+ DEBUG(10,("%s\n", sidstr));
+ return True;
+ }
+ default:
+ {
+ /* member or BDC, we're going for connection to PDC */
+ break;
+ }
+ }
+
+ return get_domain_sids(lp_workgroup(), NULL, &global_member_sid);
+}
+
+
+/****************************************************************************
+ creates some useful well known sids
+****************************************************************************/
+void generate_wellknown_sids(void)
+{
+ string_to_sid(&global_sid_S_1_5_20, "S-1-5-32");
+ string_to_sid(&global_sid_S_1_1 , "S-1-1" );
+ string_to_sid(&global_sid_S_1_1_0 , "S-1-1-0" );
+ string_to_sid(&global_sid_S_1_3 , "S-1-3" );
+ string_to_sid(&global_sid_S_1_5 , "S-1-5" );
+ string_to_sid(&global_sid_system , "S-1-5-17");
+}
+
+/****************************************************************************
+ create a sid map table
+****************************************************************************/
+BOOL create_sidmap_table(void)
+{
+ int i;
+ char **doms = NULL;
+ uint32 num_doms = 0;
+
+ for (i = 0; static_sid_name_map[i].name != NULL; i++)
+ {
+ add_sidmap_to_array(&num_maps, &sid_name_map,
+ &static_sid_name_map[i]);
+ }
+
+ enumtrustdoms(&doms, &num_doms);
+
+ for (i = 0; i < num_doms; i++)
+ {
+ struct sid_map map;
+ DOM_SID sid;
+
+ map.name = doms[i];
+ map.sid = &sid;
+
+ if (!read_sid(map.name, map.sid))
+ {
+ DEBUG(0,("Could not read Domain SID %s\n", map.name));
+ return False;
+ }
+ add_sidmap_to_array(&num_maps, &sid_name_map, &map);
+ }
+
+
+ for (i = 0; i < num_maps; i++)
+ {
+ fstring sidstr;
+ sid_to_string(sidstr, sid_name_map[i]->sid);
+ DEBUG(10,("Map:\tDomain:\t%s\tSID:\t%s\n",
+ sid_name_map[i]->name, sidstr));
+ }
+
+
+ free_char_array(num_doms, doms);
+
+ return True;
+}
+
+/****************************************************************************
+ Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
+ not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
+****************************************************************************/
+BOOL generate_sam_sid(char *domain_name, DOM_SID *sid)
+{
+ char *p;
+ pstring sid_file;
+ pstring machine_sid_file;
+ fstring file_name;
+
+ pstrcpy(sid_file, lp_smb_passwd_file());
+
+ if (sid_file[0] == 0)
+ {
+ DEBUG(0,("cannot find smb passwd file\n"));
+ return False;
+ }
+
+ p = strrchr(sid_file, '/');
+ if (p != NULL)
+ {
+ *++p = '\0';
+ }
+
+ if (!directory_exist(sid_file, NULL)) {
+ if (mkdir(sid_file, 0700) != 0) {
+ DEBUG(0,("can't create private directory %s : %s\n",
+ sid_file, strerror(errno)));
+ return False;
+ }
+ }
+
+ pstrcpy(machine_sid_file, sid_file);
+ pstrcat(machine_sid_file, "MACHINE.SID");
+
+ slprintf(file_name, sizeof(file_name)-1, "%s.SID", domain_name);
+ strupper(file_name);
+ pstrcat(sid_file, file_name);
+
+ if (file_exist(machine_sid_file, NULL))
+ {
+ if (file_exist(sid_file, NULL))
+ {
+ DEBUG(0,("both %s and %s exist when only one should, unable to continue\n",
+ machine_sid_file, sid_file));
+ return False;
+ }
+ if (file_rename(machine_sid_file, sid_file))
+ {
+ DEBUG(0,("could not rename %s to %s. Error was %s\n",
+ machine_sid_file, sid_file, strerror(errno)));
+ return False;
+ }
+ }
+
+ /* attempt to read the SID from the file */
+ if (read_sid(domain_name, sid))
+ {
+ return True;
+ }
+
+ if (!create_new_sid(sid))
+ {
+ return False;
+ }
+ /* attempt to read the SID from the file */
+ if (!write_sid(domain_name, sid))
+ {
+ return True;
+ }
+
+ /* during the attempt to write, someone else wrote? */
+
+ /* attempt to read the SID from the file */
+ if (read_sid(domain_name, sid))
+ {
+ return True;
+ }
+
+ return True;
+}
+
+/*************************************************************
+ initialise password databases, domain names, domain sid.
+**************************************************************/
+BOOL pwdb_initialise(BOOL is_server)
+{
+ get_sam_domain_name();
+
+ if (!init_myworkgroup())
+ {
+ return False;
+ }
+
+ generate_wellknown_sids();
+
+ if (is_server)
+ {
+ if (!generate_sam_sid(global_sam_name, &global_sam_sid))
+ {
+ DEBUG(0,("ERROR: Samba cannot create a SAM SID for its domain (%s).\n",
+ global_sam_name));
+ return False;
+ }
+ if (!get_member_domain_sid())
+ {
+ return False;
+ }
+ }
+ else
+ {
+ if (!get_domain_sids(lp_workgroup(), &global_member_sid,
+ &global_sam_sid))
+ {
+ return False;
+ }
+ }
+
+ return create_sidmap_table();
+}
+
+/**************************************************************************
+ turns a domain name into a SID.
+
+ *** side-effect: if the domain name is NULL, it is set to our domain ***
+
+***************************************************************************/
+BOOL map_domain_name_to_sid(DOM_SID *sid, char **nt_domain)
+{
+ int i = 0;
+
+ if (nt_domain == NULL)
+ {
+ sid_copy(sid, &global_sam_sid);
+ return True;
+ }
+
+ if ((*nt_domain) == NULL)
+ {
+ DEBUG(5,("map_domain_name_to_sid: overriding NULL name to %s\n",
+ global_sam_name));
+ (*nt_domain) = strdup(global_sam_name);
+ sid_copy(sid, &global_sam_sid);
+ return True;
+ }
+
+ if ((*nt_domain)[0] == 0)
+ {
+ free(*nt_domain);
+ (*nt_domain) = strdup(global_sam_name);
+ DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n",
+ (*nt_domain)));
+ sid_copy(sid, &global_sam_sid);
+ return True;
+ }
+
+ DEBUG(5,("map_domain_name_to_sid: %s\n", (*nt_domain)));
+
+ for (i = 0; i < num_maps; i++)
+ {
+ DEBUG(5,("compare: %s\n", sid_name_map[i]->name));
+ if (strequal(sid_name_map[i]->name, (*nt_domain)))
+ {
+ fstring sid_str;
+ sid_copy(sid, sid_name_map[i]->sid);
+ sid_to_string(sid_str, sid_name_map[i]->sid);
+ DEBUG(5,("found %s\n", sid_str));
+ return True;
+ }
+ }
+
+ DEBUG(5,("map_domain_name_to_sid: mapping to %s not known\n",
+ (*nt_domain)));
+ return False;
+}
+
+/**************************************************************************
+ turns a domain SID into a name.
+
+***************************************************************************/
+BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain)
+{
+ fstring sid_str;
+ int i = 0;
+ sid_to_string(sid_str, sid);
+
+ DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
+
+ if (nt_domain == NULL)
+ {
+ return False;
+ }
+
+ for (i = 0; i < num_maps; i++)
+ {
+ sid_to_string(sid_str, sid_name_map[i]->sid);
+ DEBUG(5,("compare: %s\n", sid_str));
+ if (sid_equal(sid_name_map[i]->sid, sid))
+ {
+ fstrcpy(nt_domain, sid_name_map[i]->name);
+ DEBUG(5,("found %s\n", nt_domain));
+ return True;
+ }
+ }
+
+ DEBUG(0,("map_domain_sid_to_name: mapping NOT IMPLEMENTED\n"));
+
+ return False;
+}
+/**************************************************************************
+ turns a domain SID into a domain controller name.
+***************************************************************************/
+BOOL map_domain_sid_to_any_dc(DOM_SID *sid, char *dc_name)
+{
+ fstring domain;
+
+ if (!map_domain_sid_to_name(sid, domain))
+ {
+ return False;
+ }
+
+ return get_any_dc_name(domain, dc_name);
+}
+
+/**************************************************************************
+ splits a name of format \DOMAIN\name or name into its two components.
+ sets the DOMAIN name to global_sam_name if it has not been specified.
+***************************************************************************/
+BOOL split_domain_name(const char *fullname, char *domain, char *name)
+{
+ fstring full_name;
+ char *p;
+
+ if (fullname == NULL || domain == NULL || name == NULL)
+ {
+ return False;
+ }
+
+ if (fullname[0] == '\\')
+ {
+ fullname++;
+ }
+ fstrcpy(full_name, fullname);
+ p = strchr(full_name+1, '\\');
+
+ if (p != NULL)
+ {
+ *p = 0;
+ fstrcpy(domain, full_name);
+ fstrcpy(name, p+1);
+ }
+ else
+ {
+ fstrcpy(domain, global_sam_name);
+ fstrcpy(name, full_name);
+ }
+
+ DEBUG(10,("name '%s' split into domain:%s and nt name:%s'\n", fullname, domain, name));
+ return True;
+}
+
+/**************************************************************************
+ enumerates all trusted domains
+***************************************************************************/
+BOOL enumtrustdoms(char ***doms, uint32 *num_entries)
+{
+ fstring tmp;
+ char *tok;
+
+ /* add trusted domains */
+
+ tok = lp_trusted_domains();
+ if (next_token(&tok, tmp, NULL, sizeof(tmp)))
+ {
+ do
+ {
+ fstring domain;
+ split_at_first_component(tmp, domain, '=', NULL);
+ add_chars_to_array(num_entries, doms, domain);
+
+ } while (next_token(NULL, tmp, NULL, sizeof(tmp)));
+ }
+
+ return True;
+}
+
+/**************************************************************************
+ enumerates all domains for which the SAM server is responsible
+***************************************************************************/
+BOOL enumdomains(char ***doms, uint32 *num_entries)
+{
+ add_chars_to_array(num_entries, doms, global_sam_name);
+ add_chars_to_array(num_entries, doms, "Builtin");
+
+ return True;
+}
+
diff --git a/source/lib/smbd_creds_db.c b/source/lib/smbd_creds_db.c
new file mode 100644
index 00000000000..232d8d9c52d
--- /dev/null
+++ b/source/lib/smbd_creds_db.c
@@ -0,0 +1,129 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+static TDB_CONTEXT *db = NULL;
+
+static char *make_creds_key(uint32 pid, uint16 vuid, int *klen)
+{
+ char *k;
+
+ (*klen) = sizeof(pid) + sizeof(vuid);
+ k = malloc((*klen) * sizeof(char));
+
+ if (k != NULL)
+ {
+ *((uint32*)k) = pid;
+ *((uint16*)(k+sizeof(pid))) = vuid;
+
+ DEBUG(10,("make_creds_key: pid: %x vuid %x\n",
+ pid, vuid));
+ dump_data(10, k, (*klen));
+ }
+
+ return k;
+}
+
+BOOL smbd_cred_get(uint32 pid, uint16 vuid, struct smbd_creds *dc)
+{
+ int klen;
+ char *k;
+ TDB_DATA key, data;
+
+ DEBUG(10,("smbd_cred_get:\n"));
+
+ k = make_creds_key(pid, vuid, &klen);
+
+ if (k == NULL) return False;
+
+ key.dptr = k;
+ key.dsize = klen;
+
+ data = tdb_fetch(db, key);
+
+ free(k);
+
+ if (data.dptr == NULL)
+ {
+ DEBUG(10,("smbd_cred_get: NULL data\n"));
+ return False;
+ }
+ if (data.dsize != sizeof(*dc))
+ {
+ DEBUG(10,("smbd_cred_get: data size mismatch\n"));
+ free(data.dptr);
+ return False;
+ }
+
+ memcpy(dc, data.dptr, sizeof(*dc));
+ free(data.dptr);
+
+ dump_data(100, (char*)dc, sizeof(*dc));
+ return True;
+}
+
+BOOL smbd_cred_store(uint32 pid, uint16 vuid, struct smbd_creds *dc)
+{
+ int klen;
+ char *k;
+ TDB_DATA key, data;
+ BOOL ret;
+
+ DEBUG(10,("smbd_cred_store:\n"));
+
+ k = make_creds_key(pid, vuid, &klen);
+
+ if (k == NULL) return False;
+
+ key.dptr = k;
+ key.dsize = klen;
+
+ data.dptr = (char*)dc;
+ data.dsize = sizeof(*dc);
+
+ ret = (tdb_store(db, key, data, TDB_REPLACE) == 0);
+
+ free(k);
+
+ dump_data(100, (char*)dc, sizeof(*dc));
+
+ return ret;
+}
+
+BOOL smbd_cred_init_db(void)
+{
+ db = tdb_open(lock_path("smbdcreds.tdb"), 0, 0,
+ O_RDWR | O_CREAT, 0600);
+
+ if (db == NULL)
+ {
+ DEBUG(0,("smbd_cred_init_db: failed\n"));
+ return False;
+ }
+
+ DEBUG(10,("smbd_cred_init_db: opened\n"));
+
+ return True;
+}
+
diff --git a/source/lib/smbrun.c b/source/lib/smbrun.c
index 5a016cd5cd8..d80d55a556d 100644
--- a/source/lib/smbrun.c
+++ b/source/lib/smbrun.c
@@ -21,7 +21,6 @@
#include "includes.h"
-/* need to move this from here!! need some sleep ... */
struct current_user current_user;
extern int DEBUGLEVEL;
diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c
index 70ce95916fc..57987326437 100644
--- a/source/lib/snprintf.c
+++ b/source/lib/snprintf.c
@@ -581,21 +581,8 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
{
int signvalue = 0;
LDOUBLE ufvalue;
-#ifndef HAVE_FCVT
char iconvert[20];
char fconvert[20];
-#else
- char iconvert[311];
- char fconvert[311];
- char *result;
- int dec_pt, sig;
- int r_length;
-# ifdef HAVE_FCVTL
- extern char *fcvtl(long double value, int ndigit, int *decpt, int *sign);
-# else
- extern char *fcvt(double value, int ndigit, int *decpt, int *sign);
-# endif
-#endif
int iplace = 0;
int fplace = 0;
int padlen = 0; /* amount to pad */
@@ -626,7 +613,6 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */
#endif
-#ifndef HAVE_FCVT
intpart = (long)ufvalue;
/*
@@ -669,61 +655,7 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
} while(fracpart && (fplace < 20));
if (fplace == 20) fplace--;
fconvert[fplace] = 0;
-#else /* use fcvt() */
- if (max > 310)
- max = 310;
-# ifdef HAVE_FCVTL
- result = fcvtl(ufvalue, max, &dec_pt, &sig);
-# else
- result = fcvt(ufvalue, max, &dec_pt, &sig);
-# endif
- r_length = strlen(result);
-
- /*
- * Fix broken fcvt implementation returns..
- */
-
- if (r_length == 0)
- {
- result[0] = '0';
- result[1] = '\0';
- r_length = 1;
- }
-
- if ( r_length < dec_pt )
- dec_pt = r_length;
-
- if (dec_pt <= 0) {
- iplace = 1;
- iconvert[0] = '0';
- iconvert[1] = '\0';
-
- fplace = 0;
-
- while(r_length)
- fconvert[fplace++] = result[--r_length];
-
- while ((dec_pt < 0) && (fplace < max)) {
- fconvert[fplace++] = '0';
- dec_pt++;
- }
- } else {
- int c;
-
- iplace=0;
- for(c=dec_pt; c; iconvert[iplace++] = result[--c])
- ;
- iconvert[iplace] = '\0';
-
- result += dec_pt;
- fplace = 0;
-
- for(c=(r_length-dec_pt); c; fconvert[fplace++] = result[--c])
- ;
- }
-#endif /* fcvt */
-
/* -1 for decimal point, another -1 if we are printing a sign */
padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0);
zpadlen = max - fplace;
@@ -859,7 +791,7 @@ static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c)
NULL
};
double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
- 0.9996, 1.996, 4.136, 6442452944.1234, 0};
+ 0.9996, 1.996, 4.136, 0};
char *int_fmt[] = {
"%-1.5d",
"%1.5d",
diff --git a/source/lib/streams.c b/source/lib/streams.c
new file mode 100644
index 00000000000..8e6ad9f53aa
--- /dev/null
+++ b/source/lib/streams.c
@@ -0,0 +1,140 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "MacExtensions.h"
+
+extern int DEBUGLEVEL;
+
+/*
+** Given a path to file/directory build a path to the stream in question.
+** If it is not a directory they place the .streams folder after the last
+** slash then add the filename with the stream cat on. If it is a directory
+** then just cat the .streams folder and the stream on it. If mode is true
+** then force the .streams directory to be created.
+**
+** Some examples.
+** input::
+** fname = folder1/folder2/filea
+** stream = :AFP_Resource:$DATA the resource fork
+** isDir = False
+** output::
+** streampath = folder1/folder2/.streams/filea:AFP_Resource:$DATA
+**
+** input::
+** fname = folder1/folder2
+** stream = :AFP_AfpInfo:$DATA the Finder Info
+** isDir = True
+** output::
+** streampath = folder1/folder2/.streams/:AFP_Resource:$DATA
+**
+*/
+void makestreampath(char *fname, char *stream, char *streampath, int mode, int isDir, int dirOnly)
+{
+ char *cptr;
+
+ pstrcpy(streampath, fname);
+ if (!isDir)
+ {
+ cptr = strrchr(streampath, '/');
+ if (cptr) *(cptr+1) = 0;
+ else streampath[0] = 0;
+ }
+ else
+ if (streampath[0] == 0) /* Start at the current position */
+ pstrcat(streampath, "./");
+ else pstrcat(streampath, "/");
+
+ pstrcat(streampath, STREAM_FOLDER_SLASH);
+ if (mode)
+ (void)mkdir(streampath, 0777);
+ if (! dirOnly)
+ {
+ cptr = strrchr(fname, '/');
+ if (!isDir)
+ {
+ cptr = strrchr(fname, '/');
+ if (cptr) pstrcat(streampath, cptr+1);
+ else pstrcat(streampath, fname);
+ }
+ pstrcat(streampath, stream);
+ }
+ DEBUG(4,("MACEXTENSION-makestreampath: streampath = %s\n", streampath));
+}
+
+/*
+** Given a path to file/directory open the stream in question.
+*/
+int openstream(char *fname, char *stream, int oflag, int mode, int isDir)
+{
+ pstring streampath;
+ char *cptr;
+
+ makestreampath(fname, stream, streampath, mode, isDir, False);
+ return(open(streampath, oflag, mode));
+}
+
+/*
+** Fill in the AFP structure with the default values and
+** then write it out.
+*/
+void writedefaultafp(int fd, SambaAfpInfo *safp, int writeit)
+{
+ safp->afp.afpi_Signature = AFP_Signature; /* Must be *(PDWORD)"AFP" */
+ safp->afp.afpi_Version = AFP_Version; /* Must be 0x00010000 */
+ safp->afp.afpi_Reserved1 = 0;
+ safp->afp.afpi_BackupTime = AFP_BackupTime; /* Backup time for the file/dir */
+ bzero(safp->afp.afpi_FinderInfo, AFP_FinderSize); /* Finder Info (32 bytes) */
+ bzero(safp->afp.afpi_ProDosInfo, 6); /* ProDos Info (6 bytes) # */
+ bzero(safp->afp.afpi_Reserved2, 6);
+ safp->createtime = time(NULL);
+ if (writeit) (void)write(fd, safp, sizeof(*safp));
+}
+
+/*
+** Check to see if the fname has a stream component.
+** If it does then check to see if it is the data fork
+** stream. If so then just remove the stream since we
+** treat them the same otherwise build a path to the
+** streams folder.
+** Return true if it is a stream
+** Return false no stream and the name has not been touched.
+*/
+int CheckForStream(char *fname)
+{
+ pstring streampath;
+ char *cptr;
+
+ cptr = strrchr(fname, ':');
+ /* Must be a streams file */
+ if (cptr && strequal(cptr, DefaultStreamTest))
+ {
+ cptr = strstr(fname, AFPDATA_STREAM);
+ if (cptr) *cptr = 0;/* The datafork just remove the stream name */
+ else /* Build the streams path */
+ {
+ makestreampath(fname, "", streampath, 1, False, False);
+ pstrcpy(fname, streampath);
+ }
+ return(True);
+ }
+ return(False);
+}
diff --git a/source/lib/stub_uid.c b/source/lib/stub_uid.c
new file mode 100644
index 00000000000..6d91f263b8b
--- /dev/null
+++ b/source/lib/stub_uid.c
@@ -0,0 +1,36 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB Utilities
+ Copyright (C) Andrew Tridgell 1997-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/* we need these because we link to locking*.o */
+void become_root(BOOL save_dir)
+{
+}
+
+void unbecome_root(BOOL restore_dir)
+{
+}
+
+const vuser_key *get_sec_ctx(void)
+{
+ return NULL;
+}
diff --git a/source/lib/surs.c b/source/lib/surs.c
new file mode 100644
index 00000000000..0b2f40c8511
--- /dev/null
+++ b/source/lib/surs.c
@@ -0,0 +1,54 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Groupname handling
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/******************************************************************
+ converts SID + SID_NAME_USE type to a UNIX id. the Domain SID is,
+ and can only be, our own SID.
+ ********************************************************************/
+BOOL surs_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id, BOOL create)
+{
+#ifdef WITH_NT5LDAP
+ return surs_nt5ldap_sam_sid_to_unixid(id, type, sid, create);
+#endif
+#if WITH_SURSTDB
+ return surs_tdb_sam_sid_to_unixid(id, type, sid, create);
+#endif
+ return surs_algdomonly_sam_sid_to_unixid(sid, type, id, create);
+}
+
+/******************************************************************
+ converts UNIX gid + SID_NAME_USE type to a SID. the Domain SID is,
+ and can only be, our own SID.
+ ********************************************************************/
+BOOL surs_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid, BOOL create)
+{
+#ifdef WITH_NT5LDAP
+ return surs_nt5ldap_unixid_to_sam_sid(id, type, sid, create);
+#endif
+#if WITH_SURSTDB
+ return surs_tdb_unixid_to_sam_sid(id, type, sid, create);
+#endif
+ return surs_algdomonly_unixid_to_sam_sid(id, type, sid, create);
+}
diff --git a/source/lib/sursalgdomonly.c b/source/lib/sursalgdomonly.c
new file mode 100644
index 00000000000..583928872b2
--- /dev/null
+++ b/source/lib/sursalgdomonly.c
@@ -0,0 +1,164 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Groupname handling
+ Copyright (C) Jeremy Allison 1998-2000.
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * algorithmic implementation of a SURS (sid to uid resolution) table.
+ * only does the local SAM, does NOT even do domain membership.
+ * repeat: this is for the LOCAL SAM only, not even the BUILTIN domain.
+ */
+
+#include "includes.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ converts a RID to a UNIX ID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static BOOL sursalg_rid_to_unix_id(uint32 rid, uint32 *id, int type)
+{
+ if((id == NULL) || (rid < 1000))
+ return False;
+ rid -= 1000;
+ if((rid % RID_MULTIPLIER) != type)
+ return False;
+ *id = rid / RID_MULTIPLIER;
+ return True;
+}
+
+/*******************************************************************
+ converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static BOOL sursalg_user_rid_to_uid(uint32 user_rid, uint32 *id)
+{
+ return sursalg_rid_to_unix_id(user_rid, id, RID_TYPE_USER);
+}
+
+/*******************************************************************
+ converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static BOOL sursalg_group_rid_to_gid(uint32 group_rid, uint32 *id)
+{
+ return sursalg_rid_to_unix_id(group_rid, id, RID_TYPE_GROUP);
+}
+
+/*******************************************************************
+ converts NT Alias RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static BOOL sursalg_alias_rid_to_gid(uint32 alias_rid, uint32 *id)
+{
+ return sursalg_rid_to_unix_id(alias_rid, id, RID_TYPE_ALIAS);
+}
+
+/*******************************************************************
+ converts NT Group RID to a UNIX uid. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static uint32 sursalg_gid_to_group_rid(uint32 gid)
+{
+ uint32 grp_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_GROUP);
+ return grp_rid;
+}
+
+/******************************************************************
+ converts UNIX gid to an NT Alias RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static uint32 sursalg_gid_to_alias_rid(uint32 gid)
+{
+ uint32 alias_rid = ((((gid)*RID_MULTIPLIER) + 1000) | RID_TYPE_ALIAS);
+ return alias_rid;
+}
+
+/*******************************************************************
+ converts UNIX uid to an NT User RID. NOTE: IS SOMETHING SPECIFIC TO SAMBA
+ ********************************************************************/
+static uint32 sursalg_uid_to_user_rid(uint32 uid)
+{
+ uint32 user_rid = ((((uid)*RID_MULTIPLIER) + 1000) | RID_TYPE_USER);
+ return user_rid;
+}
+
+/******************************************************************
+ converts SID + SID_NAME_USE type to a UNIX id. the Domain SID is,
+ and can only be, our own SID.
+ ********************************************************************/
+BOOL surs_algdomonly_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id,
+ BOOL create)
+{
+ DOM_SID tmp_sid;
+ uint32 rid;
+
+ sid_copy(&tmp_sid, sid);
+ sid_split_rid(&tmp_sid, &rid);
+ if (!sid_equal(&global_sam_sid, &tmp_sid))
+ {
+ return False;
+ }
+
+ switch (type)
+ {
+ case SID_NAME_USER:
+ {
+ return sursalg_user_rid_to_uid(rid, id);
+ }
+ case SID_NAME_ALIAS:
+ {
+ return sursalg_alias_rid_to_gid(rid, id);
+ }
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ {
+ return sursalg_group_rid_to_gid(rid, id);
+ }
+ }
+ return False;
+}
+
+/******************************************************************
+ converts UNIX gid + SID_NAME_USE type to a SID. the Domain SID is,
+ and can only be, our own SID.
+ ********************************************************************/
+BOOL surs_algdomonly_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid,
+ BOOL create)
+{
+ sid_copy(sid, &global_sam_sid);
+ switch (type)
+ {
+ case SID_NAME_USER:
+ {
+ sid_append_rid(sid, sursalg_uid_to_user_rid(id));
+ return True;
+ }
+ case SID_NAME_ALIAS:
+ {
+ sid_append_rid(sid, sursalg_gid_to_alias_rid(id));
+ return True;
+ }
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ {
+ sid_append_rid(sid, sursalg_gid_to_group_rid(id));
+ return True;
+ }
+ }
+ return False;
+}
+
diff --git a/source/lib/sursalgnt5ldap.c b/source/lib/sursalgnt5ldap.c
new file mode 100644
index 00000000000..c6fe9b11afb
--- /dev/null
+++ b/source/lib/sursalgnt5ldap.c
@@ -0,0 +1,95 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Groupname handling
+ Copyright (C) Jeremy Allison 1998-2000.
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
+ Copyright (C) Luke Howard 2000.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * LDAP implementation of a SURS (sid to uid resolution) table.
+ */
+
+#include "includes.h"
+
+#ifdef WITH_NT5LDAP
+
+#include "sids.h"
+#include "ldapdb.h"
+
+/******************************************************************
+ converts SID + SID_NAME_USE type to a UNIX id.
+ ********************************************************************/
+BOOL surs_nt5ldap_sam_sid_to_unixid(LDAPDB *hds, DOM_SID * sid, uint32 type,
+ uint32 * id, BOOL create)
+{
+ if (!ldapdb_lookup_by_sid(hds, sid))
+ return False;
+
+ switch (type)
+ {
+ case RID_TYPE_USER:
+ return ldapdb_get_uint32(hds, "uidNumber", id);
+ case RID_TYPE_GROUP:
+ case RID_TYPE_ALIAS:
+ return ldapdb_get_uint32(hds, "gidNumber", id);
+ default:
+ break;
+ }
+
+ return False;
+}
+
+/******************************************************************
+ converts UNIX gid + SID_NAME_USE type to a SID.
+ ********************************************************************/
+BOOL surs_nt5ldap_unixid_to_sam_sid(LDAPDB *hds, uint32 id, uint32 type,
+ DOM_SID * sid, BOOL create)
+{
+ char *attribute;
+ fstring filter;
+ char *attrs[] = { "objectSid", NULL };
+ BOOL ret;
+
+ switch (type)
+ {
+ case SID_NAME_USER:
+ {
+ attribute = "uidNumber";
+ break;
+ }
+ case SID_NAME_ALIAS:
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ {
+ attribute = "gidNumber";
+ break;
+ }
+ default:
+ {
+ return False;
+ }
+ }
+
+ slprintf(filter, sizeof(filter) - 1, "(&(objectSid=*)(%s=%d))",
+ attribute, id);
+ return ldapdb_search(hds, NULL, filter, attrs, 1)
+ && ldapdb_get_sid(hds, "objectSid", sid);
+}
+
+#endif /* WITH_NT5LDAP */
diff --git a/source/lib/surstdb.c b/source/lib/surstdb.c
new file mode 100644
index 00000000000..2f2da61b3de
--- /dev/null
+++ b/source/lib/surstdb.c
@@ -0,0 +1,544 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Groupname handling
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * tdb implementation of a SURS (sid to uid resolution) table.
+ */
+
+#include "includes.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+static TDB_CONTEXT *udb = NULL;
+static TDB_CONTEXT *sdb = NULL;
+static TDB_CONTEXT *gdb = NULL;
+
+static BOOL surs_init_db(void)
+{
+ if (sdb != NULL && udb != NULL && gdb != NULL)
+ {
+ return True;
+ }
+
+ become_root(False);
+ sdb =
+ tdb_open(lock_path("surssid.tdb"), 0, 0, O_RDONLY | O_CREAT,
+ 0644);
+ udb =
+ tdb_open(lock_path("sursuid.tdb"), 0, 0, O_RDONLY | O_CREAT,
+ 0644);
+ gdb =
+ tdb_open(lock_path("sursgid.tdb"), 0, 0, O_RDONLY | O_CREAT,
+ 0644);
+ unbecome_root(False);
+
+ if (gdb == NULL || sdb == NULL || udb == NULL)
+ {
+ tdb_close(sdb);
+ tdb_close(udb);
+ tdb_close(gdb);
+
+ sdb = NULL;
+ udb = NULL;
+ gdb = NULL;
+
+ DEBUG(0, ("surs_init_db: failed\n"));
+ return False;
+ }
+
+ DEBUG(10, ("surs_init_db: opened\n"));
+
+ return True;
+}
+
+static BOOL tdb_delete_sid(const DOM_SID * sid)
+{
+ DOM_SID s;
+ prs_struct key;
+
+ sid_copy(&s, sid);
+
+ if (sdb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10, ("delete NT user\n"));
+
+ prs_init(&key, 0, 4, False);
+ if (!smb_io_dom_sid("sid", &s, &key, 0))
+ {
+ prs_free_data(&key);
+ return False;
+ }
+
+ prs_tdb_delete(sdb, &key);
+ prs_free_data(&key);
+
+ return True;
+}
+
+static BOOL tdb_delete_gid(uint32 id)
+{
+ prs_struct key;
+
+ if (gdb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10, ("delete unix group\n"));
+
+ prs_init(&key, 0, 4, False);
+ if (!_prs_uint32("gid", &key, 0, &id))
+ {
+ prs_free_data(&key);
+ return False;
+ }
+
+ prs_tdb_delete(gdb, &key);
+ prs_free_data(&key);
+
+ return True;
+}
+
+static BOOL tdb_delete_uid(uint32 id)
+{
+ prs_struct key;
+
+ if (udb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10, ("delete unix user\n"));
+
+ prs_init(&key, 0, 4, False);
+ if (!_prs_uint32("uid", &key, 0, &id))
+ {
+ prs_free_data(&key);
+ return False;
+ }
+
+ prs_tdb_delete(udb, &key);
+ prs_free_data(&key);
+
+ return True;
+}
+
+static BOOL tdb_lookup_gid(uint32 gid, DOM_SID * uk)
+{
+ prs_struct key;
+ prs_struct data;
+
+ if (gdb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10, ("lookup gid\n"));
+
+ prs_init(&key, 0, 4, False);
+ if (!_prs_uint32("gid", &key, 0, &gid))
+ {
+ prs_free_data(&key);
+ return False;
+ }
+
+ prs_tdb_fetch(gdb, &key, &data);
+
+ if (uk != NULL)
+ {
+ if (!smb_io_dom_sid("sid", uk, &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+static BOOL tdb_lookup_uid(uint32 uid, DOM_SID * uk)
+{
+ prs_struct key;
+ prs_struct data;
+
+ if (udb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10, ("lookup uid\n"));
+
+ prs_init(&key, 0, 4, False);
+ if (!_prs_uint32("uid", &key, 0, &uid))
+ {
+ prs_free_data(&key);
+ return False;
+ }
+
+ prs_tdb_fetch(udb, &key, &data);
+
+ if (uk != NULL)
+ {
+ if (!smb_io_dom_sid("sid", uk, &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+static BOOL tdb_store_gid(uint32 gid, const DOM_SID * uk)
+{
+ prs_struct key;
+ prs_struct data;
+
+ DOM_SID k = *uk;
+
+ if (gdb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10, ("storing gid\n"));
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!_prs_uint32("gid", &key, 0, &gid) ||
+ !smb_io_dom_sid("sid", &k, &data, 0) ||
+ prs_tdb_store(gdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+static BOOL tdb_store_uid(uint32 uid, const DOM_SID * uk)
+{
+ prs_struct key;
+ prs_struct data;
+
+ DOM_SID k = *uk;
+
+ if (udb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10, ("storing uid\n"));
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!_prs_uint32("uid", &key, 0, &uid) ||
+ !smb_io_dom_sid("sid", &k, &data, 0) ||
+ prs_tdb_store(udb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+static BOOL tdb_lookup_sid(const DOM_SID * uk, uint32 * id)
+{
+ prs_struct key;
+ prs_struct data;
+ DOM_SID k;
+
+ sid_copy(&k, uk);
+
+ if (sdb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10, ("lookup sid\n"));
+
+ prs_init(&key, 0, 4, False);
+ if (!smb_io_dom_sid("sid", &k, &key, 0))
+ {
+ prs_free_data(&key);
+ return False;
+ }
+
+ prs_tdb_fetch(sdb, &key, &data);
+
+ if (id != NULL)
+ {
+ if (!_prs_uint32("uid", &data, 0, id))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+static BOOL tdb_store_sid(const DOM_SID * uk, uint32 id)
+{
+ prs_struct key;
+ prs_struct data;
+
+ DOM_SID k;
+
+ sid_copy(&k, uk);
+
+ if (sdb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10, ("storing SID\n"));
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!smb_io_dom_sid("sid", &k, &key, 0) ||
+ !_prs_uint32("uid", &data, 0, &id) ||
+ prs_tdb_store(sdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+static BOOL tdb_surs_unlock(void)
+{
+ BOOL ret = True;
+ if (gdb == NULL || sdb == NULL || udb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+ if (tdb_writeunlock(sdb) != 0)
+ ret = False;
+ if (tdb_writeunlock(udb) != 0)
+ ret = False;
+ if (tdb_writeunlock(gdb) != 0)
+ ret = False;
+
+ return ret;
+}
+
+static BOOL tdb_surs_lock(void)
+{
+ if (gdb == NULL || sdb == NULL || udb == NULL)
+ {
+ if (!surs_init_db())
+ {
+ return False;
+ }
+ }
+ return tdb_writelock(sdb) == 0 &&
+ tdb_writelock(udb) == 0 && tdb_writelock(gdb) == 0;
+}
+
+/******************************************************************
+ converts SID + SID_NAME_USE type to a UNIX id.
+ ********************************************************************/
+BOOL surs_tdb_sam_sid_to_unixid(DOM_SID * sid, uint32 type, uint32 * id,
+ BOOL create)
+{
+ BOOL ret = False;
+ if (create)
+ {
+ if (!tdb_surs_lock())
+ {
+ tdb_surs_unlock();
+ return False;
+ }
+ }
+ switch (type)
+ {
+ case SID_NAME_USER:
+ {
+ ret = tdb_lookup_sid(sid, id);
+ }
+ case SID_NAME_ALIAS:
+ {
+ ret = tdb_lookup_sid(sid, id);
+ }
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ {
+ ret = tdb_lookup_sid(sid, id);
+ }
+ }
+ if (!create)
+ {
+ /* just in lookup-mode */
+ return ret;
+ }
+
+ if (ret)
+ {
+ /* hm, it was already there */
+ tdb_surs_unlock();
+ return ret;
+ }
+
+ switch (type)
+ {
+ case SID_NAME_USER:
+ {
+ ret = tdb_store_uid(*id, sid)
+ && tdb_store_sid(sid, *id);
+ }
+ case SID_NAME_ALIAS:
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ {
+ ret = tdb_store_gid(*id, sid)
+ && tdb_store_sid(sid, *id);
+ }
+ }
+
+ tdb_surs_unlock();
+
+ return ret;
+}
+
+/******************************************************************
+ converts UNIX gid + SID_NAME_USE type to a SID.
+ ********************************************************************/
+BOOL surs_tdb_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID * sid,
+ BOOL create)
+{
+ BOOL ret = False;
+
+ if (create)
+ {
+ if (!tdb_surs_lock())
+ {
+ tdb_surs_unlock();
+ return False;
+ }
+ }
+ switch (type)
+ {
+ case SID_NAME_USER:
+ {
+ ret = tdb_lookup_uid(id, sid);
+ }
+ case SID_NAME_ALIAS:
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ {
+ ret = tdb_lookup_gid(id, sid);
+ }
+ }
+
+ if (!create)
+ {
+ /* just in lookup-mode */
+ return ret;
+ }
+
+ if (ret)
+ {
+ /* hm, it was already there */
+ tdb_surs_unlock();
+ return ret;
+ }
+
+ switch (type)
+ {
+ case SID_NAME_USER:
+ {
+ ret = tdb_store_uid(id, sid)
+ && tdb_store_sid(sid, id);
+ }
+ case SID_NAME_ALIAS:
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ {
+ ret = tdb_store_gid(id, sid)
+ && tdb_store_sid(sid, id);
+ }
+ }
+
+ tdb_surs_unlock();
+
+ return ret;
+}
diff --git a/source/lib/system.c b/source/lib/system.c
index 9ef0af494f3..94e1899022e 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -60,7 +60,7 @@ static int pollfd(int fd)
return(r);
}
-int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
+int sys_select(int maxfd, fd_set *fds, fd_set *w_fds, struct timeval *tval)
{
fd_set fds2;
int counter=0;
@@ -90,7 +90,7 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
}
#else /* !NO_SELECT */
-int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
+int sys_select(int maxfd, fd_set *r_fds, fd_set *w_fds, struct timeval *tval)
{
#ifdef USE_POLL
struct pollfd pfd[256];
@@ -131,7 +131,8 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
do {
if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
errno = 0;
- selrtn = select(maxfd,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
+ selrtn = select(maxfd,SELECT_CAST r_fds,SELECT_CAST w_fds,
+ NULL,tval?&t2:NULL);
} while (selrtn<0 && errno == EINTR);
return(selrtn);
@@ -140,54 +141,16 @@ int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
#endif /* NO_SELECT */
/*******************************************************************
- A wrapper for usleep in case we don't have one.
-********************************************************************/
-
-int sys_usleep(long usecs)
-{
-#ifndef HAVE_USLEEP
- struct timeval tval;
-#endif
-
- /*
- * We need this braindamage as the glibc usleep
- * is not SPEC1170 complient... grumble... JRA.
- */
-
- if(usecs < 0 || usecs > 1000000) {
- errno = EINVAL;
- return -1;
- }
-
-#if HAVE_USLEEP
- usleep(usecs);
- return 0;
-#else /* HAVE_USLEEP */
- /*
- * Fake it with select...
- */
- tval.tv_sec = 0;
- tval.tv_usec = usecs/1000;
- select(0,NULL,NULL,NULL,&tval);
- return 0;
-#endif /* HAVE_USLEEP */
-}
-
-/*******************************************************************
A stat() wrapper that will deal with 64 bit filesizes.
********************************************************************/
int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
{
- int ret;
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
- ret = stat64(fname, sbuf);
+#if defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
+ return stat64(fname, sbuf);
#else
- ret = stat(fname, sbuf);
+ return stat(fname, sbuf);
#endif
- /* we always want directories to appear zero size */
- if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
- return ret;
}
/*******************************************************************
@@ -196,15 +159,11 @@ int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
{
- int ret;
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
- ret = fstat64(fd, sbuf);
+#if defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
+ return fstat64(fd, sbuf);
#else
- ret = fstat(fd, sbuf);
+ return fstat(fd, sbuf);
#endif
- /* we always want directories to appear zero size */
- if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
- return ret;
}
/*******************************************************************
@@ -213,15 +172,11 @@ int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
{
- int ret;
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
- ret = lstat64(fname, sbuf);
+#if defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
+ return lstat64(fname, sbuf);
#else
- ret = lstat(fname, sbuf);
+ return lstat(fname, sbuf);
#endif
- /* we always want directories to appear zero size */
- if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
- return ret;
}
/*******************************************************************
@@ -230,7 +185,7 @@ int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
int sys_ftruncate(int fd, SMB_OFF_T offset)
{
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
+#if defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
return ftruncate64(fd, offset);
#else
return ftruncate(fd, offset);
@@ -243,7 +198,7 @@ int sys_ftruncate(int fd, SMB_OFF_T offset)
SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
{
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
+#if defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
return lseek64(fd, offset, whence);
#else
return lseek(fd, offset, whence);
@@ -256,10 +211,8 @@ SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
{
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
+#if defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
return fseek64(fp, offset, whence);
-#elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
- return fseeko64(fp, offset, whence);
#else
return fseek(fp, offset, whence);
#endif
@@ -271,10 +224,8 @@ int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
SMB_OFF_T sys_ftell(FILE *fp)
{
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
+#if defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
return (SMB_OFF_T)ftell64(fp);
-#elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
- return (SMB_OFF_T)ftello64(fp);
#else
return (SMB_OFF_T)ftell(fp);
#endif
@@ -323,36 +274,19 @@ FILE *sys_fopen(const char *path, const char *type)
#endif
}
-#if defined(HAVE_MMAP)
-
/*******************************************************************
An mmap() wrapper that will deal with 64 bit filesizes.
********************************************************************/
void *sys_mmap(void *addr, size_t len, int prot, int flags, int fd, SMB_OFF_T offset)
{
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_MMAP64)
+#if defined(LARGE_SMB_OFF_T) && defined(HAVE_MMAP64)
return mmap64(addr, len, prot, flags, fd, offset);
#else
return mmap(addr, len, prot, flags, fd, offset);
#endif
}
-#endif /* HAVE_MMAP */
-
-/*******************************************************************
- A readdir wrapper that will deal with 64 bit filesizes.
-********************************************************************/
-
-SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
-{
-#if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
- return readdir64(dirp);
-#else
- return readdir(dirp);
-#endif
-}
-
/*******************************************************************
The wait() calls vary between systems
********************************************************************/
@@ -371,19 +305,18 @@ system wrapper for getwd
********************************************************************/
char *sys_getwd(char *s)
{
- char *wd;
+ char *wd;
#ifdef HAVE_GETCWD
- wd = (char *)getcwd(s, sizeof (pstring));
+ wd = (char *)getcwd(s, sizeof (pstring));
#else
- wd = (char *)getwd(s);
+ wd = (char *)getwd(s);
#endif
- return wd;
+ return wd;
}
/*******************************************************************
chown isn't used much but OS/2 doesn't have it
********************************************************************/
-
int sys_chown(const char *fname,uid_t uid,gid_t gid)
{
#ifndef HAVE_CHOWN
@@ -480,12 +413,9 @@ BOOL set_process_capability( uint32 cap_flag, BOOL enable )
if (cap_set_proc(cap) == -1) {
DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
strerror(errno)));
- cap_free(cap);
return False;
}
- cap_free(cap);
-
DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
}
#endif
@@ -517,12 +447,9 @@ BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
if (cap_set_proc(cap) == -1) {
DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
strerror(errno)));
- cap_free(cap);
return False;
}
- cap_free(cap);
-
DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
}
#endif
@@ -562,20 +489,6 @@ void sys_srandom(unsigned int seed)
}
/**************************************************************************
- Returns equivalent to NGROUPS_MAX - using sysconf if needed.
-****************************************************************************/
-
-int groups_max(void)
-{
-#if defined(SYSCONF_SC_NGROUPS_MAX)
- int ret = sysconf(_SC_NGROUPS_MAX);
- return (ret == -1) ? NGROUPS_MAX : ret;
-#else
- return NGROUPS_MAX;
-#endif
-}
-
-/**************************************************************************
Wrapper for getgroups. Deals with broken (int) case.
****************************************************************************/
@@ -603,8 +516,7 @@ int sys_getgroups(int setlen, gid_t *gidset)
return -1;
}
- if (setlen == 0)
- setlen = groups_max();
+ if (setlen == 0) setlen = 1;
if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
DEBUG(0,("sys_getgroups: Malloc fail.\n"));
@@ -626,57 +538,6 @@ int sys_getgroups(int setlen, gid_t *gidset)
#endif /* HAVE_BROKEN_GETGROUPS */
}
-#ifdef HAVE_SETGROUPS
-
-/**************************************************************************
- Wrapper for setgroups. Deals with broken (int) case. Automatically used
- if we have broken getgroups.
-****************************************************************************/
-
-int sys_setgroups(int setlen, gid_t *gidset)
-{
-#if !defined(HAVE_BROKEN_GETGROUPS)
- return setgroups(setlen, gidset);
-#else
-
- GID_T *group_list;
- int i ;
-
- if (setlen == 0)
- return 0 ;
-
- if (setlen < 0 || setlen > groups_max()) {
- errno = EINVAL;
- return -1;
- }
-
- /*
- * Broken case. We need to allocate a
- * GID_T array of size setlen.
- */
-
- if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
- DEBUG(0,("sys_setgroups: Malloc fail.\n"));
- return -1;
- }
-
- for(i = 0; i < setlen; i++)
- group_list[i] = (GID_T) gidset[i];
-
- if(setgroups(setlen, group_list) != 0) {
- int saved_errno = errno;
- free((char *)group_list);
- errno = saved_errno;
- return -1;
- }
-
- free((char *)group_list);
- return 0 ;
-#endif /* HAVE_BROKEN_GETGROUPS */
-}
-
-#endif /* HAVE_SETGROUPS */
-
/*
* We only wrap pw_name and pw_passwd for now as these
* are the only potentially modified fields.
@@ -686,7 +547,7 @@ int sys_setgroups(int setlen, gid_t *gidset)
Helper function for getpwnam/getpwuid wrappers.
****************************************************************************/
-static struct passwd *setup_pwret(struct passwd *pass)
+struct passwd *copy_passwd_struct(struct passwd *pass)
{
static pstring pw_name;
static pstring pw_passwd;
@@ -697,16 +558,25 @@ static struct passwd *setup_pwret(struct passwd *pass)
return NULL;
}
+ if (pass == &pw_ret)
+ {
+ /* catch silly error where buffer was already copied */
+ DEBUG(0,("copy_passwd_struct: can't copy internal buffer!\n"));
+ return NULL;
+ }
+
memcpy((char *)&pw_ret, pass, sizeof(struct passwd));
if (pass->pw_name)
{
+ pw_name[0] = '\0';
pw_ret.pw_name = pw_name;
pstrcpy(pw_ret.pw_name, pass->pw_name);
}
if (pass->pw_passwd)
{
+ pw_passwd[0] = '\0';
pw_ret.pw_passwd = pw_passwd;
pstrcpy(pw_ret.pw_passwd, pass->pw_passwd);
}
@@ -720,7 +590,7 @@ static struct passwd *setup_pwret(struct passwd *pass)
struct passwd *sys_getpwnam(const char *name)
{
- return setup_pwret(getpwnam(name));
+ return copy_passwd_struct(getpwnam(name));
}
/**************************************************************************
@@ -729,382 +599,5 @@ struct passwd *sys_getpwnam(const char *name)
struct passwd *sys_getpwuid(uid_t uid)
{
- return setup_pwret(getpwuid(uid));
-}
-
-/**************************************************************************
- The following are the UNICODE versions of *all* system interface functions
- called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
- which currently are left as ascii as they are not used other than in name
- resolution.
-****************************************************************************/
-
-/**************************************************************************
- Wide stat. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
-{
- pstring fname;
- return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
-}
-
-/**************************************************************************
- Wide lstat. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
-{
- pstring fname;
- return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
-}
-
-/**************************************************************************
- Wide creat. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
-{
- pstring fname;
- return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
-}
-
-/**************************************************************************
- Wide open. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
-{
- pstring fname;
- return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
-}
-
-/**************************************************************************
- Wide fopen. Just narrow and call sys_xxx.
-****************************************************************************/
-
-FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
-{
- pstring fname;
- return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
-}
-
-/**************************************************************************
- Wide opendir. Just narrow and call sys_xxx.
-****************************************************************************/
-
-DIR *wsys_opendir(const smb_ucs2_t *wfname)
-{
- pstring fname;
- return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
-}
-
-/**************************************************************************
- Wide readdir. Return a structure pointer containing a wide filename.
-****************************************************************************/
-
-SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
-{
- static SMB_STRUCT_WDIRENT retval;
- SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
-
- if(!dirval)
- return NULL;
-
- /*
- * The only POSIX defined member of this struct is d_name.
- */
-
- unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
-
- return &retval;
-}
-
-/**************************************************************************
- Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
-****************************************************************************/
-
-smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
-{
- pstring fname;
- char *p = sys_getwd(fname);
-
- if(!p)
- return NULL;
-
- return unix_to_unicode(s, p, sizeof(wpstring));
-}
-
-/**************************************************************************
- Wide chown. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
-{
- pstring fname;
- return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
-}
-
-/**************************************************************************
- Wide chroot. Just narrow and call sys_xxx.
-****************************************************************************/
-
-int wsys_chroot(const smb_ucs2_t *wfname)
-{
- pstring fname;
- return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
-}
-
-/**************************************************************************
- Wide getpwnam. Return a structure pointer containing wide names.
-****************************************************************************/
-
-SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
-{
- static SMB_STRUCT_WPASSWD retval;
- fstring name;
- struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
-
- if(!pwret)
- return NULL;
-
- unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
- retval.pw_passwd = pwret->pw_passwd;
- retval.pw_uid = pwret->pw_uid;
- retval.pw_gid = pwret->pw_gid;
- unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
- unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
- unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
-
- return &retval;
-}
-
-/**************************************************************************
- Wide getpwuid. Return a structure pointer containing wide names.
-****************************************************************************/
-
-SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
-{
- static SMB_STRUCT_WPASSWD retval;
- struct passwd *pwret = sys_getpwuid(uid);
-
- if(!pwret)
- return NULL;
-
- unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
- retval.pw_passwd = pwret->pw_passwd;
- retval.pw_uid = pwret->pw_uid;
- retval.pw_gid = pwret->pw_gid;
- unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
- unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
- unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
-
- return &retval;
-}
-
-/**************************************************************************
- Extract a command into an arg list. Uses a static pstring for storage.
- Caller frees returned arg list (which contains pointers into the static pstring).
-****************************************************************************/
-
-static char **extract_args(const char *command)
-{
- static pstring trunc_cmd;
- char *ptr;
- int argcl;
- char **argl = NULL;
- int i;
-
- pstrcpy(trunc_cmd, command);
-
- if(!(ptr = strtok(trunc_cmd, " \t"))) {
- errno = EINVAL;
- return NULL;
- }
-
- /*
- * Count the args.
- */
-
- for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
- argcl++;
-
- if((argl = (char **)malloc((argcl + 1) * sizeof(char *))) == NULL)
- return NULL;
-
- /*
- * Now do the extraction.
- */
-
- pstrcpy(trunc_cmd, command);
-
- ptr = strtok(trunc_cmd, " \t");
- i = 0;
- argl[i++] = ptr;
-
- while((ptr = strtok(NULL, " \t")) != NULL)
- argl[i++] = ptr;
-
- argl[i++] = NULL;
- return argl;
-}
-
-/**************************************************************************
- Wrapper for popen. Safer as it doesn't search a path.
- Modified from the glibc sources.
-****************************************************************************/
-
-typedef struct _popen_list
-{
- FILE *fp;
- pid_t child_pid;
- struct _popen_list *next;
-} popen_list;
-
-static popen_list *popen_chain;
-
-FILE *sys_popen(const char *command, const char *mode)
-{
- int parent_end, child_end;
- int pipe_fds[2];
- popen_list *entry = NULL;
- char **argl = NULL;
-
- if (pipe(pipe_fds) < 0)
- return NULL;
-
- if (mode[0] == 'r' && mode[1] == '\0') {
- parent_end = pipe_fds[0];
- child_end = pipe_fds[1];
- } else if (mode[0] == 'w' && mode[1] == '\0') {
- parent_end = pipe_fds[1];
- child_end = pipe_fds[0];
- } else {
- errno = EINVAL;
- goto err_exit;
- }
-
- if (!*command) {
- errno = EINVAL;
- goto err_exit;
- }
-
- if((entry = (popen_list *)malloc(sizeof(popen_list))) == NULL)
- goto err_exit;
-
- /*
- * Extract the command and args into a NULL terminated array.
- */
-
- if(!(argl = extract_args(command)))
- goto err_exit;
-
- entry->child_pid = fork();
-
- if (entry->child_pid == -1) {
-
- /*
- * Error !
- */
-
- goto err_exit;
- }
-
- if (entry->child_pid == 0) {
-
- /*
- * Child !
- */
-
- int child_std_end = (mode[0] == 'r') ? STDOUT_FILENO : STDIN_FILENO;
- popen_list *p;
-
- close(parent_end);
- if (child_end != child_std_end) {
- dup2 (child_end, child_std_end);
- close (child_end);
- }
-
- /*
- * POSIX.2: "popen() shall ensure that any streams from previous
- * popen() calls that remain open in the parent process are closed
- * in the new child process."
- */
-
- for (p = popen_chain; p; p = p->next)
- close(fileno(p->fp));
-
- execv(argl[0], argl);
- _exit (127);
- }
-
- /*
- * Parent.
- */
-
- close (child_end);
- free((char *)argl);
-
- /*
- * Create the FILE * representing this fd.
- */
- entry->fp = fdopen(parent_end, mode);
-
- /* Link into popen_chain. */
- entry->next = popen_chain;
- popen_chain = entry;
-
- return entry->fp;
-
-err_exit:
-
- if(entry)
- free((char *)entry);
- if(argl)
- free((char *)argl);
- close(pipe_fds[0]);
- close(pipe_fds[1]);
- return NULL;
-}
-
-/**************************************************************************
- Wrapper for pclose. Modified from the glibc sources.
-****************************************************************************/
-
-int sys_pclose( FILE *fp)
-{
- int wstatus;
- popen_list **ptr = &popen_chain;
- popen_list *entry = NULL;
- pid_t wait_pid;
- int status = -1;
-
- /* Unlink from popen_chain. */
- for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
- if ((*ptr)->fp == fp) {
- entry = *ptr;
- *ptr = (*ptr)->next;
- status = 0;
- break;
- }
- }
-
- if (status < 0 || close(fileno(entry->fp)) < 0)
- return -1;
-
- /*
- * As Samba is catching and eating child process
- * exits we don't really care about the child exit
- * code, a -1 with errno = ECHILD will do fine for us.
- */
-
- do {
- wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
- } while (wait_pid == -1 && errno == EINTR);
-
- free((char *)entry);
-
- if (wait_pid == -1)
- return -1;
- return wstatus;
+ return copy_passwd_struct(getpwuid(uid));
}
diff --git a/source/lib/time.c b/source/lib/time.c
index 5fd260e5c90..c332b906a0c 100644
--- a/source/lib/time.c
+++ b/source/lib/time.c
@@ -247,7 +247,7 @@ its the GMT you get by taking a localtime and adding the
serverzone. This is NOT the same as GMT in some cases. This routine
converts this to real GMT.
****************************************************************************/
-time_t nt_time_to_unix(NTTIME *nt)
+time_t nt_time_to_unix(const NTTIME *nt)
{
double d;
time_t ret;
@@ -298,13 +298,6 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
{
double d;
- if (t==0)
- {
- nt->low = 0;
- nt->high = 0;
- return;
- }
-
/* this converts GMT to kludge-GMT */
t -= LocTimeDiff(t) - serverzone;
@@ -316,6 +309,15 @@ void unix_to_nt_time(NTTIME *nt, time_t t)
nt->low = (uint32)(d - ((double)nt->high)*4.0*(double)(1<<30));
}
+/****************************************************************************
+initialise an NTTIME to -1, which means "unknown" or "don't expire"
+****************************************************************************/
+
+void init_nt_time(NTTIME *nt)
+{
+ nt->high = 0x7FFFFFFF;
+ nt->low = 0xFFFFFFFF;
+}
/****************************************************************************
take an NTTIME structure, containing high / low time. convert to unix time.
@@ -504,57 +506,21 @@ char *http_timestring(time_t t)
/****************************************************************************
- Return the date and time as a string
+ return the date and time as a string
****************************************************************************/
-
-char *timestring(BOOL hires)
+char *timestring(void )
{
static fstring TimeBuf;
- struct timeval tp;
- time_t t;
- struct tm *tm;
+ time_t t = time(NULL);
+ struct tm *tm = LocalTime(&t);
- if (hires) {
- GetTimeOfDay(&tp);
- t = (time_t)tp.tv_sec;
- } else {
- t = time(NULL);
- }
- tm = LocalTime(&t);
if (!tm) {
- if (hires) {
- slprintf(TimeBuf,
- sizeof(TimeBuf)-1,
- "%ld.%06ld seconds since the Epoch",
- (long)tp.tv_sec,
- (long)tp.tv_usec);
- } else {
- slprintf(TimeBuf,
- sizeof(TimeBuf)-1,
- "%ld seconds since the Epoch",
- (long)t);
- }
+ slprintf(TimeBuf,sizeof(TimeBuf)-1,"%ld seconds since the Epoch",(long)t);
} else {
#ifdef HAVE_STRFTIME
- if (hires) {
- strftime(TimeBuf,sizeof(TimeBuf)-1,"%Y/%m/%d %H:%M:%S",tm);
- slprintf(TimeBuf+strlen(TimeBuf),
- sizeof(TimeBuf)-1 - strlen(TimeBuf),
- ".%06ld",
- (long)tp.tv_usec);
- } else {
- strftime(TimeBuf,100,"%Y/%m/%d %H:%M:%S",tm);
- }
+ strftime(TimeBuf,100,"%Y/%m/%d %T",tm);
#else
- if (hires)() {
- slprintf(TimeBuf,
- sizeof(TimeBuf)-1,
- "%s.%06ld",
- asctime(tm),
- (long)tp.tv_usec);
- } else {
- fstrcpy(TimeBuf, asctime(tm));
- }
+ fstrcpy(TimeBuf, asctime(tm));
#endif
}
return(TimeBuf);
diff --git a/source/lib/unix_sec_ctxt.c b/source/lib/unix_sec_ctxt.c
new file mode 100644
index 00000000000..ead1f3c6d32
--- /dev/null
+++ b/source/lib/unix_sec_ctxt.c
@@ -0,0 +1,303 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ uid/user handling
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+static uid_t initial_uid;
+static gid_t initial_gid;
+
+/* what context is current */
+struct unix_sec_ctxt curr_ctxt;
+
+/****************************************************************************
+initialise the security context routines
+****************************************************************************/
+void init_sec_ctxt(void)
+{
+ initial_uid = curr_ctxt.uid = geteuid();
+ initial_gid = curr_ctxt.gid = getegid();
+
+ if (initial_gid != 0 && initial_uid == 0) {
+#ifdef HAVE_SETRESUID
+ setresgid(0,0,0);
+#else
+ setgid(0);
+ setegid(0);
+#endif
+ }
+
+ initial_uid = geteuid();
+ initial_gid = getegid();
+}
+
+
+/****************************************************************************
+ become the specified uid
+****************************************************************************/
+static BOOL become_uid(uid_t uid)
+{
+ if (initial_uid != 0)
+ {
+ return(True);
+ }
+
+ if (uid == (uid_t)-1 || ((sizeof(uid_t) == 2) && (uid == (uid_t)65535)))
+ {
+ static int done;
+ if (!done) {
+ DEBUG(1,("WARNING: using uid %d is a security risk\n",(int)uid));
+ done=1;
+ }
+ }
+
+#ifdef HAVE_TRAPDOOR_UID
+#ifdef HAVE_SETUIDX
+ /* AIX3 has setuidx which is NOT a trapoor function (tridge) */
+ if (setuidx(ID_EFFECTIVE, uid) != 0) {
+ if (seteuid(uid) != 0) {
+ DEBUG(1,("Can't set uid %d (setuidx)\n", (int)uid));
+ return False;
+ }
+ }
+#endif
+#endif
+
+#ifdef HAVE_SETRESUID
+ if (setresuid(-1,uid,-1) != 0)
+#else
+ if ((seteuid(uid) != 0) &&
+ (setuid(uid) != 0))
+#endif
+ {
+ DEBUG(0,("Couldn't set uid %d currently set to (%d,%d)\n",
+ (int)uid,(int)getuid(), (int)geteuid()));
+ if (uid > (uid_t)32000) {
+ DEBUG(0,("Looks like your OS doesn't like high uid values - try using a different account\n"));
+ }
+ return(False);
+ }
+
+ if (((uid == (uid_t)-1) || ((sizeof(uid_t) == 2) && (uid == 65535))) && (geteuid() != uid))
+ {
+ DEBUG(0,("Invalid uid -1. perhaps you have a account with uid 65535?\n"));
+ return(False);
+ }
+
+ curr_ctxt.uid = uid;
+
+ return(True);
+}
+
+
+/****************************************************************************
+ become the specified gid
+****************************************************************************/
+static BOOL become_gid(gid_t gid)
+{
+ if (initial_uid != 0)
+ return(True);
+
+ if (gid == (gid_t)-1 || ((sizeof(gid_t) == 2) && (gid == (gid_t)65535))) {
+ DEBUG(1,("WARNING: using gid %d is a security risk\n",(int)gid));
+ }
+
+#ifdef HAVE_SETRESUID
+ if (setresgid(-1,gid,-1) != 0)
+#else
+ if (setgid(gid) != 0)
+#endif
+ {
+ DEBUG(0,("Couldn't set gid %d currently set to (%d,%d)\n",
+ (int)gid,(int)getgid(),(int)getegid()));
+ if (gid > 32000) {
+ DEBUG(0,("Looks like your OS doesn't like high gid values - try using a different account\n"));
+ }
+ return(False);
+ }
+
+ curr_ctxt.gid = gid;
+
+ return(True);
+}
+
+
+/****************************************************************************
+ become the user of a connection number
+****************************************************************************/
+BOOL become_unix_sec_ctxt(struct unix_sec_ctxt const *ctxt)
+{
+ if (curr_ctxt.uid == ctxt->uid)
+ {
+ DEBUG(4,("Skipping become_unix_sec_ctxt - already user\n"));
+ return(True);
+ }
+
+ unbecome_unix_sec_ctxt();
+
+ curr_ctxt.ngroups = ctxt->ngroups;
+ curr_ctxt.groups = ctxt->groups;
+ curr_ctxt.name = ctxt->name;
+
+ if (initial_uid == 0)
+ {
+ if (!become_uid(ctxt->uid)) return(False);
+#ifdef HAVE_SETGROUPS
+ if (curr_ctxt.ngroups > 0)
+ {
+ if (setgroups(curr_ctxt.ngroups,
+ curr_ctxt.groups) < 0)
+ {
+ DEBUG(0,("setgroups call failed!\n"));
+ }
+ }
+#endif
+ if (!become_gid(ctxt->gid)) return(False);
+
+ }
+
+ DEBUG(5,("become_unix_sec_ctxt uid=(%d,%d) gid=(%d,%d)\n",
+ (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
+
+ return(True);
+}
+
+/****************************************************************************
+ unbecome the user of a connection number
+****************************************************************************/
+BOOL unbecome_unix_sec_ctxt(void)
+{
+ if (initial_uid == 0)
+ {
+#ifdef HAVE_SETRESUID
+ setresuid(-1,getuid(),-1);
+ setresgid(-1,getgid(),-1);
+#else
+ if (seteuid(initial_uid) != 0)
+ setuid(initial_uid);
+ setgid(initial_gid);
+#endif
+ }
+
+#ifdef NO_EID
+ if (initial_uid == 0)
+ DEBUG(2,("Running with no EID\n"));
+ initial_uid = getuid();
+ initial_gid = getgid();
+#else
+ if (geteuid() != initial_uid) {
+ DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
+ initial_uid = geteuid();
+ }
+ if (getegid() != initial_gid) {
+ DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
+ initial_gid = getegid();
+ }
+#endif
+
+ curr_ctxt.uid = initial_uid;
+ curr_ctxt.gid = initial_gid;
+ curr_ctxt.name = NULL;
+
+ curr_ctxt.ngroups = 0;
+ curr_ctxt.groups = NULL;
+
+ DEBUG(5,("unbecome_unix_sec_ctxt now uid=(%d,%d) gid=(%d,%d)\n",
+ (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
+
+ return(True);
+}
+
+static struct unix_sec_ctxt curr_ctxt_saved;
+static int become_root_depth;
+
+/****************************************************************************
+This is used when we need to do a privileged operation (such as mucking
+with share mode files) and temporarily need root access to do it. This
+call should always be paired with an unbecome_root() call immediately
+after the operation
+
+Set save_dir if you also need to save/restore the CWD
+****************************************************************************/
+void become_unix_root_sec_ctxt(void)
+{
+ if (become_root_depth) {
+ DEBUG(0,("ERROR: become root depth is non zero\n"));
+ }
+
+ curr_ctxt_saved = curr_ctxt;
+ become_root_depth = 1;
+
+ become_uid(0);
+ become_gid(0);
+}
+
+/****************************************************************************
+When the privileged operation is over call this
+
+Set save_dir if you also need to save/restore the CWD
+****************************************************************************/
+void unbecome_unix_root_sec_ctxt(void)
+{
+ if (become_root_depth != 1)
+ {
+ DEBUG(0,("ERROR: unbecome root depth is %d\n",
+ become_root_depth));
+ }
+
+ /* we might have done a become_user() while running as root,
+ if we have then become root again in order to become
+ non root! */
+ if (curr_ctxt.uid != 0)
+ {
+ become_uid(0);
+ }
+
+ /* restore our gid first */
+ if (!become_gid(curr_ctxt_saved.gid))
+ {
+ DEBUG(0,("ERROR: Failed to restore gid\n"));
+ exit(-1);
+ }
+
+#ifdef HAVE_SETGROUPS
+ if (curr_ctxt_saved.ngroups > 0)
+ {
+ if (setgroups(curr_ctxt_saved.ngroups,
+ curr_ctxt_saved.groups) < 0)
+ {
+ DEBUG(0,("setgroups call failed!\n"));
+ }
+ }
+#endif
+ /* now restore our uid */
+ if (!become_uid(curr_ctxt_saved.uid))
+ {
+ DEBUG(0,("ERROR: Failed to restore uid\n"));
+ exit(-1);
+ }
+
+ curr_ctxt = curr_ctxt_saved;
+
+ become_root_depth = 0;
+}
+
diff --git a/source/lib/username.c b/source/lib/username.c
index 9a189980d5d..4a0d8a36bca 100644
--- a/source/lib/username.c
+++ b/source/lib/username.c
@@ -27,31 +27,311 @@ static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (
static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (char *), int N);
/****************************************************************************
- Get a users home directory.
+ Since getpwnam() makes samba really slow with the NT-domain code
+ (reading /etc/passwd again and again and again), here is an implementation
+ of very simple passwd cache
****************************************************************************/
+#define PASSWD_HASH_SIZE 1009
+/* The hashtable is rebuild every 15 seconds */
+#define PASSWD_HASH_AGE 15
+struct passwd_hash_entry {
+ int entry;
+ int next;
+};
+
+struct passwd_hash_table_s {
+ struct passwd *passwds;
+ int passwds_size;
+ int *names;
+ int *uids;
+ struct passwd_hash_entry *entries;
+ int entries_size;
+ struct timeval build_time;
+} passwd_hash_table = {
+ NULL,0,NULL,NULL,NULL,0,{0,0}
+};
+
+static int name_hash_function(const char *name)
+{
+ /* I guess that there must be better hash functions. This one was the
+ * first to come into mind :) */
+ unsigned int value=0;
+ while (*name) {
+ value=(value<<8)|(unsigned char)(*name);
+ if (value>1048576) value=value%PASSWD_HASH_SIZE;
+ name++;
+ }
+ value=value%PASSWD_HASH_SIZE;
+ return value;
+}
+
+static int uid_hash_function(uid_t uid)
+{
+ return uid%PASSWD_HASH_SIZE;
+}
+
-char *get_user_home_dir(char *user)
+static BOOL build_passwd_hash_table(void)
{
- static struct passwd *pass;
+ struct passwd_hash_table_s *pht=&passwd_hash_table; /* Convenience */
+ int num_passwds=0;
+ int num_entries=0;
+ struct passwd *pass;
+ int i;
+ int name_i,uid_i;
+
+ DEBUG(3,("Building passwd hash table\n"));
+ /* Free the allocated strings in old hash table */
+ for (i=0;i<pht->passwds_size;i++) {
+ free(pht->passwds[i].pw_name);
+ free(pht->passwds[i].pw_passwd);
+ free(pht->passwds[i].pw_gecos);
+ free(pht->passwds[i].pw_dir);
+ free(pht->passwds[i].pw_shell);
+ }
+
+ /* Initialize hash table if first table build */
+ if (pht->passwds_size==0) {
+ DEBUG(3,("Building passwd hash table for the first time\n"));
+ pht->passwds=malloc(sizeof(struct passwd)*64); /* A reasonable default */
+ pht->passwds_size=64;
+ }
+ if (pht->names==NULL) {
+ pht->names=malloc(sizeof(struct passwd_hash_entry *)*PASSWD_HASH_SIZE);
+ }
+ if (pht->uids==NULL) {
+ pht->uids=malloc(sizeof(struct passwd_hash_entry *)*PASSWD_HASH_SIZE);
+ }
+ if (pht->entries==NULL) {
+ pht->entries=malloc(sizeof(struct passwd_hash_entry)*128);
+ pht->entries_size=128;
+ }
+ if (pht->passwds==NULL || pht->names==NULL ||
+ pht->uids==NULL || pht->entries==NULL) {
+ goto fail;
+ }
+
+ /* Clear out the hash table */
+ for(i=0;i<PASSWD_HASH_SIZE;i++) pht->uids[i]=-1;
+ for(i=0;i<PASSWD_HASH_SIZE;i++) pht->names[i]=-1;
+
+ /* Now do the build */
+ setpwent();
+
+ while((pass=getpwent())) {
+
+ /* Check that we have enough space */
+ if (num_passwds==pht->passwds_size) {
+ struct passwd *new_passwds=NULL;
+ pht->passwds_size+=pht->passwds_size/2;
+ new_passwds=realloc(pht->passwds,
+ sizeof(struct passwd)*pht->passwds_size);
+ if (new_passwds==NULL) goto fail;
+ pht->passwds=new_passwds;
+ }
+ if (num_entries+1>=pht->entries_size) {
+ pht->entries_size+=pht->entries_size/2;
+ pht->entries=realloc(pht->entries,
+ sizeof(struct passwd_hash_entry)*pht->entries_size);
+ if (pht->entries==NULL) goto fail;
+ }
- pass = Get_Pwnam(user, False);
+ /* Copy the passwd struct */
+ memset(&pht->passwds[num_passwds],0,sizeof(struct passwd));
+ pht->passwds[num_passwds].pw_uid=pass->pw_uid;
+ pht->passwds[num_passwds].pw_gid=pass->pw_gid;
+ if (
+ (pht->passwds[num_passwds].pw_name=strdup(pass->pw_name))==NULL ||
+ (pht->passwds[num_passwds].pw_passwd=strdup(pass->pw_passwd))==NULL ||
+ (pht->passwds[num_passwds].pw_gecos=strdup(pass->pw_gecos))==NULL ||
+ (pht->passwds[num_passwds].pw_dir=strdup(pass->pw_dir))==NULL ||
+ (pht->passwds[num_passwds].pw_shell=strdup(pass->pw_shell))==NULL ) {
+ num_passwds++;
+ goto fail;
+ }
+
+ /* Add to the hash table */
+ /* Add the name */
+ pht->entries[num_entries].entry=num_passwds;
+ name_i=name_hash_function(pass->pw_name);
+ pht->entries[num_entries].next=pht->names[name_i];
+ pht->names[name_i]=num_entries;
+ num_entries++;
+ /* Add the uid */
+ pht->entries[num_entries].entry=num_passwds;
+ uid_i=uid_hash_function(pass->pw_uid);
+ pht->entries[num_entries].next=pht->uids[uid_i];
+ pht->uids[uid_i]=num_entries;
+ num_entries++;
+
+ /* This entry has been done */
+ num_passwds++;
+ }
+ endpwent();
+
+ if (pht->passwds_size>num_passwds) {
+ struct passwd *passwds;
+ passwds=realloc(pht->passwds,sizeof(pht->passwds[0])*num_passwds);
+ if (passwds==NULL) goto fail;
+ pht->passwds=passwds;
+ pht->passwds_size=num_passwds;
+ }
+ if (pht->entries_size>num_entries) {
+ struct passwd_hash_entry *entries;
+ entries=realloc(pht->entries,sizeof(pht->entries[0])*num_entries);
+ if (entries==NULL) goto fail;
+ pht->entries=entries;
+ pht->entries_size=num_entries;
+ }
- if (!pass) return(NULL);
- return(pass->pw_dir);
+ /* Mark the creation time */
+ GetTimeOfDay(&pht->build_time);
+ /* Everything went smoothly. */
+ return True;
+
+ fail:
+ DEBUG(0,("Failed to create passwd hash table: %s",strerror(errno)));
+ /* OK: now the untested part. Normally this should never happen:
+ * Only running out of memory could cause this and even then
+ * we have enough trouble already. */
+ while (num_passwds>0) {
+ num_passwds--;
+ free(pht->passwds[num_passwds].pw_name);
+ free(pht->passwds[num_passwds].pw_passwd);
+ free(pht->passwds[num_passwds].pw_gecos);
+ free(pht->passwds[num_passwds].pw_dir);
+ free(pht->passwds[num_passwds].pw_shell);
+ }
+ free(pht->entries);
+ free(pht->uids);
+ free(pht->names);
+ free(pht->passwds);
+ pht->passwds_size=0;
+ pht->entries_size=0;
+ /* Also mark fail time, so that retry will happen after PASSWD_HASH_AGE */
+ GetTimeOfDay(&pht->build_time);
+ return False;
}
+static BOOL have_passwd_hash(void)
+{
+ struct passwd_hash_table_s *pht=&passwd_hash_table;
+ struct timeval tv;
+ GetTimeOfDay(&tv);
+ /* I'm ignoring microseconds. If you think they matter, go ahead
+ * and implement them */
+ if (tv.tv_sec - pht->build_time.tv_sec > PASSWD_HASH_AGE) {
+ return build_passwd_hash_table();
+ }
+ return pht->passwds_size>0;
+}
+
+struct passwd *hashed_getpwnam(const char *name)
+{
+#if 0
+ struct passwd_hash_table_s *pht=&passwd_hash_table;
+
+ DEBUG(5,("getpwnam(%s)\n", name));
+
+ if (have_passwd_hash())
+ {
+ int name_i=name_hash_function(name);
+ int hash_index=pht->names[name_i];
+ while(hash_index!=-1) {
+ struct passwd *pass=&pht->passwds[pht->entries[hash_index].entry];
+ if (strcmp(name,pass->pw_name)==0) {
+ DEBUG(5,("Found: %s:%s:%d:%d:%s:%s:%s\n",
+ pass->pw_name,
+ pass->pw_passwd,
+ pass->pw_uid,
+ pass->pw_gid,
+ pass->pw_gecos,
+ pass->pw_dir,
+ pass->pw_shell));
+ return copy_passwd_struct(pass);
+ }
+ hash_index=pht->entries[hash_index].next;
+ }
+
+ /* Not found */
+ DEBUG(5,("%s not found\n",name));
+ return NULL;
+ }
+#endif
+
+ /* Fall back to real getpwnam() */
+ return sys_getpwnam(name);
+}
/*******************************************************************
- Map a username from a dos name to a unix name by looking in the username
- map. Note that this modifies the name in place.
- This is the main function that should be called *once* on
- any incoming or new username - in order to canonicalize the name.
- This is being done to de-couple the case conversions from the user mapping
- function. Previously, the map_username was being called
- every time Get_Pwnam was called.
- Returns True if username was changed, false otherwise.
+turn a uid into a user name
********************************************************************/
+char *uidtoname(uid_t uid)
+{
+ static char name[40];
+ struct passwd *pass=NULL;
+#if 0
+ struct passwd_hash_table_s *pht=&passwd_hash_table;
+
+ DEBUG(5,("uidtoname(%d)\n",uid));
+ if (have_passwd_hash()) {
+ int hash_index=pht->uids[uid_hash_function(uid)];
+ while(hash_index!=-1) {
+ pass=&pht->passwds[pht->entries[hash_index].entry];
+ if (pass->pw_uid==uid) {
+ DEBUG(5,("Found: %s:%s:%d:%d:%s:%s:%s\n",
+ pass->pw_name,
+ pass->pw_passwd,
+ pass->pw_uid,
+ pass->pw_gid,
+ pass->pw_gecos,
+ pass->pw_dir,
+ pass->pw_shell));
+ return pass->pw_name;
+ }
+ hash_index=pht->entries[hash_index].next;
+ }
+ DEBUG(5,("Hash miss"));
+ pass=NULL;
+ } else
+#endif
+ {
+ /* No hash table, fall back to getpwuid */
+ pass = getpwuid(uid);
+ }
+ if (pass) return(pass->pw_name);
+ slprintf(name, sizeof(name) - 1, "%d",(int)uid);
+ return(name);
+}
+
+/****************************************************************************
+get a users home directory.
+****************************************************************************/
+char *get_unixhome_dir(char *user)
+{
+ const struct passwd *pass;
+ static pstring home_dir;
+
+ pass = Get_Pwnam(user, False);
+
+ if (pass == NULL || pass->pw_dir == NULL) return(NULL);
+
+ pstrcpy(home_dir, pass->pw_dir);
+ DEBUG(10,("get_smbhome_dir: returning %s for user %s\n", home_dir, user));
+ return home_dir;
+}
+
+/*******************************************************************
+map a username from a dos name to a unix name by looking in the username
+map. Note that this modifies the name in place.
+This is the main function that should be called *once* on
+any incoming or new username - in order to canonicalize the name.
+This is being done to de-couple the case conversions from the user mapping
+function. Previously, the map_username was being called
+every time Get_Pwnam was called.
+Returns True if username was changed, false otherwise.
+********************************************************************/
BOOL map_username(char *user)
{
static BOOL initialised=False;
@@ -145,36 +425,38 @@ BOOL map_username(char *user)
return mapped_user;
}
+
/****************************************************************************
Get_Pwnam wrapper
****************************************************************************/
-
static struct passwd *_Get_Pwnam(char *s)
{
- struct passwd *ret;
+ struct passwd *ret;
- ret = sys_getpwnam(s);
- if (ret) {
+ ret = hashed_getpwnam(s);
#ifdef HAVE_GETPWANAM
- struct passwd_adjunct *pwret;
- pwret = getpwanam(s);
- if (pwret && pwret->pwa_passwd) {
- pstrcpy(ret->pw_passwd,pwret->pwa_passwd);
- }
+ if (ret)
+ {
+ struct passwd_adjunct *pwret;
+ pwret = getpwanam(s);
+ if (pwret != NULL && pwret->pwa_passwd != NULL)
+ {
+ pstrcpy(ret->pw_passwd, pwret->pwa_passwd);
+ }
+ }
#endif
- }
- return(ret);
+ return ret;
}
-
/****************************************************************************
- A wrapper for getpwnam() that tries with all lower and all upper case
- if the initial name fails. Also tried with first letter capitalised
- Note that this can change user!
+a wrapper for getpwnam() that tries with all lower and all upper case
+if the initial name fails. Also tried with first letter capitalised
+Note that this can change user! Function returns const to emphasise
+the fact that most of the members of the struct passwd * returned are
+dynamically allocated.
****************************************************************************/
-
-struct passwd *Get_Pwnam(char *user,BOOL allow_change)
+const struct passwd *Get_Pwnam(char *user,BOOL allow_change)
{
fstring user2;
int last_char;
@@ -192,39 +474,33 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
}
ret = _Get_Pwnam(user);
- if (ret)
- return(ret);
+ if (ret) return(ret);
strlower(user);
ret = _Get_Pwnam(user);
- if (ret)
- return(ret);
+ if (ret) return(ret);
strupper(user);
ret = _Get_Pwnam(user);
- if (ret)
- return(ret);
+ if (ret) return(ret);
- /* Try with first letter capitalised. */
+ /* try with first letter capitalised */
if (strlen(user) > 1)
strlower(user+1);
ret = _Get_Pwnam(user);
- if (ret)
- return(ret);
+ if (ret) return(ret);
/* try with last letter capitalised */
strlower(user);
last_char = strlen(user)-1;
user[last_char] = toupper(user[last_char]);
ret = _Get_Pwnam(user);
- if (ret)
- return(ret);
+ if (ret) return(ret);
- /* Try all combinations up to usernamelevel. */
+ /* try all combinations up to usernamelevel */
strlower(user);
ret = uname_string_combinations(user, _Get_Pwnam, usernamelevel);
- if (ret)
- return(ret);
+ if (ret) return(ret);
if (allow_change)
fstrcpy(user,user2);
@@ -233,9 +509,8 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
}
/****************************************************************************
- Check if a user is in a netgroup user list.
+check if a user is in a netgroup user list
****************************************************************************/
-
static BOOL user_in_netgroup_list(char *user,char *ngname)
{
#ifdef HAVE_NETGROUP
@@ -243,9 +518,12 @@ static BOOL user_in_netgroup_list(char *user,char *ngname)
if (mydomain == NULL)
yp_get_default_domain(&mydomain);
- if(mydomain == NULL) {
+ if(mydomain == NULL)
+ {
DEBUG(5,("Unable to get default yp domain\n"));
- } else {
+ }
+ else
+ {
DEBUG(5,("looking for user %s of domain %s in netgroup %s\n",
user, mydomain, ngname));
DEBUG(5,("innetgr is %s\n",
@@ -260,51 +538,78 @@ static BOOL user_in_netgroup_list(char *user,char *ngname)
}
/****************************************************************************
- Check if a user is in a UNIX user list.
+check if a user is in a UNIX user list
****************************************************************************/
-
static BOOL user_in_group_list(char *user,char *gname)
{
-#ifdef HAVE_GETGRENT
- struct group *gptr;
- char **member;
- struct passwd *pass = Get_Pwnam(user,False);
-
- if (pass) {
- gptr = getgrgid(pass->pw_gid);
- if (gptr && strequal(gptr->gr_name,gname))
- return(True);
- }
-
- while ((gptr = (struct group *)getgrent())) {
- if (!strequal(gptr->gr_name,gname))
- continue;
- member = gptr->gr_mem;
- while (member && *member) {
- if (strequal(*member,user)) {
- endgrent();
- return(True);
- }
- member++;
- }
- }
-
- endgrent();
+#ifdef HAVE_GETGRNAM
+ struct group *gptr;
+ char **member;
+ const struct passwd *pass = Get_Pwnam(user,False);
+
+ if (pass)
+ {
+ gptr = getgrgid(pass->pw_gid);
+ if (gptr && strequal(gptr->gr_name,gname))
+ return(True);
+ }
+
+ gptr = (struct group *)getgrnam(gname);
+
+ if (gptr)
+ {
+ member = gptr->gr_mem;
+ while (member && *member)
+ {
+ if (strequal(*member,user))
+ return(True);
+ member++;
+ }
+ }
#endif /* HAVE_GETGRNAM */
- return False;
+ return False;
}
/****************************************************************************
- Check if a user is in a user list - can check combinations of UNIX
- and netgroup lists.
+check if a username is valid
****************************************************************************/
+BOOL user_ok(char *user,int snum)
+{
+ pstring valid, invalid;
+ BOOL ret;
+
+ StrnCpy(valid, lp_valid_users(snum), sizeof(pstring));
+ StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring));
+
+ string_sub(valid,"%S",lp_servicename(snum));
+ string_sub(invalid,"%S",lp_servicename(snum));
+
+ ret = !user_in_list(user,invalid);
+
+ if (ret && valid && *valid) {
+ ret = user_in_list(user,valid);
+ }
+
+ if (ret && lp_onlyuser(snum)) {
+ char *user_list = lp_username(snum);
+ string_sub(user_list,"%S",lp_servicename(snum));
+ ret = user_in_list(user,user_list);
+ }
+ return(ret);
+}
+
+/****************************************************************************
+check if a user is in a user list - can check combinations of UNIX
+and netgroup lists.
+****************************************************************************/
BOOL user_in_list(char *user,char *list)
{
pstring tok;
char *p=list;
- while (next_token(&p,tok,LIST_SEP, sizeof(tok))) {
+ while (next_token(&p,tok,LIST_SEP, sizeof(tok)))
+ {
/*
* Check raw username.
*/
@@ -316,7 +621,8 @@ BOOL user_in_list(char *user,char *list)
* of UNIX and netgroups has been specified.
*/
- if(*tok == '@') {
+ if(*tok == '@')
+ {
/*
* Old behaviour. Check netgroup list
* followed by UNIX list.
@@ -325,9 +631,11 @@ BOOL user_in_list(char *user,char *list)
return True;
if(user_in_group_list(user,&tok[1]))
return True;
- } else if (*tok == '+') {
-
- if(tok[1] == '&') {
+ }
+ else if (*tok == '+')
+ {
+ if(tok[1] == '&')
+ {
/*
* Search UNIX list followed by netgroup.
*/
@@ -335,20 +643,20 @@ BOOL user_in_list(char *user,char *list)
return True;
if(user_in_netgroup_list(user,&tok[2]))
return True;
-
- } else {
-
+ }
+ else
+ {
/*
* Just search UNIX list.
*/
-
if(user_in_group_list(user,&tok[1]))
return True;
}
-
- } else if (*tok == '&') {
-
- if(tok[1] == '+') {
+ }
+ else if (*tok == '&')
+ {
+ if(tok[1] == '&')
+ {
/*
* Search netgroup list followed by UNIX list.
*/
@@ -356,7 +664,9 @@ BOOL user_in_list(char *user,char *list)
return True;
if(user_in_group_list(user,&tok[2]))
return True;
- } else {
+ }
+ else
+ {
/*
* Just search netgroup list.
*/
@@ -370,16 +680,15 @@ BOOL user_in_list(char *user,char *list)
/* The functions below have been taken from password.c and slightly modified */
/****************************************************************************
- Apply a function to upper/lower case combinations
- of a string and return true if one of them returns true.
- Try all combinations with N uppercase letters.
- offset is the first char to try and change (start with 0)
- it assumes the string starts lowercased
+apply a function to upper/lower case combinations
+of a string and return true if one of them returns true.
+try all combinations with N uppercase letters.
+offset is the first char to try and change (start with 0)
+it assumes the string starts lowercased
****************************************************************************/
-
static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(char *),int N)
{
- ssize_t len = (ssize_t)strlen(s);
+ int len = strlen(s);
int i;
struct passwd *ret;
@@ -390,36 +699,36 @@ static struct passwd *uname_string_combinations2(char *s,int offset,struct passw
if (N <= 0 || offset >= len)
return(fn(s));
- for (i=offset;i<(len-(N-1));i++) {
- char c = s[i];
- if (!islower(c))
- continue;
- s[i] = toupper(c);
- ret = uname_string_combinations2(s,i+1,fn,N-1);
- if(ret)
- return(ret);
- s[i] = c;
- }
+
+ for (i=offset;i<(len-(N-1));i++)
+
+ {
+ char c = s[i];
+ if (!islower(c)) continue;
+ s[i] = toupper(c);
+ ret = uname_string_combinations2(s,i+1,fn,N-1);
+ if(ret) return(ret);
+ s[i] = c;
+ }
return(NULL);
}
/****************************************************************************
- Apply a function to upper/lower case combinations
- of a string and return true if one of them returns true.
- Try all combinations with up to N uppercase letters.
- offset is the first char to try and change (start with 0)
- it assumes the string starts lowercased
+apply a function to upper/lower case combinations
+of a string and return true if one of them returns true.
+try all combinations with up to N uppercase letters.
+offset is the first char to try and change (start with 0)
+it assumes the string starts lowercased
****************************************************************************/
-
static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(char *),int N)
{
int n;
struct passwd *ret;
- for (n=1;n<=N;n++) {
+ for (n=1;n<=N;n++)
+ {
ret = uname_string_combinations2(s,0,fn,n);
- if(ret)
- return(ret);
+ if(ret) return(ret);
}
return(NULL);
}
diff --git a/source/lib/ustring.c b/source/lib/ustring.c
new file mode 100644
index 00000000000..f754d0ba6bf
--- /dev/null
+++ b/source/lib/ustring.c
@@ -0,0 +1,351 @@
+/*
+ Dynamic Unicode Strings
+ Copyright (C) Elrond 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "ustring.h"
+
+#define g_free(x) safe_free(x)
+
+
+#define INITIAL_SIZE 32
+
+
+UString *ustring_new(const char *init)
+{
+ UString *str;
+
+ str = g_new(UString, 1);
+ if (str == NULL)
+ {
+ return str;
+ }
+ str->len = 0;
+ str->alloc = INITIAL_SIZE;
+ str->str = g_new(uint16, str->alloc);
+ if(str->str == NULL)
+ {
+ g_free(str);
+ return NULL;
+ }
+ str->str[0] = 0;
+
+ if (init)
+ {
+ ustring_assign_ascii_str(str, init);
+ }
+
+ return str;
+}
+
+void ustring_free(UString *str)
+{
+ if (! str)
+ {
+ return;
+ }
+ g_free(str->str);
+ g_free(str);
+}
+
+static size_t nearest_pow(size_t n)
+{
+ size_t i = 1;
+ while (i < n)
+ {
+ i *= 2;
+ }
+ return i;
+}
+
+UString *ustring_grow(UString *str, size_t new_alloc)
+{
+ if(! str)
+ {
+ return str;
+ }
+ if(str->alloc >= new_alloc)
+ {
+ return str;
+ }
+ new_alloc = nearest_pow(new_alloc);
+ str->str = g_renew(uint16, str->str, new_alloc);
+ if (str->str == NULL)
+ {
+ new_alloc = 0;
+ str->len = 0;
+ }
+ str->alloc = new_alloc;
+ return str;
+}
+
+UString *ustring_shrink(UString *str)
+{
+ size_t new_alloc;
+
+ if(! str)
+ {
+ return str;
+ }
+ new_alloc = str->len + 1;
+ if (new_alloc == str->alloc)
+ {
+ return str;
+ }
+
+ str->str = g_renew(uint16, str->str, new_alloc);
+ str->alloc = new_alloc;
+ return str;
+}
+
+UString *ustring_assign(UString *str, const uint16 *src, size_t len)
+{
+ if (! str)
+ {
+ return str;
+ }
+ if ((src == NULL) || (len == 0))
+ {
+ str->len = 0;
+ str->str[0] = 0;
+ }
+
+ ustring_grow(str, len+1);
+
+ memcpy(str->str, src, len*sizeof(uint16));
+
+ str->str[len] = 0;
+ str->len = len;
+
+ return str;
+}
+
+UString *ustring_assign_ascii(UString *str, const char *src, size_t len)
+{
+ uint16 *dest;
+
+ if (! str)
+ {
+ return str;
+ }
+ if ((src == NULL) || (len == 0))
+ {
+ str->len = 0;
+ str->str[0] = 0;
+ return str;
+ }
+ ustring_grow(str, len+1);
+
+ str->len = len;
+
+ dest = str->str;
+
+ while (len > 0)
+ {
+ char c = *src++;
+ *dest++ = c;
+ len--;
+ }
+
+ *dest = 0;
+
+ return str;
+}
+
+UString *ustring_assign_ascii_str(UString *str, const char *src)
+{
+ return ustring_assign_ascii(str, src, (src ? strlen(src) : 0));
+}
+
+UString *ustring_dup(const UString *str)
+{
+ UString *new;
+
+ if (! str)
+ {
+ return str;
+ }
+ new = ustring_new(NULL);
+ if (! new)
+ {
+ return new;
+ }
+
+ ustring_assign(new, str->str, str->len);
+
+ return new;
+}
+
+int ustring_compare(const UString *a, const UString *b)
+{
+ uint16 *pa, *pb;
+ int ca, cb;
+ size_t len;
+
+ if (a == b) return 0;
+ if (!a) return 1;
+ if (!b) return -1;
+
+ pa = a->str;
+ pb = b->str;
+ len = MIN(a->len, b->len) + 1; /* include the final NUL */
+
+ while ((len > 0) && (*pa == *pb))
+ {
+ pa++;
+ pb++;
+ len--;
+ }
+ if (len == 0)
+ {
+ if (a->len == b->len) return 0;
+ if (a->len < b->len) return 1;
+ return 1;
+ }
+
+ ca = *pa;
+ cb = *pb;
+
+ return cb - ca;
+}
+
+int ustring_compare_case(const UString *a, const UString *b)
+{
+ uint16 *pa, *pb;
+ int ca, cb;
+ size_t len;
+
+ if (a == b) return 0;
+ if (!a) return 1;
+ if (!b) return -1;
+
+ pa = a->str;
+ pb = b->str;
+ len = MIN(a->len, b->len) + 1; /* include the final NUL */
+
+ while ((len > 0) && (toupper(*pa) == toupper(*pb)))
+ {
+ pa++;
+ pb++;
+ len--;
+ }
+ if (len == 0)
+ {
+ if (a->len == b->len) return 0;
+ if (a->len < b->len) return 1;
+ return 1;
+ }
+
+ ca = toupper(*pa);
+ cb = toupper(*pb);
+
+ return cb - ca;
+}
+
+UString *ustring_append_c(UString *str, uint16 c)
+{
+ if (! str)
+ {
+ return str;
+ }
+ ustring_grow(str, str->len + 2);
+ str->str[str->len] = c;
+ str->len++;
+ str->str[str->len] = 0;
+
+ return str;
+}
+
+UString *ustring_sync_len(UString *str)
+{
+ uint16 *p, *a;
+
+ if (! str)
+ {
+ return str;
+ }
+
+ a = str->str;
+ p = a + str->len - 1;
+ while((p > a) && (*p == 0))
+ {
+ p--;
+ }
+ p++;
+ str->len = p - a;
+
+ return str;
+}
+
+UString *ustring_upper(UString *str)
+{
+ uint16 *p, *e;
+
+ if (! str)
+ {
+ return str;
+ }
+
+ p = str->str;
+ e = p + str->len;
+
+ while (p < e)
+ {
+ *p = toupper(*p);
+ p++;
+ }
+
+ return str;
+}
+
+UString *ustring_lower(UString *str)
+{
+ uint16 *p, *e;
+
+ if (! str)
+ {
+ return str;
+ }
+
+ p = str->str;
+ e = p + str->len;
+
+ while (p < e)
+ {
+ *p = tolower(*p);
+ p++;
+ }
+
+ return str;
+}
+
+BOOL ustring_equal(const UString *s1, const UString *s2)
+{
+ UString *a;
+ UString *b;
+ BOOL ret;
+
+ a = ustring_sync_len(ustring_dup(s1));
+ b = ustring_sync_len(ustring_dup(s2));
+ ret = ustring_compare_case(a, b);
+
+ ustring_free(a);
+ ustring_free(b);
+
+ return ret;
+}
diff --git a/source/lib/util.c b/source/lib/util.c
index 564fc882222..91beec37c0c 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -2,7 +2,7 @@
Unix SMB/Netbios implementation.
Version 1.9.
Samba utility functions
- Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Andrew Tridgell 1992-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,50 +20,31 @@
*/
#include "includes.h"
+#include "rpc_reg.h"
#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
#ifdef WITH_NISPLUS_HOME
-#ifdef BROKEN_NISPLUS_INCLUDE_FILES
-/*
- * The following lines are needed due to buggy include files
- * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
- * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
- * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
- * an enum in /usr/include/rpcsvc/nis.h.
- */
-
-#if defined(GROUP)
-#undef GROUP
-#endif
-
-#if defined(GROUP_OBJ)
-#undef GROUP_OBJ
-#endif
-
-#endif /* BROKEN_NISPLUS_INCLUDE_FILES */
-
#include <rpcsvc/nis.h>
-
-#else /* !WITH_NISPLUS_HOME */
-
+#else
#include "rpcsvc/ypclnt.h"
-
-#endif /* WITH_NISPLUS_HOME */
-#endif /* HAVE_NETGROUP && WITH_AUTOMOUNT */
+#endif
+#endif
#ifdef WITH_SSL
#include <ssl.h>
-#undef Realloc /* SSLeay defines this and samba has a function of this name */
-extern SSL *ssl;
-extern int sslFd;
-#endif /* WITH_SSL */
+#undef Realloc /* SSLeay defines this and samba has a function of this name */
+extern SSL *ssl;
+extern int sslFd;
+#endif /* WITH_SSL */
+
+pstring scope = "";
extern int DEBUGLEVEL;
int Protocol = PROTOCOL_COREPLUS;
/* a default finfo structure to ensure all fields are sensible */
-file_info def_finfo = {-1,0,0,0,0,0,0,""};
+file_info def_finfo = { -1, 0, 0, 0, 0, 0, 0, "" };
/* the client file descriptor */
extern int Client;
@@ -86,25 +67,38 @@ BOOL use_mangled_map = False;
BOOL short_case_preserve;
BOOL case_mangle;
-fstring remote_machine="";
-fstring local_machine="";
-fstring remote_arch="UNKNOWN";
+fstring remote_machine = "";
+fstring local_machine = "";
+fstring remote_arch = "UNKNOWN";
static enum remote_arch_types ra_type = RA_UNKNOWN;
-fstring remote_proto="UNKNOWN";
-pstring user_socket_options=DEFAULT_SOCKET_OPTIONS;
-
-pstring sesssetup_user="";
-pstring samlogon_user="";
+fstring remote_proto = "UNKNOWN";
+pstring myhostname = "";
+pstring user_socket_options = "";
-BOOL sam_logon_in_ssb = False;
+pstring sesssetup_user = "";
pstring global_myname = "";
fstring global_myworkgroup = "";
char **my_netbios_names;
-static char *filename_dos(char *path,char *buf);
+char *daynames[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
+char *daynames_short[] = { "M", "Tu", "W", "Th", "F", "Sa", "Su" };
+/*************************************************************
+ initialise password databases, domain names, domain sid.
+**************************************************************/
+BOOL init_myworkgroup(void)
+{
+ fstrcpy(global_myworkgroup, lp_workgroup());
+ if (strequal(global_myworkgroup, "*"))
+ {
+ DEBUG(0,
+ ("ERROR: a workgroup name of * is no longer supported\n"));
+ return False;
+ }
+ return True;
+}
/****************************************************************************
find a suitable temporary directory. The result should be copied immediately
@@ -112,62 +106,98 @@ static char *filename_dos(char *path,char *buf);
****************************************************************************/
char *tmpdir(void)
{
- char *p;
- if ((p = getenv("TMPDIR"))) {
- return p;
- }
- return "/tmp";
+ char *p;
+ if ((p = getenv("TMPDIR")))
+ {
+ return p;
+ }
+ return "/tmp";
}
/****************************************************************************
determine whether we are in the specified group
****************************************************************************/
-BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t *groups)
+BOOL in_group(gid_t group, gid_t current_gid, int ngroups, gid_t * groups)
{
int i;
- if (group == current_gid) return(True);
+ if (group == current_gid)
+ return (True);
- for (i=0;i<ngroups;i++)
+ for (i = 0; i < ngroups; i++)
if (group == groups[i])
- return(True);
+ return (True);
- return(False);
+ return (False);
}
/****************************************************************************
+gets either a hex number (0xNNN) or decimal integer (NNN).
+****************************************************************************/
+uint32 get_number(const char *tmp)
+{
+ if (strnequal(tmp, "0x", 2))
+ {
+ return strtoul(tmp, (char **)NULL, 16);
+ }
+ else
+ {
+ return strtoul(tmp, (char **)NULL, 10);
+ }
+}
+
+/****************************************************************************
like atoi but gets the value up to the separater character
****************************************************************************/
char *Atoic(char *p, int *n, char *c)
{
- if (!isdigit((int)*p))
+ if (!isdigit(*p))
{
DEBUG(5, ("Atoic: malformed number\n"));
return NULL;
}
- (*n) = atoi(p);
+ (*n) = (int)get_number(p);
- while ((*p) && isdigit((int)*p))
+ if (strnequal(p, "0x", 2))
+ {
+ p += 2;
+ }
+
+ while ((*p) && isdigit(*p))
{
p++;
}
if (strchr(c, *p) == NULL)
{
- DEBUG(5, ("Atoic: no separator characters (%s) not found\n", c));
+ DEBUG(5,
+ ("Atoic: no separator characters (%s) not found\n", c));
return NULL;
}
return p;
}
+uint32 *add_num_to_list(uint32 ** num, int *count, int val)
+{
+ (*num) = Realloc((*num), ((*count) + 1) * sizeof(uint32));
+ if ((*num) == NULL)
+ {
+ return NULL;
+ }
+ (*num)[(*count)] = val;
+ (*count)++;
+
+ return (*num);
+}
+
/*************************************************************************
reads a list of numbers
*************************************************************************/
-char *get_numlist(char *p, uint32 **num, int *count)
+char *get_numlist(char *p, uint32 ** num, int *count)
{
int val;
@@ -177,174 +207,41 @@ char *get_numlist(char *p, uint32 **num, int *count)
}
(*count) = 0;
- (*num ) = NULL;
+ (*num) = NULL;
while ((p = Atoic(p, &val, ":,")) != NULL && (*p) != ':')
{
- (*num) = Realloc((*num), ((*count)+1) * sizeof(uint32));
- if ((*num) == NULL)
+ if (add_num_to_list(num, count, val) == NULL)
{
return NULL;
}
- (*num)[(*count)] = val;
- (*count)++;
p++;
}
return p;
}
-#define TRUNCATE_NETBIOS_NAME 1
-
/*******************************************************************
- convert, possibly using a stupid microsoft-ism which has destroyed
- the transport independence of netbios (for CIFS vendors that usually
- use the Win95-type methods, not for NT to NT communication, which uses
- DCE/RPC and therefore full-length unicode strings...) a dns name into
- a netbios name.
-
- the netbios name (NOT necessarily null-terminated) is truncated to 15
- characters.
-
- ******************************************************************/
-char *dns_to_netbios_name(char *dns_name)
+copy an IP address from one buffer to another
+********************************************************************/
+void putip(void *dest, void *src)
{
- static char netbios_name[16];
- int i;
- StrnCpy(netbios_name, dns_name, 15);
- netbios_name[15] = 0;
-
-#ifdef TRUNCATE_NETBIOS_NAME
- /* ok. this is because of a stupid microsoft-ism. if the called host
- name contains a '.', microsoft clients expect you to truncate the
- netbios name up to and including the '.' this even applies, by
- mistake, to workgroup (domain) names, which is _really_ daft.
- */
- for (i = 15; i >= 0; i--)
- {
- if (netbios_name[i] == '.')
- {
- netbios_name[i] = 0;
- break;
- }
- }
-#endif /* TRUNCATE_NETBIOS_NAME */
-
- return netbios_name;
+ memcpy(dest, src, 4);
}
-
-/****************************************************************************
-interpret the weird netbios "name". Return the name type
-****************************************************************************/
-static int name_interpret(char *in,char *out)
-{
- int ret;
- int len = (*in++) / 2;
-
- *out=0;
-
- if (len > 30 || len<1) return(0);
-
- while (len--)
- {
- if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
- *out = 0;
- return(0);
- }
- *out = ((in[0]-'A')<<4) + (in[1]-'A');
- in += 2;
- out++;
- }
- *out = 0;
- ret = out[-1];
-
-#ifdef NETBIOS_SCOPE
- /* Handle any scope names */
- while(*in)
- {
- *out++ = '.'; /* Scope names are separated by periods */
- len = *(unsigned char *)in++;
- StrnCpy(out, in, len);
- out += len;
- *out=0;
- in += len;
- }
-#endif
- return(ret);
-}
-
-/****************************************************************************
-mangle a name into netbios format
-
- Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
-****************************************************************************/
-int name_mangle( char *In, char *Out, char name_type )
- {
- int i;
- int c;
- int len;
- char buf[20];
- char *p = Out;
- extern pstring global_scope;
-
- /* Safely copy the input string, In, into buf[]. */
- (void)memset( buf, 0, 20 );
- if (strcmp(In,"*") == 0)
- buf[0] = '*';
- else
- (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
-
- /* Place the length of the first field into the output buffer. */
- p[0] = 32;
- p++;
-
- /* Now convert the name to the rfc1001/1002 format. */
- for( i = 0; i < 16; i++ )
- {
- c = toupper( buf[i] );
- p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
- p[(i*2)+1] = (c & 0x000F) + 'A';
- }
- p += 32;
- p[0] = '\0';
-
- /* Add the scope string. */
- for( i = 0, len = 0; NULL != global_scope; i++, len++ )
- {
- switch( global_scope[i] )
- {
- case '\0':
- p[0] = len;
- if( len > 0 )
- p[len+1] = 0;
- return( name_len(Out) );
- case '.':
- p[0] = len;
- p += (len + 1);
- len = -1;
- break;
- default:
- p[len+1] = global_scope[i];
- break;
- }
- }
-
- return( name_len(Out) );
- } /* name_mangle */
-
/*******************************************************************
- check if a file exists - call vfs_file_exist for samba files
+ check if a file exists
********************************************************************/
-BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
+BOOL file_exist(char *fname, SMB_STRUCT_STAT * sbuf)
{
- SMB_STRUCT_STAT st;
- if (!sbuf) sbuf = &st;
-
- if (sys_stat(fname,sbuf) != 0)
- return(False);
+ SMB_STRUCT_STAT st;
+ if (!sbuf)
+ sbuf = &st;
- return(S_ISREG(sbuf->st_mode));
+ if (sys_stat(fname, sbuf) != 0)
+ return (False);
+
+ return (S_ISREG(sbuf->st_mode));
}
/*******************************************************************
@@ -352,12 +249,12 @@ BOOL file_exist(char *fname,SMB_STRUCT_STAT *sbuf)
********************************************************************/
int file_rename(char *from, char *to)
{
- int rcode = rename (from, to);
+ int rcode = rename(from, to);
- if (errno == EXDEV)
+ if (errno == EXDEV)
{
/* Rename across filesystems needed. */
- rcode = copy_reg (from, to);
+ rcode = copy_reg(from, to);
}
return rcode;
}
@@ -367,43 +264,44 @@ check a files mod time
********************************************************************/
time_t file_modtime(char *fname)
{
- SMB_STRUCT_STAT st;
-
- if (sys_stat(fname,&st) != 0)
- return(0);
+ SMB_STRUCT_STAT st;
- return(st.st_mtime);
+ if (sys_stat(fname, &st) != 0)
+ return (0);
+
+ return (st.st_mtime);
}
/*******************************************************************
check if a directory exists
********************************************************************/
-BOOL directory_exist(char *dname,SMB_STRUCT_STAT *st)
+BOOL directory_exist(char *dname, SMB_STRUCT_STAT * st)
{
- SMB_STRUCT_STAT st2;
- BOOL ret;
+ SMB_STRUCT_STAT st2;
+ BOOL ret;
- if (!st) st = &st2;
+ if (!st)
+ st = &st2;
- if (sys_stat(dname,st) != 0)
- return(False);
+ if (sys_stat(dname, st) != 0)
+ return (False);
- ret = S_ISDIR(st->st_mode);
- if(!ret)
- errno = ENOTDIR;
- return ret;
+ ret = S_ISDIR(st->st_mode);
+ if (!ret)
+ errno = ENOTDIR;
+ return ret;
}
/*******************************************************************
returns the size in bytes of the named file
********************************************************************/
-SMB_OFF_T get_file_size(char *file_name)
+SMB_OFF_T file_size(char *file_name)
{
- SMB_STRUCT_STAT buf;
- buf.st_size = 0;
- if(sys_stat(file_name,&buf) != 0)
- return (SMB_OFF_T)-1;
- return(buf.st_size);
+ SMB_STRUCT_STAT buf;
+ buf.st_size = 0;
+ if (sys_stat(file_name, &buf) != 0)
+ return (SMB_OFF_T) - 1;
+ return (buf.st_size);
}
/*******************************************************************
@@ -411,18 +309,40 @@ return a string representing an attribute for a file
********************************************************************/
char *attrib_string(uint16 mode)
{
- static fstring attrstr;
+ static fstring attrstr;
+
+ attrstr[0] = 0;
- attrstr[0] = 0;
+ if (mode & aVOLID)
+ fstrcat(attrstr, "V");
+ if (mode & aDIR)
+ fstrcat(attrstr, "D");
+ if (mode & aARCH)
+ fstrcat(attrstr, "A");
+ if (mode & aHIDDEN)
+ fstrcat(attrstr, "H");
+ if (mode & aSYSTEM)
+ fstrcat(attrstr, "S");
+ if (mode & aRONLY)
+ fstrcat(attrstr, "R");
- if (mode & aVOLID) fstrcat(attrstr,"V");
- if (mode & aDIR) fstrcat(attrstr,"D");
- if (mode & aARCH) fstrcat(attrstr,"A");
- if (mode & aHIDDEN) fstrcat(attrstr,"H");
- if (mode & aSYSTEM) fstrcat(attrstr,"S");
- if (mode & aRONLY) fstrcat(attrstr,"R");
+ return (attrstr);
+}
- return(attrstr);
+/****************************************************************************
+ make a file into unix format
+****************************************************************************/
+void unix_format(char *fname)
+{
+ string_replace(fname, '\\', '/');
+}
+
+/****************************************************************************
+ make a file into dos format
+****************************************************************************/
+void dos_format(char *fname)
+{
+ string_replace(fname, '/', '\\');
}
/*******************************************************************
@@ -431,36 +351,36 @@ char *attrib_string(uint16 mode)
void show_msg(char *buf)
{
int i;
- int bcc=0;
-
- if (DEBUGLEVEL < 5) return;
+ int bcc = 0;
- DEBUG(5,("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
- smb_len(buf),
- (int)CVAL(buf,smb_com),
- (int)CVAL(buf,smb_rcls),
- (int)CVAL(buf,smb_reh),
- (int)SVAL(buf,smb_err),
- (int)CVAL(buf,smb_flg),
- (int)SVAL(buf,smb_flg2)));
- DEBUG(5,("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
- (int)SVAL(buf,smb_tid),
- (int)SVAL(buf,smb_pid),
- (int)SVAL(buf,smb_uid),
- (int)SVAL(buf,smb_mid),
- (int)CVAL(buf,smb_wct)));
+ if (DEBUGLEVEL < 5)
+ return;
- for (i=0;i<(int)CVAL(buf,smb_wct);i++)
+ DEBUG(5,
+ ("size=%d\nsmb_com=0x%x\nsmb_rcls=%d\nsmb_reh=%d\nsmb_err=%d\nsmb_flg=%d\nsmb_flg2=%d\n",
+ smb_len(buf), (int)CVAL(buf, smb_com), (int)CVAL(buf,
+ smb_rcls),
+ (int)CVAL(buf, smb_reh), (int)SVAL(buf, smb_err),
+ (int)CVAL(buf, smb_flg), (int)SVAL(buf, smb_flg2)));
+ DEBUG(5,
+ ("smb_tid=%d\nsmb_pid=%d\nsmb_uid=%d\nsmb_mid=%d\nsmt_wct=%d\n",
+ (int)SVAL(buf, smb_tid), (int)SVAL(buf, smb_pid),
+ (int)SVAL(buf, smb_uid), (int)SVAL(buf, smb_mid),
+ (int)CVAL(buf, smb_wct)));
+
+ for (i = 0; i < (int)CVAL(buf, smb_wct); i++)
{
- DEBUG(5,("smb_vwv[%d]=%d (0x%X)\n",i,
- SVAL(buf,smb_vwv+2*i),SVAL(buf,smb_vwv+2*i)));
+ DEBUG(5, ("smb_vwv[%d]=%d (0x%X)\n", i,
+ SVAL(buf, smb_vwv + 2 * i), SVAL(buf,
+ smb_vwv + 2 * i)));
}
- bcc = (int)SVAL(buf,smb_vwv+2*(CVAL(buf,smb_wct)));
+ bcc = (int)SVAL(buf, smb_vwv + 2 * (CVAL(buf, smb_wct)));
- DEBUG(5,("smb_bcc=%d\n",bcc));
+ DEBUG(5, ("smb_bcc=%d\n", bcc));
- if (DEBUGLEVEL < 10) return;
+ if (DEBUGLEVEL < 10)
+ return;
if (DEBUGLEVEL < 50)
{
@@ -471,341 +391,160 @@ void show_msg(char *buf)
}
/*******************************************************************
- set the length and marker of an smb packet
+ return the length of an smb packet
********************************************************************/
-void smb_setlen(char *buf,int len)
+int smb_len(char *buf)
{
- _smb_setlen(buf,len);
-
- CVAL(buf,4) = 0xFF;
- CVAL(buf,5) = 'S';
- CVAL(buf,6) = 'M';
- CVAL(buf,7) = 'B';
+ return (PVAL(buf, 3) | (PVAL(buf, 2) << 8) |
+ ((PVAL(buf, 1) & 1) << 16));
}
/*******************************************************************
- setup the word count and byte count for a smb message
+ set the length of an smb packet
********************************************************************/
-int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
+void _smb_setlen(char *buf, int len)
{
- if (zero)
- memset(buf + smb_size,'\0',num_words*2 + num_bytes);
- CVAL(buf,smb_wct) = num_words;
- SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
- smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
- return (smb_size + num_words*2 + num_bytes);
+ buf[0] = 0;
+ buf[1] = (len & 0x10000) >> 16;
+ buf[2] = (len & 0xFF00) >> 8;
+ buf[3] = len & 0xFF;
}
/*******************************************************************
-reduce a file name, removing .. elements.
+ set the length and marker of an smb packet
********************************************************************/
-void dos_clean_name(char *s)
+void smb_setlen(char *buf, int len)
{
- char *p=NULL;
-
- DEBUG(3,("dos_clean_name [%s]\n",s));
-
- /* remove any double slashes */
- all_string_sub(s, "\\\\", "\\", 0);
-
- while ((p = strstr(s,"\\..\\")) != NULL)
- {
- pstring s1;
-
- *p = 0;
- pstrcpy(s1,p+3);
-
- if ((p=strrchr(s,'\\')) != NULL)
- *p = 0;
- else
- *s = 0;
- pstrcat(s,s1);
- }
+ _smb_setlen(buf, len);
- trim_string(s,NULL,"\\..");
-
- all_string_sub(s, "\\.\\", "\\", 0);
+ CVAL(buf, 4) = 0xFF;
+ CVAL(buf, 5) = 'S';
+ CVAL(buf, 6) = 'M';
+ CVAL(buf, 7) = 'B';
}
/*******************************************************************
-reduce a file name, removing .. elements.
+ setup the word count and byte count for a smb message
********************************************************************/
-void unix_clean_name(char *s)
+int set_message(char *buf, int num_words, int num_bytes, BOOL zero)
{
- char *p=NULL;
-
- DEBUG(3,("unix_clean_name [%s]\n",s));
-
- /* remove any double slashes */
- all_string_sub(s, "//","/", 0);
-
- /* Remove leading ./ characters */
- if(strncmp(s, "./", 2) == 0) {
- trim_string(s, "./", NULL);
- if(*s == 0)
- pstrcpy(s,"./");
- }
-
- while ((p = strstr(s,"/../")) != NULL)
- {
- pstring s1;
-
- *p = 0;
- pstrcpy(s1,p+3);
-
- if ((p=strrchr(s,'/')) != NULL)
- *p = 0;
- else
- *s = 0;
- pstrcat(s,s1);
- }
-
- trim_string(s,NULL,"/..");
+ if (zero)
+ bzero(buf + smb_size, num_words * 2 + num_bytes);
+ CVAL(buf, smb_wct) = num_words;
+ SSVAL(buf, smb_vwv + num_words * SIZEOFWORD, num_bytes);
+ smb_setlen(buf, smb_size + num_words * 2 + num_bytes - 4);
+ return (smb_size + num_words * 2 + num_bytes);
}
/*******************************************************************
-reduce a file name, removing .. elements and checking that
-it is below dir in the heirachy. This uses dos_GetWd() and so must be run
-on the system that has the referenced file system.
+return the number of smb words
+********************************************************************/
+static int smb_numwords(char *buf)
+{
+ return (CVAL(buf, smb_wct));
+}
-widelinks are allowed if widelinks is true
+/*******************************************************************
+return the size of the smb_buf region of a message
********************************************************************/
+int smb_buflen(char *buf)
+{
+ return (SVAL(buf, smb_vwv0 + smb_numwords(buf) * 2));
+}
-BOOL reduce_name(char *s,char *dir,BOOL widelinks)
+/*******************************************************************
+ return a pointer to the smb_buf data area
+********************************************************************/
+static int smb_buf_ofs(char *buf)
{
-#ifndef REDUCE_PATHS
- return True;
-#else
- pstring dir2;
- pstring wd;
- pstring base_name;
- pstring newname;
- char *p=NULL;
- BOOL relative = (*s != '/');
-
- *dir2 = *wd = *base_name = *newname = 0;
-
- if (widelinks)
- {
- unix_clean_name(s);
- /* can't have a leading .. */
- if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
- {
- DEBUG(3,("Illegal file name? (%s)\n",s));
- return(False);
- }
-
- if (strlen(s) == 0)
- pstrcpy(s,"./");
-
- return(True);
- }
-
- DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
-
- /* remove any double slashes */
- all_string_sub(s,"//","/",0);
-
- pstrcpy(base_name,s);
- p = strrchr(base_name,'/');
-
- if (!p)
- return(True);
-
- if (!dos_GetWd(wd))
- {
- DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
- return(False);
- }
-
- if (dos_ChDir(dir) != 0)
- {
- DEBUG(0,("couldn't chdir to %s\n",dir));
- return(False);
- }
-
- if (!dos_GetWd(dir2))
- {
- DEBUG(0,("couldn't getwd for %s\n",dir));
- dos_ChDir(wd);
- return(False);
- }
-
- if (p && (p != base_name))
- {
- *p = 0;
- if (strcmp(p+1,".")==0)
- p[1]=0;
- if (strcmp(p+1,"..")==0)
- *p = '/';
- }
-
- if (dos_ChDir(base_name) != 0)
- {
- dos_ChDir(wd);
- DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
- return(False);
- }
-
- if (!dos_GetWd(newname))
- {
- dos_ChDir(wd);
- DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
- return(False);
- }
-
- if (p && (p != base_name))
- {
- pstrcat(newname,"/");
- pstrcat(newname,p+1);
- }
-
- {
- size_t l = strlen(dir2);
- if (dir2[l-1] == '/')
- l--;
-
- if (strncmp(newname,dir2,l) != 0)
- {
- dos_ChDir(wd);
- DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,(int)l));
- return(False);
- }
-
- if (relative)
- {
- if (newname[l] == '/')
- pstrcpy(s,newname + l + 1);
- else
- pstrcpy(s,newname+l);
- }
- else
- pstrcpy(s,newname);
- }
-
- dos_ChDir(wd);
-
- if (strlen(s) == 0)
- pstrcpy(s,"./");
-
- DEBUG(3,("reduced to %s\n",s));
- return(True);
-#endif
+ return (smb_size + CVAL(buf, smb_wct) * 2);
}
-/****************************************************************************
-expand some *s
-****************************************************************************/
-static void expand_one(char *Mask,int len)
+/*******************************************************************
+ return a pointer to the smb_buf data area
+********************************************************************/
+char *smb_buf(char *buf)
{
- char *p1;
- while ((p1 = strchr(Mask,'*')) != NULL)
- {
- int lfill = (len+1) - strlen(Mask);
- int l1= (p1 - Mask);
- pstring tmp;
- pstrcpy(tmp,Mask);
- memset(tmp+l1,'?',lfill);
- pstrcpy(tmp + l1 + lfill,Mask + l1 + 1);
- pstrcpy(Mask,tmp);
- }
+ return (buf + smb_buf_ofs(buf));
}
-/****************************************************************************
-expand a wildcard expression, replacing *s with ?s
-****************************************************************************/
-void expand_mask(char *Mask,BOOL doext)
+/*******************************************************************
+return the SMB offset into an SMB buffer
+********************************************************************/
+int smb_offset(char *p, char *buf)
{
- pstring mbeg,mext;
- pstring dirpart;
- pstring filepart;
- BOOL hasdot = False;
- char *p1;
- BOOL absolute = (*Mask == '\\');
+ return (PTR_DIFF(p, buf + 4) + chain_size);
+}
- *mbeg = *mext = *dirpart = *filepart = 0;
- /* parse the directory and filename */
- if (strchr(Mask,'\\'))
- split_at_last_component(Mask,dirpart,'\\',NULL);
- filename_dos(Mask,filepart);
+/*******************************************************************
+reduce a file name, removing .. elements.
+********************************************************************/
+void dos_clean_name(char *s)
+{
+ char *p = NULL;
- pstrcpy(mbeg,filepart);
- if ((p1 = strchr(mbeg,'.')) != NULL)
- {
- hasdot = True;
- *p1 = 0;
- p1++;
- pstrcpy(mext,p1);
- }
- else
- {
- pstrcpy(mext,"");
- if (strlen(mbeg) > 8)
- {
- pstrcpy(mext,mbeg + 8);
- mbeg[8] = 0;
- }
- }
+ DEBUG(3, ("dos_clean_name [%s]\n", s));
+
+ /* remove any double slashes */
+ string_sub(s, "\\\\", "\\");
- if (*mbeg == 0)
- pstrcpy(mbeg,"????????");
- if ((*mext == 0) && doext && !hasdot)
- pstrcpy(mext,"???");
+ while ((p = strstr(s, "\\..\\")) != NULL)
+ {
+ pstring s1;
- if (strequal(mbeg,"*") && *mext==0)
- pstrcpy(mext,"*");
+ *p = 0;
+ pstrcpy(s1, p + 3);
- /* expand *'s */
- expand_one(mbeg,8);
- if (*mext)
- expand_one(mext,3);
+ if ((p = strrchr(s, '\\')) != NULL)
+ *p = 0;
+ else
+ *s = 0;
+ pstrcat(s, s1);
+ }
- pstrcpy(Mask,dirpart);
- if (*dirpart || absolute) pstrcat(Mask,"\\");
- pstrcat(Mask,mbeg);
- pstrcat(Mask,".");
- pstrcat(Mask,mext);
+ trim_string(s, NULL, "\\..");
- DEBUG(6,("Mask expanded to [%s]\n",Mask));
-}
+ string_sub(s, "\\.\\", "\\");
+}
/****************************************************************************
make a dir struct
****************************************************************************/
-void make_dir_struct(char *buf,char *mask,char *fname,SMB_OFF_T size,int mode,time_t date)
-{
- char *p;
- pstring mask2;
-
- pstrcpy(mask2,mask);
-
- if ((mode & aDIR) != 0)
- size = 0;
-
- memset(buf+1,' ',11);
- if ((p = strchr(mask2,'.')) != NULL)
- {
- *p = 0;
- memcpy(buf+1,mask2,MIN(strlen(mask2),8));
- memcpy(buf+9,p+1,MIN(strlen(p+1),3));
- *p = '.';
- }
- else
- memcpy(buf+1,mask2,MIN(strlen(mask2),11));
-
- memset(buf+21,'\0',DIR_STRUCT_SIZE-21);
- CVAL(buf,21) = mode;
- put_dos_date(buf,22,date);
- SSVAL(buf,26,size & 0xFFFF);
- SSVAL(buf,28,(size >> 16)&0xFFFF);
- StrnCpy(buf+30,fname,12);
- if (!case_sensitive)
- strupper(buf+30);
- DEBUG(8,("put name [%s] into dir struct\n",buf+30));
+void make_dir_struct(char *buf, char *mask, char *fname, SMB_OFF_T size,
+ int mode, time_t date)
+{
+ char *p;
+ pstring mask2;
+
+ pstrcpy(mask2, mask);
+
+ if ((mode & aDIR) != 0)
+ size = 0;
+
+ memset(buf + 1, ' ', 11);
+ if ((p = strchr(mask2, '.')) != NULL)
+ {
+ *p = 0;
+ memcpy(buf + 1, mask2, MIN(strlen(mask2), 8));
+ memcpy(buf + 9, p + 1, MIN(strlen(p + 1), 3));
+ *p = '.';
+ }
+ else
+ memcpy(buf + 1, mask2, MIN(strlen(mask2), 11));
+
+ bzero(buf + 21, DIR_STRUCT_SIZE - 21);
+ CVAL(buf, 21) = mode;
+ put_dos_date(buf, 22, date);
+ SSVAL(buf, 26, size & 0xFFFF);
+ SSVAL(buf, 28, (size >> 16) & 0xFFFF);
+ StrnCpy(buf + 30, fname, 12);
+ if (!case_sensitive)
+ strupper(buf + 30);
+ DEBUG(8, ("put name [%s] into dir struct\n", buf + 30));
}
@@ -814,23 +553,29 @@ close the low 3 fd's and open dev/null in their place
********************************************************************/
void close_low_fds(void)
{
- int fd;
- int i;
- close(0); close(1); close(2);
- /* try and use up these file descriptors, so silly
- library routines writing to stdout etc won't cause havoc */
- for (i=0;i<3;i++) {
- fd = sys_open("/dev/null",O_RDWR,0);
- if (fd < 0) fd = sys_open("/dev/null",O_WRONLY,0);
- if (fd < 0) {
- DEBUG(0,("Can't open /dev/null\n"));
- return;
- }
- if (fd != i) {
- DEBUG(0,("Didn't get file descriptor %d\n",i));
- return;
- }
- }
+ int fd;
+ int i;
+ close(0);
+ close(1);
+ close(2);
+ /* try and use up these file descriptors, so silly
+ library routines writing to stdout etc won't cause havoc */
+ for (i = 0; i < 3; i++)
+ {
+ fd = sys_open("/dev/null", O_RDWR, 0);
+ if (fd < 0)
+ fd = sys_open("/dev/null", O_WRONLY, 0);
+ if (fd < 0)
+ {
+ DEBUG(0, ("Can't open /dev/null\n"));
+ return;
+ }
+ if (fd != i)
+ {
+ DEBUG(0, ("Didn't get file descriptor %d\n", i));
+ return;
+ }
+ }
}
/****************************************************************************
@@ -841,7 +586,7 @@ if BSD use FNDELAY
****************************************************************************/
int set_blocking(int fd, BOOL set)
{
- int val;
+ int val;
#ifdef O_NONBLOCK
#define FLAG_TO_SET O_NONBLOCK
#else
@@ -852,144 +597,121 @@ int set_blocking(int fd, BOOL set)
#endif
#endif
- if((val = fcntl(fd, F_GETFL, 0)) == -1)
- return -1;
- if(set) /* Turn blocking on - ie. clear nonblock flag */
- val &= ~FLAG_TO_SET;
- else
- val |= FLAG_TO_SET;
- return fcntl( fd, F_SETFL, val);
+ if ((val = fcntl(fd, F_GETFL, 0)) == -1)
+ return -1;
+ if (set) /* Turn blocking on - ie. clear nonblock flag */
+ val &= ~FLAG_TO_SET;
+ else
+ val |= FLAG_TO_SET;
+ return fcntl(fd, F_SETFL, val);
#undef FLAG_TO_SET
}
-/****************************************************************************
-transfer some data between two fd's
-****************************************************************************/
-SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n,char *header,int headlen,int align)
-{
- static char *buf=NULL;
- static int size=0;
- char *buf1,*abuf;
- SMB_OFF_T total = 0;
-
- DEBUG(4,("transfer_file n=%.0f (head=%d) called\n",(double)n,headlen));
-
- if (size == 0) {
- size = lp_readsize();
- size = MAX(size,1024);
- }
-
- while (!buf && size>0) {
- buf = (char *)Realloc(buf,size+8);
- if (!buf) size /= 2;
- }
-
- if (!buf) {
- DEBUG(0,("Can't allocate transfer buffer!\n"));
- exit(1);
- }
-
- abuf = buf + (align%8);
-
- if (header)
- n += headlen;
-
- while (n > 0)
- {
- int s = (int)MIN(n,(SMB_OFF_T)size);
- int ret,ret2=0;
-
- ret = 0;
-
- if (header && (headlen >= MIN(s,1024))) {
- buf1 = header;
- s = headlen;
- ret = headlen;
- headlen = 0;
- header = NULL;
- } else {
- buf1 = abuf;
- }
-
- if (header && headlen > 0)
- {
- ret = MIN(headlen,size);
- memcpy(buf1,header,ret);
- headlen -= ret;
- header += ret;
- if (headlen <= 0) header = NULL;
- }
-
- if (s > ret)
- ret += read(infd,buf1+ret,s-ret);
-
- if (ret > 0)
- {
- ret2 = (outfd>=0?write_data(outfd,buf1,ret):ret);
- if (ret2 > 0) total += ret2;
- /* if we can't write then dump excess data */
- if (ret2 != ret)
- transfer_file(infd,-1,n-(ret+headlen),NULL,0,0);
- }
- if (ret <= 0 || ret2 != ret)
- return(total);
- n -= ret;
- }
- return(total);
+
+/*******************************************************************
+find the difference in milliseconds between two struct timeval
+values
+********************************************************************/
+int TvalDiff(struct timeval *tvalold, struct timeval *tvalnew)
+{
+ return ((tvalnew->tv_sec - tvalold->tv_sec) * 1000 +
+ ((int)tvalnew->tv_usec - (int)tvalold->tv_usec) / 1000);
}
/****************************************************************************
-find a pointer to a netbios name
+transfer some data between two fd's
****************************************************************************/
-static char *name_ptr(char *buf,int ofs)
+SMB_OFF_T transfer_file(int infd, int outfd, SMB_OFF_T n, char *header,
+ int headlen, int align)
{
- unsigned char c = *(unsigned char *)(buf+ofs);
+ static char *buf = NULL;
+ static int size = 0;
+ char *buf1, *abuf;
+ SMB_OFF_T total = 0;
- if ((c & 0xC0) == 0xC0)
- {
- uint16 l = RSVAL(buf, ofs) & 0x3FFF;
- DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
- return(buf + l);
- }
- else
- return(buf+ofs);
-}
+ DEBUG(4,
+ ("transfer_file n=%.0f (head=%d) called\n", (double)n,
+ headlen));
-/****************************************************************************
-extract a netbios name from a buf
-****************************************************************************/
-int name_extract(char *buf,int ofs,char *name)
-{
- char *p = name_ptr(buf,ofs);
- int d = PTR_DIFF(p,buf+ofs);
- pstrcpy(name,"");
- if (d < -50 || d > 50) return(0);
- return(name_interpret(p,name));
-}
-
-/****************************************************************************
-return the total storage length of a mangled name
-****************************************************************************/
-int name_len(char *s1)
-{
- /* NOTE: this argument _must_ be unsigned */
- unsigned char *s = (unsigned char *)s1;
- int len;
+ if (size == 0)
+ {
+ size = lp_readsize();
+ size = MAX(size, 1024);
+ }
- /* If the two high bits of the byte are set, return 2. */
- if (0xC0 == (*s & 0xC0))
- return(2);
+ while (!buf && size > 0)
+ {
+ buf = (char *)Realloc(buf, size + 8);
+ if (!buf)
+ size /= 2;
+ }
- /* Add up the length bytes. */
- for (len = 1; (*s); s += (*s) + 1) {
- len += *s + 1;
- SMB_ASSERT(len < 80);
+ if (!buf)
+ {
+ DEBUG(0, ("Can't allocate transfer buffer!\n"));
+ exit(1);
}
- return(len);
-} /* name_len */
+ abuf = buf + (align % 8);
+
+ if (header)
+ n += headlen;
+
+ while (n > 0)
+ {
+ int s = (int)MIN(n, (SMB_OFF_T) size);
+ int ret, ret2 = 0;
+
+ ret = 0;
+
+ if (header && (headlen >= MIN(s, 1024)))
+ {
+ buf1 = header;
+ s = headlen;
+ ret = headlen;
+ headlen = 0;
+ header = NULL;
+ }
+ else
+ {
+ buf1 = abuf;
+ }
+
+ if (header && headlen > 0)
+ {
+ ret = MIN(headlen, size);
+ memcpy(buf1, header, ret);
+ headlen -= ret;
+ header += ret;
+ if (headlen <= 0)
+ header = NULL;
+ }
+
+ if (s > ret)
+ ret += read(infd, buf1 + ret, s - ret);
+
+ if (ret > 0)
+ {
+ ret2 =
+ (outfd >=
+ 0 ? write_data(outfd, buf1, ret) : ret);
+ if (ret2 > 0)
+ total += ret2;
+ /* if we can't write then dump excess data */
+ if (ret2 != ret)
+ transfer_file(infd, -1, n - (ret + headlen),
+ NULL, 0, 0);
+ }
+ if (ret <= 0 || ret2 != ret)
+ return (total);
+ n -= ret;
+ }
+ return (total);
+}
+
+
/*******************************************************************
@@ -997,125 +719,133 @@ sleep for a specified number of milliseconds
********************************************************************/
void msleep(int t)
{
- int tdiff=0;
- struct timeval tval,t1,t2;
- fd_set fds;
+ int tdiff = 0;
+ struct timeval tval, t1, t2;
+ fd_set fds;
+
+ GetTimeOfDay(&t1);
+ GetTimeOfDay(&t2);
- GetTimeOfDay(&t1);
- GetTimeOfDay(&t2);
-
- while (tdiff < t) {
- tval.tv_sec = (t-tdiff)/1000;
- tval.tv_usec = 1000*((t-tdiff)%1000);
-
- FD_ZERO(&fds);
- errno = 0;
- sys_select(0,&fds,&tval);
+ while (tdiff < t)
+ {
+ tval.tv_sec = (t - tdiff) / 1000;
+ tval.tv_usec = 1000 * ((t - tdiff) % 1000);
+
+ FD_ZERO(&fds);
+ errno = 0;
+ sys_select(0, &fds, NULL, &tval);
- GetTimeOfDay(&t2);
- tdiff = TvalDiff(&t1,&t2);
- }
+ GetTimeOfDay(&t2);
+ tdiff = TvalDiff(&t1, &t2);
+ }
}
+/****************************************************************************
+open the directory and look-up the matching names
+****************************************************************************/
+BOOL get_file_match(const char *dirname, const char *regexp,
+ uint32 * total, char ***list)
+{
+ DIR *dirp;
+ char *dpname;
+
+ dirp = opendir(dirname);
+
+ if (dirp == NULL)
+ {
+ DEBUG(2, ("Error opening directory [%s]\n", dirname));
+ return False;
+ }
+
+ DEBUG(5, ("get_dir_match: %s with %s\n", dirname, regexp));
+
+ while ((dpname = readdirname(dirp)) != NULL)
+ {
+ if (do_match(dpname, regexp, False))
+ {
+ DEBUGADD(7, ("Found: [%s]\n", dpname));
+
+ add_chars_to_array(total, list, dpname);
+ DEBUGADD(6, ("Added: [%s]\n", dpname));
+ }
+ }
+
+ closedir(dirp);
+
+ return True;
+}
/*********************************************************
* Recursive routine that is called by unix_mask_match.
* Does the actual matching. This is the 'original code'
* used by the unix matcher.
*********************************************************/
+static BOOL unix_do_match(char *str, char *regexp, int case_sig)
+{
+ char *p;
+
+ for (p = regexp; *p && *str;)
+ {
+ switch (*p)
+ {
+ case '?':
+ str++;
+ p++;
+ break;
+
+ case '*':
+ /* Look for a character matching
+ the one after the '*' */
+ p++;
+ if (!*p)
+ return True; /* Automatic match */
+ while (*str)
+ {
+ while (*str
+ && (case_sig ? (*p != *str)
+ : (toupper(*p) !=
+ toupper(*str))))
+ str++;
+ if (unix_do_match(str, p, case_sig))
+ return True;
+ if (!*str)
+ return False;
+ else
+ str++;
+ }
+ return False;
+
+ default:
+ if (case_sig)
+ {
+ if (*str != *p)
+ return False;
+ }
+ else
+ {
+ if (toupper(*str) != toupper(*p))
+ return False;
+ }
+ str++, p++;
+ break;
+ }
+ }
+ if (!*p && !*str)
+ return True;
+
+ if (!*p && str[0] == '.' && str[1] == 0)
+ return (True);
+
+ if (!*str && *p == '?')
+ {
+ while (*p == '?')
+ p++;
+ return (!*p);
+ }
-BOOL unix_do_match(char *str, char *regexp, BOOL case_sig)
-{
- char *p;
-
-
- while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
- str++;
-
- for( p = regexp; *p && *str; ) {
- switch(*p) {
- case '?':
- str++; p++;
- break;
-
- case '*':
- /*
- * Look for a character matching
- * the one after the '*'.
- */
- p++;
- if(!*p)
- return True; /* Automatic match */
- while(*str) {
- /*
- * Patch from weidel@multichart.de. In the case of the regexp
- * '*XX*' we want to ensure there are at least 2 'X' characters
- * in the filename after the '*' for a match to be made.
- */
-
- {
- int matchcount=0;
-
- /*
- * Eat all the characters that match, but count how many there were.
- */
-
- while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str)))) {
- str++;
- matchcount++;
- }
-
- /*
- * Now check that if the regexp had n identical characters that
- * matchcount had at least that many matches.
- */
-
- while (( *(p+1) && (case_sig ? (*(p+1) == *p) : (toupper(*(p+1))==toupper(*p))))) {
- p++;
- matchcount--;
- }
- if ( matchcount <= 0 ) {
- return False;
- }
- }
- str--; /* We've eaten the match char after the '*' */
- if(unix_do_match(str,p,case_sig))
- return True;
- if(!*str)
- return False;
- else
- str++;
- }
- return False;
-
- default:
- if(case_sig) {
- if(*str != *p)
- return False;
- } else {
- if(toupper(*str) != toupper(*p))
- return False;
- }
- str++, p++;
- break;
- }
- }
-
- if(!*p && !*str)
- return True;
-
- if (!*p && str[0] == '.' && str[1] == 0)
- return(True);
-
- if (!*str && *p == '?')
- {
- while (*p == '?') p++;
- return(!*p);
- }
-
- if(!*str && (*p == '*' && p[1] == '\0'))
- return True;
- return False;
+ if (!*str && (*p == '*' && p[1] == '\0'))
+ return True;
+ return False;
}
@@ -1126,147 +856,176 @@ BOOL unix_do_match(char *str, char *regexp, BOOL case_sig)
* This is the 'original code' used by the unix matcher.
*********************************************************/
-static BOOL unix_mask_match(char *str, char *regexp, BOOL case_sig)
+static BOOL unix_mask_match(char *str, char *regexp, int case_sig,
+ BOOL trans2)
{
- char *p;
- pstring p1, p2;
- fstring ebase,eext,sbase,sext;
- BOOL matched;
+ char *p;
+ pstring p1, p2;
+ fstring ebase, eext, sbase, sext;
+
+ BOOL matched;
- /* Make local copies of str and regexp */
- StrnCpy(p1,regexp,sizeof(pstring)-1);
- StrnCpy(p2,str,sizeof(pstring)-1);
+ /* Make local copies of str and regexp */
+ StrnCpy(p1, regexp, sizeof(pstring) - 1);
+ StrnCpy(p2, str, sizeof(pstring) - 1);
+
+ if (!strchr(p2, '.'))
+ {
+ pstrcat(p2, ".");
+ }
- /* Remove any *? and ** as they are meaningless */
- for(p = p1; *p; p++)
- while( *p == '*' && (p[1] == '?' ||p[1] == '*'))
- (void)pstrcpy( &p[1], &p[2]);
+ /* Remove any *? and ** as they are meaningless */
+ for (p = p1; *p; p++)
+ while (*p == '*' && (p[1] == '?' || p[1] == '*'))
+ (void)pstrcpy(&p[1], &p[2]);
- if (strequal(p1,"*")) return(True);
+ if (strequal(p1, "*"))
+ return (True);
- DEBUG(8,("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig));
+ DEBUG(8,
+ ("unix_mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2,
+ p1, case_sig));
- fstrcpy(ebase,p1);
- fstrcpy(sbase,p2);
+ if (trans2)
+ {
+ fstrcpy(ebase, p1);
+ fstrcpy(sbase, p2);
+ }
+ else
+ {
+ if ((p = strrchr(p1, '.')))
+ {
+ *p = 0;
+ fstrcpy(ebase, p1);
+ fstrcpy(eext, p + 1);
+ }
+ else
+ {
+ fstrcpy(ebase, p1);
+ eext[0] = 0;
+ }
+
+ if (!strequal(p2, ".") && !strequal(p2, "..")
+ && (p = strrchr(p2, '.')))
+ {
+ *p = 0;
+ fstrcpy(sbase, p2);
+ fstrcpy(sext, p + 1);
+ }
+ else
+ {
+ fstrcpy(sbase, p2);
+ fstrcpy(sext, "");
+ }
+ }
- matched = unix_do_match(sbase,ebase,case_sig);
+ matched = unix_do_match(sbase, ebase, case_sig) &&
+ (trans2 || unix_do_match(sext, eext, case_sig));
- DEBUG(8,("unix_mask_match returning %d\n", matched));
+ DEBUG(8, ("unix_mask_match returning %d\n", matched));
- return matched;
+ return matched;
}
/*********************************************************
* Recursive routine that is called by mask_match.
* Does the actual matching. Returns True if matched,
* False if failed. This is the 'new' NT style matcher.
-* The win9x_semantics parameter is needed as Win9x matching
-* is *actually different*. In Win9x, trailing '?' characters
-* will only match the *exact* number of characters. Under
-* DOS and NT they match any number. This makes no
-* sense.....
*********************************************************/
-static BOOL do_match(char *str, char *regexp, int case_sig, BOOL win9x_semantics)
-{
- char *p;
-
- for( p = regexp; *p && *str; ) {
- switch(*p) {
- case '?':
- str++; p++;
- break;
-
- case '*':
- /* Look for a character matching
- the one after the '*' */
- p++;
- if(!*p)
- return True; /* Automatic match */
- while(*str) {
- while(*str && (case_sig ? (*p != *str) : (toupper(*p)!=toupper(*str))))
- str++;
-
- /*
- * Patch from weidel@multichart.de. In the case of the regexp
- * '*XX*' we want to ensure there are at least 2 'X' characters
- * in the filename after the '*' for a match to be made.
- */
-
- {
- int matchcount=0;
-
- /*
- * Eat all the characters that match, but count how many there were.
- */
-
- while(*str && (case_sig ? (*p == *str) : (toupper(*p)==toupper(*str)))) {
- str++;
- matchcount++;
- }
-
- /*
- * Now check that if the regexp had n identical characters that
- * matchcount had at least that many matches.
- */
-
- while (( *(p+1) && (case_sig ? (*(p+1) == *p) : (toupper(*(p+1))==toupper(*p))))) {
- p++;
- matchcount--;
- }
- if ( matchcount <= 0 ) {
- return False;
- }
- }
- str--; /* We've eaten the match char after the '*' */
- if(do_match(str,p,case_sig,win9x_semantics)) {
- return True;
- }
- if(!*str) {
- return False;
- } else {
- str++;
- }
- }
- return False;
-
- default:
- if(case_sig) {
- if(*str != *p) {
- return False;
- }
- } else {
- if(toupper(*str) != toupper(*p)) {
- return False;
- }
- }
- str++, p++;
- break;
- }
- }
-
- if(!*p && !*str)
- return True;
-
- if (!*p && str[0] == '.' && str[1] == 0) {
- return(True);
- }
-
- if (!win9x_semantics) {
- if (!*str && *p == '?') {
- while (*p == '?')
- p++;
- return(!*p);
- }
- }
-
- if(!*str && (*p == '*' && p[1] == '\0')) {
- return True;
- }
-
- return False;
+BOOL do_match(char *str, const char *regexp, int case_sig)
+{
+ const char *p;
+
+ for (p = regexp; *p && *str;)
+ {
+ switch (*p)
+ {
+ case '?':
+ str++;
+ p++;
+ break;
+
+ case '*':
+ /* Look for a character matching
+ the one after the '*' */
+ p++;
+ if (!*p)
+ return True; /* Automatic match */
+ while (*str)
+ {
+ while (*str
+ && (case_sig ? (*p != *str)
+ : (toupper(*p) !=
+ toupper(*str))))
+ str++;
+ /* Now eat all characters that match, as
+ we want the *last* character to match. */
+ while (*str
+ && (case_sig ? (*p == *str)
+ : (toupper(*p) ==
+ toupper(*str))))
+ str++;
+ str--; /* We've eaten the match char after the '*' */
+ if (do_match(str, p, case_sig))
+ {
+ return True;
+ }
+ if (!*str)
+ {
+ return False;
+ }
+ else
+ {
+ str++;
+ }
+ }
+ return False;
+
+ default:
+ if (case_sig)
+ {
+ if (*str != *p)
+ {
+ return False;
+ }
+ }
+ else
+ {
+ if (toupper(*str) != toupper(*p))
+ {
+ return False;
+ }
+ }
+ str++, p++;
+ break;
+ }
+ }
+
+ if (!*p && !*str)
+ return True;
+
+ if (!*p && str[0] == '.' && str[1] == 0)
+ {
+ return (True);
+ }
+
+ if (!*str && *p == '?')
+ {
+ while (*p == '?')
+ p++;
+ return (!*p);
+ }
+
+ if (!*str && (*p == '*' && p[1] == '\0'))
+ {
+ return True;
+ }
+
+ return False;
}
+
/*********************************************************
* Routine to match a given string with a regexp - uses
* simplified regexp that takes * and ? only. Case can be
@@ -1275,243 +1034,269 @@ static BOOL do_match(char *str, char *regexp, int case_sig, BOOL win9x_semantics
* This is the new 'NT style' matcher.
*********************************************************/
-BOOL mask_match(char *str, char *regexp, BOOL case_sig, BOOL trans2)
+BOOL mask_match(char *str, char *regexp, int case_sig, BOOL trans2)
{
- char *p;
- pstring t_pattern, t_filename, te_pattern, te_filename;
- fstring ebase,eext,sbase,sext;
- BOOL matched = False;
- BOOL win9x_semantics = (get_remote_arch() == RA_WIN95) && trans2;
-
- /* special case - if it is exactly the same then it always matches! */
- if(exact_match(str, regexp, case_sig))
- return True;
-
- /* Make local copies of str and regexp */
- pstrcpy(t_pattern,regexp);
- pstrcpy(t_filename,str);
+ char *p;
+ pstring t_pattern, t_filename, te_pattern, te_filename;
+ fstring ebase, eext, sbase, sext;
- if(trans2) {
+ BOOL matched = False;
- /* a special case for 16 bit apps */
- if (strequal(t_pattern,"????????.???"))
- pstrcpy(t_pattern,"*");
+ /* Make local copies of str and regexp */
+ pstrcpy(t_pattern, regexp);
+ pstrcpy(t_filename, str);
#if 0
- /*
- * Handle broken clients that send us old 8.3 format.
- */
- pstring_sub(t_pattern,"????????","*");
- pstring_sub(t_pattern,".???",".*");
+ /*
+ * Not sure if this is a good idea. JRA.
+ */
+ if (trans2 && is_8_3(t_pattern, False) && is_8_3(t_filename, False))
+ trans2 = False;
#endif
- }
#if 0
- /*
- * Not sure if this is a good idea. JRA.
- */
- if(trans2 && is_8_3(t_pattern,False) && is_8_3(t_filename,False))
- trans2 = False;
+ if (!strchr(t_filename, '.'))
+ {
+ pstrcat(t_filename, ".");
+ }
#endif
-#if 0
- if (!strchr(t_filename,'.')) {
- pstrcat(t_filename,".");
- }
-#endif
+ /* Remove any *? and ** as they are meaningless */
+ string_sub(t_pattern, "*?", "*");
+ string_sub(t_pattern, "**", "*");
+
+ if (strequal(t_pattern, "*"))
+ return (True);
- /* Remove any *? and ** as they are meaningless */
- for(p = t_pattern; *p; p++)
- while( *p == '*' && (p[1] == '?' || p[1] == '*'))
- (void)pstrcpy( &p[1], &p[2]);
-
- if (strequal(t_pattern,"*"))
- return(True);
-
- DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename, t_pattern, case_sig));
-
- if(trans2) {
- /*
- * Match each component of the regexp, split up by '.'
- * characters.
- */
- char *fp, *rp, *cp2, *cp1;
- BOOL last_wcard_was_star = False;
- int num_path_components, num_regexp_components;
-
- pstrcpy(te_pattern,t_pattern);
- pstrcpy(te_filename,t_filename);
- /*
- * Remove multiple "*." patterns.
- */
- pstring_sub(te_pattern, "*.*.", "*.");
- num_regexp_components = count_chars(te_pattern, '.');
- num_path_components = count_chars(te_filename, '.');
-
- /*
- * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
- */
- if(num_regexp_components == 0)
- matched = do_match( te_filename, te_pattern, case_sig, win9x_semantics);
- else {
- for( cp1 = te_pattern, cp2 = te_filename; cp1;) {
- fp = strchr(cp2, '.');
- if(fp)
- *fp = '\0';
- rp = strchr(cp1, '.');
- if(rp)
- *rp = '\0';
-
- if(cp1[0] && cp1[strlen(cp1)-1] == '*')
- last_wcard_was_star = True;
- else
- last_wcard_was_star = False;
-
- if(!do_match(cp2, cp1, case_sig, win9x_semantics))
- break;
-
- /*
- * Ugly ! Special case for Win9x *only*. If filename is XXXX and pattern extension
- * is '*' or all '?' then disallow match.
- */
-
- if (win9x_semantics) {
- if (*cp2 == '\0' && str_is_all(cp1, '?'))
- break;
- }
-
- cp1 = rp ? rp + 1 : NULL;
- cp2 = fp ? fp + 1 : "";
-
- if(last_wcard_was_star || ((cp1 != NULL) && (*cp1 == '*'))) {
- /* Eat the extra path components. */
- int i;
-
- for(i = 0; i < num_path_components - num_regexp_components; i++) {
- fp = strchr(cp2, '.');
- if(fp)
- *fp = '\0';
-
- if((cp1 != NULL) && do_match( cp2, cp1, case_sig, win9x_semantics)) {
- cp2 = fp ? fp + 1 : "";
- break;
- }
- cp2 = fp ? fp + 1 : "";
- }
- num_path_components -= i;
- }
- }
- if(cp1 == NULL && ((*cp2 == '\0') || last_wcard_was_star))
- matched = True;
- }
- } else {
-
- /* -------------------------------------------------
- * Behaviour of Win95
- * for 8.3 filenames and 8.3 Wildcards
- * -------------------------------------------------
- */
- if (strequal (t_filename, ".")) {
- /*
- * Patterns: *.* *. ?. ? ????????.??? are valid.
- *
- */
- if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
- strequal(t_pattern, "????????.???") ||
- strequal(t_pattern, "?.") || strequal(t_pattern, "?"))
- matched = True;
- } else if (strequal (t_filename, "..")) {
- /*
- * Patterns: *.* *. ?. ? *.? ????????.??? are valid.
- *
- */
- if(strequal(t_pattern, "*.*") || strequal(t_pattern, "*.") ||
- strequal(t_pattern, "?.") || strequal(t_pattern, "?") ||
- strequal(t_pattern, "????????.???") ||
- strequal(t_pattern, "*.?") || strequal(t_pattern, "?.*"))
- matched = True;
- } else {
-
- if ((p = strrchr (t_pattern, '.'))) {
- /*
- * Wildcard has a suffix.
- */
- *p = 0;
- fstrcpy (ebase, t_pattern);
- if (p[1]) {
- fstrcpy (eext, p + 1);
- } else {
- /* pattern ends in DOT: treat as if there is no DOT */
- *eext = 0;
- if (strequal (ebase, "*"))
- return (True);
- }
- } else {
- /*
- * No suffix for wildcard.
- */
- fstrcpy (ebase, t_pattern);
- eext[0] = 0;
- }
-
- p = strrchr (t_filename, '.');
- if (p && (p[1] == 0) ) {
- /*
- * Filename has an extension of '.' only.
- */
- *p = 0; /* nuke dot at end of string */
- p = 0; /* and treat it as if there is no extension */
- }
-
- if (p) {
- /*
- * Filename has an extension.
- */
- *p = 0;
- fstrcpy (sbase, t_filename);
- fstrcpy (sext, p + 1);
- if (*eext) {
- matched = do_match(sbase, ebase, case_sig, False)
- && do_match(sext, eext, case_sig, False);
- } else {
- /* pattern has no extension */
- /* Really: match complete filename with pattern ??? means exactly 3 chars */
- matched = do_match(str, ebase, case_sig, False);
- }
- } else {
- /*
- * Filename has no extension.
- */
- fstrcpy (sbase, t_filename);
- fstrcpy (sext, "");
- if (*eext) {
- /* pattern has extension */
- matched = do_match(sbase, ebase, case_sig, False)
- && do_match(sext, eext, case_sig, False);
-
- } else {
- matched = do_match(sbase, ebase, case_sig, False);
+ DEBUG(8,
+ ("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", t_filename,
+ t_pattern, case_sig));
+
+ if (trans2)
+ {
+ /*
+ * Match each component of the regexp, split up by '.'
+ * characters.
+ */
+ char *fp, *rp, *cp2, *cp1;
+ BOOL last_wcard_was_star = False;
+ int num_path_components, num_regexp_components;
+
+ pstrcpy(te_pattern, t_pattern);
+ pstrcpy(te_filename, t_filename);
+ /*
+ * Remove multiple "*." patterns.
+ */
+ string_sub(te_pattern, "*.*.", "*.");
+ num_regexp_components = count_chars(te_pattern, '.');
+ num_path_components = count_chars(te_filename, '.');
+
+ /*
+ * Check for special 'hack' case of "DIR a*z". - needs to match a.b.c...z
+ */
+ if (num_regexp_components == 0)
+ matched = do_match(te_filename, te_pattern, case_sig);
+ else
+ {
+ for (cp1 = te_pattern, cp2 = te_filename; cp1;)
+ {
+ fp = strchr(cp2, '.');
+ if (fp)
+ *fp = '\0';
+ rp = strchr(cp1, '.');
+ if (rp)
+ *rp = '\0';
+
+ if (cp1[strlen(cp1) - 1] == '*')
+ last_wcard_was_star = True;
+ else
+ last_wcard_was_star = False;
+
+ if (!do_match(cp2, cp1, case_sig))
+ break;
+
+ cp1 = rp ? rp + 1 : NULL;
+ cp2 = fp ? fp + 1 : "";
+
+ if (last_wcard_was_star
+ || ((cp1 != NULL) && (*cp1 == '*')))
+ {
+ /* Eat the extra path components. */
+ int i;
+
+ for (i = 0;
+ i <
+ num_path_components -
+ num_regexp_components; i++)
+ {
+ fp = strchr(cp2, '.');
+ if (fp)
+ *fp = '\0';
+
+ if ((cp1 != NULL)
+ && do_match(cp2, cp1,
+ case_sig))
+ {
+ cp2 =
+ fp ? fp +
+ 1 : "";
+ break;
+ }
+ cp2 = fp ? fp + 1 : "";
+ }
+ num_path_components -= i;
+ }
+ }
+ if (cp1 == NULL
+ && ((*cp2 == '\0') || last_wcard_was_star))
+ matched = True;
+ }
+ }
+ else
+ {
+
+ /* -------------------------------------------------
+ * Behaviour of Win95
+ * for 8.3 filenames and 8.3 Wildcards
+ * -------------------------------------------------
+ */
+ if (strequal(t_filename, "."))
+ {
+ /*
+ * Patterns: *.* *. ?. ? are valid
+ *
+ */
+ if (strequal(t_pattern, "*.*")
+ || strequal(t_pattern, "*.")
+ || strequal(t_pattern, "?.")
+ || strequal(t_pattern, "?"))
+ matched = True;
+ }
+ else if (strequal(t_filename, ".."))
+ {
+ /*
+ * Patterns: *.* *. ?. ? *.? are valid
+ *
+ */
+ if (strequal(t_pattern, "*.*")
+ || strequal(t_pattern, "*.")
+ || strequal(t_pattern, "?.")
+ || strequal(t_pattern, "?")
+ || strequal(t_pattern, "*.?")
+ || strequal(t_pattern, "?.*"))
+ matched = True;
+ }
+ else
+ {
+
+ if ((p = strrchr(t_pattern, '.')))
+ {
+ /*
+ * Wildcard has a suffix.
+ */
+ *p = 0;
+ fstrcpy(ebase, t_pattern);
+ if (p[1])
+ {
+ fstrcpy(eext, p + 1);
+ }
+ else
+ {
+ /* pattern ends in DOT: treat as if there is no DOT */
+ *eext = 0;
+ if (strequal(ebase, "*"))
+ return (True);
+ }
+ }
+ else
+ {
+ /*
+ * No suffix for wildcard.
+ */
+ fstrcpy(ebase, t_pattern);
+ eext[0] = 0;
+ }
+
+ p = strrchr(t_filename, '.');
+ if (p && (p[1] == 0))
+ {
+ /*
+ * Filename has an extension of '.' only.
+ */
+ *p = 0; /* nuke dot at end of string */
+ p = 0; /* and treat it as if there is no extension */
+ }
+
+ if (p)
+ {
+ /*
+ * Filename has an extension.
+ */
+ *p = 0;
+ fstrcpy(sbase, t_filename);
+ fstrcpy(sext, p + 1);
+ if (*eext)
+ {
+ matched =
+ do_match(sbase, ebase,
+ case_sig)
+ && do_match(sext, eext,
+ case_sig);
+ }
+ else
+ {
+ /* pattern has no extension */
+ /* Really: match complete filename with pattern ??? means exactly 3 chars */
+ matched =
+ do_match(str, ebase,
+ case_sig);
+ }
+ }
+ else
+ {
+ /*
+ * Filename has no extension.
+ */
+ fstrcpy(sbase, t_filename);
+ fstrcpy(sext, "");
+ if (*eext)
+ {
+ /* pattern has extension */
+ matched =
+ do_match(sbase, ebase,
+ case_sig)
+ && do_match(sext, eext,
+ case_sig);
+ }
+ else
+ {
+ matched =
+ do_match(sbase, ebase,
+ case_sig);
#ifdef EMULATE_WEIRD_W95_MATCHING
- /*
- * Even Microsoft has some problems
- * Behaviour Win95 -> local disk
- * is different from Win95 -> smb drive from Nt 4.0
- * This branch would reflect the Win95 local disk behaviour
- */
- if (!matched) {
- /* a? matches aa and a in w95 */
- fstrcat (sbase, ".");
- matched = do_match(sbase, ebase, case_sig, False);
- }
+ /*
+ * Even Microsoft has some problems
+ * Behaviour Win95 -> local disk
+ * is different from Win95 -> smb drive from Nt 4.0
+ * This branch would reflect the Win95 local disk behaviour
+ */
+ if (!matched)
+ {
+ /* a? matches aa and a in w95 */
+ fstrcat(sbase, ".");
+ matched =
+ do_match(sbase, ebase,
+ case_sig);
+ }
#endif
- }
- }
- }
- }
+ }
+ }
+ }
+ }
- DEBUG(8,("mask_match returning %d\n", matched));
+ DEBUG(8, ("mask_match returning %d\n", matched));
- return matched;
+ return matched;
}
/****************************************************************************
@@ -1519,18 +1304,20 @@ become a daemon, discarding the controlling terminal
****************************************************************************/
void become_daemon(void)
{
- if (fork()) {
+ if (fork())
+ {
_exit(0);
}
- /* detach from the terminal */
+ /* detach from the terminal */
#ifdef HAVE_SETSID
setsid();
#elif defined(TIOCNOTTY)
{
int i = sys_open("/dev/tty", O_RDWR, 0);
- if (i != -1) {
- ioctl(i, (int) TIOCNOTTY, (char *)0);
+ if (i != -1)
+ {
+ ioctl(i, (int)TIOCNOTTY, (char *)0);
close(i);
}
}
@@ -1546,25 +1333,24 @@ put up a yes/no prompt
****************************************************************************/
BOOL yesno(char *p)
{
- pstring ans;
- printf("%s",p);
+ pstring ans;
+ printf("%s", p);
- if (!fgets(ans,sizeof(ans)-1,stdin))
- return(False);
+ if (!fgets(ans, sizeof(ans) - 1, stdin))
+ return (False);
- if (*ans == 'y' || *ans == 'Y')
- return(True);
+ if (*ans == 'y' || *ans == 'Y')
+ return (True);
- return(False);
+ return (False);
}
+
+
/****************************************************************************
set the length of a file from a filedescriptor.
Returns 0 on success, -1 on failure.
****************************************************************************/
-
-/* tpot vfs need to recode this function */
-
int set_filelen(int fd, SMB_OFF_T len)
{
/* According to W. R. Stevens advanced UNIX prog. Pure 4.3 BSD cannot
@@ -1572,39 +1358,39 @@ int set_filelen(int fd, SMB_OFF_T len)
for this */
#ifdef HAVE_FTRUNCATE_EXTEND
- return sys_ftruncate(fd, len);
+ return sys_ftruncate(fd, len);
#else
- SMB_STRUCT_STAT st;
- char c = 0;
- SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T)0, SEEK_CUR);
-
- if(currpos == -1)
- return -1;
- /* Do an fstat to see if the file is longer than
- the requested size (call ftruncate),
- or shorter, in which case seek to len - 1 and write 1
- byte of zero */
- if(sys_fstat(fd, &st)<0)
- return -1;
+ SMB_STRUCT_STAT st;
+ char c = 0;
+ SMB_OFF_T currpos = sys_lseek(fd, (SMB_OFF_T) 0, SEEK_CUR);
+
+ if (currpos == -1)
+ return -1;
+ /* Do an fstat to see if the file is longer than
+ the requested size (call ftruncate),
+ or shorter, in which case seek to len - 1 and write 1
+ byte of zero */
+ if (sys_fstat(fd, &st) < 0)
+ return -1;
#ifdef S_ISFIFO
- if (S_ISFIFO(st.st_mode))
- return 0;
+ if (S_ISFIFO(st.st_mode))
+ return 0;
#endif
- if(st.st_size == len)
- return 0;
- if(st.st_size > len)
- return sys_ftruncate(fd, len);
-
- if(sys_lseek(fd, len-1, SEEK_SET) != len -1)
- return -1;
- if(write(fd, &c, 1)!=1)
- return -1;
- /* Seek to where we were */
- if(sys_lseek(fd, currpos, SEEK_SET) != currpos)
- return -1;
- return 0;
+ if (st.st_size == len)
+ return 0;
+ if (st.st_size > len)
+ return sys_ftruncate(fd, len);
+
+ if (sys_lseek(fd, len - 1, SEEK_SET) != len - 1)
+ return -1;
+ if (write(fd, &c, 1) != 1)
+ return -1;
+ /* Seek to where we were */
+ if (sys_lseek(fd, currpos, SEEK_SET) != currpos)
+ return -1;
+ return 0;
#endif
}
@@ -1613,52 +1399,49 @@ int set_filelen(int fd, SMB_OFF_T len)
/****************************************************************************
this is a version of setbuffer() for those machines that only have setvbuf
****************************************************************************/
- void setbuffer(FILE *f,char *buf,int bufsize)
+/* *INDENT-OFF* */
+ void setbuffer(FILE * f, char *buf, int bufsize)
{
- setvbuf(f,buf,_IOFBF,bufsize);
+ setvbuf(f, buf, _IOFBF, bufsize);
}
+/* *INDENT-ON* */
#endif
-/****************************************************************************
-parse out a filename from a path name. Assumes dos style filenames.
-****************************************************************************/
-static char *filename_dos(char *path,char *buf)
-{
- char *p = strrchr(path,'\\');
-
- if (!p)
- pstrcpy(buf,path);
- else
- pstrcpy(buf,p+1);
-
- return(buf);
-}
-
-
/****************************************************************************
expand a pointer to be a particular size
****************************************************************************/
-void *Realloc(void *p,size_t size)
+void *Realloc(void *p, size_t size)
{
- void *ret=NULL;
+ void *ret = NULL;
- if (size == 0) {
- if (p) free(p);
- DEBUG(5,("Realloc asked for 0 bytes\n"));
- return NULL;
- }
+ if (size == 0)
+ {
+ if (p)
+ free(p);
+ DEBUG(5, ("Realloc asked for 0 bytes\n"));
+ return NULL;
+ }
- if (!p)
- ret = (void *)malloc(size);
- else
- ret = (void *)realloc(p,size);
+ if (!p)
+ ret = (void *)malloc(size);
+ else
+ ret = (void *)realloc(p, size);
+
+#ifdef MEM_MAN
+ {
+ extern FILE *dbf;
+ smb_mem_write_info(ret, dbf);
+ }
+#endif
- if (!ret)
- DEBUG(0,("Memory allocation error: failed to expand to %d bytes\n",(int)size));
+ if (!ret)
+ DEBUG(0,
+ ("Memory allocation error: failed to expand to %d bytes\n",
+ size));
- return(ret);
+ return (ret);
}
@@ -1677,106 +1460,127 @@ void safe_free(void *p)
/****************************************************************************
get my own name and IP
****************************************************************************/
-BOOL get_myname(char *my_name)
+BOOL get_myname(char *my_name, struct in_addr *ip)
{
+ struct hostent *hp;
pstring hostname;
*hostname = 0;
/* get my host name */
- if (gethostname(hostname, sizeof(hostname)) == -1) {
- DEBUG(0,("gethostname failed\n"));
+ if (gethostname(hostname, MAXHOSTNAMELEN) == -1)
+ {
+ DEBUG(0, ("gethostname failed\n"));
return False;
- }
+ }
- /* Ensure null termination. */
- hostname[sizeof(hostname)-1] = '\0';
+ /* get host info */
+ if ((hp = Get_Hostbyname(hostname)) == 0)
+ {
+ DEBUG(0, ("Get_Hostbyname: Unknown host %s\n", hostname));
+ return False;
+ }
- if (my_name) {
+ if (my_name)
+ {
/* split off any parts after an initial . */
- char *p = strchr(hostname,'.');
- if (p) *p = 0;
-
- fstrcpy(my_name,hostname);
+ char *p = strchr(hostname, '.');
+ if (p)
+ *p = 0;
+
+ fstrcpy(my_name, hostname);
}
-
- return(True);
+
+ if (ip)
+ putip((char *)ip, (char *)hp->h_addr);
+
+ return (True);
}
+
/****************************************************************************
-interpret a protocol description string, with a default
+true if two IP addresses are equal
****************************************************************************/
-int interpret_protocol(char *str,int def)
-{
- if (strequal(str,"NT1"))
- return(PROTOCOL_NT1);
- if (strequal(str,"LANMAN2"))
- return(PROTOCOL_LANMAN2);
- if (strequal(str,"LANMAN1"))
- return(PROTOCOL_LANMAN1);
- if (strequal(str,"CORE"))
- return(PROTOCOL_CORE);
- if (strequal(str,"COREPLUS"))
- return(PROTOCOL_COREPLUS);
- if (strequal(str,"CORE+"))
- return(PROTOCOL_COREPLUS);
-
- DEBUG(0,("Unrecognised protocol level %s\n",str));
-
- return(def);
+BOOL ip_equal(struct in_addr ip1, struct in_addr ip2)
+{
+ uint32 a1, a2;
+ a1 = ntohl(ip1.s_addr);
+ a2 = ntohl(ip2.s_addr);
+ return (a1 == a2);
}
+
/****************************************************************************
- Return true if a string could be a pure IP address.
+interpret a protocol description string, with a default
****************************************************************************/
-
-BOOL is_ipaddress(const char *str)
+int interpret_protocol(char *str, int def)
{
- BOOL pure_address = True;
- int i;
-
- for (i=0; pure_address && str[i]; i++)
- if (!(isdigit((int)str[i]) || str[i] == '.'))
- pure_address = False;
+ if (strequal(str, "NT1"))
+ return (PROTOCOL_NT1);
+ if (strequal(str, "LANMAN2"))
+ return (PROTOCOL_LANMAN2);
+ if (strequal(str, "LANMAN1"))
+ return (PROTOCOL_LANMAN1);
+ if (strequal(str, "CORE"))
+ return (PROTOCOL_CORE);
+ if (strequal(str, "COREPLUS"))
+ return (PROTOCOL_COREPLUS);
+ if (strequal(str, "CORE+"))
+ return (PROTOCOL_COREPLUS);
- /* Check that a pure number is not misinterpreted as an IP */
- pure_address = pure_address && (strchr(str, '.') != NULL);
+ DEBUG(0, ("Unrecognised protocol level %s\n", str));
- return pure_address;
+ return (def);
}
+
/****************************************************************************
interpret an internet address or name into an IP address in 4 byte form
****************************************************************************/
-
uint32 interpret_addr(char *str)
{
- struct hostent *hp;
- uint32 res;
+ struct hostent *hp;
+ uint32 res;
+ int i;
+ BOOL pure_address = True;
- if (strcmp(str,"0.0.0.0") == 0) return(0);
- if (strcmp(str,"255.255.255.255") == 0) return(0xFFFFFFFF);
+ if (strcmp(str, "0.0.0.0") == 0)
+ return (0);
+ if (strcmp(str, "255.255.255.255") == 0)
+ return (0xFFFFFFFF);
- /* if it's in the form of an IP address then get the lib to interpret it */
- if (is_ipaddress(str)) {
- res = inet_addr(str);
- } else {
- /* otherwise assume it's a network name of some sort and use
- Get_Hostbyname */
- if ((hp = Get_Hostbyname(str)) == 0) {
- DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str));
- return 0;
- }
- if(hp->h_addr == NULL) {
- DEBUG(3,("Get_Hostbyname: host address is invalid for host %s\n",str));
- return 0;
- }
- putip((char *)&res,(char *)hp->h_addr);
- }
+ for (i = 0; pure_address && str[i]; i++)
+ if (!(isdigit((int)str[i]) || str[i] == '.'))
+ pure_address = False;
+
+ /* if it's in the form of an IP address then get the lib to interpret it */
+ if (pure_address)
+ {
+ res = inet_addr(str);
+ }
+ else
+ {
+ /* otherwise assume it's a network name of some sort and use
+ Get_Hostbyname */
+ if ((hp = Get_Hostbyname(str)) == 0)
+ {
+ DEBUG(3, ("Get_Hostbyname: Unknown host. %s\n", str));
+ return 0;
+ }
+ if (hp->h_addr == NULL)
+ {
+ DEBUG(3,
+ ("Get_Hostbyname: host address is invalid for host %s\n",
+ str));
+ return 0;
+ }
+ putip((char *)&res, (char *)hp->h_addr);
+ }
- if (res == (uint32)-1) return(0);
+ if (res == (uint32) - 1)
+ return (0);
- return(res);
+ return (res);
}
/*******************************************************************
@@ -1784,10 +1588,10 @@ uint32 interpret_addr(char *str)
******************************************************************/
struct in_addr *interpret_addr2(char *str)
{
- static struct in_addr ret;
- uint32 a = interpret_addr(str);
- ret.s_addr = a;
- return(&ret);
+ static struct in_addr ret;
+ uint32 a = interpret_addr(str);
+ ret.s_addr = a;
+ return (&ret);
}
/*******************************************************************
@@ -1795,55 +1599,59 @@ struct in_addr *interpret_addr2(char *str)
******************************************************************/
BOOL zero_ip(struct in_addr ip)
{
- uint32 a;
- putip((char *)&a,(char *)&ip);
- return(a == 0);
+ uint32 a;
+ putip((char *)&a, (char *)&ip);
+ return (a == 0);
}
/*******************************************************************
matchname - determine if host name matches IP address
******************************************************************/
-BOOL matchname(char *remotehost,struct in_addr addr)
-{
- struct hostent *hp;
- int i;
-
- if ((hp = Get_Hostbyname(remotehost)) == 0) {
- DEBUG(0,("Get_Hostbyname(%s): lookup failure.\n", remotehost));
- return False;
- }
-
- /*
- * Make sure that gethostbyname() returns the "correct" host name.
- * Unfortunately, gethostbyname("localhost") sometimes yields
- * "localhost.domain". Since the latter host name comes from the
- * local DNS, we just have to trust it (all bets are off if the local
- * DNS is perverted). We always check the address list, though.
- */
-
- if (strcasecmp(remotehost, hp->h_name)
- && strcasecmp(remotehost, "localhost")) {
- DEBUG(0,("host name/name mismatch: %s != %s\n",
- remotehost, hp->h_name));
- return False;
- }
-
- /* Look up the host address in the address list we just got. */
- for (i = 0; hp->h_addr_list[i]; i++) {
- if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr)) == 0)
- return True;
- }
-
- /*
- * The host name does not map to the original host address. Perhaps
- * someone has compromised a name server. More likely someone botched
- * it, but that could be dangerous, too.
- */
-
- DEBUG(0,("host name/address mismatch: %s != %s\n",
- inet_ntoa(addr), hp->h_name));
- return False;
+BOOL matchname(char *remotehost, struct in_addr addr)
+{
+ struct hostent *hp;
+ int i;
+
+ if ((hp = Get_Hostbyname(remotehost)) == 0)
+ {
+ DEBUG(0, ("Get_Hostbyname(%s): lookup failure", remotehost));
+ return False;
+ }
+
+ /*
+ * Make sure that gethostbyname() returns the "correct" host name.
+ * Unfortunately, gethostbyname("localhost") sometimes yields
+ * "localhost.domain". Since the latter host name comes from the
+ * local DNS, we just have to trust it (all bets are off if the local
+ * DNS is perverted). We always check the address list, though.
+ */
+
+ if (strcasecmp(remotehost, hp->h_name)
+ && strcasecmp(remotehost, "localhost"))
+ {
+ DEBUG(0, ("host name/name mismatch: %s != %s",
+ remotehost, hp->h_name));
+ return False;
+ }
+
+ /* Look up the host address in the address list we just got. */
+ for (i = 0; hp->h_addr_list[i]; i++)
+ {
+ if (memcmp(hp->h_addr_list[i], (caddr_t) & addr, sizeof(addr))
+ == 0)
+ return True;
+ }
+
+ /*
+ * The host name does not map to the original host address. Perhaps
+ * someone has compromised a name server. More likely someone botched
+ * it, but that could be dangerous, too.
+ */
+
+ DEBUG(0, ("host name/address mismatch: %s != %s",
+ inet_ntoa(addr), hp->h_name));
+ return False;
}
@@ -1853,22 +1661,23 @@ BOOL matchname(char *remotehost,struct in_addr addr)
Based on a fix from <Thomas.Hepper@icem.de>.
*******************************************************************/
-static void strip_mount_options( pstring *str)
+static void strip_mount_options(pstring *str)
{
- if (**str == '-')
- {
- char *p = *str;
- while(*p && !isspace(*p))
- p++;
- while(*p && isspace(*p))
- p++;
- if(*p) {
- pstring tmp_str;
+ if (**str == '-')
+ {
+ char *p = *str;
+ while (*p && !isspace(*p))
+ p++;
+ while (*p && isspace(*p))
+ p++;
+ if (*p)
+ {
+ pstring tmp_str;
- pstrcpy(tmp_str, p);
- pstrcpy(*str, tmp_str);
- }
- }
+ pstrcpy(tmp_str, p);
+ pstrcpy(*str, tmp_str);
+ }
+ }
}
/*******************************************************************
@@ -1881,105 +1690,122 @@ static void strip_mount_options( pstring *str)
#ifdef WITH_NISPLUS_HOME
static char *automount_lookup(char *user_name)
{
- static fstring last_key = "";
- static pstring last_value = "";
-
- char *nis_map = (char *)lp_nis_home_map_name();
-
- char nis_domain[NIS_MAXNAMELEN + 1];
- char buffer[NIS_MAXATTRVAL + 1];
- nis_result *result;
- nis_object *object;
- entry_obj *entry;
-
- strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
- nis_domain[NIS_MAXNAMELEN] = '\0';
-
- DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
-
- if (strcmp(user_name, last_key))
- {
- slprintf(buffer, sizeof(buffer)-1, "[%s=%s]%s.%s", "key", user_name, nis_map, nis_domain);
- DEBUG(5, ("NIS+ querystring: %s\n", buffer));
-
- if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
- {
- if (result->status != NIS_SUCCESS)
- {
- DEBUG(3, ("NIS+ query failed: %s\n", nis_sperrno(result->status)));
- fstrcpy(last_key, ""); pstrcpy(last_value, "");
- }
- else
- {
- object = result->objects.objects_val;
- if (object->zo_data.zo_type == ENTRY_OBJ)
- {
- entry = &object->zo_data.objdata_u.en_data;
- DEBUG(5, ("NIS+ entry type: %s\n", entry->en_type));
- DEBUG(3, ("NIS+ result: %s\n", entry->en_cols.en_cols_val[1].ec_value.ec_value_val));
-
- pstrcpy(last_value, entry->en_cols.en_cols_val[1].ec_value.ec_value_val);
- pstring_sub(last_value, "&", user_name);
- fstrcpy(last_key, user_name);
- }
- }
- }
- nis_freeresult(result);
- }
-
- strip_mount_options(&last_value);
-
- DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
- return last_value;
+ static fstring last_key = "";
+ static pstring last_value = "";
+
+ char *nis_map = (char *)lp_nis_home_map_name();
+
+ char nis_domain[NIS_MAXNAMELEN + 1];
+ char buffer[NIS_MAXATTRVAL + 1];
+ nis_result *result;
+ nis_object *object;
+ entry_obj *entry;
+
+ strncpy(nis_domain, (char *)nis_local_directory(), NIS_MAXNAMELEN);
+ nis_domain[NIS_MAXNAMELEN] = '\0';
+
+ DEBUG(5, ("NIS+ Domain: %s\n", nis_domain));
+
+ if (strcmp(user_name, last_key))
+ {
+ slprintf(buffer, sizeof(buffer) - 1, "[%s=%s]%s.%s", "key",
+ user_name, nis_map, nis_domain);
+ DEBUG(5, ("NIS+ querystring: %s\n", buffer));
+
+ if (result = nis_list(buffer, RETURN_RESULT, NULL, NULL))
+ {
+ if (result->status != NIS_SUCCESS)
+ {
+ DEBUG(3,
+ ("NIS+ query failed: %s\n",
+ nis_sperrno(result->status)));
+ fstrcpy(last_key, "");
+ pstrcpy(last_value, "");
+ }
+ else
+ {
+ object = result->objects.objects_val;
+ if (object->zo_data.zo_type == ENTRY_OBJ)
+ {
+ entry =
+ &object->zo_data.
+ objdata_u.en_data;
+ DEBUG(5,
+ ("NIS+ entry type: %s\n",
+ entry->en_type));
+ DEBUG(3,
+ ("NIS+ result: %s\n",
+ entry->en_cols.
+ en_cols_val[1].ec_value.
+ ec_value_val));
+
+ pstrcpy(last_value,
+ entry->en_cols.
+ en_cols_val[1].ec_value.
+ ec_value_val);
+ string_sub(last_value, "&",
+ user_name);
+ fstrcpy(last_key, user_name);
+ }
+ }
+ }
+ nis_freeresult(result);
+ }
+
+ strip_mount_options(&last_value);
+
+ DEBUG(4, ("NIS+ Lookup: %s resulted in %s\n", user_name, last_value));
+ return last_value;
}
#else /* WITH_NISPLUS_HOME */
static char *automount_lookup(char *user_name)
{
- static fstring last_key = "";
- static pstring last_value = "";
-
- int nis_error; /* returned by yp all functions */
- char *nis_result; /* yp_match inits this */
- int nis_result_len; /* and set this */
- char *nis_domain; /* yp_get_default_domain inits this */
- char *nis_map = (char *)lp_nis_home_map_name();
-
- if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
- {
- DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
- return last_value;
- }
-
- DEBUG(5, ("NIS Domain: %s\n", nis_domain));
-
- if (!strcmp(user_name, last_key))
- {
- nis_result = last_value;
- nis_result_len = strlen(last_value);
- nis_error = 0;
- }
- else
- {
- if ((nis_error = yp_match(nis_domain, nis_map,
- user_name, strlen(user_name),
- &nis_result, &nis_result_len)) != 0)
- {
- DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
- yperr_string(nis_error), user_name, nis_map));
- }
- if (!nis_error && nis_result_len >= sizeof(pstring))
- {
- nis_result_len = sizeof(pstring)-1;
- }
- fstrcpy(last_key, user_name);
- strncpy(last_value, nis_result, nis_result_len);
- last_value[nis_result_len] = '\0';
- }
-
- strip_mount_options(&last_value);
-
- DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
- return last_value;
+ static fstring last_key = "";
+ static pstring last_value = "";
+
+ int nis_error; /* returned by yp all functions */
+ char *nis_result; /* yp_match inits this */
+ int nis_result_len; /* and set this */
+ char *nis_domain; /* yp_get_default_domain inits this */
+ char *nis_map = (char *)lp_nis_home_map_name();
+
+ if ((nis_error = yp_get_default_domain(&nis_domain)) != 0)
+ {
+ DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error)));
+ return last_value;
+ }
+
+ DEBUG(5, ("NIS Domain: %s\n", nis_domain));
+
+ if (!strcmp(user_name, last_key))
+ {
+ nis_result = last_value;
+ nis_result_len = strlen(last_value);
+ nis_error = 0;
+ }
+ else
+ {
+ if ((nis_error = yp_match(nis_domain, nis_map,
+ user_name, strlen(user_name),
+ &nis_result, &nis_result_len)) != 0)
+ {
+ DEBUG(3,
+ ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n",
+ yperr_string(nis_error), user_name, nis_map));
+ }
+ if (!nis_error && nis_result_len >= sizeof(pstring))
+ {
+ nis_result_len = sizeof(pstring) - 1;
+ }
+ fstrcpy(last_key, user_name);
+ strncpy(last_value, nis_result, nis_result_len);
+ last_value[nis_result_len] = '\0';
+ }
+
+ strip_mount_options(&last_value);
+
+ DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value));
+ return last_value;
}
#endif /* WITH_NISPLUS_HOME */
#endif
@@ -2001,20 +1827,22 @@ static char *automount_server(char *user_name)
if (lp_nis_home_map())
{
- int home_server_len;
+ int home_server_len;
char *automount_value = automount_lookup(user_name);
- home_server_len = strcspn(automount_value,":");
- DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len));
+ home_server_len = strcspn(automount_value, ":");
+ DEBUG(5,
+ ("NIS lookup succeeded. Home server length: %d\n",
+ home_server_len));
if (home_server_len > sizeof(pstring))
{
home_server_len = sizeof(pstring);
}
strncpy(server_name, automount_value, home_server_len);
- server_name[home_server_len] = '\0';
+ server_name[home_server_len] = '\0';
}
#endif
- DEBUG(4,("Home server: %s\n", server_name));
+ DEBUG(4, ("Home server: %s\n", server_name));
return server_name;
}
@@ -2029,205 +1857,240 @@ static char *automount_path(char *user_name)
/* use the passwd entry as the default */
/* this will be the default if WITH_AUTOMOUNT is not used or fails */
- /* pstrcpy() copes with get_user_home_dir() returning NULL */
- pstrcpy(server_path, get_user_home_dir(user_name));
+ /* pstrcpy() copes with get_unixhome_dir() returning NULL */
+ pstrcpy(server_path, get_unixhome_dir(user_name));
#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT))
if (lp_nis_home_map())
{
- char *home_path_start;
+ char *home_path_start;
char *automount_value = automount_lookup(user_name);
- home_path_start = strchr(automount_value,':');
+ home_path_start = strchr(automount_value, ':');
if (home_path_start != NULL)
{
- DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
- home_path_start?(home_path_start+1):""));
- pstrcpy(server_path, home_path_start+1);
+ DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n",
+ home_path_start ? (home_path_start +
+ 1) : ""));
+ pstrcpy(server_path, home_path_start + 1);
}
}
#endif
- DEBUG(4,("Home server path: %s\n", server_path));
+ DEBUG(4, ("Home server path: %s\n", server_path));
return server_path;
}
+
/*******************************************************************
- Given a pointer to a %$(NAME) expand it as an environment variable.
- Return the number of characters by which the pointer should be advanced.
- Based on code by Branko Cibej <branko.cibej@hermes.si>
- When this is called p points at the '%' character.
+sub strings with useful parameters
+Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
+Paul Rippin <pr3245@nopc.eurostat.cec.be>
********************************************************************/
-
-static size_t expand_env_var(char *p, int len)
+void standard_sub_basic(char *str)
{
- fstring envname;
- char *envval;
- char *q, *r;
- int copylen;
-
- if (p[1] != '$')
- return 1;
-
- if (p[2] != '(')
- return 2;
-
- /*
- * Look for the terminating ')'.
- */
+ char *s, *p;
+ char pidstr[10];
- if ((q = strchr(p,')')) == NULL) {
- DEBUG(0,("expand_env_var: Unterminated environment variable [%s]\n", p));
- return 2;
- }
+ for (s = str; s && *s && (p = strchr(s, '%')); s = p)
+ {
+ switch (*(p + 1))
+ {
+ case 'I':
+ string_sub(p, "%I", client_connection_addr());
+ break;
+ case 'L':
+ string_sub(p, "%L", local_machine);
+ break;
+ case 'M':
+ string_sub(p, "%M", client_connection_name());
+ break;
+ case 'R':
+ string_sub(p, "%R", remote_proto);
+ break;
+ case 'T':
+ string_sub(p, "%T", timestring());
+ break;
+ case 'a':
+ string_sub(p, "%a", remote_arch);
+ break;
+ case 'd':
+ {
+ slprintf(pidstr, sizeof(pidstr) - 1, "%d",
+ (int)getpid());
+ string_sub(p, "%d", pidstr);
+ break;
+ }
+ case 'h':
+ string_sub(p, "%h", myhostname);
+ break;
+ case 'm':
+ string_sub(p, "%m", remote_machine);
+ break;
+ case 'v':
+ string_sub(p, "%v", VERSION);
+ break;
+ case '$': /* Expand environment variables */
+ {
+ /* Contributed by Branko Cibej <branko.cibej@hermes.si> */
+ fstring envname;
+ char *envval;
+ char *q, *r;
+ int copylen;
+
+ if (*(p + 2) != '(')
+ {
+ p += 2;
+ break;
+ }
+ if ((q = strchr(p, ')')) == NULL)
+ {
+ DEBUG(0,
+ ("standard_sub_basic: Unterminated environment \
+ variable [%s]\n",
+ p));
+ p += 2;
+ break;
+ }
- /*
- * Extract the name from within the %$(NAME) string.
- */
+ r = p + 3;
+ copylen = MIN((q - r), (sizeof(envname) - 1));
+ strncpy(envname, r, copylen);
+ envname[copylen] = '\0';
- r = p+3;
- copylen = MIN((q-r),(sizeof(envname)-1));
- strncpy(envname,r,copylen);
- envname[copylen] = '\0';
+ if ((envval = getenv(envname)) == NULL)
+ {
+ DEBUG(0,
+ ("standard_sub_basic: Environment variable [%s] not set\n",
+ envname));
+ p += 2;
+ break;
+ }
- if ((envval = getenv(envname)) == NULL) {
- DEBUG(0,("expand_env_var: Environment variable [%s] not set\n", envname));
- return 2;
+ copylen =
+ MIN((q + 1 - p),
+ (sizeof(envname) - 1));
+ strncpy(envname, p, copylen);
+ envname[copylen] = '\0';
+ string_sub(p, envname, envval);
+ break;
+ }
+ case '\0':
+ p++;
+ break; /* don't run off end if last character is % */
+ default:
+ p += 2;
+ break;
+ }
}
-
- /*
- * Copy the full %$(NAME) into envname so it
- * can be replaced.
- */
-
- copylen = MIN((q+1-p),(sizeof(envname)-1));
- strncpy(envname,p,copylen);
- envname[copylen] = '\0';
- string_sub(p,envname,envval,len);
- return 0; /* Allow the environment contents to be parsed. */
+ return;
}
/*******************************************************************
- Substitute strings with useful parameters.
- Rewritten by Stefaan A Eeckels <Stefaan.Eeckels@ecc.lu> and
- Paul Rippin <pr3245@nopc.eurostat.cec.be>.
+user-specific sub strings with useful parameters
********************************************************************/
-
-void standard_sub_basic(char *str)
+void standard_sub_vuser(const user_struct * vuser, char *str)
{
char *s, *p;
- char pidstr[10];
- struct passwd *pass;
- char *username = sam_logon_in_ssb ? samlogon_user : sesssetup_user;
- for (s = str ; s && *s && (p = strchr(s,'%')); s = p )
+ for (s = str; vuser != NULL && s && *s && (p = strchr(s, '%')); s = p)
{
- int l = sizeof(pstring) - (int)(p-str);
-
- if (l < 0) {
- DEBUG(0,("ERROR: string overflow by %d in standard_sub_basic(%.50s)\n",
- -l, str));
-
- return;
- }
-
- switch (*(p+1))
+ switch (*(p + 1))
{
- case 'G' :
+ case 'G':
{
- if ((pass = Get_Pwnam(username,False))!=NULL) {
- string_sub(p,"%G",gidtoname(pass->pw_gid),l);
- } else {
+ const struct passwd *pass;
+ if ((pass = Get_Pwnam(vuser->name, False)) !=
+ NULL)
+ {
+ string_sub(p, "%G",
+ gidtoname(pass->pw_gid));
+ }
+ else
+ {
p += 2;
}
break;
}
- case 'N' : string_sub(p,"%N", automount_server(username),l); break;
- case 'I' : string_sub(p,"%I", client_addr(Client),l); break;
- case 'L' : string_sub(p,"%L", local_machine,l); break;
- case 'M' : string_sub(p,"%M", client_name(Client),l); break;
- case 'R' : string_sub(p,"%R", remote_proto,l); break;
- case 'T' : string_sub(p,"%T", timestring(False),l); break;
- case 'U' : string_sub(p,"%U", username,l); break;
- case 'a' : string_sub(p,"%a", remote_arch,l); break;
- case 'd' :
- {
- slprintf(pidstr,sizeof(pidstr) - 1, "%d",(int)getpid());
- string_sub(p,"%d", pidstr,l);
+ case 'N':
+ string_sub(p, "%N",
+ automount_server(vuser->name));
+ break;
+ case 'U':
+ string_sub(p, "%U", vuser->requested_name);
+ break;
+ case '\0':
+ p++;
+ break; /* don't run off end if last character is % */
+ default:
+ p += 2;
break;
- }
- case 'h' : string_sub(p,"%h", myhostname(),l); break;
- case 'm' : string_sub(p,"%m", remote_machine,l); break;
- case 'v' : string_sub(p,"%v", VERSION,l); break;
- case '$' : p += expand_env_var(p,l); break; /* Expand environment variables */
- case '\0': p++; break; /* don't run off end if last character is % */
- default : p+=2; break;
}
}
+ standard_sub_basic(str);
return;
}
/****************************************************************************
- Do some standard substitutions in a string.
+do some standard substitutions in a string
****************************************************************************/
-
-void standard_sub(connection_struct *conn,char *str)
+void standard_sub(connection_struct * conn, user_struct * vuser, char *str)
{
char *p, *s, *home;
- for (s=str; (p=strchr(s, '%'));s=p) {
- int l = sizeof(pstring) - (int)(p-str);
+ for (s = str; conn != NULL && (p = strchr(s, '%')); s = p)
+ {
+ switch (*(p + 1))
+ {
+ case 'H':
+ if ((home = get_unixhome_dir(conn->user)) !=
+ NULL)
+ {
+ string_sub(p, "%H", home);
+ }
+ else
+ {
+ p += 2;
+ }
+ break;
+
+ /* Patch from jkf@soton.ac.uk Left the %N (NIS
+ * server name) in standard_sub_basic as it is
+ * a feature for logon servers, hence uses the
+ * username. The %p (NIS server path) code is
+ * here as it is used instead of the default
+ * "path =" string in [homes] and so needs the
+ * service name, not the username. */
+ case 'p':
+ string_sub(p, "%p",
+ automount_path(lp_servicename
+ (SNUM(conn))));
+ break;
+ case 'P':
+ string_sub(p, "%P", conn->connectpath);
+ break;
+ case 'S':
+ string_sub(p, "%S",
+ lp_servicename(SNUM(conn))); break;
+ case 'g':
+ string_sub(p, "%g", gidtoname(conn->gid));
+ break;
+ case 'u':
+ string_sub(p, "%u", conn->user);
+ break;
- switch (*(p+1)) {
- case 'H':
- if ((home = get_user_home_dir(conn->user))) {
- string_sub(p,"%H",home,l);
- } else {
+ case '\0':
+ p++;
+ break; /* don't run off the end of the string */
+ default:
p += 2;
- }
- break;
-
- case 'P':
- string_sub(p,"%P",conn->connectpath,l);
- break;
-
- case 'S':
- string_sub(p,"%S",
- lp_servicename(SNUM(conn)),l);
- break;
-
- case 'g':
- string_sub(p,"%g",
- gidtoname(conn->gid),l);
- break;
- case 'u':
- string_sub(p,"%u",conn->user,l);
- break;
-
- /* Patch from jkf@soton.ac.uk Left the %N (NIS
- * server name) in standard_sub_basic as it is
- * a feature for logon servers, hence uses the
- * username. The %p (NIS server path) code is
- * here as it is used instead of the default
- * "path =" string in [homes] and so needs the
- * service name, not the username. */
- case 'p':
- string_sub(p,"%p",
- automount_path(lp_servicename(SNUM(conn))),l);
- break;
- case '\0':
- p++;
- break; /* don't run off the end of the string
- */
-
- default: p+=2;
- break;
+ break;
}
}
-
- standard_sub_basic(str);
+
+ standard_sub_vuser(vuser, str);
}
@@ -2235,15 +2098,15 @@ void standard_sub(connection_struct *conn,char *str)
/*******************************************************************
are two IPs on the same subnet?
********************************************************************/
-BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
+BOOL same_net(struct in_addr ip1, struct in_addr ip2, struct in_addr mask)
{
- uint32 net1,net2,nmask;
+ uint32 net1, net2, nmask;
+
+ nmask = ntohl(mask.s_addr);
+ net1 = ntohl(ip1.s_addr);
+ net2 = ntohl(ip2.s_addr);
- nmask = ntohl(mask.s_addr);
- net1 = ntohl(ip1.s_addr);
- net2 = ntohl(ip2.s_addr);
-
- return((net1 & nmask) == (net2 & nmask));
+ return ((net1 & nmask) == (net2 & nmask));
}
@@ -2253,58 +2116,59 @@ if the initial name fails
****************************************************************************/
struct hostent *Get_Hostbyname(const char *name)
{
- char *name2 = strdup(name);
- struct hostent *ret;
+ char *name2 = strdup(name);
+ struct hostent *ret;
+
+ if (!name2)
+ {
+ DEBUG(0,
+ ("Memory allocation error in Get_Hostbyname! panic\n"));
+ exit(0);
+ }
- if (!name2)
- {
- DEBUG(0,("Memory allocation error in Get_Hostbyname! panic\n"));
- exit(0);
- }
-
- /*
- * This next test is redundent and causes some systems (with
- * broken isalnum() calls) problems.
- * JRA.
- */
+ /*
+ * This next test is redundent and causes some systems (with
+ * broken isalnum() calls) problems.
+ * JRA.
+ */
#if 0
- if (!isalnum(*name2))
- {
- free(name2);
- return(NULL);
- }
+ if (!isalnum(*name2))
+ {
+ free(name2);
+ return (NULL);
+ }
#endif /* 0 */
- ret = sys_gethostbyname(name2);
- if (ret != NULL)
- {
- free(name2);
- return(ret);
- }
-
- /* try with all lowercase */
- strlower(name2);
- ret = sys_gethostbyname(name2);
- if (ret != NULL)
- {
- free(name2);
- return(ret);
- }
-
- /* try with all uppercase */
- strupper(name2);
- ret = sys_gethostbyname(name2);
- if (ret != NULL)
- {
- free(name2);
- return(ret);
- }
-
- /* nothing works :-( */
- free(name2);
- return(NULL);
+ ret = sys_gethostbyname(name2);
+ if (ret != NULL)
+ {
+ free(name2);
+ return (ret);
+ }
+
+ /* try with all lowercase */
+ strlower(name2);
+ ret = sys_gethostbyname(name2);
+ if (ret != NULL)
+ {
+ free(name2);
+ return (ret);
+ }
+
+ /* try with all uppercase */
+ strupper(name2);
+ ret = sys_gethostbyname(name2);
+ if (ret != NULL)
+ {
+ free(name2);
+ return (ret);
+ }
+
+ /* nothing works :-( */
+ free(name2);
+ return (NULL);
}
@@ -2312,24 +2176,139 @@ struct hostent *Get_Hostbyname(const char *name)
check if a process exists. Does this work on all unixes?
****************************************************************************/
-BOOL process_exists(pid_t pid)
+BOOL process_exists(int pid)
{
- return(kill(pid,0) == 0 || errno != ESRCH);
+ return (kill(pid, 0) == 0 || errno != ESRCH);
}
-/*******************************************************************
-turn a uid into a user name
-********************************************************************/
-char *uidtoname(uid_t uid)
+/****************************************************************************
+Setup the groups a user belongs to.
+****************************************************************************/
+int get_unixgroups(const char *user, uid_t uid, gid_t gid, int *p_ngroups,
+ gid_t ** p_groups)
{
- static char name[40];
- struct passwd *pass = sys_getpwuid(uid);
- if (pass) return(pass->pw_name);
- slprintf(name, sizeof(name) - 1, "%d",(int)uid);
- return(name);
+ int i, ngroups;
+ gid_t grp = 0;
+ gid_t *groups = NULL;
+
+ if (-1 == initgroups(user, gid))
+ {
+ DEBUG(0, ("Unable to initgroups!\n"));
+ if (getuid() == 0)
+ {
+ if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000)
+ {
+ DEBUG(0,
+ ("This is probably a problem with the account %s\n",
+ user));
+ }
+ }
+ return -1;
+ }
+
+ ngroups = sys_getgroups(0, &grp);
+ if (ngroups <= 0)
+ {
+ ngroups = 32;
+ }
+
+ if ((groups = (gid_t *) malloc(sizeof(gid_t) * ngroups)) == NULL)
+ {
+ DEBUG(0, ("get_unixgroups malloc fail !\n"));
+ return -1;
+ }
+
+ ngroups = sys_getgroups(ngroups, groups);
+
+ (*p_ngroups) = ngroups;
+ (*p_groups) = groups;
+
+ DEBUG(3, ("%s is in %d groups: ", user, ngroups));
+ for (i = 0; i < ngroups; i++)
+ {
+ DEBUG(3, ("%s%d", (i ? ", " : ""), (int)groups[i]));
+ }
+ DEBUG(3, ("\n"));
+
+ return 0;
}
+/****************************************************************************
+get all unix groups. copying group members is hideous on memory, so it's
+NOT done here. however, names of unix groups _are_ string-allocated so
+free_unix_grps() must be called.
+****************************************************************************/
+BOOL get_unix_grps(int *p_ngroups, struct group **p_groups)
+{
+ struct group *grp;
+
+ DEBUG(10, ("get_unix_grps\n"));
+
+ if (p_ngroups == NULL || p_groups == NULL)
+ {
+ return False;
+ }
+
+ (*p_ngroups) = 0;
+ (*p_groups) = NULL;
+
+ setgrent();
+
+ while ((grp = getgrent()) != NULL)
+ {
+ struct group *copy_grp;
+
+
+ (*p_groups) =
+ (struct group *)Realloc((*p_groups),
+ (size_t) ((*p_ngroups) +
+ 1) *
+ sizeof(struct group));
+ if ((*p_groups) == NULL)
+ {
+ (*p_ngroups) = 0;
+ endgrent();
+
+ return False;
+ }
+
+ copy_grp = &(*p_groups)[*p_ngroups];
+ memcpy(copy_grp, grp, sizeof(*grp));
+ copy_grp->gr_name = strdup(copy_grp->gr_name);
+ copy_grp->gr_mem = NULL;
+
+ (*p_ngroups)++;
+ }
+
+ endgrent();
+
+ DEBUG(10, ("get_unix_grps: %d groups\n", (*p_ngroups)));
+ return True;
+}
+
+/****************************************************************************
+free memory associated with unix groups.
+****************************************************************************/
+void free_unix_grps(int ngroups, struct group *p_groups)
+{
+ int i;
+
+ if (p_groups == NULL)
+ {
+ return;
+ }
+
+ for (i = 0; i < ngroups; i++)
+ {
+ if (p_groups[i].gr_name != NULL)
+ {
+ free(p_groups[i].gr_name);
+ }
+ }
+
+ free(p_groups);
+}
/*******************************************************************
turn a gid into a group name
@@ -2339,43 +2318,55 @@ char *gidtoname(gid_t gid)
{
static char name[40];
struct group *grp = getgrgid(gid);
- if (grp) return(grp->gr_name);
- slprintf(name,sizeof(name) - 1, "%d",(int)gid);
- return(name);
+ if (grp)
+ return (grp->gr_name);
+ slprintf(name, sizeof(name) - 1, "%d", (int)gid);
+ return (name);
}
/*******************************************************************
-turn a user name into a uid
+turn a group name into a gid
********************************************************************/
-uid_t nametouid(const char *name)
-{
- struct passwd *pass;
- char *p;
- uid_t u;
- u = strtol(name, &p, 0);
- if (p != name) return u;
-
- pass = sys_getpwnam(name);
- if (pass) return(pass->pw_uid);
- return (uid_t)-1;
+BOOL nametogid(const char *name, gid_t * gid)
+{
+ struct group *grp = getgrnam(name);
+ if (grp)
+ {
+ *gid = grp->gr_gid;
+ return True;
+ }
+ else if (isdigit(name[0]))
+ {
+ *gid = (gid_t) get_number(name);
+ return True;
+ }
+ else
+ {
+ return False;
+ }
}
/*******************************************************************
-turn a group name into a gid
+turn a user name into a uid
********************************************************************/
-gid_t nametogid(const char *name)
+BOOL nametouid(const char *name, uid_t * uid)
{
- struct group *grp;
- char *p;
- gid_t g;
-
- g = strtol(name, &p, 0);
- if (p != name) return g;
-
- grp = getgrnam(name);
- if (grp) return(grp->gr_gid);
- return (gid_t)-1;
+ const struct passwd *pass = Get_Pwnam(name, False);
+ if (pass)
+ {
+ *uid = pass->pw_uid;
+ return True;
+ }
+ else if (isdigit(name[0]))
+ {
+ *uid = (uid_t) get_number(name);
+ return True;
+ }
+ else
+ {
+ return False;
+ }
}
/*******************************************************************
@@ -2384,10 +2375,11 @@ something really nasty happened - panic!
void smb_panic(char *why)
{
char *cmd = lp_panic_action();
- if (cmd && *cmd) {
+ if (cmd && *cmd)
+ {
system(cmd);
}
- DEBUG(0,("PANIC: %s\n", why));
+ DEBUG(0, ("PANIC: %s\n", why));
dbgflush();
abort();
}
@@ -2396,20 +2388,23 @@ void smb_panic(char *why)
/*******************************************************************
a readdir wrapper which just returns the file name
********************************************************************/
-char *readdirname(DIR *p)
+char *readdirname(DIR * p)
{
- SMB_STRUCT_DIRENT *ptr;
+ struct dirent *ptr;
char *dname;
- if (!p) return(NULL);
-
- ptr = (SMB_STRUCT_DIRENT *)sys_readdir(p);
- if (!ptr) return(NULL);
+ if (!p)
+ return (NULL);
+
+ ptr = (struct dirent *)readdir(p);
+ if (!ptr)
+ return (NULL);
dname = ptr->d_name;
#ifdef NEXT2
- if (telldir(p) < 0) return(NULL);
+ if (telldir(p) < 0)
+ return (NULL);
#endif
#ifdef HAVE_BROKEN_READDIR
@@ -2419,11 +2414,11 @@ char *readdirname(DIR *p)
{
static pstring buf;
- memcpy(buf, dname, NAMLEN(ptr)+1);
+ memcpy(buf, dname, NAMLEN(ptr) + 1);
dname = buf;
}
- return(dname);
+ return (dname);
}
/*******************************************************************
@@ -2431,53 +2426,61 @@ char *readdirname(DIR *p)
of a path matches a (possibly wildcarded) entry in a namelist.
********************************************************************/
-BOOL is_in_path(char *name, name_compare_entry *namelist)
-{
- pstring last_component;
- char *p;
-
- DEBUG(8, ("is_in_path: %s\n", name));
-
- /* if we have no list it's obviously not in the path */
- if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL)))
- {
- DEBUG(8,("is_in_path: no name list.\n"));
- return False;
- }
-
- /* Get the last component of the unix name. */
- p = strrchr(name, '/');
- strncpy(last_component, p ? ++p : name, sizeof(last_component)-1);
- last_component[sizeof(last_component)-1] = '\0';
-
- for(; namelist->name != NULL; namelist++)
- {
- if(namelist->is_wild)
- {
- /*
- * Look for a wildcard match. Use the old
- * 'unix style' mask match, rather than the
- * new NT one.
- */
- if (unix_mask_match(last_component, namelist->name, case_sensitive))
- {
- DEBUG(8,("is_in_path: mask match succeeded\n"));
- return True;
- }
- }
- else
- {
- if((case_sensitive && (strcmp(last_component, namelist->name) == 0))||
- (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0)))
- {
- DEBUG(8,("is_in_path: match succeeded\n"));
- return True;
- }
- }
- }
- DEBUG(8,("is_in_path: match not found\n"));
-
- return False;
+BOOL is_in_path(char *name, name_compare_entry * namelist)
+{
+ pstring last_component;
+ char *p;
+
+ DEBUG(8, ("is_in_path: %s\n", name));
+
+ /* if we have no list it's obviously not in the path */
+ if ((namelist == NULL)
+ || ((namelist != NULL) && (namelist[0].name == NULL)))
+ {
+ DEBUG(8, ("is_in_path: no name list.\n"));
+ return False;
+ }
+
+ /* Get the last component of the unix name. */
+ p = strrchr(name, '/');
+ strncpy(last_component, p ? ++p : name, sizeof(last_component) - 1);
+ last_component[sizeof(last_component) - 1] = '\0';
+
+ for (; namelist->name != NULL; namelist++)
+ {
+ if (namelist->is_wild)
+ {
+ /*
+ * Look for a wildcard match. Use the old
+ * 'unix style' mask match, rather than the
+ * new NT one.
+ */
+ if (unix_mask_match
+ (last_component, namelist->name, case_sensitive,
+ False))
+ {
+ DEBUG(8,
+ ("is_in_path: mask match succeeded\n"));
+ return True;
+ }
+ }
+ else
+ {
+ if (
+ (case_sensitive
+ && (strcmp(last_component, namelist->name) == 0))
+ || (!case_sensitive
+ && (StrCaseCmp(last_component, namelist->name)
+ == 0)))
+ {
+ DEBUG(8, ("is_in_path: match succeeded\n"));
+ return True;
+ }
+ }
+ }
+ DEBUG(8, ("is_in_path: match not found\n"));
+
+ return False;
}
/*******************************************************************
@@ -2492,289 +2495,109 @@ BOOL is_in_path(char *name, name_compare_entry *namelist)
remove a potentially expensive call to mask_match
if possible.
********************************************************************/
-
-void set_namearray(name_compare_entry **ppname_array, char *namelist)
-{
- char *name_end;
- char *nameptr = namelist;
- int num_entries = 0;
- int i;
-
- (*ppname_array) = NULL;
-
- if((nameptr == NULL ) || ((nameptr != NULL) && (*nameptr == '\0')))
- return;
-
- /* We need to make two passes over the string. The
- first to count the number of elements, the second
- to split it.
- */
- while(*nameptr)
- {
- if ( *nameptr == '/' )
- {
- /* cope with multiple (useless) /s) */
- nameptr++;
- continue;
- }
- /* find the next / */
- name_end = strchr(nameptr, '/');
-
- /* oops - the last check for a / didn't find one. */
- if (name_end == NULL)
- break;
-
- /* next segment please */
- nameptr = name_end + 1;
- num_entries++;
- }
-
- if(num_entries == 0)
- return;
-
- if(( (*ppname_array) = (name_compare_entry *)malloc(
- (num_entries + 1) * sizeof(name_compare_entry))) == NULL)
- {
- DEBUG(0,("set_namearray: malloc fail\n"));
- return;
- }
-
- /* Now copy out the names */
- nameptr = namelist;
- i = 0;
- while(*nameptr)
- {
- if ( *nameptr == '/' )
- {
- /* cope with multiple (useless) /s) */
- nameptr++;
- continue;
- }
- /* find the next / */
- if ((name_end = strchr(nameptr, '/')) != NULL)
- {
- *name_end = 0;
- }
-
- /* oops - the last check for a / didn't find one. */
- if(name_end == NULL)
- break;
-
- (*ppname_array)[i].is_wild = ((strchr( nameptr, '?')!=NULL) ||
- (strchr( nameptr, '*')!=NULL));
- if(((*ppname_array)[i].name = strdup(nameptr)) == NULL)
- {
- DEBUG(0,("set_namearray: malloc fail (1)\n"));
- return;
- }
-
- /* next segment please */
- nameptr = name_end + 1;
- i++;
- }
-
- (*ppname_array)[i].name = NULL;
-
- return;
-}
-/****************************************************************************
-routine to free a namearray.
-****************************************************************************/
-
-void free_namearray(name_compare_entry *name_array)
+void set_namearray(name_compare_entry ** ppname_array, char *namelist)
{
- if(name_array == 0)
- return;
+ char *name_end;
+ char *nameptr = namelist;
+ int num_entries = 0;
+ int i;
- if(name_array->name != NULL)
- free(name_array->name);
+ (*ppname_array) = NULL;
- free((char *)name_array);
-}
+ if ((nameptr == NULL) || ((nameptr != NULL) && (*nameptr == '\0')))
+ return;
-/****************************************************************************
- Pathetically try and map a 64 bit lock offset into 31 bits. I hate Windows :-).
-****************************************************************************/
+ /* We need to make two passes over the string. The
+ first to count the number of elements, the second
+ to split it.
+ */
+ while (*nameptr)
+ {
+ if (*nameptr == '/')
+ {
+ /* cope with multiple (useless) /s) */
+ nameptr++;
+ continue;
+ }
+ /* find the next / */
+ name_end = strchr(nameptr, '/');
-uint32 map_lock_offset(uint32 high, uint32 low)
-{
- unsigned int i;
- uint32 mask = 0;
- uint32 highcopy = high;
+ /* oops - the last check for a / didn't find one. */
+ if (name_end == NULL)
+ break;
+
+ /* next segment please */
+ nameptr = name_end + 1;
+ num_entries++;
+ }
+
+ if (num_entries == 0)
+ return;
- /*
- * Try and find out how many significant bits there are in high.
- */
+ if (((*ppname_array) = (name_compare_entry *) malloc(
+ (num_entries +
+ 1) *
+ sizeof
+ (name_compare_entry)))
+ == NULL)
+ {
+ DEBUG(0, ("set_namearray: malloc fail\n"));
+ return;
+ }
- for(i = 0; highcopy; i++)
- highcopy >>= 1;
+ /* Now copy out the names */
+ nameptr = namelist;
+ i = 0;
+ while (*nameptr)
+ {
+ if (*nameptr == '/')
+ {
+ /* cope with multiple (useless) /s) */
+ nameptr++;
+ continue;
+ }
+ /* find the next / */
+ if ((name_end = strchr(nameptr, '/')) != NULL)
+ {
+ *name_end = 0;
+ }
- /*
- * We use 31 bits not 32 here as POSIX
- * lock offsets may not be negative.
- */
+ /* oops - the last check for a / didn't find one. */
+ if (name_end == NULL)
+ break;
- mask = (~0) << (31 - i);
+ (*ppname_array)[i].is_wild = ((strchr(nameptr, '?') != NULL) ||
+ (strchr(nameptr, '*') != NULL));
+ if (((*ppname_array)[i].name = strdup(nameptr)) == NULL)
+ {
+ DEBUG(0, ("set_namearray: malloc fail (1)\n"));
+ return;
+ }
- if(low & mask)
- return 0; /* Fail. */
+ /* next segment please */
+ nameptr = name_end + 1;
+ i++;
+ }
- high <<= (31 - i);
+ (*ppname_array)[i].name = NULL;
- return (high|low);
+ return;
}
/****************************************************************************
-routine to do file locking
+routine to free a namearray.
****************************************************************************/
-BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
-{
-#if HAVE_FCNTL_LOCK
- SMB_STRUCT_FLOCK lock;
- int ret;
-#if defined(LARGE_SMB_OFF_T)
- /*
- * In the 64 bit locking case we store the original
- * values in case we have to map to a 32 bit lock on
- * a filesystem that doesn't support 64 bit locks.
- */
- SMB_OFF_T orig_offset = offset;
- SMB_OFF_T orig_count = count;
-#endif /* LARGE_SMB_OFF_T */
-
- if(lp_ole_locking_compat()) {
- SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
- SMB_OFF_T mask = (mask2<<2);
-
- /* make sure the count is reasonable, we might kill the lockd otherwise */
- count &= ~mask;
-
- /* the offset is often strange - remove 2 of its bits if either of
- the top two bits are set. Shift the top ones by two bits. This
- still allows OLE2 apps to operate, but should stop lockd from
- dieing */
- if ((offset & mask) != 0)
- offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
- } else {
- SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
- SMB_OFF_T mask = (mask2<<1);
- SMB_OFF_T neg_mask = ~mask;
-
- /* interpret negative counts as large numbers */
- if (count < 0)
- count &= ~mask;
-
- /* no negative offsets */
- if(offset < 0)
- offset &= ~mask;
-
- /* count + offset must be in range */
- while ((offset < 0 || (offset + count < 0)) && mask)
- {
- offset &= ~mask;
- mask = ((mask >> 1) & neg_mask);
- }
- }
-
- DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
-
- lock.l_type = type;
- lock.l_whence = SEEK_SET;
- lock.l_start = offset;
- lock.l_len = count;
- lock.l_pid = 0;
-
- errno = 0;
-
- ret = fcntl(fd,op,&lock);
- if (errno == EFBIG)
- {
- if( DEBUGLVL( 0 ))
- {
- dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
- dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
- dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
- }
- /* 32 bit NFS file system, retry with smaller offset */
- errno = 0;
- lock.l_len = count & 0x7fffffff;
- ret = fcntl(fd,op,&lock);
- }
-
- if (errno != 0)
- DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
-
- /* a lock query */
- if (op == SMB_F_GETLK)
- {
- if ((ret != -1) &&
- (lock.l_type != F_UNLCK) &&
- (lock.l_pid != 0) &&
- (lock.l_pid != getpid()))
- {
- DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
- return(True);
- }
-
- /* it must be not locked or locked by me */
- return(False);
- }
-
- /* a lock set or unset */
- if (ret == -1)
- {
- DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
- (double)offset,(double)count,op,type,strerror(errno)));
-
- /* perhaps it doesn't support this sort of locking?? */
- if (errno == EINVAL)
- {
-
-#if defined(LARGE_SMB_OFF_T)
- {
- /*
- * Ok - if we get here then we have a 64 bit lock request
- * that has returned EINVAL. Try and map to 31 bits for offset
- * and length and try again. This may happen if a filesystem
- * doesn't support 64 bit offsets (efs/ufs) although the underlying
- * OS does.
- */
- uint32 off_low = (orig_offset & 0xFFFFFFFF);
- uint32 off_high = ((orig_offset >> 32) & 0xFFFFFFFF);
-
- lock.l_len = (orig_count & 0x7FFFFFFF);
- lock.l_start = (SMB_OFF_T)map_lock_offset(off_high, off_low);
- ret = fcntl(fd,op,&lock);
- if (ret == -1)
- {
- if (errno == EINVAL)
- {
- DEBUG(3,("locking not supported? returning True\n"));
- return(True);
- }
- return False;
- }
- DEBUG(3,("64 -> 32 bit modified lock call successful\n"));
- return True;
- }
-#else /* LARGE_SMB_OFF_T */
- DEBUG(3,("locking not supported? returning True\n"));
- return(True);
-#endif /* LARGE_SMB_OFF_T */
- }
-
- return(False);
- }
-
- /* everything went OK */
- DEBUG(8,("Lock call successful\n"));
-
- return(True);
-#else
- return(False);
-#endif
+void free_namearray(name_compare_entry * name_array)
+{
+ if (name_array == 0)
+ return;
+
+ if (name_array->name != NULL)
+ free(name_array->name);
+
+ free((char *)name_array);
}
/*******************************************************************
@@ -2783,15 +2606,16 @@ returns true is it is equal, false otherwise
********************************************************************/
BOOL is_myname(char *s)
{
- int n;
- BOOL ret = False;
+ int n;
+ BOOL ret = False;
- for (n=0; my_netbios_names[n]; n++) {
- if (strequal(my_netbios_names[n], s))
- ret=True;
- }
- DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
- return(ret);
+ for (n = 0; my_netbios_names[n]; n++)
+ {
+ if (strequal(my_netbios_names[n], s))
+ ret = True;
+ }
+ DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret));
+ return (ret);
}
/*******************************************************************
@@ -2799,32 +2623,29 @@ set the horrid remote_arch string based on an enum.
********************************************************************/
void set_remote_arch(enum remote_arch_types type)
{
- ra_type = type;
- switch( type )
- {
- case RA_WFWG:
- fstrcpy(remote_arch, "WfWg");
- return;
- case RA_OS2:
- fstrcpy(remote_arch, "OS2");
- return;
- case RA_WIN95:
- fstrcpy(remote_arch, "Win95");
- return;
- case RA_WINNT:
- fstrcpy(remote_arch, "WinNT");
- return;
- case RA_WIN2K:
- fstrcpy(remote_arch, "Win2K");
- return;
- case RA_SAMBA:
- fstrcpy(remote_arch,"Samba");
- return;
- default:
- ra_type = RA_UNKNOWN;
- fstrcpy(remote_arch, "UNKNOWN");
- break;
- }
+ ra_type = type;
+ switch (type)
+ {
+ case RA_WFWG:
+ fstrcpy(remote_arch, "WfWg");
+ return;
+ case RA_OS2:
+ fstrcpy(remote_arch, "OS2");
+ return;
+ case RA_WIN95:
+ fstrcpy(remote_arch, "Win95");
+ return;
+ case RA_WINNT:
+ fstrcpy(remote_arch, "WinNT");
+ return;
+ case RA_SAMBA:
+ fstrcpy(remote_arch, "Samba");
+ return;
+ default:
+ ra_type = RA_UNKNOWN;
+ fstrcpy(remote_arch, "UNKNOWN");
+ break;
+ }
}
/*******************************************************************
@@ -2832,110 +2653,188 @@ void set_remote_arch(enum remote_arch_types type)
********************************************************************/
enum remote_arch_types get_remote_arch(void)
{
- return ra_type;
+ return ra_type;
}
/*******************************************************************
+ align a pointer to a multiple of 4 bytes.
+ ********************************************************************/
+char *align4(char *q, char *base)
+{
+ int mod = PTR_DIFF(q, base) & 3;
+ if (mod != 0)
+ {
+ q += mod;
+ }
+ return q;
+}
+
+/*******************************************************************
align a pointer to a multiple of 2 bytes
********************************************************************/
char *align2(char *q, char *base)
{
- if ((q - base) & 1)
+ if (PTR_DIFF(q, base) & 1)
{
q++;
}
return q;
}
-void out_ascii(FILE *f, unsigned char *buf,int len)
+void out_ascii(FILE * f, const uchar * buf, int len)
{
int i;
- for (i=0;i<len;i++)
+ for (i = 0; i < len; i++)
{
- fprintf(f, "%c", isprint(buf[i])?buf[i]:'.');
+ fprintf(f, "%c", isprint(buf[i]) ? buf[i] : '.');
}
}
-void out_data(FILE *f,char *buf1,int len, int per_line)
+void out_struct(FILE * f, const char *buf1, int len, int per_line)
{
- unsigned char *buf = (unsigned char *)buf1;
- int i=0;
- if (len<=0)
+ const uchar *buf = (const uchar *)buf1;
+ int i;
+
+ if (len <= 0)
{
return;
}
- fprintf(f, "[%03X] ",i);
- for (i=0;i<len;)
+ fprintf(f, "{\n\t");
+ for (i = 0; i < len;)
{
- fprintf(f, "%02X ",(int)buf[i]);
+ fprintf(f, "0x%02X", (int)buf[i]);
i++;
- if (i%(per_line/2) == 0) fprintf(f, " ");
- if (i%per_line == 0)
- {
- out_ascii(f,&buf[i-per_line ],per_line/2); fprintf(f, " ");
- out_ascii(f,&buf[i-per_line/2],per_line/2); fprintf(f, "\n");
- if (i<len) fprintf(f, "[%03X] ",i);
+ if (i != len)
+ {
+ fprintf(f, ", ");
}
+ if (i % per_line == 0 && i != len)
+ {
+ fprintf(f, "\n\t");
+ }
+ }
+ fprintf(f, "\n};\n");
+}
+
+void out_data(FILE * f, const char *buf1, int len, int per_line)
+{
+ const uchar *buf = (const uchar *)buf1;
+ int i = 0;
+ if (len <= 0)
+ {
+ return;
}
- if ((i%per_line) != 0)
+
+ fprintf(f, "[%03X] ", i);
+ for (i = 0; i < len;)
+ {
+ fprintf(f, "%02X ", (int)buf[i]);
+ i++;
+ if (i % (per_line / 2) == 0)
+ fprintf(f, " ");
+ if (i % per_line == 0)
+ {
+ out_ascii(f, &buf[i - per_line], per_line / 2);
+ fprintf(f, " ");
+ out_ascii(f, &buf[i - per_line / 2], per_line / 2);
+ fprintf(f, "\n");
+ if (i < len)
+ fprintf(f, "[%03X] ", i);
+ }
+ }
+ if ((i % per_line) != 0)
{
int n;
- n = per_line - (i%per_line);
+ n = per_line - (i % per_line);
fprintf(f, " ");
- if (n>(per_line/2)) fprintf(f, " ");
+ if (n > (per_line / 2))
+ fprintf(f, " ");
while (n--)
{
fprintf(f, " ");
}
- n = MIN(per_line/2,i%per_line);
- out_ascii(f,&buf[i-(i%per_line)],n); fprintf(f, " ");
- n = (i%per_line) - n;
- if (n>0) out_ascii(f,&buf[i-n],n);
- fprintf(f, "\n");
+ n = MIN(per_line / 2, i % per_line);
+ out_ascii(f, &buf[i - (i % per_line)], n);
+ fprintf(f, " ");
+ n = (i % per_line) - n;
+ if (n > 0)
+ out_ascii(f, &buf[i - n], n);
+ fprintf(f, "\n");
}
}
-void print_asc(int level, unsigned char *buf,int len)
+void print_asc(int level, uchar const *buf, int len)
{
int i;
- for (i=0;i<len;i++)
- DEBUG(level,("%c", isprint(buf[i])?buf[i]:'.'));
-}
-
-void dump_data(int level,char *buf1,int len)
-{
- unsigned char *buf = (unsigned char *)buf1;
- int i=0;
- if (len<=0) return;
-
- DEBUG(level,("[%03X] ",i));
- for (i=0;i<len;) {
- DEBUG(level,("%02X ",(int)buf[i]));
- i++;
- if (i%8 == 0) DEBUG(level,(" "));
- if (i%16 == 0) {
- print_asc(level,&buf[i-16],8); DEBUG(level,(" "));
- print_asc(level,&buf[i-8],8); DEBUG(level,("\n"));
- if (i<len) DEBUG(level,("[%03X] ",i));
- }
- }
- if (i%16) {
- int n;
-
- n = 16 - (i%16);
- DEBUG(level,(" "));
- if (n>8) DEBUG(level,(" "));
- while (n--) DEBUG(level,(" "));
-
- n = MIN(8,i%16);
- print_asc(level,&buf[i-(i%16)],n); DEBUG(level,(" "));
- n = (i%16) - n;
- if (n>0) print_asc(level,&buf[i-n],n);
- DEBUG(level,("\n"));
- }
+ for (i = 0; i < len; i++)
+ {
+ DEBUGADD(level, ("%c", isprint(buf[i]) ? buf[i] : '.'));
+ }
+}
+
+void dump_data(int level, const char *buf1, int len)
+{
+ uchar const *buf = (uchar const *)buf1;
+ int i = 0;
+ if (len < 0)
+ return;
+ if (len == 0)
+ {
+ DEBUG(level, ("\n"));
+ return;
+ }
+
+ DEBUG(level, ("[%03X] ", i));
+ for (i = 0; i < len;)
+ {
+ DEBUGADD(level, ("%02X ", (int)buf[i]));
+ i++;
+ if (i % 8 == 0)
+ DEBUGADD(level, (" "));
+ if (i % 16 == 0)
+ {
+ print_asc(level, &buf[i - 16], 8);
+ DEBUGADD(level, (" "));
+ print_asc(level, &buf[i - 8], 8);
+ DEBUGADD(level, ("\n"));
+ if (i < len)
+ DEBUGADD(level, ("[%03X] ", i));
+ }
+ }
+
+ if (i % 16 != 0) /* finish off a non-16-char-length row */
+ {
+ int n;
+
+ n = 16 - (i % 16);
+ DEBUGADD(level, (" "));
+ if (n > 8)
+ DEBUGADD(level, (" "));
+ while (n--)
+ DEBUGADD(level, (" "));
+
+ n = MIN(8, i % 16);
+ print_asc(level, &buf[i - (i % 16)], n);
+ DEBUGADD(level, (" "));
+ n = (i % 16) - n;
+ if (n > 0)
+ print_asc(level, &buf[i - n], n);
+ DEBUGADD(level, ("\n"));
+ }
+}
+
+void dump_data_pw(const char *msg, const uchar * data, size_t len)
+{
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("%s", msg));
+ if (data != NULL && len > 0)
+ {
+ dump_data(100, data, len);
+ }
+#endif
}
char *tab_depth(int depth)
@@ -2960,22 +2859,23 @@ int str_checksum(const char *s)
{
int res = 0;
int c;
- int i=0;
-
- while(*s) {
+ int i = 0;
+
+ while (*s)
+ {
c = *s;
- res ^= (c << (i % 15)) ^ (c >> (15-(i%15)));
+ res ^= (c << (i % 15)) ^ (c >> (15 - (i % 15)));
s++;
i++;
}
- return(res);
-} /* str_checksum */
+ return (res);
+} /* str_checksum */
/*****************************************************************
zero a memory area then free it. Used to catch bugs faster
-*****************************************************************/
+*****************************************************************/
void zero_free(void *p, size_t size)
{
memset(p, 0, size);
@@ -2985,55 +2885,21 @@ void zero_free(void *p, size_t size)
/*****************************************************************
set our open file limit to a requested max and return the limit
-*****************************************************************/
+*****************************************************************/
int set_maxfiles(int requested_max)
{
#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
struct rlimit rlp;
- int saved_current_limit;
-
- if(getrlimit(RLIMIT_NOFILE, &rlp)) {
- DEBUG(0,("set_maxfiles: getrlimit (1) for RLIMIT_NOFILE failed with error %s\n",
- strerror(errno) ));
- /* just guess... */
- return requested_max;
- }
-
- /*
- * Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
+ getrlimit(RLIMIT_NOFILE, &rlp);
+ /* Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
* account for the extra fd we need
* as well as the log files and standard
- * handles etc. Save the limit we want to set in case
- * we are running on an OS that doesn't support this limit (AIX)
- * which always returns RLIM_INFINITY for rlp.rlim_max.
- */
-
- saved_current_limit = rlp.rlim_cur = MIN(requested_max,rlp.rlim_max);
-
- if(setrlimit(RLIMIT_NOFILE, &rlp)) {
- DEBUG(0,("set_maxfiles: setrlimit for RLIMIT_NOFILE for %d files failed with error %s\n",
- (int)rlp.rlim_cur, strerror(errno) ));
- /* just guess... */
- return saved_current_limit;
- }
-
- if(getrlimit(RLIMIT_NOFILE, &rlp)) {
- DEBUG(0,("set_maxfiles: getrlimit (2) for RLIMIT_NOFILE failed with error %s\n",
- strerror(errno) ));
- /* just guess... */
- return saved_current_limit;
- }
-
-#if defined(RLIM_INFINITY)
- if(rlp.rlim_cur == RLIM_INFINITY)
- return saved_current_limit;
-#endif
-
- if((int)rlp.rlim_cur > saved_current_limit)
- return saved_current_limit;
-
+ * handles etc. */
+ rlp.rlim_cur = MIN(requested_max, rlp.rlim_max);
+ setrlimit(RLIMIT_NOFILE, &rlp);
+ getrlimit(RLIMIT_NOFILE, &rlp);
return rlp.rlim_cur;
-#else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */
+#else
/*
* No way to know - just guess...
*/
@@ -3041,14 +2907,24 @@ int set_maxfiles(int requested_max)
#endif
}
+
+/*****************************************************************
+ splits out the last subkey of a key
+ *****************************************************************/
+void reg_get_subkey(char *full_keyname, char *key_name, char *subkey_name)
+{
+ split_at_last_component(full_keyname, key_name, '\\', subkey_name);
+}
+
/*****************************************************************
splits out the start of the key (HKLM or HKU) and the rest of the key
- *****************************************************************/
-BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name)
+ *****************************************************************/
+BOOL reg_split_key(const char *full_keyname, uint32 * reg_type,
+ char *key_name)
{
pstring tmp;
- if (!next_token(&full_keyname, tmp, "\\", sizeof(tmp)))
+ if (!next_token((char **)(&full_keyname), tmp, "\\", sizeof(tmp)))
{
return False;
}
@@ -3057,7 +2933,15 @@ BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name)
DEBUG(10, ("reg_split_key: hive %s\n", tmp));
- if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
+ if (strequal(tmp, "HKCR") || strequal(tmp, "HKEY_CLASSES_ROOT"))
+ {
+ (*reg_type) = HKEY_CLASSES_ROOT;
+ }
+ else if (strequal(tmp, "HKCU") || strequal(tmp, "HKEY_CURRENT_USER"))
+ {
+ (*reg_type) = HKEY_CURRENT_USER;
+ }
+ else if (strequal(tmp, "HKLM") || strequal(tmp, "HKEY_LOCAL_MACHINE"))
{
(*reg_type) = HKEY_LOCAL_MACHINE;
}
@@ -3067,10 +2951,10 @@ BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name)
}
else
{
- DEBUG(10,("reg_split_key: unrecognised hive key %s\n", tmp));
+ DEBUG(10, ("reg_split_key: unrecognised hive key %s\n", tmp));
return False;
}
-
+
if (next_token(NULL, tmp, "\n\r", sizeof(tmp)))
{
fstrcpy(key_name, tmp);
@@ -3085,105 +2969,526 @@ BOOL reg_split_key(char *full_keyname, uint32 *reg_type, char *key_name)
return True;
}
+char *get_trusted_serverlist(const char *domain)
+{
+ pstring tmp;
+ static pstring srv_list;
+ char *trusted_list = lp_trusted_domains();
-/*****************************************************************
-like mktemp() but make sure that no % characters are used
-% characters are bad for us because of the macro subs
- *****************************************************************/
-char *smbd_mktemp(char *template)
+ if (domain == NULL ||
+ strequal(domain, "") || strequal(lp_workgroup(), domain))
+ {
+ pstrcpy(srv_list, lp_passwordserver());
+ DEBUG(10, ("local domain server list: %s\n", srv_list));
+ return srv_list;
+ }
+
+ if (!next_token(&trusted_list, tmp, NULL, sizeof(tmp)))
+ {
+ return NULL;
+ }
+
+ do
+ {
+ fstring trust_dom;
+ split_at_first_component(tmp, trust_dom, '=', srv_list);
+
+ if (strequal(domain, trust_dom))
+ {
+ DEBUG(10, ("trusted: %s\n", srv_list));
+ return srv_list;
+ }
+
+ }
+ while (next_token(NULL, tmp, NULL, sizeof(tmp)));
+
+ return NULL;
+}
+
+/**********************************************************
+ Map the Active Directory userAccountControl attribute to
+ SMB account control bits. The attribute is stored in the
+ directory as an integer.
+ **********************************************************/
+NTDS_USER_FLAG_ENUM pwdb_acct_ctrl_to_ad(uint16 smbac)
+{
+ NTDS_USER_FLAG_ENUM adac;
+
+ adac = 0;
+
+ adac |= NTDS_UF_TRUSTED_FOR_DELEGATION; /* | NTDS_UF_USE_DES_KEY_ONLY; */
+
+ if (smbac & ACB_DISABLED)
+ adac |= NTDS_UF_ACCOUNTDISABLE;
+ if (smbac & ACB_HOMDIRREQ)
+ adac |= NTDS_UF_HOMEDIR_REQUIRED;
+ if (smbac & ACB_PWNOTREQ)
+ adac |= NTDS_UF_PASSWD_NOTREQD;
+ if (smbac & ACB_TEMPDUP)
+ adac |= NTDS_UF_TEMP_DUPLICATE_ACCOUNT;
+ if (smbac & ACB_NORMAL)
+ adac |= NTDS_UF_NORMAL_ACCOUNT;
+ if (smbac & ACB_MNS)
+ adac |= NTDS_UF_MNS_LOGON_ACCOUNT;
+ if (smbac & ACB_DOMTRUST)
+ adac |= NTDS_UF_INTERDOMAIN_TRUST_ACCOUNT;
+ if (smbac & ACB_WSTRUST)
+ adac |= NTDS_UF_WORKSTATION_TRUST_ACCOUNT;
+ if (smbac & ACB_SVRTRUST)
+ adac |= NTDS_UF_SERVER_TRUST_ACCOUNT;
+ if (smbac & ACB_PWNOEXP)
+ adac |= NTDS_UF_DONT_EXPIRE_PASSWD;
+ if (smbac & ACB_AUTOLOCK)
+ adac |= NTDS_UF_LOCKOUT;
+ if (smbac & ACB_PWLOCK)
+ adac |= NTDS_UF_PASSWD_CANT_CHANGE;
+
+ return adac;
+}
+
+/**********************************************************
+ Map the Active Directory userAccountControl attribute to
+ SMB account control bits. The attribute is stored in the
+ directory as an integer.
+ **********************************************************/
+uint16 pwdb_acct_ctrl_from_ad(NTDS_USER_FLAG_ENUM adac)
+{
+ int smbac;
+
+ smbac = 0;
+
+ if (adac & NTDS_UF_ACCOUNTDISABLE)
+ adac |= ACB_DISABLED;
+ if (adac & NTDS_UF_HOMEDIR_REQUIRED)
+ adac |= ACB_HOMDIRREQ;;
+ if (adac & NTDS_UF_PASSWD_NOTREQD)
+ adac |= ACB_PWNOTREQ;
+ if (adac & NTDS_UF_TEMP_DUPLICATE_ACCOUNT)
+ adac |= ACB_TEMPDUP;
+ if (adac & NTDS_UF_NORMAL_ACCOUNT)
+ adac |= ACB_NORMAL;
+ if (adac & NTDS_UF_MNS_LOGON_ACCOUNT)
+ adac |= ACB_MNS;
+ if (adac & NTDS_UF_INTERDOMAIN_TRUST_ACCOUNT)
+ adac |= ACB_DOMTRUST;
+ if (adac & NTDS_UF_WORKSTATION_TRUST_ACCOUNT)
+ adac |= ACB_WSTRUST;
+ if (adac & NTDS_UF_SERVER_TRUST_ACCOUNT)
+ adac |= ACB_SVRTRUST;
+ if (adac & NTDS_UF_DONT_EXPIRE_PASSWD)
+ adac |= ACB_PWNOEXP;
+ if (adac & NTDS_UF_LOCKOUT)
+ adac |= ACB_AUTOLOCK;
+ if (adac & NTDS_UF_PASSWD_CANT_CHANGE)
+ adac |= ACB_PWLOCK;
+
+ return smbac;
+}
+
+/**********************************************************
+ Encode the account control bits into a string.
+ length = length of string to encode into (including terminating
+ null). length *MUST BE MORE THAN 2* !
+ **********************************************************/
+
+char *pwdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
+{
+ static fstring acct_str;
+ size_t i = 0;
+
+ acct_str[i++] = '[';
+
+ if (acct_ctrl & ACB_PWNOTREQ)
+ acct_str[i++] = 'N';
+ if (acct_ctrl & ACB_DISABLED)
+ acct_str[i++] = 'D';
+ if (acct_ctrl & ACB_HOMDIRREQ)
+ acct_str[i++] = 'H';
+ if (acct_ctrl & ACB_TEMPDUP)
+ acct_str[i++] = 'T';
+ if (acct_ctrl & ACB_NORMAL)
+ acct_str[i++] = 'U';
+ if (acct_ctrl & ACB_MNS)
+ acct_str[i++] = 'M';
+ if (acct_ctrl & ACB_WSTRUST)
+ acct_str[i++] = 'W';
+ if (acct_ctrl & ACB_SVRTRUST)
+ acct_str[i++] = 'S';
+ if (acct_ctrl & ACB_AUTOLOCK)
+ acct_str[i++] = 'L';
+ if (acct_ctrl & ACB_PWNOEXP)
+ acct_str[i++] = 'X';
+ if (acct_ctrl & ACB_DOMTRUST)
+ acct_str[i++] = 'I';
+ if (acct_ctrl & ACB_PWLOCK)
+ acct_str[i++] = 'P';
+
+ for (; i < length - 2; i++)
+ {
+ acct_str[i] = ' ';
+ }
+
+ i = length - 2;
+ acct_str[i++] = ']';
+ acct_str[i++] = '\0';
+
+ return acct_str;
+}
+
+/**********************************************************
+ Decode the account control bits from a string.
+
+ this function breaks coding standards minimum line width of 80 chars.
+ reason: vertical line-up code clarity - all case statements fit into
+ 15 lines, which is more important.
+ **********************************************************/
+
+uint16 pwdb_decode_acct_ctrl(const char *p)
{
- char *p = mktemp(template);
- char *p2;
- SMB_STRUCT_STAT st;
+ uint16 acct_ctrl = 0;
+ BOOL finished = False;
+
+ /*
+ * Check if the account type bits have been encoded after the
+ * NT password (in the form [NDHTUWSLXI]).
+ */
- if (!p) return NULL;
+ if (*p != '[')
+ return 0;
- while ((p2=strchr(p,'%'))) {
- p2[0] = 'A';
- while (sys_stat(p,&st) == 0 && p2[0] < 'Z') {
- /* damn, it exists */
- p2[0]++;
+ for (p++; *p && !finished; p++)
+ {
+ switch (*p)
+ {
+ case 'N':
+ {
+ acct_ctrl |= ACB_PWNOTREQ;
+ break; /* 'N'o password. */
+ }
+ case 'D':
+ {
+ acct_ctrl |= ACB_DISABLED;
+ break; /* 'D'isabled. */
+ }
+ case 'H':
+ {
+ acct_ctrl |= ACB_HOMDIRREQ;
+ break; /* 'H'omedir required. */
+ }
+ case 'T':
+ {
+ acct_ctrl |= ACB_TEMPDUP;
+ break; /* 'T'emp account. */
+ }
+ case 'U':
+ {
+ acct_ctrl |= ACB_NORMAL;
+ break; /* 'U'ser account (normal). */
+ }
+ case 'M':
+ {
+ acct_ctrl |= ACB_MNS;
+ break; /* 'M'NS logon user account. What is this ? */
+ }
+ case 'W':
+ {
+ acct_ctrl |= ACB_WSTRUST;
+ break; /* 'W'orkstation account. */
+ }
+ case 'S':
+ {
+ acct_ctrl |= ACB_SVRTRUST;
+ break; /* 'S'erver account. */
+ }
+ case 'L':
+ {
+ acct_ctrl |= ACB_AUTOLOCK;
+ break; /* 'L'ocked account. */
+ }
+ case 'X':
+ {
+ acct_ctrl |= ACB_PWNOEXP;
+ break; /* No 'X'piry on password */
+ }
+ case 'I':
+ {
+ acct_ctrl |= ACB_DOMTRUST;
+ break; /* 'I'nterdomain trust account. */
+ }
+ case 'P':
+ {
+ acct_ctrl |= ACB_PWLOCK;
+ break; /* 'P'assword cannot be changed remotely */
+ }
+ case ' ':
+ {
+ break;
+ }
+ case ':':
+ case '\n':
+ case '\0':
+ case ']':
+ default:
+ {
+ finished = True;
+ }
}
- if (p2[0] == 'Z') {
- /* oh well ... better return something */
- p2[0] = '%';
- return p;
+ }
+
+ return acct_ctrl;
+}
+
+/*******************************************************************
+ gets password-database-format time from a string.
+ ********************************************************************/
+
+static time_t get_time_from_string(const char *p)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ if (p[i] == '\0' || !isxdigit((int)(p[i] & 0xFF)))
+ {
+ break;
}
}
+ if (i == 8)
+ {
+ /*
+ * p points at 8 characters of hex digits -
+ * read into a time_t as the seconds since
+ * 1970 that the password was last changed.
+ */
+ return (time_t) strtol(p, NULL, 16);
+ }
+ return (time_t) - 1;
+}
- return p;
+/*******************************************************************
+ gets password time last changed time
+ ********************************************************************/
+
+time_t pwdb_get_time_last_changed(const char *p)
+{
+ if (*p && !StrnCaseCmp(p, "TLC-", 4))
+ {
+ return get_time_from_string(p + 4);
+ }
+ return (time_t) - 1;
+}
+
+/*******************************************************************
+ gets password last set time
+ ********************************************************************/
+
+time_t pwdb_get_last_set_time(const char *p)
+{
+ if (*p && !StrnCaseCmp(p, "LCT-", 4))
+ {
+ return get_time_from_string(p + 4);
+ }
+ return (time_t) - 1;
+}
+
+
+/*******************************************************************
+ sets password-database-format time in a string.
+ ********************************************************************/
+static void set_time_in_string(char *p, int max_len, char *type, time_t t)
+{
+ slprintf(p, max_len, ":%s-%08X", type, (uint32) t);
+}
+
+/*******************************************************************
+ sets logon time
+ ********************************************************************/
+void pwdb_set_logon_time(char *p, int max_len, time_t t)
+{
+ set_time_in_string(p, max_len, "LNT", t);
+}
+
+/*******************************************************************
+ sets logoff time
+ ********************************************************************/
+void pwdb_set_logoff_time(char *p, int max_len, time_t t)
+{
+ set_time_in_string(p, max_len, "LOT", t);
+}
+
+/*******************************************************************
+ sets kickoff time
+ ********************************************************************/
+void pwdb_set_kickoff_time(char *p, int max_len, time_t t)
+{
+ set_time_in_string(p, max_len, "KOT", t);
+}
+
+/*******************************************************************
+ sets password can change time
+ ********************************************************************/
+void pwdb_set_can_change_time(char *p, int max_len, time_t t)
+{
+ set_time_in_string(p, max_len, "CCT", t);
+}
+
+/*******************************************************************
+ sets password last change time
+ ********************************************************************/
+void pwdb_set_time_last_changed(char *p, int max_len, time_t t)
+{
+ set_time_in_string(p, max_len, "TLC", t);
+}
+
+/*******************************************************************
+ sets password last set time
+ ********************************************************************/
+void pwdb_set_must_change_time(char *p, int max_len, time_t t)
+{
+ set_time_in_string(p, max_len, "MCT", t);
}
+/*******************************************************************
+ sets password last set time
+ ********************************************************************/
+void pwdb_set_last_set_time(char *p, int max_len, time_t t)
+{
+ set_time_in_string(p, max_len, "LCT", t);
+}
+
+
+/*************************************************************
+ Routine to set 32 hex password characters from a 16 byte array.
+**************************************************************/
+void pwdb_sethexpwd(char *p, const uchar * pwd, uint16 acct_ctrl)
+{
+ if (pwd != NULL)
+ {
+ int i;
+ for (i = 0; i < 16; i++)
+ {
+ slprintf(&p[i * 2], 33, "%02X", pwd[i]);
+ }
+ }
+ else
+ {
+ if (IS_BITS_SET_ALL(acct_ctrl, ACB_PWNOTREQ))
+ {
+ safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX",
+ 33);
+ }
+ else
+ {
+ safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+ 33);
+ }
+ }
+}
+
+/*************************************************************
+ Routine to get the 32 hex characters and turn them
+ into a 16 byte array.
+**************************************************************/
+BOOL pwdb_gethexpwd(const char *p, char *pwd, uint32 * acct_ctrl)
+{
+ if (strnequal(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 32))
+ {
+ if (acct_ctrl != NULL)
+ {
+ *acct_ctrl |= ACB_PWNOTREQ;
+ }
+ pwd[0] = 0;
+ return True;
+ }
+ else if (strnequal(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 32))
+ {
+ pwd[0] = 0;
+ return True;
+ }
+ else
+ {
+ return strhex_to_str(pwd, 32, p) == 16;
+ }
+}
/*****************************************************************
like strdup but for memory
- *****************************************************************/
-void *memdup(void *p, size_t size)
+ *****************************************************************/
+void *memdup(const void *p, size_t size)
{
void *p2;
+ if (!p)
+ return NULL;
+ if (size == 0)
+ return NULL;
p2 = malloc(size);
- if (!p2) return NULL;
+ if (!p2)
+ return NULL;
memcpy(p2, p, size);
return p2;
}
/*****************************************************************
-get local hostname and cache result
- *****************************************************************/
-char *myhostname(void)
+a useful function for returning a path in the Samba password directory
+ *****************************************************************/
+char *passdb_path(char *name)
{
- static pstring ret;
- if (ret[0] == 0) {
- get_myname(ret);
+ static pstring fname;
+
+ pstrcpy(fname, lp_sam_directory());
+ trim_string(fname, "", "/");
+
+ if (!directory_exist(fname, NULL))
+ {
+ /* must be 0755 because root can readwrite, all others read */
+ mkdir(fname, 0755);
}
- return ret;
-}
+ pstrcat(fname, "/");
+ pstrcat(fname, name);
+
+ DEBUG(20, ("passdb_path: %s\n", fname));
+
+ return fname;
+}
/*****************************************************************
a useful function for returning a path in the Samba lock directory
- *****************************************************************/
+ *****************************************************************/
char *lock_path(char *name)
{
static pstring fname;
- pstrcpy(fname,lp_lockdir());
- trim_string(fname,"","/");
-
- if (!directory_exist(fname,NULL)) {
- mkdir(fname,0755);
+ pstrcpy(fname, lp_lockdir());
+ trim_string(fname, "", "/");
+
+ if (!directory_exist(fname, NULL))
+ {
+ mkdir(fname, 0755);
}
-
- pstrcat(fname,"/");
- pstrcat(fname,name);
+
+ pstrcat(fname, "/");
+ pstrcat(fname, name);
return fname;
}
-/*******************************************************************
- Given a filename - get its directory name
- NB: Returned in static storage. Caveats:
- o Not safe in thread environment.
- o Caller must not free.
- o If caller wishes to preserve, they should copy.
-********************************************************************/
+struct field_info sid_name_info[] = {
+ {SID_NAME_UNKNOWN, "UNKNOWN"}, /* default */
+ {SID_NAME_USER, "User"},
+ {SID_NAME_DOM_GRP, "Domain Group"},
+ {SID_NAME_DOMAIN, "Domain"},
+ {SID_NAME_ALIAS, "Local Group"},
+ {SID_NAME_WKN_GRP, "Well-known Group"},
+ {SID_NAME_DELETED, "Deleted"},
+ {SID_NAME_INVALID, "Invalid"},
+ {0, NULL}
+};
-char *parent_dirname(const char *path)
+/****************************************************************************
+convert a SID_NAME_USE to a string
+****************************************************************************/
+const char *get_sid_name_use_str(uint32 sid_name_use)
{
- static pstring dirpath;
- char *p;
-
- if (!path)
- return(NULL);
-
- pstrcpy(dirpath, path);
- p = strrchr(dirpath, '/'); /* Find final '/', if any */
- if (!p) {
- pstrcpy(dirpath, "."); /* No final "/", so dir is "." */
- } else {
- if (p == dirpath)
- ++p; /* For root "/", leave "/" in place */
- *p = '\0';
- }
- return dirpath;
+ return enum_field_to_str(sid_name_use, sid_name_info, True);
}
diff --git a/source/lib/util_array.c b/source/lib/util_array.c
index 567c170834a..fe59e6af81a 100644
--- a/source/lib/util_array.c
+++ b/source/lib/util_array.c
@@ -28,11 +28,14 @@ void free_void_array(uint32 num_entries, void **entries,
uint32 i;
if (entries != NULL)
{
- for (i = 0; i < num_entries; i++)
+ if (free_item != NULL)
{
- if (entries[i] != NULL)
+ for (i = 0; i < num_entries; i++)
{
- free_item(entries[i]);
+ if (entries[i] != NULL)
+ {
+ free_item(entries[i]);
+ }
}
}
free(entries);
@@ -104,6 +107,7 @@ static struct use_info *use_info_dup(const struct use_info *from)
{
ZERO_STRUCTP(copy);
copy->connected = from->connected;
+ copy->key = from->key;
if (from->srv_name != NULL)
{
copy->srv_name = strdup(from->srv_name );
@@ -179,6 +183,19 @@ uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name)
}
+void free_unistr_array(uint32 num_entries, UNISTR2 **entries)
+{
+ void(*fn)(void*) = (void(*)(void*))&unistr2_free;
+ free_void_array(num_entries, (void**)entries, *fn);
+}
+
+UNISTR2* add_unistr_to_array(uint32 *len, UNISTR2 ***array, UNISTR2 *name)
+{
+ void*(*fn)(const void*) = (void*(*)(const void*))&unistr2_dup;
+ return (UNISTR2*)add_copy_to_array(len,
+ (void***)array, (const void*)name, *fn, False);
+}
+
void free_sid_array(uint32 num_entries, DOM_SID **entries)
{
void(*fn)(void*) = (void(*)(void*))&free;
diff --git a/source/lib/util_file.c b/source/lib/util_file.c
index 9eb38460d92..44b37466c71 100644
--- a/source/lib/util_file.c
+++ b/source/lib/util_file.c
@@ -51,7 +51,7 @@ BOOL do_file_lock(int fd, int waitsecs, int type)
lock.l_len = 1;
lock.l_pid = 0;
- alarm(waitsecs);
+ alarm(5);
ret = fcntl(fd, SMB_F_SETLKW, &lock);
alarm(0);
CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
@@ -108,27 +108,138 @@ BOOL file_unlock(int fd, int *plock_depth)
return ret;
}
+/****************************************************************************
+routine to do file locking
+****************************************************************************/
+BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
+{
+#if HAVE_FCNTL_LOCK
+ SMB_STRUCT_FLOCK lock;
+ int ret;
+
+ if(lp_ole_locking_compat()) {
+ SMB_OFF_T mask2= ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
+ SMB_OFF_T mask = (mask2<<2);
+
+ /* make sure the count is reasonable, we might kill the lockd otherwise */
+ count &= ~mask;
+
+ /* the offset is often strange - remove 2 of its bits if either of
+ the top two bits are set. Shift the top ones by two bits. This
+ still allows OLE2 apps to operate, but should stop lockd from
+ dieing */
+ if ((offset & mask) != 0)
+ offset = (offset & ~mask) | (((offset & mask) >> 2) & mask2);
+ } else {
+ SMB_OFF_T mask2 = ((SMB_OFF_T)0x4) << (SMB_OFF_T_BITS-4);
+ SMB_OFF_T mask = (mask2<<1);
+ SMB_OFF_T neg_mask = ~mask;
+
+ /* interpret negative counts as large numbers */
+ if (count < 0)
+ count &= ~mask;
+
+ /* no negative offsets */
+ if(offset < 0)
+ offset &= ~mask;
+
+ /* count + offset must be in range */
+ while ((offset < 0 || (offset + count < 0)) && mask)
+ {
+ offset &= ~mask;
+ mask = ((mask >> 1) & neg_mask);
+ }
+ }
+
+ DEBUG(8,("fcntl_lock %d %d %.0f %.0f %d\n",fd,op,(double)offset,(double)count,type));
+
+ lock.l_type = type;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = offset;
+ lock.l_len = count;
+ lock.l_pid = 0;
+
+ errno = 0;
+
+ ret = fcntl(fd,op,&lock);
+ if (errno == EFBIG)
+ {
+ if( DEBUGLVL( 0 ))
+ {
+ dbgtext("fcntl_lock: WARNING: lock request at offset %.0f, length %.0f returned\n", (double)offset,(double)count);
+ dbgtext("a 'file too large' error. This can happen when using 64 bit lock offsets\n");
+ dbgtext("on 32 bit NFS mounted file systems. Retrying with 32 bit truncated length.\n");
+ }
+ /* 32 bit NFS file system, retry with smaller offset */
+ errno = 0;
+ lock.l_len = count & 0xffffffff;
+ ret = fcntl(fd,op,&lock);
+ }
+
+ if (errno != 0)
+ DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
+
+ /* a lock query */
+ if (op == SMB_F_GETLK)
+ {
+ if ((ret != -1) &&
+ (lock.l_type != F_UNLCK) &&
+ (lock.l_pid != 0) &&
+ (lock.l_pid != getpid()))
+ {
+ DEBUG(3,("fd %d is locked by pid %d\n",fd,(int)lock.l_pid));
+ return(True);
+ }
+
+ /* it must be not locked or locked by me */
+ return(False);
+ }
+
+ /* a lock set or unset */
+ if (ret == -1)
+ {
+ DEBUG(3,("lock failed at offset %.0f count %.0f op %d type %d (%s)\n",
+ (double)offset,(double)count,op,type,strerror(errno)));
+
+ /* perhaps it doesn't support this sort of locking?? */
+ if (errno == EINVAL)
+ {
+ DEBUG(3,("locking not supported? returning True\n"));
+ return(True);
+ }
+
+ return(False);
+ }
+
+ /* everything went OK */
+ DEBUG(8,("Lock call successful\n"));
+
+ return(True);
+#else
+ return(False);
+#endif
+}
/***************************************************************
locks a file for enumeration / modification.
update to be set = True if modification is required.
****************************************************************/
-void *startfilepwent(char *pfile, char *s_readbuf, int bufsize,
+void *startfileent(char *pfile, char *s_readbuf, int bufsize,
int *file_lock_depth, BOOL update)
{
FILE *fp = NULL;
if (!*pfile)
{
- DEBUG(0, ("startfilepwent: No file set\n"));
+ DEBUG(0, ("startfileent: No file set\n"));
return (NULL);
}
- DEBUG(10, ("startfilepwent: opening file %s\n", pfile));
+ DEBUG(10, ("startfileent: opening file %s\n", pfile));
fp = sys_fopen(pfile, update ? "r+b" : "rb");
if (fp == NULL) {
- DEBUG(0, ("startfilepwent: unable to open file %s\n", pfile));
+ DEBUG(0, ("startfileent: unable to open file %s\n", pfile));
return NULL;
}
@@ -137,7 +248,7 @@ void *startfilepwent(char *pfile, char *s_readbuf, int bufsize,
if (!file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK), 5, file_lock_depth))
{
- DEBUG(0, ("startfilepwent: unable to lock file %s\n", pfile));
+ DEBUG(0, ("startfileent: unable to lock file %s\n", pfile));
fclose(fp);
return NULL;
}
@@ -152,13 +263,13 @@ void *startfilepwent(char *pfile, char *s_readbuf, int bufsize,
/***************************************************************
End enumeration of the file.
****************************************************************/
-void endfilepwent(void *vp, int *file_lock_depth)
+void endfileent(void *vp, int *file_lock_depth)
{
FILE *fp = (FILE *)vp;
file_unlock(fileno(fp), file_lock_depth);
fclose(fp);
- DEBUG(7, ("endfilepwent: closed file.\n"));
+ DEBUG(7, ("endfileent: closed file.\n"));
}
/*************************************************************************
@@ -181,7 +292,6 @@ BOOL setfilepwpos(void *vp, SMB_BIG_UINT tok)
/*************************************************************************
gets a line out of a file.
- line is of format "xxxx:xxxxxx:xxxxx:".
lines with "#" at the front are ignored.
*************************************************************************/
int getfileline(void *vp, char *linebuf, int linebuf_size)
@@ -189,7 +299,6 @@ int getfileline(void *vp, char *linebuf, int linebuf_size)
/* Static buffers we will return. */
FILE *fp = (FILE *)vp;
unsigned char c;
- unsigned char *p;
size_t linebuf_len;
if (fp == NULL)
@@ -249,12 +358,6 @@ int getfileline(void *vp, char *linebuf, int linebuf_size)
continue;
}
- p = (unsigned char *) strchr(linebuf, ':');
- if (p == NULL)
- {
- DEBUG(0, ("getfileline: malformed line entry (no :)\n"));
- continue;
- }
return linebuf_len;
}
return -1;
@@ -327,3 +430,50 @@ char *fgets_slash(char *s2,int maxlen,FILE *f)
return(s);
}
+/****************************************************************************
+checks if a file has changed since last read
+****************************************************************************/
+BOOL file_modified(const char *filename, time_t *lastmodified)
+{
+ SMB_STRUCT_STAT st;
+
+ if (sys_stat(filename, &st) != 0)
+ {
+ DEBUG(0, ("file_changed: Unable to stat file %s. Error was %s\n",
+ filename, strerror(errno) ));
+ return False;
+ }
+
+ if(st.st_mtime <= *lastmodified)
+ {
+ DEBUG(20, ("file_modified: %s not modified\n", filename));
+ return False;
+ }
+
+ DEBUG(20, ("file_modified: %s modified\n", filename));
+ *lastmodified = st.st_mtime;
+ return True;
+}
+
+/***************************************************************************
+opens a file if modified otherwise returns NULL
+***************************************************************************/
+void *open_file_if_modified(const char *filename, char *mode, time_t *lastmodified)
+{
+ FILE *f;
+
+ if (!file_modified(filename, lastmodified))
+ {
+ return NULL;
+ }
+
+ if( (f = fopen(filename, mode)) == NULL)
+ {
+ DEBUG(0, ("open_file_if_modified: can't open file %s. Error was %s\n",
+ filename, strerror(errno)));
+ return NULL;
+ }
+
+ return (void *)f;
+}
+
diff --git a/source/lib/util_hnd.c b/source/lib/util_hnd.c
new file mode 100644
index 00000000000..6e0fd73c7ff
--- /dev/null
+++ b/source/lib/util_hnd.c
@@ -0,0 +1,514 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+
+extern int DEBUGLEVEL;
+
+#ifndef MAX_OPEN_POLS
+#define MAX_OPEN_POLS 64
+#endif
+
+#define POL_NO_INFO 0
+#define POL_REG_INFO 1
+#define POL_SAMR_INFO 2
+#define POL_CLI_INFO 3
+#define POL_SVC_INFO 4
+
+
+struct policy
+{
+ struct policy *next, *prev;
+ int pnum;
+ BOOL open;
+ POLICY_HND pol_hnd;
+ uint32 access_mask;
+ vuser_key key;
+
+ char *name;
+
+ int type;
+ void (*free_fn)(void*);
+ void *dev;
+};
+
+/****************************************************************************
+ i hate this. a global policy handle cache. yuk.
+****************************************************************************/
+struct policy_cache *get_global_hnd_cache(void)
+{
+ static struct policy_cache *cache = NULL;
+
+ if (cache == NULL)
+ {
+ cache = init_policy_cache(1024);
+ }
+ return cache;
+}
+
+/****************************************************************************
+ create a unique policy handle
+****************************************************************************/
+static void create_pol_hnd(POLICY_HND *hnd)
+{
+ static uint32 pol_hnd_low = 0;
+ static uint32 pol_hnd_high = 0;
+
+ if (hnd == NULL) return;
+
+ /* i severely doubt that pol_hnd_high will ever be non-zero... */
+ pol_hnd_low++;
+ if (pol_hnd_low == 0) pol_hnd_high++;
+
+ SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */
+ SIVAL(hnd->data, 4 , pol_hnd_low ); /* second bit is incrementing */
+ SIVAL(hnd->data, 8 , pol_hnd_high); /* second bit is incrementing */
+ SIVAL(hnd->data, 12, time(NULL)); /* something random */
+ SIVAL(hnd->data, 16, getpid()); /* something more random */
+}
+
+/****************************************************************************
+ initialise policy handle states...
+****************************************************************************/
+struct policy_cache *init_policy_cache(int num_pol_hnds)
+{
+ struct policy_cache *cache = malloc(sizeof(struct policy_cache));
+ if (cache != NULL)
+ {
+ cache->bmap = NULL;
+ cache->Policy = NULL;
+ }
+ return cache;
+}
+
+/****************************************************************************
+ free policy handle states...
+****************************************************************************/
+void free_policy_cache(struct policy_cache *cache)
+{
+ free(cache);
+}
+
+/****************************************************************************
+ find policy by handle
+****************************************************************************/
+static struct policy *find_policy(struct policy_cache *cache,
+ const POLICY_HND *hnd)
+{
+ struct policy *p;
+
+ for (p=cache->Policy;p;p=p->next) {
+ if (memcmp(&p->pol_hnd, hnd, sizeof(*hnd)) == 0) {
+ DEBUG(4,("Found policy hnd[%x] ", p->pnum));
+ dump_data(4, (const char *)hnd->data,
+ sizeof(hnd->data));
+ return p;
+ }
+ }
+
+ DEBUG(4,("cache->Policy not found: "));
+ dump_data(4, (const char *)hnd->data, sizeof(hnd->data));
+
+ return NULL;
+}
+
+/****************************************************************************
+ set the name of a POLICY_HND
+****************************************************************************/
+BOOL policy_hnd_set_name(struct policy_cache *cache,
+ POLICY_HND *hnd, const char *name)
+{
+ struct policy *p = find_policy(cache, hnd);
+ if (!p)
+ {
+ DEBUG(3, ("Error setting name for policy\n"));
+ return False;
+ }
+ safe_free(p->name);
+ if (name)
+ {
+ DEBUG(4, ("policy pnum=%x setting name to %s\n",
+ p->pnum, name));
+ p->name = strdup(name);
+ return (p->name != NULL);
+ }
+ else
+ {
+ DEBUG(4, ("policy pnum=%x setting name to %s\n",
+ p->pnum, "NULL"));
+ p->name = NULL;
+ return True;
+ }
+}
+
+/****************************************************************************
+ get the name of a POLICY_HND
+****************************************************************************/
+static const char *pol_get_name(const struct policy *p)
+{
+ if (!p)
+ {
+ return "(NULL)";
+ }
+ if (p->name)
+ {
+ return p->name;
+ }
+ return "";
+}
+
+/****************************************************************************
+ get the name of a POLICY_HND, public interface
+****************************************************************************/
+const char *policy_hnd_get_name(struct policy_cache *cache,
+ const POLICY_HND *hnd)
+{
+ const char *name;
+ struct policy *p = find_policy(cache, hnd);
+
+ if (!p)
+ {
+ DEBUG(3, ("Error getting name for policy\n"));
+ return "(invalid POLICY_HND)";
+ }
+ name = pol_get_name(p);
+ DEBUG(4, ("policy(pnum=%x %s): getting name\n",
+ p->pnum, name));
+ return name;
+}
+
+
+/****************************************************************************
+ find first available policy slot. copies a policy handle for you.
+****************************************************************************/
+BOOL dup_policy_hnd(struct policy_cache *cache,
+ POLICY_HND *hnd,
+ const POLICY_HND *from)
+{
+ struct policy *p = find_policy(cache, from);
+
+ if (!p || !p->open)
+ {
+ return False;
+ }
+ DEBUG(3,("Duplicating policy state pnum=%x\n", p->pnum));
+ return register_policy_hnd(cache, &p->key, hnd, p->access_mask);
+}
+
+/****************************************************************************
+ find first available policy slot. creates a policy handle for you.
+****************************************************************************/
+BOOL register_policy_hnd(struct policy_cache *cache,
+ const vuser_key *key,
+ POLICY_HND *hnd,
+ uint32 access_mask)
+{
+ struct policy *p;
+ static int count = 1;
+
+ p = (struct policy *)malloc(sizeof(*p));
+ if (!p)
+ {
+ DEBUG(0,("ERROR: out of memory!\n"));
+ return False;
+ }
+
+ ZERO_STRUCTP(p);
+
+ p->open = True;
+ p->pnum = count++;
+ p->access_mask = access_mask;
+ if (key != NULL)
+ {
+ p->key = *key;
+ }
+ else
+ {
+ p->key.vuid = UID_FIELD_INVALID;
+ p->key.pid = getpid();
+ }
+
+
+ DLIST_ADD(cache->Policy, p);
+
+ DEBUG(4,("Opened policy hnd[%x] ", p->pnum));
+ DEBUG(10,("register_policy_hnd: vuser [%d, %x]\n",
+ p->key.pid, p->key.vuid));
+
+ memcpy(&p->pol_hnd, hnd, sizeof(*hnd));
+ dump_data(4, (char *)hnd->data, sizeof(hnd->data));
+
+ return True;
+}
+
+/****************************************************************************
+ find first available policy slot. creates a policy handle for you.
+****************************************************************************/
+BOOL open_policy_hnd(struct policy_cache *cache,
+ const vuser_key *key,
+ POLICY_HND *hnd,
+ uint32 access_mask)
+{
+ create_pol_hnd(hnd);
+ return register_policy_hnd(cache, key, hnd, access_mask);
+}
+
+/****************************************************************************
+ find first available policy slot. creates a policy handle for you.
+****************************************************************************/
+BOOL open_policy_hnd_link(struct policy_cache *cache,
+ const POLICY_HND *parent_hnd,
+ POLICY_HND *hnd,
+ uint32 access_mask)
+{
+ const vuser_key *key = get_policy_vuser_key(cache, parent_hnd);
+ if (key == NULL)
+ {
+ return False;
+ }
+ create_pol_hnd(hnd);
+ return register_policy_hnd(cache, key, hnd, access_mask);
+}
+
+/****************************************************************************
+ find policy index by handle
+****************************************************************************/
+int find_policy_by_hnd(struct policy_cache *cache, const POLICY_HND *hnd)
+{
+ struct policy *p = find_policy(cache, hnd);
+
+ return p?p->pnum:-1;
+}
+
+
+/****************************************************************************
+ set pol state.
+****************************************************************************/
+BOOL set_policy_state(struct policy_cache *cache, POLICY_HND *hnd,
+ void(*fn)(void*), void *dev)
+{
+ struct policy *p = find_policy(cache, hnd);
+
+ if (p && p->open)
+ {
+ DEBUG(3,("Setting policy state pnum=%x\n", p->pnum));
+
+ p->dev = dev;
+ p->free_fn = fn;
+ return True;
+ }
+
+ DEBUG(3,("Error setting policy state\n"));
+
+ return False;
+}
+
+/****************************************************************************
+ get pol state.
+****************************************************************************/
+void *get_policy_state_info(struct policy_cache *cache, const POLICY_HND *hnd)
+{
+ struct policy *p = find_policy(cache, hnd);
+
+ if (p != NULL && p->open)
+ {
+ DEBUG(3, ("policy(pnum=%x %s): Getting policy state\n",
+ p->pnum, pol_get_name(p)));
+ return p->dev;
+ }
+
+ DEBUG(3,("Error getting policy state\n"));
+ return NULL;
+}
+
+/****************************************************************************
+ set the type of the state of a POLICY_HND
+****************************************************************************/
+BOOL policy_hnd_set_state_type(struct policy_cache *cache,
+ POLICY_HND *hnd, int type)
+{
+ struct policy *p = find_policy(cache, hnd);
+
+ if (!p || !p->open)
+ {
+ DEBUG(3, ("Error setting type for policy state\n"));
+ return False;
+ }
+ DEBUG(4, ("policy(pnum=%x %s): setting type to %d\n",
+ p->pnum, pol_get_name(p), type));
+ p->type = type;
+ return True;
+}
+
+/****************************************************************************
+ get the type of the state of a POLICY_HND
+****************************************************************************/
+int policy_hnd_get_state_type(struct policy_cache *cache,
+ const POLICY_HND *hnd)
+{
+ struct policy *p = find_policy(cache, hnd);
+
+ if (!p || !p->open)
+ {
+ DEBUG(3, ("Error getting type for policy state\n"));
+ return -1;
+ }
+ DEBUG(4, ("policy(pnum=%x %s): getting type %d\n",
+ p->pnum, pol_get_name(p), p->type));
+
+ return p->type;
+}
+
+/****************************************************************************
+ check the type of the state of a POLICY_HND
+****************************************************************************/
+BOOL policy_hnd_check_state_type(struct policy_cache *cache,
+ const POLICY_HND *hnd, int type)
+{
+ struct policy *p = find_policy(cache, hnd);
+ BOOL ret;
+
+ if (!p || !p->open)
+ {
+ DEBUG(3, ("Error checking type for policy state\n"));
+ return False;
+ }
+
+ ret = (p->type==type);
+
+ if (ret)
+ {
+ DEBUG(4, ("policy(pnum=%x %s): checking if type %d is %d\n",
+ p->pnum, pol_get_name(p), p->type, type));
+ }
+ else
+ {
+ DEBUG(3, ("policy(pnum=%x %s): type %d is not %d\n",
+ p->pnum, pol_get_name(p), p->type, type));
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ close an lsa policy
+****************************************************************************/
+BOOL close_policy_hnd(struct policy_cache *cache, POLICY_HND *hnd)
+{
+ struct policy *p = find_policy(cache, hnd);
+
+ if (!p)
+ {
+ DEBUG(3,("Error closing policy\n"));
+ return False;
+ }
+
+ DEBUG(3, ("policy(pnum=%x %s): Closing\n", p->pnum, pol_get_name(p)));
+
+ DLIST_REMOVE(cache->Policy, p);
+
+ if (p->free_fn != NULL)
+ {
+ p->free_fn(p->dev);
+ }
+ else
+ {
+ safe_free(p->dev);
+ }
+
+ safe_free(p->name);
+
+ free(p);
+
+ ZERO_STRUCTP(hnd);
+
+ return True;
+}
+
+/****************************************************************************
+ get pol state.
+****************************************************************************/
+BOOL policy_link_key(struct policy_cache *cache, const POLICY_HND *hnd,
+ POLICY_HND *to)
+{
+ struct policy *p = find_policy(cache, hnd);
+ struct policy *pto = find_policy(cache, to);
+
+ if (p != NULL && p->open && pto != NULL && pto->open)
+ {
+ DEBUG(3,("Linking policy key pnum=%x pid=%d vuid=%x\n",
+ p->key.pid, p->key.vuid, p->pnum));
+ pto->key = p->key;
+ return True;
+ }
+
+ DEBUG(3,("Error getting policy link states\n"));
+ return False;
+}
+
+/****************************************************************************
+ get pol state.
+****************************************************************************/
+const vuser_key *get_policy_vuser_key(struct policy_cache *cache,
+ const POLICY_HND *hnd)
+{
+ struct policy *p = find_policy(cache, hnd);
+
+ if (p != NULL && p->open)
+ {
+ DEBUG(3,("Getting policy vuser_key pnum=%x pid=%d vuid=%x\n",
+ p->pnum, p->key.pid, p->key.vuid));
+ return &p->key;
+ }
+
+ DEBUG(3,("Error getting policy state\n"));
+ return NULL;
+}
+
+/****************************************************************************
+ get user session key.
+****************************************************************************/
+BOOL pol_get_usr_sesskey(struct policy_cache *cache, const POLICY_HND *hnd,
+ uchar usr_sess_key[16])
+{
+ const vuser_key *key = get_policy_vuser_key(cache, hnd);
+ user_struct *vuser;
+
+ if (key == NULL || key->vuid == UID_FIELD_INVALID)
+ {
+ memset(usr_sess_key, 0, 16);
+ return True;
+ }
+ vuser = get_valid_user_struct(key);
+ if (vuser == NULL)
+ {
+ DEBUG(10,("pol_get_usr_sesskey: no vuser struct\n"));
+ return False;
+ }
+ memcpy(usr_sess_key, vuser->usr.user_sess_key, 16);
+ vuid_free_user_struct(vuser);
+ return True;
+}
+
diff --git a/source/lib/util_pwdb.c b/source/lib/util_pwdb.c
new file mode 100644
index 00000000000..a319e7c163c
--- /dev/null
+++ b/source/lib/util_pwdb.c
@@ -0,0 +1,393 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Password and authentication handling
+ Copyright (C) Jeremy Allison 1996-1998
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+extern fstring global_myworkgroup;
+
+extern pstring global_myname;
+
+typedef struct
+{
+ uint32 rid;
+ char *defaultname;
+ char *name;
+} rid_name;
+
+/*
+ * A list of the rids of well known BUILTIN and Domain users
+ * and groups.
+ */
+
+static rid_name builtin_alias_rids[] =
+{
+ { BUILTIN_ALIAS_RID_ADMINS , "Administrators" , NULL },
+ { BUILTIN_ALIAS_RID_USERS , "Users" , NULL },
+ { BUILTIN_ALIAS_RID_GUESTS , "Guests" , NULL },
+ { BUILTIN_ALIAS_RID_POWER_USERS , "Power Users" , NULL },
+
+ { BUILTIN_ALIAS_RID_ACCOUNT_OPS , "Account Operators" , NULL },
+ { BUILTIN_ALIAS_RID_SYSTEM_OPS , "System Operators" , NULL },
+ { BUILTIN_ALIAS_RID_PRINT_OPS , "Print Operators" , NULL },
+ { BUILTIN_ALIAS_RID_BACKUP_OPS , "Backup Operators" , NULL },
+ { BUILTIN_ALIAS_RID_REPLICATOR , "Replicator" , NULL },
+ { 0 , NULL , NULL}
+};
+
+/* array lookup of well-known Domain RID users. */
+static rid_name domain_user_rids[] =
+{
+ { DOMAIN_USER_RID_ADMIN , "Administrator" , NULL },
+ { DOMAIN_USER_RID_GUEST , "Guest" , NULL },
+ { 0 , NULL , NULL}
+};
+
+/* array lookup of well-known Domain RID groups. */
+static rid_name domain_group_rids[] =
+{
+ { DOMAIN_GROUP_RID_ADMINS , "Domain Admins" , NULL },
+ { DOMAIN_GROUP_RID_USERS , "Domain Users" , NULL },
+ { DOMAIN_GROUP_RID_GUESTS , "Domain Guests" , NULL },
+ { 0 , NULL , NULL}
+};
+
+/*******************************************************************
+ make an entry in wk name map
+ the name is strdup()ed!
+ *******************************************************************/
+static BOOL make_alias_entry(rid_name *map, char *defaultname, char *name)
+{
+ if(isdigit(*defaultname))
+ {
+ long rid = -1;
+ char *s;
+
+ if(*defaultname == '0')
+ {
+ if(defaultname[1] == 'x')
+ {
+ s = "%lx";
+ defaultname += 2;
+ }
+ else
+ {
+ s = "%lo";
+ }
+ }
+ else
+ {
+ s = "%ld";
+ }
+
+ sscanf(defaultname, s, &rid);
+
+ for( ; map->rid; map++)
+ {
+ if(map->rid == rid) {
+ map->name = strdup(name);
+ DEBUG(5, ("make_alias_entry: mapping %s (rid 0x%x) to %s\n",
+ map->defaultname, map->rid, map->name));
+ return True;
+ }
+ }
+ return False;
+ }
+
+ for( ; map->rid; map++)
+ {
+ if(!StrCaseCmp(map->name, defaultname)) {
+ map->name = strdup(name);
+ DEBUG(5, ("make_alias_entry: mapping %s (rid 0x%x) to %s\n",
+ map->defaultname, map->rid, map->name));
+ return True;
+ }
+ }
+ return False;
+}
+
+/*******************************************************************
+ reset wk map to default values
+ *******************************************************************/
+static void reset_wk_map(rid_name *map)
+{
+ for( ; map->rid; map++)
+ {
+ if(map->name != NULL && map->name != map->defaultname)
+ free(map->name);
+ map->name = map->defaultname;
+ }
+}
+
+/*******************************************************************
+ reset all wk maps
+ *******************************************************************/
+static void reset_wk_maps(void)
+{
+ DEBUG(4, ("reset_wk_maps: Initializing maps\n"));
+ reset_wk_map(builtin_alias_rids);
+ reset_wk_map(domain_user_rids);
+ reset_wk_map(domain_group_rids);
+}
+
+/*******************************************************************
+ Load builtin alias map
+ *******************************************************************/
+static BOOL load_wk_rid_map(void)
+{
+ static int map_initialized = 0;
+ static time_t builtin_rid_file_last_modified = (time_t)0;
+ char *builtin_rid_file = lp_builtinrid_file();
+
+ FILE *fp;
+ char *s;
+ pstring buf;
+
+ if (!map_initialized)
+ {
+ reset_wk_maps();
+ map_initialized = 1;
+ }
+
+ if (!*builtin_rid_file)
+ {
+ return False;
+ }
+
+ fp = open_file_if_modified(builtin_rid_file, "r", &builtin_rid_file_last_modified);
+ if(!fp)
+ {
+ DEBUG(0,("load_wk_rid_map: can't open name map %s. Error was %s\n",
+ builtin_rid_file, strerror(errno)));
+ return False;
+ }
+
+ reset_wk_maps();
+ DEBUG(4,("load_wk_rid_map: Scanning builtin rid map %s\n",builtin_rid_file));
+
+ while ((s = fgets_slash(buf, sizeof(buf), fp)) != NULL)
+ {
+ pstring defaultname;
+ pstring name;
+
+ DEBUG(10,("Read line |%s|\n", s));
+
+ if (!*s || strchr("#;",*s))
+ continue;
+
+ if (!next_token(&s,name, "\t\n\r=", sizeof(defaultname)))
+ continue;
+
+ if (!next_token(&s,defaultname, "\t\n\r=", sizeof(name)))
+ continue;
+
+ trim_string(defaultname, " ", " ");
+ trim_string(name, " ", " ");
+
+ if (!*defaultname || !*name)
+ continue;
+
+ if(make_alias_entry(builtin_alias_rids, defaultname, name))
+ continue;
+ if(make_alias_entry(domain_user_rids, defaultname, name))
+ continue;
+ if(make_alias_entry(domain_group_rids, defaultname, name))
+ continue;
+
+ DEBUG(0,("load_wk_rid_map: Unknown alias %s in map %s\n",
+ defaultname, builtin_rid_file));
+ }
+
+ fclose(fp);
+ return True;
+}
+
+/*******************************************************************
+ lookup_wk_group_name
+ ********************************************************************/
+uint32 lookup_wk_group_name(const char *group_name, const char *domain,
+ DOM_SID *sid, uint32 *type)
+{
+ char *grp_name;
+ int i = -1; /* start do loop at -1 */
+ uint32 rid;
+
+ if (strequal(domain, global_sam_name))
+ {
+ sid_copy(sid, &global_sam_sid);
+ }
+ else if (strequal(domain, "BUILTIN"))
+ {
+ sid_copy(sid, &global_sid_S_1_5_20);
+ }
+ else
+ {
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
+
+ load_wk_rid_map();
+
+ do /* find, if it exists, a group rid for the group name */
+ {
+ i++;
+ rid = domain_group_rids[i].rid;
+ grp_name = domain_group_rids[i].name;
+
+ if (strequal(grp_name, group_name))
+ {
+ sid_append_rid(sid, rid);
+ (*type) = SID_NAME_DOM_GRP;
+
+ return 0x0;
+ }
+
+ } while (grp_name != NULL);
+
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_wk_user_name
+ ********************************************************************/
+uint32 lookup_wk_user_name(const char *user_name, const char *domain,
+ DOM_SID *sid, uint32 *type)
+{
+ char *usr_name;
+ int i = -1; /* start do loop at -1 */
+
+ if (strequal(domain, global_sam_name))
+ {
+ sid_copy(sid, &global_sam_sid);
+ }
+ else if (strequal(domain, "BUILTIN"))
+ {
+ sid_copy(sid, &global_sid_S_1_5_20);
+ }
+ else
+ {
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
+
+ load_wk_rid_map();
+
+ do /* find, if it exists, a alias rid for the alias name */
+ {
+ i++;
+ usr_name = domain_user_rids[i].name;
+
+ } while (usr_name != NULL && !strequal(usr_name, user_name));
+
+ if (usr_name != NULL)
+ {
+ sid_append_rid(sid, domain_user_rids[i].rid);
+ (*type) = SID_NAME_USER;
+ return 0;
+ }
+
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ lookup_builtin_alias_name
+ ********************************************************************/
+uint32 lookup_builtin_alias_name(const char *alias_name, const char *domain,
+ DOM_SID *sid, uint32 *type)
+{
+ char *als_name;
+ int i = 0;
+ uint32 rid;
+
+ if (strequal(domain, "BUILTIN"))
+ {
+ if (sid != NULL)
+ {
+ sid_copy(sid, &global_sid_S_1_5_20);
+ }
+ }
+ else
+ {
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
+
+ load_wk_rid_map();
+
+ do /* find, if it exists, a alias rid for the alias name*/
+ {
+ rid = builtin_alias_rids[i].rid;
+ als_name = builtin_alias_rids[i].name;
+
+ if (strequal(als_name, alias_name))
+ {
+ if (sid != NULL)
+ {
+ sid_append_rid(sid, rid);
+ }
+
+ if (type != NULL)
+ {
+ (*type) = SID_NAME_ALIAS;
+ }
+
+ return 0x0;
+ }
+
+ i++;
+
+ } while (als_name != NULL);
+
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+}
+
+/*************************************************************
+ the following functions lookup wk rid's.
+ these may be unnecessary...
+**************************************************************/
+static char *lookup_wk_rid(uint32 rid, rid_name *table)
+{
+ load_wk_rid_map();
+ for( ; table->rid ; table++)
+ {
+ if(table->rid == rid)
+ {
+ return table->name;
+ }
+ }
+ return NULL;
+}
+
+char *lookup_wk_alias_rid(uint32 rid)
+{
+ return lookup_wk_rid(rid, builtin_alias_rids);
+}
+
+char *lookup_wk_user_rid(uint32 rid)
+{
+ return lookup_wk_rid(rid, domain_user_rids);
+}
+
+char *lookup_wk_group_rid(uint32 rid)
+{
+ return lookup_wk_rid(rid, domain_group_rids);
+}
diff --git a/source/lib/util_seaccess.c b/source/lib/util_seaccess.c
new file mode 100644
index 00000000000..fba48d3c84d
--- /dev/null
+++ b/source/lib/util_seaccess.c
@@ -0,0 +1,277 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+static uint32 acegrant(uint32 mask, uint32 *acc_req, uint32 *acc_grant, uint32 *acc_deny)
+{
+ /* maximum allowed: grant what's in the ace */
+ if ((*acc_req) == SEC_RIGHTS_MAXIMUM_ALLOWED)
+ {
+ (*acc_grant) |= mask & ~(*acc_deny);
+ }
+ else
+ {
+ (*acc_grant) |= (*acc_req) & mask;
+ (*acc_req) &= ~(*acc_grant);
+ }
+ if ((*acc_req) == 0x0)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ return NT_STATUS_NOPROBLEMO;
+}
+
+static uint32 acedeny(uint32 mask, uint32 *acc_req, uint32 *acc_grant, uint32 *acc_deny)
+{
+ /* maximum allowed: grant what's in the ace */
+ if ((*acc_req) == SEC_RIGHTS_MAXIMUM_ALLOWED)
+ {
+ (*acc_deny) |= mask & ~(*acc_grant);
+ }
+ else
+ {
+ if ((*acc_req) & mask)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+#if 0
+ (*acc_deny) |= (*acc_req) & mask;
+ (*acc_req) &= ~(*acc_deny);
+#endif
+ }
+ if ((*acc_req) == 0x0)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ return NT_STATUS_NOPROBLEMO;
+}
+
+static BOOL check_ace(const SEC_ACE *ace, BOOL is_owner,
+ const DOM_SID *sid,
+ uint32 *acc_req,
+ uint32 *acc_grant,
+ uint32 *acc_deny,
+ uint32 *status)
+{
+ uint32 mask = ace->info.mask;
+
+ if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY)
+ {
+ /* inherit only is ignored */
+ return False;
+ }
+
+ /* only owner allowed write-owner rights */
+ if (!is_owner)
+ {
+ mask &= (~SEC_RIGHTS_WRITE_OWNER);
+ }
+
+ switch (ace->type)
+ {
+ case SEC_ACE_TYPE_ACCESS_ALLOWED:
+ {
+ /* everyone - or us */
+ if (sid_equal(&ace->sid, &global_sid_S_1_1_0) ||
+ sid_equal(&ace->sid, sid))
+ {
+ (*status) = acegrant(mask, acc_req, acc_grant, acc_deny);
+ if ((*status) != NT_STATUS_NOPROBLEMO)
+ {
+ return True;
+ }
+
+ }
+ break;
+ }
+ case SEC_ACE_TYPE_ACCESS_DENIED:
+ {
+ /* everyone - or us */
+ if (sid_equal(&ace->sid, &global_sid_S_1_1_0) ||
+ sid_equal(&ace->sid, sid))
+ {
+ (*status) = acedeny(mask, acc_req, acc_grant, acc_deny);
+ if ((*status) != NT_STATUS_NOPROBLEMO)
+ {
+ return True;
+ }
+ }
+ break;
+ }
+ case SEC_ACE_TYPE_SYSTEM_AUDIT:
+ {
+ (*status) = NT_STATUS_NOT_IMPLEMENTED;
+ return True;
+ }
+ case SEC_ACE_TYPE_SYSTEM_ALARM:
+ {
+ (*status) = NT_STATUS_NOT_IMPLEMENTED;
+ return True;
+ }
+ default:
+ {
+ (*status) = NT_STATUS_INVALID_PARAMETER;
+ return True;
+ }
+ }
+ return False;
+}
+
+/***********************************************************************
+ checks access_requested rights of user against sd. returns access granted
+ and a status code if the grant succeeded, error message if it failed.
+
+ the previously_granted access rights requires some explanation: if you
+ open a policy handle with a set of permissions, you cannot then perform
+ operations that require more privileges than those requested. pass in
+ the [previously granted] permissions from the open_policy_hnd call as
+ prev_grant_acc, and this function will do the checking for you.
+ ***********************************************************************/
+BOOL se_access_check(const SEC_DESC * sd, const NET_USER_INFO_3 * user,
+ uint32 acc_req, uint32 prev_grant_acc,
+ uint32 * acc_grant,
+ uint32 * status)
+{
+ int num_aces;
+ int num_groups;
+ DOM_SID usr_sid;
+ DOM_SID grp_sid;
+ DOM_SID **grp_sids = NULL;
+ uint32 ngrp_sids = 0;
+ BOOL is_owner;
+ BOOL is_system;
+ const SEC_ACL *acl = NULL;
+ uint32 grnt;
+ uint32 deny;
+
+ if (status == NULL)
+ {
+ return False;
+ }
+
+ if (prev_grant_acc == SEC_RIGHTS_MAXIMUM_ALLOWED)
+ {
+ prev_grant_acc = 0xffffffff;
+ }
+
+ /* cannot request any more than previously requested access */
+ acc_req &= prev_grant_acc;
+
+ if (acc_req == 0x0)
+ {
+ (*status) = NT_STATUS_ACCESS_DENIED;
+ return False;
+ }
+
+ /* we must know the owner sid */
+ if (sd->owner_sid == NULL)
+ {
+ return False;
+ }
+
+ (*status) = NT_STATUS_NOPROBLEMO;
+
+ /* create user sid */
+ sid_copy(&grp_sid, &user->dom_sid.sid);
+ sid_append_rid(&grp_sid, user->group_id);
+
+ /* create group sid */
+ sid_copy(&usr_sid, &user->dom_sid.sid);
+ sid_append_rid(&usr_sid, user->user_id);
+
+ /* preparation: check owner sid, create array of group sids */
+ is_owner = sid_equal(&usr_sid, sd->owner_sid);
+ add_sid_to_array(&ngrp_sids, &grp_sids, &grp_sid);
+
+ for (num_groups = 0; num_groups < user->num_groups; num_groups++)
+ {
+ sid_copy(&grp_sid, &user->dom_sid.sid);
+ sid_append_rid(&grp_sid, user->gids[num_groups].g_rid);
+ add_sid_to_array(&ngrp_sids, &grp_sids, &grp_sid);
+ }
+
+ /* check for system acl or user (discretionary) acl */
+ is_system = sid_equal(&usr_sid, &global_sid_system);
+ if (is_system)
+ {
+ acl = sd->sacl;
+ }
+ else
+ {
+ acl = sd->dacl;
+ }
+
+ /* acl must have something in it */
+ if (acl == NULL || acl->ace == NULL || acl->num_aces == 0)
+ {
+ return False;
+ }
+
+ /*
+ * OK! we have an ACE, it has at least one thing in it,
+ * we have a user sid, we have an array of group sids.
+ * let's go!
+ */
+
+ deny = 0;
+ grnt = 0;
+
+ /* check each ace */
+ for (num_aces = 0; num_aces < acl->num_aces; num_aces++)
+ {
+ const SEC_ACE *ace = &acl->ace[num_aces];
+
+ /* first check the user sid */
+ if (check_ace(ace, is_owner, &usr_sid, &acc_req,
+ &grnt, &deny, status))
+ {
+ free_sid_array(ngrp_sids, grp_sids);
+ return (*status) != NT_STATUS_NOPROBLEMO;
+ }
+ /* now check the group sids */
+ for (num_groups = 0; num_groups < ngrp_sids; num_groups++)
+ {
+ if (check_ace(ace, False, grp_sids[num_groups],
+ &acc_req, &grnt, &deny, status))
+ {
+ free_sid_array(ngrp_sids, grp_sids);
+ return (*status) != NT_STATUS_NOPROBLEMO;
+ }
+ }
+ }
+
+ if (grnt == 0x0 && (*status) == NT_STATUS_NOPROBLEMO)
+ {
+ (*status) = NT_STATUS_ACCESS_DENIED;
+ }
+ else if (acc_grant != NULL)
+ {
+ (*acc_grant) = grnt;
+ }
+
+ free_sid_array(ngrp_sids, grp_sids);
+ return (*status) != NT_STATUS_NOPROBLEMO;
+}
+
diff --git a/source/lib/util_sec.c b/source/lib/util_sec.c
index 4306a94191d..4a2ac2565e6 100644
--- a/source/lib/util_sec.c
+++ b/source/lib/util_sec.c
@@ -30,8 +30,6 @@ extern int DEBUGLEVEL;
#endif
#include <stdlib.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <errno.h>
#ifdef HAVE_SYS_PRIV_H
#include <sys/priv.h>
@@ -203,21 +201,9 @@ void save_re_uid(void)
void restore_re_uid(void)
{
set_effective_uid(0);
-
-#if USE_SETRESUID
- setresuid(saved_ruid, saved_euid, -1);
-#elif USE_SETREUID
- setreuid(saved_ruid, -1);
- setreuid(-1,saved_euid);
-#elif USE_SETUIDX
- setuidx(ID_REAL, saved_ruid);
- setuidx(ID_EFFECTIVE, saved_euid);
-#else
set_effective_uid(saved_euid);
- if (getuid() != saved_ruid)
- setuid(saved_ruid);
+ if (getuid() != saved_ruid) setuid(saved_ruid);
set_effective_uid(saved_euid);
-#endif
assert_uid(saved_ruid, saved_euid);
}
@@ -305,35 +291,6 @@ void become_user_permanently(uid_t uid, gid_t gid)
assert_gid(gid, gid);
}
-
-/****************************************************************************
-this function just checks that we don't get ENOSYS back
-****************************************************************************/
-static int have_syscall(void)
-{
- errno = 0;
-
-#if USE_SETRESUID
- setresuid(-1,-1,-1);
-#endif
-
-#if USE_SETREUID
- setreuid(-1,-1);
-#endif
-
-#if USE_SETEUID
- seteuid(-1);
-#endif
-
-#if USE_SETUIDX
- setuidx(ID_EFFECTIVE, -1);
-#endif
-
- if (errno == ENOSYS) return -1;
-
- return 0;
-}
-
#ifdef AUTOCONF_TEST
main()
{
@@ -344,18 +301,15 @@ main()
exit(1);
#endif
- /* if not running as root then at least check to see if we get ENOSYS - this
- handles Linux 2.0.x with glibc 2.1 */
- fprintf(stderr,"not running as root: checking for ENOSYS\n");
- exit(have_syscall());
+ /* assume that if we have the functions then they work */
+ fprintf(stderr,"not running as root: assuming OK\n");
+ exit(0);
}
gain_root_privilege();
gain_root_group_privilege();
set_effective_gid(1);
set_effective_uid(1);
- save_re_uid();
- restore_re_uid();
gain_root_privilege();
gain_root_group_privilege();
become_user_permanently(1, 1);
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index f2f7b3c8ae1..b0a82877146 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -3,8 +3,6 @@
Version 1.9.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
- Copyright (C) Jeremy Allison 1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,206 +23,13 @@
extern int DEBUGLEVEL;
-DOM_SID global_sam_sid;
-extern pstring global_myname;
-extern fstring global_myworkgroup;
-
-/*
- * Some useful sids
- */
-
-DOM_SID global_sid_S_1_5_0x20; /* local well-known domain */
-DOM_SID global_sid_World_Domain; /* everyone */
-DOM_SID global_sid_World; /* everyone */
-DOM_SID global_sid_Creator_Owner_Domain; /* Creator Owner */
-DOM_SID global_sid_Creator_Owner; /* Creator Owner */
-DOM_SID global_sid_NT_Authority; /* NT Authority */
-
-typedef struct _known_sid_users {
- uint32 rid;
- uint8 sid_name_use;
- char *known_user_name;
-} known_sid_users;
-
-/* static known_sid_users no_users[] = {{0, 0, NULL}}; */
-static known_sid_users everyone_users[] = {{ 0, SID_NAME_WKN_GRP, "Everyone" }, {0, 0, NULL}};
-static known_sid_users creator_owner_users[] = {{ 0, SID_NAME_ALIAS, "Creator Owner" }, {0, 0, NULL}};
-static known_sid_users nt_authority_users[] = {{ 1, SID_NAME_ALIAS, "Dialup" },
- { 2, SID_NAME_ALIAS, "Network"},
- { 3, SID_NAME_ALIAS, "Batch"},
- { 4, SID_NAME_ALIAS, "Interactive"},
- { 6, SID_NAME_ALIAS, "Service"},
- { 7, SID_NAME_ALIAS, "AnonymousLogon"},
- { 8, SID_NAME_ALIAS, "Proxy"},
- { 9, SID_NAME_ALIAS, "ServerLogon"},
- {0, 0, NULL}};
-
-static struct sid_name_map_info
-{
- DOM_SID *sid;
- char *name;
- known_sid_users *known_users;
-}
-sid_name_map[] =
-{
- { &global_sam_sid, global_myname, NULL},
- { &global_sam_sid, global_myworkgroup, NULL},
- { &global_sid_S_1_5_0x20, "BUILTIN", NULL},
- { &global_sid_World_Domain, "", &everyone_users[0] },
- { &global_sid_Creator_Owner_Domain, "", &creator_owner_users[0] },
- { &global_sid_NT_Authority, "NT Authority", &nt_authority_users[0] },
- { NULL, NULL, NULL}
-};
-
-/****************************************************************************
- Creates some useful well known sids
-****************************************************************************/
-
-void generate_wellknown_sids(void)
-{
- string_to_sid(&global_sid_S_1_5_0x20, "S-1-5-32");
- string_to_sid(&global_sid_World_Domain, "S-1-1");
- string_to_sid(&global_sid_World, "S-1-1-0");
- string_to_sid(&global_sid_Creator_Owner_Domain, "S-1-3");
- string_to_sid(&global_sid_Creator_Owner, "S-1-3-0");
- string_to_sid(&global_sid_NT_Authority, "S-1-5");
-}
-
-/**************************************************************************
- Turns a domain SID into a name, returned in the nt_domain argument.
-***************************************************************************/
-
-BOOL map_domain_sid_to_name(DOM_SID *sid, char *nt_domain)
-{
- fstring sid_str;
- int i = 0;
- sid_to_string(sid_str, sid);
-
- DEBUG(5,("map_domain_sid_to_name: %s\n", sid_str));
-
- if (nt_domain == NULL)
- return False;
-
- while (sid_name_map[i].sid != NULL) {
- sid_to_string(sid_str, sid_name_map[i].sid);
- DEBUG(5,("map_domain_sid_to_name: compare: %s\n", sid_str));
- if (sid_equal(sid_name_map[i].sid, sid)) {
- fstrcpy(nt_domain, sid_name_map[i].name);
- DEBUG(5,("map_domain_sid_to_name: found '%s'\n", nt_domain));
- return True;
- }
- i++;
- }
- DEBUG(5,("map_domain_sid_to_name: mapping for %s not found\n", sid_str));
-
- return False;
-}
-
-/**************************************************************************
- Looks up a known username from one of the known domains.
-***************************************************************************/
-
-BOOL lookup_known_rid(DOM_SID *sid, uint32 rid, char *name, uint8 *psid_name_use)
-{
- int i = 0;
- struct sid_name_map_info *psnm;
-
- for(i = 0; sid_name_map[i].sid != NULL; i++) {
- psnm = &sid_name_map[i];
- if(sid_equal(psnm->sid, sid)) {
- int j;
- for(j = 0; psnm->known_users && psnm->known_users[j].known_user_name != NULL; j++) {
- if(rid == psnm->known_users[j].rid) {
- DEBUG(5,("lookup_builtin_rid: rid = %u, domain = '%s', user = '%s'\n",
- (unsigned int)rid, psnm->name, psnm->known_users[j].known_user_name ));
- fstrcpy( name, psnm->known_users[j].known_user_name);
- *psid_name_use = psnm->known_users[j].sid_name_use;
- return True;
- }
- }
- }
- }
-
- return False;
-}
-
-/**************************************************************************
- Turns a domain name into a SID.
- *** side-effect: if the domain name is NULL, it is set to our domain ***
-***************************************************************************/
-
-BOOL map_domain_name_to_sid(DOM_SID *sid, char *nt_domain)
-{
- int i = 0;
-
- if (nt_domain == NULL) {
- DEBUG(5,("map_domain_name_to_sid: mapping NULL domain to our SID.\n"));
- sid_copy(sid, &global_sam_sid);
- return True;
- }
-
- if (nt_domain[0] == 0) {
- fstrcpy(nt_domain, global_myname);
- DEBUG(5,("map_domain_name_to_sid: overriding blank name to %s\n", nt_domain));
- sid_copy(sid, &global_sam_sid);
- return True;
- }
-
- DEBUG(5,("map_domain_name_to_sid: %s\n", nt_domain));
-
- while (sid_name_map[i].name != NULL) {
- DEBUG(5,("map_domain_name_to_sid: compare: %s\n", sid_name_map[i].name));
- if (strequal(sid_name_map[i].name, nt_domain)) {
- fstring sid_str;
- sid_copy(sid, sid_name_map[i].sid);
- sid_to_string(sid_str, sid_name_map[i].sid);
- DEBUG(5,("map_domain_name_to_sid: found %s\n", sid_str));
- return True;
- }
- i++;
- }
-
- DEBUG(0,("map_domain_name_to_sid: mapping to %s not found.\n", nt_domain));
- return False;
-}
-
-/**************************************************************************
- Splits a name of format \DOMAIN\name or name into its two components.
- Sets the DOMAIN name to global_myname if it has not been specified.
-***************************************************************************/
-
-void split_domain_name(const char *fullname, char *domain, char *name)
-{
- pstring full_name;
- char *p;
-
- *domain = *name = '\0';
-
- if (fullname[0] == '\\')
- fullname++;
-
- pstrcpy(full_name, fullname);
- p = strchr(full_name+1, '\\');
-
- if (p != NULL) {
- *p = 0;
- fstrcpy(domain, full_name);
- fstrcpy(name, p+1);
- } else {
- fstrcpy(domain, global_myname);
- fstrcpy(name, full_name);
- }
-
- DEBUG(10,("split_domain_name:name '%s' split into domain :'%s' and user :'%s'\n",
- fullname, domain, name));
-}
/*****************************************************************
Convert a SID to an ascii string.
*****************************************************************/
-char *sid_to_string(fstring sidstr_out, DOM_SID *sid)
+char *sid_to_string(pstring sidstr_out, const DOM_SID *sid)
{
char subauth[16];
int i;
@@ -234,11 +39,12 @@ char *sid_to_string(fstring sidstr_out, DOM_SID *sid)
(sid->id_auth[3] << 16) +
(sid->id_auth[2] << 24);
- slprintf(sidstr_out, sizeof(fstring) - 1, "S-%u-%lu", (unsigned int)sid->sid_rev_num, (unsigned long)ia);
+ slprintf(sidstr_out, sizeof(pstring) - 1, "S-%u-%lu", (unsigned int)sid->sid_rev_num, (unsigned long)ia);
- for (i = 0; i < sid->num_auths; i++) {
+ for (i = 0; i < sid->num_auths; i++)
+ {
slprintf(subauth, sizeof(subauth)-1, "-%lu", (unsigned long)sid->sub_auths[i]);
- fstrcat(sidstr_out, subauth);
+ pstrcat(sidstr_out, subauth);
}
DEBUG(7,("sid_to_string returning %s\n", sidstr_out));
@@ -249,68 +55,72 @@ char *sid_to_string(fstring sidstr_out, DOM_SID *sid)
Convert a string to a SID. Returns True on success, False on fail.
*****************************************************************/
-BOOL string_to_sid(DOM_SID *sidout, char *sidstr)
+BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
{
- pstring tok;
- char *p = sidstr;
- /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
- uint32 ia;
+ const char *p = sidstr;
+ /* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
+ uint32 ia;
- memset((char *)sidout, '\0', sizeof(DOM_SID));
+ memset((char *)sidout, '\0', sizeof(DOM_SID));
- if (StrnCaseCmp( sidstr, "S-", 2)) {
- DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
- return False;
- }
+ if (StrnCaseCmp( sidstr, "S-", 2))
+ {
+ DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
+ return False;
+ }
- p += 2;
- if (!next_token(&p, tok, "-", sizeof(tok))) {
- DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
- return False;
- }
+ if ((p = strchr(p, '-')) == NULL)
+ {
+ DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+ return False;
+ }
- /* Get the revision number. */
- sidout->sid_rev_num = (uint8)strtoul(tok, NULL, 10);
+ p++;
- if (!next_token(&p, tok, "-", sizeof(tok))) {
- DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
- return False;
- }
+ /* Get the revision number. */
+ sidout->sid_rev_num = (uint8)strtoul(p,NULL,10);
- /* identauth in decimal should be < 2^32 */
- ia = (uint32)strtoul(tok, NULL, 10);
-
- /* NOTE - the ia value is in big-endian format. */
- sidout->id_auth[0] = 0;
- sidout->id_auth[1] = 0;
- sidout->id_auth[2] = (ia & 0xff000000) >> 24;
- sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
- sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
- sidout->id_auth[5] = (ia & 0x000000ff);
-
- sidout->num_auths = 0;
-
- while(next_token(&p, tok, "-", sizeof(tok)) &&
- sidout->num_auths < MAXSUBAUTHS) {
- /*
- * NOTE - the subauths are in native machine-endian format. They
- * are converted to little-endian when linearized onto the wire.
- */
- sid_append_rid(sidout, (uint32)strtoul(tok, NULL, 10));
- }
+ if ((p = strchr(p, '-')) == NULL)
+ {
+ DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
+ return False;
+ }
- DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
+ p++;
- return True;
+ /* identauth in decimal should be < 2^32 */
+ ia = (uint32)strtoul(p,NULL,10);
+
+ /* NOTE - the ia value is in big-endian format. */
+ sidout->id_auth[0] = 0;
+ sidout->id_auth[1] = 0;
+ sidout->id_auth[2] = (ia & 0xff000000) >> 24;
+ sidout->id_auth[3] = (ia & 0x00ff0000) >> 16;
+ sidout->id_auth[4] = (ia & 0x0000ff00) >> 8;
+ sidout->id_auth[5] = (ia & 0x000000ff);
+
+ sidout->num_auths = 0;
+
+ while (((p = strchr(p, '-')) != NULL) && sidout->num_auths < MAXSUBAUTHS)
+ {
+ p++;
+ /*
+ * NOTE - the subauths are in native machine-endian format. They
+ * are converted to little-endian when linearized onto the wire.
+ */
+ sid_append_rid(sidout, (uint32)strtoul(p, NULL, 10));
+ }
+
+ return True;
}
/*****************************************************************
- Add a rid to the end of a sid
+ add a rid to the end of a sid
*****************************************************************/
-
BOOL sid_append_rid(DOM_SID *sid, uint32 rid)
{
- if (sid->num_auths < MAXSUBAUTHS) {
+ if (sid->num_auths < MAXSUBAUTHS)
+ {
sid->sub_auths[sid->num_auths++] = rid;
return True;
}
@@ -318,113 +128,129 @@ BOOL sid_append_rid(DOM_SID *sid, uint32 rid)
}
/*****************************************************************
- Removes the last rid from the end of a sid
+ removes the last rid from the end of a sid
*****************************************************************/
-
BOOL sid_split_rid(DOM_SID *sid, uint32 *rid)
{
- if (sid->num_auths > 0) {
+ if (sid->num_auths > 0)
+ {
sid->num_auths--;
- *rid = sid->sub_auths[sid->num_auths];
+ if (rid != NULL)
+ {
+ (*rid) = sid->sub_auths[sid->num_auths];
+ }
return True;
}
return False;
}
/*****************************************************************
- Copies a sid
+ copies a sid
*****************************************************************/
-
-void sid_copy(DOM_SID *dst, const DOM_SID *src)
+void sid_copy(DOM_SID *sid1, const DOM_SID *sid2)
{
int i;
- dst->sid_rev_num = src->sid_rev_num;
- dst->num_auths = src->num_auths;
-
- memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth));
-
- for (i = 0; i < src->num_auths; i++)
- dst->sub_auths[i] = src->sub_auths[i];
-}
-
-/*****************************************************************
- Duplicates a sid - mallocs the target.
-*****************************************************************/
-
-DOM_SID *sid_dup(DOM_SID *src)
-{
- DOM_SID *dst;
-
- if(!src)
- return NULL;
+ for (i = 0; i < 6; i++)
+ {
+ sid1->id_auth[i] = sid2->id_auth[i];
+ }
- if((dst = malloc(sizeof(DOM_SID))) != NULL) {
- memset(dst, '\0', sizeof(DOM_SID));
- sid_copy( dst, src);
- }
+ for (i = 0; i < sid2->num_auths; i++)
+ {
+ sid1->sub_auths[i] = sid2->sub_auths[i];
+ }
- return dst;
+ sid1->num_auths = sid2->num_auths;
+ sid1->sid_rev_num = sid2->sid_rev_num;
}
/*****************************************************************
- Write a sid out into on-the-wire format.
+ compare two sids up to the auths of the first sid
*****************************************************************/
-
-BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid)
+BOOL sid_front_equal(const DOM_SID *sid1, const DOM_SID *sid2)
{
- size_t i;
+ int i;
- if(len < sid_size(sid))
- return False;
+ /* compare most likely different rids, first: i.e start at end */
+ for (i = sid1->num_auths-1; i >= 0; --i)
+ {
+ if (sid1->sub_auths[i] != sid2->sub_auths[i]) return False;
+ }
+
+ if (sid1->num_auths > sid2->num_auths ) return False;
+ if (sid1->sid_rev_num != sid2->sid_rev_num) return False;
- SCVAL(outbuf,0,sid->sid_rev_num);
- SCVAL(outbuf,1,sid->num_auths);
- memcpy(&outbuf[2], sid->id_auth, 6);
- for(i = 0; i < sid->num_auths; i++)
- SIVAL(outbuf, 8 + (i*4), sid->sub_auths[i]);
+ for (i = 0; i < 6; i++)
+ {
+ if (sid1->id_auth[i] != sid2->id_auth[i]) return False;
+ }
return True;
}
/*****************************************************************
- Compare two sids.
+ compare two sids
*****************************************************************/
-
-BOOL sid_equal(DOM_SID *sid1, DOM_SID *sid2)
+BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
{
int i;
/* compare most likely different rids, first: i.e start at end */
for (i = sid1->num_auths-1; i >= 0; --i)
- if (sid1->sub_auths[i] != sid2->sub_auths[i])
- return False;
+ {
+ if (sid1->sub_auths[i] != sid2->sub_auths[i]) return False;
+ }
- if (sid1->num_auths != sid2->num_auths)
- return False;
- if (sid1->sid_rev_num != sid2->sid_rev_num)
- return False;
+ if (sid1->num_auths != sid2->num_auths ) return False;
+ if (sid1->sid_rev_num != sid2->sid_rev_num) return False;
for (i = 0; i < 6; i++)
- if (sid1->id_auth[i] != sid2->id_auth[i])
- return False;
+ {
+ if (sid1->id_auth[i] != sid2->id_auth[i]) return False;
+ }
return True;
}
/*****************************************************************
- Calculates size of a sid.
+ calculates size of a sid
*****************************************************************/
-
-size_t sid_size(DOM_SID *sid)
+int sid_size(const DOM_SID *sid)
{
if (sid == NULL)
+ {
return 0;
-
+ }
return sid->num_auths * sizeof(uint32) + 8;
}
+
+/*****************************************************************
+ Duplicates a sid - mallocs the target.
+*****************************************************************/
+
+DOM_SID *sid_dup(const DOM_SID *src)
+{
+ DOM_SID *dst;
+
+ if(!src)
+ return NULL;
+
+ if((dst = (DOM_SID*)malloc(sizeof(DOM_SID))) != NULL) {
+ memset(dst, '\0', sizeof(DOM_SID));
+ sid_copy( dst, src);
+ }
+
+ return dst;
+}
+
+
+/****************************************************************************
+ Read a SID from a file.
+****************************************************************************/
+
static BOOL read_sid_from_file(int fd, char *sid_file, DOM_SID *sid)
{
fstring fline;
@@ -449,7 +275,7 @@ static BOOL read_sid_from_file(int fd, char *sid_file, DOM_SID *sid)
}
sid_to_string(sid_str, sid);
- DEBUG(5,("read_sid_from_file: sid %s\n", sid_str));
+ DEBUG(5,("read_sid_from_file %s: sid %s\n", sid_file, sid_str));
return True;
}
@@ -458,7 +284,7 @@ static BOOL read_sid_from_file(int fd, char *sid_file, DOM_SID *sid)
Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
****************************************************************************/
-BOOL read_sid(char *sam_name, DOM_SID *sid)
+BOOL read_sid(char *domain_name, DOM_SID *sid)
{
int fd;
char *p;
@@ -468,7 +294,7 @@ BOOL read_sid(char *sam_name, DOM_SID *sid)
pstrcpy(sid_file, lp_smb_passwd_file());
- DEBUG(10,("read_sid: Domain: %s\n", sam_name));
+ DEBUG(10,("read_sid: Domain: %s\n", domain_name));
if (sid_file[0] == 0)
{
@@ -492,7 +318,7 @@ BOOL read_sid(char *sam_name, DOM_SID *sid)
}
}
- slprintf(file_name, sizeof(file_name)-1, "%s.SID", sam_name);
+ slprintf(file_name, sizeof(file_name)-1, "%s.SID", domain_name);
strupper(file_name);
pstrcat(sid_file, file_name);
@@ -539,7 +365,7 @@ BOOL read_sid(char *sam_name, DOM_SID *sid)
Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
****************************************************************************/
-BOOL write_sid(char *sam_name, DOM_SID *sid)
+BOOL write_sid(char *domain_name, DOM_SID *sid)
{
int fd;
char *p;
@@ -551,7 +377,7 @@ BOOL write_sid(char *sam_name, DOM_SID *sid)
pstrcpy(sid_file, lp_smb_passwd_file());
sid_to_string(sid_string, sid);
- DEBUG(10,("write_sid: Domain: %s SID: %s\n", sam_name, sid_string));
+ DEBUG(10,("write_sid: Domain: %s SID: %s\n", domain_name, sid_string));
fstrcat(sid_string, "\n");
if (sid_file[0] == 0)
@@ -574,7 +400,7 @@ BOOL write_sid(char *sam_name, DOM_SID *sid)
}
}
- slprintf(file_name, sizeof(file_name)-1, "%s.SID", sam_name);
+ slprintf(file_name, sizeof(file_name)-1, "%s.SID", domain_name);
strupper(file_name);
pstrcat(sid_file, file_name);
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index fd5ed71c9cc..5a77a003485 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -35,18 +35,22 @@ BOOL passive = False;
/* the client file descriptor */
int Client = -1;
+/* the port, where client connected */
+int ClientPort = 0;
+
/* the last IP received from */
struct in_addr lastip;
/* the last port received from */
int lastport=0;
+
int smb_read_error = 0;
+
/****************************************************************************
- Determine if a file descriptor is in fact a socket.
+determine if a file descriptor is in fact a socket
****************************************************************************/
-
BOOL is_a_socket(int fd)
{
int v,l;
@@ -54,6 +58,7 @@ BOOL is_a_socket(int fd)
return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
}
+
enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
struct
@@ -76,9 +81,6 @@ struct
#ifdef IPTOS_THROUGHPUT
{"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON},
#endif
-#ifdef SO_REUSEPORT
- {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL},
-#endif
#ifdef SO_SNDBUF
{"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT},
#endif
@@ -99,63 +101,69 @@ struct
#endif
{NULL,0,0,0,0}};
+
+
/****************************************************************************
- Set user socket options.
+set user socket options
****************************************************************************/
-
void set_socket_options(int fd, char *options)
{
- fstring tok;
-
- while (next_token(&options,tok," \t,", sizeof(tok))) {
- int ret=0,i;
- int value = 1;
- char *p;
- BOOL got_value = False;
-
- if ((p = strchr(tok,'='))) {
- *p = 0;
- value = atoi(p+1);
- got_value = True;
- }
+ fstring tok;
- for (i=0;socket_options[i].name;i++)
- if (strequal(socket_options[i].name,tok))
- break;
+ while (next_token(&options,tok," \t,", sizeof(tok)))
+ {
+ int ret=0,i;
+ int value = 1;
+ char *p;
+ BOOL got_value = False;
- if (!socket_options[i].name) {
- DEBUG(0,("Unknown socket option %s\n",tok));
- continue;
- }
+ if ((p = strchr(tok,'=')))
+ {
+ *p = 0;
+ value = atoi(p+1);
+ got_value = True;
+ }
- switch (socket_options[i].opttype) {
- case OPT_BOOL:
- case OPT_INT:
- ret = setsockopt(fd,socket_options[i].level,
- socket_options[i].option,(char *)&value,sizeof(int));
- break;
-
- case OPT_ON:
- if (got_value)
- DEBUG(0,("syntax error - %s does not take a value\n",tok));
-
- {
- int on = socket_options[i].value;
- ret = setsockopt(fd,socket_options[i].level,
- socket_options[i].option,(char *)&on,sizeof(int));
- }
- break;
- }
-
- if (ret != 0)
- DEBUG(0,("Failed to set socket option %s (Error %s)\n",tok, strerror(errno) ));
+ for (i=0;socket_options[i].name;i++)
+ if (strequal(socket_options[i].name,tok))
+ break;
+
+ if (!socket_options[i].name)
+ {
+ DEBUG(0,("Unknown socket option %s\n",tok));
+ continue;
+ }
+
+ switch (socket_options[i].opttype)
+ {
+ case OPT_BOOL:
+ case OPT_INT:
+ ret = setsockopt(fd,socket_options[i].level,
+ socket_options[i].option,(char *)&value,sizeof(int));
+ break;
+
+ case OPT_ON:
+ if (got_value)
+ DEBUG(0,("syntax error - %s does not take a value\n",tok));
+
+ {
+ int on = socket_options[i].value;
+ ret = setsockopt(fd,socket_options[i].level,
+ socket_options[i].option,(char *)&on,sizeof(int));
+ }
+ break;
}
+
+ if (ret != 0)
+ DEBUG(0,("Failed to set socket option %s\n",tok));
+ }
}
+
+
/****************************************************************************
- Close the socket communication.
+ close the socket communication
****************************************************************************/
-
void close_sockets(void )
{
#ifdef WITH_SSL
@@ -166,10 +174,31 @@ void close_sockets(void )
Client = -1;
}
+
+
/****************************************************************************
- Read from a socket.
+write to a socket
****************************************************************************/
+ssize_t write_socket(int fd,char *buf,size_t len)
+{
+ ssize_t ret=0;
+ if (passive)
+ return(len);
+ DEBUG(6,("write_socket(%d,%d)\n",fd,len));
+ ret = write_data(fd,buf,len);
+
+ DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,len,ret));
+ if(ret <= 0)
+ DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
+ len, fd, strerror(errno) ));
+
+ return(ret);
+}
+
+/****************************************************************************
+read from a socket
+****************************************************************************/
ssize_t read_udp_socket(int fd,char *buf,size_t len)
{
ssize_t ret;
@@ -177,8 +206,8 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len)
int socklen;
socklen = sizeof(sock);
- memset((char *)&sock,'\0',socklen);
- memset((char *)&lastip,'\0',sizeof(lastip));
+ bzero((char *)&sock,socklen);
+ bzero((char *)&lastip,sizeof(lastip));
ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
if (ret <= 0) {
DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
@@ -195,13 +224,13 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len)
}
/****************************************************************************
- Read data from a socket with a timout in msec.
- mincount = if timeout, minimum to read before returning
- maxcount = number to be read.
- time_out = timeout in milliseconds
+read data from a device with a timout in msec.
+mincount = if timeout, minimum to read before returning
+maxcount = number to be read.
+time_out = timeout in milliseconds
****************************************************************************/
-static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
+ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
{
fd_set fds;
int selrtn;
@@ -210,8 +239,7 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma
struct timeval timeout;
/* just checking .... */
- if (maxcnt <= 0)
- return(0);
+ if (maxcnt <= 0) return(0);
smb_read_error = 0;
@@ -231,13 +259,11 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma
#endif /* WITH_SSL */
if (readret == 0) {
- DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
smb_read_error = READ_EOF;
return -1;
}
if (readret == -1) {
- DEBUG(0,("read_socket_with_timeout: read error = %s.\n", strerror(errno) ));
smb_read_error = READ_ERROR;
return -1;
}
@@ -256,23 +282,22 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma
timeout.tv_sec = (time_t)(time_out / 1000);
timeout.tv_usec = (long)(1000 * (time_out % 1000));
- for (nread=0; nread < mincnt; ) {
+ for (nread=0; nread < mincnt; )
+ {
FD_ZERO(&fds);
FD_SET(fd,&fds);
- selrtn = sys_select(fd+1,&fds,&timeout);
+ selrtn = sys_select(fd+1,&fds,NULL, &timeout);
/* Check if error */
if(selrtn == -1) {
/* something is wrong. Maybe the socket is dead? */
- DEBUG(0,("read_socket_with_timeout: timeout read. select error = %s.\n", strerror(errno) ));
smb_read_error = READ_ERROR;
return -1;
}
-
+
/* Did we timeout ? */
if (selrtn == 0) {
- DEBUG(10,("read_socket_with_timeout: timeout read. select timed out.\n"));
smb_read_error = READ_TIMEOUT;
return -1;
}
@@ -289,14 +314,12 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma
if (readret == 0) {
/* we got EOF on the file descriptor */
- DEBUG(5,("read_socket_with_timeout: timeout read. EOF from client.\n"));
smb_read_error = READ_EOF;
return -1;
}
if (readret == -1) {
/* the descriptor is probably dead */
- DEBUG(0,("read_socket_with_timeout: timeout read. read error = %s.\n", strerror(errno) ));
smb_read_error = READ_ERROR;
return -1;
}
@@ -308,91 +331,10 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma
return((ssize_t)nread);
}
-/****************************************************************************
- Read data from a fd with a timout in msec.
- mincount = if timeout, minimum to read before returning
- maxcount = number to be read.
- time_out = timeout in milliseconds
-****************************************************************************/
-
-ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned int time_out)
-{
- fd_set fds;
- int selrtn;
- ssize_t readret;
- size_t nread = 0;
- struct timeval timeout;
-
- /* just checking .... */
- if (maxcnt <= 0)
- return(0);
-
- /* Blocking read */
- if (time_out <= 0) {
- if (mincnt == 0) mincnt = maxcnt;
-
- while (nread < mincnt) {
-#ifdef WITH_SSL
- if(fd == sslFd){
- readret = SSL_read(ssl, buf + nread, maxcnt - nread);
- }else{
- readret = read(fd, buf + nread, maxcnt - nread);
- }
-#else /* WITH_SSL */
- readret = read(fd, buf + nread, maxcnt - nread);
-#endif /* WITH_SSL */
-
- if (readret <= 0)
- return readret;
-
- nread += readret;
- }
- return((ssize_t)nread);
- }
-
- /* Most difficult - timeout read */
- /* If this is ever called on a disk file and
- mincnt is greater then the filesize then
- system performance will suffer severely as
- select always returns true on disk files */
-
- /* Set initial timeout */
- timeout.tv_sec = (time_t)(time_out / 1000);
- timeout.tv_usec = (long)(1000 * (time_out % 1000));
-
- for (nread=0; nread < mincnt; ) {
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
-
- selrtn = sys_select(fd+1,&fds,&timeout);
-
- if(selrtn <= 0)
- return selrtn;
-
-#ifdef WITH_SSL
- if(fd == sslFd){
- readret = SSL_read(ssl, buf + nread, maxcnt - nread);
- }else{
- readret = read(fd, buf + nread, maxcnt - nread);
- }
-#else /* WITH_SSL */
- readret = read(fd, buf+nread, maxcnt-nread);
-#endif /* WITH_SSL */
-
- if (readret <= 0)
- return readret;
-
- nread += readret;
- }
-
- /* Return the number we got */
- return((ssize_t)nread);
-}
/****************************************************************************
send a keepalive packet (rfc1002)
****************************************************************************/
-
BOOL send_keepalive(int client)
{
unsigned char buf[4];
@@ -400,13 +342,14 @@ BOOL send_keepalive(int client)
buf[0] = 0x85;
buf[1] = buf[2] = buf[3] = 0;
- return(write_socket_data(client,(char *)buf,4) == 4);
+ return(write_data(client,(char *)buf,4) == 4);
}
+
+
/****************************************************************************
read data from the client, reading exactly N bytes.
****************************************************************************/
-
ssize_t read_data(int fd,char *buffer,size_t N)
{
ssize_t ret;
@@ -428,13 +371,11 @@ ssize_t read_data(int fd,char *buffer,size_t N)
if (ret == 0)
{
- DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
smb_read_error = READ_EOF;
return 0;
}
if (ret == -1)
{
- DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
smb_read_error = READ_ERROR;
return -1;
}
@@ -443,50 +384,10 @@ ssize_t read_data(int fd,char *buffer,size_t N)
return (ssize_t)total;
}
-/****************************************************************************
- Read data from a socket, reading exactly N bytes.
-****************************************************************************/
-
-static ssize_t read_socket_data(int fd,char *buffer,size_t N)
-{
- ssize_t ret;
- size_t total=0;
-
- smb_read_error = 0;
-
- while (total < N)
- {
-#ifdef WITH_SSL
- if(fd == sslFd){
- ret = SSL_read(ssl, buffer + total, N - total);
- }else{
- ret = read(fd,buffer + total,N - total);
- }
-#else /* WITH_SSL */
- ret = read(fd,buffer + total,N - total);
-#endif /* WITH_SSL */
-
- if (ret == 0)
- {
- DEBUG(10,("read_socket_data: recv of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
- smb_read_error = READ_EOF;
- return 0;
- }
- if (ret == -1)
- {
- DEBUG(0,("read_socket_data: recv failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
- smb_read_error = READ_ERROR;
- return -1;
- }
- total += ret;
- }
- return (ssize_t)total;
-}
/****************************************************************************
- Write data to a fd.
+ write data to a fd
****************************************************************************/
-
ssize_t write_data(int fd,char *buffer,size_t N)
{
size_t total=0;
@@ -504,42 +405,7 @@ ssize_t write_data(int fd,char *buffer,size_t N)
ret = write(fd,buffer + total,N - total);
#endif /* WITH_SSL */
- if (ret == -1) {
- DEBUG(0,("write_data: write failure. Error = %s\n", strerror(errno) ));
- return -1;
- }
- if (ret == 0) return total;
-
- total += ret;
- }
- return (ssize_t)total;
-}
-
-/****************************************************************************
- Write data to a socket - use send rather than write.
-****************************************************************************/
-
-ssize_t write_socket_data(int fd,char *buffer,size_t N)
-{
- size_t total=0;
- ssize_t ret;
-
- while (total < N)
- {
-#ifdef WITH_SSL
- if(fd == sslFd){
- ret = SSL_write(ssl,buffer + total,N - total);
- }else{
- ret = send(fd,buffer + total,N - total, 0);
- }
-#else /* WITH_SSL */
- ret = send(fd,buffer + total,N - total,0);
-#endif /* WITH_SSL */
-
- if (ret == -1) {
- DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) ));
- return -1;
- }
+ if (ret == -1) return -1;
if (ret == 0) return total;
total += ret;
@@ -547,26 +413,7 @@ ssize_t write_socket_data(int fd,char *buffer,size_t N)
return (ssize_t)total;
}
-/****************************************************************************
-write to a socket
-****************************************************************************/
-
-ssize_t write_socket(int fd,char *buf,size_t len)
-{
- ssize_t ret=0;
-
- if (passive)
- return(len);
- DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len));
- ret = write_socket_data(fd,buf,len);
-
- DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret));
- if(ret <= 0)
- DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
- (int)len, fd, strerror(errno) ));
- return(ret);
-}
/****************************************************************************
read 4 bytes of a smb packet and return the smb length of the packet
@@ -575,7 +422,6 @@ This version of the function will return a length of zero on receiving
a keepalive packet.
timeout is in milliseconds.
****************************************************************************/
-
static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
{
ssize_t len=0;
@@ -585,9 +431,9 @@ static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int
while (!ok)
{
if (timeout > 0)
- ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4);
+ ok = (read_with_timeout(fd,inbuf,4,4,timeout) == 4);
else
- ok = (read_socket_data(fd,inbuf,4) == 4);
+ ok = (read_data(fd,inbuf,4) == 4);
if (!ok)
return(-1);
@@ -610,7 +456,6 @@ store the result in the buffer. This version of the function will
never return a session keepalive (length of zero).
timeout is in milliseconds.
****************************************************************************/
-
ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
{
ssize_t len;
@@ -627,8 +472,6 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
break;
}
- DEBUG(10,("read_smb_length: got smb length of %d\n",len));
-
return len;
}
@@ -639,14 +482,13 @@ ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
This function will return on a
receipt of a session keepalive packet.
****************************************************************************/
-
BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
{
ssize_t len,ret;
smb_read_error = 0;
- memset(buffer,'\0',smb_size + 100);
+ bzero(buffer,smb_size + 100);
len = read_smb_length_return_keepalive(fd,buffer,timeout);
if (len < 0)
@@ -664,7 +506,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
}
if(len > 0) {
- ret = read_socket_data(fd,buffer+4,len);
+ ret = read_data(fd,buffer+4,len);
if (ret != len) {
smb_read_error = READ_ERROR;
return False;
@@ -687,6 +529,7 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
{
BOOL ret;
+ uint8 msg_type;
for(;;)
{
@@ -700,45 +543,25 @@ BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
}
/* Ignore session keepalive packets. */
- if(CVAL(buffer,0) != 0x85)
+ msg_type = CVAL(buffer,0);
+ if (msg_type != 0x85)
break;
}
+ if (msg_type == 0)
+ {
+ show_msg(buffer);
+ }
+ else
+ {
+ dump_data(10, buffer, smb_len(buffer) + 4);
+ }
show_msg(buffer);
return ret;
}
/****************************************************************************
- send an null session message to a fd
-****************************************************************************/
-
-BOOL send_null_session_msg(int fd)
-{
- ssize_t ret;
- uint32 blank = 0;
- size_t len = 4;
- size_t nwritten=0;
- char *buffer = (char *)&blank;
-
- while (nwritten < len)
- {
- ret = write_socket(fd,buffer+nwritten,len - nwritten);
- if (ret <= 0)
- {
- DEBUG(0,("send_null_session_msg: Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret));
- close_sockets();
- exit(1);
- }
- nwritten += ret;
- }
-
- DEBUG(10,("send_null_session_msg: sent 4 null bytes to client.\n"));
- return True;
-}
-
-/****************************************************************************
send an smb to a fd
****************************************************************************/
-
BOOL send_smb(int fd,char *buffer)
{
size_t len;
@@ -751,7 +574,7 @@ BOOL send_smb(int fd,char *buffer)
ret = write_socket(fd,buffer+nwritten,len - nwritten);
if (ret <= 0)
{
- DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",(int)len,(int)ret));
+ DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",len,ret));
close_sockets();
exit(1);
}
@@ -761,10 +584,11 @@ BOOL send_smb(int fd,char *buffer)
return True;
}
+
+
/****************************************************************************
send a single packet to a port on another machine
****************************************************************************/
-
BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
{
BOOL ret;
@@ -783,7 +607,7 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
}
/* set the address and port */
- memset((char *)&sock_out,'\0',sizeof(sock_out));
+ bzero((char *)&sock_out,sizeof(sock_out));
putip((char *)&sock_out.sin_addr,(char *)&ip);
sock_out.sin_port = htons( port );
sock_out.sin_family = AF_INET;
@@ -803,11 +627,12 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
return(ret);
}
+
/****************************************************************************
open a socket of the specified type, port and address for incoming data
****************************************************************************/
-
-int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebind)
+int open_socket_in(int type, int port, int dlevel,uint32 socket_addr,
+ BOOL rebind)
{
struct hostent *hp;
struct sockaddr_in sock;
@@ -825,7 +650,7 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebin
return -1;
}
- memset((char *)&sock,'\0',sizeof(sock));
+ bzero((char *)&sock,sizeof(sock));
memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
#ifdef HAVE_SOCK_SIN_LEN
@@ -844,14 +669,7 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebin
val=1;
else
val=0;
- if(setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1)
- DEBUG(dlevel,("setsockopt: SO_REUSEADDR=%d on port %d failed with error = %s\n",
- val, port, strerror(errno) ));
-#ifdef SO_REUSEPORT
- if(setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1)
- DEBUG(dlevel,("setsockopt: SO_REUSEPORT=%d on port %d failed with error = %s\n",
- val, port, strerror(errno) ));
-#endif /* SO_REUSEPORT */
+ setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val));
}
/* now we've got a socket - we need to bind it */
@@ -877,16 +695,16 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebin
return res;
}
+
/****************************************************************************
- create an outgoing socket. timeout is in milliseconds.
+ create an outgoing socket
**************************************************************************/
-
int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
{
struct sockaddr_in sock_out;
int res,ret;
int connect_loop = 250; /* 250 milliseconds */
- int loops = (timeout) / connect_loop;
+ int loops = (timeout * 1000) / connect_loop;
/* create a socket to write to */
res = socket(PF_INET, type, 0);
@@ -895,7 +713,7 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout)
if (type != SOCK_STREAM) return(res);
- memset((char *)&sock_out,'\0',sizeof(sock_out));
+ bzero((char *)&sock_out,sizeof(sock_out));
putip((char *)&sock_out.sin_addr,(char *)addr);
sock_out.sin_port = htons( port );
@@ -953,6 +771,41 @@ connect_again:
static BOOL global_client_name_done = False;
static BOOL global_client_addr_done = False;
+static pstring client_name_buf;
+static fstring client_addr_buf;
+static int last_fd=-1;
+
+void set_client_connection_name(const char* name, int fd)
+{
+ global_client_name_done = True;
+ pstrcpy(client_name_buf, name);
+ last_fd = fd;
+}
+
+void set_client_connection_addr(const char* addr, int fd)
+{
+ global_client_addr_done = True;
+ pstrcpy(client_addr_buf, addr);
+ last_fd = fd;
+}
+
+char *client_connection_name(void)
+{
+ if (global_client_name_done)
+ {
+ return client_name_buf;
+ }
+ return client_name(Client);
+}
+
+char *client_connection_addr(void)
+{
+ if (global_client_addr_done)
+ {
+ return client_addr_buf;
+ }
+ return client_addr(Client);
+}
void reset_globals_after_fork(void)
{
@@ -973,31 +826,28 @@ void reset_globals_after_fork(void)
/*******************************************************************
return the DNS name of the client
******************************************************************/
-
char *client_name(int fd)
{
struct sockaddr sa;
struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
int length = sizeof(sa);
- static pstring name_buf;
struct hostent *hp;
- static int last_fd=-1;
if (global_client_name_done && last_fd == fd)
- return name_buf;
+ return client_name_buf;
last_fd = fd;
global_client_name_done = False;
- pstrcpy(name_buf,"UNKNOWN");
+ pstrcpy(client_name_buf,"UNKNOWN");
if (fd == -1) {
- return name_buf;
+ return client_name_buf;
}
if (getpeername(fd, &sa, &length) < 0) {
DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
- return name_buf;
+ return client_name_buf;
}
/* Look up the remote host name. */
@@ -1005,51 +855,48 @@ char *client_name(int fd)
sizeof(sockin->sin_addr),
AF_INET)) == 0) {
DEBUG(1,("Gethostbyaddr failed for %s\n",client_addr(fd)));
- StrnCpy(name_buf,client_addr(fd),sizeof(name_buf) - 1);
+ StrnCpy(client_name_buf,client_addr(fd),sizeof(client_name_buf) - 1);
} else {
- StrnCpy(name_buf,(char *)hp->h_name,sizeof(name_buf) - 1);
- if (!matchname(name_buf, sockin->sin_addr)) {
- DEBUG(0,("Matchname failed on %s %s\n",name_buf,client_addr(fd)));
- pstrcpy(name_buf,"UNKNOWN");
+ StrnCpy(client_name_buf,(char *)hp->h_name,sizeof(client_name_buf) - 1);
+ if (!matchname(client_name_buf, sockin->sin_addr)) {
+ DEBUG(0,("Matchname failed on %s %s\n",client_name_buf,client_addr(fd)));
+ pstrcpy(client_name_buf,"UNKNOWN");
}
}
global_client_name_done = True;
- return name_buf;
+ return client_name_buf;
}
/*******************************************************************
return the IP addr of the client as a string
******************************************************************/
-
char *client_addr(int fd)
{
struct sockaddr sa;
struct sockaddr_in *sockin = (struct sockaddr_in *) (&sa);
int length = sizeof(sa);
- static fstring addr_buf;
- static int last_fd = -1;
if (global_client_addr_done && fd == last_fd)
- return addr_buf;
+ return client_addr_buf;
last_fd = fd;
global_client_addr_done = False;
- fstrcpy(addr_buf,"0.0.0.0");
+ fstrcpy(client_addr_buf,"0.0.0.0");
if (fd == -1) {
- return addr_buf;
+ return client_addr_buf;
}
if (getpeername(fd, &sa, &length) < 0) {
DEBUG(0,("getpeername failed. Error was %s\n", strerror(errno) ));
- return addr_buf;
+ return client_addr_buf;
}
- fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr));
+ fstrcpy(client_addr_buf,(char *)inet_ntoa(sockin->sin_addr));
global_client_addr_done = True;
- return addr_buf;
+ return client_addr_buf;
}
/*******************************************************************
@@ -1076,7 +923,8 @@ int open_pipe_sock(char *path)
if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0)
{
- DEBUG(0,("socket connect to %s failed\n", sa.sun_path));
+ DEBUG(0,("socket connect to %s failed: %s\n",
+ sa.sun_path,strerror(errno)));
close(sock);
return -1;
}
@@ -1090,10 +938,13 @@ int create_pipe_socket(char *dir, int dir_perms,
int s;
struct sockaddr_un sa;
- DEBUG(0,("create_pipe_socket: %s %d %s %d\n",
+ DEBUG(0,("create_pipe_socket: %s perms=%d %s perms=%d\n",
dir, dir_perms, path, path_perms));
- DEBUG(0,("*** RACE CONDITION. PLEASE SOMEONE EXAMINE create_pipe_Socket AND FIX IT ***\n"));
+ DEBUG(0,("*** Please someone examine create_pipe_socket and fix it ***\n"));
+ DEBUG(0,("*** if used other than for exclusive root access ***\n"));
+ DEBUG(0,("*** (see perms, which should be 0700 and 0600) ***\n"));
+ DEBUG(0,("*** there is a race condition to be exploited. ***\n"));
mkdir(dir, dir_perms);
diff --git a/source/lib/util_status.c b/source/lib/util_status.c
new file mode 100644
index 00000000000..836388a1bd5
--- /dev/null
+++ b/source/lib/util_status.c
@@ -0,0 +1,160 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba connection status utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Michael Glauche 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+parse the STATUS..LCK file. caller is responsible for freeing *crec.
+********************************************************************/
+BOOL get_connection_status(struct connect_record **crec,
+ uint32 *connection_count)
+{
+ int fd;
+ pstring fname;
+ int conn;
+ int num_recs;
+ struct connect_record *c;
+ int i;
+
+ if (crec == NULL || connection_count == NULL)
+ {
+ return False;
+ }
+
+ pstrcpy(fname,lp_lockdir());
+ standard_sub_basic(fname);
+ trim_string(fname,"","/");
+ pstrcat(fname,"/STATUS..LCK");
+
+ fd = sys_open(fname,O_RDONLY, 0);
+
+ if (fd == -1)
+ {
+ DEBUG(0,("Couldn't open status file %s\n",fname));
+ return False;
+ }
+
+ (*crec) = NULL;
+
+ num_recs = file_size(fname) / sizeof(*c);
+
+ DEBUG(5,("Opened status file %s, record count %d\n",fname, num_recs));
+
+ for (i = 0, conn = 0; i < num_recs; i++)
+ {
+ (*crec) = Realloc((*crec), (conn+1) * sizeof((*crec)[conn]));
+ if ((*crec) == NULL)
+ {
+ DEBUG(0,("Realloc failed in get_connection_status\n"));
+ return False;
+ }
+
+ c = &((*crec)[conn]);
+ if (sys_lseek(fd,i*sizeof(*c),SEEK_SET) != i*sizeof(*c) ||
+ read(fd,c,sizeof(*c)) != sizeof(*c))
+ {
+ DEBUG(0,("unable to read a crec in get_connection_status\n"));
+ break;
+ }
+ DEBUG(10,("cnum:%u. pid: %d magic: %x\n",
+ c->cnum, c->pid, c->magic));
+
+ /* valid connection, smbd process still going, connection still going */
+ if ( c->magic == 0x280267 && process_exists(c->pid) && c->cnum != -1 )
+ {
+ conn++;
+ }
+
+ }
+ close(fd);
+ (*connection_count)=conn;
+ return True;
+}
+
+/*******************************************************************
+Get the number of open Sessions. Not optimal yet. Has at least O(n*log(n)).
+ ********************************************************************/
+BOOL get_session_count(struct connect_record **srec,uint32 *session_count)
+{
+ struct connect_record *crec = NULL;
+ struct connect_record *c;
+
+ uint32 connection_count;
+ uint32 conn;
+ int *pid;
+ int i;
+ int MaxPid;
+ BOOL found;
+
+ (*srec) = NULL;
+ pid = NULL;
+ if (get_connection_status(&crec, &connection_count))
+ {
+ MaxPid = 0;
+ for (conn = 0; conn < connection_count; conn++)
+ {
+ DEBUG(10,("Connection nr : %u\n",conn));
+ found=False;
+ for (i = 0; i < MaxPid; i++)
+ {
+ if (crec[conn].pid == pid[i])
+ {
+ found = True;
+ i=MaxPid;
+ }
+ }
+ if (!found) {
+ (*srec) = Realloc((*srec), (MaxPid+1) * sizeof((*srec)[MaxPid]));
+ if ((*srec) == NULL)
+ {
+ DEBUG(0,("Realloc failed in get_connection_status\n"));
+ return False;
+ }
+ pid = Realloc(pid, (MaxPid+1) * sizeof(int));
+ if (pid == NULL)
+ {
+ DEBUG(0,("Realloc failed in get_session_count\n"));
+ free(crec);
+ return False;
+ }
+ c = &((*srec)[MaxPid]);
+ pid[MaxPid]=crec[conn].pid;
+ pstrcpy(c->machine,crec[conn].machine);
+ c->uid = crec[conn].uid;
+ c->pid = crec[conn].pid;
+ c->cnum = crec[conn].cnum;
+ pstrcpy(c->name,crec[conn].name);
+
+ MaxPid++;
+ }
+ }
+ } else {
+/* crec is not valid, so no need to free it here */
+ return False;
+ }
+ free(crec);
+ (*session_count) = MaxPid;
+ return True;
+}
+
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index d703670860b..d9d37ecc84b 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -343,7 +343,7 @@ void strlower(char *s)
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- size_t skip = get_character_len( *s );
+ size_t skip = skip_multibyte_char( *s );
if( skip != 0 )
s += skip;
else
@@ -396,7 +396,7 @@ void strupper(char *s)
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- size_t skip = get_character_len( *s );
+ size_t skip = skip_multibyte_char( *s );
if( skip != 0 )
s += skip;
else
@@ -440,29 +440,17 @@ BOOL strisnormal(char *s)
void string_replace(char *s,char oldc,char newc)
{
size_t skip;
-
- /*
- * sbcs optimization.
- */
- if(!global_is_multibyte_codepage) {
- while (*s) {
+ while (*s)
+ {
+ skip = skip_multibyte_char( *s );
+ if( skip != 0 )
+ s += skip;
+ else
+ {
if (oldc == *s)
*s = newc;
s++;
}
- } else {
- while (*s)
- {
- skip = get_character_len( *s );
- if( skip != 0 )
- s += skip;
- else
- {
- if (oldc == *s)
- *s = newc;
- s++;
- }
- }
}
}
@@ -474,7 +462,7 @@ char *skip_string(char *buf,size_t n)
{
while (n--)
buf += strlen(buf) + 1;
- return(buf);
+ return buf;
}
/*******************************************************************
@@ -488,17 +476,10 @@ size_t str_charnum(const char *s)
{
size_t len = 0;
- /*
- * sbcs optimization.
- */
- if(!global_is_multibyte_codepage) {
- return strlen(s);
- } else {
- while (*s != '\0') {
- int skip = get_character_len(*s);
- s += (skip ? skip : 1);
- len++;
- }
+ while (*s != '\0') {
+ int skip = skip_multibyte_char(*s);
+ s += (skip ? skip : 1);
+ len++;
}
return len;
}
@@ -537,7 +518,7 @@ BOOL trim_string(char *s,const char *front,const char *back)
if(back_len)
{
- if(!global_is_multibyte_codepage)
+ if(!is_multibyte_codepage())
{
s_len = strlen(s);
while ((s_len >= back_len) &&
@@ -571,20 +552,11 @@ BOOL trim_string(char *s,const char *front,const char *back)
size_t charcount = 0;
char *mbp = s;
- /*
- * sbcs optimization.
- */
- if(!global_is_multibyte_codepage) {
- while(charcount < (mb_s_len - mb_back_len)) {
- mbp += 1;
- charcount++;
- }
- } else {
- while(charcount < (mb_s_len - mb_back_len)) {
- size_t skip = skip_multibyte_char(*mbp);
- mbp += (skip ? skip : 1);
- charcount++;
- }
+ while(charcount < (mb_s_len - mb_back_len))
+ {
+ size_t skip = skip_multibyte_char(*mbp);
+ mbp += (skip ? skip : 1);
+ charcount++;
}
/*
@@ -643,7 +615,7 @@ BOOL strhasupper(const char *s)
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- size_t skip = get_character_len( *s );
+ size_t skip = skip_multibyte_char( *s );
if( skip != 0 )
s += skip;
else {
@@ -698,7 +670,7 @@ BOOL strhaslower(const char *s)
else
#endif /* KANJI_WIN95_COMPATIBILITY */
{
- size_t skip = get_character_len( *s );
+ size_t skip = skip_multibyte_char( *s );
if( skip != 0 )
s += skip;
else {
@@ -748,7 +720,7 @@ size_t count_chars(const char *s,char c)
{
while (*s)
{
- size_t skip = get_character_len( *s );
+ size_t skip = skip_multibyte_char( *s );
if( skip != 0 )
s += skip;
else {
@@ -761,69 +733,21 @@ size_t count_chars(const char *s,char c)
return(count);
}
-/*******************************************************************
-Return True if a string consists only of one particular character.
-********************************************************************/
-BOOL str_is_all(const char *s,char c)
-{
- if(s == NULL)
- return False;
- if(!*s)
- return False;
-
-#if !defined(KANJI_WIN95_COMPATIBILITY)
- /*
- * For completeness we should put in equivalent code for code pages
- * 949 (Korean hangul) and 950 (Big5 Traditional Chinese) here - but
- * doubt anyone wants Samba to behave differently from Win95 and WinNT
- * here. They both treat full width ascii characters as case senstive
- * filenames (ie. they don't do the work we do here).
- * JRA.
- */
-
- if(lp_client_code_page() == KANJI_CODEPAGE)
- {
- /* Win95 treats full width ascii characters as case sensitive. */
- while (*s)
- {
- if (is_shift_jis (*s))
- s += 2;
- else
- {
- if (*s != c)
- return False;
- s++;
- }
- }
- }
- else
-#endif /* KANJI_WIN95_COMPATIBILITY */
- {
- while (*s)
- {
- size_t skip = get_character_len( *s );
- if( skip != 0 )
- s += skip;
- else {
- if (*s != c)
- return False;
- s++;
- }
- }
- }
- return True;
-}
/*******************************************************************
safe string copy into a known length string. maxlength does not
include the terminating zero.
********************************************************************/
-
char *safe_strcpy(char *dest,const char *src, size_t maxlength)
{
size_t len;
+ if (maxlength == 0)
+ {
+ return dest;
+ }
+
if (!dest) {
DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
return NULL;
@@ -838,7 +762,7 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
if (len > maxlength) {
DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
- (int)(len-maxlength), src));
+ len-maxlength, src));
len = maxlength;
}
@@ -851,7 +775,6 @@ char *safe_strcpy(char *dest,const char *src, size_t maxlength)
safe string cat into a string. maxlength does not
include the terminating zero.
********************************************************************/
-
char *safe_strcat(char *dest, const char *src, size_t maxlength)
{
size_t src_len, dest_len;
@@ -870,7 +793,7 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength)
if (src_len + dest_len > maxlength) {
DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
- (int)(src_len + dest_len - maxlength), src));
+ src_len + dest_len - maxlength, src));
src_len = maxlength - dest_len;
}
@@ -879,48 +802,28 @@ char *safe_strcat(char *dest, const char *src, size_t maxlength)
return dest;
}
-/*******************************************************************
- Paranoid strcpy into a buffer of given length (includes terminating
- zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
- does *NOT* check for multibyte characters. Don't change it !
-********************************************************************/
-
-char *alpha_strcpy(char *dest, const char *src, size_t maxlength)
+/****************************************************************************
+this is a safer strcpy(), meant to prevent core dumps when nasty things happen
+****************************************************************************/
+char *StrCpy(char *dest,const char *src)
{
- size_t len, i;
-
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in alpha_strcpy\n"));
- return NULL;
- }
-
- if (!src) {
- *dest = 0;
- return dest;
- }
-
- len = strlen(src);
- if (len >= maxlength)
- len = maxlength - 1;
-
- for(i = 0; i < len; i++) {
- int val = (src[i] & 0xff);
- if(isupper(val) ||islower(val) || isdigit(val))
- dest[i] = src[i];
- else
- dest[i] = '_';
- }
+ char *d = dest;
- dest[i] = '\0';
+ /* I don't want to get lazy with these ... */
+ SMB_ASSERT(dest && src);
- return dest;
+ if (!dest) return(NULL);
+ if (!src) {
+ *dest = 0;
+ return(dest);
+ }
+ while ((*d++ = *src++)) ;
+ return(dest);
}
/****************************************************************************
- Like strncpy but always null terminates. Make sure there is room!
- The variable n should always be one less than the available size.
+like strncpy but always null terminates. Make sure there is room!
****************************************************************************/
-
char *StrnCpy(char *dest,const char *src,size_t n)
{
char *d = dest;
@@ -934,11 +837,12 @@ char *StrnCpy(char *dest,const char *src,size_t n)
return(dest);
}
+
/****************************************************************************
like strncpy but copies up to the character marker. always null terminates.
returns a pointer to the character marker in the source string (src).
****************************************************************************/
-char *strncpyn(char *dest, const char *src,size_t n, char c)
+char *strncpyn(char *dest, char *src,size_t n, char c)
{
char *p;
size_t str_len;
@@ -1036,7 +940,7 @@ static char *null_string = NULL;
/****************************************************************************
set a string value, allocing the space for the string
****************************************************************************/
-static BOOL string_init(char **dest,const char *src)
+BOOL string_init(char **dest,const char *src)
{
size_t l;
if (!src)
@@ -1099,42 +1003,29 @@ enough room!
This routine looks for pattern in s and replaces it with
insert. It may do multiple replacements.
-any of " ; ' $ or ` in the insert string are replaced with _
-if len==0 then no length check is performed
+any of " ; ' or ` in the insert string are replaced with _
****************************************************************************/
-void string_sub(char *s,const char *pattern,const char *insert, size_t len)
+void string_sub(char *s,const char *pattern,const char *insert)
{
char *p;
- ssize_t ls,lp,li, i;
+ size_t ls,lp,li, i;
if (!insert || !pattern || !s) return;
- ls = (ssize_t)strlen(s);
- lp = (ssize_t)strlen(pattern);
- li = (ssize_t)strlen(insert);
+ ls = strlen(s);
+ lp = strlen(pattern);
+ li = strlen(insert);
if (!*pattern) return;
while (lp <= ls && (p = strstr(s,pattern))) {
- if (len && (ls + (li-lp) >= len)) {
- DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n",
- (int)(ls + (li-lp) - len),
- pattern, (int)len));
- break;
- }
- if (li != lp) {
- memmove(p+li,p+lp,strlen(p+lp)+1);
- }
+ memmove(p+li,p+lp,ls + 1 - (PTR_DIFF(p,s) + lp));
for (i=0;i<li;i++) {
switch (insert[i]) {
case '`':
case '"':
case '\'':
case ';':
- case '$':
- case '%':
- case '\r':
- case '\n':
p[i] = '_';
break;
default:
@@ -1146,15 +1037,6 @@ void string_sub(char *s,const char *pattern,const char *insert, size_t len)
}
}
-void fstring_sub(char *s,const char *pattern,const char *insert)
-{
- string_sub(s, pattern, insert, sizeof(fstring));
-}
-
-void pstring_sub(char *s,const char *pattern,const char *insert)
-{
- string_sub(s, pattern, insert, sizeof(pstring));
-}
/****************************************************************************
similar to string_sub() but allows for any character to be substituted.
@@ -1193,9 +1075,9 @@ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
/****************************************************************************
splits out the front and back at a separator.
****************************************************************************/
-void split_at_last_component(char *path, char *front, char sep, char *back)
+void split_at_first_component(char *path, char *front, char sep, char *back)
{
- char *p = strrchr(path, sep);
+ char *p = strchr(path, sep);
if (p != NULL)
{
@@ -1211,7 +1093,7 @@ void split_at_last_component(char *path, char *front, char sep, char *back)
{
pstrcpy(back, p+1);
}
- *p = '\\';
+ *p = sep;
}
else
{
@@ -1222,28 +1104,108 @@ void split_at_last_component(char *path, char *front, char sep, char *back)
}
}
-
/****************************************************************************
-write an octal as a string
+ splits out the front and back at a separator.
****************************************************************************/
-char *octal_string(int i)
+void split_at_last_component(char *path, char *front, char sep, char *back)
{
- static char ret[64];
- if (i == -1) {
- return "-1";
+ char *p = strrchr(path, sep);
+
+ if (p != NULL)
+ {
+ *p = 0;
+ }
+ if (front != NULL)
+ {
+ pstrcpy(front, path);
+ }
+ else if (back != NULL)
+ {
+ pstrcpy(back, path);
+ }
+ if (p != NULL)
+ {
+ if (back != NULL)
+ {
+ pstrcpy(back, p+1);
+ }
+ *p = sep;
+ }
+ else
+ {
+ if (back != NULL && front != NULL)
+ {
+ back[0] = 0;
+ }
}
- slprintf(ret, sizeof(ret), "0%o", i);
- return ret;
}
+/****************************************************************************
+convert a bit field to a string. if you want multiple bits to be detected
+set them first, e.g SV_TYPE_ALL to be "All" or "Full Control" for ACB_INFOs.
+
+strings are expected to contain their own separators, although the code
+below only assumes that separators are spaces.
+
+****************************************************************************/
+char *bit_field_to_str(uint32 type, struct field_info *bs)
+{
+ static fstring typestr;
+ int i = 0;
+
+ typestr[0] = 0;
+
+ if (type == 0 || bs == NULL)
+ {
+ return NULL;
+ }
+
+ while (bs[i].str != NULL && type != 0)
+ {
+ if (IS_BITS_SET_ALL(bs[i].bits, type))
+ {
+ fstrcat(typestr, bs[i].str);
+ type &= ~bs[i].bits;
+ }
+ i++;
+ }
+
+ i = strlen(typestr)-1;
+ if (i > 0 && typestr[i] == ' ')
+ {
+ typestr[i] = 0;
+ }
+
+ return typestr;
+}
/****************************************************************************
-truncate a string at a specified length
+convert an enumeration to a string. first item is the default.
****************************************************************************/
-char *string_truncate(char *s, int length)
+char *enum_field_to_str(uint32 type, struct field_info *bs, BOOL first_default)
{
- if (s && strlen(s) > length) {
- s[length] = 0;
+ int i = 0;
+
+ if (bs == NULL)
+ {
+ return NULL;
}
- return s;
+
+ while (bs[i].str != NULL && type != 0)
+ {
+ if (bs[i].bits == type)
+ {
+ return bs[i].str;
+ }
+ i++;
+ }
+
+ /* oops - none found */
+
+ if (first_default)
+ {
+ return bs[0].str;
+ }
+
+ return NULL;
}
diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c
index c0701f0427a..6065cf53508 100644
--- a/source/lib/util_unistr.c
+++ b/source/lib/util_unistr.c
@@ -2,7 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
Samba utility functions
- Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -23,69 +24,63 @@
extern int DEBUGLEVEL;
- smb_ucs2_t wchar_list_sep[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)',',
- (smb_ucs2_t)';', (smb_ucs2_t)':', (smb_ucs2_t)'\n',
- (smb_ucs2_t)'\r', 0 };
-/*
- * The following are the codepage to ucs2 and vica versa maps.
- * These are dynamically loaded from a unicode translation file.
- */
+/*******************************************************************
+ Put an ASCII string into a UNICODE buffer (little endian).
+ ********************************************************************/
+
+char *ascii_to_unibuf(char *dest, const char *src, int maxlen)
+{
+ char *destend = dest + maxlen;
+ register char c;
+
+ while (dest < destend)
+ {
+ c = *(src++);
+ if (c == 0)
+ {
+ break;
+ }
-static smb_ucs2_t *doscp_to_ucs2;
-static uint16 *ucs2_to_doscp;
+ *(dest++) = c;
+ *(dest++) = 0;
+ }
-static smb_ucs2_t *unixcp_to_ucs2;
-static uint16 *ucs2_to_unixcp;
+ *dest++ = 0;
+ *dest++ = 0;
+ return dest;
+}
-#ifndef MAXUNI
-#define MAXUNI 1024
-#endif
/*******************************************************************
- Write a string in (little-endian) unicode format. src is in
- the current DOS codepage. len is the length in bytes of the
- string pointed to by dst.
-
- the return value is the length of the string *without* the trailing
- two bytes of zero
-********************************************************************/
+ Pull an ASCII string out of a UNICODE buffer (little endian).
+ ********************************************************************/
-int dos_PutUniCode(char *dst,const char *src, ssize_t len)
+const char* unibuf_to_ascii(char *dest, const char *src, int maxlen)
{
- int ret = 0;
- while (*src && (len > 2)) {
- size_t skip = get_character_len(*src);
- smb_ucs2_t val = (*src & 0xff);
-
- /*
- * If this is a multibyte character (and all DOS/Windows
- * codepages have at maximum 2 byte multibyte characters)
- * then work out the index value for the unicode conversion.
- */
-
- if (skip == 2)
- val = ((val << 8) | (src[1] & 0xff));
-
- SSVAL(dst,ret,doscp_to_ucs2[val]);
- ret += 2;
- len -= 2;
- if (skip)
- src += skip;
- else
- src++;
+ char *destend = dest + maxlen;
+ register char c;
+
+ while (dest < destend)
+ {
+ c = *(src++);
+ if ((c == 0) && (*src == 0))
+ {
+ break;
+ }
+
+ *dest++ = c;
+ src++;
}
- SSVAL(dst,ret,0);
- return(ret);
+
+ *dest = 0;
+
+ return src;
}
+
/*******************************************************************
Put an ASCII string into a UNICODE array (uint16's).
-
- Warning: doesn't do any codepage !!! BAD !!!
-
- Help ! Fix Me ! Fix Me !
-********************************************************************/
-
+ ********************************************************************/
void ascii_to_unistr(uint16 *dest, const char *src, int maxlen)
{
uint16 *destend = dest + maxlen;
@@ -105,13 +100,10 @@ void ascii_to_unistr(uint16 *dest, const char *src, int maxlen)
*dest = 0;
}
+
/*******************************************************************
Pull an ASCII string out of a UNICODE array (uint16's).
-
- Warning: doesn't do any codepage !!! BAD !!!
-
- Help ! Fix Me ! Fix Me !
-********************************************************************/
+ ********************************************************************/
void unistr_to_ascii(char *dest, const uint16 *src, int len)
{
@@ -134,115 +126,10 @@ void unistr_to_ascii(char *dest, const uint16 *src, int len)
/*******************************************************************
- Skip past some unicode strings in a buffer.
-********************************************************************/
-
-char *skip_unicode_string(char *buf,int n)
-{
- while (n--) {
- while (*buf)
- buf += 2;
- buf += 2;
- }
- return(buf);
-}
-
-/*******************************************************************
- Return a DOS codepage version of a little-endian unicode string.
- Hack alert: uses fixed buffer(s).
-********************************************************************/
-
-char *dos_unistrn2(uint16 *src, int len)
-{
- static char lbufs[8][MAXUNI];
- static int nexti;
- char *lbuf = lbufs[nexti];
- char *p;
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; (len > 0) && (p-lbuf < MAXUNI-3) && *src; len--, src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
-
- *p = 0;
- return lbuf;
-}
-
-static char lbufs[8][MAXUNI];
-static int nexti;
-
-/*******************************************************************
- Return a DOS codepage version of a little-endian unicode string.
- Hack alert: uses fixed buffer(s).
-********************************************************************/
-
-char *dos_unistr2(uint16 *src)
-{
- char *lbuf = lbufs[nexti];
- char *p;
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; *src && (p-lbuf < MAXUNI-3); src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
-
- *p = 0;
- return lbuf;
-}
-
-/*******************************************************************
-Return a DOS codepage version of a little-endian unicode string
-********************************************************************/
-
-char *dos_unistr2_to_str(UNISTR2 *str)
-{
- char *lbuf = lbufs[nexti];
- char *p;
- uint16 *src = str->buffer;
- int max_size = MIN(sizeof(str->buffer)-3, str->uni_str_len);
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; *src && p-lbuf < max_size; src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
-
- *p = 0;
- return lbuf;
-}
-
-/*******************************************************************
Convert a UNISTR2 structure to an ASCII string
- Warning: this version does DOS codepage.
-********************************************************************/
+ ********************************************************************/
-void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
+char *unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
{
char *destend;
const uint16 *src;
@@ -250,1674 +137,407 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
register uint16 c;
src = str->buffer;
+
+ if (dest == NULL)
+ {
+ if (maxlen == 0)
+ {
+ maxlen = str->uni_str_len;
+ }
+ dest = g_new(char, maxlen + 1);
+ if (dest == NULL)
+ {
+ DEBUG(2, ("malloc(%d) problem in unistr2_to_ascii\n",
+ maxlen + 1));
+ return NULL;
+ }
+ }
+
len = MIN(str->uni_str_len, maxlen);
destend = dest + len;
while (dest < destend)
{
- uint16 ucs2_val;
- uint16 cp_val;
-
- c = *src;
+ c = *(src++);
if (c == 0)
{
break;
}
-
- ucs2_val = SVAL(src++,0);
- cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *(dest++) = (char)cp_val;
- else {
- *dest= (cp_val >> 8) & 0xff;
- *(dest++) = (cp_val & 0xff);
- }
+
+ *(dest++) = (char)c;
}
*dest = 0;
-}
-
-
-/*******************************************************************
-Return a number stored in a buffer
-********************************************************************/
-uint32 buffer2_to_uint32(BUFFER2 *str)
-{
- if (str->buf_len == 4)
- return IVAL(str->buffer, 0);
- else
- return 0;
-}
-
-/*******************************************************************
-Return a DOS codepage version of a NOTunicode string
-********************************************************************/
-
-char *dos_buffer2_to_str(BUFFER2 *str)
-{
- char *lbuf = lbufs[nexti];
- char *p;
- uint16 *src = str->buffer;
- int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; *src && p-lbuf < max_size; src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
-
- *p = 0;
- return lbuf;
+ return dest;
}
-/*******************************************************************
- Return a dos codepage version of a NOTunicode string
-********************************************************************/
-
-char *dos_buffer2_to_multistr(BUFFER2 *str)
-{
- char *lbuf = lbufs[nexti];
- char *p;
- uint16 *src = str->buffer;
- int max_size = MIN(sizeof(str->buffer)-3, str->buf_len/2);
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; p-lbuf < max_size; src++) {
- if (*src == 0) {
- *p++ = ' ';
- } else {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
-
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
- }
- }
- }
-
- *p = 0;
- return lbuf;
-}
/*******************************************************************
- Create a null-terminated unicode string from a null-terminated DOS
- codepage string.
- Return number of unicode chars copied, excluding the null character.
- Unicode strings created are in little-endian format.
-********************************************************************/
+ Skip a UNICODE string in a little endian buffer.
+ ********************************************************************/
-size_t dos_struni2(char *dst, const char *src, size_t max_len)
+char *skip_unibuf(char *srcbuf, int len)
{
- size_t len = 0;
-
- if (dst == NULL)
- return 0;
+ uint16 *src = (uint16 *)srcbuf;
+ uint16 *srcend = src + len/2;
- if (src != NULL) {
- for (; *src && len < max_len-2; len++, dst +=2) {
- size_t skip = get_character_len(*src);
- smb_ucs2_t val = (*src & 0xff);
-
- /*
- * If this is a multibyte character (and all DOS/Windows
- * codepages have at maximum 2 byte multibyte characters)
- * then work out the index value for the unicode conversion.
- */
-
- if (skip == 2)
- val = ((val << 8) | (src[1] & 0xff));
-
- SSVAL(dst,0,doscp_to_ucs2[val]);
- if (skip)
- src += skip;
- else
- src++;
- }
+ while ((src < srcend) && (*(src++) != 0))
+ {
}
- SSVAL(dst,0,0);
-
- return len;
+ return (char *)src;
}
+
/*******************************************************************
- Return a DOS codepage version of a little-endian unicode string.
- Hack alert: uses fixed buffer(s).
-********************************************************************/
+ UNICODE strcpy between buffers.
+ ********************************************************************/
-char *dos_unistr(char *buf)
+char *uni_strncpy(char *destbuf, const char *srcbuf, int len)
{
- char *lbuf = lbufs[nexti];
- uint16 *src = (uint16 *)buf;
- char *p;
-
- nexti = (nexti+1)%8;
-
- for (p = lbuf; *src && p-lbuf < MAXUNI-3; src++) {
- uint16 ucs2_val = SVAL(src,0);
- uint16 cp_val = ucs2_to_doscp[ucs2_val];
+ const uint16 *src = (const uint16 *)srcbuf;
+ uint16 *dest = (uint16 *)destbuf;
+ uint16 *destend = dest + len/2;
+ register uint16 c;
- if (cp_val < 256)
- *p++ = (char)cp_val;
- else {
- *p++ = (cp_val >> 8) & 0xff;
- *p++ = (cp_val & 0xff);
+ while (dest < destend)
+ {
+ c = *(src++);
+ if (c == 0)
+ {
+ break;
}
- }
-
- *p = 0;
- return lbuf;
-}
-/*******************************************************************
- Strcpy for unicode strings. returns length (in num of wide chars)
-********************************************************************/
-
-int unistrcpy(char *dst, char *src)
-{
- int num_wchars = 0;
- uint16 *wsrc = (uint16 *)src;
- uint16 *wdst = (uint16 *)dst;
-
- while (*wsrc) {
- *wdst++ = *wsrc++;
- num_wchars++;
+ *(dest++) = c;
}
- *wdst = 0;
- return num_wchars;
+ *dest++ = 0;
+ return (char *)dest;
}
-
/*******************************************************************
- Free any existing maps.
-********************************************************************/
+ Return a number stored in a buffer
+ ********************************************************************/
-static void free_maps(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
+uint32 buffer2_to_uint32(const BUFFER2 *str)
{
- /* this handles identity mappings where we share the pointer */
- if (*pp_ucs2_to_cp == *pp_cp_to_ucs2) {
- *pp_ucs2_to_cp = NULL;
- }
-
- if (*pp_cp_to_ucs2) {
- free(*pp_cp_to_ucs2);
- *pp_cp_to_ucs2 = NULL;
+ if (str->buf_len == 4)
+ {
+ const uchar *src = str->buffer;
+ return IVAL(src, 0);
}
-
- if (*pp_ucs2_to_cp) {
- free(*pp_ucs2_to_cp);
- *pp_ucs2_to_cp = NULL;
+ else
+ {
+ return 0;
}
}
/*******************************************************************
- Build a default (null) codepage to unicode map.
-********************************************************************/
-
-void default_unicode_map(smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
-{
- int i;
-
- free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
-
- if ((*pp_ucs2_to_cp = (uint16 *)malloc(2*65536)) == NULL) {
- DEBUG(0,("default_unicode_map: malloc fail for ucs2_to_cp size %u.\n", 2*65536));
- abort();
- }
-
- *pp_cp_to_ucs2 = *pp_ucs2_to_cp; /* Default map is an identity. */
- for (i = 0; i < 65536; i++)
- (*pp_cp_to_ucs2)[i] = i;
-}
-
-/*******************************************************************
- Load a codepage to unicode and vica-versa map.
-********************************************************************/
-
-BOOL load_unicode_map(const char *codepage, smb_ucs2_t **pp_cp_to_ucs2, uint16 **pp_ucs2_to_cp)
-{
- pstring unicode_map_file_name;
- FILE *fp = NULL;
- SMB_STRUCT_STAT st;
- smb_ucs2_t *cp_to_ucs2 = *pp_cp_to_ucs2;
- uint16 *ucs2_to_cp = *pp_ucs2_to_cp;
- size_t cp_to_ucs2_size;
- size_t ucs2_to_cp_size;
- size_t i;
- size_t size;
- char buf[UNICODE_MAP_HEADER_SIZE];
-
- DEBUG(5, ("load_unicode_map: loading unicode map for codepage %s.\n", codepage));
-
- if (*codepage == '\0')
- goto clean_and_exit;
-
- if(strlen(CODEPAGEDIR) + 13 + strlen(codepage) > sizeof(unicode_map_file_name)) {
- DEBUG(0,("load_unicode_map: filename too long to load\n"));
- goto clean_and_exit;
- }
-
- pstrcpy(unicode_map_file_name, CODEPAGEDIR);
- pstrcat(unicode_map_file_name, "/");
- pstrcat(unicode_map_file_name, "unicode_map.");
- pstrcat(unicode_map_file_name, codepage);
-
- if(sys_stat(unicode_map_file_name,&st)!=0) {
- DEBUG(0,("load_unicode_map: filename %s does not exist.\n",
- unicode_map_file_name));
- goto clean_and_exit;
- }
-
- size = st.st_size;
-
- if ((size != UNICODE_MAP_HEADER_SIZE + 4*65536) && (size != UNICODE_MAP_HEADER_SIZE +(2*256 + 2*65536))) {
- DEBUG(0,("load_unicode_map: file %s is an incorrect size for a \
-unicode map file (size=%d).\n", unicode_map_file_name, (int)size));
- goto clean_and_exit;
- }
-
- if((fp = sys_fopen( unicode_map_file_name, "r")) == NULL) {
- DEBUG(0,("load_unicode_map: cannot open file %s. Error was %s\n",
- unicode_map_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- if(fread( buf, 1, UNICODE_MAP_HEADER_SIZE, fp)!=UNICODE_MAP_HEADER_SIZE) {
- DEBUG(0,("load_unicode_map: cannot read header from file %s. Error was %s\n",
- unicode_map_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- /* Check the version value */
- if(SVAL(buf,UNICODE_MAP_VERSION_OFFSET) != UNICODE_MAP_FILE_VERSION_ID) {
- DEBUG(0,("load_unicode_map: filename %s has incorrect version id. \
-Needed %hu, got %hu.\n",
- unicode_map_file_name, (uint16)UNICODE_MAP_FILE_VERSION_ID,
- SVAL(buf,UNICODE_MAP_VERSION_OFFSET)));
- goto clean_and_exit;
- }
-
- /* Check the codepage value */
- if(!strequal(&buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], codepage)) {
- DEBUG(0,("load_unicode_map: codepage %s in file %s is not the same as that \
-requested (%s).\n", &buf[UNICODE_MAP_CLIENT_CODEPAGE_OFFSET], unicode_map_file_name, codepage ));
- goto clean_and_exit;
- }
-
- ucs2_to_cp_size = 2*65536;
- if (size == UNICODE_MAP_HEADER_SIZE + 4*65536) {
- /*
- * This is a multibyte code page.
- */
- cp_to_ucs2_size = 2*65536;
- } else {
- /*
- * Single byte code page.
- */
- cp_to_ucs2_size = 2*256;
- }
-
- /*
- * Free any old translation tables.
- */
-
- free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
-
- if ((cp_to_ucs2 = (smb_ucs2_t *)malloc(cp_to_ucs2_size)) == NULL) {
- DEBUG(0,("load_unicode_map: malloc fail for cp_to_ucs2 size %u.\n", cp_to_ucs2_size ));
- goto clean_and_exit;
- }
-
- if ((ucs2_to_cp = (uint16 *)malloc(ucs2_to_cp_size)) == NULL) {
- DEBUG(0,("load_unicode_map: malloc fail for ucs2_to_cp size %u.\n", ucs2_to_cp_size ));
- goto clean_and_exit;
- }
-
- if(fread( (char *)cp_to_ucs2, 1, cp_to_ucs2_size, fp)!=cp_to_ucs2_size) {
- DEBUG(0,("load_unicode_map: cannot read cp_to_ucs2 from file %s. Error was %s\n",
- unicode_map_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- if(fread( (char *)ucs2_to_cp, 1, ucs2_to_cp_size, fp)!=ucs2_to_cp_size) {
- DEBUG(0,("load_unicode_map: cannot read ucs2_to_cp from file %s. Error was %s\n",
- unicode_map_file_name, strerror(errno)));
- goto clean_and_exit;
- }
-
- /*
- * Now ensure the 16 bit values are in the correct endianness.
- */
-
- for (i = 0; i < cp_to_ucs2_size/2; i++)
- cp_to_ucs2[i] = SVAL(cp_to_ucs2,i*2);
-
- for (i = 0; i < ucs2_to_cp_size/2; i++)
- ucs2_to_cp[i] = SVAL(ucs2_to_cp,i*2);
-
- fclose(fp);
-
- *pp_cp_to_ucs2 = cp_to_ucs2;
- *pp_ucs2_to_cp = ucs2_to_cp;
-
- return True;
-
-clean_and_exit:
-
- /* pseudo destructor :-) */
-
- if(fp != NULL)
- fclose(fp);
-
- free_maps(pp_cp_to_ucs2, pp_ucs2_to_cp);
-
- default_unicode_map(pp_cp_to_ucs2, pp_ucs2_to_cp);
-
- return False;
-}
-
-/*******************************************************************
- Load a dos codepage to unicode and vica-versa map.
-********************************************************************/
-
-BOOL load_dos_unicode_map(int codepage)
-{
- fstring codepage_str;
-
- slprintf(codepage_str, sizeof(fstring)-1, "%03d", codepage);
- return load_unicode_map(codepage_str, &doscp_to_ucs2, &ucs2_to_doscp);
-}
-
-/*******************************************************************
- Load a UNIX codepage to unicode and vica-versa map.
-********************************************************************/
-
-BOOL load_unix_unicode_map(const char *unix_char_set)
-{
- fstring upper_unix_char_set;
-
- fstrcpy(upper_unix_char_set, unix_char_set);
- strupper(upper_unix_char_set);
- return load_unicode_map(upper_unix_char_set, &unixcp_to_ucs2, &ucs2_to_unixcp);
-}
-
-/*******************************************************************
- The following functions reproduce many of the non-UNICODE standard
- string functions in Samba.
-********************************************************************/
-
-/*******************************************************************
- Convert a UNICODE string to multibyte format. Note that the 'src' is in
- native byte order, not little endian. Always zero terminates.
- dst_len is in bytes.
-********************************************************************/
-
-static char *unicode_to_multibyte(char *dst, const smb_ucs2_t *src,
- size_t dst_len, const uint16 *ucs2_to_cp)
-{
- size_t dst_pos;
-
- for(dst_pos = 0; *src && (dst_pos < dst_len - 1);) {
- smb_ucs2_t val = ucs2_to_cp[*src++];
- if(val < 256) {
- dst[dst_pos++] = (char)val;
- } else {
-
- if(dst_pos >= dst_len - 2)
- break;
-
- /*
- * A 2 byte value is always written as
- * high/low into the buffer stream.
- */
-
- dst[dst_pos++] = (char)((val >> 8) & 0xff);
- dst[dst_pos++] = (char)(val & 0xff);
- }
- }
-
- dst[dst_pos] = '\0';
-
- return dst;
-}
-
-/*******************************************************************
- Convert a multibyte string to UNICODE format. Note that the 'dst' is in
- native byte order, not little endian. Always zero terminates.
- dst_len is in bytes.
-********************************************************************/
-
-smb_ucs2_t *multibyte_to_unicode(smb_ucs2_t *dst, const char *src,
- size_t dst_len, smb_ucs2_t *cp_to_ucs2)
+ Convert a 'multi-string' buffer to space-separated ASCII.
+ ********************************************************************/
+void buffer2_to_multistr(char *dest, const BUFFER2 *str, size_t maxlen)
{
- size_t i;
-
- dst_len /= sizeof(smb_ucs2_t); /* Convert to smb_ucs2_t units. */
-
- for(i = 0; (i < (dst_len - 1)) && src[i];) {
- size_t skip = get_character_len(*src);
- smb_ucs2_t val = (*src & 0xff);
-
- /*
- * If this is a multibyte character
- * then work out the index value for the unicode conversion.
- */
+ char *destend;
+ const uchar *src;
+ size_t len;
+ register uint16 c;
- if (skip == 2)
- val = ((val << 8) | (src[1] & 0xff));
+ src = str->buffer;
+ len = MIN(str->buf_len/2, maxlen);
+ destend = dest + len;
- dst[i++] = cp_to_ucs2[val];
- if (skip)
- src += skip;
- else
- src++;
+ while (dest < destend)
+ {
+ c = *(src++);
+ *(dest++) = (c == 0) ? ' ' : (char)c;
+ src++;
}
- dst[i] = 0;
-
- return dst;
-}
-
-/*******************************************************************
- Convert a UNICODE string to multibyte format. Note that the 'src' is in
- native byte order, not little endian. Always zero terminates.
- This function may be replaced if the MB codepage format is an
- encoded one (ie. utf8, hex). See the code in lib/kanji.c
- for details. dst_len is in bytes.
-********************************************************************/
-
-char *unicode_to_unix(char *dst, const smb_ucs2_t *src, size_t dst_len)
-{
- return unicode_to_multibyte(dst, src, dst_len, ucs2_to_unixcp);
-}
-
-/*******************************************************************
- Convert a UNIX string to UNICODE format. Note that the 'dst' is in
- native byte order, not little endian. Always zero terminates.
- This function may be replaced if the UNIX codepage format is a
- multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
- for details. dst_len is in bytes, not ucs2 units.
-********************************************************************/
-
-smb_ucs2_t *unix_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
-{
- return multibyte_to_unicode(dst, src, dst_len, unixcp_to_ucs2);
-}
-
-/*******************************************************************
- Convert a UNICODE string to DOS format. Note that the 'src' is in
- native byte order, not little endian. Always zero terminates.
- dst_len is in bytes.
-********************************************************************/
-
-char *unicode_to_dos(char *dst, const smb_ucs2_t *src, size_t dst_len)
-{
- return unicode_to_multibyte(dst, src, dst_len, ucs2_to_doscp);
-}
-
-/*******************************************************************
- Convert a DOS string to UNICODE format. Note that the 'dst' is in
- native byte order, not little endian. Always zero terminates.
- This function may be replaced if the DOS codepage format is a
- multi-byte one (ie. JIS, SJIS or utf8). See the code in lib/kanji.c
- for details. dst_len is in bytes, not ucs2 units.
-********************************************************************/
-
-smb_ucs2_t *dos_to_unicode(smb_ucs2_t *dst, const char *src, size_t dst_len)
-{
- return multibyte_to_unicode(dst, src, dst_len, doscp_to_ucs2);
-}
-
-/*******************************************************************
- Count the number of characters in a smb_ucs2_t string.
-********************************************************************/
-
-size_t strlen_w(const smb_ucs2_t *src)
-{
- size_t len;
-
- for(len = 0; *src; len++)
- ;
-
- return len;
-}
-
-/*******************************************************************
- Safe wstring copy into a known length string. maxlength includes
- the terminating zero. maxlength is in bytes.
-********************************************************************/
-
-smb_ucs2_t *safe_strcpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src, size_t maxlength)
-{
- size_t ucs2_len;
-
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcpy_w\n"));
- return NULL;
- }
-
- if (!src) {
- *dest = 0;
- return dest;
- }
-
- /*
- * Convert maxlength to smb_ucs2_t units.
- */
-
- maxlength /= sizeof(smb_ucs2_t);
-
- ucs2_len = strlen_w(src);
-
- if (ucs2_len >= maxlength) {
- fstring out;
- DEBUG(0,("ERROR: string overflow by %u bytes in safe_strcpy_w [%.50s]\n",
- (unsigned int)((ucs2_len-maxlength)*sizeof(smb_ucs2_t)),
- unicode_to_unix(out,src,sizeof(out))) );
- ucs2_len = maxlength - 1;
- }
-
- memcpy(dest, src, ucs2_len*sizeof(smb_ucs2_t));
- dest[ucs2_len] = 0;
- return dest;
-}
-
-/*******************************************************************
- Safe string cat into a string. maxlength includes the terminating zero.
- maxlength is in bytes.
-********************************************************************/
-
-smb_ucs2_t *safe_strcat_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
-{
- size_t ucs2_src_len, ucs2_dest_len;
-
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcat_w\n"));
- return NULL;
- }
-
- if (!src)
- return dest;
-
- /*
- * Convert maxlength to smb_ucs2_t units.
- */
-
- maxlength /= sizeof(smb_ucs2_t);
-
- ucs2_src_len = strlen_w(src);
- ucs2_dest_len = strlen_w(dest);
-
- if (ucs2_src_len + ucs2_dest_len >= maxlength) {
- fstring out;
- int new_len = maxlength - ucs2_dest_len - 1;
- DEBUG(0,("ERROR: string overflow by %u characters in safe_strcat_w [%.50s]\n",
- (unsigned int)(sizeof(smb_ucs2_t)*(ucs2_src_len + ucs2_dest_len - maxlength)),
- unicode_to_unix(out,src,sizeof(out))) );
- ucs2_src_len = (size_t)(new_len > 0 ? new_len : 0);
- }
-
- memcpy(&dest[ucs2_dest_len], src, ucs2_src_len*sizeof(smb_ucs2_t));
- dest[ucs2_dest_len + ucs2_src_len] = 0;
- return dest;
+ *dest = 0;
}
/*******************************************************************
- Compare the two strings s1 and s2. len is in ucs2 units.
-********************************************************************/
-
-int strcmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+ Convert a buffer4 to space-separated ASCII.
+ ********************************************************************/
+void buffer4_to_str(char *dest, const BUFFER4 *str, size_t maxlen)
{
- smb_ucs2_t c1, c2;
+ char *destend;
+ const uchar *src;
+ size_t len;
+ register uint16 c;
- for (;;) {
- c1 = *s1++;
- c2 = *s2++;
+ src = str->buffer;
+ len = MIN(str->buf_len, maxlen);
+ destend = dest + len;
- if (c1 != c2)
- return c1 - c2;
+ while (dest < destend)
+ {
+ c = *(src++);
+ *(dest++) = (char)c;
+ }
- if (c1 == 0)
- return 0;
- }
- return 0;
+ *dest = 0;
}
-/*******************************************************************
- Compare the first n characters of s1 to s2. len is in ucs2 units.
-********************************************************************/
-
-int strncmp_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2, size_t len)
-{
- smb_ucs2_t c1, c2;
-
- for (; len != 0; --len) {
- c1 = *s1++;
- c2 = *s2++;
-
- if (c1 != c2)
- return c1 - c2;
-
- if (c1 == 0)
- return 0;
-
- }
- return 0;
-}
/*******************************************************************
- Search string s2 from s1.
+creates a new UNISTR2.
********************************************************************/
-
-smb_ucs2_t *strstr_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
+UNISTR2 *unistr2_new(const char *init)
{
- size_t len = strlen_w(s2);
-
- if (!*s2)
- return (smb_ucs2_t *)s1;
-
- for(;*s1; s1++) {
- if (*s1 == *s2) {
- if (strncmp_w(s1, s2, len) == 0)
- return (smb_ucs2_t *)s1;
- }
+ UNISTR2 *str;
+ str = g_new(UNISTR2, 1);
+ if (str == NULL)
+ {
+ DEBUG(1, ("malloc problem in unistr2_new\n"));
+ return NULL;
}
- return NULL;
-}
-/*******************************************************************
- Search for ucs2 char c from the beginning of s.
-********************************************************************/
-
-smb_ucs2_t *strchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
-{
- do {
- if (*s == c)
- return (smb_ucs2_t *)s;
- } while (*s++);
-
- return NULL;
-}
-
-/*******************************************************************
- Search for ucs2 char c from the end of s.
-********************************************************************/
+ str->uni_max_len = 0;
+ str->undoc = 0;
+ str->uni_str_len = 0;
-smb_ucs2_t *strrchr_w(const smb_ucs2_t *s, smb_ucs2_t c)
-{
- smb_ucs2_t *retval = 0;
-
- do {
- if (*s == c)
- retval = (smb_ucs2_t *)s;
- } while (*s++);
+ if (init != NULL)
+ {
+ unistr2_assign_ascii_str(str, init);
+ }
- return retval;
+ return str;
}
-/*******************************************************************
- Search token from s1 separated by any ucs2 char of s2.
-********************************************************************/
-
-smb_ucs2_t *strtok_w(smb_ucs2_t *s1, const smb_ucs2_t *s2)
+UNISTR2 *unistr2_assign(UNISTR2 *str, const uint16 *src, size_t len)
{
- static smb_ucs2_t *s = NULL;
- smb_ucs2_t *q;
-
- if (!s1) {
- if (!s)
- return NULL;
- s1 = s;
+ if (str == NULL)
+ {
+ DEBUG(1, ("NULL unistr2\n"));
+ return NULL;
}
- for (q = s1; *s1; s1++) {
- smb_ucs2_t *p = strchr_w(s2, *s1);
- if (p) {
- if (s1 != q) {
- s = s1 + 1;
- *s1 = '\0';
- return q;
- }
- q = s1 + 1;
- }
+ if (src == NULL)
+ {
+ len = 0;
}
- s = NULL;
- if (*q)
- return q;
-
- return NULL;
-}
-
-/*******************************************************************
- Duplicate a ucs2 string.
-********************************************************************/
-
-smb_ucs2_t *strdup_w(const smb_ucs2_t *s)
-{
- size_t newlen = (strlen_w(s)+1)*sizeof(smb_ucs2_t);
- smb_ucs2_t *newstr = (smb_ucs2_t *)malloc(newlen);
- if (newstr == NULL)
- return NULL;
- safe_strcpy_w(newstr, s, newlen);
- return newstr;
-}
-
-/*******************************************************************
- Mapping tables for UNICODE character. Allows toupper/tolower and
- isXXX functions to work.
-********************************************************************/
-
-typedef struct {
- smb_ucs2_t lower;
- smb_ucs2_t upper;
- unsigned char flags;
-} smb_unicode_table_t;
-
-static smb_unicode_table_t map_table[] = {
-#include "unicode_map_table.h"
-};
-
-/*******************************************************************
- Is an upper case wchar.
-********************************************************************/
-
-int isupper_w( smb_ucs2_t val)
-{
- return (map_table[val].flags & UNI_UPPER);
-}
-
-/*******************************************************************
- Is a lower case wchar.
-********************************************************************/
-
-int islower_w( smb_ucs2_t val)
-{
- return (map_table[val].flags & UNI_LOWER);
-}
-
-/*******************************************************************
- Is a digit wchar.
-********************************************************************/
-
-int isdigit_w( smb_ucs2_t val)
-{
- return (map_table[val].flags & UNI_DIGIT);
-}
-
-/*******************************************************************
- Is a hex digit wchar.
-********************************************************************/
-
-int isxdigit_w( smb_ucs2_t val)
-{
- return (map_table[val].flags & UNI_XDIGIT);
-}
-
-/*******************************************************************
- Is a space wchar.
-********************************************************************/
-
-int isspace_w( smb_ucs2_t val)
-{
- return (map_table[val].flags & UNI_SPACE);
-}
-
-/*******************************************************************
- Convert a wchar to upper case.
-********************************************************************/
-
-smb_ucs2_t toupper_w( smb_ucs2_t val )
-{
- return map_table[val].upper;
-}
-
-/*******************************************************************
- Convert a wchar to lower case.
-********************************************************************/
-
-smb_ucs2_t tolower_w( smb_ucs2_t val )
-{
- return map_table[val].lower;
-}
-
-static smb_ucs2_t *last_ptr = NULL;
-
-void set_first_token_w(smb_ucs2_t *ptr)
-{
- last_ptr = ptr;
-}
-
-/****************************************************************************
- Get the next token from a string, return False if none found
- handles double-quotes.
- Based on a routine by GJC@VILLAGE.COM.
- Extensively modified by Andrew.Tridgell@anu.edu.au
- bufsize is in bytes.
-****************************************************************************/
-
-static smb_ucs2_t sep_list[] = { (smb_ucs2_t)' ', (smb_ucs2_t)'\t', (smb_ucs2_t)'\n', (smb_ucs2_t)'\r', 0};
-static smb_ucs2_t quotechar = (smb_ucs2_t)'\"';
-
-BOOL next_token_w(smb_ucs2_t **ptr, smb_ucs2_t *buff, smb_ucs2_t *sep, size_t bufsize)
-{
- smb_ucs2_t *s;
- BOOL quoted;
- size_t len=1;
-
- /*
- * Convert bufsize to smb_ucs2_t units.
- */
-
- bufsize /= sizeof(smb_ucs2_t);
-
- if (!ptr)
- ptr = &last_ptr;
- if (!ptr)
- return(False);
-
- s = *ptr;
-
- /*
- * Default to simple separators.
- */
-
- if (!sep)
- sep = sep_list;
-
- /*
- * Find the first non sep char.
- */
-
- while(*s && strchr_w(sep,*s))
- s++;
-
- /*
- * Nothing left ?
- */
+ if (len >= MAX_UNISTRLEN)
+ {
+ len = MAX_UNISTRLEN - 1;
+ }
- if (!*s)
- return(False);
+ unistr2_grow(str, len + 1);
- /*
- * Copy over the token.
- */
+ /* set up string lengths. */
+ str->uni_max_len = len;
+ str->undoc = 0;
+ str->uni_str_len = len;
- for (quoted = False; len < bufsize && *s && (quoted || !strchr_w(sep,*s)); s++) {
- if (*s == quotechar) {
- quoted = !quoted;
- } else {
- len++;
- *buff++ = *s;
- }
+ if (len != 0)
+ {
+ memcpy(str->buffer, src, len * sizeof(uint16));
}
+ str->buffer[len] = 0;
- *ptr = (*s) ? s+1 : s;
- *buff = 0;
- last_ptr = *ptr;
-
- return(True);
+ return str;
}
-/****************************************************************************
- Convert list of tokens to array; dependent on above routine.
- Uses last_ptr from above - bit of a hack.
-****************************************************************************/
-
-smb_ucs2_t **toktocliplist_w(int *ctok, smb_ucs2_t *sep)
+UNISTR2 *unistr2_assign_ascii(UNISTR2 *str, const char *buf, int len)
{
- smb_ucs2_t *s=last_ptr;
- int ictok=0;
- smb_ucs2_t **ret, **iret;
-
- if (!sep)
- sep = sep_list;
-
- while(*s && strchr_w(sep,*s))
- s++;
-
- /*
- * Nothing left ?
- */
-
- if (!*s)
- return(NULL);
-
- do {
- ictok++;
- while(*s && (!strchr_w(sep,*s)))
- s++;
- while(*s && strchr_w(sep,*s))
- *s++=0;
- } while(*s);
-
- *ctok = ictok;
- s = last_ptr;
-
- if (!(ret=iret=malloc(ictok*sizeof(smb_ucs2_t *))))
+ if (str == NULL)
+ {
+ DEBUG(1, ("NULL unistr2\n"));
return NULL;
-
- while(ictok--) {
- *iret++=s;
- while(*s++)
- ;
- while(!*s)
- s++;
}
- return ret;
-}
-
-/*******************************************************************
- Case insensitive string compararison.
-********************************************************************/
-
-int StrCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t)
-{
- /*
- * Compare until we run out of string, either t or s, or find a difference.
- */
-
- while (*s && *t && toupper_w(*s) == toupper_w(*t)) {
- s++;
- t++;
+ if (buf == NULL)
+ {
+ len = 0;
}
- return(toupper_w(*s) - toupper_w(*t));
-}
-
-/*******************************************************************
- Case insensitive string compararison, length limited.
-********************************************************************/
-
-int StrnCaseCmp_w(const smb_ucs2_t *s, const smb_ucs2_t *t, size_t n)
-{
- /*
- * Compare until we run out of string, either t or s, or chars.
- */
-
- while (n && *s && *t && toupper_w(*s) == toupper_w(*t)) {
- s++;
- t++;
- n--;
+ if (len >= MAX_UNISTRLEN)
+ {
+ len = MAX_UNISTRLEN - 1;
}
- /*
- * Not run out of chars - strings are different lengths.
- */
-
- if (n)
- return(toupper_w(*s) - toupper_w(*t));
-
- /*
- * Identical up to where we run out of chars,
- * and strings are same length.
- */
+ unistr2_grow(str, len + 1);
- return(0);
-}
-
-/*******************************************************************
- Compare 2 strings.
-********************************************************************/
-
-BOOL strequal_w(const smb_ucs2_t *s1, const smb_ucs2_t *s2)
-{
- if (s1 == s2)
- return(True);
- if (!s1 || !s2)
- return(False);
-
- return(StrCaseCmp_w(s1,s2)==0);
-}
+ /* set up string lengths. */
+ str->uni_max_len = len;
+ str->undoc = 0;
+ str->uni_str_len = len;
-/*******************************************************************
- Compare 2 strings up to and including the nth char.
-******************************************************************/
+ /* store the string (wide chars) */
+ ascii_to_unistr(str->buffer, buf, len);
-BOOL strnequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2,size_t n)
-{
- if (s1 == s2)
- return(True);
- if (!s1 || !s2 || !n)
- return(False);
-
- return(StrnCaseCmp_w(s1,s2,n)==0);
+ return str;
}
-/*******************************************************************
- Compare 2 strings (case sensitive).
-********************************************************************/
-
-BOOL strcsequal_w(const smb_ucs2_t *s1,const smb_ucs2_t *s2)
+UNISTR2 *unistr2_assign_ascii_str(UNISTR2 *str, const char *buf)
{
- if (s1 == s2)
- return(True);
- if (!s1 || !s2)
- return(False);
-
- return(strcmp_w(s1,s2)==0);
+ return unistr2_assign_ascii(str, buf, (buf ? strlen(buf) : 0));
}
/*******************************************************************
- Convert a string to lower case.
+grows the buffer of a UNISTR2.
+ doesn't shrink
+ doesn't modify lengh
********************************************************************/
-
-void strlower_w(smb_ucs2_t *s)
+UNISTR2 *unistr2_grow(UNISTR2 *str, size_t new_size)
{
- while (*s) {
- if (isupper_w(*s))
- *s = tolower_w(*s);
- s++;
+ if (str == NULL)
+ {
+ DEBUG(1, ("NULL unistr2\n"));
+ return NULL;
}
-}
-
-/*******************************************************************
- Convert a string to upper case.
-********************************************************************/
-
-void strupper_w(smb_ucs2_t *s)
-{
- while (*s) {
- if (islower_w(*s))
- *s = toupper_w(*s);
- s++;
+ /* It's currently a fake, yes */
+ if (new_size > MAX_UNISTRLEN)
+ {
+ DEBUG(3, ("Growing buffer beyond its current static size\n"));
}
+ return str;
}
-/*******************************************************************
- Convert a string to "normal" form.
-********************************************************************/
-
-void strnorm_w(smb_ucs2_t *s)
-{
- extern int case_default;
- if (case_default == CASE_UPPER)
- strupper_w(s);
- else
- strlower_w(s);
-}
/*******************************************************************
- Check if a string is in "normal" case.
+copies a UNISTR2 structure.
********************************************************************/
-
-BOOL strisnormal_w(smb_ucs2_t *s)
+BOOL unistr2upper(UNISTR2 *str, const UNISTR2 *from)
{
- extern int case_default;
- if (case_default == CASE_UPPER)
- return(!strhaslower_w(s));
+ if (from != NULL)
+ {
+ int i;
- return(!strhasupper_w(s));
-}
+ ZERO_STRUCTP(str);
-/****************************************************************************
- String replace.
-****************************************************************************/
+ /* copy up string lengths*/
+ str->uni_max_len = from->uni_max_len;
+ str->undoc = from->undoc;
+ str->uni_str_len = from->uni_str_len;
-void string_replace_w(smb_ucs2_t *s, smb_ucs2_t oldc, smb_ucs2_t newc)
-{
- while (*s) {
- if (oldc == *s)
- *s = newc;
- s++;
+ /* copy the string */
+ for (i = 0; i < from->uni_str_len; i++)
+ {
+ str->buffer[i] = toupper(from->buffer[i]);
+ }
+ }
+ else
+ {
+ str->uni_max_len = 1;
+ str->undoc = 0;
+ str->uni_str_len = 1;
+ str->buffer[0] = 0;
}
-}
-
-/*******************************************************************
- Skip past some strings in a buffer. n is in bytes.
-********************************************************************/
-
-smb_ucs2_t *skip_string_w(smb_ucs2_t *buf,size_t n)
-{
- while (n--)
- buf += (strlen_w(buf)*sizeof(smb_ucs2_t)) + 1;
- return(buf);
-}
-
-/*******************************************************************
- Count the number of characters in a string. Same as strlen_w in
- smb_ucs2_t string units.
-********************************************************************/
-size_t str_charnum_w(const smb_ucs2_t *s)
-{
- return strlen_w(s);
+ return True;
}
/*******************************************************************
- Trim the specified elements off the front and back of a string.
+copies a UNISTR2 structure.
********************************************************************/
-
-BOOL trim_string_w(smb_ucs2_t *s,const smb_ucs2_t *front,const smb_ucs2_t *back)
+BOOL copy_unistr2(UNISTR2 *str, const UNISTR2 *from)
{
- BOOL ret = False;
- size_t front_len = (front && *front) ? strlen_w(front) : 0;
- size_t back_len = (back && *back) ? strlen_w(back) : 0;
- size_t s_len;
-
- while (front_len && strncmp_w(s, front, front_len) == 0) {
- smb_ucs2_t *p = s;
- ret = True;
-
- while (1) {
- if (!(*p = p[front_len]))
- break;
- p++;
- }
- }
-
- if(back_len) {
- s_len = strlen_w(s);
- while ((s_len >= back_len) &&
- (strncmp_w(s + s_len - back_len, back, back_len)==0)) {
- ret = True;
- s[s_len - back_len] = 0;
- s_len = strlen_w(s);
- }
+ if (str == NULL)
+ {
+ return False;
}
+ if (from != NULL)
+ {
+ ZERO_STRUCTP(str);
- return(ret);
-}
-
-/****************************************************************************
- Does a string have any uppercase chars in it ?
-****************************************************************************/
+ /* set up string lengths. add one if string is not null-terminated */
+ str->uni_max_len = from->uni_max_len;
+ str->undoc = from->undoc;
+ str->uni_str_len = from->uni_str_len;
-BOOL strhasupper_w(const smb_ucs2_t *s)
-{
- while (*s) {
- if (isupper_w(*s))
- return(True);
- s++;
+ /* copy the string */
+ memcpy(str->buffer, from->buffer, str->uni_str_len * 2);
}
- return(False);
-}
-
-/****************************************************************************
- Does a string have any lowercase chars in it ?
-****************************************************************************/
-
-BOOL strhaslower_w(const smb_ucs2_t *s)
-{
- while (*s) {
- if (islower(*s))
- return(True);
- s++;
+ else
+ {
+ str->uni_max_len = 1;
+ str->undoc = 0;
+ str->uni_str_len = 1;
+ str->buffer[0] = 0;
}
- return(False);
-}
-
-/****************************************************************************
- Find the number of 'c' chars in a string.
-****************************************************************************/
-size_t count_chars_w(const smb_ucs2_t *s,smb_ucs2_t c)
-{
- size_t count=0;
-
- while (*s) {
- if (*s == c)
- count++;
- s++;
- }
- return(count);
+ return True;
}
/*******************************************************************
- Return True if a string consists only of one particular character.
+duplicates a UNISTR2 structure.
********************************************************************/
-
-BOOL str_is_all_w(const smb_ucs2_t *s,smb_ucs2_t c)
+UNISTR2 *unistr2_dup(const UNISTR2 *name)
{
- if(s == NULL)
- return False;
- if(!*s)
- return False;
-
- while (*s) {
- if (*s != c)
- return False;
- s++;
- }
- return True;
+ UNISTR2 *copy = (UNISTR2*)malloc(sizeof(*copy));
+ copy_unistr2(copy, name);
+ return copy;
}
/*******************************************************************
- Paranoid strcpy into a buffer of given length (includes terminating
- zero. Strips out all but 'a-Z0-9' and replaces with '_'. Deliberately
- does *NOT* check for multibyte characters. Don't change it !
- maxlength is in bytes.
+frees a UNISTR2 structure.
********************************************************************/
-
-smb_ucs2_t *alpha_strcpy_w(smb_ucs2_t *dest, const smb_ucs2_t *src, size_t maxlength)
+void unistr2_free(UNISTR2 *name)
{
- size_t len, i;
-
- /*
- * Convert to smb_ucs2_t units.
- */
-
- maxlength /= sizeof(smb_ucs2_t);
-
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in alpha_strcpy_w\n"));
- return NULL;
- }
-
- if (!src) {
- *dest = 0;
- return dest;
- }
-
- len = strlen_w(src);
- if (len >= maxlength)
- len = maxlength - 1;
-
- for(i = 0; i < len; i++) {
- smb_ucs2_t val = src[i];
- if(isupper_w(val) ||islower_w(val) || isdigit_w(val))
- dest[i] = src[i];
- else
- dest[i] = (smb_ucs2_t)'_';
- }
-
- dest[i] = 0;
-
- return dest;
+ free(name);
}
-/****************************************************************************
- Like strncpy but always null terminates. Make sure there is room !
- The variable n should always be one less than the available size and is in bytes.
-****************************************************************************/
-
-smb_ucs2_t *StrnCpy_w(smb_ucs2_t *dest,const smb_ucs2_t *src,size_t n)
-{
- smb_ucs2_t *d = dest;
- if (!dest)
- return(NULL);
- if (!src) {
- *dest = 0;
- return(dest);
- }
-
- /*
- * Convert to smb_ucs2_t units.
- */
-
- n /= sizeof(smb_ucs2_t);
-
- while (n-- && (*d++ = *src++))
- ;
- *d = 0;
- return(dest);
-}
-
-/****************************************************************************
- Like strncpy but copies up to the character marker. Always null terminates.
- returns a pointer to the character marker in the source string (src).
- n is in bytes.
-****************************************************************************/
-
-smb_ucs2_t *strncpyn_w(smb_ucs2_t *dest, const smb_ucs2_t *src,size_t n, smb_ucs2_t c)
-{
- smb_ucs2_t *p;
- size_t str_len;
-
- p = strchr_w(src, c);
- if (p == NULL) {
- fstring cval;
- smb_ucs2_t mbcval[2];
- mbcval[0] = c;
- mbcval[1] = 0;
- DEBUG(5, ("strncpyn_w: separator character (%s) not found\n",
- unicode_to_unix(cval,mbcval,sizeof(cval)) ));
- return NULL;
- }
-
- str_len = PTR_DIFF(p, src) + sizeof(smb_ucs2_t);
- safe_strcpy_w(dest, src, MIN(n, str_len));
-
- return p;
-}
-
-/*************************************************************
- Routine to get hex characters and turn them into a 16 byte array.
- The array can be variable length, and any non-hex-numeric
- characters are skipped. "0xnn" or "0Xnn" is specially catered
- for. len is in bytes.
- Valid examples: "0A5D15"; "0x15, 0x49, 0xa2"; "59\ta9\te3\n"
-**************************************************************/
-
-static smb_ucs2_t hexprefix[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'x', 0 };
-static smb_ucs2_t hexchars[] = { (smb_ucs2_t)'0', (smb_ucs2_t)'1', (smb_ucs2_t)'2', (smb_ucs2_t)'3',
- (smb_ucs2_t)'4', (smb_ucs2_t)'5', (smb_ucs2_t)'6', (smb_ucs2_t)'7',
- (smb_ucs2_t)'8', (smb_ucs2_t)'9', (smb_ucs2_t)'A', (smb_ucs2_t)'B',
- (smb_ucs2_t)'C', (smb_ucs2_t)'D', (smb_ucs2_t)'E', (smb_ucs2_t)'F', 0 };
-
-size_t strhex_to_str_w(char *p, size_t len, const smb_ucs2_t *strhex)
-{
- size_t i;
- size_t num_chars = 0;
- unsigned char lonybble, hinybble;
- smb_ucs2_t *p1 = NULL, *p2 = NULL;
-
- /*
- * Convert to smb_ucs2_t units.
- */
-
- len /= sizeof(smb_ucs2_t);
-
- for (i = 0; i < len && strhex[i] != 0; i++) {
- if (strnequal_w(hexchars, hexprefix, 2)) {
- i++; /* skip two chars */
- continue;
- }
-
- if (!(p1 = strchr_w(hexchars, toupper_w(strhex[i]))))
- break;
-
- i++; /* next hex digit */
-
- if (!(p2 = strchr_w(hexchars, toupper_w(strhex[i]))))
- break;
-
- /* get the two nybbles */
- hinybble = (PTR_DIFF(p1, hexchars)/sizeof(smb_ucs2_t));
- lonybble = (PTR_DIFF(p2, hexchars)/sizeof(smb_ucs2_t));
-
- p[num_chars] = (hinybble << 4) | lonybble;
- num_chars++;
-
- p1 = NULL;
- p2 = NULL;
- }
- return num_chars;
-}
-
-/****************************************************************************
- Check if a string is part of a list.
-****************************************************************************/
-
-BOOL in_list_w(smb_ucs2_t *s,smb_ucs2_t *list,BOOL casesensitive)
-{
- wpstring tok;
- smb_ucs2_t *p=list;
-
- if (!list)
- return(False);
-
- while (next_token_w(&p,tok,LIST_SEP_W,sizeof(tok))) {
- if (casesensitive) {
- if (strcmp_w(tok,s) == 0)
- return(True);
- } else {
- if (StrCaseCmp_w(tok,s) == 0)
- return(True);
- }
- }
- return(False);
-}
-
-/* This is used to prevent lots of mallocs of size 2 */
-static smb_ucs2_t *null_string = NULL;
-
-/****************************************************************************
- Set a string value, allocing the space for the string.
-****************************************************************************/
-
-BOOL string_init_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
-{
- size_t l;
-
- if (!null_string) {
- if((null_string = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t))) == NULL) {
- DEBUG(0,("string_init_w: malloc fail for null_string.\n"));
- return False;
- }
- *null_string = 0;
- }
-
- if (!src)
- src = null_string;
-
- l = strlen_w(src);
-
- if (l == 0)
- *dest = null_string;
- else {
- (*dest) = (smb_ucs2_t *)malloc(sizeof(smb_ucs2_t)*(l+1));
- if ((*dest) == NULL) {
- DEBUG(0,("Out of memory in string_init_w\n"));
- return False;
- }
-
- wpstrcpy(*dest,src);
- }
- return(True);
-}
-
-/****************************************************************************
- Free a string value.
-****************************************************************************/
-
-void string_free_w(smb_ucs2_t **s)
-{
- if (!s || !(*s))
- return;
- if (*s == null_string)
- *s = NULL;
- if (*s)
- free((char *)*s);
- *s = NULL;
-}
-
-/****************************************************************************
- Set a string value, allocing the space for the string, and deallocating any
- existing space.
-****************************************************************************/
-
-BOOL string_set_w(smb_ucs2_t **dest,const smb_ucs2_t *src)
+/*******************************************************************
+ case insensitive string compararison
+********************************************************************/
+int StrCaseCmpW(const UNISTR2 *ws, const UNISTR2 *wt)
{
- string_free_w(dest);
-
- return(string_init_w(dest,src));
-}
-
-/****************************************************************************
- Substitute a string for a pattern in another string. Make sure there is
- enough room !
-
- This routine looks for pattern in s and replaces it with
- insert. It may do multiple replacements.
+ int len = MIN(ws->uni_str_len, wt->uni_str_len);
+ uint16 *s = ws->buffer;
+ uint16 *t = wt->buffer;
+ uint16 sc;
+ uint16 tc;
- Any of " ; ' $ or ` in the insert string are replaced with _
- if len==0 then no length check is performed
- len is in bytes.
-****************************************************************************/
+ while (len > 0 && *s && *t && toupper(*s) == toupper(*t))
+ {
+ s++;
+ t++;
+ len--;
+ }
-void string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
-{
- smb_ucs2_t *p;
- ssize_t ls,lp,li, i;
-
- /*
- * Convert to smb_ucs2_t units.
- */
-
- len /= sizeof(smb_ucs2_t);
-
- if (!insert || !pattern || !s)
- return;
-
- ls = (ssize_t)strlen_w(s);
- lp = (ssize_t)strlen_w(pattern);
- li = (ssize_t)strlen_w(insert);
-
- if (!*pattern)
- return;
-
- while (lp <= ls && (p = strstr_w(s,pattern))) {
- if (len && (ls + (li-lp) >= len)) {
- fstring out;
- DEBUG(0,("ERROR: string overflow by %d in string_sub_w(%.50s, %d)\n",
- (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
- unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
- break;
- }
- if (li != lp)
- memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
-
- for (i=0;i<li;i++) {
- switch (insert[i]) {
- case (smb_ucs2_t)'`':
- case (smb_ucs2_t)'"':
- case (smb_ucs2_t)'\'':
- case (smb_ucs2_t)';':
- case (smb_ucs2_t)'$':
- case (smb_ucs2_t)'%':
- case (smb_ucs2_t)'\r':
- case (smb_ucs2_t)'\n':
- p[i] = (smb_ucs2_t)'_';
- break;
- default:
- p[i] = insert[i];
- }
- }
- s = p + li;
- ls += (li-lp);
+ if (len == 0 && ws->uni_str_len == wt->uni_str_len)
+ {
+ return 0;
}
-}
-void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert)
-{
- string_sub_w(s, pattern, insert, sizeof(wfstring));
-}
+ sc = toupper(*s);
+ tc = toupper(*t);
-void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert)
-{
- string_sub_w(s, pattern, insert, sizeof(wpstring));
-}
-
-/****************************************************************************
- Similar to string_sub() but allows for any character to be substituted.
- Use with caution !
- if len==0 then no length check is performed.
-****************************************************************************/
-
-void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len)
-{
- smb_ucs2_t *p;
- ssize_t ls,lp,li;
-
- /*
- * Convert to smb_ucs2_t units.
- */
-
- len /= sizeof(smb_ucs2_t);
-
- if (!insert || !pattern || !s)
- return;
-
- ls = (ssize_t)strlen_w(s);
- lp = (ssize_t)strlen_w(pattern);
- li = (ssize_t)strlen_w(insert);
-
- if (!*pattern)
- return;
-
- while (lp <= ls && (p = strstr_w(s,pattern))) {
- if (len && (ls + (li-lp) >= len)) {
- fstring out;
- DEBUG(0,("ERROR: string overflow by %d in all_string_sub_w(%.50s, %d)\n",
- (int)(sizeof(smb_ucs2_t)*(ls + (li-lp) - len)),
- unicode_to_unix(out,pattern,sizeof(out)), (int)len*sizeof(smb_ucs2_t)));
- break;
- }
- if (li != lp)
- memmove(p+li,p+lp,sizeof(smb_ucs2_t)*(strlen_w(p+lp)+1));
-
- memcpy(p, insert, li*sizeof(smb_ucs2_t));
- s = p + li;
- ls += (li-lp);
+ if (wt->uni_str_len > ws->uni_str_len)
+ {
+ /* wt is longer, therefore last ws char must be 0 */
+ sc = 0;
}
-}
-
-/****************************************************************************
- Splits out the front and back at a separator.
-****************************************************************************/
-
-void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back)
-{
- smb_ucs2_t *p = strrchr_w(path, sep);
-
- if (p != NULL)
- *p = 0;
- if (front != NULL)
- wpstrcpy(front, path);
-
- if (p != NULL) {
- if (back != NULL)
- wpstrcpy(back, p+1);
- *p = (smb_ucs2_t)'\\';
- } else {
- if (back != NULL)
- back[0] = 0;
+ if (ws->uni_str_len > wt->uni_str_len)
+ {
+ /* ws is longer, therefore last wt char must be 0 */
+ tc = 0;
}
-}
-
-
-/****************************************************************************
- Write an octal as a string.
-****************************************************************************/
-smb_ucs2_t *octal_string_w(int i)
-{
- static smb_ucs2_t wret[64];
- char ret[64];
-
- if (i == -1)
- slprintf(ret, sizeof(ret), "-1");
- else
- slprintf(ret, sizeof(ret), "0%o", i);
- return unix_to_unicode(wret, ret, sizeof(wret));
+ return sc - tc;
}
-
-/****************************************************************************
- Truncate a string at a specified length.
- length is in bytes.
-****************************************************************************/
-
-smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length)
+/*******************************************************************
+ compare 2 UNISTR2 strings . first implementation, unicode string
+ comparison isn't simple, you don't necessarily have a NULL-termination
+ character but it's the same string...
+********************************************************************/
+BOOL unistr2equal(const UNISTR2 *s1, const UNISTR2 *s2)
{
- /*
- * Convert to smb_ucs2_t units.
- */
-
- length /= sizeof(smb_ucs2_t);
-
- if (s && strlen_w(s) > length)
- s[length] = 0;
+#if 0
+ DEBUG(20,("unistr2equal:\n"));
+ dump_data(20, s1, sizeof(*s1));
+ dump_data(20, s2, sizeof(*s2));
+#endif
- return s;
+ if (s1 == s2) return(True);
+ if (!s1 || !s2) return(False);
+
+ return(StrCaseCmpW(s1,s2)==0);
}
diff --git a/source/lib/vagent.c b/source/lib/vagent.c
new file mode 100644
index 00000000000..96df03e2f3e
--- /dev/null
+++ b/source/lib/vagent.c
@@ -0,0 +1,242 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2
+ SMB agent/socket plugin
+ Copyright (C) Andrew Tridgell 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "smb.h"
+
+extern int DEBUGLEVEL;
+
+
+/****************************************************************************
+terminate socket connection
+****************************************************************************/
+static void sock_redir_free(struct vagent_ops *va, struct sock_redir *sock)
+{
+ if (sock->c != -1)
+ {
+ close(sock->c);
+ sock->c = -1;
+ }
+ if (sock->n != NULL)
+ {
+ va->free_sock(sock->n);
+ sock->n = NULL;
+ }
+ free(sock);
+}
+
+/****************************************************************************
+free a sockent array
+****************************************************************************/
+static void free_sock_array(struct vagent_ops*va)
+{
+ void(*fn)(void*) = (void(*)(void*))&va->free_sock;
+ free_void_array(va->num_socks, (void**)va->socks, *fn);
+}
+
+/****************************************************************************
+add a sockent state to the array
+****************************************************************************/
+static struct sock_redir* add_sock_to_array(uint32 *len,
+ struct sock_redir ***array,
+ struct sock_redir *sock)
+{
+ int i;
+ for (i = 0; i < (*len); i++)
+ {
+ if ((*array)[i] == NULL)
+ {
+ (*array)[i] = sock;
+ return sock;
+ }
+ }
+
+ return (struct sock_redir*)add_item_to_array(len,
+ (void***)array, (void*)sock);
+
+}
+
+/****************************************************************************
+initiate sockent array
+****************************************************************************/
+void init_sock_redir(struct vagent_ops*va)
+{
+ va->socks = NULL;
+ va->num_socks = 0;
+}
+
+/****************************************************************************
+terminate sockent array
+****************************************************************************/
+void free_sock_redir(struct vagent_ops*va)
+{
+ free_sock_array(va);
+ init_sock_redir(va);
+}
+
+/****************************************************************************
+create a new sockent state from user credentials
+****************************************************************************/
+static struct sock_redir *sock_redir_get(struct vagent_ops *va, int fd)
+{
+ struct sock_redir *sock = (struct sock_redir*)malloc(sizeof(*sock));
+
+ if (sock == NULL)
+ {
+ return NULL;
+ }
+
+ ZERO_STRUCTP(sock);
+
+ sock->c = fd;
+ sock->n = NULL;
+
+ DEBUG(10,("sock_redir_get:\tfd:\t%d\n", fd));
+
+ return sock;
+}
+/****************************************************************************
+init sock state
+****************************************************************************/
+static void sock_add(struct vagent_ops *va, int fd)
+{
+ struct sock_redir *sock;
+ sock = sock_redir_get(va, fd);
+ if (sock != NULL)
+ {
+ add_sock_to_array(&va->num_socks, &va->socks, sock);
+ }
+}
+
+/****************************************************************************
+delete a sockent state
+****************************************************************************/
+static BOOL sock_del(struct vagent_ops *va, int fd)
+{
+ int i;
+
+ for (i = 0; i < va->num_socks; i++)
+ {
+ if (va->socks[i] == NULL) continue;
+ if (va->socks[i]->c == fd)
+ {
+ sock_redir_free(va, va->socks[i]);
+ va->socks[i] = NULL;
+ return True;
+ }
+ }
+
+ return False;
+}
+
+void start_agent(struct vagent_ops *va)
+{
+ int s, c;
+
+ s = va->get_agent_sock(va->id);
+
+ while (1)
+ {
+ int i;
+ fd_set fds;
+ int num;
+ struct sockaddr_un addr;
+ int in_addrlen = sizeof(addr);
+ int maxfd = s;
+
+ FD_ZERO(&fds);
+ FD_SET(s, &fds);
+
+ for (i = 0; i < va->num_socks; i++)
+ {
+ if (va->socks[i] != NULL)
+ {
+ int fd = va->socks[i]->c;
+ FD_SET(fd, &fds);
+ maxfd = MAX(maxfd, fd);
+
+ if (va->socks[i]->n != NULL)
+ {
+ fd = va->socks[i]->s;
+ FD_SET(fd, &fds);
+ maxfd = MAX(fd, maxfd);
+ }
+ }
+ }
+
+ dbgflush();
+ num = sys_select(maxfd+1,&fds,NULL, NULL);
+
+ if (num <= 0)
+ {
+ continue;
+ }
+
+ if (FD_ISSET(s, &fds))
+ {
+ FD_CLR(s, &fds);
+ c = accept(s, (struct sockaddr*)&addr, &in_addrlen);
+ if (c != -1)
+ {
+ sock_add(va, c);
+ }
+ }
+
+ for (i = 0; i < va->num_socks; i++)
+ {
+ if (va->socks[i] == NULL)
+ {
+ continue;
+ }
+ if (FD_ISSET(va->socks[i]->c, &fds))
+ {
+ FD_CLR(va->socks[i]->c, &fds);
+ if (!va->process_cli_sock(va->socks,
+ va->num_socks,
+ va->socks[i]))
+ {
+ sock_redir_free(va, va->socks[i]);
+ va->socks[i] = NULL;
+ }
+ }
+ if (va->socks[i] == NULL)
+ {
+ continue;
+ }
+ if (va->socks[i]->n == NULL)
+ {
+ continue;
+ }
+ if (FD_ISSET(va->socks[i]->s, &fds))
+ {
+ FD_CLR(va->socks[i]->s, &fds);
+ if (!va->process_srv_sock(va->socks,
+ va->num_socks,
+ va->socks[i]->s))
+ {
+ sock_redir_free(va, va->socks[i]);
+ va->socks[i] = NULL;
+ }
+ }
+ }
+ }
+}
+
diff --git a/source/lib/vuser.c b/source/lib/vuser.c
new file mode 100644
index 00000000000..7456917c3f9
--- /dev/null
+++ b/source/lib/vuser.c
@@ -0,0 +1,209 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Password and authentication handling
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/* this holds info on user ids that are already validated for this VC */
+static int num_validated_users = 0;
+
+/****************************************************************************
+check if a uid has been validated.
+****************************************************************************/
+BOOL is_valid_user_struct(const vuser_key * key)
+{
+ if (key == NULL)
+ {
+ return False;
+ }
+
+ if (key->vuid == UID_FIELD_INVALID)
+ {
+ return False;
+ }
+ return tdb_lookup_vuid(key, NULL);
+}
+
+/****************************************************************************
+check if a uid has been validated, and return an pointer to the user_struct
+if it has. NULL if not. vuid is biased by an offset. This allows us to
+tell random client vuid's (normally zero) from valid vuids.
+****************************************************************************/
+user_struct *get_valid_user_struct(const vuser_key * key)
+{
+ user_struct *usr = NULL;
+ if (key == NULL)
+ {
+ return NULL;
+ }
+
+ if (key->vuid == UID_FIELD_INVALID)
+ {
+ return NULL;
+ }
+ if (!tdb_lookup_vuid(key, &usr))
+ {
+ return NULL;
+ }
+ if (((int)usr->uid) == -1 || ((int)usr->gid) == -1)
+ {
+ vuid_free_user_struct(usr);
+ return NULL;
+ }
+ return usr;
+}
+
+/****************************************************************************
+invalidate a uid
+****************************************************************************/
+void invalidate_vuid(vuser_key * key)
+{
+ tdb_delete_vuid(key);
+}
+
+
+/****************************************************************************
+return a validated username
+****************************************************************************/
+BOOL validated_username(vuser_key * key, char *name, size_t len)
+{
+ user_struct *vuser = get_valid_user_struct(key);
+ if (vuser == NULL)
+ {
+ return False;
+ }
+ safe_strcpy(name, vuser->name, len - 1);
+ return True;
+}
+
+
+/****************************************************************************
+register a uid/name pair as being valid and that a valid password
+has been given. vuid is biased by an offset. This allows us to
+tell random client vuid's (normally zero) from valid vuids.
+****************************************************************************/
+uint16 create_vuid(pid_t pid,
+ uid_t uid, gid_t gid,
+ int n_groups, gid_t * groups,
+ const char *unix_name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest, const NET_USER_INFO_3 * info3)
+{
+ user_struct vuser;
+ vuser_key key;
+ uint16 vuid;
+
+ vuser.uid = uid;
+ vuser.gid = gid;
+ vuser.guest = guest;
+ fstrcpy(vuser.name, unix_name);
+ fstrcpy(vuser.requested_name, requested_name);
+ fstrcpy(vuser.real_name, real_name);
+ memcpy(&vuser.usr, info3, sizeof(vuser.usr));
+
+ vuser.n_groups = n_groups;
+ vuser.groups = groups;
+
+ num_validated_users++;
+ vuid = (uint16) ((num_validated_users - 1) + VUID_OFFSET);
+
+ DEBUG(3, ("uid %d vuid %d registered to unix name %s\n",
+ (int)uid, vuid, unix_name));
+ dump_data_pw("vuid usr sess key:\n", vuser.usr.user_sess_key,
+ sizeof(vuser.usr.user_sess_key));
+
+ key.pid = (uint32) pid;
+ key.vuid = vuid;
+
+ if (!tdb_store_vuid(&key, &vuser))
+ {
+ return UID_FIELD_INVALID;
+ }
+
+ return vuid;
+}
+
+/****************************************************************************
+register a uid/name pair as being valid and that a valid password
+has been given. vuid is biased by an offset. This allows us to
+tell random client vuid's (normally zero) from valid vuids.
+****************************************************************************/
+uint16 register_vuid(pid_t pid, uid_t uid, gid_t gid,
+ const char *unix_name,
+ const char *requested_name,
+ BOOL guest, const NET_USER_INFO_3 * info3)
+{
+ int n_groups = 0;
+ gid_t *groups = NULL;
+ fstring real_name;
+ struct passwd *pwfile; /* for getting real name from passwd file */
+
+ /* Ensure no vuid gets registered in share level security. */
+ if (lp_security() == SEC_SHARE)
+ return UID_FIELD_INVALID;
+
+ /* Find all the groups this uid is in and store them.
+ Used by become_user() */
+ get_unixgroups(unix_name, uid, gid, &n_groups, &groups);
+
+ DEBUG(3, ("uid %d registered to name %s\n", (int)uid, unix_name));
+
+ DEBUG(3, ("Clearing default real name\n"));
+ fstrcpy(real_name, "<Full Name>\0");
+ if (lp_unix_realname())
+ {
+ if ((pwfile = hashed_getpwnam(unix_name)) != NULL)
+ {
+ DEBUG(3,
+ ("User name: %s\tReal name: %s\n", unix_name,
+ pwfile->pw_gecos));
+ fstrcpy(real_name, pwfile->pw_gecos);
+ }
+ }
+
+ return create_vuid(pid, uid, gid, n_groups, groups,
+ unix_name, requested_name,
+ real_name, guest, info3);
+}
+
+/*******************************************************************
+check if a username is OK
+********************************************************************/
+BOOL check_vuser_ok(struct uid_cache *cache, user_struct * vuser, int snum)
+{
+ int i;
+ for (i = 0; i < cache->entries; i++)
+ if (cache->list[i] == vuser->uid)
+ return (True);
+
+ if (!user_ok(vuser->name, snum))
+ return (False);
+
+ i = cache->entries % UID_CACHE_SIZE;
+ cache->list[i] = vuser->uid;
+
+ if (cache->entries < UID_CACHE_SIZE)
+ cache->entries++;
+
+ return (True);
+}
diff --git a/source/lib/vuser_db.c b/source/lib/vuser_db.c
new file mode 100644
index 00000000000..731387e82ad
--- /dev/null
+++ b/source/lib/vuser_db.c
@@ -0,0 +1,168 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * this module stores a user_struct which can be globally accessed (by root)
+ * across process boundaries, in order to obtain info about users currently
+ * accessing * samba.
+ *
+ * the database key is the process number (pid) of the creater of the
+ * structure plus the vuid - SMB virtual user id. NORMALLY, this would
+ * be smbd pid and an smbd-generated vuid.
+ *
+ */
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+static TDB_CONTEXT *tdb = NULL;
+
+BOOL tdb_delete_vuid( const vuser_key *uk)
+{
+ prs_struct key;
+ vuser_key k = *uk;
+
+ if (tdb == NULL)
+ {
+ if (!vuid_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10,("delete user %x,%x\n", uk->pid, uk->vuid));
+
+ prs_init(&key, 0, 4, False);
+ if (!vuid_io_key("key", &k, &key, 0))
+ {
+ return False;
+ }
+
+ prs_tdb_delete(tdb, &key);
+
+ prs_free_data(&key);
+
+ return True;
+}
+
+BOOL tdb_lookup_vuid( const vuser_key *uk, user_struct **usr)
+{
+ prs_struct key;
+ prs_struct data;
+ vuser_key k = *uk;
+
+ if (usr != NULL)
+ {
+ (*usr) = (user_struct *)malloc(sizeof(**usr));
+ if ((*usr) == NULL)
+ {
+ return False;
+ }
+ ZERO_STRUCTP((*usr));
+ }
+ if (tdb == NULL)
+ {
+ if (!vuid_init_db())
+ {
+ safe_free((*usr));
+ return False;
+ }
+ }
+
+ DEBUG(10,("lookup user %x,%x\n", uk->pid, uk->vuid));
+
+ prs_init(&key, 0, 4, False);
+ if (!vuid_io_key("key", &k, &key, 0))
+ {
+ prs_free_data(&key);
+ safe_free((*usr));
+ return False;
+ }
+
+ prs_tdb_fetch(tdb, &key, &data);
+
+ if (usr != NULL)
+ {
+ if (!vuid_io_user_struct("usr", (*usr), &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ safe_free((*usr));
+ return False;
+ }
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+BOOL tdb_store_vuid( const vuser_key *uk, user_struct *usr)
+{
+ prs_struct key;
+ prs_struct data;
+ vuser_key k = *uk;
+
+ if (tdb == NULL)
+ {
+ if (!vuid_init_db())
+ {
+ return False;
+ }
+ }
+
+ DEBUG(10,("storing user %x,%x\n", uk->pid, uk->vuid));
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!vuid_io_key("key", &k, &key, 0) ||
+ !vuid_io_user_struct("usr", usr, &data, 0) ||
+ prs_tdb_store(tdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+BOOL vuid_init_db(void)
+{
+ tdb = tdb_open(lock_path("vuid.tdb"), 0, 0, O_RDWR | O_CREAT, 0600);
+
+ if (tdb == NULL)
+ {
+ DEBUG(0,("vuid_init_db: failed\n"));
+ return False;
+ }
+
+ DEBUG(10,("vuid_init_db: opened\n"));
+
+ return True;
+}
+
diff --git a/source/libsmb/.cvsignore b/source/libsmb/.cvsignore
index 07da2225c72..1ab6832045e 100644
--- a/source/libsmb/.cvsignore
+++ b/source/libsmb/.cvsignore
@@ -1,3 +1,3 @@
-*.po
+*.[pl]o
*.po32
diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c
index 8d7dbec8590..5eda1bc356a 100644
--- a/source/libsmb/clientgen.c
+++ b/source/libsmb/clientgen.c
@@ -2,7 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB client generic functions
- Copyright (C) Andrew Tridgell 1994-1998
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,54 +23,87 @@
#define NO_SYSLOG
#include "includes.h"
+#include "nterr.h"
#include "trans2.h"
-
extern int DEBUGLEVEL;
-extern pstring user_socket_options;
-
-static void cli_process_oplock(struct cli_state *cli);
-/*
- * Change the port number used to call on
+/*
+ * set the port that will be used for connections by the client
*/
+
int cli_set_port(struct cli_state *cli, int port)
{
- if (port > 0)
+
+ if (port != 0)
cli->port = port;
- return cli->port;
+ return cli->port; /* return it incase caller wants it */
+
}
/****************************************************************************
-recv an smb
+copy a string (unicode or otherwise) into an SMB buffer. skips a string
+plus points to next
****************************************************************************/
-static BOOL cli_receive_smb(struct cli_state *cli)
+static char *cli_put_string(struct cli_state *cli, char *p, const char *str,
+ BOOL skip_end)
{
- BOOL ret;
- again:
- ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
-
- if (ret) {
- /* it might be an oplock break request */
- if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) &&
- CVAL(cli->inbuf,smb_com) == SMBlockingX &&
- SVAL(cli->inbuf,smb_vwv6) == 0 &&
- SVAL(cli->inbuf,smb_vwv7) == 0) {
- if (cli->use_oplocks) cli_process_oplock(cli);
- /* try to prevent loops */
- CVAL(cli->inbuf,smb_com) = 0xFF;
- goto again;
+ uint16 flgs2 = SVAL(cli->outbuf, smb_flg2);
+ if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS))
+ {
+ p = align2(p, cli->outbuf);
+ p = ascii_to_unibuf(p, str, 1024);
+ if (skip_end)
+ {
+ CVAL(p, 0) = 0; p++;
+ CVAL(p, 0) = 0; p++;
}
+ return p;
}
+ else
+ {
+ pstrcpy(p, str);
+ p = skip_string(p, 1);
+ if (skip_end)
+ {
+ CVAL(p, 0) = 0; p++;
+ }
+ return p;
+ }
+}
- return ret;
+/****************************************************************************
+copy a string (unicode or otherwise) into an SMB buffer. skips a string
+plus points to next
+****************************************************************************/
+static const char *cli_get_string(struct cli_state *cli, char *p,
+ char *str, size_t str_len)
+{
+ uint16 flgs2 = SVAL(cli->inbuf,smb_flg2);
+ if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS))
+ {
+ return unibuf_to_ascii(str, p, str_len);
+ }
+ else
+ {
+ safe_strcpy(str, p, str_len-1);
+ return skip_string(p, 1);
+ }
+}
+
+/****************************************************************************
+recv an smb
+****************************************************************************/
+static BOOL cli_receive_smb(struct cli_state *cli)
+{
+ return client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
}
/****************************************************************************
send an smb to a fd and re-establish if necessary
****************************************************************************/
-static BOOL cli_send_smb(struct cli_state *cli)
+static BOOL cli_send_smb(struct cli_state *cli, BOOL show)
{
size_t len;
size_t nwritten=0;
@@ -78,9 +112,26 @@ static BOOL cli_send_smb(struct cli_state *cli)
len = smb_len(cli->outbuf) + 4;
+ if (show)
+ {
+ uint8 msg_type = CVAL(cli->outbuf, 0);
+ if (msg_type == 0)
+ {
+ show_msg(cli->outbuf);
+ }
+ else
+ {
+ dump_data(10, cli->outbuf, len);
+ }
+ }
+
while (nwritten < len) {
ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten);
- if (ret <= 0 && errno == EPIPE && !reestablished) {
+ if (ret <= 0 && errno == EPIPE && !reestablished)
+ {
+ DEBUG(5,("cli_send_smb: write error (%s) - reconnecting\n",
+ strerror(errno)));
+
if (cli_reestablish_connection(cli)) {
reestablished = True;
nwritten=0;
@@ -89,9 +140,8 @@ static BOOL cli_send_smb(struct cli_state *cli)
}
if (ret <= 0) {
DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",
- (int)len,(int)ret));
- close_sockets();
- exit(1);
+ len,ret));
+ return False;
}
nwritten += ret;
}
@@ -99,62 +149,26 @@ static BOOL cli_send_smb(struct cli_state *cli)
return True;
}
-/****************************************************************************
-setup basics in a outgoing packet
-****************************************************************************/
-static void cli_setup_packet(struct cli_state *cli)
-{
- cli->rap_error = 0;
- cli->nt_error = 0;
- SSVAL(cli->outbuf,smb_pid,cli->pid);
- SSVAL(cli->outbuf,smb_uid,cli->vuid);
- SSVAL(cli->outbuf,smb_mid,cli->mid);
- if (cli->protocol > PROTOCOL_CORE) {
- SCVAL(cli->outbuf,smb_flg,0x8);
- SSVAL(cli->outbuf,smb_flg2,0x1);
- }
+/******************************************************
+ Return an error message - either an SMB error or a RAP
+ error.
+*******************************************************/
+
+char *cli_errstr(struct cli_state *cli)
+{
+ static fstring error_message;
+ cli_safe_errstr(cli, error_message, sizeof(error_message));
+ return error_message;
}
-
-
/****************************************************************************
-process an oplock break request from the server
+ return a description of an SMB error
****************************************************************************/
-static void cli_process_oplock(struct cli_state *cli)
+void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len)
{
- char *oldbuf = cli->outbuf;
- pstring buf;
- int fnum;
-
- fnum = SVAL(cli->inbuf,smb_vwv2);
-
- /* damn, we really need to keep a record of open files so we
- can detect a oplock break and a close crossing on the
- wire. for now this swallows the errors */
- if (fnum == 0) return;
-
- cli->outbuf = buf;
-
- memset(buf,'\0',smb_size);
- set_message(buf,8,0,True);
-
- CVAL(buf,smb_com) = SMBlockingX;
- SSVAL(buf,smb_tid, cli->cnum);
- cli_setup_packet(cli);
- SSVAL(buf,smb_vwv0,0xFF);
- SSVAL(buf,smb_vwv1,0);
- SSVAL(buf,smb_vwv2,fnum);
- SSVAL(buf,smb_vwv3,2); /* oplock break ack */
- SIVAL(buf,smb_vwv4,0); /* timoeut */
- SSVAL(buf,smb_vwv6,0); /* unlockcount */
- SSVAL(buf,smb_vwv7,0); /* lockcount */
-
- cli_send_smb(cli);
-
- cli->outbuf = oldbuf;
+ smb_safe_errstr(cli->inbuf, msg, len);
}
-
/*****************************************************
RAP error codes - a small start but will be extended.
*******************************************************/
@@ -173,36 +187,36 @@ struct
{2244, "This password cannot be used now (password history conflict)." },
{2245, "The password is shorter than required." },
{2246, "The password of this user is too recent to change."},
-
- /* these really shouldn't be here ... */
- {0x80, "Not listening on called name"},
- {0x81, "Not listening for calling name"},
- {0x82, "Called name not present"},
- {0x83, "Called name present, but insufficient resources"},
-
{0, NULL}
};
/****************************************************************************
- return a description of an SMB error
+ return a description of a RAP error
****************************************************************************/
-static char *cli_smb_errstr(struct cli_state *cli)
+BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen)
{
- return smb_errstr(cli->inbuf);
+ int i;
+
+ slprintf(err_msg, msglen - 1, "RAP code %d", rap_error);
+
+ for (i = 0; rap_errmap[i].message != NULL; i++)
+ {
+ if (rap_errmap[i].err == rap_error)
+ {
+ safe_strcpy( err_msg, rap_errmap[i].message, msglen);
+ return True;
+ }
+ }
+ return False;
}
-/******************************************************
- Return an error message - either an SMB error or a RAP
- error.
-*******************************************************/
-
-char *cli_errstr(struct cli_state *cli)
+/****************************************************************************
+ return a description of an SMB error
+****************************************************************************/
+void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen)
{
- static fstring error_message;
uint8 errclass;
uint32 errnum;
- uint32 nt_rpc_error;
- int i;
/*
* Errors are of three kinds - smb errors,
@@ -211,51 +225,55 @@ char *cli_errstr(struct cli_state *cli)
* errors, whose error code is in cli.rap_error.
*/
- cli_error(cli, &errclass, &errnum, &nt_rpc_error);
+ cli_error(cli, &errclass, &errnum);
if (errclass != 0)
{
- return cli_smb_errstr(cli);
+ cli_safe_smb_errstr(cli, err_msg, msglen);
}
-
- /*
- * Was it an NT error ?
- */
-
- if (nt_rpc_error)
+ else if (cli->nt_error)
{
- char *nt_msg = get_nt_error_msg(nt_rpc_error);
-
- if (nt_msg == NULL)
- {
- slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error);
- }
- else
- {
- fstrcpy(error_message, nt_msg);
- }
+ /*
+ * Was it an NT error ?
+ */
- return error_message;
+ (void)get_safe_nt_error_msg(cli->nt_error, err_msg, msglen);
}
+ else
+ {
+ /*
+ * Must have been a rap error.
+ */
+ (void)get_safe_rap_errstr(cli->rap_error, err_msg, msglen);
+ }
+}
+/****************************************************************************
+setup basics in a outgoing packet
+****************************************************************************/
+static void cli_setup_packet(struct cli_state *cli)
+{
+ uint16 flgs2 = 0;
+ flgs2 |= FLAGS2_LONG_PATH_COMPONENTS;
+ flgs2 |= FLAGS2_32_BIT_ERROR_CODES;
+ flgs2 |= FLAGS2_EXT_SEC;
+#if 0
+ flgs2 |= FLAGS2_UNICODE_STRINGS;
+#endif
- /*
- * Must have been a rap error.
- */
-
- slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error);
+ cli->rap_error = 0;
+ cli->nt_error = 0;
+ SSVAL(cli->outbuf,smb_pid,cli->pid);
+ SSVAL(cli->outbuf,smb_uid,cli->vuid);
+ SSVAL(cli->outbuf,smb_mid,cli->mid);
- for (i = 0; rap_errmap[i].message != NULL; i++)
+ if (cli->protocol > PROTOCOL_CORE)
{
- if (rap_errmap[i].err == cli->rap_error)
- {
- fstrcpy( error_message, rap_errmap[i].message);
- break;
- }
- }
-
- return error_message;
+ SCVAL(cli->outbuf,smb_flg,0x8);
+ SSVAL(cli->outbuf,smb_flg2,flgs2);
+ }
}
+
/*****************************************************************************
Convert a character pointer in a cli_call_api() response to a form we can use.
This function contains code to prevent core dumps if the server returns
@@ -282,7 +300,7 @@ static char *fix_char_ptr(unsigned int datap, unsigned int converter,
/****************************************************************************
send a SMB trans or trans2 request
****************************************************************************/
-static BOOL cli_send_trans(struct cli_state *cli, int trans,
+BOOL cli_send_trans(struct cli_state *cli, int trans,
char *name, int pipe_name_len,
int fid, int flags,
uint16 *setup, int lsetup, int msetup,
@@ -298,7 +316,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans,
this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));
- memset(cli->outbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
set_message(cli->outbuf,14+lsetup,0,True);
CVAL(cli->outbuf,smb_com) = trans;
SSVAL(cli->outbuf,smb_tid, cli->cnum);
@@ -336,8 +354,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans,
set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */
PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False);
- show_msg(cli->outbuf);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
@@ -377,8 +394,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans,
set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False);
- show_msg(cli->outbuf);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
tot_data += this_ldata;
tot_param += this_lparam;
@@ -388,7 +404,6 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans,
return(True);
}
-
/****************************************************************************
receive a SMB trans or trans2 response allocating the necessary memory
****************************************************************************/
@@ -399,16 +414,12 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
int total_data=0;
int total_param=0;
int this_data,this_param;
- uint8 eclass;
- uint32 ecode;
-
+
*data_len = *param_len = 0;
if (!cli_receive_smb(cli))
return False;
- show_msg(cli->inbuf);
-
/* sanity check */
if (CVAL(cli->inbuf,smb_com) != trans) {
DEBUG(0,("Expected %s response, got command 0x%02x\n",
@@ -417,16 +428,9 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
return(False);
}
- /*
- * An NT RPC pipe call can return ERRDOS, ERRmoredata
- * to a trans call. This is not an error and should not
- * be treated as such.
- */
-
- if (cli_error(cli, &eclass, &ecode, NULL))
+ if (cli_error(cli, NULL, NULL))
{
- if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
- return(False);
+ return(False);
}
/* parse out the lengths */
@@ -468,8 +472,6 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
if (!cli_receive_smb(cli))
return False;
- show_msg(cli->inbuf);
-
/* sanity check */
if (CVAL(cli->inbuf,smb_com) != trans) {
DEBUG(0,("Expected %s response, got command 0x%02x\n",
@@ -477,10 +479,10 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
CVAL(cli->inbuf,smb_com)));
return(False);
}
- if (cli_error(cli, &eclass, &ecode, NULL))
+
+ if (cli_error(cli, NULL, NULL))
{
- if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
- return(False);
+ return(False);
}
}
@@ -600,7 +602,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation)
/****************************************************************************
call a NetShareEnum - try and browse available connections on a host
****************************************************************************/
-int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *))
+BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *))
{
char *rparam = NULL;
char *rdata = NULL;
@@ -618,16 +620,12 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co
pstrcpy(p,"B13BWz");
p = skip_string(p,1);
SSVAL(p,0,1);
- /*
- * Win2k needs a *smaller* buffer than 0xFFFF here -
- * it returns "out of server memory" with 0xFFFF !!! JRA.
- */
- SSVAL(p,2,0xFFE0);
+ SSVAL(p,2,0xFFFF);
p += 4;
if (cli_api(cli,
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
- NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */
+ NULL, 0, 0xFFFF, /* data, length, maxlen */
&rparam, &rprcnt, /* return params, length */
&rdata, &rdrcnt)) /* return data, length */
{
@@ -644,8 +642,6 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co
int type = SVAL(p,14);
int comment_offset = IVAL(p,16) & 0xFFFF;
char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
- dos_to_unix(sname,True);
- dos_to_unix(cmnt,True);
fn(sname, type, cmnt);
}
} else {
@@ -723,8 +719,6 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
- dos_to_unix(sname, True);
- dos_to_unix(cmnt, True);
fn(sname, stype, cmnt);
}
}
@@ -760,76 +754,41 @@ prots[] =
/****************************************************************************
- Send a session setup. The username is in UNIX character format and must be
- converted to DOS codepage format before sending. If the password is in
- plaintext, the same should be done.
+send a session setup
****************************************************************************/
-
-BOOL cli_session_setup(struct cli_state *cli,
- char *user,
- char *pass, int passlen,
- char *ntpass, int ntpasslen,
- char *workgroup)
+BOOL cli_session_setup_x(struct cli_state *cli,
+ char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *user_domain)
{
+ uint8 eclass;
+ uint32 ecode;
char *p;
- fstring pword, ntpword;
+ BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY;
- if (cli->protocol < PROTOCOL_LANMAN1)
+ if (cli->reuse)
+ {
+ DEBUG(3,("cli_session_setup_x: reuse enabled, skipping SMBsesssetupX\n"));
return True;
-
- if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
- return False;
}
- if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) {
- /* Null session connect. */
- pword[0] = '\0';
- ntpword[0] = '\0';
- } else {
- if ((cli->sec_mode & 2) && passlen != 24) {
- /*
- * Encrypted mode needed, and non encrypted password supplied.
- */
- passlen = 24;
- ntpasslen = 24;
- fstrcpy(pword, pass);
- unix_to_dos(pword,True);
- fstrcpy(ntpword, ntpass);;
- unix_to_dos(ntpword,True);
- SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword);
- SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword);
- } else if ((cli->sec_mode & 2) && passlen == 24) {
- /*
- * Encrypted mode needed, and encrypted password supplied.
- */
- memcpy(pword, pass, passlen);
- if(ntpasslen == 24) {
- memcpy(ntpword, ntpass, ntpasslen);
- } else {
- fstrcpy(ntpword, "");
- ntpasslen = 0;
- }
- } else {
- /*
- * Plaintext mode needed, assume plaintext supplied.
- */
- fstrcpy(pword, pass);
- unix_to_dos(pword,True);
- fstrcpy(ntpword, "");
- ntpasslen = 0;
- }
- }
+ DEBUG(100,("cli_session_setup. extended security: %s\n",
+ BOOLSTR(esec)));
- /* if in share level security then don't send a password now */
- if (!(cli->sec_mode & 1)) {
- fstrcpy(pword, "");
- passlen=1;
- fstrcpy(ntpword, "");
- ntpasslen=1;
- }
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("cli_session_setup. pass, ntpass\n"));
+ dump_data(100, pass, passlen);
+ dump_data(100, ntpass, ntpasslen);
+#endif
+
+ if (cli->protocol < PROTOCOL_LANMAN1)
+ {
+ return True;
+ }
/* send a session setup command */
- memset(cli->outbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
if (cli->protocol < PROTOCOL_NT1)
{
@@ -844,13 +803,36 @@ BOOL cli_session_setup(struct cli_state *cli,
SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
SSVAL(cli->outbuf,smb_vwv7,passlen);
p = smb_buf(cli->outbuf);
- memcpy(p,pword,passlen);
+ memcpy(p,pass,passlen);
p += passlen;
pstrcpy(p,user);
- unix_to_dos(p,True);
strupper(p);
}
- else
+ else if (esec)
+ {
+ set_message(cli->outbuf,12,0,True);
+ CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
+ cli_setup_packet(cli);
+
+ CVAL(cli->outbuf,smb_vwv0) = 0xFF;
+ SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
+ SSVAL(cli->outbuf,smb_vwv3,2);
+ SSVAL(cli->outbuf,smb_vwv4,cli->pid);
+ SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
+ SSVAL(cli->outbuf,smb_vwv7,passlen);
+ SIVAL(cli->outbuf,smb_vwv10, CAP_EXTENDED_SECURITY|CAP_STATUS32|CAP_UNICODE);
+ p = smb_buf(cli->outbuf);
+ memcpy(p,pass,passlen);
+ p += passlen;
+
+ p = cli_put_string(cli, p, "Unix", False);
+ p = cli_put_string(cli, p, "Samba", False);
+ p = cli_put_string(cli, p, "", False);
+ p++;
+
+ set_message(cli->outbuf,12,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
+ }
+ else
{
set_message(cli->outbuf,13,0,True);
CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
@@ -863,74 +845,227 @@ BOOL cli_session_setup(struct cli_state *cli,
SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
SSVAL(cli->outbuf,smb_vwv7,passlen);
SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
- SSVAL(cli->outbuf,smb_vwv11,0);
+ SIVAL(cli->outbuf,smb_vwv11, 0);
p = smb_buf(cli->outbuf);
- memcpy(p,pword,passlen);
+ memcpy(p,pass,passlen);
p += SVAL(cli->outbuf,smb_vwv7);
- memcpy(p,ntpword,ntpasslen);
+ memcpy(p,ntpass,ntpasslen);
p += SVAL(cli->outbuf,smb_vwv8);
- pstrcpy(p,user);
- unix_to_dos(p,True);
- strupper(p);
- p = skip_string(p,1);
- pstrcpy(p,workgroup);
- strupper(p);
- p = skip_string(p,1);
- pstrcpy(p,"Unix");p = skip_string(p,1);
- pstrcpy(p,"Samba");p = skip_string(p,1);
+ strupper(user);
+ p = cli_put_string(cli, p, user, False);
+ strupper(user_domain);
+ p = cli_put_string(cli, p, user_domain, False);
+ p = cli_put_string(cli, p, "Unix", True);
+ p = cli_put_string(cli, p, "Samba", False);
+
set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
}
- cli_send_smb(cli);
- if (!cli_receive_smb(cli))
+ cli_send_smb(cli, True);
+ if (!cli_receive_smb(cli))
+ {
+ DEBUG(10,("cli_session_setup_x: receive smb failed\n"));
return False;
+ }
+
+ if (cli_error(cli, &eclass, &ecode))
+ {
+ uint16 flgs2 = SVAL(cli->inbuf,smb_flg2);
+ if (IS_BITS_CLR_ALL(flgs2, FLAGS2_32_BIT_ERROR_CODES))
+ {
+ if (ecode != ERRmoredata || !esec)
+ {
+ return False;
+ }
+ }
+ else if (ecode != 0xC0000016) /* STATUS_MORE_PROCESSING_REQD */
+ {
+ return False;
+ }
+ }
- show_msg(cli->inbuf);
+ /* use the returned vuid from now on */
+ cli->vuid = SVAL(cli->inbuf,smb_uid);
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
- return False;
- }
+ if (cli->protocol >= PROTOCOL_NT1)
+ {
+ if (esec)
+ {
+ }
+ else
+ {
+ /*
+ * Save off some of the connected server
+ * info.
+ */
+ char *server_domain;
+ char *server_os;
+ char *server_type;
- /* use the returned vuid from now on */
- cli->vuid = SVAL(cli->inbuf,smb_uid);
-
- if (cli->protocol >= PROTOCOL_NT1) {
- /*
- * Save off some of the connected server
- * info.
- */
- char *server_domain,*server_os,*server_type;
- server_os = smb_buf(cli->inbuf);
- server_type = skip_string(server_os,1);
- server_domain = skip_string(server_type,1);
- fstrcpy(cli->server_os, server_os);
- dos_to_unix(cli->server_os, True);
- fstrcpy(cli->server_type, server_type);
- dos_to_unix(cli->server_type, True);
- fstrcpy(cli->server_domain, server_domain);
- dos_to_unix(cli->server_domain, True);
- }
+ server_os = smb_buf(cli->inbuf);
+ server_type = skip_string(server_os,1);
+ server_domain = skip_string(server_type,1);
- fstrcpy(cli->user_name, user);
- dos_to_unix(cli->user_name, True);
+ fstrcpy(cli->server_os, server_os);
+ fstrcpy(cli->server_type, server_type);
+ fstrcpy(cli->server_domain, server_domain);
+ }
+ }
return True;
}
+static BOOL cli_calc_session_pwds(struct cli_state *cli,
+ char *myhostname,
+ char *pword, char *ntpword,
+ char *pass, int *passlen,
+ char *ntpass, int *ntpasslen,
+ char *sess_key,
+ BOOL ntlmv2)
+{
+ BOOL ntpass_ok = ntpass != NULL && ntpasslen != NULL;
+
+ if (pass == NULL || passlen == NULL)
+ {
+ DEBUG(0,("cli_calc_session_pwds: pass and passlen are NULL\n"));
+ return False;
+ }
+ if ((ntpass != NULL || ntpasslen != NULL) &&
+ (ntpass == NULL || ntpasslen == NULL))
+ {
+ DEBUG(0,("cli_calc_session_pwds: ntpasswd pointers invalid\n"));
+ return False;
+ }
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("cli_calc_session_pwds. pass, ntpass\n"));
+ dump_data(100, pass, *passlen);
+ if (ntpass_ok)
+ {
+ dump_data(100, ntpass, *ntpasslen);
+ }
+#endif
+ if (!IS_BITS_SET_ALL(cli->sec_mode, 1))
+ {
+ /* if in share level security then don't send a password now */
+ pword[0] = '\0';
+ *passlen=1;
+ if (ntpass_ok)
+ {
+ ntpword[0] = '\0';
+ *ntpasslen=1;
+ }
+ return True;
+ }
+ else if ((*passlen == 0 || *passlen == 1) && (pass[0] == '\0'))
+ {
+ /* Null session connect. */
+ pword [0] = '\0';
+ if (ntpass_ok)
+ {
+ ntpword[0] = '\0';
+ *ntpasslen=0;
+ }
+
+ return True;
+ }
+
+ if (!ntpass_ok)
+ {
+ return False;
+ }
+
+ if (*passlen == 24 && *ntpasslen >= 24)
+ {
+ if (IS_BITS_SET_ALL(cli->sec_mode, 2))
+ {
+ /* encrypted password, implicit from 24-byte lengths */
+ memcpy(pword , pass , *passlen);
+ memcpy(ntpword, ntpass, *ntpasslen);
+ }
+ else
+ {
+ DEBUG(0,("cli_calc_session_pwds: encrypted passwords not supported by server\n"));
+ return False;
+ }
+ }
+ else if (*ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2))
+ {
+ /* plain-text password: server doesn't support encrypted. */
+ fstrcpy(pword, pass);
+ fstrcpy(ntpword, "");
+ *ntpasslen = 0;
+ }
+ else if (ntpasslen != NULL)
+ {
+ if (cli->use_ntlmv2 != False)
+ {
+ DEBUG(10,("cli_establish_connection: NTLMv2\n"));
+ pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey,
+ cli->usr.user_name, myhostname,
+ cli->usr.domain, sess_key);
+ }
+ else
+ {
+ DEBUG(10,("cli_establish_connection: NTLMv1\n"));
+ pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey,
+ sess_key);
+ }
+
+ pwd_get_lm_nt_owf(&(cli->usr.pwd), pass, ntpass,
+ ntpasslen);
+
+ *passlen = 24;
+ }
+ return True;
+}
+
+/****************************************************************************
+send a session setup
+****************************************************************************/
+BOOL cli_session_setup(struct cli_state *cli,
+ char *myhostname, char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *user_domain)
+{
+ fstring pword, ntpword;
+
+ if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1)
+ {
+ return False;
+ }
+
+ fstrcpy(cli->usr.user_name, user);
+
+ return cli_calc_session_pwds(cli, myhostname, pword, ntpword,
+ pass, &passlen,
+ ntpass, &ntpasslen, cli->nt.usr_sess_key,
+ cli->use_ntlmv2) &&
+ cli_session_setup_x(cli, user, pass, passlen, ntpass, ntpasslen,
+ user_domain);
+}
+
/****************************************************************************
Send a uloggoff.
*****************************************************************************/
BOOL cli_ulogoff(struct cli_state *cli)
{
- memset(cli->outbuf,'\0',smb_size);
+ if (cli->reuse)
+ {
+ DEBUG(3,("cli_ulogoff: reuse enabled, skipping SMBulogoff\n"));
+ return True;
+ }
+
+ bzero(cli->outbuf,smb_size);
set_message(cli->outbuf,2,0,True);
CVAL(cli->outbuf,smb_com) = SMBulogoffX;
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli))
return False;
@@ -943,10 +1078,10 @@ send a tconX
BOOL cli_send_tconX(struct cli_state *cli,
char *share, char *dev, char *pass, int passlen)
{
- fstring fullshare, pword, dos_pword;
+ fstring fullshare, pword;
char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
fstrcpy(cli->share, share);
@@ -957,32 +1092,17 @@ BOOL cli_send_tconX(struct cli_state *cli,
}
if ((cli->sec_mode & 2) && *pass && passlen != 24) {
- /*
- * Non-encrypted passwords - convert to DOS codepage before encryption.
- */
passlen = 24;
- fstrcpy(dos_pword,pass);
- unix_to_dos(dos_pword,True);
- SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword);
+ SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword);
} else {
- if(!(cli->sec_mode & 2)) {
- /*
- * Non-encrypted passwords - convert to DOS codepage before using.
- */
- fstrcpy(pword,pass);
- unix_to_dos(pword,True);
- } else {
- memcpy(pword, pass, passlen);
- }
+ memcpy(pword, pass, passlen);
}
slprintf(fullshare, sizeof(fullshare)-1,
"\\\\%s\\%s", cli->desthost, share);
- unix_to_dos(fullshare, True);
strupper(fullshare);
- set_message(cli->outbuf,4,
- 2 + strlen(fullshare) + passlen + strlen(dev),True);
+ set_message(cli->outbuf,4, 0, True);
CVAL(cli->outbuf,smb_com) = SMBtconX;
cli_setup_packet(cli);
@@ -992,14 +1112,15 @@ BOOL cli_send_tconX(struct cli_state *cli,
p = smb_buf(cli->outbuf);
memcpy(p,pword,passlen);
p += passlen;
- fstrcpy(p,fullshare);
- p = skip_string(p,1);
- pstrcpy(p,dev);
- unix_to_dos(p,True);
+ p = cli_put_string(cli, p, fullshare, False);
+ fstrcpy(p, dev);
+ p = skip_string(p, 1);
+
+ set_message(cli->outbuf,4,PTR_DIFF(p, smb_buf(cli->outbuf)),False);
SCVAL(cli->inbuf,smb_rcls, 1);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli))
return False;
@@ -1009,8 +1130,10 @@ BOOL cli_send_tconX(struct cli_state *cli,
fstrcpy(cli->dev, "A:");
- if (cli->protocol >= PROTOCOL_NT1) {
- fstrcpy(cli->dev, smb_buf(cli->inbuf));
+ if (cli->protocol >= PROTOCOL_NT1)
+ {
+ cli_get_string(cli, smb_buf(cli->inbuf),
+ cli->dev, sizeof(cli->dev));
}
if (strcasecmp(share,"IPC$")==0) {
@@ -1018,8 +1141,8 @@ BOOL cli_send_tconX(struct cli_state *cli,
}
/* only grab the device if we have a recent protocol level */
- if (cli->protocol >= PROTOCOL_NT1 &&
- smb_buflen(cli->inbuf) == 3) {
+ if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3)
+ {
/* almost certainly win95 - enable bug fixes */
cli->win95 = True;
}
@@ -1034,13 +1157,13 @@ send a tree disconnect
****************************************************************************/
BOOL cli_tdis(struct cli_state *cli)
{
- memset(cli->outbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
set_message(cli->outbuf,0,0,True);
CVAL(cli->outbuf,smb_com) = SMBtdis;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli))
return False;
@@ -1054,8 +1177,8 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst)
{
char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True);
@@ -1063,18 +1186,16 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst)
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR);
+ SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN);
p = smb_buf(cli->outbuf);
*p++ = 4;
pstrcpy(p,fname_src);
- unix_to_dos(p,True);
p = skip_string(p,1);
*p++ = 4;
pstrcpy(p,fname_dst);
- unix_to_dos(p,True);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1093,8 +1214,8 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
{
char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,1, 2 + strlen(fname),True);
@@ -1107,9 +1228,8 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
p = smb_buf(cli->outbuf);
*p++ = 4;
pstrcpy(p,fname);
- unix_to_dos(p,True);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1128,8 +1248,8 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname)
{
char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,0, 2 + strlen(dname),True);
@@ -1140,9 +1260,8 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname)
p = smb_buf(cli->outbuf);
*p++ = 4;
pstrcpy(p,dname);
- unix_to_dos(p,True);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1161,8 +1280,8 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
{
char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,0, 2 + strlen(dname),True);
@@ -1173,9 +1292,8 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
p = smb_buf(cli->outbuf);
*p++ = 4;
pstrcpy(p,dname);
- unix_to_dos(p,True);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1192,12 +1310,12 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
/****************************************************************************
open a file
****************************************************************************/
-int cli_nt_create(struct cli_state *cli, char *fname)
+int cli_nt_create(struct cli_state *cli, const char *fname)
{
char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,24,1 + strlen(fname),True);
@@ -1218,10 +1336,9 @@ int cli_nt_create(struct cli_state *cli, char *fname)
p = smb_buf(cli->outbuf);
pstrcpy(p,fname);
- unix_to_dos(p,True);
p = skip_string(p,1);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return -1;
}
@@ -1236,14 +1353,20 @@ int cli_nt_create(struct cli_state *cli, char *fname)
/****************************************************************************
open a file
-WARNING: if you open with O_WRONLY then getattrE won't work!
****************************************************************************/
-int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
+int cli_open(struct cli_state *cli, const char *fname,
+ int flags, int share_mode)
{
char *p;
unsigned openfn=0;
unsigned accessmode=0;
+ /* you must open for RW not just write - otherwise getattrE doesn't
+ work! */
+ if ((flags & O_ACCMODE) == O_WRONLY && strncmp(cli->dev, "LPT", 3)) {
+ flags = (flags & ~O_ACCMODE) | O_RDWR;
+ }
+
if (flags & O_CREAT)
openfn |= (1<<4);
if (!(flags & O_EXCL)) {
@@ -1267,12 +1390,8 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
}
#endif /* O_SYNC */
- if (share_mode == DENY_FCB) {
- accessmode = 0xFF;
- }
-
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,15,1 + strlen(fname),True);
@@ -1286,21 +1405,13 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
SSVAL(cli->outbuf,smb_vwv5,0);
SSVAL(cli->outbuf,smb_vwv8,openfn);
-
- if (cli->use_oplocks) {
- /* if using oplocks then ask for a batch oplock via
- core and extended methods */
- CVAL(cli->outbuf,smb_flg) |=
- FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK;
- SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);
- }
p = smb_buf(cli->outbuf);
- pstrcpy(p,fname);
- unix_to_dos(p,True);
- p = skip_string(p,1);
+ p = cli_put_string(cli, p, fname, False);
+
+ set_message(cli->outbuf,15,PTR_DIFF(p, smb_buf(cli->outbuf)),False);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return -1;
}
@@ -1320,8 +1431,8 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
****************************************************************************/
BOOL cli_close(struct cli_state *cli, int fnum)
{
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,3,0,True);
@@ -1332,7 +1443,7 @@ BOOL cli_close(struct cli_state *cli, int fnum)
SSVAL(cli->outbuf,smb_vwv0,fnum);
SIVALS(cli->outbuf,smb_vwv1,-1);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1348,14 +1459,13 @@ BOOL cli_close(struct cli_state *cli, int fnum)
/****************************************************************************
lock a file
****************************************************************************/
-BOOL cli_lock(struct cli_state *cli, int fnum,
- uint32 offset, uint32 len, int timeout, enum brl_type lock_type)
+BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout)
{
char *p;
int saved_timeout = cli->timeout;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0', smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,8,10,True);
@@ -1365,7 +1475,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum,
CVAL(cli->outbuf,smb_vwv0) = 0xFF;
SSVAL(cli->outbuf,smb_vwv2,fnum);
- CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0);
+ CVAL(cli->outbuf,smb_vwv3) = 0;
SIVALS(cli->outbuf, smb_vwv4, timeout);
SSVAL(cli->outbuf,smb_vwv6,0);
SSVAL(cli->outbuf,smb_vwv7,1);
@@ -1374,9 +1484,9 @@ BOOL cli_lock(struct cli_state *cli, int fnum,
SSVAL(p, 0, cli->pid);
SIVAL(p, 2, offset);
SIVAL(p, 6, len);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
- cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000);
+ cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout;
if (!cli_receive_smb(cli)) {
cli->timeout = saved_timeout;
@@ -1395,12 +1505,12 @@ BOOL cli_lock(struct cli_state *cli, int fnum,
/****************************************************************************
unlock a file
****************************************************************************/
-BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
+BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout)
{
char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,8,10,True);
@@ -1411,7 +1521,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
CVAL(cli->outbuf,smb_vwv0) = 0xFF;
SSVAL(cli->outbuf,smb_vwv2,fnum);
CVAL(cli->outbuf,smb_vwv3) = 0;
- SIVALS(cli->outbuf, smb_vwv4, 0);
+ SIVALS(cli->outbuf, smb_vwv4, timeout);
SSVAL(cli->outbuf,smb_vwv6,1);
SSVAL(cli->outbuf,smb_vwv7,0);
@@ -1420,7 +1530,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len)
SIVAL(p, 2, offset);
SIVAL(p, 6, len);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1440,8 +1550,8 @@ issue a single SMBread and don't wait for a reply
static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
size_t size, int i)
{
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,10,0,True);
@@ -1456,39 +1566,73 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
SSVAL(cli->outbuf,smb_vwv6,size);
SSVAL(cli->outbuf,smb_mid,cli->mid + i);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
+}
+
+/****************************************************************************
+ read from a file
+****************************************************************************/
+size_t cli_read_one(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size)
+{
+ char *p;
+ int size2;
+
+ if (size == 0) return 0;
+
+ if (buf == NULL)
+ {
+ DEBUG(1, ("cli_read_one: NULL buf\n"));
+ return 0;
+ }
+
+ cli_issue_read(cli, fnum, offset, size, 0);
+
+ if (!cli_receive_smb(cli))
+ {
+ return -1;
+ }
+
+ size2 = SVAL(cli->inbuf, smb_vwv5);
+
+ if (cli_error(cli, NULL, NULL))
+ {
+ return -1;
+ }
+
+ if (size2 > size)
+ {
+ DEBUG(0,("server returned more than we wanted!\n"));
+ exit(1);
+ }
+
+ p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6);
+ memcpy(buf, p, size2);
+
+ return size2;
}
/****************************************************************************
read from a file
****************************************************************************/
-size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size)
+size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size, BOOL overlap)
{
char *p;
int total = -1;
int issued=0;
int received=0;
-/*
- * There is a problem in this code when mpx is more than one.
- * for some reason files can get corrupted when being read.
- * Until we understand this fully I am serializing reads (one
- * read/one reply) for now. JRA.
- */
-#if 0
- int mpx = MAX(cli->max_mux-1, 1);
-#else
- int mpx = 1;
-#endif
- int block = (cli->max_xmit - (smb_size+32)) & ~1023;
+ int mpx = overlap ? MIN(MAX(cli->max_mux-1, 1), MAX_MAX_MUX_LIMIT) : 1;
+ int block = (cli->max_xmit - (smb_size+32)) & ~2047;
int mid;
int blocks = (size + (block-1)) / block;
if (size == 0) return 0;
- while (received < blocks) {
+ while (received < blocks)
+ {
int size2;
- while (issued - received < mpx && issued < blocks) {
+ while (issued - received < mpx && issued < blocks)
+ {
int size1 = MIN(block, size-issued*block);
cli_issue_read(cli, fnum, offset+issued*block, size1, issued);
issued++;
@@ -1502,7 +1646,8 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
mid = SVAL(cli->inbuf, smb_mid) - cli->mid;
size2 = SVAL(cli->inbuf, smb_vwv5);
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ if (cli_error(cli, NULL, NULL))
+ {
blocks = MIN(blocks, mid-1);
continue;
}
@@ -1514,11 +1659,13 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
continue;
}
- if (size2 > block) {
+ if (size2 > block)
+ {
DEBUG(0,("server returned more than we wanted!\n"));
exit(1);
}
- if (mid >= issued) {
+ if (mid >= issued)
+ {
DEBUG(0,("invalid mid from server!\n"));
exit(1);
}
@@ -1529,7 +1676,8 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
total = MAX(total, mid*block + size2);
}
- while (received < issued) {
+ while (received < issued)
+ {
cli_receive_smb(cli);
received++;
}
@@ -1542,12 +1690,12 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
issue a single SMBwrite and don't wait for a reply
****************************************************************************/
static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf,
- size_t size, int i)
+ size_t size, size_t bytes_left, int i)
{
char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,12,size,True);
@@ -1559,10 +1707,10 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
SSVAL(cli->outbuf,smb_vwv2,fnum);
SIVAL(cli->outbuf,smb_vwv3,offset);
- SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0);
+ SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_SOME(mode, 0x000C) ? 0xFFFFFFFF : 0);
SSVAL(cli->outbuf,smb_vwv7,mode);
- SSVAL(cli->outbuf,smb_vwv8,IS_BITS_SET_ALL(mode, 0x0008) ? size : 0);
+ SSVAL(cli->outbuf,smb_vwv8,IS_BITS_SET_SOME(mode, 0x000C) ? bytes_left : 0);
SSVAL(cli->outbuf,smb_vwv10,size);
SSVAL(cli->outbuf,smb_vwv11,
smb_buf(cli->outbuf) - smb_base(cli->outbuf));
@@ -1572,8 +1720,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
SSVAL(cli->outbuf,smb_mid,cli->mid + i);
- show_msg(cli->outbuf);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
}
/****************************************************************************
@@ -1585,100 +1732,63 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
****************************************************************************/
ssize_t cli_write(struct cli_state *cli,
int fnum, uint16 write_mode,
- char *buf, off_t offset, size_t size)
+ char *buf, off_t offset, size_t size, size_t bytes_left)
{
- int bwritten = 0;
- int issued = 0;
- int received = 0;
+ int total = -1;
+ int issued=0;
+ int received=0;
int mpx = MAX(cli->max_mux-1, 1);
int block = (cli->max_xmit - (smb_size+32)) & ~1023;
+ int mid;
int blocks = (size + (block-1)) / block;
- while (received < blocks) {
+ if (size == 0) return 0;
- while ((issued - received < mpx) && (issued < blocks))
- {
- int bsent = issued * block;
- int size1 = MIN(block, size - bsent);
+ while (received < blocks)
+ {
+ int size2;
- cli_issue_write(cli, fnum, offset + bsent,
+ while (issued - received < mpx && issued < blocks)
+ {
+ int size1 = MIN(block, size-issued*block);
+ cli_issue_write(cli, fnum, offset+issued*block,
write_mode,
- buf + bsent,
- size1, issued);
+ buf + issued*block,
+ size1, bytes_left, issued);
issued++;
+ bytes_left -= size1;
}
- if (!cli_receive_smb(cli))
- {
- return bwritten;
+ if (!cli_receive_smb(cli)) {
+ return total;
}
received++;
+ mid = SVAL(cli->inbuf, smb_mid) - cli->mid;
+ size2 = SVAL(cli->inbuf, smb_vwv2);
- if (CVAL(cli->inbuf,smb_rcls) != 0)
- {
- break;
+ if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ blocks = MIN(blocks, mid-1);
+ continue;
+ }
+
+ if (size2 <= 0) {
+ blocks = MIN(blocks, mid-1);
+ /* this distinguishes EOF from an error */
+ total = MAX(total, 0);
+ continue;
}
- bwritten += SVAL(cli->inbuf, smb_vwv2);
+ total += size2;
+
+ total = MAX(total, mid*block + size2);
}
- while (received < issued && cli_receive_smb(cli))
- {
+ while (received < issued) {
+ cli_receive_smb(cli);
received++;
}
- return bwritten;
-}
-
-
-/****************************************************************************
- write to a file using a SMBwrite and not bypassing 0 byte writes
-****************************************************************************/
-ssize_t cli_smbwrite(struct cli_state *cli,
- int fnum, char *buf, off_t offset, size_t size1)
-{
- char *p;
- ssize_t total = 0;
-
- do {
- size_t size = MIN(size1, cli->max_xmit - 48);
-
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
-
- set_message(cli->outbuf,5, 3 + size,True);
-
- CVAL(cli->outbuf,smb_com) = SMBwrite;
- SSVAL(cli->outbuf,smb_tid,cli->cnum);
- cli_setup_packet(cli);
-
- SSVAL(cli->outbuf,smb_vwv0,fnum);
- SSVAL(cli->outbuf,smb_vwv1,size);
- SIVAL(cli->outbuf,smb_vwv2,offset);
- SSVAL(cli->outbuf,smb_vwv4,0);
-
- p = smb_buf(cli->outbuf);
- *p++ = 1;
- SSVAL(p, 0, size);
- memcpy(p+2, buf, size);
-
- cli_send_smb(cli);
- if (!cli_receive_smb(cli)) {
- return -1;
- }
-
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
- return -1;
- }
-
- size = SVAL(cli->inbuf,smb_vwv0);
- if (size == 0) break;
-
- size1 -= size;
- total += size;
- } while (size1);
-
return total;
}
@@ -1690,10 +1800,10 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
uint16 *attr, size_t *size,
time_t *c_time, time_t *a_time, time_t *m_time)
{
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
- set_message(cli->outbuf,1,0,True);
+ set_message(cli->outbuf,2,0,True);
CVAL(cli->outbuf,smb_com) = SMBgetattrE;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -1701,7 +1811,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
SSVAL(cli->outbuf,smb_vwv0,fd);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1742,8 +1852,8 @@ BOOL cli_getatr(struct cli_state *cli, char *fname,
{
char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,0,strlen(fname)+2,True);
@@ -1754,9 +1864,8 @@ BOOL cli_getatr(struct cli_state *cli, char *fname,
p = smb_buf(cli->outbuf);
*p = 4;
pstrcpy(p+1, fname);
- unix_to_dos(p+1,True);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1789,8 +1898,8 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
{
char *p;
- memset(cli->outbuf,'\0',smb_size);
- memset(cli->inbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
+ bzero(cli->inbuf,smb_size);
set_message(cli->outbuf,8,strlen(fname)+4,True);
@@ -1804,11 +1913,10 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
p = smb_buf(cli->outbuf);
*p = 4;
pstrcpy(p+1, fname);
- unix_to_dos(p+1,True);
p = skip_string(p,1);
*p = 4;
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1841,7 +1949,6 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
memset(param, 0, param_len);
SSVAL(param, 0, SMB_INFO_STANDARD);
pstrcpy(&param[6], fname);
- unix_to_dos(&param[6],True);
do {
ret = (cli_send_trans(cli, SMBtrans2,
@@ -1859,7 +1966,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
it gives ERRSRV/ERRerror temprarily */
uint8 eclass;
uint32 ecode;
- cli_error(cli, &eclass, &ecode, NULL);
+ cli_error(cli, &eclass, &ecode);
if (eclass != ERRSRV || ecode != ERRerror) break;
msleep(100);
}
@@ -1915,7 +2022,6 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
memset(param, 0, param_len);
SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO);
pstrcpy(&param[6], fname);
- unix_to_dos(&param[6],True);
if (!cli_send_trans(cli, SMBtrans2,
NULL, 0, /* name, length */
@@ -1953,7 +2059,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
*mode = SVAL(rdata, 32);
}
if (size) {
- *size = IVAL(rdata, 48);
+ *size = IVAL(rdata, 40);
}
if (ino) {
*ino = IVAL(rdata, 64);
@@ -2025,7 +2131,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
*mode = SVAL(rdata, 32);
}
if (size) {
- *size = IVAL(rdata, 48);
+ *size = IVAL(rdata, 40);
}
if (ino) {
*ino = IVAL(rdata, 64);
@@ -2061,7 +2167,6 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
finfo->size = IVAL(p,16);
finfo->mode = CVAL(p,24);
pstrcpy(finfo->name,p+27);
- dos_to_unix(finfo->name,True);
}
return(28 + CVAL(p,26));
@@ -2074,7 +2179,6 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
finfo->size = IVAL(p,16);
finfo->mode = CVAL(p,24);
pstrcpy(finfo->name,p+31);
- dos_to_unix(finfo->name,True);
}
return(32 + CVAL(p,30));
@@ -2088,7 +2192,6 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
finfo->size = IVAL(p,20);
finfo->mode = CVAL(p,28);
pstrcpy(finfo->name,p+33);
- dos_to_unix(finfo->name,True);
}
return(SVAL(p,4)+4);
@@ -2101,7 +2204,6 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
finfo->size = IVAL(p,20);
finfo->mode = CVAL(p,28);
pstrcpy(finfo->name,p+37);
- dos_to_unix(finfo->name,True);
}
return(SVAL(p,4)+4);
@@ -2137,8 +2239,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
p += 4; /* EA size */
p += 2; /* short name len? */
p += 24; /* short name? */
- StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen));
- dos_to_unix(finfo->name,True);
+ StrnCpy(finfo->name,p,namelen);
return(ret);
}
return(SVAL(p,0));
@@ -2166,6 +2267,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
int dirlist_len = 0;
int total_received = -1;
BOOL First = True;
+ int ff_resume_key = 0;
int ff_searchcount=0;
int ff_eos=0;
int ff_lastname=0;
@@ -2178,7 +2280,6 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
pstring param;
pstrcpy(mask,Mask);
- unix_to_dos(mask,True);
while (ff_eos == 0) {
loop_count++;
@@ -2202,12 +2303,12 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
SSVAL(param,0,ff_dir_handle);
SSVAL(param,2,max_matches); /* max count */
SSVAL(param,4,info_level);
- SIVAL(param,6,0); /* ff_resume_key */
+ SIVAL(param,6,ff_resume_key); /* ff_resume_key */
SSVAL(param,10,8+4+2); /* resume required + close on end + continue */
pstrcpy(param+12,mask);
- DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n",
- ff_dir_handle,ff_lastname,mask));
+ DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
+ ff_dir_handle,ff_resume_key,ff_lastname,mask));
}
if (!cli_send_trans(cli, SMBtrans2,
@@ -2228,7 +2329,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
it gives ERRSRV/ERRerror temprarily */
uint8 eclass;
uint32 ecode;
- cli_error(cli, &eclass, &ecode, NULL);
+ cli_error(cli, &eclass, &ecode);
if (eclass != ERRSRV || ecode != ERRerror) break;
msleep(100);
continue;
@@ -2260,19 +2361,19 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
switch(info_level)
{
case 260:
+ ff_resume_key =0;
StrnCpy(mask,p+ff_lastname,
- MIN(sizeof(mask)-1,data_len-ff_lastname));
+ data_len-ff_lastname);
break;
case 1:
pstrcpy(mask,p + ff_lastname + 1);
+ ff_resume_key = 0;
break;
}
} else {
pstrcpy(mask,"");
}
-
- dos_to_unix(mask, True);
-
+
/* and add them to the dirlist pool */
dirlist = Realloc(dirlist,dirlist_len + data_len);
@@ -2296,10 +2397,8 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
if (rdata) free(rdata); rdata = NULL;
if (rparam) free(rparam); rparam = NULL;
- DEBUG(3,("received %d entries (eos=%d)\n",
- ff_searchcount,ff_eos));
-
- if (ff_searchcount > 0) loop_count = 0;
+ DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
+ ff_searchcount,ff_eos,ff_resume_key));
First = False;
}
@@ -2334,7 +2433,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
char *rparam = NULL;
char *rdata = NULL;
int rprcnt, rdrcnt;
- pstring dos_new_password;
if (strlen(user) >= sizeof(fstring)-1) {
DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user));
@@ -2360,22 +2458,19 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
*/
memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw));
fstrcpy(upper_case_old_pw, old_password);
- unix_to_dos(upper_case_old_pw,True);
strupper(upper_case_old_pw);
E_P16((uchar *)upper_case_old_pw, old_pw_hash);
- pstrcpy(dos_new_password, new_password);
- unix_to_dos(dos_new_password, True);
-
- if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False))
- return False;
+ if (!make_oem_passwd_hash( data, new_password, 0, old_pw_hash, False))
+ {
+ return False;
+ }
/*
* Now place the old password hash in the data.
*/
memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw));
fstrcpy(upper_case_new_pw, new_password);
- unix_to_dos(upper_case_new_pw,True);
strupper(upper_case_new_pw);
E_P16((uchar *)upper_case_new_pw, new_pw_hash);
@@ -2384,13 +2479,14 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
data_len = 532;
- if (cli_send_trans(cli,SMBtrans,
+ if (!cli_send_trans(cli,SMBtrans,
PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */
0,0, /* fid, flags */
NULL,0,0, /* setup, length, max */
param,param_len,2, /* param, length, max */
data,data_len,0 /* data, length, max */
- ) == False) {
+ ))
+ {
DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n",
user ));
return False;
@@ -2420,7 +2516,7 @@ BOOL cli_negprot(struct cli_state *cli)
int numprots;
int plength;
- memset(cli->outbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
/* setup the protocol strings */
for (plength=0,numprots=0;
@@ -2436,7 +2532,6 @@ BOOL cli_negprot(struct cli_state *cli)
numprots++) {
*p++ = 2;
pstrcpy(p,prots[numprots].name);
- unix_to_dos(p,True);
p += strlen(p) + 1;
}
@@ -2445,11 +2540,11 @@ BOOL cli_negprot(struct cli_state *cli)
CVAL(smb_buf(cli->outbuf),0) = 2;
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli))
+ {
return False;
-
- show_msg(cli->inbuf);
+ }
if (CVAL(cli->inbuf,smb_rcls) != 0 ||
((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
@@ -2459,28 +2554,56 @@ BOOL cli_negprot(struct cli_state *cli)
cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
- if (cli->protocol >= PROTOCOL_NT1) {
+ if (cli->protocol >= PROTOCOL_NT1)
+ {
+ char *buf = smb_buf(cli->inbuf);
+ int bcc = SVAL(cli->inbuf,smb_vwv+2*(CVAL(cli->inbuf,smb_wct)));
/* NT protocol */
cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1);
cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1);
- cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1);
- cli->serverzone *= 60;
+ cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60;
/* this time arrives in real GMT */
cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1);
- memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
+
cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
- if (cli->capabilities & 1) {
+ if (IS_BITS_SET_ALL(cli->capabilities, CAP_RAW_MODE))
+ {
cli->readbraw_supported = True;
cli->writebraw_supported = True;
}
- } else if (cli->protocol >= PROTOCOL_LANMAN1) {
+
+ if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY))
+ {
+ /* oops, some kerberos-related nonsense. */
+ /* expect to have to use NTLMSSP-over-SMB */
+ DEBUG(10,("unknown kerberos-related (?) blob\n"));
+ memset(cli->cryptkey, 0, 8);
+ cli->server_domain[0] = 0;
+ }
+ else
+ {
+ memcpy(cli->cryptkey, buf,8);
+ if (bcc > 8)
+ {
+ unibuf_to_ascii(cli->server_domain, buf+8,
+ sizeof(cli->server_domain));
+ }
+ else
+ {
+ cli->server_domain[0] = 0;
+ }
+ DEBUG(5,("server's domain: %s bcc: %d\n",
+ cli->server_domain, bcc));
+ }
+ }
+ else if (cli->protocol >= PROTOCOL_LANMAN1)
+ {
cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
- cli->serverzone = SVALS(cli->inbuf,smb_vwv10);
- cli->serverzone *= 60;
+ cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60;
/* this time is converted to GMT by make_unix_date */
cli->servertime = make_unix_date(cli->inbuf+smb_vwv8);
cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
@@ -2511,6 +2634,11 @@ BOOL cli_session_request(struct cli_state *cli,
memcpy(&(cli->calling), calling, sizeof(*calling));
memcpy(&(cli->called ), called , sizeof(*called ));
+ if (cli->port == 445)
+ {
+ return True;
+ }
+
/* put in the destination name */
p = cli->outbuf+len;
name_mangle(cli->called .name, p, cli->called .name_type);
@@ -2529,41 +2657,12 @@ BOOL cli_session_request(struct cli_state *cli,
retry:
#endif /* WITH_SSL */
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
DEBUG(5,("Sent session request\n"));
if (!cli_receive_smb(cli))
return False;
- if (CVAL(cli->inbuf,0) == 0x84) {
- /* C. Hoch 9/14/95 Start */
- /* For information, here is the response structure.
- * We do the byte-twiddling to for portability.
- struct RetargetResponse{
- unsigned char type;
- unsigned char flags;
- int16 length;
- int32 ip_addr;
- int16 port;
- };
- */
- int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
- /* SESSION RETARGET */
- putip((char *)&cli->dest_ip,cli->inbuf+4);
-
- close_sockets();
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT);
- if (cli->fd == -1)
- return False;
-
- DEBUG(3,("Retargeted\n"));
-
- set_socket_options(cli->fd,user_socket_options);
-
- /* Try again */
- return cli_session_request(cli, calling, called);
- } /* C. Hoch 9/14/95 End */
-
#ifdef WITH_SSL
if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */
if (!sslutil_fd_is_ssl(cli->fd)){
@@ -2575,7 +2674,7 @@ retry:
if (CVAL(cli->inbuf,0) != 0x82) {
/* This is the wrong place to put the error... JRA. */
- cli->rap_error = CVAL(cli->inbuf,4);
+ cli->rap_error = CVAL(cli->inbuf,0);
return False;
}
return(True);
@@ -2588,6 +2687,7 @@ open the client sockets
BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
{
extern struct in_addr ipzero;
+ int port = cli->port;
fstrcpy(cli->desthost, host);
@@ -2600,14 +2700,25 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
cli->dest_ip = *ip;
}
- if (cli->port == 0) cli->port = 139; /* Set to default */
+
+ if (port == 0) port = SMB_PORT2;
cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
- cli->port, cli->timeout);
+ port, cli->timeout);
if (cli->fd == -1)
- return False;
+ {
+ if (cli->port != 0)
+ {
+ return False;
+ }
+ port = SMB_PORT;
+
+ cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
+ port, cli->timeout);
+ if (cli->fd == -1) return False;
+ }
- set_socket_options(cli->fd,user_socket_options);
+ cli->port = port;
return True;
}
@@ -2616,6 +2727,17 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
/****************************************************************************
initialise a client structure
****************************************************************************/
+void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr)
+{
+ copy_nt_creds(&cli->usr, usr);
+ cli->nt.ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0;
+ DEBUG(10,("cli_init_creds: ntlmssp_flgs: %x\n",
+ cli->nt.ntlmssp_cli_flgs));
+}
+
+/****************************************************************************
+initialise a client structure
+****************************************************************************/
struct cli_state *cli_initialise(struct cli_state *cli)
{
if (!cli) {
@@ -2638,7 +2760,7 @@ struct cli_state *cli_initialise(struct cli_state *cli)
cli->mid = 1;
cli->vuid = UID_FIELD_INVALID;
cli->protocol = PROTOCOL_NT1;
- cli->timeout = 20000; /* Timeout is in milliseconds. */
+ cli->timeout = 20000;
cli->bufsize = CLI_BUFFER_SIZE+4;
cli->max_xmit = cli->bufsize;
cli->outbuf = (char *)malloc(cli->bufsize);
@@ -2648,19 +2770,39 @@ struct cli_state *cli_initialise(struct cli_state *cli)
return False;
}
- memset(cli->outbuf, '\0', cli->bufsize);
- memset(cli->inbuf, '\0', cli->bufsize);
-
cli->initialised = 1;
+ cli->capabilities = CAP_DFS | CAP_NT_SMBS | CAP_STATUS32;
+ cli->use_ntlmv2 = lp_client_ntlmv2();
+
+ cli_init_creds(cli, NULL);
return cli;
}
/****************************************************************************
+close the socket descriptor
+****************************************************************************/
+void cli_close_socket(struct cli_state *cli)
+{
+#ifdef WITH_SSL
+ if (cli->fd != -1)
+ {
+ sslutil_disconnect(cli->fd);
+ }
+#endif /* WITH_SSL */
+ if (cli->fd != -1)
+ {
+ close(cli->fd);
+ }
+ cli->fd = -1;
+}
+
+/****************************************************************************
shutdown a client structure
****************************************************************************/
void cli_shutdown(struct cli_state *cli)
{
+ DEBUG(10,("cli_shutdown\n"));
if (cli->outbuf)
{
free(cli->outbuf);
@@ -2669,12 +2811,7 @@ void cli_shutdown(struct cli_state *cli)
{
free(cli->inbuf);
}
-#ifdef WITH_SSL
- if (cli->fd != -1)
- sslutil_disconnect(cli->fd);
-#endif /* WITH_SSL */
- if (cli->fd != -1)
- close(cli->fd);
+ cli_close_socket(cli);
memset(cli, 0, sizeof(*cli));
}
@@ -2687,43 +2824,43 @@ void cli_shutdown(struct cli_state *cli)
for 32 bit "warnings", a return code of 0 is expected.
****************************************************************************/
-int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error)
+int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num)
{
int flgs2;
char rcls;
int code;
- if (eclass) *eclass = 0;
- if (num ) *num = 0;
- if (nt_rpc_error) *nt_rpc_error = 0;
-
- if(!cli->initialised)
+ if (!cli->initialised)
+ {
+ DEBUG(0,("cli_error: client state uninitialised!\n"));
return EINVAL;
-
- if(!cli->inbuf)
- return ENOMEM;
+ }
flgs2 = SVAL(cli->inbuf,smb_flg2);
- if (nt_rpc_error) *nt_rpc_error = cli->nt_error;
- if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
+ if (eclass) *eclass = 0;
+ if (num ) *num = 0;
+
+ if (flgs2 & FLAGS2_32_BIT_ERROR_CODES)
+ {
/* 32 bit error codes detected */
uint32 nt_err = IVAL(cli->inbuf,smb_rcls);
if (num) *num = nt_err;
DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err));
if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0;
- switch (nt_err & 0xFFFFFF) {
- case NT_STATUS_ACCESS_VIOLATION: return EACCES;
- case NT_STATUS_NO_SUCH_FILE: return ENOENT;
- case NT_STATUS_NO_SUCH_DEVICE: return ENODEV;
- case NT_STATUS_INVALID_HANDLE: return EBADF;
- case NT_STATUS_NO_MEMORY: return ENOMEM;
- case NT_STATUS_ACCESS_DENIED: return EACCES;
- case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT;
- case NT_STATUS_SHARING_VIOLATION: return EBUSY;
- case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR;
- case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST;
+ switch (nt_err & 0xFFFFFF)
+ {
+ case NT_STATUS_ACCESS_VIOLATION : return EACCES;
+ case NT_STATUS_NO_SUCH_FILE : return ENOENT;
+ case NT_STATUS_NO_SUCH_DEVICE : return ENODEV;
+ case NT_STATUS_INVALID_HANDLE : return EBADF;
+ case NT_STATUS_NO_MEMORY : return ENOMEM;
+ case NT_STATUS_ACCESS_DENIED : return EACCES;
+ case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT;
+ case NT_STATUS_SHARING_VIOLATION : return EBUSY;
+ case NT_STATUS_OBJECT_PATH_INVALID : return ENOTDIR;
+ case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST;
}
/* for all other cases - a default code */
@@ -2746,6 +2883,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_
case ERRrename: return EEXIST;
case ERRbadshare: return EBUSY;
case ERRlock: return EBUSY;
+ case ERRmoredata: return 0; /* Informational only */
}
}
if (rcls == ERRSRV) {
@@ -2802,29 +2940,36 @@ BOOL cli_reestablish_connection(struct cli_state *cli)
if (cli->cnum != 0)
{
+ do_tcon = True;
+ }
+
+ if (do_tcon)
+ {
fstrcpy(share, cli->share);
fstrcpy(dev , cli->dev);
- do_tcon = True;
}
memcpy(&called , &(cli->called ), sizeof(called ));
memcpy(&calling, &(cli->calling), sizeof(calling));
- fstrcpy(dest_host, cli->full_dest_host_name);
+ fstrcpy(dest_host, cli->desthost);
DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n",
nmb_namestr(&calling), nmb_namestr(&called),
inet_ntoa(cli->dest_ip),
- cli->user_name, cli->domain));
+ cli->usr.user_name, cli->usr.domain));
cli->fd = -1;
if (cli_establish_connection(cli,
dest_host, &cli->dest_ip,
&calling, &called,
- share, dev, False, do_tcon)) {
- if (cli->fd != oldfd) {
- if (dup2(cli->fd, oldfd) == oldfd) {
- close(cli->fd);
+ share, dev, False, do_tcon))
+ {
+ if (cli->fd != oldfd)
+ {
+ if (dup2(cli->fd, oldfd) == oldfd)
+ {
+ cli_close_socket(cli);
}
}
return True;
@@ -2832,18 +2977,108 @@ BOOL cli_reestablish_connection(struct cli_state *cli)
return False;
}
+static BOOL cli_init_redirect(struct cli_state *cli,
+ const char* srv_name, struct in_addr *destip,
+ const struct ntuser_creds *usr)
+{
+ int sock;
+ fstring ip_name;
+ struct cli_state cli_redir;
+ fstring path;
+ vuser_key key;
+
+ uint32 len;
+ char *data;
+ char *in = cli->inbuf;
+ char *out = cli->outbuf;
+ prs_struct ps;
+ uint16 command;
+
+ key.pid = getpid();
+ key.vuid = UID_FIELD_INVALID;
+
+ slprintf(path, sizeof(path)-1, "/tmp/.smb.%d/agent", getuid());
+
+ if (strequal(srv_name, "*SMBSERVER"))
+ {
+ fstrcpy(ip_name, "\\\\");
+ fstrcpy(&ip_name[2], inet_ntoa(*destip));
+ srv_name = ip_name;
+ }
+
+ sock = open_pipe_sock(path);
+
+ if (sock < 0)
+ {
+ return False;
+ }
+
+ command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON;
+
+ if (!create_ntuser_creds(&ps, srv_name, 0x0, command,
+ &key, usr,
+ cli->reuse))
+ {
+ DEBUG(0,("could not parse credentials\n"));
+ close(sock);
+ return False;
+ }
+
+ len = ps.offset;
+ data = prs_data(&ps, 0);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("data len: %d\n", len));
+ dump_data(100, data, len);
+#endif
+
+ SIVAL(data, 0, len);
+
+ if (write(sock, data, len) <= 0)
+ {
+ DEBUG(0,("write failed\n"));
+ close(sock);
+ return False;
+ }
+
+ len = read(sock, &cli_redir, sizeof(cli_redir));
+
+ if (len != sizeof(cli_redir))
+ {
+ DEBUG(0,("read failed\n"));
+ close(sock);
+ return False;
+ }
+
+ memcpy(cli, &cli_redir, sizeof(cli_redir));
+ cli->inbuf = in;
+ cli->outbuf = out;
+ cli->fd = sock;
+ cli->reuse = False;
+
+ return sock;
+}
+
/****************************************************************************
establishes a connection right up to doing tconX, reading in a password.
****************************************************************************/
BOOL cli_establish_connection(struct cli_state *cli,
- char *dest_host, struct in_addr *dest_ip,
+ const char *dest_host, struct in_addr *dest_ip,
struct nmb_name *calling, struct nmb_name *called,
char *service, char *service_type,
BOOL do_shutdown, BOOL do_tcon)
{
- DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n",
- nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip),
- cli->user_name, cli->domain));
+ fstring callingstr;
+ fstring calledstr;
+
+ nmb_safe_namestr(calling, callingstr, sizeof(callingstr));
+ nmb_safe_namestr(called , calledstr , sizeof(calledstr ));
+
+ DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s] with NTLM%s, nopw: %s\n",
+ callingstr, calledstr, inet_ntoa(*dest_ip),
+ cli->usr.user_name, cli->usr.domain,
+ cli->use_ntlmv2 ? "v2" : "v1",
+ BOOLSTR(pwd_is_nullpwd(&cli->usr.pwd))));
/* establish connection */
@@ -2852,12 +3087,24 @@ BOOL cli_establish_connection(struct cli_state *cli,
return False;
}
+ if (cli->fd == -1 && cli->redirect)
+ {
+ if (cli_init_redirect(cli, dest_host, dest_ip, &cli->usr))
+ {
+ DEBUG(10,("cli_establish_connection: redirected OK\n"));
+ return True;
+ }
+ else
+ {
+ DEBUG(10,("redirect FAILED, make direct connection\n"));
+ }
+ }
if (cli->fd == -1)
{
if (!cli_connect(cli, dest_host, dest_ip))
{
DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
- nmb_namestr(calling), inet_ntoa(*dest_ip)));
+ callingstr, inet_ntoa(*dest_ip)));
return False;
}
}
@@ -2866,7 +3113,9 @@ BOOL cli_establish_connection(struct cli_state *cli,
{
DEBUG(1,("failed session request\n"));
if (do_shutdown)
- cli_shutdown(cli);
+ {
+ cli_shutdown(cli);
+ }
return False;
}
@@ -2874,33 +3123,243 @@ BOOL cli_establish_connection(struct cli_state *cli,
{
DEBUG(1,("failed negprot\n"));
if (do_shutdown)
- cli_shutdown(cli);
+ {
+ cli_shutdown(cli);
+ }
return False;
}
- if (cli->pwd.cleartext || cli->pwd.null_pwd)
+#if 0
+ if (cli->usr.domain[0] == 0)
{
- fstring passwd;
- int pass_len;
+ safe_strcpy(cli->usr.domain, cli->server_domain,
+ sizeof(cli->usr.domain));
+ }
+#endif
- if (cli->pwd.null_pwd)
+ if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY))
+ {
+ /* common to both session setups */
+ uint32 ntlmssp_flgs;
+ char pwd_buf[128];
+ int buf_len;
+ char *p;
+ char *e = pwd_buf + sizeof(pwd_buf);
+
+ /* 1st session setup */
+ uchar pwd_data[34] =
+ {
+ 0x60, 0x40, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
+ 0x05, 0x02, 0xa0, 0x36, 0x30, 0x34, 0xa0, 0x0e,
+ 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
+ 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x22,
+ 0x04, 0x20
+ };
+ /* 2nd session setup */
+#if 0
+ uchar pwd_data_2[8] =
+ {
+ 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b
+ };
+#endif
+ prs_struct auth_resp;
+ int resp_len;
+ char *p_gssapi;
+ char *p_oem;
+ char *p_gssapi_end;
+ uint16 gssapi_len;
+
+ memset(pwd_buf, 0, sizeof(pwd_buf));
+ memcpy(pwd_buf, pwd_data, sizeof(pwd_data));
+ p = pwd_buf + sizeof(pwd_data);
+
+ safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1);
+ p = skip_string(p, 1);
+ CVAL(p, 0) = 0x1;
+ p += 4;
+ ntlmssp_flgs =
+ NTLMSSP_NEGOTIATE_UNICODE |
+ NTLMSSP_NEGOTIATE_OEM |
+ NTLMSSP_NEGOTIATE_SIGN |
+ NTLMSSP_NEGOTIATE_SEAL |
+ NTLMSSP_NEGOTIATE_LM_KEY |
+ NTLMSSP_NEGOTIATE_NTLM |
+ NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
+ NTLMSSP_NEGOTIATE_00001000 |
+ NTLMSSP_NEGOTIATE_00002000;
+ SIVAL(p, 0, ntlmssp_flgs);
+ p += 4;
+ p += 16; /* skip some NULL space */
+ CVAL(p, 0) = 0; p++; /* alignment */
+
+ buf_len = PTR_DIFF(p, pwd_buf);
+
+ /* first session negotiation stage */
+ if (!cli_session_setup_x(cli, cli->usr.user_name,
+ pwd_buf, buf_len,
+ NULL, 0,
+ cli->usr.domain))
+ {
+ DEBUG(1,("failed session setup\n"));
+ if (do_shutdown)
+ {
+ cli_shutdown(cli);
+ }
+ return False;
+ }
+
+ DEBUG(1,("1st session setup ok\n"));
+
+ if (*cli->server_domain || *cli->server_os || *cli->server_type)
+ {
+ DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
+ cli->server_domain,
+ cli->server_os,
+ cli->server_type));
+ }
+
+ p = smb_buf(cli->inbuf) + 0x2f;
+ ntlmssp_flgs = IVAL(p, 0); /* 0x80808a05; */
+ p += 4;
+ memcpy(cli->cryptkey, p, 8);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("cli_session_setup_x: ntlmssp %8x\n",
+ ntlmssp_flgs));
+
+ DEBUG(100,("cli_session_setup_x: crypt key\n"));
+ dump_data(100, cli->cryptkey, 8);
+#endif
+ prs_init(&auth_resp, 0x0, 4, False);
+
+ if (cli->use_ntlmv2 != False)
+ {
+ DEBUG(10,("cli_establish_connection: NTLMv2\n"));
+ pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey,
+ cli->usr.user_name, calling->name,
+ cli->usr.domain,
+ cli->nt.usr_sess_key);
+ }
+ else
+ {
+ DEBUG(10,("cli_establish_connection: NTLMv1\n"));
+ pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey,
+ cli->nt.usr_sess_key);
+ }
+
+ create_ntlmssp_resp(&cli->usr.pwd, cli->usr.domain,
+ cli->usr.user_name, cli->calling.name,
+ ntlmssp_flgs,
+ &auth_resp);
+ prs_link(NULL, &auth_resp, NULL);
+
+ memset(pwd_buf, 0, sizeof(pwd_buf));
+ p = pwd_buf;
+
+ CVAL(p, 0) = 0xa1; p++;
+ CVAL(p, 0) = 0x82; p++;
+ p_gssapi = p; p+= 2;
+ CVAL(p, 0) = 0x30; p++;
+ CVAL(p, 0) = 0x82; p++;
+ p += 2;
+
+ CVAL(p, 0) = 0xa2; p++;
+ CVAL(p, 0) = 0x82; p++;
+ p_oem = p; p+= 2;
+ CVAL(p, 0) = 0x04; p++;
+ CVAL(p, 0) = 0x82; p++;
+ p += 2;
+
+ p_gssapi_end = p;
+
+ safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1);
+ p = skip_string(p, 1);
+ CVAL(p, 0) = 0x3;
+ p += 4;
+
+ resp_len = prs_buf_len(&auth_resp);
+ prs_buf_copy(p, &auth_resp, 0, resp_len);
+ prs_free_data(&auth_resp);
+
+ p += resp_len;
+
+ buf_len = PTR_DIFF(p, pwd_buf);
+ gssapi_len = PTR_DIFF(p, p_gssapi_end) + 12;
+
+ *p_gssapi++ = (gssapi_len >> 8) & 0xff;
+ *p_gssapi++ = gssapi_len & 0xff;
+
+ p_gssapi += 2;
+ gssapi_len -= 4;
+
+ *p_gssapi++ = (gssapi_len >> 8) & 0xff;
+ *p_gssapi++ = gssapi_len & 0xff;
+
+ gssapi_len -= 4;
+
+ *p_oem++ = (gssapi_len >> 8) & 0xff;
+ *p_oem++ = gssapi_len & 0xff;
+
+ p_oem += 2;
+ gssapi_len -= 4;
+
+ *p_oem++ = (gssapi_len >> 8) & 0xff;
+ *p_oem++ = gssapi_len & 0xff;
+
+ /* second session negotiation stage */
+ if (!cli_session_setup_x(cli, cli->usr.user_name,
+ pwd_buf, buf_len,
+ NULL, 0,
+ cli->usr.domain))
+ {
+ DEBUG(1,("failed session setup\n"));
+ if (do_shutdown)
+ {
+ cli_shutdown(cli);
+ }
+ return False;
+ }
+
+ DEBUG(1,("2nd session setup ok\n"));
+
+ if (do_tcon)
+ {
+ if (!cli_send_tconX(cli, service, service_type,
+ NULL, 0))
+
+ {
+ DEBUG(1,("failed tcon_X\n"));
+ if (do_shutdown)
+ {
+ cli_shutdown(cli);
+ }
+ return False;
+ }
+ }
+ }
+ else if (cli->usr.pwd.cleartext || cli->usr.pwd.null_pwd)
+ {
+ fstring passwd, ntpasswd;
+ int pass_len = 0, ntpass_len = 0;
+
+ if (cli->usr.pwd.null_pwd)
{
/* attempt null session */
- passwd[0] = 0;
- pass_len = 1;
+ passwd[0] = ntpasswd[0] = 0;
+ pass_len = ntpass_len = 1;
}
else
{
/* attempt clear-text session */
- pwd_get_cleartext(&(cli->pwd), passwd);
+ pwd_get_cleartext(&(cli->usr.pwd), passwd);
pass_len = strlen(passwd);
}
/* attempt clear-text session */
- if (!cli_session_setup(cli, cli->user_name,
+ if (!cli_session_setup(cli, calling->name,
+ cli->usr.user_name,
passwd, pass_len,
- NULL, 0,
- cli->domain))
+ ntpasswd, ntpass_len,
+ cli->usr.domain))
{
DEBUG(1,("failed session setup\n"));
if (do_shutdown)
@@ -2926,25 +3385,71 @@ BOOL cli_establish_connection(struct cli_state *cli,
else
{
/* attempt encrypted session */
- unsigned char nt_sess_pwd[24];
unsigned char lm_sess_pwd[24];
+ unsigned char nt_sess_pwd[128];
+ size_t nt_sess_pwd_len;
+
+ if (cli->use_ntlmv2 != False)
+ {
+ DEBUG(10,("cli_establish_connection: NTLMv2\n"));
+ pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey,
+ cli->usr.user_name, calling->name,
+ cli->usr.domain,
+ cli->nt.usr_sess_key);
+ }
+ else
+ {
+ DEBUG(10,("cli_establish_connection: NTLMv1\n"));
+ pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey,
+ cli->nt.usr_sess_key);
+ }
- /* creates (storing a copy of) and then obtains a 24 byte password OWF */
- pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey);
- pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd);
+ pwd_get_lm_nt_owf(&(cli->usr.pwd), lm_sess_pwd, nt_sess_pwd,
+ &nt_sess_pwd_len);
/* attempt encrypted session */
- if (!cli_session_setup(cli, cli->user_name,
- (char*)lm_sess_pwd, sizeof(lm_sess_pwd),
- (char*)nt_sess_pwd, sizeof(nt_sess_pwd),
- cli->domain))
+ if (!cli_session_setup_x(cli, cli->usr.user_name,
+ (char*)lm_sess_pwd, sizeof(lm_sess_pwd),
+ (char*)nt_sess_pwd, nt_sess_pwd_len,
+ cli->usr.domain))
{
DEBUG(1,("failed session setup\n"));
+
+ if (cli->use_ntlmv2 == Auto)
+ {
+ DEBUG(10,("NTLMv2 failed. Using NTLMv1\n"));
+ cli->use_ntlmv2 = False;
+ if (do_tcon)
+ {
+ fstrcpy(cli->share, service);
+ fstrcpy(cli->dev, service_type);
+ }
+ fstrcpy(cli->desthost, dest_host);
+ cli_close_socket(cli);
+ return cli_establish_connection(cli,
+ dest_host, dest_ip,
+ calling, called,
+ service, service_type,
+ do_shutdown, do_tcon);
+ }
+
if (do_shutdown)
- cli_shutdown(cli);
+ {
+ cli_shutdown(cli);
+ }
return False;
}
+ DEBUG(1,("session setup ok\n"));
+
+ if (*cli->server_domain || *cli->server_os || *cli->server_type)
+ {
+ DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
+ cli->server_domain,
+ cli->server_os,
+ cli->server_type));
+ }
+
if (do_tcon)
{
if (!cli_send_tconX(cli, service, service_type,
@@ -2952,18 +3457,186 @@ BOOL cli_establish_connection(struct cli_state *cli,
{
DEBUG(1,("failed tcon_X\n"));
if (do_shutdown)
- cli_shutdown(cli);
+ {
+ cli_shutdown(cli);
+ }
return False;
}
}
}
if (do_shutdown)
- cli_shutdown(cli);
+ {
+ cli_shutdown(cli);
+ }
return True;
}
+BOOL cli_connect_auth(struct cli_state *cli,
+ const char* desthost,
+ struct in_addr *dest_ip,
+ const struct ntuser_creds *usr)
+{
+ extern pstring global_myname;
+ extern pstring scope;
+ struct nmb_name calling, called;
+
+ ZERO_STRUCTP(cli);
+ if (!cli_initialise(cli))
+ {
+ DEBUG(0,("unable to initialise client connection.\n"));
+ return False;
+ }
+
+ make_nmb_name(&calling, global_myname, 0x0 , scope);
+ make_nmb_name(&called , desthost , 0x20, scope);
+
+ cli_init_creds(cli, usr);
+
+ if (!cli_establish_connection(cli, desthost, dest_ip,
+ &calling, &called,
+ "IPC$", "IPC",
+ False, True))
+ {
+ cli_shutdown(cli);
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+ connect to one of multiple servers: don't care which
+****************************************************************************/
+BOOL cli_connect_servers_auth(struct cli_state *cli,
+ char *p,
+ const struct ntuser_creds *usr)
+{
+ fstring remote_host;
+ BOOL connected_ok = False;
+
+ /*
+ * Treat each name in the 'password server =' line as a potential
+ * PDC/BDC. Contact each in turn and try and authenticate.
+ */
+
+ DEBUG(10,("cli_connect_servers_auth: %s\n", p));
+
+ while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host)))
+ {
+ fstring desthost;
+ struct in_addr dest_ip;
+ strupper(remote_host);
+
+ if (!resolve_srv_name( remote_host, desthost, &dest_ip))
+ {
+ DEBUG(1,("Can't resolve address for %s\n", remote_host));
+ continue;
+ }
+
+ if (!cli_connect_auth(cli, desthost, &dest_ip, usr) &&
+ !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, usr))
+ {
+ continue;
+ }
+
+ if (cli->protocol < PROTOCOL_LANMAN2 ||
+ !IS_BITS_SET_ALL(cli->sec_mode, 1))
+ {
+ DEBUG(1,("machine %s not in user level security mode\n",
+ remote_host));
+ cli_shutdown(cli);
+ continue;
+ }
+
+ /*
+ * We have an anonymous connection to IPC$.
+ */
+
+ connected_ok = True;
+ break;
+ }
+
+ if (!connected_ok)
+ {
+ DEBUG(0,("Domain password server not available.\n"));
+ }
+
+ return connected_ok;
+}
+
+/****************************************************************************
+ connect to one of multiple servers: don't care which
+****************************************************************************/
+BOOL cli_connect_serverlist(struct cli_state *cli, char *p)
+{
+ fstring remote_host;
+ fstring desthost;
+ struct in_addr dest_ip;
+ BOOL connected_ok = False;
+
+ /*
+ * Treat each name in the 'password server =' line as a potential
+ * PDC/BDC. Contact each in turn and try and authenticate.
+ */
+
+ while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host)))
+ {
+ ZERO_STRUCTP(cli);
+
+ if (!cli_initialise(cli))
+ {
+ DEBUG(0,("cli_connect_serverlist: unable to initialise client connection.\n"));
+ return False;
+ }
+
+ standard_sub_basic(remote_host);
+ strupper(remote_host);
+
+ if (!resolve_srv_name( remote_host, desthost, &dest_ip))
+ {
+ DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_host));
+ continue;
+ }
+
+ if ((lp_security() != SEC_USER) && (ismyip(dest_ip)))
+ {
+ DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_host));
+ continue;
+ }
+
+ if (!cli_connect_auth(cli, remote_host , &dest_ip, NULL) &&
+ !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, NULL))
+ {
+ continue;
+ }
+
+
+ if (cli->protocol < PROTOCOL_LANMAN2 ||
+ !IS_BITS_SET_ALL(cli->sec_mode, 1))
+ {
+ DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n",
+ remote_host));
+ cli_shutdown(cli);
+ continue;
+ }
+
+ /*
+ * We have an anonymous connection to IPC$.
+ */
+
+ connected_ok = True;
+ break;
+ }
+
+ if (!connected_ok)
+ {
+ DEBUG(0,("cli_connect_serverlist: Domain password server not available.\n"));
+ }
+
+ return connected_ok;
+}
/****************************************************************************
cancel a print job
@@ -2976,7 +3649,7 @@ int cli_printjob_del(struct cli_state *cli, int job)
int rdrcnt,rprcnt, ret = -1;
pstring param;
- memset(param,'\0',sizeof(param));
+ bzero(param,sizeof(param));
p = param;
SSVAL(p,0,81); /* DosPrintJobDel() */
@@ -3017,7 +3690,7 @@ int cli_print_queue(struct cli_state *cli,
int result_code=0;
int i = -1;
- memset(param,'\0',sizeof(param));
+ bzero(param,sizeof(param));
p = param;
SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */
@@ -3079,29 +3752,29 @@ check for existance of a dir
****************************************************************************/
BOOL cli_chkpath(struct cli_state *cli, char *path)
{
- pstring path2;
+ fstring path2;
char *p;
- safe_strcpy(path2,path,sizeof(pstring));
+ fstrcpy(path2,path);
trim_string(path2,NULL,"\\");
if (!*path2) *path2 = '\\';
- memset(cli->outbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
set_message(cli->outbuf,0,4 + strlen(path2),True);
SCVAL(cli->outbuf,smb_com,SMBchkpth);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
+
p = smb_buf(cli->outbuf);
*p++ = 4;
- safe_strcpy(p,path2,strlen(path2));
- unix_to_dos(p,True);
+ fstrcpy(p,path2);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
- if (cli_error(cli, NULL, NULL, NULL)) return False;
+ if (cli_error(cli, NULL, NULL)) return False;
return True;
}
@@ -3116,7 +3789,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
char *p;
/* send a SMBsendstrt command */
- memset(cli->outbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
set_message(cli->outbuf,0,0,True);
CVAL(cli->outbuf,smb_com) = SMBsendstrt;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -3125,22 +3798,20 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
p = smb_buf(cli->outbuf);
*p++ = 4;
pstrcpy(p,username);
- unix_to_dos(p,True);
p = skip_string(p,1);
*p++ = 4;
pstrcpy(p,host);
- unix_to_dos(p,True);
p = skip_string(p,1);
set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
- if (cli_error(cli, NULL, NULL, NULL)) return False;
+ if (cli_error(cli, NULL, NULL)) return False;
*grp = SVAL(cli->inbuf,smb_vwv0);
@@ -3155,7 +3826,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
{
char *p;
- memset(cli->outbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
set_message(cli->outbuf,1,len+3,True);
CVAL(cli->outbuf,smb_com) = SMBsendtxt;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -3167,13 +3838,13 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
*p = 1;
SSVAL(p,1,len);
memcpy(p+3,msg,len);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
- if (cli_error(cli, NULL, NULL, NULL)) return False;
+ if (cli_error(cli, NULL, NULL)) return False;
return True;
}
@@ -3183,7 +3854,7 @@ end a message
****************************************************************************/
BOOL cli_message_end(struct cli_state *cli, int grp)
{
- memset(cli->outbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
set_message(cli->outbuf,1,0,True);
CVAL(cli->outbuf,smb_com) = SMBsendend;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -3192,13 +3863,13 @@ BOOL cli_message_end(struct cli_state *cli, int grp)
cli_setup_packet(cli);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
- if (cli_error(cli, NULL, NULL, NULL)) return False;
+ if (cli_error(cli, NULL, NULL)) return False;
return True;
}
@@ -3209,13 +3880,13 @@ query disk space
****************************************************************************/
BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
{
- memset(cli->outbuf,'\0',smb_size);
+ bzero(cli->outbuf,smb_size);
set_message(cli->outbuf,0,0,True);
CVAL(cli->outbuf,smb_com) = SMBdskattr;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- cli_send_smb(cli);
+ cli_send_smb(cli, True);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -3227,60 +3898,39 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
return True;
}
-/****************************************************************************
- Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
-****************************************************************************/
-
-BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost,
- struct in_addr *pdest_ip)
+BOOL get_any_dc_name(const char *domain, char *srv_name)
{
- struct nmb_name calling, called;
-
- make_nmb_name(&calling, srchost, 0x0);
-
- /*
- * If the called name is an IP address
- * then use *SMBSERVER immediately.
- */
-
- if(is_ipaddress(desthost))
- make_nmb_name(&called, "*SMBSERVER", 0x20);
- else
- make_nmb_name(&called, desthost, 0x20);
-
- if (!cli_session_request(cli, &calling, &called)) {
- struct nmb_name smbservername;
+ struct cli_state cli;
+ char *servers;
- make_nmb_name(&smbservername , "*SMBSERVER", 0x20);
+ DEBUG(10,("get_any_dc_name: domain %s\n", domain));
- /*
- * If the name wasn't *SMBSERVER then
- * try with *SMBSERVER if the first name fails.
- */
+ servers = get_trusted_serverlist(domain);
- if (nmb_name_equal(&called, &smbservername)) {
+ if (servers == NULL)
+ {
+ /* no domain found, not even our own domain. */
+ return False;
+ }
- /*
- * The name used was *SMBSERVER, don't bother with another name.
- */
+ if (servers[0] == 0)
+ {
+ /* empty list: return our own name */
+ fstrcpy(srv_name, "\\\\.");
+ return True;
+ }
- DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \
-with error %s.\n", desthost, cli_errstr(cli) ));
- cli_shutdown(cli);
+ if (!cli_connect_servers_auth(&cli, servers, NULL))
+ {
return False;
}
- cli_shutdown(cli);
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli.desthost);
+ strupper(srv_name);
- if (!cli_initialise(cli) ||
- !cli_connect(cli, desthost, pdest_ip) ||
- !cli_session_request(cli, &calling, &smbservername)) {
- DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \
-name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) ));
- cli_shutdown(cli);
- return False;
- }
- }
+ cli_shutdown(&cli);
- return True;
+ return True;
}
+
diff --git a/source/libsmb/clienttrust.c b/source/libsmb/clienttrust.c
new file mode 100644
index 00000000000..7111d255114
--- /dev/null
+++ b/source/libsmb/clienttrust.c
@@ -0,0 +1 @@
+/* retired */
diff --git a/source/libsmb/credentials.c b/source/libsmb/credentials.c
index 26d5c13bc9a..a4416b885b8 100644
--- a/source/libsmb/credentials.c
+++ b/source/libsmb/credentials.c
@@ -28,7 +28,7 @@ extern int DEBUGLEVEL;
/****************************************************************************
represent a credential as a string
****************************************************************************/
-char *credstr(uchar *cred)
+char *credstr(const uchar *cred)
{
static fstring buf;
slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X",
@@ -46,11 +46,11 @@ Input: 8 byte challenge block
Output:
8 byte session key
****************************************************************************/
-void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass,
+void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, const char *pass,
uchar session_key[8])
{
uint32 sum[2];
- unsigned char sum2[8];
+ uchar sum2[8];
sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0);
sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4);
@@ -58,7 +58,7 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass,
SIVAL(sum2,0,sum[0]);
SIVAL(sum2,4,sum[1]);
- cred_hash1(session_key, sum2,(unsigned char *)pass);
+ cred_hash1(session_key, sum2,(const uchar *)pass);
/* debug output */
DEBUG(4,("cred_session_key\n"));
@@ -115,8 +115,8 @@ Output:
returns 1 if computed credential matches received credential
returns 0 otherwise
****************************************************************************/
-int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred,
- UTIME timestamp)
+int cred_assert(const DOM_CHAL *cred, uchar session_key[8],
+ DOM_CHAL *stored_cred, UTIME timestamp)
{
DOM_CHAL cred2;
@@ -179,7 +179,7 @@ BOOL clnt_deal_with_creds(uchar sess_key[8],
****************************************************************************/
BOOL deal_with_creds(uchar sess_key[8],
DOM_CRED *sto_clnt_cred,
- DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred)
+ const DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred)
{
UTIME new_clnt_time;
uint32 new_cred;
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index 08f26f10d57..51601d15fbb 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -22,32 +22,18 @@
#include "includes.h"
+extern pstring scope;
+extern pstring global_myname;
extern int DEBUGLEVEL;
/* nmbd.c sets this to True. */
BOOL global_in_nmbd = False;
-/****************************************************************************
-generate a random trn_id
-****************************************************************************/
-static int generate_trn_id(void)
-{
- static int trn_id;
-
- if (trn_id == 0) {
- srandom(getpid());
- }
-
- trn_id = random();
-
- return trn_id % (unsigned)0x7FFF;
-}
-
+ static int name_trn_id = 0;
/****************************************************************************
- Interpret a node status response.
+interpret a node status response
****************************************************************************/
-
static void _interpret_node_status(char *p, char *master,char *rname)
{
int numnames = CVAL(p,0);
@@ -57,54 +43,56 @@ static void _interpret_node_status(char *p, char *master,char *rname)
if (master) *master = 0;
p += 1;
- while (numnames--) {
- char qname[17];
- int type;
- fstring flags;
- int i;
- *flags = 0;
- StrnCpy(qname,p,15);
- type = CVAL(p,15);
- p += 16;
-
- fstrcat(flags, (p[0] & 0x80) ? "<GROUP> " : " ");
- if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B ");
- if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P ");
- if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M ");
- if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H ");
- if (p[0] & 0x10) fstrcat(flags,"<DEREGISTERING> ");
- if (p[0] & 0x08) fstrcat(flags,"<CONFLICT> ");
- if (p[0] & 0x04) fstrcat(flags,"<ACTIVE> ");
- if (p[0] & 0x02) fstrcat(flags,"<PERMANENT> ");
-
- if (master && !*master && type == 0x1d) {
- StrnCpy(master,qname,15);
- trim_string(master,NULL," ");
- }
+ while (numnames--)
+ {
+ char qname[17];
+ int type;
+ fstring flags;
+ int i;
+ *flags = 0;
+ StrnCpy(qname,p,15);
+ type = CVAL(p,15);
+ p += 16;
+
+ fstrcat(flags, (p[0] & 0x80) ? "<GROUP> " : " ");
+ if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B ");
+ if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P ");
+ if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M ");
+ if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H ");
+ if (p[0] & 0x10) fstrcat(flags,"<DEREGISTERING> ");
+ if (p[0] & 0x08) fstrcat(flags,"<CONFLICT> ");
+ if (p[0] & 0x04) fstrcat(flags,"<ACTIVE> ");
+ if (p[0] & 0x02) fstrcat(flags,"<PERMANENT> ");
+
+ if (master && !*master && type == 0x1d) {
+ StrnCpy(master,qname,15);
+ trim_string(master,NULL," ");
+ }
- if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
- StrnCpy(rname,qname,15);
- trim_string(rname,NULL," ");
- }
+ if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
+ StrnCpy(rname,qname,15);
+ trim_string(rname,NULL," ");
+ }
- for (i = strlen( qname) ; --i >= 0 ; ) {
- if (!isprint((int)qname[i])) qname[i] = '.';
+ for (i = strlen( qname) ; --i >= 0 ; ) {
+ if (!isprint((int)qname[i])) qname[i] = '.';
+ }
+ DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags));
+ p+=2;
}
- DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags));
- p+=2;
- }
-
DEBUG(1,("num_good_sends=%d num_good_receives=%d\n",
IVAL(p,20),IVAL(p,24)));
}
+
/****************************************************************************
- Internal function handling a netbios name status query on a host.
-**************************************************************************/
-static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
- struct in_addr to_ip,char *master,
- char *rname, BOOL verbose,
- void (*fn_interpret_node_status)(char *, char *,char *))
+ do a netbios name status query on a host
+
+ the "master" parameter is a hack used for finding workgroups.
+ **************************************************************************/
+BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
+ struct in_addr to_ip,char *master,char *rname,
+ void (*fn)(struct packet_struct *))
{
BOOL found=False;
int retries = 2;
@@ -113,10 +101,27 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
struct packet_struct p;
struct packet_struct *p2;
struct nmb_packet *nmb = &p.packet.nmb;
+ int packet_type = NMB_PACKET;
+ BOOL first_time = True;
+
+ if (fd == -1)
+ {
+ retries = 1;
+ packet_type = NMB_SOCK_PACKET;
+ fd = get_nmb_sock();
+
+ if (fd < 0)
+ {
+ return False;
+ }
+ }
+ bzero((char *)&p,sizeof(p));
- memset((char *)&p,'\0',sizeof(p));
+ if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) +
+ ((unsigned)getpid()%(unsigned)100);
+ name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
- nmb->header.name_trn_id = generate_trn_id();
+ nmb->header.name_trn_id = name_trn_id;
nmb->header.opcode = 0;
nmb->header.response = False;
nmb->header.nm_flags.bcast = False;
@@ -130,7 +135,7 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
nmb->header.nscount = 0;
nmb->header.arcount = 0;
- make_nmb_name(&nmb->question.question_name,name,name_type);
+ make_nmb_name(&nmb->question.question_name,name,name_type,scope);
nmb->question.question_type = 0x21;
nmb->question.question_class = 0x1;
@@ -139,91 +144,107 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
p.port = NMB_PORT;
p.fd = fd;
p.timestamp = time(NULL);
- p.packet_type = NMB_PACKET;
+ p.packet_type = packet_type;
GetTimeOfDay(&tval);
- if (!send_packet(&p))
- return(False);
-
- retries--;
-
- while (1) {
- struct timeval tval2;
- GetTimeOfDay(&tval2);
- if (TvalDiff(&tval,&tval2) > retry_time) {
- if (!retries)
- break;
- if (!found && !send_packet(&p))
- return False;
- GetTimeOfDay(&tval);
- retries--;
+ while (1)
+ {
+ struct timeval tval2;
+ GetTimeOfDay(&tval2);
+ if (first_time || TvalDiff(&tval,&tval2) > retry_time)
+ {
+ first_time = False;
+ if (!found && !send_packet(&p))
+ {
+ if (packet_type == NMB_SOCK_PACKET) close(fd);
+ return False;
+ }
+ GetTimeOfDay(&tval);
+ }
+
+ if ((p2=receive_packet(fd,packet_type,90)))
+ {
+ struct nmb_packet *nmb2 = &p2->packet.nmb;
+ debug_nmb_packet(p2);
+
+ if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
+ !nmb2->header.response) {
+ /* its not for us - maybe deal with it later */
+ if (fn)
+ fn(p2);
+ else
+ free_packet(p2);
+ continue;
+ }
+
+ if (nmb2->header.opcode != 0 ||
+ nmb2->header.nm_flags.bcast ||
+ nmb2->header.rcode ||
+ !nmb2->header.ancount ||
+ nmb2->answers->rr_type != 0x21) {
+ /* XXXX what do we do with this? could be a redirect, but
+ we'll discard it for the moment */
+ free_packet(p2);
+ continue;
}
- if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
- struct nmb_packet *nmb2 = &p2->packet.nmb;
- debug_nmb_packet(p2);
-
- if (nmb2->header.opcode != 0 ||
- nmb2->header.nm_flags.bcast ||
- nmb2->header.rcode ||
- !nmb2->header.ancount ||
- nmb2->answers->rr_type != 0x21) {
- /* XXXX what do we do with this? could be a
- redirect, but we'll discard it for the
- moment */
- free_packet(p2);
- continue;
- }
+ retries--;
- if(fn_interpret_node_status)
- (*fn_interpret_node_status)(&nmb2->answers->rdata[0],master,rname);
- free_packet(p2);
- return(True);
- }
- }
+ _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
+ free_packet(p2);
+ if (packet_type == NMB_SOCK_PACKET) close(fd);
+ return(True);
+ }
+ }
+
- if(verbose)
- DEBUG(0,("No status response (this is not unusual)\n"));
+ DEBUG(0,("No status response (this is not unusual)\n"));
+if (packet_type == NMB_SOCK_PACKET) close(fd);
return(False);
}
-/****************************************************************************
- Do a netbios name status query on a host.
- The "master" parameter is a hack used for finding workgroups.
-**************************************************************************/
-BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
- struct in_addr to_ip,char *master,char *rname)
-{
- return internal_name_status(fd,name,name_type,recurse,
- to_ip,master,rname,True,
- _interpret_node_status);
-}
/****************************************************************************
- Do a netbios name query to find someones IP.
- Returns an array of IP addresses or NULL if none.
- *count will be set to the number of addresses returned.
-****************************************************************************/
-
-struct in_addr *name_query(int fd,const char *name,int name_type,
- BOOL bcast,BOOL recurse,
- struct in_addr to_ip, int *count)
+ do a netbios name query to find someones IP
+ returns an array of IP addresses or NULL if none
+ *count will be set to the number of addresses returned
+ ****************************************************************************/
+struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse,
+ struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *))
{
BOOL found=False;
int i, retries = 3;
- int retry_time = bcast?250:2000;
+ int retry_time = bcast?2000:2000;
struct timeval tval;
struct packet_struct p;
struct packet_struct *p2;
struct nmb_packet *nmb = &p.packet.nmb;
struct in_addr *ip_list = NULL;
+ BOOL packet_type = NMB_PACKET;
+ BOOL first_send = True;
+
+ if (fd == -1)
+ {
+ retries = 1;
+ packet_type = NMB_SOCK_PACKET;
+ fd = get_nmb_sock();
+
+ if (fd < 0)
+ {
+ return NULL;
+ }
+ }
- memset((char *)&p,'\0',sizeof(p));
+ bzero((char *)&p,sizeof(p));
(*count) = 0;
- nmb->header.name_trn_id = generate_trn_id();
+ if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) +
+ ((unsigned)getpid()%(unsigned)100);
+ name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
+
+ nmb->header.name_trn_id = name_trn_id;
nmb->header.opcode = 0;
nmb->header.response = False;
nmb->header.nm_flags.bcast = bcast;
@@ -237,7 +258,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
nmb->header.nscount = 0;
nmb->header.arcount = 0;
- make_nmb_name(&nmb->question.question_name,name,name_type);
+ make_nmb_name(&nmb->question.question_name,name,name_type,scope);
nmb->question.question_type = 0x20;
nmb->question.question_class = 0x1;
@@ -246,70 +267,93 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
p.port = NMB_PORT;
p.fd = fd;
p.timestamp = time(NULL);
- p.packet_type = NMB_PACKET;
+ p.packet_type = packet_type;
- GetTimeOfDay(&tval);
+ GetTimeOfDay(&tval);
- if (!send_packet(&p))
- return NULL;
+ while (retries >= 0)
+ {
+ struct timeval tval2;
+
+ GetTimeOfDay(&tval2);
+ if (first_send || TvalDiff(&tval,&tval2) > retry_time)
+ {
+ first_send = False;
+ if (!found && !send_packet(&p))
+ {
+ if (packet_type == NMB_SOCK_PACKET) close(fd);
+ return NULL;
+ }
+ GetTimeOfDay(&tval);
+ }
- retries--;
+ if ((p2=receive_packet(fd,packet_type,90)))
+ {
+ struct nmb_packet *nmb2 = &p2->packet.nmb;
+ debug_nmb_packet(p2);
- while (1)
- {
- struct timeval tval2;
- GetTimeOfDay(&tval2);
- if (TvalDiff(&tval,&tval2) > retry_time) {
- if (!retries)
- break;
- if (!found && !send_packet(&p))
- return NULL;
- GetTimeOfDay(&tval);
- retries--;
- }
+ if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
+ !nmb2->header.response)
+ {
+ DEBUG(10,("packet not for us (received %d, expected %d\n",
+ nmb2->header.name_trn_id, nmb->header.name_trn_id));
+ /*
+ * Its not for us - maybe deal with it later
+ * (put it on the queue?).
+ */
+ if (fn)
+ fn(p2);
+ else
+ free_packet(p2);
+
+ continue;
+ }
- if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
- struct nmb_packet *nmb2 = &p2->packet.nmb;
- debug_nmb_packet(p2);
-
- if (nmb2->header.opcode != 0 ||
- nmb2->header.nm_flags.bcast ||
- nmb2->header.rcode ||
- !nmb2->header.ancount) {
- /*
- * XXXX what do we do with this? Could be a
- * redirect, but we'll discard it for the
- * moment. */
- free_packet(p2);
- continue;
- }
+ retries--;
- ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) *
- ((*count)+nmb2->answers->rdlength/6));
- if (ip_list) {
- DEBUG(2,("Got a positive name query response from %s ( ",
- inet_ntoa(p2->ip)));
- for (i=0;i<nmb2->answers->rdlength/6;i++) {
- putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
- DEBUG(2,("%s ",inet_ntoa(ip_list[(*count)])));
- (*count)++;
- }
- DEBUG(2,(")\n"));
- }
+ if (nmb2->header.opcode != 0 ||
+ nmb2->header.nm_flags.bcast ||
+ nmb2->header.rcode ||
+ !nmb2->header.ancount)
+ {
+ /*
+ * XXXX what do we do with this? Could be a redirect, but
+ * we'll discard it for the moment.
+ */
+ free_packet(p2);
+ continue;
+ }
- found=True;
- retries=0;
- free_packet(p2);
- /*
- * If we're doing a unicast lookup we only
- * expect one reply. Don't wait the full 2
- * seconds if we got one. JRA.
- */
- if(!bcast && found)
- break;
- }
+ ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) *
+ ((*count)+nmb2->answers->rdlength/6));
+ if (ip_list)
+ {
+ DEBUG(fn?3:2,("Got a positive name query response from %s ( ",
+ inet_ntoa(p2->ip)));
+ for (i=0;i<nmb2->answers->rdlength/6;i++)
+ {
+ putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
+ DEBUG(fn?3:2,("%s ",inet_ntoa(ip_list[(*count)])));
+ (*count)++;
+ }
+ DEBUG(fn?3:2,(")\n"));
+ }
+
+ found=True;
+ retries=0;
+ free_packet(p2);
+ if (fn)
+ break;
+
+ if(found)
+ {
+ DEBUG(10,("returning OK\n"));
+ break;
+ }
+ }
}
+ if (packet_type == NMB_SOCK_PACKET) close(fd);
return ip_list;
}
@@ -331,7 +375,6 @@ FILE *startlmhosts(char *fname)
/********************************************************
Parse the next line in the lmhosts file.
*********************************************************/
-
BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
{
pstring line;
@@ -396,7 +439,7 @@ BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipad
char *endptr;
ptr++;
- *name_type = (int)strtol(ptr, &endptr, 16);
+ *name_type = (int)strtol(ptr, &endptr,0);
if(!*ptr || (endptr == ptr))
{
@@ -422,107 +465,108 @@ void endlmhosts(FILE *fp)
fclose(fp);
}
+
+
/********************************************************
- Resolve via "bcast" method.
+resolve via "bcast" method
*********************************************************/
-
-static BOOL resolve_bcast(const char *name, int name_type,
- struct in_addr **return_ip_list, int *return_count)
+static BOOL resolve_bcast(const char *name, struct in_addr *return_ip, int name_type)
{
int sock, i;
- int num_interfaces = iface_count();
-
- *return_ip_list = NULL;
- *return_count = 0;
/*
* "bcast" means do a broadcast lookup on all the local interfaces.
*/
- DEBUG(3,("resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
+ DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s<0x20>\n", name));
sock = open_socket_in( SOCK_DGRAM, 0, 3,
- interpret_addr(lp_socket_address()), True );
-
- if (sock == -1) return False;
-
- set_socket_options(sock,"SO_BROADCAST");
- /*
- * Lookup the name on all the interfaces, return on
- * the first successful match.
- */
- for( i = num_interfaces-1; i >= 0; i--) {
- struct in_addr sendto_ip;
- /* Done this way to fix compiler error on IRIX 5.x */
- sendto_ip = *iface_bcast(*iface_n_ip(i));
- *return_ip_list = name_query(sock, name, name_type, True,
- True, sendto_ip, return_count);
- if(*return_ip_list != NULL) {
- close(sock);
- return True;
+ interpret_addr(lp_socket_address()),True);
+
+ if (sock != -1) {
+ struct in_addr *iplist = NULL;
+ int count;
+ int num_interfaces = iface_count();
+ set_socket_options(sock,"SO_BROADCAST");
+ /*
+ * Lookup the name on all the interfaces, return on
+ * the first successful match.
+ */
+ for( i = 0; i < num_interfaces; i++) {
+ struct in_addr sendto_ip;
+ /* Done this way to fix compiler error on IRIX 5.x */
+ sendto_ip = *iface_bcast(*iface_n_ip(i));
+ iplist = name_query(sock, name, name_type, True,
+ True, sendto_ip, &count, NULL);
+ if(iplist != NULL) {
+ *return_ip = iplist[0];
+ free((char *)iplist);
+ close(sock);
+ return True;
+ }
}
+ close(sock);
}
- close(sock);
return False;
}
+
+
/********************************************************
- Resolve via "wins" method.
+resolve via "wins" method
*********************************************************/
-
-static BOOL resolve_wins(const char *name, int name_type,
- struct in_addr **return_iplist, int *return_count)
+static BOOL resolve_wins(const char *name, struct in_addr *return_ip, int name_type)
{
- int sock;
- struct in_addr wins_ip;
- BOOL wins_ismyip;
-
- *return_iplist = NULL;
- *return_count = 0;
-
- /*
- * "wins" means do a unicast lookup to the WINS server.
- * Ignore if there is no WINS server specified or if the
- * WINS server is one of our interfaces (if we're being
- * called from within nmbd - we can't do this call as we
- * would then block).
- */
-
- DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
-
- if(!*lp_wins_server()) {
- DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS server present.\n"));
- return False;
- }
+ int sock;
+ struct in_addr wins_ip;
+ BOOL wins_ismyip;
+
+ /*
+ * "wins" means do a unicast lookup to the WINS server.
+ * Ignore if there is no WINS server specified or if the
+ * WINS server is one of our interfaces (if we're being
+ * called from within nmbd - we can't do this call as we
+ * would then block).
+ */
+
+ DEBUG(3,("resolve_name: Attempting wins lookup for name %s<0x20>\n", name));
+
+ if(!*lp_wins_server()) {
+ DEBUG(3,("resolve_name: WINS server resolution selected and no WINS server present.\n"));
+ return False;
+ }
- wins_ip = *interpret_addr2(lp_wins_server());
- wins_ismyip = ismyip(wins_ip);
+ wins_ip = *interpret_addr2(lp_wins_server());
+ wins_ismyip = ismyip(wins_ip);
- if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) {
- sock = open_socket_in( SOCK_DGRAM, 0, 3,
- interpret_addr(lp_socket_address()), True );
+ if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) {
+ sock = open_socket_in( SOCK_DGRAM, 0, 3,
+ interpret_addr(lp_socket_address()),True);
- if (sock != -1) {
- *return_iplist = name_query(sock, name, name_type, False,
- True, wins_ip, return_count);
- if(*return_iplist != NULL) {
- close(sock);
- return True;
- }
- close(sock);
- }
- }
+ if (sock != -1) {
+ struct in_addr *iplist = NULL;
+ int count;
+ iplist = name_query(sock, name, name_type, False,
+ True, wins_ip, &count, NULL);
+ if(iplist != NULL) {
+ *return_ip = iplist[0];
+ free((char *)iplist);
+ close(sock);
+ return True;
+ }
+ close(sock);
+ }
+ }
- return False;
+ return False;
}
+
/********************************************************
- Resolve via "lmhosts" method.
+resolve via "lmhosts" method
*********************************************************/
-
-static BOOL resolve_lmhosts(const char *name, int name_type,
- struct in_addr **return_iplist, int *return_count)
+static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int name_type)
{
/*
* "lmhosts" means parse the local lmhosts file.
@@ -531,27 +575,15 @@ static BOOL resolve_lmhosts(const char *name, int name_type,
FILE *fp;
pstring lmhost_name;
int name_type2;
- struct in_addr return_ip;
- *return_iplist = NULL;
- *return_count = 0;
-
- DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
+ DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n", name));
fp = startlmhosts( LMHOSTSFILE );
if(fp) {
- while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
+ while (getlmhostsent(fp, lmhost_name, &name_type2, return_ip)) {
if (strequal(name, lmhost_name) &&
- ((name_type2 == -1) || (name_type == name_type2))
- ) {
+ name_type == name_type2) {
endlmhosts(fp);
- *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
- if(*return_iplist == NULL) {
- DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
- return False;
- }
- **return_iplist = return_ip;
- *return_count = 1;
return True;
}
}
@@ -562,94 +594,89 @@ static BOOL resolve_lmhosts(const char *name, int name_type,
/********************************************************
- Resolve via "hosts" method.
+resolve via "hosts" method
*********************************************************/
-
-static BOOL resolve_hosts(const char *name,
- struct in_addr **return_iplist, int *return_count)
+static BOOL resolve_hosts(const char *name, struct in_addr *return_ip)
{
/*
* "host" means do a localhost, or dns lookup.
*/
struct hostent *hp;
- *return_iplist = NULL;
- *return_count = 0;
-
- DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
+ DEBUG(3,("resolve_name: Attempting host lookup for name %s\n", name));
if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
- struct in_addr return_ip;
- putip((char *)&return_ip,(char *)hp->h_addr);
- *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
- if(*return_iplist == NULL) {
- DEBUG(3,("resolve_hosts: malloc fail !\n"));
- return False;
- }
- **return_iplist = return_ip;
- *return_count = 1;
+ putip((char *)return_ip,(char *)hp->h_addr);
return True;
}
return False;
}
+
/********************************************************
- Internal interface to resolve a name into an IP address.
- Use this function if the string is either an IP address, DNS
- or host name or NetBIOS name. This uses the name switch in the
+ Resolve a name into an IP address. Use this function if
+ the string is either an IP address, DNS or host name
+ or NetBIOS name. This uses the name switch in the
smb.conf to determine the order of name resolution.
*********************************************************/
+BOOL is_ip_address(const char *name)
+{
+ int i;
+ for (i=0; name[i]; i++)
+ if (!(isdigit((int)name[i]) || name[i] == '.'))
+ return False;
+
+ return True;
+}
-static BOOL internal_resolve_name(const char *name, int name_type,
- struct in_addr **return_iplist, int *return_count)
+/********************************************************
+ Resolve a name into an IP address. Use this function if
+ the string is either an IP address, DNS or host name
+ or NetBIOS name. This uses the name switch in the
+ smb.conf to determine the order of name resolution.
+*********************************************************/
+BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
{
pstring name_resolve_list;
fstring tok;
char *ptr;
- BOOL allones = (strcmp(name,"255.255.255.255") == 0);
- BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
- BOOL is_address = is_ipaddress(name);
- *return_iplist = NULL;
- *return_count = 0;
-
- if (allzeros || allones || is_address) {
- *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
- if(*return_iplist == NULL) {
- DEBUG(3,("internal_resolve_name: malloc fail !\n"));
- return False;
- }
- if(is_address) {
- /* if it's in the form of an IP address then get the lib to interpret it */
- (*return_iplist)->s_addr = inet_addr(name);
- } else {
- (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
- *return_count = 1;
- }
+
+ if (strcmp(name,"0.0.0.0") == 0) {
+ return_ip->s_addr = 0;
return True;
}
-
+ if (strcmp(name,"255.255.255.255") == 0) {
+ return_ip->s_addr = 0xFFFFFFFF;
+ return True;
+ }
+
+ /* if it's in the form of an IP address then get the lib to interpret it */
+ if (is_ip_address(name)) {
+ return_ip->s_addr = inet_addr(name);
+ return True;
+ }
+
pstrcpy(name_resolve_list, lp_name_resolve_order());
ptr = name_resolve_list;
- if (!ptr || !*ptr)
- ptr = "host";
+ if (!ptr || !*ptr) ptr = "host";
while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
if((strequal(tok, "host") || strequal(tok, "hosts"))) {
- if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
+ if (name_type == 0x20 && resolve_hosts(name, return_ip)) {
return True;
}
} else if(strequal( tok, "lmhosts")) {
- if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
+ if (resolve_lmhosts(name, return_ip, name_type)) {
return True;
}
} else if(strequal( tok, "wins")) {
/* don't resolve 1D via WINS */
if (name_type != 0x1D &&
- resolve_wins(name, name_type, return_iplist, return_count)) {
+ resolve_wins(name, return_ip, name_type)) {
return True;
}
} else if(strequal( tok, "bcast")) {
- if (resolve_bcast(name, name_type, return_iplist, return_count)) {
+ if (resolve_bcast(name, return_ip, name_type)) {
return True;
}
} else {
@@ -657,244 +684,50 @@ static BOOL internal_resolve_name(const char *name, int name_type,
}
}
- if((*return_iplist) != NULL) {
- free((char *)(*return_iplist));
- *return_iplist = NULL;
- }
return False;
}
/********************************************************
- Internal interface to resolve a name into one IP address.
- Use this function if the string is either an IP address, DNS
- or host name or NetBIOS name. This uses the name switch in the
- smb.conf to determine the order of name resolution.
+ resolve a name of format \\server_name or \\ipaddress
+ into a name. also, cut the \\ from the front for us.
*********************************************************/
-
-BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
+BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
+ struct in_addr *ip)
{
- struct in_addr *ip_list = NULL;
- int count = 0;
-
- if(internal_resolve_name(name, name_type, &ip_list, &count)) {
- *return_ip = ip_list[0];
- free((char *)ip_list);
- return True;
- }
- if(ip_list != NULL)
- free((char *)ip_list);
- return False;
-}
+ BOOL ret;
+ const char *sv_name = srv_name;
-/********************************************************
- Find the IP address of the master browser or DMB for a workgroup.
-*********************************************************/
+ DEBUG(10,("resolve_srv_name: %s\n", srv_name));
-BOOL find_master_ip(char *group, struct in_addr *master_ip)
-{
- struct in_addr *ip_list = NULL;
- int count = 0;
-
- if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
- *master_ip = ip_list[0];
- free((char *)ip_list);
- return True;
- }
- if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
- *master_ip = ip_list[0];
- free((char *)ip_list);
+ if (srv_name == NULL || strequal("\\\\.", srv_name))
+ {
+ fstrcpy(dest_host, global_myname);
+ ip = interpret_addr2("127.0.0.1");
return True;
}
- if(ip_list != NULL)
- free((char *)ip_list);
- return False;
-}
-
-
-/********************************************************
- Lookup a PDC name given a Domain name and IP address.
-*********************************************************/
-BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name)
-{
- int retries = 3;
- int retry_time = 2000;
- struct timeval tval;
- struct packet_struct p;
- struct dgram_packet *dgram = &p.packet.dgram;
- char *ptr,*p2;
- char tmp[4];
- int len;
- struct sockaddr_in sock_name;
- int sock_len = sizeof(sock_name);
- const char *mailslot = "\\MAILSLOT\\NET\\NETLOGON";
- char *mailslot_name;
- char buffer[1024];
- char *bufp;
- int dgm_id = generate_trn_id();
- int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
-
- if(sock == -1)
- return False;
-
- /* Find out the transient UDP port we have been allocated. */
- if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
- DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
- strerror(errno)));
- close(sock);
- return False;
+ if (strnequal("\\\\", srv_name, 2))
+ {
+ sv_name = &srv_name[2];
}
- /*
- * Create the request data.
- */
-
- memset(buffer,'\0',sizeof(buffer));
- bufp = buffer;
- SSVAL(bufp,0,QUERYFORPDC);
- bufp += 2;
- fstrcpy(bufp,srcname);
- bufp += (strlen(bufp) + 1);
- slprintf(bufp, sizeof(fstring), "\\MAILSLOT\\NET\\GETDC%d", dgm_id);
- mailslot_name = bufp;
- bufp += (strlen(bufp) + 1);
- bufp = align2(bufp, buffer);
- dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1);
- bufp = skip_unicode_string(bufp, 1);
- SIVAL(bufp,0,1);
- SSVAL(bufp,4,0xFFFF);
- SSVAL(bufp,6,0xFFFF);
- bufp += 8;
- len = PTR_DIFF(bufp,buffer);
-
- memset((char *)&p,'\0',sizeof(p));
-
- /* DIRECT GROUP or UNIQUE datagram. */
- dgram->header.msg_type = 0x10;
- dgram->header.flags.node_type = M_NODE;
- dgram->header.flags.first = True;
- dgram->header.flags.more = False;
- dgram->header.dgm_id = dgm_id;
- dgram->header.source_ip = *iface_ip(*pdc_ip);
- dgram->header.source_port = ntohs(sock_name.sin_port);
- dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
- dgram->header.packet_offset = 0;
-
- make_nmb_name(&dgram->source_name,srcname,0);
- make_nmb_name(&dgram->dest_name,domain,0x1B);
+ fstrcpy(dest_host, sv_name);
+ ret = resolve_name(dest_host, ip, 0x20);
- ptr = &dgram->data[0];
-
- /* Setup the smb part. */
- ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
- memcpy(tmp,ptr,4);
- set_message(ptr,17,17 + len,True);
- memcpy(ptr,tmp,4);
-
- CVAL(ptr,smb_com) = SMBtrans;
- SSVAL(ptr,smb_vwv1,len);
- SSVAL(ptr,smb_vwv11,len);
- SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
- SSVAL(ptr,smb_vwv13,3);
- SSVAL(ptr,smb_vwv14,1);
- SSVAL(ptr,smb_vwv15,1);
- SSVAL(ptr,smb_vwv16,2);
- p2 = smb_buf(ptr);
- pstrcpy(p2,mailslot);
- p2 = skip_string(p2,1);
-
- memcpy(p2,buffer,len);
- p2 += len;
-
- dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
-
- p.ip = *pdc_ip;
- p.port = DGRAM_PORT;
- p.fd = sock;
- p.timestamp = time(NULL);
- p.packet_type = DGRAM_PACKET;
-
- GetTimeOfDay(&tval);
-
- if (!send_packet(&p)) {
- DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
- close(sock);
- return False;
+ if (is_ip_address(dest_host))
+ {
+ fstrcpy(dest_host, "*SMBSERVER");
}
- retries--;
-
- while (1) {
- struct timeval tval2;
- struct packet_struct *p_ret;
-
- GetTimeOfDay(&tval2);
- if (TvalDiff(&tval,&tval2) > retry_time) {
- if (!retries)
- break;
- if (!send_packet(&p)) {
- DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
- close(sock);
- return False;
- }
- GetTimeOfDay(&tval);
- retries--;
- }
-
- if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) {
- struct dgram_packet *dgram2 = &p_ret->packet.dgram;
- char *buf;
- char *buf2;
-
- buf = &dgram2->data[0];
- buf -= 4;
-
- if (CVAL(buf,smb_com) != SMBtrans) {
- DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)
- CVAL(buf,smb_com), (unsigned int)SMBtrans ));
- free_packet(p_ret);
- continue;
- }
-
- len = SVAL(buf,smb_vwv11);
- buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
-
- if (len <= 0) {
- DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
- free_packet(p_ret);
- continue;
- }
-
- DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
- nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
- inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len));
-
- if(SVAL(buf2,0) != QUERYFORPDC_R) {
- DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
- (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
- free_packet(p_ret);
- continue;
- }
-
- buf2 += 2;
- /* Note this is safe as it is a bounded strcpy. */
- fstrcpy(ret_name, buf2);
- ret_name[sizeof(fstring)-1] = '\0';
- close(sock);
- free_packet(p_ret);
- return True;
- }
- }
-
- close(sock);
- return False;
+ return ret;
}
-
/********************************************************
- Get the IP address list of the PDC/BDC's of a Domain.
+find the IP address of the master browser or DMB for a workgroup
*********************************************************/
-BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count)
+BOOL find_master_ip(char *group, struct in_addr *master_ip)
{
- return internal_resolve_name(group, 0x1C, ip_list, count);
+ if (resolve_name(group, master_ip, 0x1D)) return True;
+
+ return resolve_name(group, master_ip, 0x1B);
}
diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c
index 7b62ca45461..7dd1b484191 100644
--- a/source/libsmb/nmblib.c
+++ b/source/libsmb/nmblib.c
@@ -179,34 +179,27 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na
unsigned char *ubuf = (unsigned char *)inbuf;
int ret = 0;
BOOL got_pointer=False;
- int loop_count=0;
- if (length - offset < 2)
- return(0);
+ if (length - offset < 2) return(0);
/* handle initial name pointers */
- if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
- return(0);
+ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
m = ubuf[offset];
- if (!m)
- return(0);
- if ((m & 0xC0) || offset+m+2 > length)
- return(0);
+ if (!m) return(0);
+ if ((m & 0xC0) || offset+m+2 > length) return(0);
- memset((char *)name,'\0',sizeof(*name));
+ bzero((char *)name,sizeof(*name));
/* the "compressed" part */
- if (!got_pointer)
- ret += m + 2;
+ if (!got_pointer) ret += m + 2;
offset++;
- while (m > 0) {
+ while (m) {
unsigned char c1,c2;
c1 = ubuf[offset++]-'A';
c2 = ubuf[offset++]-'A';
- if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
- return(0);
+ if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0);
name->name[n++] = (c1<<4) | c2;
m -= 2;
}
@@ -220,38 +213,21 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na
/* remove trailing spaces */
name->name[15] = 0;
n = 14;
- while (n && name->name[n]==' ')
- name->name[n--] = 0;
+ while (n && name->name[n]==' ') name->name[n--] = 0;
}
/* now the domain parts (if any) */
n = 0;
while (ubuf[offset]) {
/* we can have pointers within the domain part as well */
- if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
- return(0);
+ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
m = ubuf[offset];
- /*
- * Don't allow null domain parts.
- */
- if (!m)
- return(0);
- if (!got_pointer)
- ret += m+1;
- if (n)
- name->scope[n++] = '.';
- if (m+2+offset>length || n+m+1>sizeof(name->scope))
- return(0);
+ if (!got_pointer) ret += m+1;
+ if (n) name->scope[n++] = '.';
+ if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
offset++;
- while (m--)
- name->scope[n++] = (char)ubuf[offset++];
-
- /*
- * Watch for malicious loops.
- */
- if (loop_count++ == 10)
- return 0;
+ while (m--) name->scope[n++] = (char)ubuf[offset++];
}
name->scope[n++] = 0;
@@ -275,7 +251,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
if (strcmp(name->name,"*") == 0) {
/* special case for wildcard name */
- memset(buf1,'\0',20);
+ bzero(buf1,20);
buf1[0] = '*';
buf1[15] = name->name_type;
} else {
@@ -301,8 +277,8 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
p = &buf[offset+1];
while ((p = strchr(p,'.'))) {
- buf[offset] = PTR_DIFF(p,&buf[offset+1]);
- offset += (buf[offset] + 1);
+ buf[offset] = PTR_DIFF(p,&buf[offset]);
+ offset += buf[offset];
p = &buf[offset+1];
}
buf[offset] = strlen(&buf[offset+1]);
@@ -311,6 +287,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
return(ret);
}
+
/*******************************************************************
useful for debugging messages
******************************************************************/
@@ -320,16 +297,24 @@ char *nmb_namestr(struct nmb_name *n)
static fstring ret[4];
char *p = ret[i];
- if (!n->scope[0])
- slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
- else
- slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
+ nmb_safe_namestr(n, p, sizeof(fstring));
i = (i+1)%4;
return(p);
}
/*******************************************************************
+ useful for debugging messages
+ ******************************************************************/
+void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len)
+{
+ if (!n->scope[0])
+ slprintf(str, len-1, "%s<%02x>",n->name,n->name_type);
+ else
+ slprintf(str, len-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
+}
+
+/*******************************************************************
allocate and parse some resource records
******************************************************************/
static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
@@ -339,14 +324,13 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
*recs = (struct res_rec *)malloc(sizeof(**recs)*count);
if (!*recs) return(False);
- memset((char *)*recs,'\0',sizeof(**recs)*count);
+ bzero(*recs,sizeof(**recs)*count);
for (i=0;i<count;i++) {
int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
(*offset) += l;
if (!l || (*offset)+10 > length) {
free(*recs);
- *recs = NULL;
return(False);
}
(*recs)[i].rr_type = RSVAL(inbuf,(*offset));
@@ -357,7 +341,6 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
(*offset)+(*recs)[i].rdlength > length) {
free(*recs);
- *recs = NULL;
return(False);
}
memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
@@ -422,7 +405,7 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
int offset;
int flags;
- memset((char *)dgram,'\0',sizeof(*dgram));
+ bzero((char *)dgram,sizeof(*dgram));
if (length < 14) return(False);
@@ -464,7 +447,7 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
{
int nm_flags,offset;
- memset((char *)nmb,'\0',sizeof(*nmb));
+ bzero((char *)nmb,sizeof(*nmb));
if (length < 12) return(False);
@@ -580,18 +563,12 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
free_and_exit:
- if(copy_nmb->answers) {
+ if(copy_nmb->answers)
free((char *)copy_nmb->answers);
- copy_nmb->answers = NULL;
- }
- if(copy_nmb->nsrecs) {
+ if(copy_nmb->nsrecs)
free((char *)copy_nmb->nsrecs);
- copy_nmb->nsrecs = NULL;
- }
- if(copy_nmb->additional) {
+ if(copy_nmb->additional)
free((char *)copy_nmb->additional);
- copy_nmb->additional = NULL;
- }
free((char *)pkt_copy);
DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
@@ -628,9 +605,11 @@ static struct packet_struct *copy_dgram_packet(struct packet_struct *packet)
******************************************************************/
struct packet_struct *copy_packet(struct packet_struct *packet)
{
- if(packet->packet_type == NMB_PACKET)
+ if((packet->packet_type == NMB_PACKET)
+ || (packet->packet_type == NMB_SOCK_PACKET))
return copy_nmb_packet(packet);
- else if (packet->packet_type == DGRAM_PACKET)
+ else if ((packet->packet_type == DGRAM_PACKET)
+ || (packet->packet_type == DGRAM_SOCK_PACKET))
return copy_dgram_packet(packet);
return NULL;
}
@@ -640,18 +619,9 @@ struct packet_struct *copy_packet(struct packet_struct *packet)
******************************************************************/
static void free_nmb_packet(struct nmb_packet *nmb)
{
- if (nmb->answers) {
- free(nmb->answers);
- nmb->answers = NULL;
- }
- if (nmb->nsrecs) {
- free(nmb->nsrecs);
- nmb->nsrecs = NULL;
- }
- if (nmb->additional) {
- free(nmb->additional);
- nmb->additional = NULL;
- }
+ if (nmb->answers) free(nmb->answers);
+ if (nmb->nsrecs) free(nmb->nsrecs);
+ if (nmb->additional) free(nmb->additional);
}
/*******************************************************************
@@ -669,78 +639,99 @@ void free_packet(struct packet_struct *packet)
{
if (packet->locked)
return;
- if (packet->packet_type == NMB_PACKET)
+ if ((packet->packet_type == NMB_PACKET)
+ || (packet->packet_type == NMB_SOCK_PACKET))
free_nmb_packet(&packet->packet.nmb);
- else if (packet->packet_type == DGRAM_PACKET)
+ else if ((packet->packet_type == DGRAM_PACKET)
+ || (packet->packet_type == DGRAM_SOCK_PACKET))
free_dgram_packet(&packet->packet.dgram);
- ZERO_STRUCTPN(packet);
free(packet);
}
/*******************************************************************
-parse a packet buffer into a packet structure
- ******************************************************************/
-struct packet_struct *parse_packet(char *buf,int length,
- enum packet_type packet_type)
-{
- extern struct in_addr lastip;
- extern int lastport;
- struct packet_struct *p;
- BOOL ok=False;
-
- p = (struct packet_struct *)malloc(sizeof(*p));
- if (!p) return(NULL);
-
- p->next = NULL;
- p->prev = NULL;
- p->ip = lastip;
- p->port = lastport;
- p->locked = False;
- p->timestamp = time(NULL);
- p->packet_type = packet_type;
-
- switch (packet_type) {
- case NMB_PACKET:
- ok = parse_nmb(buf,length,&p->packet.nmb);
- break;
-
- case DGRAM_PACKET:
- ok = parse_dgram(buf,length,&p->packet.dgram);
- break;
- }
-
- if (!ok) {
- free_packet(p);
- return NULL;
- }
-
- return p;
-}
-
-/*******************************************************************
read a packet from a socket and parse it, returning a packet ready
to be used or put on the queue. This assumes a UDP socket
******************************************************************/
struct packet_struct *read_packet(int fd,enum packet_type packet_type)
{
- struct packet_struct *packet;
- char buf[MAX_DGRAM_SIZE];
- int length;
+ extern struct in_addr lastip;
+ struct nmb_state con;
+ extern int lastport;
+ struct packet_struct *packet;
+ char buf[MAX_DGRAM_SIZE];
+ int length;
+ BOOL ok=False;
+
+ if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
+ {
+ uint16 trn_id = 0;
+ if (!read_nmb_sock(fd, &con))
+ {
+ return False;
+ }
+ if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
+ {
+ return False;
+ }
+ }
length = read_udp_socket(fd,buf,sizeof(buf));
- if (length < MIN_DGRAM_SIZE) return(NULL);
- packet = parse_packet(buf, length, packet_type);
- if (!packet) return NULL;
+ dump_data(100, buf, length);
- packet->fd = fd;
-
- num_good_receives++;
-
- DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
- length, inet_ntoa(packet->ip), packet->port ) );
+ if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
+ {
+ uint16 trn_id = 0;
+ if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
+ {
+ return False;
+ }
+ }
- return(packet);
+ if (length < MIN_DGRAM_SIZE) return(NULL);
+
+ if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
+ {
+ lastip = con.ip;
+ lastport = con.port;
+ }
+
+ packet = (struct packet_struct *)malloc(sizeof(*packet));
+ if (!packet) return(NULL);
+
+ packet->next = NULL;
+ packet->prev = NULL;
+ packet->ip = lastip;
+ packet->port = lastport;
+ packet->fd = fd;
+ packet->locked = False;
+ packet->timestamp = time(NULL);
+ packet->packet_type = packet_type;
+ switch (packet_type)
+ {
+ case NMB_PACKET:
+ case NMB_SOCK_PACKET:
+ ok = parse_nmb(buf,length,&packet->packet.nmb);
+ break;
+
+ case DGRAM_PACKET:
+ case DGRAM_SOCK_PACKET:
+ ok = parse_dgram(buf,length,&packet->packet.dgram);
+ break;
+ }
+ if (!ok) {
+ DEBUG(10,("read_packet: discarding packet id = %d\n",
+ packet->packet.nmb.header.name_trn_id));
+ free(packet);
+ return(NULL);
+ }
+
+ num_good_receives++;
+
+ DEBUG(5,("Received a packet of len %d from (%s) port %d\n",
+ length, inet_ntoa(packet->ip), packet->port ) );
+
+ return(packet);
}
@@ -753,7 +744,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
struct sockaddr_in sock_out;
/* set the address and port */
- memset((char *)&sock_out,'\0',sizeof(sock_out));
+ bzero((char *)&sock_out,sizeof(sock_out));
putip((char *)&sock_out.sin_addr,(char *)&ip);
sock_out.sin_port = htons( port );
sock_out.sin_family = AF_INET;
@@ -789,7 +780,7 @@ static int build_dgram(char *buf,struct packet_struct *p)
/* put in the header */
ubuf[0] = dgram->header.msg_type;
- ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
+ ubuf[1] = (((unsigned int)dgram->header.flags.node_type)<<2);
if (dgram->header.flags.more) ubuf[1] |= 1;
if (dgram->header.flags.first) ubuf[1] |= 2;
RSSVAL(ubuf,2,dgram->header.dgm_id);
@@ -819,14 +810,13 @@ static int build_dgram(char *buf,struct packet_struct *p)
/*******************************************************************
build a nmb name
*******************************************************************/
-void make_nmb_name( struct nmb_name *n, const char *name, int type)
+void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope )
{
- extern pstring global_scope;
memset( (char *)n, '\0', sizeof(struct nmb_name) );
StrnCpy( n->name, name, 15 );
strupper( n->name );
n->name_type = (unsigned int)type & 0xFF;
- StrnCpy( n->scope, global_scope, 63 );
+ StrnCpy( n->scope, this_scope, 63 );
strupper( n->scope );
}
@@ -916,26 +906,6 @@ static int build_nmb(char *buf,struct packet_struct *p)
/*******************************************************************
-linearise a packet
- ******************************************************************/
-int build_packet(char *buf, struct packet_struct *p)
-{
- int len = 0;
-
- switch (p->packet_type) {
- case NMB_PACKET:
- len = build_nmb(buf,p);
- break;
-
- case DGRAM_PACKET:
- len = build_dgram(buf,p);
- break;
- }
-
- return len;
-}
-
-/*******************************************************************
send a packet_struct
******************************************************************/
BOOL send_packet(struct packet_struct *p)
@@ -943,98 +913,105 @@ BOOL send_packet(struct packet_struct *p)
char buf[1024];
int len=0;
- memset(buf,'\0',sizeof(buf));
-
- len = build_packet(buf, p);
-
- if (!len) return(False);
-
- return(send_udp(p->fd,buf,len,p->ip,p->port));
-}
-
-/****************************************************************************
- receive a packet with timeout on a open UDP filedescriptor
- The timeout is in milliseconds
- ***************************************************************************/
-struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
-{
- fd_set fds;
- struct timeval timeout;
-
- FD_ZERO(&fds);
- FD_SET(fd,&fds);
- timeout.tv_sec = t/1000;
- timeout.tv_usec = 1000*(t%1000);
-
- sys_select(fd+1,&fds,&timeout);
+ DEBUG(100,("send_packet: %d %d\n", p->fd, p->packet_type));
- if (FD_ISSET(fd,&fds))
- return(read_packet(fd,type));
-
- return(NULL);
-}
+ bzero(buf,sizeof(buf));
+ switch (p->packet_type)
+ {
+ case NMB_PACKET:
+ case NMB_SOCK_PACKET:
+ len = build_nmb(buf,p);
+ debug_nmb_packet(p);
+ break;
+
+ case DGRAM_PACKET:
+ case DGRAM_SOCK_PACKET:
+ len = build_dgram(buf,p);
+ break;
+ }
-/****************************************************************************
- receive a UDP/137 packet either via UDP or from the unexpected packet
- queue. The packet must be a reply packet and have the specified trn_id
- The timeout is in milliseconds
- ***************************************************************************/
-struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id)
-{
- struct packet_struct *p;
+ if (!len) return(False);
- p = receive_packet(fd, NMB_PACKET, t);
+ switch (p->packet_type)
+ {
+ case DGRAM_PACKET:
+ case NMB_PACKET:
+ return(send_udp(p->fd,buf,len,p->ip,p->port));
+ break;
- if (p && p->packet.nmb.header.response &&
- p->packet.nmb.header.name_trn_id == trn_id) {
- return p;
+ case NMB_SOCK_PACKET:
+ case DGRAM_SOCK_PACKET:
+ {
+ fstring qbuf;
+ struct nmb_state nmb;
+ int qlen;
+ uint16 trn_id;
+ char *q = qbuf + 4;
+
+ nmb.ip = p->ip;
+ nmb.port = p->port;
+
+ SSVAL(q, 0, 0);
+ q += 2;
+ SSVAL(q, 0, 0);
+ q += 2;
+ memcpy(q, &nmb, sizeof(nmb));
+ q += sizeof(nmb);
+
+ qlen = PTR_DIFF(q, qbuf);
+ SIVAL(qbuf, 0, qlen);
+
+ dump_data(100, qbuf, qlen);
+
+ if (write(p->fd,qbuf,qlen) != qlen)
+ {
+ DEBUG(0,("send_packet: write hdr failed\n"));
+ return False;
+ }
+ if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
+ {
+ DEBUG(0,("send_packet: 1st ack failed\n"));
+ return False;
+ }
+ if (write(p->fd,buf,len) != len)
+ {
+ DEBUG(0,("send_packet: write packet failed\n"));
+ return False;
+ }
+ if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
+ {
+ DEBUG(0,("send_packet: 2nd ack failed\n"));
+ return False;
+ }
+ return True;
}
- if (p) free_packet(p);
+ }
- /* try the unexpected packet queue */
- return receive_unexpected(NMB_PACKET, trn_id, NULL);
+ return False;
}
/****************************************************************************
- receive a UDP/138 packet either via UDP or from the unexpected packet
- queue. The packet must be a reply packet and have the specified mailslot name
+ receive a packet with timeout on a open UDP filedescriptor
The timeout is in milliseconds
***************************************************************************/
-struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name)
-{
- struct packet_struct *p;
-
- p = receive_packet(fd, DGRAM_PACKET, t);
-
- if (p && match_mailslot_name(p, mailslot_name)) {
- return p;
- }
- if (p) free_packet(p);
-
- /* try the unexpected packet queue */
- return receive_unexpected(DGRAM_PACKET, 0, mailslot_name);
-}
-
-
-/****************************************************************************
- see if a datagram has the right mailslot name
-***************************************************************************/
-BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name)
+struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
{
- struct dgram_packet *dgram = &p->packet.dgram;
- char *buf;
+ fd_set fds;
+ struct timeval timeout;
- buf = &dgram->data[0];
- buf -= 4;
+ FD_ZERO(&fds);
+ FD_SET(fd,&fds);
+ timeout.tv_sec = t/1000;
+ timeout.tv_usec = 1000*(t%1000);
- buf = smb_buf(buf);
+ DEBUG(100,("receive_packet: %d %d\n", fd, type));
+ sys_select(fd+1,&fds,NULL, &timeout);
- if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) {
- return True;
- }
+ if (FD_ISSET(fd,&fds))
+ return(read_packet(fd,type));
- return False;
+ return(NULL);
}
@@ -1082,3 +1059,270 @@ void sort_query_replies(char *data, int n, struct in_addr ip)
qsort(data, n, 6, QSORT_CAST name_query_comp);
}
+
+BOOL read_nmb_sock(int c, struct nmb_state *con)
+{
+ fstring buf;
+ char *p = buf;
+ int rl;
+ uint32 len;
+ uint16 version;
+ uint16 command;
+
+ ZERO_STRUCTP(con);
+
+ rl = read(c, &buf, sizeof(len));
+
+ if (rl < 0)
+ {
+ DEBUG(0,("read_nmb_sock: error\n"));
+ return False;
+ }
+ if (rl != sizeof(len))
+ {
+ DEBUG(0,("Unable to read length\n"));
+ dump_data(0, buf, sizeof(len));
+ return False;
+ }
+
+ len = IVAL(buf, 0);
+
+ if (len > sizeof(buf))
+ {
+ DEBUG(0,("length %d too long\n", len));
+ return False;
+ }
+
+ rl = read(c, buf, len);
+
+ if (rl < 0)
+ {
+ DEBUG(0,("Unable to read from connection\n"));
+ return False;
+ }
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, buf, rl);
+#endif
+ version = SVAL(p, 0);
+ p += 2;
+ command = SVAL(p, 0);
+ p += 2;
+
+ memcpy(con, p, sizeof(*con));
+ p += sizeof(*con);
+
+ DEBUG(10,("read_nmb_sock: ip %s port: %d\n",
+ inet_ntoa(con->ip), con->port));
+
+ if (PTR_DIFF(p, buf) != rl)
+ {
+ DEBUG(0,("Buffer size %d %d!\n",
+ PTR_DIFF(p, buf), rl));
+ return False;
+ }
+
+ return True;
+}
+
+int get_nmb_sock(void)
+{
+ fstring path;
+ slprintf(path, sizeof(path)-1, "/tmp/.nmb/agent");
+
+ return open_pipe_sock(path);
+}
+
+#define TRUNCATE_NETBIOS_NAME 1
+
+/*******************************************************************
+ convert, possibly using a stupid microsoft-ism which has destroyed
+ the transport independence of netbios (for CIFS vendors that usually
+ use the Win95-type methods, not for NT to NT communication, which uses
+ DCE/RPC and therefore full-length unicode strings...) a dns name into
+ a netbios name.
+
+ the netbios name (NOT necessarily null-terminated) is truncated to 15
+ characters.
+
+ ******************************************************************/
+char *dns_to_netbios_name(char *dns_name)
+{
+ static char netbios_name[16];
+ int i;
+ StrnCpy(netbios_name, dns_name, 15);
+ netbios_name[15] = 0;
+
+#ifdef TRUNCATE_NETBIOS_NAME
+ /* ok. this is because of a stupid microsoft-ism. if the called host
+ name contains a '.', microsoft clients expect you to truncate the
+ netbios name up to and including the '.' this even applies, by
+ mistake, to workgroup (domain) names, which is _really_ daft.
+ */
+ for (i = 15; i >= 0; i--)
+ {
+ if (netbios_name[i] == '.')
+ {
+ netbios_name[i] = 0;
+ break;
+ }
+ }
+#endif /* TRUNCATE_NETBIOS_NAME */
+
+ return netbios_name;
+}
+
+
+/****************************************************************************
+interpret the weird netbios "name". Return the name type
+****************************************************************************/
+static int name_interpret(char *in,char *out)
+{
+ int ret;
+ int len = (*in++) / 2;
+
+ *out=0;
+
+ if (len > 30 || len<1) return(0);
+
+ while (len--)
+ {
+ if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
+ *out = 0;
+ return(0);
+ }
+ *out = ((in[0]-'A')<<4) + (in[1]-'A');
+ in += 2;
+ out++;
+ }
+ *out = 0;
+ ret = out[-1];
+
+#ifdef NETBIOS_SCOPE
+ /* Handle any scope names */
+ while(*in)
+ {
+ *out++ = '.'; /* Scope names are separated by periods */
+ len = *(uchar *)in++;
+ StrnCpy(out, in, len);
+ out += len;
+ *out=0;
+ in += len;
+ }
+#endif
+ return(ret);
+}
+
+/****************************************************************************
+mangle a name into netbios format
+
+ Note: <Out> must be (33 + strlen(scope) + 2) bytes long, at minimum.
+****************************************************************************/
+int name_mangle( char *In, char *Out, char name_type )
+ {
+ extern pstring scope;
+ int i;
+ int c;
+ int len;
+ char buf[20];
+ char *p = Out;
+
+ /* Safely copy the input string, In, into buf[]. */
+ (void)memset( buf, 0, 20 );
+ if (strcmp(In,"*") == 0)
+ buf[0] = '*';
+ else
+ (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type );
+
+ /* Place the length of the first field into the output buffer. */
+ p[0] = 32;
+ p++;
+
+ /* Now convert the name to the rfc1001/1002 format. */
+ for( i = 0; i < 16; i++ )
+ {
+ c = toupper( buf[i] );
+ p[i*2] = ( (c >> 4) & 0x000F ) + 'A';
+ p[(i*2)+1] = (c & 0x000F) + 'A';
+ }
+ p += 32;
+ p[0] = '\0';
+
+ /* Add the scope string. */
+ for( i = 0, len = 0; NULL != scope; i++, len++ )
+ {
+ switch( scope[i] )
+ {
+ case '\0':
+ p[0] = len;
+ if( len > 0 )
+ p[len+1] = 0;
+ return( name_len(Out) );
+ case '.':
+ p[0] = len;
+ p += (len + 1);
+ len = 0;
+ break;
+ default:
+ p[len+1] = scope[i];
+ break;
+ }
+ }
+
+ return( name_len(Out) );
+ } /* name_mangle */
+
+/****************************************************************************
+find a pointer to a netbios name
+****************************************************************************/
+static char *name_ptr(char *buf,int ofs)
+{
+ uchar c = *(uchar *)(buf+ofs);
+
+ if ((c & 0xC0) == 0xC0)
+ {
+ uint16 l;
+ char p[2];
+ memcpy(p,buf+ofs,2);
+ p[0] &= ~0xC0;
+ l = RSVAL(p,0);
+ DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
+ return(buf + l);
+ }
+ else
+ return(buf+ofs);
+}
+
+/****************************************************************************
+extract a netbios name from a buf
+****************************************************************************/
+int name_extract(char *buf,int ofs,char *name)
+{
+ char *p = name_ptr(buf,ofs);
+ int d = PTR_DIFF(p,buf+ofs);
+ pstrcpy(name,"");
+ if (d < -50 || d > 50) return(0);
+ return(name_interpret(p,name));
+}
+
+/****************************************************************************
+return the total storage length of a mangled name
+****************************************************************************/
+int name_len(char *s1)
+{
+ /* NOTE: this argument _must_ be unsigned */
+ uchar *s = (uchar *)s1;
+ int len;
+
+ /* If the two high bits of the byte are set, return 2. */
+ if (0xC0 == (*s & 0xC0))
+ return(2);
+
+ /* Add up the length bytes. */
+ for (len = 1; (*s); s += (*s) + 1) {
+ len += *s + 1;
+ SMB_ASSERT(len < 80);
+ }
+
+ return(len);
+} /* name_len */
diff --git a/source/libsmb/nterr.c b/source/libsmb/nterr.c
index d2f9335000d..11af406b5fb 100644
--- a/source/libsmb/nterr.c
+++ b/source/libsmb/nterr.c
@@ -10,7 +10,7 @@ typedef struct
} nt_err_code_struct;
-nt_err_code_struct nt_errs[] =
+static nt_err_code_struct nt_errs[] =
{
{ "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL },
{ "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED },
@@ -514,18 +514,18 @@ nt_err_code_struct nt_errs[] =
{ "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS },
{ "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT },
{ "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE },
+ { "NT_STATUS_NO_SUCH_JOB", NT_STATUS_NO_SUCH_JOB },
{ NULL, 0 }
};
/*****************************************************************************
returns an NT error message. not amazingly helpful, but better than a number.
*****************************************************************************/
-char *get_nt_error_msg(uint32 nt_code)
+BOOL get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len)
{
- static pstring msg;
int idx = 0;
- pstrcpy(msg, "Unknown NT error");
+ snprintf(msg, len, "NT code %08x", nt_code);
nt_code &= 0xFFFF;
@@ -533,11 +533,23 @@ char *get_nt_error_msg(uint32 nt_code)
{
if (nt_errs[idx].nt_errcode == nt_code)
{
- pstrcpy(msg, nt_errs[idx].nt_errstr);
- return msg;
+ safe_strcpy(msg, nt_errs[idx].nt_errstr, len);
+ return True;
}
idx++;
}
- return msg;
+ return False;
}
+/*****************************************************************************
+ returns an NT error message. not amazingly helpful, but better than a number.
+ *****************************************************************************/
+const char *get_nt_error_msg(uint32 nt_code)
+{
+ static pstring msg;
+ if (get_safe_nt_error_msg(nt_code, msg, sizeof(msg)))
+ {
+ return msg;
+ }
+ return "";
+}
diff --git a/source/libsmb/passchange.c b/source/libsmb/passchange.c
index 335d9a7d1ab..b5552d4cea1 100644
--- a/source/libsmb/passchange.c
+++ b/source/libsmb/passchange.c
@@ -23,6 +23,7 @@
extern pstring global_myname;
+extern pstring scope;
/*************************************************************
change a password on a remote machine using IPC calls
@@ -35,8 +36,6 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
struct cli_state cli;
struct in_addr ip;
- *err_str = '\0';
-
if(!resolve_name( remote_machine, &ip, 0x20)) {
slprintf(err_str, err_str_len-1, "unable to find an IP address for machine %s.\n",
remote_machine );
@@ -51,8 +50,8 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
return False;
}
- make_nmb_name(&calling, global_myname , 0x0);
- make_nmb_name(&called , remote_machine, 0x20);
+ make_nmb_name(&calling, global_myname , 0x0 , scope);
+ make_nmb_name(&called , remote_machine, 0x20, scope);
if (!cli_session_request(&cli, &calling, &called)) {
slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n",
@@ -76,7 +75,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
* Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix.
*/
- if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
+ if (!cli_session_setup(&cli, global_myname, "", "", 0, "", 0, "")) {
slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n",
remote_machine, cli_errstr(&cli) );
cli_shutdown(&cli);
diff --git a/source/libsmb/pwd_cache.c b/source/libsmb/pwd_cache.c
index 4f02c42efbd..2c3352ea6c6 100644
--- a/source/libsmb/pwd_cache.c
+++ b/source/libsmb/pwd_cache.c
@@ -29,11 +29,12 @@ initialises a password structure
****************************************************************************/
void pwd_init(struct pwd_info *pwd)
{
- memset((char *)pwd->password , '\0', sizeof(pwd->password ));
- memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd));
- memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd));
- memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf));
- memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf));
+ ZERO_STRUCT(pwd->password );
+ ZERO_STRUCT(pwd->smb_lm_pwd);
+ ZERO_STRUCT(pwd->smb_nt_pwd);
+ ZERO_STRUCT(pwd->smb_lm_owf);
+ ZERO_STRUCT(pwd->smb_nt_owf);
+ pwd->nt_owf_len = 0;
pwd->null_pwd = True; /* safest option... */
pwd->cleartext = False;
@@ -41,16 +42,24 @@ void pwd_init(struct pwd_info *pwd)
}
/****************************************************************************
+returns NULL password flag
+****************************************************************************/
+BOOL pwd_is_nullpwd(const struct pwd_info *pwd)
+{
+ return pwd->null_pwd;
+}
+
+/****************************************************************************
de-obfuscates a password
****************************************************************************/
-static void pwd_deobfuscate(struct pwd_info *pwd)
+static void pwd_deobfuscate(const struct pwd_info *pwd)
{
}
/****************************************************************************
obfuscates a password
****************************************************************************/
-static void pwd_obfuscate(struct pwd_info *pwd)
+static void pwd_obfuscate(const struct pwd_info *pwd)
{
}
@@ -64,54 +73,67 @@ void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key)
/****************************************************************************
compares two passwords. hmm, not as trivial as expected. hmm.
****************************************************************************/
-BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2)
+BOOL pwd_compare(const struct pwd_info *_pwd1, const struct pwd_info *_pwd2)
{
- pwd_deobfuscate(pwd1);
- pwd_deobfuscate(pwd2);
- if (pwd1->cleartext && pwd2->cleartext)
+ struct pwd_info pwd1;
+ struct pwd_info pwd2;
+
+ memcpy(&pwd1, _pwd1, sizeof(pwd1));
+ memcpy(&pwd2, _pwd2, sizeof(pwd2));
+
+ pwd_deobfuscate(&pwd1);
+ pwd_deobfuscate(&pwd2);
+
+ if (pwd1.cleartext && pwd2.cleartext)
{
- if (strequal(pwd1->password, pwd2->password))
+ if (strequal(pwd1.password, pwd2.password))
{
- pwd_obfuscate(pwd1);
- pwd_obfuscate(pwd2);
+ ZERO_STRUCT(pwd1);
+ ZERO_STRUCT(pwd2);
+
return True;
}
}
- if (pwd1->null_pwd && pwd2->null_pwd)
+ if (pwd1.null_pwd && pwd2.null_pwd)
{
- pwd_obfuscate(pwd1);
- pwd_obfuscate(pwd2);
+ ZERO_STRUCT(pwd1);
+ ZERO_STRUCT(pwd2);
+
return True;
}
- if (!pwd1->null_pwd && !pwd2->null_pwd &&
- !pwd1->cleartext && !pwd2->cleartext)
+ if (!pwd1.null_pwd && !pwd2.null_pwd &&
+ !pwd1.cleartext && !pwd2.cleartext)
{
#ifdef DEBUG_PASSWORD
DEBUG(100,("pwd compare: nt#\n"));
- dump_data(100, pwd1->smb_nt_pwd, 16);
- dump_data(100, pwd2->smb_nt_pwd, 16);
+ dump_data(100, pwd1.smb_nt_pwd, 16);
+ dump_data(100, pwd2.smb_nt_pwd, 16);
#endif
- if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0)
+ if (memcmp(pwd1.smb_nt_pwd, pwd2.smb_nt_pwd, 16) == 0)
{
- pwd_obfuscate(pwd1);
- pwd_obfuscate(pwd2);
+ ZERO_STRUCT(pwd1);
+ ZERO_STRUCT(pwd2);
+
return True;
}
#ifdef DEBUG_PASSWORD
DEBUG(100,("pwd compare: lm#\n"));
- dump_data(100, pwd1->smb_lm_pwd, 16);
- dump_data(100, pwd2->smb_lm_pwd, 16);
+ dump_data(100, pwd1.smb_lm_pwd, 16);
+ dump_data(100, pwd2.smb_lm_pwd, 16);
#endif
- if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
+ if (memcmp(pwd1.smb_lm_pwd, pwd2.smb_lm_pwd, 16) == 0)
{
- pwd_obfuscate(pwd1);
- pwd_obfuscate(pwd2);
+ ZERO_STRUCT(pwd1);
+ ZERO_STRUCT(pwd2);
+
return True;
}
}
- pwd_obfuscate(pwd1);
- pwd_obfuscate(pwd2);
+
+ ZERO_STRUCT(pwd1);
+ ZERO_STRUCT(pwd2);
+
return False;
}
@@ -160,7 +182,6 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr)
{
pwd_init(pwd);
fstrcpy(pwd->password, clr);
- unix_to_dos(pwd->password,True);
pwd->cleartext = True;
pwd->null_pwd = False;
pwd->crypted = False;
@@ -177,7 +198,6 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr)
if (pwd->cleartext)
{
fstrcpy(clr, pwd->password);
- dos_to_unix(clr, True);
}
else
{
@@ -189,7 +209,9 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr)
/****************************************************************************
stores lm and nt hashed passwords
****************************************************************************/
-void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
+void pwd_set_lm_nt_16(struct pwd_info *pwd,
+ const uchar lm_pwd[16],
+ const uchar nt_pwd[16])
{
pwd_init(pwd);
@@ -199,7 +221,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
}
else
{
- memset((char *)pwd->smb_lm_pwd, '\0', 16);
+ bzero(pwd->smb_lm_pwd, 16);
}
if (nt_pwd)
@@ -208,7 +230,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
}
else
{
- memset((char *)pwd->smb_nt_pwd, '\0', 16);
+ bzero(pwd->smb_nt_pwd, 16);
}
pwd->null_pwd = False;
@@ -221,7 +243,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
/****************************************************************************
gets lm and nt hashed passwords
****************************************************************************/
-void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
+void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
{
pwd_deobfuscate(pwd);
if (lm_pwd != NULL)
@@ -240,14 +262,9 @@ void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
****************************************************************************/
void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
{
- pstring dos_passwd;
-
pwd_init(pwd);
- pstrcpy(dos_passwd, clr);
- unix_to_dos(dos_passwd, True);
-
- nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
+ nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
pwd->null_pwd = False;
pwd->cleartext = False;
pwd->crypted = False;
@@ -258,31 +275,111 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
/****************************************************************************
makes lm and nt OWF crypts
****************************************************************************/
-void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
+void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
+ const char *user, const char *server, const char *domain,
+ uchar sess_key[16])
{
+ uchar kr[16];
+
+ DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
+ user, server, domain));
+
pwd_deobfuscate(pwd);
+ SMBgenclientchals(pwd->lm_cli_chal,
+ pwd->nt_cli_chal,
+ &pwd->nt_cli_chal_len,
+ server, domain);
+
+ ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr);
+
+ /* lm # */
+ SMBOWFencrypt_ntv2(kr,
+ srv_key, 8,
+ pwd->lm_cli_chal, 8,
+ pwd->smb_lm_owf);
+ memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8);
+
+ /* nt # */
+ SMBOWFencrypt_ntv2(kr,
+ srv_key, 8,
+ pwd->nt_cli_chal, pwd->nt_cli_chal_len,
+ pwd->smb_nt_owf);
+ memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len);
+ pwd->nt_owf_len = pwd->nt_cli_chal_len + 16;
+
+ SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, sess_key);
+
+#if DEBUG_PASSWORD
+#endif
+
#ifdef DEBUG_PASSWORD
- DEBUG(100,("client cryptkey: "));
- dump_data(100, (char *)cryptkey, 8);
+ DEBUG(100,("server cryptkey: "));
+ dump_data(100, srv_key, 8);
+
+ DEBUG(100,("client lmv2 cryptkey: "));
+ dump_data(100, pwd->lm_cli_chal, 8);
+
+ DEBUG(100,("client ntv2 cryptkey: "));
+ dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len);
+
+ DEBUG(100,("ntv2_owf_passwd: "));
+ dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
+ DEBUG(100,("nt_sess_pwd: "));
+ dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
+
+ DEBUG(100,("lmv2_owf_passwd: "));
+ dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
+ DEBUG(100,("lm_sess_pwd: "));
+ dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
+
+ DEBUG(100,("session key:\n"));
+ dump_data(100, sess_key, 16);
#endif
+ pwd->crypted = True;
- SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
+ pwd_obfuscate(pwd);
+}
+/****************************************************************************
+ makes lm and nt OWF crypts
+ ****************************************************************************/
+void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8],
+ uchar sess_key[16])
+{
+ if (pwd->null_pwd)
+ {
#ifdef DEBUG_PASSWORD
- DEBUG(100,("nt_owf_passwd: "));
- dump_data(100, (char *)pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf));
- DEBUG(100,("nt_sess_pwd: "));
- dump_data(100, (char *)pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
+ DEBUG(100,("pwd_make_lm_nt_owf: NULL password\n"));
#endif
+ pwd->nt_owf_len = 0;
+ return;
+ }
+ pwd_deobfuscate(pwd);
+ /* generate 24-byte hashes */
SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf);
+ SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
+ pwd->nt_owf_len = 24;
+
+ SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, sess_key);
#ifdef DEBUG_PASSWORD
+ DEBUG(100,("client cryptkey: "));
+ dump_data(100, cryptkey, 8);
+
+ DEBUG(100,("nt_owf_passwd: "));
+ dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
+ DEBUG(100,("nt_sess_pwd: "));
+ dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
+
DEBUG(100,("lm_owf_passwd: "));
- dump_data(100, (char *)pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
+ dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
DEBUG(100,("lm_sess_pwd: "));
- dump_data(100, (char *)pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
+ dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
+
+ DEBUG(100,("session key:\n"));
+ dump_data(100, sess_key, 16);
#endif
pwd->crypted = True;
@@ -293,8 +390,21 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
/****************************************************************************
gets lm and nt crypts
****************************************************************************/
-void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24])
+void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
+ uchar *nt_owf, size_t *nt_owf_len)
{
+ if (pwd->null_pwd)
+ {
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("pwd_get_lm_nt_owf: NULL password\n"));
+#endif
+ if (nt_owf_len != NULL)
+ {
+ *nt_owf_len = 0;
+ }
+ return;
+ }
+
pwd_deobfuscate(pwd);
if (lm_owf != NULL)
{
@@ -302,7 +412,12 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24])
}
if (nt_owf != NULL)
{
- memcpy(nt_owf, pwd->smb_nt_owf, 24);
+ memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
+ }
+ if (nt_owf_len != NULL)
+ {
+ *nt_owf_len = pwd->nt_owf_len;
}
pwd_obfuscate(pwd);
}
+
diff --git a/source/libsmb/smbdes.c b/source/libsmb/smbdes.c
index d0e1c6e85fb..0d0908605d3 100644
--- a/source/libsmb/smbdes.c
+++ b/source/libsmb/smbdes.c
@@ -5,7 +5,7 @@
a partial implementation of DES designed for use in the
SMB authentication protocol
- Copyright (C) Andrew Tridgell 1998
+ Copyright (C) Andrew Tridgell 1998-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -259,7 +259,7 @@ static void dohash(char *out, char *in, char *key, int forw)
permute(out, rl, perm6, 64);
}
-static void str_to_key(unsigned char *str,unsigned char *key)
+static void str_to_key(const uchar *str, uchar *key)
{
int i;
@@ -277,13 +277,13 @@ static void str_to_key(unsigned char *str,unsigned char *key)
}
-static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
+void smbhash(uchar *out, const uchar *in, const uchar *key, int forw)
{
int i;
char outb[64];
char inb[64];
char keyb[64];
- unsigned char key2[8];
+ uchar key2[8];
str_to_key(key, key2);
@@ -305,95 +305,114 @@ static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, i
}
}
-void E_P16(unsigned char *p14,unsigned char *p16)
+void E_P16(uchar *p14,uchar *p16)
{
- unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
+ uchar sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
smbhash(p16, sp8, p14, 1);
smbhash(p16+8, sp8, p14+7, 1);
}
-void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
+void E_P24(const uchar *p21, const uchar *c8, uchar *p24)
{
smbhash(p24, c8, p21, 1);
smbhash(p24+8, c8, p21+7, 1);
smbhash(p24+16, c8, p21+14, 1);
}
-void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
+void D_P16(const uchar *p14, const uchar *in, uchar *out)
{
smbhash(out, in, p14, 0);
smbhash(out+8, in+8, p14+7, 0);
}
-void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out)
+void E_old_pw_hash( const uchar *p14, const uchar *in, uchar *out)
{
smbhash(out, in, p14, 1);
smbhash(out+8, in+8, p14+7, 1);
}
-void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key)
+void cred_hash1(uchar *out, const uchar *in, const uchar *key)
{
- unsigned char buf[8];
+ uchar buf[8];
smbhash(buf, in, key, 1);
smbhash(out, buf, key+9, 1);
}
-void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key)
+void cred_hash2(uchar *out,uchar *in,uchar *key)
{
- unsigned char buf[8];
- static unsigned char key2[8];
+ uchar buf[8];
+ static uchar key2[8];
smbhash(buf, in, key, 1);
key2[0] = key[7];
smbhash(out, buf, key2, 1);
}
-void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw)
+void cred_hash3(uchar *out, const uchar *in,uchar *key, int forw)
{
- static unsigned char key2[8];
+ static uchar key2[8];
smbhash(out, in, key, forw);
key2[0] = key[7];
smbhash(out + 8, in + 8, key2, forw);
}
-void SamOEMhash( unsigned char *data, unsigned char *key, int val)
+void SamOEMhash( uchar *data, const uchar *key, int val)
{
- unsigned char s_box[256];
- unsigned char index_i = 0;
- unsigned char index_j = 0;
- unsigned char j = 0;
+ uchar hash[256];
+ uchar index_i = 0;
+ uchar index_j = 0;
+ uchar j = 0;
int ind;
+ int len = 0;
+ if (val == 1) len = 516;
+ if (val == 0) len = 16;
+ if (val == 3) len = 8;
+ if (val == 2) len = 68;
+ if (val == 4) len = 32;
for (ind = 0; ind < 256; ind++)
{
- s_box[ind] = (unsigned char)ind;
+ hash[ind] = (uchar)ind;
}
for( ind = 0; ind < 256; ind++)
{
- unsigned char tc;
+ uchar tc;
- j += (s_box[ind] + key[ind%16]);
+ j += (hash[ind] + key[ind%16]);
- tc = s_box[ind];
- s_box[ind] = s_box[j];
- s_box[j] = tc;
+ tc = hash[ind];
+ hash[ind] = hash[j];
+ hash[j] = tc;
}
- for( ind = 0; ind < (val ? 516 : 16); ind++)
+ for( ind = 0; ind < len; ind++)
{
- unsigned char tc;
- unsigned char t;
+ uchar tc;
+ uchar t;
index_i++;
- index_j += s_box[index_i];
+ index_j += hash[index_i];
- tc = s_box[index_i];
- s_box[index_i] = s_box[index_j];
- s_box[index_j] = tc;
+ tc = hash[index_i];
+ hash[index_i] = hash[index_j];
+ hash[index_j] = tc;
- t = s_box[index_i] + s_box[index_j];
- data[ind] = data[ind] ^ s_box[t];
+ t = hash[index_i] + hash[index_j];
+ data[ind] = data[ind] ^ hash[t];
}
}
+
+void sam_pwd_hash(uint32 rid, const uchar *in, uchar *out, int forw)
+{
+ uchar s[14];
+
+ s[0] = s[4] = s[8] = s[12] = (uchar)(rid & 0xFF);
+ s[1] = s[5] = s[9] = s[13] = (uchar)((rid >> 8) & 0xFF);
+ s[2] = s[6] = s[10] = (uchar)((rid >> 16) & 0xFF);
+ s[3] = s[7] = s[11] = (uchar)((rid >> 24) & 0xFF);
+
+ smbhash(out, in, s, forw);
+ smbhash(out+8, in+8, s+7, forw);
+}
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index b927e193dd7..1ac28ef2008 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -2,8 +2,10 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-1998
- Modified by Jeremy Allison 1995.
+ Copyright (C) Andrew Tridgell 1992-2000
+ Modified by Jeremy Allison.
+ Copyright (C) Jeremy Allison 1995-2000.
+ Copyright (C) Luke Kennethc Casson Leighton 1996-2000.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,38 +26,47 @@
extern int DEBUGLEVEL;
-#include "byteorder.h"
-
/*
This implements the X/Open SMB password encryption
It takes a password, a 8 byte "crypt key" and puts 24 bytes of
encrypted password into p24 */
-void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
+void SMBencrypt(uchar * pwrd, uchar * c8, uchar * p24)
{
- uchar p14[15], p21[21];
+ uchar p21[21];
- memset(p21,'\0',21);
- memset(p14,'\0',14);
- StrnCpy((char *)p14,(char *)passwd,14);
+ lm_owf_gen(pwrd, p21);
+ SMBOWFencrypt(p21, c8, p24);
- strupper((char *)p14);
- E_P16(p14, p21);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("SMBencrypt: lm#, challenge, response\n"));
+ dump_data(100, p21, 16);
+ dump_data(100, c8, 8);
+ dump_data(100, p24, 24);
+#endif
+}
+void SMBNTencrypt(uchar * pwrd, uchar * c8, uchar * p24)
+{
+ uchar p21[21];
+
+ ZERO_STRUCT(p21);
+
+ nt_owf_gen(pwrd, p21);
SMBOWFencrypt(p21, c8, p24);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
- dump_data(100, (char *)p21, 16);
- dump_data(100, (char *)c8, 8);
- dump_data(100, (char *)p24, 24);
+ DEBUG(100, ("SMBNTencrypt: nt#, challenge, response\n"));
+ dump_data(100, p21, 16);
+ dump_data(100, c8, 8);
+ dump_data(100, p24, 24);
#endif
}
/* Routines for Windows NT MD4 Hash functions. */
-static int _my_wcslen(int16 *str)
+static int _my_wcslen(int16 * str)
{
int len = 0;
- while(*str++ != 0)
+ while (*str++ != 0)
len++;
return len;
}
@@ -66,18 +77,36 @@ static int _my_wcslen(int16 *str)
* this must be in intel (little-endian)
* format.
*/
-
-static int _my_mbstowcs(int16 *dst, uchar *src, int len)
+
+static int _my_mbstowcsupper(int16 * dst, const uchar * src, int len)
{
int i;
int16 val;
-
- for(i = 0; i < len; i++) {
+
+ for (i = 0; i < len; i++)
+ {
+ val = toupper(*src);
+ SSVAL(dst, 0, val);
+ dst++;
+ src++;
+ if (val == 0)
+ break;
+ }
+ return i;
+}
+
+static int _my_mbstowcs(int16 * dst, const uchar * src, int len)
+{
+ int i;
+ int16 val;
+
+ for (i = 0; i < len; i++)
+ {
val = *src;
- SSVAL(dst,0,val);
+ SSVAL(dst, 0, val);
dst++;
src++;
- if(val == 0)
+ if (val == 0)
break;
}
return i;
@@ -86,117 +115,310 @@ static int _my_mbstowcs(int16 *dst, uchar *src, int len)
/*
* Creates the MD4 Hash of the users password in NT UNICODE.
*/
-
-void E_md4hash(uchar *passwd, uchar *p16)
+
+void E_md4hash(uchar * pwrd, uchar * p16)
{
int len;
int16 wpwd[129];
-
+
/* Password cannot be longer than 128 characters */
- len = strlen((char *)passwd);
- if(len > 128)
+ len = strlen((char *)pwrd);
+ if (len > 128)
len = 128;
/* Password must be converted to NT unicode */
- _my_mbstowcs(wpwd, passwd, len);
- wpwd[len] = 0; /* Ensure string is null terminated */
+ _my_mbstowcs(wpwd, pwrd, len);
+ wpwd[len] = 0; /* Ensure string is null terminated */
/* Calculate length in bytes */
len = _my_wcslen(wpwd) * sizeof(int16);
- mdfour(p16, (unsigned char *)wpwd, len);
+ mdfour(p16, (uchar *) wpwd, len);
}
-/* Does both the NT and LM owfs of a user's password */
-void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16])
+/* Does the LM owf of a user's password */
+void lm_owf_genW(const UNISTR2 * pwd, uchar p16[16])
{
- char passwd[130];
+ char pwrd[15];
+
+ ZERO_STRUCT(pwrd);
+ if (pwd != NULL)
+ {
+ unistr2_to_ascii(pwrd, pwd, sizeof(pwrd) - 1);
+ }
- memset(passwd,'\0',130);
- safe_strcpy( passwd, pwd, sizeof(passwd)-1);
+ /* Mangle the passwords into Lanman format */
+ pwrd[14] = '\0';
+ strupper(pwrd);
- /* Calculate the MD4 hash (NT compatible) of the password */
- memset(nt_p16, '\0', 16);
- E_md4hash((uchar *)passwd, nt_p16);
+ /* Calculate the SMB (lanman) hash functions of the password */
+
+ E_P16((uchar *) pwrd, (uchar *) p16);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
- dump_data(120, passwd, strlen(passwd));
- dump_data(100, (char *)nt_p16, 16);
+ DEBUG(100, ("lm_owf_genW: pwd, lm#\n"));
+ dump_data(120, pwrd, strlen(pwrd));
+ dump_data(100, p16, 16);
#endif
+ /* clear out local copy of user's password (just being paranoid). */
+ bzero(pwrd, sizeof(pwrd));
+}
+
+/* Does the LM owf of a user's password */
+void lm_owf_gen(const char *pwd, uchar p16[16])
+{
+ char pwrd[15];
+
+ ZERO_STRUCT(pwrd);
+
+ if (pwd != NULL)
+ {
+ safe_strcpy(pwrd, pwd, sizeof(pwrd) - 1);
+ }
/* Mangle the passwords into Lanman format */
- passwd[14] = '\0';
- strupper(passwd);
+ pwrd[14] = '\0';
+ strupper(pwrd);
/* Calculate the SMB (lanman) hash functions of the password */
- memset(p16, '\0', 16);
- E_P16((uchar *) passwd, (uchar *)p16);
+ E_P16((uchar *) pwrd, (uchar *) p16);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
- dump_data(120, passwd, strlen(passwd));
- dump_data(100, (char *)p16, 16);
+ DEBUG(100, ("nt_lm_owf_gen: pwd, lm#\n"));
+ dump_data(120, pwrd, strlen(pwrd));
+ dump_data(100, p16, 16);
#endif
/* clear out local copy of user's password (just being paranoid). */
- memset(passwd, '\0', sizeof(passwd));
+ bzero(pwrd, sizeof(pwrd));
+}
+
+/* Does both the NT and LM owfs of a user's password */
+void nt_owf_genW(const UNISTR2 * pwd, uchar nt_p16[16])
+{
+ UNISTR2 pwrd;
+
+ ZERO_STRUCT(pwrd);
+ if (pwd != NULL)
+ {
+ copy_unistr2(&pwrd, pwd);
+ }
+
+ /* Calculate the MD4 hash (NT compatible) of the password */
+ mdfour(nt_p16, (uchar *) pwrd.buffer, pwrd.uni_str_len * 2);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("nt_owf_genW: pwd, nt#\n"));
+ dump_data(120, (const char *)pwrd.buffer, pwrd.uni_str_len * 2);
+ dump_data(100, nt_p16, 16);
+#endif
+ /* clear out local copy of user's password (just being paranoid). */
+ ZERO_STRUCT(pwrd);
+}
+
+/* Does both the NT and LM owfs of a user's password */
+void nt_owf_gen(const char *pwd, uchar nt_p16[16])
+{
+ char pwrd[130];
+
+ ZERO_STRUCT(pwrd);
+ if (pwd != NULL)
+ {
+ safe_strcpy(pwrd, pwd, sizeof(pwrd) - 1);
+ }
+
+ /* Calculate the MD4 hash (NT compatible) of the password */
+ E_md4hash((uchar *) pwrd, nt_p16);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("nt_owf_gen: pwd, nt#\n"));
+ dump_data(120, pwrd, strlen(pwrd));
+ dump_data(100, nt_p16, 16);
+#endif
+ /* clear out local copy of user's password (just being paranoid). */
+ bzero(pwrd, sizeof(pwrd));
+}
+
+/* Does both the NT and LM owfs of a user's UNICODE password */
+void nt_lm_owf_genW(const UNISTR2 * pwd, uchar nt_p16[16], uchar lm_p16[16])
+{
+ nt_owf_genW(pwd, nt_p16);
+ lm_owf_genW(pwd, lm_p16);
+}
+
+/* Does both the NT and LM owfs of a user's password */
+void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16])
+{
+ nt_owf_gen(pwd, nt_p16);
+ lm_owf_gen(pwd, lm_p16);
}
/* Does the des encryption from the NT or LM MD4 hash. */
-void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24])
+void SMBOWFencrypt(const uchar pwrd[16], const uchar * c8, uchar p24[24])
{
uchar p21[21];
-
- memset(p21,'\0',21);
-
- memcpy(p21, passwd, 16);
+
+ ZERO_STRUCT(p21);
+
+ memcpy(p21, pwrd, 16);
E_P24(p21, c8, p24);
}
-/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
-void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24])
+void SMBOWFencrypt_ntv2(const uchar kr[16],
+ const uchar * srv_chal, int srv_chal_len,
+ const uchar * cli_chal, int cli_chal_len,
+ char resp_buf[16])
{
- uchar p21[21];
-
- memset(p21,'\0',21);
- memcpy(p21, passwd, 8);
- memset(p21 + 8, 0xbd, 8);
+ HMACMD5Context ctx;
+
+ hmac_md5_init_limK_to_64(kr, 16, &ctx);
+ hmac_md5_update(srv_chal, srv_chal_len, &ctx);
+ hmac_md5_update(cli_chal, cli_chal_len, &ctx);
+ hmac_md5_final(resp_buf, &ctx);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
+ dump_data(100, srv_chal, srv_chal_len);
+ dump_data(100, cli_chal, cli_chal_len);
+ dump_data(100, resp_buf, 16);
+#endif
+}
+
+void SMBsesskeygen_ntv2(const uchar kr[16],
+ const uchar * nt_resp, char sess_key[16])
+{
+ HMACMD5Context ctx;
+
+ hmac_md5_init_limK_to_64(kr, 16, &ctx);
+ hmac_md5_update(nt_resp, 16, &ctx);
+ hmac_md5_final(sess_key, &ctx);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("SMBsesskeygen_ntv2:\n"));
+ dump_data(100, sess_key, 16);
+#endif
+}
+
+void SMBsesskeygen_ntv1(const uchar kr[16],
+ const uchar * nt_resp, char sess_key[16])
+{
+ mdfour(sess_key, kr, 16);
- E_P24(p21, ntlmchalresp, p24);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
- dump_data(100, (char *)p21, 21);
- dump_data(100, (char *)ntlmchalresp, 8);
- dump_data(100, (char *)p24, 24);
+ DEBUG(100, ("SMBsesskeygen_ntv1:\n"));
+ dump_data(100, sess_key, 16);
#endif
}
+void SMBgenclientchals(char *lm_cli_chal,
+ char *nt_cli_chal, int *nt_cli_chal_len,
+ const char *srv, const char *dom)
+{
+ NTTIME nt_time;
+ int srv_len = strlen(srv);
+ int dom_len = strlen(dom);
+ fstring server;
+ fstring domain;
+ fstrcpy(server, srv);
+ fstrcpy(domain, dom);
+ strupper(server);
+ strupper(domain);
+
+ generate_random_buffer(lm_cli_chal, 8, False);
+ unix_to_nt_time(&nt_time, time(NULL));
+
+ CVAL(nt_cli_chal, 0) = 0x1;
+ CVAL(nt_cli_chal, 1) = 0x1;
+ SSVAL(nt_cli_chal, 2, 0x0);
+ SIVAL(nt_cli_chal, 4, 0x0);
+ SIVAL(nt_cli_chal, 8, nt_time.low);
+ SIVAL(nt_cli_chal, 12, nt_time.high);
+ memcpy(nt_cli_chal + 16, lm_cli_chal, 8);
+ /* fill in offset 24, size of structure, later */
+
+ *nt_cli_chal_len = 28;
+
+ SSVAL(nt_cli_chal, *nt_cli_chal_len, 2);
+ *nt_cli_chal_len += 2;
+ SSVAL(nt_cli_chal, *nt_cli_chal_len, dom_len * 2);
+ *nt_cli_chal_len += 2;
+ ascii_to_unibuf(nt_cli_chal + (*nt_cli_chal_len), domain,
+ dom_len * 2);
+ *nt_cli_chal_len += dom_len * 2;
+ *nt_cli_chal_len += 4 - ((*nt_cli_chal_len) % 4);
+
+ SSVAL(nt_cli_chal, *nt_cli_chal_len, 2);
+ *nt_cli_chal_len += 2;
+ SSVAL(nt_cli_chal, 30, srv_len * 2);
+ *nt_cli_chal_len += 2;
+ ascii_to_unibuf(nt_cli_chal + (*nt_cli_chal_len), server,
+ srv_len * 2);
+ *nt_cli_chal_len += srv_len * 2;
+
+ SSVAL(nt_cli_chal, 24, (*nt_cli_chal_len) + 16);
+ SSVAL(nt_cli_chal, 26, (*nt_cli_chal_len) + 15);
+
+ DEBUG(100, ("SMBgenclientchals: srv %s, dom %s\n", server, domain));
+ dump_data(100, nt_cli_chal, *nt_cli_chal_len);
+}
+
+void ntv2_owf_gen(const uchar owf[16],
+ const char *user_n, const char *domain_n, uchar kr_buf[16])
+{
+ pstring user_u;
+ pstring dom_u;
+ HMACMD5Context ctx;
+
+ int user_l = strlen(user_n);
+ int domain_l = strlen(domain_n);
-/* Does the NT MD4 hash then des encryption. */
-
-void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
+ _my_mbstowcsupper((int16 *) user_u, user_n, user_l * 2);
+ _my_mbstowcsupper((int16 *) dom_u, domain_n, domain_l * 2);
+
+ hmac_md5_init_limK_to_64(owf, 16, &ctx);
+ hmac_md5_update(user_u, user_l * 2, &ctx);
+ hmac_md5_update(dom_u, domain_l * 2, &ctx);
+ hmac_md5_final(kr_buf, &ctx);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n"));
+ dump_data(100, user_u, user_l * 2);
+ dump_data(100, dom_u, domain_l * 2);
+ dump_data(100, owf, 16);
+ dump_data(100, kr_buf, 16);
+#endif
+}
+
+/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
+void NTLMSSPOWFencrypt(const uchar pwrd[8], const uchar * ntlmchalresp,
+ uchar p24[24])
{
uchar p21[21];
-
- memset(p21,'\0',21);
-
- E_md4hash(passwd, p21);
- SMBOWFencrypt(p21, c8, p24);
+ ZERO_STRUCT(p21);
+ memcpy(p21, pwrd, 8);
+ memset(p21 + 8, 0xbd, 8);
+
+ E_P24(p21, ntlmchalresp, p24);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
- dump_data(100, (char *)p21, 16);
- dump_data(100, (char *)c8, 8);
- dump_data(100, (char *)p24, 24);
+ DEBUG(100, ("NTLMSSPOWFencrypt: p21, c8, p24\n"));
+ dump_data(100, p21, 21);
+ dump_data(100, ntlmchalresp, 8);
+ dump_data(100, p24, 24);
#endif
}
-BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode)
+BOOL make_oem_passwd_hash(uchar data[516],
+ const char *pwrd, int new_pw_len,
+ const uchar old_pw_hash[16], BOOL unicode)
{
- int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);
+ if (new_pw_len == 0)
+ {
+ new_pw_len = strlen(pwrd) * (unicode ? 2 : 1);
+ }
if (new_pw_len > 512)
{
- DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
+ DEBUG(0,
+ ("make_oem_passwd_hash: new password is too long.\n"));
return False;
}
@@ -206,25 +428,212 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
* for this area to make it harder to
* decrypt. JRA.
*/
- generate_random_buffer((unsigned char *)data, 516, False);
+ generate_random_buffer(data, 516, False);
if (unicode)
{
- /* Note that passwd should be in DOS oem character set. */
- dos_struni2( &data[512 - new_pw_len], passwd, 512);
+ ascii_to_unibuf(&data[512 - new_pw_len], pwrd, new_pw_len);
}
else
{
- /* Note that passwd should be in DOS oem character set. */
- fstrcpy( &data[512 - new_pw_len], passwd);
+ fstrcpy(&data[512 - new_pw_len], pwrd);
}
SIVAL(data, 512, new_pw_len);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("make_oem_passwd_hash\n"));
+ DEBUG(100, ("make_oem_passwd_hash\n"));
dump_data(100, data, 516);
#endif
- SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True);
+ if (old_pw_hash != NULL)
+ {
+ SamOEMhash(data, old_pw_hash, True);
+ }
return True;
}
+BOOL nt_encrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key)
+{
+ const uchar *keyptr = key;
+ const uchar *keyend = key + 16;
+ int datalen = in->str_str_len;
+
+ uchar *outbuf = (uchar *) out->buffer;
+ const uchar *inbuf = (const uchar *)in->buffer;
+ const uchar *inbufend;
+
+ out->str_max_len = in->str_max_len;
+ out->str_str_len = in->str_str_len;
+ out->undoc = 0;
+
+ inbufend = inbuf + datalen;
+
+ dump_data_pw("nt_encrypt_string2\n", inbuf, datalen);
+
+ while (inbuf < inbufend)
+ {
+ smbhash(outbuf, inbuf, keyptr, 1);
+
+ keyptr += 7;
+ if (keyptr + 7 > keyend)
+ {
+ keyptr = (keyend - keyptr) + key;
+ }
+
+ inbuf += 8;
+ outbuf += 8;
+ }
+
+ dump_data_pw("nt_encrypt_string2\n", out->buffer, datalen);
+
+ return True;
+}
+
+BOOL nt_decrypt_string2(STRING2 * out, const STRING2 * in, const uchar * key)
+{
+ int datalen = in->str_str_len;
+
+ const uchar *keyptr = key;
+ const uchar *keyend = key + 16;
+
+ uchar *outbuf = (uchar *) out->buffer;
+ const uchar *inbuf = (const uchar *)in->buffer;
+ const uchar *inbufend;
+
+ if (in->str_str_len > MAX_STRINGLEN)
+ {
+ DEBUG(0, ("nt_decrypt_string2: failed\n"));
+ return False;
+ }
+
+ out->str_max_len = in->str_max_len;
+ out->str_str_len = in->str_str_len;
+ out->undoc = in->undoc;
+
+ inbufend = inbuf + datalen;
+
+ while (inbuf < inbufend)
+ {
+ smbhash(outbuf, inbuf, keyptr, 0);
+ keyptr += 7;
+ if (keyptr + 7 > keyend)
+ {
+ keyptr = (keyend - keyptr) + key;
+ }
+
+ inbuf += 8;
+ outbuf += 8;
+ }
+
+ datalen = IVAL(out->buffer, 0);
+
+ dump_data_pw("nt_decrypt_string2\n", out->buffer, out->str_str_len);
+
+ if (datalen != in->str_str_len - 8)
+ {
+ DEBUG(2, ("nt_decrypt_string2: length-match failed\n"));
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ creates a DCE/RPC bind authentication response
+
+ - initialises the parse structure.
+ - dynamically allocates the header data structure
+ - caller is expected to free the header data structure once used.
+
+ ********************************************************************/
+void create_ntlmssp_resp(struct pwd_info *pwd,
+ char *domain, char *user_name, char *my_name,
+ uint32 ntlmssp_cli_flgs, prs_struct * auth_resp)
+{
+ RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+ uchar lm_owf[24];
+ uchar nt_owf[128];
+ size_t nt_owf_len;
+
+ pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len);
+
+ make_rpc_auth_ntlmssp_resp(&ntlmssp_resp,
+ lm_owf, nt_owf, nt_owf_len,
+ domain, user_name, my_name,
+ ntlmssp_cli_flgs);
+
+ smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp,
+ 0);
+ prs_realloc_data(auth_resp, auth_resp->offset);
+}
+
+/***********************************************************
+ decode a password buffer
+************************************************************/
+BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
+ int new_pwrd_size, uint32 * new_pw_len)
+{
+ /*
+ * The length of the new password is in the last 4 bytes of
+ * the data buffer.
+ */
+
+ (*new_pw_len) = IVAL(buffer, 512);
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, buffer, 516);
+#endif
+
+ if ((*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1)
+ {
+ DEBUG(0,
+ ("decode_pw_buffer: incorrect password length (%d).\n",
+ (*new_pw_len)));
+ return False;
+ }
+
+ memcpy(new_pwrd, &buffer[512 - (*new_pw_len)], (*new_pw_len));
+ new_pwrd[(*new_pw_len)] = '\0';
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, new_pwrd, (*new_pw_len));
+#endif
+
+ return True;
+}
+
+/***********************************************************
+ encode a password buffer
+************************************************************/
+BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
+ int new_pw_len, BOOL nt_pass_set)
+{
+ generate_random_buffer(buffer, 516, True);
+
+ if (nt_pass_set)
+ {
+ /*
+ * nt passwords are in unicode. last char overwrites NULL
+ * in ascii_to_unibuf, so use SIVAL *afterwards*.
+ */
+ new_pw_len *= 2;
+ ascii_to_unibuf(&buffer[512 - new_pw_len], new_pass,
+ new_pw_len);
+ }
+ else
+ {
+ memcpy(&buffer[512 - new_pw_len], new_pass, new_pw_len);
+ }
+
+ /*
+ * The length of the new password is in the last 4 bytes of
+ * the data buffer.
+ */
+
+ SIVAL(buffer, 512, new_pw_len);
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, buffer, 516);
+#endif
+
+ return True;
+}
diff --git a/source/libsmb/smberr.c b/source/libsmb/smberr.c
index c2d8884d738..228eee5892a 100644
--- a/source/libsmb/smberr.c
+++ b/source/libsmb/smberr.c
@@ -143,39 +143,70 @@ struct
{0xFF,"ERRCMD",NULL},
{-1,NULL,NULL}};
+char *smb_err_msg(uint8 class, uint32 num)
+{
+ static pstring ret;
+ smb_safe_err_msg(class, num, ret, sizeof(ret));
+ return ret;
+}
+
/****************************************************************************
return a SMB error string from a SMB buffer
****************************************************************************/
-char *smb_errstr(char *inbuf)
+BOOL smb_safe_err_msg(uint8 class, uint32 num, char *ret, size_t len)
{
- static pstring ret;
- int class = CVAL(inbuf,smb_rcls);
- int num = SVAL(inbuf,smb_err);
- int i,j;
-
- for (i=0;err_classes[i].class;i++)
- if (err_classes[i].code == class)
- {
- if (err_classes[i].err_msgs)
- {
- err_code_struct *err = err_classes[i].err_msgs;
- for (j=0;err[j].name;j++)
- if (num == err[j].code)
+ int i,j;
+
+ for (i=0;err_classes[i].class;i++)
+ {
+ if (err_classes[i].code == class)
{
- if (DEBUGLEVEL > 0)
- slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class,
- err[j].name,err[j].message);
- else
- slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name);
- return ret;
+ err_code_struct *err = err_classes[i].err_msgs;
+ if (err != NULL)
+ {
+ for (j=0;err[j].name;j++)
+ {
+ if (num == err[j].code)
+ {
+ if (DEBUGLEVEL > 0)
+ {
+ slprintf(ret, len - 1, "%s - %s (%s)",err_classes[i].class,
+ err[j].name,err[j].message);
+ }
+ else
+ {
+ slprintf(ret, len - 1, "%s - %s",err_classes[i].class,err[j].name);
+ }
+ return True;
+ }
+ }
+ }
+ slprintf(ret, len - 1, "%s - %d",err_classes[i].class, num);
+ return True;
}
- }
- slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num);
- return ret;
- }
-
- slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num);
- return(ret);
+ }
+
+ slprintf(ret, len - 1, "Error: Unknown error (%d,%d)",class,num);
+ return False;
+}
+
+/****************************************************************************
+return a SMB error string from a SMB buffer
+****************************************************************************/
+BOOL smb_safe_errstr(char *inbuf, char *msg, size_t len)
+{
+ return smb_safe_err_msg(CVAL(inbuf,smb_rcls), SVAL(inbuf,smb_err),
+ msg, len);
+}
+
+/****************************************************************************
+return a SMB error string from a SMB buffer
+****************************************************************************/
+char *smb_errstr(char *inbuf)
+{
+ static fstring errmsg;
+ (void)smb_safe_errstr(inbuf, errmsg, sizeof(errmsg));
+ return errmsg;
}
diff --git a/source/locking/locking.c b/source/locking/locking.c
index 2f85e92932a..f53fd745639 100644
--- a/source/locking/locking.c
+++ b/source/locking/locking.c
@@ -38,27 +38,41 @@ extern int DEBUGLEVEL;
/* the locking database handle */
static TDB_CONTEXT *tdb;
-int global_smbpid;
-
-
/****************************************************************************
-remove any locks on this fd
+ Utility function to map a lock type correctly depending on the real open
+ mode of a file.
****************************************************************************/
-void locking_close_file(files_struct *fsp)
+static int map_lock_type(files_struct *fsp, int lock_type)
{
- if (!lp_locking(SNUM(fsp->conn))) return;
-
- brl_close(fsp->fd_ptr->dev, fsp->fd_ptr->inode,
- getpid(), fsp->conn->cnum, fsp->fnum);
+ if((lock_type == F_WRLCK) && (fsp->fd_ptr->real_open_flags == O_RDONLY)) {
+ /*
+ * Many UNIX's cannot get a write lock on a file opened read-only.
+ * Win32 locking semantics allow this.
+ * Do the best we can and attempt a read-only lock.
+ */
+ DEBUG(10,("map_lock_type: Downgrading write lock to read due to read-only file.\n"));
+ return F_RDLCK;
+ } else if( (lock_type == F_RDLCK) && (fsp->fd_ptr->real_open_flags == O_WRONLY)) {
+ /*
+ * Ditto for read locks on write only files.
+ */
+ DEBUG(10,("map_lock_type: Changing read lock to write due to write-only file.\n"));
+ return F_WRLCK;
+ }
+
+ /*
+ * This return should be the most normal, as we attempt
+ * to always open files read/write.
+ */
+
+ return lock_type;
}
-
/****************************************************************************
Utility function called to see if a file region is locked.
****************************************************************************/
BOOL is_locked(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset,
- enum brl_type lock_type)
+ SMB_OFF_T count,SMB_OFF_T offset, int lock_type)
{
int snum = SNUM(conn);
@@ -68,9 +82,13 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
if (!lp_locking(snum) || !lp_strict_locking(snum))
return(False);
- return !brl_locktest(fsp->fd_ptr->dev, fsp->fd_ptr->inode,
- global_smbpid, getpid(), conn->cnum,
- offset, count, lock_type);
+ /*
+ * Note that most UNIX's can *test* for a write lock on
+ * a read-only fd, just not *set* a write lock on a read-only
+ * fd. So we don't need to use map_lock_type here.
+ */
+
+ return(fcntl_lock(fsp->fd_ptr->fd,SMB_F_GETLK,offset,count,lock_type));
}
@@ -78,7 +96,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
Utility function called by locking requests.
****************************************************************************/
BOOL do_lock(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset,enum brl_type lock_type,
+ SMB_OFF_T count,SMB_OFF_T offset,int lock_type,
int *eclass,uint32 *ecode)
{
BOOL ok = False;
@@ -95,12 +113,9 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
DEBUG(10,("do_lock: lock type %d start=%.0f len=%.0f requested for file %s\n",
lock_type, (double)offset, (double)count, fsp->fsp_name ));
- if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
- ok = brl_lock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum,
- global_smbpid, getpid(), conn->cnum,
- offset, count,
- lock_type);
- }
+ if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
+ ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,
+ map_lock_type(fsp,lock_type));
if (!ok) {
*eclass = ERRDOS;
@@ -115,8 +130,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
Utility function called by unlocking requests.
****************************************************************************/
BOOL do_unlock(files_struct *fsp,connection_struct *conn,
- SMB_OFF_T count,SMB_OFF_T offset,
- int *eclass,uint32 *ecode)
+ SMB_OFF_T count,SMB_OFF_T offset,int *eclass,uint32 *ecode)
{
BOOL ok = False;
@@ -126,11 +140,8 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for file %s\n",
(double)offset, (double)count, fsp->fsp_name ));
- if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
- ok = brl_unlock(fsp->fd_ptr->dev, fsp->fd_ptr->inode, fsp->fnum,
- global_smbpid, getpid(), conn->cnum,
- offset, count);
- }
+ if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn))
+ ok = fcntl_lock(fsp->fd_ptr->fd,SMB_F_SETLK,offset,count,F_UNLCK);
if (!ok) {
*eclass = ERRDOS;
@@ -145,8 +156,6 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
****************************************************************************/
BOOL locking_init(int read_only)
{
- brl_init(read_only);
-
if (tdb) return True;
tdb = tdb_open(lock_path("locking.tdb"),
@@ -465,21 +474,19 @@ BOOL modify_share_mode(files_struct *fsp, int new_mode, uint16 new_oplock)
return mod_share_mode(fsp, modify_share_mode_fn, (void *)&mv);
}
+static void (*traverse_callback)(share_mode_entry *, char *);
/****************************************************************************
traverse the whole database with this function, calling traverse_callback
on each share mode
****************************************************************************/
-static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void* state)
+static int traverse_fn(TDB_CONTEXT *db, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
{
struct locking_data *data;
share_mode_entry *shares;
char *name;
int i;
- SHAREMODE_FN(traverse_callback) = (SHAREMODE_FN_CAST())state;
-
data = (struct locking_data *)dbuf.dptr;
shares = (share_mode_entry *)(dbuf.dptr + sizeof(*data));
name = dbuf.dptr + sizeof(*data) + data->num_share_mode_entries*sizeof(*shares);
@@ -494,8 +501,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
Call the specified function on each entry under management by the
share mode system.
********************************************************************/
-int share_mode_forall(SHAREMODE_FN(fn))
+int share_mode_forall(void (*fn)(share_mode_entry *, char *))
{
if (!tdb) return 0;
- return tdb_traverse(tdb, traverse_fn, (void*)fn);
+ traverse_callback = fn;
+ return tdb_traverse(tdb, traverse_fn, NULL);
}
diff --git a/source/locking/locking_shm.c b/source/locking/locking_shm.c
new file mode 100644
index 00000000000..375a8b7f109
--- /dev/null
+++ b/source/locking/locking_shm.c
@@ -0,0 +1,708 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ shared memory locking implementation
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ Revision History:
+
+ 12 aug 96: Erik.Devriendt@te6.siemens.be
+ added support for shared memory implementation of share mode locking
+
+ May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
+ locking to deal with multiple share modes per open file.
+
+ September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
+ support.
+
+ October 1997 - split into separate file (tridge)
+*/
+
+#include "includes.h"
+
+#ifdef FAST_SHARE_MODES
+
+extern int DEBUGLEVEL;
+
+static struct shmem_ops *shmops;
+
+/* share mode record pointed to in shared memory hash bucket */
+typedef struct
+{
+ int next_offset; /* offset of next record in chain from hash bucket */
+ int locking_version;
+ SMB_DEV_T st_dev;
+ SMB_INO_T st_ino;
+ int num_share_mode_entries;
+ int share_mode_entries; /* Chain of share mode entries for this file */
+ char file_name[1];
+} share_mode_record;
+
+/* share mode entry pointed to by share_mode_record struct */
+typedef struct
+{
+ int next_share_mode_entry;
+ share_mode_entry e;
+} shm_share_mode_entry;
+
+static int read_only;
+
+
+/* Conversion to hash entry index from device and inode numbers. */
+#define HASH_ENTRY(dev,ino) ((unsigned int)(((dev) ^ (ino)) % shmops->hash_size()))
+
+
+/*******************************************************************
+ deinitialize the shared memory for share_mode management
+ ******************************************************************/
+static BOOL shm_stop_share_mode_mgmt(void)
+{
+ return shmops->shm_close();
+}
+
+/*******************************************************************
+ lock a hash bucket entry in shared memory for share_mode management
+ ******************************************************************/
+static BOOL shm_lock_share_entry(connection_struct *conn,
+ SMB_DEV_T dev, SMB_INO_T inode, int *ptok)
+{
+ return shmops->lock_hash_entry(HASH_ENTRY(dev, inode));
+}
+
+/*******************************************************************
+ unlock a hash bucket entry in shared memory for share_mode management
+ ******************************************************************/
+static BOOL shm_unlock_share_entry(connection_struct *conn,
+ SMB_DEV_T dev, SMB_INO_T inode, int token)
+{
+ return shmops->unlock_hash_entry(HASH_ENTRY(dev, inode));
+}
+
+/*******************************************************************
+get all share mode entries in shared memory for a dev/inode pair.
+********************************************************************/
+static int shm_get_share_modes(connection_struct *conn,
+ int token, SMB_DEV_T dev, SMB_INO_T inode,
+ share_mode_entry **old_shares)
+{
+ int *mode_array;
+ unsigned int hash_entry = HASH_ENTRY(dev, inode);
+ share_mode_record *file_scanner_p;
+ share_mode_record *file_prev_p;
+ shm_share_mode_entry *entry_scanner_p;
+ shm_share_mode_entry *entry_prev_p;
+ int num_entries;
+ int num_entries_copied;
+ BOOL found = False;
+ share_mode_entry *share_array = (share_mode_entry *)0;
+
+ *old_shares = 0;
+
+ mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
+
+ if(mode_array[hash_entry] == 0)
+ {
+ DEBUG(5,("get_share_modes hash bucket %d empty\n", hash_entry));
+ return 0;
+ }
+
+ file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
+ file_prev_p = file_scanner_p;
+ while(file_scanner_p)
+ {
+ if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
+ {
+ found = True;
+ break;
+ }
+ else
+ {
+ file_prev_p = file_scanner_p ;
+ file_scanner_p = (share_mode_record *)shmops->offset2addr(
+ file_scanner_p->next_offset);
+ }
+ }
+
+ if(!found)
+ {
+ DEBUG(5,("get_share_modes no entry for file dev = %x ino = %.0f\n",
+ (unsigned int)dev, (double)inode));
+ return (0);
+ }
+
+ if(file_scanner_p->locking_version != LOCKING_VERSION)
+ {
+ DEBUG(0,("ERROR: get_share_modes Deleting old share mode v1 %d dev=%x ino=%.0f\n",
+ file_scanner_p->locking_version, (unsigned int)dev, (double)inode));
+
+ if(file_prev_p == file_scanner_p)
+ mode_array[hash_entry] = file_scanner_p->next_offset;
+ else
+ file_prev_p->next_offset = file_scanner_p->next_offset;
+ shmops->shm_free(shmops->addr2offset(file_scanner_p));
+ return (0);
+ }
+
+ /* Allocate the old_shares array */
+ num_entries = file_scanner_p->num_share_mode_entries;
+ if(num_entries)
+ {
+ *old_shares = share_array = (share_mode_entry *)
+ malloc(num_entries * sizeof(share_mode_entry));
+ if(*old_shares == 0)
+ {
+ DEBUG(0,("get_share_modes: malloc fail!\n"));
+ return 0;
+ }
+ }
+
+ num_entries_copied = 0;
+
+ entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
+ file_scanner_p->share_mode_entries);
+ entry_prev_p = entry_scanner_p;
+ while(entry_scanner_p)
+ {
+ int pid = entry_scanner_p->e.pid;
+
+ if (pid && !process_exists(pid))
+ {
+ /* Delete this share mode entry */
+ shm_share_mode_entry *delete_entry_p = entry_scanner_p;
+
+ if(entry_prev_p == entry_scanner_p)
+ {
+ /* We are at start of list */
+ file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
+ entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
+ file_scanner_p->share_mode_entries);
+ entry_prev_p = entry_scanner_p;
+ }
+ else
+ {
+ entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
+ entry_scanner_p = (shm_share_mode_entry*)
+ shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
+ }
+ /* Decrement the number of share mode entries on this share mode record */
+ file_scanner_p->num_share_mode_entries -= 1;
+
+ /* PARANOIA TEST */
+ if(file_scanner_p->num_share_mode_entries < 0)
+ {
+ DEBUG(0,("PANIC ERROR: get_share_mode: entries=%d dev=%x ino=%.0f\n",
+ file_scanner_p->num_share_mode_entries, (unsigned int)dev, (double)inode));
+ return 0;
+ }
+
+ DEBUG(0,("get_share_modes: process %d no longer exists\n", pid));
+
+ shmops->shm_free(shmops->addr2offset(delete_entry_p));
+ }
+ else
+ {
+ /* This is a valid share mode entry and the process that
+ created it still exists. Copy it into the output array.
+ */
+ share_array[num_entries_copied].pid = entry_scanner_p->e.pid;
+ share_array[num_entries_copied].share_mode = entry_scanner_p->e.share_mode;
+ share_array[num_entries_copied].op_port = entry_scanner_p->e.op_port;
+ share_array[num_entries_copied].op_type = entry_scanner_p->e.op_type;
+ memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->e.time,
+ sizeof(struct timeval));
+ num_entries_copied++;
+ DEBUG(5,("get_share_modes Read share mode 0x%X pid=%d\n",
+ entry_scanner_p->e.share_mode, entry_scanner_p->e.pid));
+ entry_prev_p = entry_scanner_p;
+ entry_scanner_p = (shm_share_mode_entry *)
+ shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
+ }
+ }
+
+ /* If no valid share mode entries were found then this record shouldn't exist ! */
+ if(num_entries_copied == 0)
+ {
+ DEBUG(0,("get_share_modes: file with dev %x inode %.0f empty\n",
+ (unsigned int)dev, (double)inode));
+
+ if(*old_shares)
+ free((char *)*old_shares);
+ *old_shares = 0;
+
+ if(file_prev_p == file_scanner_p)
+ mode_array[hash_entry] = file_scanner_p->next_offset;
+ else
+ file_prev_p->next_offset = file_scanner_p->next_offset;
+ shmops->shm_free(shmops->addr2offset(file_scanner_p));
+ }
+
+ DEBUG(5,("get_share_modes: file with dev %x inode %.0f -> %d entries\n",
+ (unsigned int)dev, (double)inode, num_entries_copied));
+
+ return(num_entries_copied);
+}
+
+/*******************************************************************
+del the share mode of a file.
+********************************************************************/
+static void shm_del_share_mode(int token, files_struct *fsp)
+{
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
+ int *mode_array;
+ unsigned int hash_entry;
+ share_mode_record *file_scanner_p;
+ share_mode_record *file_prev_p;
+ shm_share_mode_entry *entry_scanner_p;
+ shm_share_mode_entry *entry_prev_p;
+ BOOL found = False;
+ int pid = getpid();
+
+ dev = fsp->fd_ptr->dev;
+ inode = fsp->fd_ptr->inode;
+
+ hash_entry = HASH_ENTRY(dev, inode);
+
+ mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
+
+ if(mode_array[hash_entry] == 0)
+ {
+ DEBUG(0,("PANIC ERROR:del_share_mode hash bucket %d empty\n",
+ hash_entry));
+ return;
+ }
+
+ file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
+ file_prev_p = file_scanner_p;
+
+ while(file_scanner_p)
+ {
+ if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
+ {
+ found = True;
+ break;
+ }
+ else
+ {
+ file_prev_p = file_scanner_p ;
+ file_scanner_p = (share_mode_record *)
+ shmops->offset2addr(file_scanner_p->next_offset);
+ }
+ }
+
+ if(!found)
+ {
+ DEBUG(0,("ERROR: del_share_mode no entry for dev %x inode %.0f\n",
+ (unsigned int)dev, (double)inode));
+ return;
+ }
+
+ if(file_scanner_p->locking_version != LOCKING_VERSION)
+ {
+ DEBUG(0,("ERROR: del_share_modes Deleting old share mode v1 %d dev=%x ino=%.0f\n",
+ file_scanner_p->locking_version, (unsigned int)dev, (double)inode));
+
+ if(file_prev_p == file_scanner_p)
+ mode_array[hash_entry] = file_scanner_p->next_offset;
+ else
+ file_prev_p->next_offset = file_scanner_p->next_offset;
+ shmops->shm_free(shmops->addr2offset(file_scanner_p));
+ return;
+ }
+
+ found = False;
+ entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
+ file_scanner_p->share_mode_entries);
+ entry_prev_p = entry_scanner_p;
+ while(entry_scanner_p)
+ {
+ if( (pid == entry_scanner_p->e.pid) &&
+ (memcmp(&entry_scanner_p->e.time,
+ &fsp->open_time,sizeof(struct timeval)) == 0) )
+ {
+ found = True;
+ break;
+ }
+ else
+ {
+ entry_prev_p = entry_scanner_p;
+ entry_scanner_p = (shm_share_mode_entry *)
+ shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
+ }
+ }
+
+ if (found)
+ {
+ /* Decrement the number of entries in the record. */
+ file_scanner_p->num_share_mode_entries -= 1;
+
+ DEBUG(2,("del_share_modes Deleting share mode entry dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode));
+
+ if(entry_prev_p == entry_scanner_p)
+ /* We are at start of list */
+ file_scanner_p->share_mode_entries = entry_scanner_p->next_share_mode_entry;
+ else
+ entry_prev_p->next_share_mode_entry = entry_scanner_p->next_share_mode_entry;
+ shmops->shm_free(shmops->addr2offset(entry_scanner_p));
+
+ /* PARANOIA TEST */
+ if(file_scanner_p->num_share_mode_entries < 0)
+ {
+ DEBUG(0,("PANIC ERROR:del_share_mode num_share_mode_entries=%d\n",
+ file_scanner_p->num_share_mode_entries));
+ return;
+ }
+
+ /* If we deleted the last share mode entry then remove the share mode record. */
+ if(file_scanner_p->num_share_mode_entries == 0)
+ {
+ DEBUG(2,("del_share_modes num entries = 0, deleting share_mode dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode));
+
+ if(file_prev_p == file_scanner_p)
+ mode_array[hash_entry] = file_scanner_p->next_offset;
+ else
+ file_prev_p->next_offset = file_scanner_p->next_offset;
+ shmops->shm_free(shmops->addr2offset(file_scanner_p));
+ }
+ }
+ else
+ {
+ DEBUG(0,("ERROR: del_share_modes No share mode dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode));
+ }
+}
+
+/*******************************************************************
+set the share mode of a file. Return False on fail, True on success.
+********************************************************************/
+static BOOL shm_set_share_mode(int token, files_struct *fsp, uint16 port, uint16 op_type)
+{
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
+ int *mode_array;
+ unsigned int hash_entry;
+ share_mode_record *file_scanner_p;
+ shm_share_mode_entry *new_entry_p;
+ int new_entry_offset;
+ BOOL found = False;
+
+ dev = fsp->fd_ptr->dev;
+ inode = fsp->fd_ptr->inode;
+
+ hash_entry = HASH_ENTRY(dev, inode);
+
+ mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
+
+ file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
+
+ while(file_scanner_p)
+ {
+ if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
+ {
+ found = True;
+ break;
+ }
+ else
+ {
+ file_scanner_p = (share_mode_record *)
+ shmops->offset2addr(file_scanner_p->next_offset);
+ }
+ }
+
+ if(!found)
+ {
+ /* We must create a share_mode_record */
+ share_mode_record *new_mode_p = NULL;
+ int new_offset = shmops->shm_alloc(sizeof(share_mode_record) +
+ strlen(fsp->fsp_name) + 1);
+ if(new_offset == 0) {
+ DEBUG(0,("ERROR:set_share_mode shmops->shm_alloc fail!\n"));
+ return False;
+ }
+ new_mode_p = shmops->offset2addr(new_offset);
+ new_mode_p->locking_version = LOCKING_VERSION;
+ new_mode_p->st_dev = dev;
+ new_mode_p->st_ino = inode;
+ new_mode_p->num_share_mode_entries = 0;
+ new_mode_p->share_mode_entries = 0;
+ pstrcpy(new_mode_p->file_name, fsp->fsp_name);
+
+ /* Chain onto the start of the hash chain (in the hope we will be used first). */
+ new_mode_p->next_offset = mode_array[hash_entry];
+ mode_array[hash_entry] = new_offset;
+
+ file_scanner_p = new_mode_p;
+
+ DEBUG(3,("set_share_mode: Created share record for %s (dev %x inode %.0f)\n",
+ fsp->fsp_name, (unsigned int)dev, (double)inode));
+ }
+
+ /* Now create the share mode entry */
+ new_entry_offset = shmops->shm_alloc(sizeof(shm_share_mode_entry));
+ if(new_entry_offset == 0) {
+ int delete_offset = mode_array[hash_entry];
+ DEBUG(0,("ERROR:set_share_mode: shmops->shm_alloc fail 1!\n"));
+ /* Unlink the damaged record */
+ mode_array[hash_entry] = file_scanner_p->next_offset;
+ /* And delete it */
+ shmops->shm_free( delete_offset );
+ return False;
+ }
+
+ new_entry_p = shmops->offset2addr(new_entry_offset);
+
+ new_entry_p->e.pid = getpid();
+ new_entry_p->e.share_mode = fsp->share_mode;
+ new_entry_p->e.op_port = port;
+ new_entry_p->e.op_type = op_type;
+ memcpy( (char *)&new_entry_p->e.time, (char *)&fsp->open_time, sizeof(struct timeval));
+
+ /* Chain onto the share_mode_record */
+ new_entry_p->next_share_mode_entry = file_scanner_p->share_mode_entries;
+ file_scanner_p->share_mode_entries = new_entry_offset;
+
+ /* PARANOIA TEST */
+ if(file_scanner_p->num_share_mode_entries < 0)
+ {
+ DEBUG(0,("PANIC ERROR:set_share_mode num_share_mode_entries=%d\n",
+ file_scanner_p->num_share_mode_entries));
+ return False;
+ }
+
+ /* Increment the share_mode_entries counter */
+ file_scanner_p->num_share_mode_entries += 1;
+
+ DEBUG(3,("set_share_mode: Created share entry for %s with mode 0x%X pid=%d\n",
+ fsp->fsp_name, fsp->share_mode, new_entry_p->e.pid));
+
+ return(True);
+}
+
+/*******************************************************************
+ Call a generic modify function for a share mode entry.
+********************************************************************/
+
+static BOOL shm_mod_share_entry(int token, files_struct *fsp,
+ void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
+ void *param)
+{
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
+ int *mode_array;
+ unsigned int hash_entry;
+ share_mode_record *file_scanner_p;
+ share_mode_record *file_prev_p;
+ shm_share_mode_entry *entry_scanner_p;
+ BOOL found = False;
+ int pid = getpid();
+
+ dev = fsp->fd_ptr->dev;
+ inode = fsp->fd_ptr->inode;
+
+ hash_entry = HASH_ENTRY(dev, inode);
+
+ mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
+
+ if(mode_array[hash_entry] == 0)
+ {
+ DEBUG(0,("PANIC ERROR:modify_share_entry: hash bucket %d empty\n",
+ hash_entry));
+ return False;
+ }
+
+ file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[hash_entry]);
+ file_prev_p = file_scanner_p;
+
+ while(file_scanner_p)
+ {
+ if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) )
+ {
+ found = True;
+ break;
+ }
+ else
+ {
+ file_prev_p = file_scanner_p ;
+ file_scanner_p = (share_mode_record *)
+ shmops->offset2addr(file_scanner_p->next_offset);
+ }
+ }
+
+ if(!found)
+ {
+ DEBUG(0,("ERROR:modify_share_entry: no entry found for dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode));
+ return False;
+ }
+
+ if(file_scanner_p->locking_version != LOCKING_VERSION)
+ {
+ DEBUG(0,("ERROR: modify_share_entry: Deleting old share mode v1=%d dev=%x ino=%.0f\n",
+ file_scanner_p->locking_version, (unsigned int)dev, (double)inode));
+
+ if(file_prev_p == file_scanner_p)
+ mode_array[hash_entry] = file_scanner_p->next_offset;
+ else
+ file_prev_p->next_offset = file_scanner_p->next_offset;
+ shmops->shm_free(shmops->addr2offset(file_scanner_p));
+ return False;
+ }
+
+ found = False;
+ entry_scanner_p = (shm_share_mode_entry*)shmops->offset2addr(
+ file_scanner_p->share_mode_entries);
+ while(entry_scanner_p)
+ {
+ if( (pid == entry_scanner_p->e.pid) &&
+ (entry_scanner_p->e.share_mode == fsp->share_mode) &&
+ (memcmp(&entry_scanner_p->e.time,
+ &fsp->open_time,sizeof(struct timeval)) == 0) )
+ {
+ /*
+ * Call the generic function with the given parameter.
+ */
+
+ DEBUG(5,("modify_share_entry: Calling generic function to modify entry for dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode));
+
+ (*mod_fn)( &entry_scanner_p->e, dev, inode, param);
+ found = True;
+ break;
+ }
+ else
+ {
+ entry_scanner_p = (shm_share_mode_entry *)
+ shmops->offset2addr(entry_scanner_p->next_share_mode_entry);
+ }
+ }
+
+ if(!found)
+ {
+ DEBUG(0,("ERROR: modify_share_entry: No entry found for dev=%x ino=%.0f\n",
+ (unsigned int)dev, (double)inode));
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+call the specified function on each entry under management by the
+share mode system
+********************************************************************/
+static int shm_share_forall(void (*fn)(share_mode_entry *, char *))
+{
+ int i, count=0;
+ int *mode_array;
+ share_mode_record *file_scanner_p;
+
+ mode_array = (int *)shmops->offset2addr(shmops->get_userdef_off());
+
+ for( i = 0; i < shmops->hash_size(); i++) {
+ shmops->lock_hash_entry(i);
+ if(mode_array[i] == 0) {
+ shmops->unlock_hash_entry(i);
+ continue;
+ }
+
+ file_scanner_p = (share_mode_record *)shmops->offset2addr(mode_array[i]);
+ while((file_scanner_p != 0) &&
+ (file_scanner_p->num_share_mode_entries != 0)) {
+ shm_share_mode_entry *entry_scanner_p =
+ (shm_share_mode_entry *)
+ shmops->offset2addr(file_scanner_p->share_mode_entries);
+
+ while(entry_scanner_p != 0) {
+
+ if (process_exists(entry_scanner_p->e.pid)) {
+ fn(&entry_scanner_p->e,
+ file_scanner_p->file_name);
+ count++;
+ }
+
+ entry_scanner_p =
+ (shm_share_mode_entry *)
+ shmops->offset2addr(
+ entry_scanner_p->next_share_mode_entry);
+ } /* end while entry_scanner_p */
+ file_scanner_p = (share_mode_record *)
+ shmops->offset2addr(file_scanner_p->next_offset);
+ } /* end while file_scanner_p */
+ shmops->unlock_hash_entry(i);
+ } /* end for */
+
+ return count;
+}
+
+
+/*******************************************************************
+dump the state of the system
+********************************************************************/
+static void shm_share_status(FILE *f)
+{
+ int bytes_free, bytes_used, bytes_overhead, bytes_total;
+
+ shmops->get_usage(&bytes_free, &bytes_used, &bytes_overhead);
+ bytes_total = bytes_free + bytes_used + bytes_overhead;
+
+ fprintf(f, "Share mode memory usage (bytes):\n");
+ fprintf(f, " %d(%d%%) free + %d(%d%%) used + %d(%d%%) overhead = %d(100%%) total\n",
+ bytes_free, (bytes_free * 100)/bytes_total,
+ bytes_used, (bytes_used * 100)/bytes_total,
+ bytes_overhead, (bytes_overhead * 100)/bytes_total,
+ bytes_total);
+}
+
+
+static struct share_ops share_ops = {
+ shm_stop_share_mode_mgmt,
+ shm_lock_share_entry,
+ shm_unlock_share_entry,
+ shm_get_share_modes,
+ shm_del_share_mode,
+ shm_set_share_mode,
+ shm_mod_share_entry,
+ shm_share_forall,
+ shm_share_status,
+};
+
+/*******************************************************************
+ initialize the shared memory for share_mode management
+ ******************************************************************/
+struct share_ops *locking_shm_init(int ronly)
+{
+ read_only = ronly;
+
+#ifdef HAVE_SYSV_IPC
+ shmops = sysv_shm_open(read_only);
+ if (shmops) return &share_ops;
+#endif
+
+#ifdef HAVE_SHARED_MMAP
+ shmops = smb_shm_open(read_only);
+ if (shmops) return &share_ops;
+#endif
+
+ return NULL;
+}
+
+#else
+ int locking_shm_dummy_procedure(void)
+{return 0;}
+#endif /* FAST_SHARE_MODES */
diff --git a/source/locking/locking_slow.c b/source/locking/locking_slow.c
new file mode 100644
index 00000000000..64bedca4ad2
--- /dev/null
+++ b/source/locking/locking_slow.c
@@ -0,0 +1,1098 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ slow (lockfile) locking implementation
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ Revision History:
+
+ 12 aug 96: Erik.Devriendt@te6.siemens.be
+ added support for shared memory implementation of share mode locking
+
+ May 1997. Jeremy Allison (jallison@whistle.com). Modified share mode
+ locking to deal with multiple share modes per open file.
+
+ September 1997. Jeremy Allison (jallison@whistle.com). Added oplock
+ support.
+
+ October 1997 - split into separate file (tridge)
+*/
+
+#include "includes.h"
+
+#ifndef FAST_SHARE_MODES
+
+extern int DEBUGLEVEL;
+
+/*
+ * Locking file header lengths & offsets.
+ */
+#define SMF_VERSION_OFFSET 0
+#define SMF_NUM_ENTRIES_OFFSET 4
+#define SMF_FILENAME_LEN_OFFSET 8
+#define SMF_HEADER_LENGTH 10
+
+#define SMF_ENTRY_LENGTH 20
+
+/*
+ * Share mode record offsets.
+ */
+
+#define SME_SEC_OFFSET 0
+#define SME_USEC_OFFSET 4
+#define SME_SHAREMODE_OFFSET 8
+#define SME_PID_OFFSET 12
+#define SME_PORT_OFFSET 16
+#define SME_OPLOCK_TYPE_OFFSET 18
+
+/* we need world read for smbstatus to function correctly */
+#ifdef SECURE_SHARE_MODES
+#define SHARE_FILE_MODE 0600
+#else
+#define SHARE_FILE_MODE 0644
+#endif
+
+static int read_only;
+
+/*******************************************************************
+ deinitialize share_mode management
+ ******************************************************************/
+static BOOL slow_stop_share_mode_mgmt(void)
+{
+ return True;
+}
+
+
+/*******************************************************************
+ name a share file
+ ******************************************************************/
+static BOOL share_name(connection_struct *conn,
+ SMB_DEV_T dev, SMB_INO_T inode, char *name)
+{
+ int len;
+ pstrcpy(name,lp_lockdir());
+ trim_string(name,"","/");
+ if (!*name) return(False);
+ len = strlen(name);
+ name += len;
+
+#ifdef LARGE_SMB_INO_T
+ slprintf(name, sizeof(pstring) - len - 1, "/share.%u.%.0f",(unsigned int)dev,(double)inode);
+#else /* LARGE_SMB_INO_T */
+ slprintf(name, sizeof(pstring) - len - 1, "/share.%u.%lu",(unsigned int)dev,(unsigned long)inode);
+#endif /* LARGE_SMB_INO_T */
+ return(True);
+}
+
+/*******************************************************************
+Force a share file to be deleted.
+********************************************************************/
+static int delete_share_file(connection_struct *conn, char *fname )
+{
+ if (read_only) return -1;
+
+ /* the share file could be owned by anyone, so do this as root */
+ become_root(False);
+
+ if(unlink(fname) != 0)
+ {
+ DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n",
+ fname, strerror(errno)));
+ }
+ else
+ {
+ DEBUG(5,("delete_share_file: Deleted share file %s\n", fname));
+ }
+
+ /* return to our previous privilage level */
+ unbecome_root(False);
+
+ return 0;
+}
+
+/*******************************************************************
+ lock a share mode file.
+ ******************************************************************/
+static BOOL slow_lock_share_entry(connection_struct *conn,
+ SMB_DEV_T dev, SMB_INO_T inode, int *ptok)
+{
+ pstring fname;
+ int fd;
+ int ret = True;
+
+ *ptok = (int)-1;
+
+ if(!share_name(conn, dev, inode, fname))
+ return False;
+
+ if (read_only) return True;
+
+ /* we need to do this as root */
+ become_root(False);
+
+ {
+ BOOL gotlock = False;
+ /*
+ * There was a race condition in the original slow share mode code.
+ * A smbd could open a share mode file, and before getting
+ * the lock, another smbd could delete the last entry for
+ * the share mode file and delete the file entry from the
+ * directory. Thus this smbd would be left with a locked
+ * share mode fd attached to a file that no longer had a
+ * directory entry. Thus another smbd would think that
+ * there were no outstanding opens on the file. To fix
+ * this we now check we can do a stat() call on the filename
+ * before allowing the lock to proceed, and back out completely
+ * and try the open again if we cannot.
+ * Jeremy Allison (jallison@whistle.com).
+ */
+
+ do
+ {
+ SMB_STRUCT_STAT dummy_stat;
+
+ fd = sys_open(fname,read_only?O_RDONLY:(O_RDWR|O_CREAT), SHARE_FILE_MODE);
+
+ if(fd < 0)
+ {
+ DEBUG(0,("ERROR lock_share_entry: failed to open share file %s. Error was %s\n",
+ fname, strerror(errno)));
+ ret = False;
+ break;
+ }
+
+ /* At this point we have an open fd to the share mode file.
+ Lock the first byte exclusively to signify a lock. */
+ if(conn->vfs_ops.lock(fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False)
+ {
+ DEBUG(0,("ERROR lock_share_entry: fcntl_lock on file %s failed with %s\n",
+ fname, strerror(errno)));
+ close(fd);
+ ret = False;
+ break;
+ }
+
+ /*
+ * If we cannot stat the filename, the file was deleted between
+ * the open and the lock call. Back out and try again.
+ */
+
+ if(sys_stat(fname, &dummy_stat)!=0)
+ {
+ DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n",
+ fname, strerror(errno)));
+ close(fd);
+ }
+ else
+ gotlock = True;
+ } while(!gotlock);
+
+ /*
+ * We have to come here if any of the above calls fail
+ * as we don't want to return and leave ourselves running
+ * as root !
+ */
+ }
+
+ *ptok = (int)fd;
+
+ /* return to our previous privilage level */
+ unbecome_root(False);
+
+ return ret;
+}
+
+/*******************************************************************
+ unlock a share mode file.
+ ******************************************************************/
+static BOOL slow_unlock_share_entry(connection_struct *conn,
+ SMB_DEV_T dev, SMB_INO_T inode, int token)
+{
+ int fd = token;
+ int ret = True;
+ SMB_STRUCT_STAT sb;
+ pstring fname;
+
+ if (read_only) return True;
+
+ /* Fix for zero length share files from
+ Gerald Werner <wernerg@mfldclin.edu> */
+
+ share_name(conn, dev, inode, fname);
+
+ /* get the share mode file size */
+ if(sys_fstat((int)token, &sb) != 0)
+ {
+ DEBUG(0,("ERROR: unlock_share_entry: Failed to do stat on share file %s (%s)\n",
+ fname, strerror(errno)));
+ sb.st_size = 1;
+ ret = False;
+ }
+
+ /* If the file was zero length, we must delete before
+ doing the unlock to avoid a race condition (see
+ the code in lock_share_mode_entry for details.
+ */
+
+ /* remove the share file if zero length */
+ if(sb.st_size == 0)
+ delete_share_file(conn, fname);
+
+ /* token is the fd of the open share mode file. */
+ /* Unlock the first byte. */
+ if(conn->vfs_ops.lock(fd, SMB_F_SETLKW, 0, 1, F_UNLCK) == False)
+ {
+ DEBUG(0,("ERROR unlock_share_entry: fcntl_lock failed with %s\n",
+ strerror(errno)));
+ ret = False;
+ }
+
+ close(fd);
+ return ret;
+}
+
+/*******************************************************************
+Read a share file into a buffer.
+********************************************************************/
+static int read_share_file(connection_struct *conn, int fd, char *fname, char **out, BOOL *p_new_file)
+{
+ SMB_STRUCT_STAT sb;
+ char *buf;
+ SMB_OFF_T size;
+
+ *out = 0;
+ *p_new_file = False;
+
+ if(sys_fstat(fd, &sb) != 0)
+ {
+ DEBUG(0,("ERROR: read_share_file: Failed to do stat on share file %s (%s)\n",
+ fname, strerror(errno)));
+ return -1;
+ }
+
+ if(sb.st_size == 0)
+ {
+ *p_new_file = True;
+ return 0;
+ }
+
+ /* Allocate space for the file */
+ if((buf = (char *)malloc((size_t)sb.st_size)) == NULL)
+ {
+ DEBUG(0,("read_share_file: malloc for file size %d fail !\n",
+ (int)sb.st_size));
+ return -1;
+ }
+
+ if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
+ {
+ DEBUG(0,("ERROR: read_share_file: Failed to reset position to 0 \
+for share file %s (%s)\n", fname, strerror(errno)));
+ if(buf)
+ free(buf);
+ return -1;
+ }
+
+ if (read(fd,buf,(size_t)sb.st_size) != (size_t)sb.st_size)
+ {
+ DEBUG(0,("ERROR: read_share_file: Failed to read share file %s (%s)\n",
+ fname, strerror(errno)));
+ if(buf)
+ free(buf);
+ return -1;
+ }
+
+ if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) {
+ DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \
+locking version (was %d, should be %d).\n",fname,
+ IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION));
+ if(buf)
+ free(buf);
+ delete_share_file(conn, fname);
+ return -1;
+ }
+
+ /* Sanity check for file contents */
+ size = sb.st_size;
+ size -= SMF_HEADER_LENGTH; /* Remove the header */
+
+ /* Remove the filename component. */
+ size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET);
+
+ /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
+ if((size % SMF_ENTRY_LENGTH) != 0)
+ {
+ DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \
+deleting it.\n", fname));
+ if(buf)
+ free(buf);
+ delete_share_file(conn, fname);
+ return -1;
+ }
+
+ *out = buf;
+ return 0;
+}
+
+/*******************************************************************
+get all share mode entries in a share file for a dev/inode pair.
+********************************************************************/
+static int slow_get_share_modes(connection_struct *conn, int token,
+ SMB_DEV_T dev, SMB_INO_T inode,
+ share_mode_entry **old_shares)
+{
+ int fd = token;
+ pstring fname;
+ int i;
+ int num_entries;
+ int num_entries_copied;
+ int newsize;
+ share_mode_entry *share_array;
+ char *buf = 0;
+ char *base = 0;
+ BOOL new_file;
+
+ *old_shares = 0;
+
+ /* Read the share file header - this is of the form:
+ 0 - locking version.
+ 4 - number of share mode entries.
+ 8 - 2 byte name length
+ [n bytes] file name (zero terminated).
+
+ Followed by <n> share mode entries of the form :
+
+ 0 - tv_sec
+ 4 - tv_usec
+ 8 - share_mode
+ 12 - pid
+ 16 - oplock port (if oplocks in use) - 2 bytes.
+ */
+
+ share_name(conn, dev, inode, fname);
+
+ if(read_share_file( conn, fd, fname, &buf, &new_file) != 0)
+ {
+ DEBUG(0,("ERROR: get_share_modes: Failed to read share file %s\n",
+ fname));
+ return 0;
+ }
+
+ if(new_file == True)
+ return 0;
+
+ num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
+
+ DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n",
+ fname, num_entries));
+
+ /* PARANOIA TEST */
+ if(num_entries < 0)
+ {
+ DEBUG(0,("PANIC ERROR:get_share_mode: num_share_mode_entries < 0 (%d) \
+for share file %s\n", num_entries, fname));
+ return 0;
+ }
+
+ if(num_entries)
+ {
+ *old_shares = share_array = (share_mode_entry *)
+ malloc(num_entries * sizeof(share_mode_entry));
+ if(*old_shares == 0)
+ {
+ DEBUG(0,("get_share_modes: malloc fail !\n"));
+ return 0;
+ }
+ }
+ else
+ {
+ /* No entries - just delete the file. */
+ DEBUG(0,("get_share_modes: share file %s has no share mode entries - deleting.\n",
+ fname));
+ if(buf)
+ free(buf);
+ delete_share_file(conn, fname);
+ return 0;
+ }
+
+ num_entries_copied = 0;
+ base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
+
+ for( i = 0; i < num_entries; i++)
+ {
+ int pid;
+ char *p = base + (i*SMF_ENTRY_LENGTH);
+
+ pid = IVAL(p,SME_PID_OFFSET);
+
+ if(!process_exists(pid))
+ {
+ DEBUG(0,("get_share_modes: process %d no longer exists and \
+it left a share mode entry with mode 0x%X in share file %s\n",
+ pid, IVAL(p,SME_SHAREMODE_OFFSET), fname));
+ continue;
+ }
+ share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET);
+ share_array[num_entries_copied].time.tv_usec = IVAL(p,SME_USEC_OFFSET);
+ share_array[num_entries_copied].share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
+ share_array[num_entries_copied].pid = pid;
+ share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET);
+ share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
+
+ num_entries_copied++;
+ }
+
+ if(num_entries_copied == 0)
+ {
+ /* Delete the whole file. */
+ DEBUG(0,("get_share_modes: share file %s had no valid entries - deleting it !\n",
+ fname));
+ if(*old_shares)
+ free((char *)*old_shares);
+ *old_shares = 0;
+ if(buf)
+ free(buf);
+ delete_share_file(conn, fname);
+ return 0;
+ }
+
+ /* If we deleted some entries we need to re-write the whole number of
+ share mode entries back into the file. */
+
+ if(num_entries_copied != num_entries)
+ {
+ if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
+ {
+ DEBUG(0,("ERROR: get_share_modes: lseek failed to reset to \
+position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
+ if(*old_shares)
+ free((char *)*old_shares);
+ *old_shares = 0;
+ if(buf)
+ free(buf);
+ return 0;
+ }
+
+ SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, num_entries_copied);
+ for( i = 0; i < num_entries_copied; i++)
+ {
+ char *p = base + (i*SMF_ENTRY_LENGTH);
+
+ SIVAL(p,SME_PID_OFFSET,share_array[i].pid);
+ SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode);
+ SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec);
+ SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec);
+ SSVAL(p,SME_PORT_OFFSET,share_array[i].op_port);
+ SSVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type);
+ }
+
+ newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied);
+ if(write(fd, buf, newsize) != newsize)
+ {
+ DEBUG(0,("ERROR: get_share_modes: failed to re-write share \
+mode file %s (%s)\n", fname, strerror(errno)));
+ if(*old_shares)
+ free((char *)*old_shares);
+ *old_shares = 0;
+ if(buf)
+ free(buf);
+ return 0;
+ }
+ /* Now truncate the file at this point. */
+ if(sys_ftruncate(fd, (SMB_OFF_T)newsize)!= 0)
+ {
+ DEBUG(0,("ERROR: get_share_modes: failed to ftruncate share \
+mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
+ if(*old_shares)
+ free((char *)*old_shares);
+ *old_shares = 0;
+ if(buf)
+ free(buf);
+ return 0;
+ }
+ }
+
+ if(buf)
+ free(buf);
+
+ DEBUG(5,("get_share_modes: Read share file %s returning %d entries\n",fname,
+ num_entries_copied));
+
+ return num_entries_copied;
+}
+
+/*******************************************************************
+del a share mode from a share mode file.
+********************************************************************/
+static void slow_del_share_mode(int token, files_struct *fsp)
+{
+ pstring fname;
+ int fd = (int)token;
+ char *buf = 0;
+ char *base = 0;
+ int num_entries;
+ int newsize;
+ int i;
+ int pid;
+ BOOL deleted = False;
+ BOOL new_file;
+
+ share_name(fsp->conn, fsp->fd_ptr->dev,
+ fsp->fd_ptr->inode, fname);
+
+ if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0)
+ {
+ DEBUG(0,("ERROR: del_share_mode: Failed to read share file %s\n",
+ fname));
+ return;
+ }
+
+ if(new_file == True)
+ {
+ DEBUG(0,("ERROR:del_share_mode: share file %s is new (size zero), deleting it.\n",
+ fname));
+ delete_share_file(fsp->conn, fname);
+ return;
+ }
+
+ num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
+
+ DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n",
+ fname, num_entries));
+
+ /* PARANOIA TEST */
+ if(num_entries < 0)
+ {
+ DEBUG(0,("PANIC ERROR:del_share_mode: num_share_mode_entries < 0 (%d) \
+for share file %s\n", num_entries, fname));
+ return;
+ }
+
+ if(num_entries == 0)
+ {
+ /* No entries - just delete the file. */
+ DEBUG(0,("del_share_mode: share file %s has no share mode entries - deleting.\n",
+ fname));
+ if(buf)
+ free(buf);
+ delete_share_file(fsp->conn, fname);
+ return;
+ }
+
+ pid = getpid();
+
+ /* Go through the entries looking for the particular one
+ we have set - delete it.
+ */
+
+ base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
+
+ for(i = 0; i < num_entries; i++)
+ {
+ char *p = base + (i*SMF_ENTRY_LENGTH);
+
+ if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) ||
+ (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) ||
+ (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) ||
+ (IVAL(p,SME_PID_OFFSET) != pid))
+ continue;
+
+ DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n",
+ i, num_entries, fname));
+
+ /* Remove this entry. */
+ if(i != num_entries - 1)
+ memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH);
+
+ deleted = True;
+ break;
+ }
+
+ if(!deleted)
+ {
+ DEBUG(0,("del_share_mode: entry not found in share file %s\n", fname));
+ if(buf)
+ free(buf);
+ return;
+ }
+
+ num_entries--;
+ SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries);
+
+ if(num_entries == 0)
+ {
+ /* Deleted the last entry - remove the file. */
+ DEBUG(5,("del_share_mode: removed last entry in share file - deleting share file %s\n",
+ fname));
+ if(buf)
+ free(buf);
+ delete_share_file(fsp->conn,fname);
+ return;
+ }
+
+ /* Re-write the file - and truncate it at the correct point. */
+ if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
+ {
+ DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \
+position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
+ if(buf)
+ free(buf);
+ return;
+ }
+
+ newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
+ if(write(fd, buf, newsize) != newsize)
+ {
+ DEBUG(0,("ERROR: del_share_mode: failed to re-write share \
+mode file %s (%s)\n", fname, strerror(errno)));
+ if(buf)
+ free(buf);
+ return;
+ }
+
+ /* Now truncate the file at this point. */
+ if(sys_ftruncate(fd, (SMB_OFF_T)newsize) != 0)
+ {
+ DEBUG(0,("ERROR: del_share_mode: failed to ftruncate share \
+mode file %s to size %d (%s)\n", fname, newsize, strerror(errno)));
+ if(buf)
+ free(buf);
+ return;
+ }
+}
+
+/*******************************************************************
+set the share mode of a file
+********************************************************************/
+static BOOL slow_set_share_mode(int token,files_struct *fsp, uint16 port, uint16 op_type)
+{
+ pstring fname;
+ int fd = (int)token;
+ int pid = (int)getpid();
+ SMB_STRUCT_STAT sb;
+ char *buf;
+ int num_entries;
+ int header_size;
+ char *p;
+
+ share_name(fsp->conn, fsp->fd_ptr->dev,
+ fsp->fd_ptr->inode, fname);
+
+ if(fsp->conn->vfs_ops.fstat_file(fd, &sb) != 0)
+ {
+ DEBUG(0,("ERROR: set_share_mode: Failed to do stat on share file %s\n",
+ fname));
+ return False;
+ }
+
+ /* Sanity check for file contents (if it's not a new share file). */
+ if(sb.st_size != 0)
+ {
+ SMB_OFF_T size = sb.st_size;
+
+ /* Allocate space for the file plus one extra entry */
+ if((buf = (char *)malloc((size_t)(sb.st_size + SMF_ENTRY_LENGTH))) == NULL)
+ {
+ DEBUG(0,("set_share_mode: malloc for file size %d fail !\n",
+ (int)(sb.st_size + SMF_ENTRY_LENGTH)));
+ return False;
+ }
+
+ if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
+ {
+ DEBUG(0,("ERROR: set_share_mode: Failed to reset position \
+to 0 for share file %s (%s)\n", fname, strerror(errno)));
+ if(buf)
+ free(buf);
+ return False;
+ }
+
+ if (read(fd,buf,(size_t)sb.st_size) != (size_t)sb.st_size)
+ {
+ DEBUG(0,("ERROR: set_share_mode: Failed to read share file %s (%s)\n",
+ fname, strerror(errno)));
+ if(buf)
+ free(buf);
+ return False;
+ }
+
+ if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION)
+ {
+ DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \
+locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET),
+ LOCKING_VERSION));
+ if(buf)
+ free(buf);
+ delete_share_file(fsp->conn, fname);
+ return False;
+ }
+
+ size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */
+
+ /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */
+ if((size % SMF_ENTRY_LENGTH) != 0)
+ {
+ DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \
+deleting it.\n", fname));
+ if(buf)
+ free(buf);
+ delete_share_file(fsp->conn, fname);
+ return False;
+ }
+
+ }
+ else
+ {
+ /* New file - just use a single_entry. */
+ if((buf = (char *)malloc(SMF_HEADER_LENGTH +
+ strlen(fsp->fsp_name) + 1 + SMF_ENTRY_LENGTH)) == NULL)
+ {
+ DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n"));
+ return False;
+ }
+ SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION);
+ SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0);
+ SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fsp->fsp_name) + 1);
+ pstrcpy(buf + SMF_HEADER_LENGTH, fsp->fsp_name);
+ }
+
+ num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
+ header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
+ p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH);
+ SIVAL(p,SME_SEC_OFFSET,fsp->open_time.tv_sec);
+ SIVAL(p,SME_USEC_OFFSET,fsp->open_time.tv_usec);
+ SIVAL(p,SME_SHAREMODE_OFFSET,fsp->share_mode);
+ SIVAL(p,SME_PID_OFFSET,pid);
+ SSVAL(p,SME_PORT_OFFSET,port);
+ SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type);
+
+ num_entries++;
+
+ SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries);
+
+ if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
+ {
+ DEBUG(0,("ERROR: set_share_mode: (1) Failed to reset position to \
+0 for share file %s (%s)\n", fname, strerror(errno)));
+ if(buf)
+ free(buf);
+ return False;
+ }
+
+ if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) !=
+ (header_size + (num_entries*SMF_ENTRY_LENGTH)))
+ {
+ DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \
+deleting it (%s).\n",fname, strerror(errno)));
+ delete_share_file(fsp->conn, fname);
+ if(buf)
+ free(buf);
+ return False;
+ }
+
+ /* Now truncate the file at this point - just for safety. */
+
+ if(sys_ftruncate(fd, (SMB_OFF_T)(header_size + (SMF_ENTRY_LENGTH*num_entries)))!= 0)
+ {
+ DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \
+mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries),
+ strerror(errno)));
+ if(buf)
+ free(buf);
+ return False;
+ }
+
+ if(buf)
+ free(buf);
+
+ DEBUG(3,("set_share_mode: Created share file %s with \
+mode 0x%X pid=%d\n",fname,fsp->share_mode,pid));
+
+ return True;
+}
+
+/*******************************************************************
+ Call a generic modify function for a share mode entry.
+********************************************************************/
+
+static BOOL slow_mod_share_entry(int token, files_struct *fsp,
+ void (*mod_fn)(share_mode_entry *, SMB_DEV_T, SMB_INO_T, void *),
+ void *param)
+{
+ pstring fname;
+ int fd = (int)token;
+ char *buf = 0;
+ char *base = 0;
+ int num_entries;
+ int fsize;
+ int i;
+ int pid;
+ BOOL found = False;
+ BOOL new_file;
+ share_mode_entry entry;
+
+ share_name(fsp->conn, fsp->fd_ptr->dev,
+ fsp->fd_ptr->inode, fname);
+
+ if(read_share_file( fsp->conn, fd, fname, &buf, &new_file) != 0)
+ {
+ DEBUG(0,("ERROR: slow_mod_share_entry: Failed to read share file %s\n",
+ fname));
+ return False;
+ }
+
+ if(new_file == True)
+ {
+ DEBUG(0,("ERROR: slow_mod_share_entry: share file %s is new (size zero), \
+deleting it.\n", fname));
+ delete_share_file(fsp->conn, fname);
+ return False;
+ }
+
+ num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET);
+
+ DEBUG(5,("slow_mod_share_entry: share file %s has %d share mode entries.\n",
+ fname, num_entries));
+
+ /* PARANOIA TEST */
+ if(num_entries < 0)
+ {
+ DEBUG(0,("PANIC ERROR:slow_mod_share_entry: num_share_mode_entries < 0 (%d) \
+for share file %s\n", num_entries, fname));
+ return False;
+ }
+
+ if(num_entries == 0)
+ {
+ /* No entries - just delete the file. */
+ DEBUG(0,("slow_mod_share_entry: share file %s has no share mode entries - deleting.\n",
+ fname));
+ if(buf)
+ free(buf);
+ delete_share_file(fsp->conn, fname);
+ return False;
+ }
+
+ pid = getpid();
+
+ base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET);
+
+ for(i = 0; i < num_entries; i++)
+ {
+ char *p = base + (i*SMF_ENTRY_LENGTH);
+
+ if((IVAL(p,SME_SEC_OFFSET) != fsp->open_time.tv_sec) ||
+ (IVAL(p,SME_USEC_OFFSET) != fsp->open_time.tv_usec) ||
+ (IVAL(p,SME_SHAREMODE_OFFSET) != fsp->share_mode) ||
+ (IVAL(p,SME_PID_OFFSET) != pid))
+ continue;
+
+ DEBUG(5,("slow_mod_share_entry: Calling generic function to modify entry number %d (of %d) \
+from the share file %s\n", i, num_entries, fname));
+
+ /*
+ * Copy into the share_mode_entry structure and then call
+ * the generic function with the given parameter.
+ */
+
+ entry.pid = IVAL(p,SME_PID_OFFSET);
+ entry.op_port = SVAL(p,SME_PORT_OFFSET);
+ entry.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
+ entry.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
+ entry.time.tv_sec = IVAL(p,SME_SEC_OFFSET)
+ entry.time.tv_sec = IVAL(p,SME_USEC_OFFSET);
+
+ (*mod_fn)( &entry, fsp->fd_ptr->dev, fsp->fd_ptr->inode, param);
+
+ /*
+ * Now copy any changes the function made back into the buffer.
+ */
+
+ SIVAL(p,SME_PID_OFFSET, entry.pid)
+ SSVAL(p,SME_PORT_OFFSET,entry.op_port);
+ SSVAL(p,SME_OPLOCK_TYPE_OFFSET,entry.op_type);
+ SIVAL(p,SME_SHAREMODE_OFFSET,entry.share_mode);
+ SIVAL(p,SME_SEC_OFFSET,entry.time.tv_sec)
+ SIVAL(p,SME_USEC_OFFSET,entry.time.tv_sec);
+
+ found = True;
+ break;
+ }
+
+ if(!found)
+ {
+ DEBUG(0,("slow_mod_share_entry: entry not found in share file %s\n", fname));
+ if(buf)
+ free(buf);
+ return False;
+ }
+
+ /* Re-write the file - and truncate it at the correct point. */
+ if(sys_lseek(fd, (SMB_OFF_T)0, SEEK_SET) != 0)
+ {
+ DEBUG(0,("ERROR: slow_mod_share_entry: lseek failed to reset to \
+position 0 for share mode file %s (%s)\n", fname, strerror(errno)));
+ if(buf)
+ free(buf);
+ return False;
+ }
+
+ fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries);
+ if(write(fd, buf, fsize) != fsize)
+ {
+ DEBUG(0,("ERROR: slow_mod_share_entry: failed to re-write share \
+mode file %s (%s)\n", fname, strerror(errno)));
+ if(buf)
+ free(buf);
+ return False;
+ }
+
+ return True;
+}
+
+
+
+/*******************************************************************
+call the specified function on each entry under management by the
+share ode system
+********************************************************************/
+static int slow_share_forall(void (*fn)(share_mode_entry *, char *))
+{
+ int i, count=0;
+ DIR *dir;
+ char *s;
+ share_mode_entry e;
+
+ dir = opendir(lp_lockdir());
+ if (!dir) {
+ return(0);
+ }
+
+ while ((s=readdirname(dir))) {
+ char *buf;
+ char *base;
+ int fd;
+ pstring lname;
+ SMB_DEV_T dev;
+ SMB_INO_T inode;
+ BOOL new_file;
+ pstring fname;
+
+#ifdef LARGE_SMB_INO_T
+ double inode_ascii;
+ if (sscanf(s,"share.%u.%lf",&dev,&inode_ascii)!=2) continue;
+ inode = (SMB_INO_T)inode_ascii;
+#else /* LARGE_SMB_INO_T */
+ unsigned long inode_long;
+ if (sscanf(s,"share.%u.%lu",&dev,&inode_long)!=2) continue;
+ inode = (SMB_INO_T)inode_long;
+#endif /* LARGE_SMB_INO_T */
+
+ pstrcpy(lname,lp_lockdir());
+ trim_string(lname,NULL,"/");
+ pstrcat(lname,"/");
+ pstrcat(lname,s);
+
+ fd = sys_open(lname,read_only?O_RDONLY:O_RDWR,0);
+ if (fd < 0) {
+ continue;
+ }
+
+ /* Lock the share mode file while we read it. */
+ if(!read_only &&
+ fcntl_lock(fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False) {
+ close(fd);
+ continue;
+ }
+
+ if(read_share_file( 0, fd, lname, &buf, &new_file)) {
+ close(fd);
+ continue;
+ }
+ pstrcpy( fname, &buf[10]);
+ close(fd);
+
+ base = buf + SMF_HEADER_LENGTH +
+ SVAL(buf,SMF_FILENAME_LEN_OFFSET);
+ for( i = 0; i < IVAL(buf, SMF_NUM_ENTRIES_OFFSET); i++) {
+ char *p = base + (i*SMF_ENTRY_LENGTH);
+ e.pid = IVAL(p,SME_PID_OFFSET);
+ e.share_mode = IVAL(p,SME_SHAREMODE_OFFSET);
+ e.time.tv_sec = IVAL(p,SME_SEC_OFFSET);
+ e.time.tv_usec = IVAL(p,SME_USEC_OFFSET);
+ e.op_port = SVAL(p,SME_PORT_OFFSET);
+ e.pid = SVAL(p,SME_PID_OFFSET);
+ e.op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET);
+
+ if (process_exists(e.pid)) {
+ fn(&e, fname);
+ count++;
+ }
+ } /* end for i */
+
+ if(buf)
+ free(buf);
+ base = 0;
+ } /* end while */
+ closedir(dir);
+
+ return count;
+}
+
+
+/*******************************************************************
+dump the state of the system
+********************************************************************/
+static void slow_share_status(FILE *f)
+{
+
+}
+
+
+static struct share_ops share_ops = {
+ slow_stop_share_mode_mgmt,
+ slow_lock_share_entry,
+ slow_unlock_share_entry,
+ slow_get_share_modes,
+ slow_del_share_mode,
+ slow_set_share_mode,
+ slow_mod_share_entry,
+ slow_share_forall,
+ slow_share_status,
+};
+
+/*******************************************************************
+ initialize the slow share_mode management
+ ******************************************************************/
+struct share_ops *locking_slow_init(int ronly)
+{
+
+ read_only = ronly;
+
+ if (!directory_exist(lp_lockdir(),NULL)) {
+ if (!read_only)
+ mkdir(lp_lockdir(),0755);
+ if (!directory_exist(lp_lockdir(),NULL))
+ return NULL;
+ }
+
+ return &share_ops;
+}
+#else
+ int locking_slow_dummy_procedure(void);
+ int locking_slow_dummy_procedure(void) {return 0;}
+#endif /* !FAST_SHARE_MODES */
diff --git a/source/locking/shmem.c b/source/locking/shmem.c
new file mode 100644
index 00000000000..435c0d4c789
--- /dev/null
+++ b/source/locking/shmem.c
@@ -0,0 +1,963 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Shared memory functions
+ Copyright (C) Erik Devriendt 1996-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+
+
+#ifdef HAVE_SHARED_MMAP
+
+
+extern int DEBUGLEVEL;
+
+
+#define SMB_SHM_MAGIC 0x53484100
+/* = "SHM" in hex */
+
+#define SMB_SHM_VERSION 2
+
+/* we need world read for smbstatus to function correctly */
+#ifdef SECURE_SHARE_MODES
+#define SHM_FILE_MODE 0600
+#else
+#define SHM_FILE_MODE 0644
+#endif
+
+#define SHMEM_HASH_SIZE 13
+
+
+/* WARNING : offsets are used because mmap() does not guarantee that all processes have the
+ shared memory mapped to the same address */
+
+struct SmbShmHeader
+{
+ int smb_shm_magic;
+ int smb_shm_version;
+ int total_size; /* in bytes */
+ BOOL consistent;
+ int first_free_off;
+ int userdef_off; /* a userdefined offset. can be used to store root of tree or list */
+ struct { /* a cell is a range of bytes of sizeof(struct SmbShmBlockDesc) size */
+ int cells_free;
+ int cells_used;
+ int cells_system; /* number of cells used as allocated block descriptors */
+ } statistics;
+};
+
+#define SMB_SHM_NOT_FREE_OFF (-1)
+struct SmbShmBlockDesc
+{
+ int next; /* offset of next block in the free list or SMB_SHM_NOT_FREE_OFF when block in use */
+ int size; /* user size in BlockDescSize units */
+};
+
+#define EOList_Addr (struct SmbShmBlockDesc *)( 0 )
+#define EOList_Off 0
+
+#define CellSize sizeof(struct SmbShmBlockDesc)
+
+/* HeaderSize aligned on 8 byte boundary */
+#define AlignedHeaderSize ((sizeof(struct SmbShmHeader)+7) & ~7)
+
+static int smb_shm_fd = -1;
+static pstring smb_shm_processreg_name = "";
+
+static struct SmbShmHeader *smb_shm_header_p = (struct SmbShmHeader *)0;
+static int smb_shm_times_locked = 0;
+
+static BOOL smb_shm_initialize_called = False;
+
+static int read_only;
+
+static BOOL smb_shm_global_lock(void)
+{
+ if (smb_shm_fd < 0)
+ {
+ DEBUG(0,("ERROR smb_shm_global_lock : bad smb_shm_fd (%d)\n",smb_shm_fd));
+ return False;
+ }
+
+ smb_shm_times_locked++;
+
+ if(smb_shm_times_locked > 1)
+ {
+ DEBUG(5,("smb_shm_global_lock : locked %d times\n",smb_shm_times_locked));
+ return True;
+ }
+
+ if (read_only)
+ return True;
+
+ /* Do an exclusive wait lock on the first byte of the file */
+ if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, 0, 1, F_WRLCK) == False)
+ {
+ DEBUG(0,("ERROR smb_shm_global_lock : fcntl_lock failed with code %s\n",strerror(errno)));
+ smb_shm_times_locked--;
+ return False;
+ }
+
+ return True;
+
+}
+
+static BOOL smb_shm_global_unlock(void)
+{
+ if (smb_shm_fd < 0)
+ {
+ DEBUG(0,("ERROR smb_shm_global_unlock : bad smb_shm_fd (%d)\n",smb_shm_fd));
+ return False;
+ }
+
+ if(smb_shm_times_locked == 0)
+ {
+ DEBUG(0,("ERROR smb_shm_global_unlock : shmem not locked\n"));
+ return False;
+ }
+
+ smb_shm_times_locked--;
+
+ if(smb_shm_times_locked > 0)
+ {
+ DEBUG(5,("smb_shm_global_unlock : still locked %d times\n",smb_shm_times_locked));
+ return True;
+ }
+
+ if (read_only)
+ return True;
+
+ /* Do a wait unlock on the first byte of the file */
+ if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, 0, 1, F_UNLCK) == False)
+ {
+ DEBUG(0,("ERROR smb_shm_global_unlock : fcntl_lock failed with code %s\n",strerror(errno)));
+ smb_shm_times_locked++;
+ return False;
+ }
+
+ return True;
+
+}
+
+
+static void *smb_shm_offset2addr(int offset)
+{
+ if (offset == 0 )
+ return (void *)(0);
+
+ if (!smb_shm_header_p)
+ return (void *)(0);
+
+ return (void *)((char *)smb_shm_header_p + offset );
+}
+
+static int smb_shm_addr2offset(void *addr)
+{
+ if (!addr)
+ return 0;
+
+ if (!smb_shm_header_p)
+ return 0;
+
+ return (int)((char *)addr - (char *)smb_shm_header_p);
+}
+
+
+
+static int smb_shm_alloc(int size)
+{
+ unsigned num_cells ;
+ struct SmbShmBlockDesc *scanner_p;
+ struct SmbShmBlockDesc *prev_p;
+ struct SmbShmBlockDesc *new_p;
+ int result_offset;
+
+
+ if( !smb_shm_header_p )
+ {
+ /* not mapped yet */
+ DEBUG(0,("ERROR smb_shm_alloc : shmem not mapped\n"));
+ return 0;
+ }
+
+ smb_shm_global_lock();
+
+ if( !smb_shm_header_p->consistent)
+ {
+ DEBUG(0,("ERROR smb_shm_alloc : shmem not consistent\n"));
+ smb_shm_global_unlock();
+ return 0;
+ }
+
+
+ /* calculate the number of cells */
+ num_cells = (size + CellSize -1) / CellSize;
+
+ /* set start of scan */
+ prev_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(smb_shm_header_p->first_free_off);
+ scanner_p = prev_p ;
+
+ /* scan the free list to find a matching free space */
+ while ( ( scanner_p != EOList_Addr ) && ( scanner_p->size < num_cells ) )
+ {
+ prev_p = scanner_p;
+ scanner_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(scanner_p->next);
+ }
+
+ /* at this point scanner point to a block header or to the end of the list */
+ if ( scanner_p == EOList_Addr )
+ {
+ DEBUG(0,("ERROR smb_shm_alloc : alloc of %d bytes failed, no free space found\n",size));
+ smb_shm_global_unlock();
+ return (0);
+ }
+
+ /* going to modify shared mem */
+ smb_shm_header_p->consistent = False;
+
+ /* if we found a good one : scanner == the good one */
+ if ( scanner_p->size <= num_cells + 2 )
+ {
+ /* there is no use in making a new one, it will be too small anyway
+ * we will link out scanner
+ */
+ if ( prev_p == scanner_p )
+ {
+ smb_shm_header_p->first_free_off = scanner_p->next ;
+ }
+ else
+ {
+ prev_p->next = scanner_p->next ;
+ }
+ smb_shm_header_p->statistics.cells_free -= scanner_p->size;
+ smb_shm_header_p->statistics.cells_used += scanner_p->size;
+ }
+ else
+ {
+ /* Make a new one */
+ new_p = scanner_p + 1 + num_cells;
+ new_p->size = scanner_p->size - num_cells - 1;
+ new_p->next = scanner_p->next;
+ scanner_p->size = num_cells;
+ scanner_p->next = smb_shm_addr2offset(new_p);
+
+ if ( prev_p != scanner_p )
+ {
+ prev_p->next = smb_shm_addr2offset(new_p) ;
+ }
+ else
+ {
+ smb_shm_header_p->first_free_off = smb_shm_addr2offset(new_p) ;
+ }
+ smb_shm_header_p->statistics.cells_free -= num_cells+1;
+ smb_shm_header_p->statistics.cells_used += num_cells;
+ smb_shm_header_p->statistics.cells_system += 1;
+ }
+
+ result_offset = smb_shm_addr2offset( &(scanner_p[1]) );
+ scanner_p->next = SMB_SHM_NOT_FREE_OFF ;
+
+ /* end modification of shared mem */
+ smb_shm_header_p->consistent = True;
+
+ DEBUG(6,("smb_shm_alloc : request for %d bytes, allocated %d bytes at offset %d\n",size,scanner_p->size*CellSize,result_offset ));
+
+ smb_shm_global_unlock();
+ return ( result_offset );
+}
+
+
+
+
+/*
+ * Function to create the hash table for the share mode entries. Called
+ * when smb shared memory is global locked.
+ */
+static BOOL smb_shm_create_hash_table( unsigned int size )
+{
+ size *= sizeof(int);
+
+ smb_shm_global_lock();
+ smb_shm_header_p->userdef_off = smb_shm_alloc( size );
+
+ if(smb_shm_header_p->userdef_off == 0)
+ {
+ DEBUG(0,("smb_shm_create_hash_table: Failed to create hash table of size %d\n",size));
+ smb_shm_global_unlock();
+ return False;
+ }
+
+ /* Clear hash buckets. */
+ memset( smb_shm_offset2addr(smb_shm_header_p->userdef_off), '\0', size);
+ smb_shm_global_unlock();
+ return True;
+}
+
+static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *other_processes)
+{
+ int smb_shm_processes_fd = -1;
+ int nb_read;
+ pid_t other_pid;
+ SMB_OFF_T seek_back = -((SMB_OFF_T)sizeof(other_pid));
+ SMB_OFF_T free_slot = -1;
+ SMB_OFF_T erased_slot;
+
+ smb_shm_processes_fd = sys_open(processreg_file,
+ read_only?O_RDONLY:(O_RDWR|O_CREAT),
+ SHM_FILE_MODE);
+
+ if ( smb_shm_processes_fd < 0 )
+ {
+ DEBUG(0, ("ERROR smb_shm_register_process : processreg_file \
+open failed with code %s\n",strerror(errno)));
+ return False;
+ }
+
+ *other_processes = False;
+
+ while ((nb_read = read(smb_shm_processes_fd, &other_pid, sizeof(other_pid))) > 0)
+ {
+ if(other_pid)
+ {
+ if(process_exists(other_pid))
+ *other_processes = True;
+ else
+ {
+ /* erase old pid */
+ DEBUG(5,("smb_shm_register_process : erasing stale record \
+for pid %d (seek_back = %.0f)\n", (int)other_pid, (double)seek_back));
+ other_pid = (pid_t)0;
+ if((erased_slot = sys_lseek(smb_shm_processes_fd,
+ seek_back, SEEK_CUR)) == -1)
+ {
+ DEBUG(0, ("ERROR smb_shm_register_process : sys_lseek failed \
+with error %s\n", strerror(errno)));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+
+ if(write(smb_shm_processes_fd, &other_pid, sizeof(other_pid)) == -1)
+ {
+ DEBUG(0, ("ERROR smb_shm_register_process : write failed \
+with error %s\n", strerror(errno)));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+
+ if(free_slot < 0)
+ free_slot = erased_slot;
+ }
+ }
+ else
+ {
+ if(free_slot < 0)
+ {
+ if((free_slot = sys_lseek(smb_shm_processes_fd,
+ seek_back, SEEK_CUR))==-1)
+ {
+ DEBUG(0, ("ERROR smb_shm_register_process : sys_lseek \
+failed with error %s\n", strerror(errno)));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+ } /* end if free_slot */
+ } /* end else */
+ } /* end if other_pid */
+
+ if (nb_read < 0)
+ {
+ DEBUG(0,("ERROR smb_shm_register_process : processreg_file read \
+failed with code %s\n",strerror(errno)));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+
+ if(free_slot < 0)
+ {
+ if((free_slot = sys_lseek(smb_shm_processes_fd, 0, SEEK_END)) == -1)
+ {
+ DEBUG(0,("ERROR smb_shm_register_process : sys_lseek failed with code %s\n",strerror(errno)));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+ }
+
+ DEBUG(5,("smb_shm_register_process : writing record for pid %d at offset %.0f\n",
+ (int)pid, (double)free_slot));
+
+ if(sys_lseek(smb_shm_processes_fd, free_slot, SEEK_SET) == -1)
+ {
+ DEBUG(0,("ERROR smb_shm_register_process : sys_lseek failed with code %s\n",strerror(errno)));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+
+ if(write(smb_shm_processes_fd, &pid, sizeof(pid)) == -1)
+ {
+ DEBUG(0,("ERROR smb_shm_register_process : processreg_file write failed with code %s\n",strerror(errno)));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+
+ close(smb_shm_processes_fd);
+
+ return True;
+}
+
+static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid)
+{
+ int smb_shm_processes_fd = -1;
+ int nb_read;
+ pid_t other_pid;
+ SMB_OFF_T seek_back = -((SMB_OFF_T)sizeof(other_pid));
+ BOOL found = False;
+
+
+ smb_shm_processes_fd = sys_open(processreg_file, O_RDWR, 0);
+ if ( smb_shm_processes_fd < 0 )
+ {
+ DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file open failed with code %s\n",strerror(errno)));
+ return False;
+ }
+
+ while ((nb_read = read(smb_shm_processes_fd, &other_pid, sizeof(other_pid))) > 0)
+ {
+ DEBUG(5,("smb_shm_unregister_process : read record for pid %d\n",(int)other_pid));
+ if(other_pid == pid)
+ {
+ /* erase pid */
+ DEBUG(5,("smb_shm_unregister_process : erasing record for pid %d (seek_val = %.0f)\n",
+ (int)other_pid, (double)seek_back));
+ other_pid = (pid_t)0;
+ if(sys_lseek(smb_shm_processes_fd, seek_back, SEEK_CUR) == -1)
+ {
+ DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file sys_lseek failed with code %s\n",strerror(errno)));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+ if(write(smb_shm_processes_fd, &other_pid, sizeof(other_pid)) < 0)
+ {
+ DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file write failed with code %s\n",strerror(errno)));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+
+ found = True;
+ break;
+ }
+ }
+ if (nb_read < 0)
+ {
+ DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file read failed with code %s\n",strerror(errno)));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+
+ if(!found)
+ {
+ DEBUG(0,("ERROR smb_shm_unregister_process : couldn't find pid %d in file %s\n",
+ (int)pid,processreg_file));
+ close(smb_shm_processes_fd);
+ return False;
+ }
+
+
+ close(smb_shm_processes_fd);
+
+ return True;
+}
+
+
+static BOOL smb_shm_validate_header(int size)
+{
+ if( !smb_shm_header_p )
+ {
+ /* not mapped yet */
+ DEBUG(0,("ERROR smb_shm_validate_header : shmem not mapped\n"));
+ return False;
+ }
+
+ if(smb_shm_header_p->smb_shm_magic != SMB_SHM_MAGIC)
+ {
+ DEBUG(0,("ERROR smb_shm_validate_header : bad magic\n"));
+ return False;
+ }
+ if(smb_shm_header_p->smb_shm_version != SMB_SHM_VERSION)
+ {
+ DEBUG(0,("ERROR smb_shm_validate_header : bad version %X\n",smb_shm_header_p->smb_shm_version));
+ return False;
+ }
+
+ if(smb_shm_header_p->total_size != size)
+ {
+ DEBUG(0,("ERROR smb_shm_validate_header : shmem size mismatch (old = %d, new = %d)\n",smb_shm_header_p->total_size,size));
+ return False;
+ }
+
+ if(!smb_shm_header_p->consistent)
+ {
+ DEBUG(0,("ERROR smb_shm_validate_header : shmem not consistent\n"));
+ return False;
+ }
+ return True;
+}
+
+static BOOL smb_shm_initialize(int size)
+{
+ struct SmbShmBlockDesc * first_free_block_p;
+
+ DEBUG(5,("smb_shm_initialize : initializing shmem file of size %d\n",size));
+
+ if( !smb_shm_header_p )
+ {
+ /* not mapped yet */
+ DEBUG(0,("ERROR smb_shm_initialize : shmem not mapped\n"));
+ return False;
+ }
+
+ smb_shm_header_p->smb_shm_magic = SMB_SHM_MAGIC;
+ smb_shm_header_p->smb_shm_version = SMB_SHM_VERSION;
+ smb_shm_header_p->total_size = size;
+ smb_shm_header_p->first_free_off = AlignedHeaderSize;
+ smb_shm_header_p->userdef_off = 0;
+
+ first_free_block_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(smb_shm_header_p->first_free_off);
+ first_free_block_p->next = EOList_Off;
+ first_free_block_p->size = ( size - AlignedHeaderSize - CellSize ) / CellSize ;
+
+ smb_shm_header_p->statistics.cells_free = first_free_block_p->size;
+ smb_shm_header_p->statistics.cells_used = 0;
+ smb_shm_header_p->statistics.cells_system = 1;
+
+ smb_shm_header_p->consistent = True;
+
+ smb_shm_initialize_called = True;
+
+ return True;
+}
+
+static void smb_shm_solve_neighbors(struct SmbShmBlockDesc *head_p )
+{
+ struct SmbShmBlockDesc *next_p;
+
+ /* Check if head_p and head_p->next are neighbors and if so join them */
+ if ( head_p == EOList_Addr ) return ;
+ if ( head_p->next == EOList_Off ) return ;
+
+ next_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(head_p->next);
+ if ( ( head_p + head_p->size + 1 ) == next_p)
+ {
+ head_p->size += next_p->size +1 ; /* adapt size */
+ head_p->next = next_p->next ; /* link out */
+
+ smb_shm_header_p->statistics.cells_free += 1;
+ smb_shm_header_p->statistics.cells_system -= 1;
+ }
+}
+
+
+
+static BOOL smb_shm_close( void )
+{
+
+ if(smb_shm_initialize_called == False)
+ return True;
+
+ DEBUG(5,("smb_shm_close\n"));
+ if(smb_shm_times_locked > 0)
+ DEBUG(0,("WARNING smb_shm_close : shmem was still locked %d times\n",smb_shm_times_locked));;
+ if ((smb_shm_header_p != NULL) &&
+ (munmap((caddr_t)smb_shm_header_p, smb_shm_header_p->total_size) < 0))
+ {
+ DEBUG(0,("ERROR smb_shm_close : munmap failed with code %s\n",strerror(errno)));
+ }
+
+ smb_shm_global_lock();
+ DEBUG(5,("calling smb_shm_unregister_process(%s, %d)\n",
+ smb_shm_processreg_name, (int)getpid()));
+ smb_shm_unregister_process(smb_shm_processreg_name, getpid());
+ smb_shm_global_unlock();
+
+ close(smb_shm_fd);
+
+ smb_shm_fd = -1;
+ smb_shm_processreg_name[0] = '\0';
+
+ smb_shm_header_p = (struct SmbShmHeader *)0;
+ smb_shm_times_locked = 0;
+
+ return True;
+}
+
+
+static BOOL smb_shm_free(int offset)
+{
+ struct SmbShmBlockDesc *header_p ; /* pointer to header of block to free */
+ struct SmbShmBlockDesc *scanner_p ; /* used to scan the list */
+ struct SmbShmBlockDesc *prev_p ; /* holds previous in the list */
+
+ if( !smb_shm_header_p )
+ {
+ /* not mapped yet */
+ DEBUG(0,("ERROR smb_shm_free : shmem not mapped\n"));
+ return False;
+ }
+
+ smb_shm_global_lock();
+
+ if( !smb_shm_header_p->consistent)
+ {
+ DEBUG(0,("ERROR smb_shm_free : shmem not consistent\n"));
+ smb_shm_global_unlock();
+ return False;
+ }
+
+ header_p = ( (struct SmbShmBlockDesc *)smb_shm_offset2addr(offset) - 1); /* make pointer to header of block */
+
+ if (header_p->next != SMB_SHM_NOT_FREE_OFF)
+ {
+ DEBUG(0,("ERROR smb_shm_free : bad offset (%d)\n",offset));
+ smb_shm_global_unlock();
+ return False;
+ }
+
+ /* find a place in the free_list to put the header in */
+
+ /* set scanner and previous pointer to start of list */
+ prev_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(smb_shm_header_p->first_free_off);
+ scanner_p = prev_p ;
+
+ while ( ( scanner_p != EOList_Addr) && (scanner_p < header_p) ) /* while we didn't scan past its position */
+ {
+ prev_p = scanner_p ;
+ scanner_p = (struct SmbShmBlockDesc *)smb_shm_offset2addr(scanner_p->next);
+ }
+
+ smb_shm_header_p->consistent = False;
+
+ DEBUG(6,("smb_shm_free : freeing %d bytes at offset %d\n",header_p->size*CellSize,offset));
+
+ /* zero the area being freed - this allows us to find bugs faster */
+ memset(smb_shm_offset2addr(offset), 0, header_p->size*CellSize);
+
+ if ( scanner_p == prev_p )
+ {
+ smb_shm_header_p->statistics.cells_free += header_p->size;
+ smb_shm_header_p->statistics.cells_used -= header_p->size;
+
+ /* we must free it at the beginning of the list */
+ smb_shm_header_p->first_free_off = smb_shm_addr2offset(header_p); /* set the free_list_pointer to this block_header */
+
+ /* scanner is the one that was first in the list */
+ header_p->next = smb_shm_addr2offset(scanner_p);
+ smb_shm_solve_neighbors( header_p ); /* if neighbors then link them */
+
+ smb_shm_header_p->consistent = True;
+ smb_shm_global_unlock();
+ return True;
+ }
+ else
+ {
+ smb_shm_header_p->statistics.cells_free += header_p->size;
+ smb_shm_header_p->statistics.cells_used -= header_p->size;
+
+ prev_p->next = smb_shm_addr2offset(header_p);
+ header_p->next = smb_shm_addr2offset(scanner_p);
+ smb_shm_solve_neighbors(header_p) ;
+ smb_shm_solve_neighbors(prev_p) ;
+
+ smb_shm_header_p->consistent = True;
+ smb_shm_global_unlock();
+ return True;
+ }
+}
+
+static int smb_shm_get_userdef_off(void)
+{
+ if (!smb_shm_header_p)
+ return 0;
+ else
+ return smb_shm_header_p->userdef_off;
+}
+
+/*******************************************************************
+ Lock a particular hash bucket entry.
+ ******************************************************************/
+static BOOL smb_shm_lock_hash_entry( unsigned int entry)
+{
+ int start = (smb_shm_header_p->userdef_off + (entry * sizeof(int)));
+
+ if (smb_shm_fd < 0)
+ {
+ DEBUG(0,("ERROR smb_shm_lock_hash_entry : bad smb_shm_fd (%d)\n",smb_shm_fd));
+ return False;
+ }
+
+ if (read_only)
+ return True;
+
+ /* Do an exclusive wait lock on the 4 byte region mapping into this entry */
+ if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, start, sizeof(int), F_WRLCK) == False)
+ {
+ DEBUG(0,("ERROR smb_shm_lock_hash_entry : fcntl_lock failed with code %s\n",strerror(errno)));
+ return False;
+ }
+
+ DEBUG(9,("smb_shm_lock_hash_entry: locked hash bucket %d\n", entry));
+ return True;
+}
+
+/*******************************************************************
+ Unlock a particular hash bucket entry.
+ ******************************************************************/
+static BOOL smb_shm_unlock_hash_entry( unsigned int entry )
+{
+ int start = (smb_shm_header_p->userdef_off + (entry * sizeof(int)));
+
+ if (smb_shm_fd < 0)
+ {
+ DEBUG(0,("ERROR smb_shm_unlock_hash_entry : bad smb_shm_fd (%d)\n",smb_shm_fd));
+ return False;
+ }
+
+ if (read_only)
+ return True;
+
+ /* Do a wait lock on the 4 byte region mapping into this entry */
+ if (fcntl_lock(smb_shm_fd, SMB_F_SETLKW, start, sizeof(int), F_UNLCK) == False)
+ {
+ DEBUG(0,("ERROR smb_shm_unlock_hash_entry : fcntl_lock failed with code %s\n",strerror(errno)));
+ return False;
+ }
+
+ DEBUG(9,("smb_shm_unlock_hash_entry: unlocked hash bucket %d\n", entry));
+ return True;
+}
+
+/*******************************************************************
+ Gather statistics on shared memory usage.
+ ******************************************************************/
+static BOOL smb_shm_get_usage(int *bytes_free,
+ int *bytes_used,
+ int *bytes_overhead)
+{
+ if( !smb_shm_header_p )
+ {
+ /* not mapped yet */
+ DEBUG(0,("ERROR smb_shm_free : shmem not mapped\n"));
+ return False;
+ }
+ *bytes_free = smb_shm_header_p->statistics.cells_free * CellSize;
+ *bytes_used = smb_shm_header_p->statistics.cells_used * CellSize;
+ *bytes_overhead = smb_shm_header_p->statistics.cells_system * CellSize + AlignedHeaderSize;
+
+ return True;
+}
+
+/*******************************************************************
+hash a number into a hash_entry
+ ******************************************************************/
+static unsigned smb_shm_hash_size(void)
+{
+ return SHMEM_HASH_SIZE;
+}
+
+static struct shmem_ops shmops = {
+ smb_shm_close,
+ smb_shm_alloc,
+ smb_shm_free,
+ smb_shm_get_userdef_off,
+ smb_shm_offset2addr,
+ smb_shm_addr2offset,
+ smb_shm_lock_hash_entry,
+ smb_shm_unlock_hash_entry,
+ smb_shm_get_usage,
+ smb_shm_hash_size,
+};
+
+/*******************************************************************
+ open the shared memory
+ ******************************************************************/
+struct shmem_ops *smb_shm_open(int ronly)
+{
+ pstring file_name;
+ SMB_OFF_T filesize;
+ BOOL created_new = False;
+ BOOL other_processes = True;
+ SMB_OFF_T size = (SMB_OFF_T)lp_shmem_size();
+
+ read_only = ronly;
+
+ pstrcpy(file_name,lp_lockdir());
+ if (!directory_exist(file_name,NULL)) {
+ if (read_only)
+ return NULL;
+ mkdir(file_name,0755);
+ }
+ trim_string(file_name,"","/");
+ if (!*file_name)
+ return(False);
+ pstrcat(file_name, "/SHARE_MEM_FILE");
+
+ DEBUG(5,("smb_shm_open : using shmem file %s to be of size %.0f\n",
+ file_name,(double)size));
+
+ smb_shm_fd = sys_open(file_name, read_only?O_RDONLY:(O_RDWR|O_CREAT),
+ SHM_FILE_MODE);
+
+ if ( smb_shm_fd < 0 )
+ {
+ DEBUG(0,("ERROR smb_shm_open : open failed with code %s\n",strerror(errno)));
+ return NULL;
+ }
+
+ if (!smb_shm_global_lock())
+ {
+ DEBUG(0,("ERROR smb_shm_open : can't do smb_shm_global_lock\n"));
+ return NULL;
+ }
+
+ if( (filesize = sys_lseek(smb_shm_fd, 0, SEEK_END)) == -1)
+ {
+ DEBUG(0,("ERROR smb_shm_open : sys_lseek failed with code %s\n",
+ strerror(errno)));
+ smb_shm_global_unlock();
+ close(smb_shm_fd);
+ return NULL;
+ }
+
+ /*
+ * Return the file offset to 0 to save on later seeks.
+ */
+ if(sys_lseek(smb_shm_fd,0,SEEK_SET) == -1)
+ {
+ DEBUG(0,("ERROR smb_shm_open : sys_lseek failed with code %s\n",
+ strerror(errno)));
+ smb_shm_global_unlock();
+ close(smb_shm_fd);
+ return NULL;
+ }
+
+ if (filesize == 0)
+ {
+ /*
+ * We just created a new one.
+ */
+ created_new = True;
+ }
+
+ /*
+ * To find out if some other process is already mapping the file,
+ * we use a registration file containing the processids of the file
+ * mapping processes.
+ */
+
+ /* construct processreg file name */
+ pstrcpy(smb_shm_processreg_name, file_name);
+ pstrcat(smb_shm_processreg_name, ".processes");
+
+ if (!read_only && !smb_shm_register_process(smb_shm_processreg_name,
+ getpid(), &other_processes))
+ {
+ smb_shm_global_unlock();
+ close(smb_shm_fd);
+ return NULL;
+ }
+
+ if (!read_only && (created_new || !other_processes))
+ {
+ /* we just created a new one, or are the first opener, lets set it size */
+ if( sys_ftruncate(smb_shm_fd, size) <0)
+ {
+ DEBUG(0,("ERROR smb_shm_open : ftruncate failed with code %s\n",
+ strerror(errno)));
+ smb_shm_unregister_process(smb_shm_processreg_name, getpid());
+ smb_shm_global_unlock();
+ close(smb_shm_fd);
+ return NULL;
+ }
+
+ /* paranoia */
+ if(sys_lseek(smb_shm_fd,0,SEEK_SET) == -1)
+ {
+ DEBUG(0,("ERROR smb_shm_open : sys_lseek failed with code %s\n",
+ strerror(errno)));
+ smb_shm_unregister_process(smb_shm_processreg_name, getpid());
+ smb_shm_global_unlock();
+ close(smb_shm_fd);
+ return NULL;
+ }
+
+ filesize = size;
+ }
+
+ if (size != filesize )
+ {
+ /* the existing file has a different size and we are not the first opener.
+ Since another process is still using it, we will use the file size */
+ DEBUG(0,("WARNING smb_shm_open : filesize (%.0f) != expected \
+size (%.0f), using filesize\n", (double)filesize, (double)size));
+
+ size = filesize;
+ }
+
+ smb_shm_header_p = (struct SmbShmHeader *)sys_mmap(NULL, size,
+ read_only?PROT_READ: (PROT_READ | PROT_WRITE),
+ MAP_FILE | MAP_SHARED, smb_shm_fd, (SMB_OFF_T)0);
+
+ /*
+ * WARNING, smb_shm_header_p can be different for different
+ * processes mapping the same file !
+ */
+ if (smb_shm_header_p == (struct SmbShmHeader *)(-1))
+ {
+ DEBUG(0,("ERROR smb_shm_open : mmap failed with code %s\n",strerror(errno)));
+ smb_shm_unregister_process(smb_shm_processreg_name, getpid());
+ smb_shm_global_unlock();
+ close(smb_shm_fd);
+ return NULL;
+ }
+
+
+ if (!read_only && (created_new || !other_processes))
+ {
+ smb_shm_initialize(size);
+ /* Create the hash buckets for the share file entries. */
+ smb_shm_create_hash_table(SHMEM_HASH_SIZE);
+ }
+ else if (!smb_shm_validate_header(size) )
+ {
+ /* existing file is corrupt, samba admin should remove it by hand */
+ DEBUG(0,("ERROR smb_shm_open : corrupt shared mem file, remove it manually\n"));
+ munmap((caddr_t)smb_shm_header_p, size);
+ smb_shm_unregister_process(smb_shm_processreg_name, getpid());
+ smb_shm_global_unlock();
+ close(smb_shm_fd);
+ return NULL;
+ }
+
+ smb_shm_global_unlock();
+ return &shmops;
+}
+
+
+#else /* HAVE_SHARED_MMAP */
+ int shmem_dummy_procedure(void)
+{return 0;}
+#endif /* HAVE_SHARED_MMAP */
diff --git a/source/locking/shmem_sysv.c b/source/locking/shmem_sysv.c
new file mode 100644
index 00000000000..d4e814d26fb
--- /dev/null
+++ b/source/locking/shmem_sysv.c
@@ -0,0 +1,716 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Shared memory functions - SYSV IPC implementation
+ Copyright (C) Andrew Tridgell 1997-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+
+
+#ifdef HAVE_SYSV_IPC
+
+extern int DEBUGLEVEL;
+
+#define SHMEM_KEY ((key_t)0x280267)
+#define SEMAPHORE_KEY (SHMEM_KEY+2)
+
+#define SHM_MAGIC 0x53484100
+#define SHM_VERSION 2
+
+#define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6))
+
+
+#ifdef SECURE_SEMAPHORES
+/* secure semaphores are slow because we have to do a become_root()
+ on every call! */
+#define SEMAPHORE_PERMS IPC_PERMS
+#else
+#define SEMAPHORE_PERMS 0666
+#endif
+
+#define SHMEM_HASH_SIZE 13
+
+#define MIN_SHM_SIZE 0x1000
+
+static int shm_id;
+static int sem_id;
+static int shm_size;
+static int hash_size;
+static int global_lock_count;
+
+struct ShmHeader {
+ int shm_magic;
+ int shm_version;
+ int total_size; /* in bytes */
+ BOOL consistent;
+ int first_free_off;
+ int userdef_off; /* a userdefined offset. can be used to store
+ root of tree or list */
+ struct { /* a cell is a range of bytes of sizeof(struct
+ ShmBlockDesc) size */
+ int cells_free;
+ int cells_used;
+ int cells_system; /* number of cells used as allocated
+ block descriptors */
+ } statistics;
+};
+
+#define SHM_NOT_FREE_OFF (-1)
+struct ShmBlockDesc
+{
+ int next; /* offset of next block in the free list or
+ SHM_NOT_FREE_OFF when block in use */
+ int size; /* user size in BlockDescSize units */
+};
+
+#define EOList_Addr NULL
+#define EOList_Off (0)
+
+#define CellSize sizeof(struct ShmBlockDesc)
+
+/* HeaderSize aligned on a 8 byte boundary */
+#define AlignedHeaderSize ((sizeof(struct ShmHeader)+7) & ~7)
+
+static struct ShmHeader *shm_header_p = NULL;
+
+static int read_only;
+
+static BOOL sem_change(int i, int op)
+{
+#ifdef SECURE_SEMAPHORES
+ extern struct current_user current_user;
+ int became_root=0;
+#endif
+ struct sembuf sb;
+ int ret;
+
+ if (read_only) return True;
+
+#ifdef SECURE_SEMAPHORES
+ if (current_user.uid != 0) {
+ become_root(0);
+ became_root = 1;
+ }
+#endif
+
+ sb.sem_num = i;
+ sb.sem_op = op;
+ sb.sem_flg = 0;
+
+ ret = semop(sem_id, &sb, 1);
+
+ if (ret != 0) {
+ DEBUG(0,("ERROR: sem_change(%d,%d) failed (%s)\n",
+ i, op, strerror(errno)));
+ }
+
+#ifdef SECURE_SEMAPHORES
+ if (became_root) {
+ unbecome_root(0);
+ }
+#endif
+
+ return ret == 0;
+}
+
+static BOOL global_lock(void)
+{
+ global_lock_count++;
+ if (global_lock_count == 1)
+ return sem_change(0, -1);
+ return True;
+}
+
+static BOOL global_unlock(void)
+{
+ global_lock_count--;
+ if (global_lock_count == 0)
+ return sem_change(0, 1);
+ return True;
+}
+
+static void *shm_offset2addr(int offset)
+{
+ if (offset == 0 )
+ return (void *)(0);
+
+ if (!shm_header_p)
+ return (void *)(0);
+
+ return (void *)((char *)shm_header_p + offset);
+}
+
+static int shm_addr2offset(void *addr)
+{
+ if (!addr)
+ return 0;
+
+ if (!shm_header_p)
+ return 0;
+
+ return (int)((char *)addr - (char *)shm_header_p);
+}
+
+
+static int shm_alloc(int size)
+{
+ unsigned num_cells ;
+ struct ShmBlockDesc *scanner_p;
+ struct ShmBlockDesc *prev_p;
+ struct ShmBlockDesc *new_p;
+ int result_offset;
+
+
+ if (!shm_header_p) {
+ /* not mapped yet */
+ DEBUG(0,("ERROR shm_alloc : shmem not mapped\n"));
+ return 0;
+ }
+
+ global_lock();
+
+ if (!shm_header_p->consistent) {
+ DEBUG(0,("ERROR shm_alloc : shmem not consistent\n"));
+ global_unlock();
+ return 0;
+ }
+
+ /* calculate the number of cells */
+ num_cells = (size + (CellSize-1)) / CellSize;
+
+ /* set start of scan */
+ prev_p = (struct ShmBlockDesc *)shm_offset2addr(shm_header_p->first_free_off);
+ scanner_p = prev_p ;
+
+ /* scan the free list to find a matching free space */
+ while ((scanner_p != EOList_Addr) && (scanner_p->size < num_cells)) {
+ prev_p = scanner_p;
+ scanner_p = (struct ShmBlockDesc *)shm_offset2addr(scanner_p->next);
+ }
+
+ /* at this point scanner point to a block header or to the end of
+ the list */
+ if (scanner_p == EOList_Addr) {
+ DEBUG(0,("ERROR shm_alloc : alloc of %d bytes failed\n",size));
+ global_unlock();
+ return (0);
+ }
+
+ /* going to modify shared mem */
+ shm_header_p->consistent = False;
+
+ /* if we found a good one : scanner == the good one */
+ if (scanner_p->size > num_cells + 2) {
+ /* Make a new one */
+ new_p = scanner_p + 1 + num_cells;
+ new_p->size = scanner_p->size - (num_cells + 1);
+ new_p->next = scanner_p->next;
+ scanner_p->size = num_cells;
+ scanner_p->next = shm_addr2offset(new_p);
+
+ shm_header_p->statistics.cells_free -= 1;
+ shm_header_p->statistics.cells_system += 1;
+ }
+
+ /* take it from the free list */
+ if (prev_p == scanner_p) {
+ shm_header_p->first_free_off = scanner_p->next;
+ } else {
+ prev_p->next = scanner_p->next;
+ }
+ shm_header_p->statistics.cells_free -= scanner_p->size;
+ shm_header_p->statistics.cells_used += scanner_p->size;
+
+ result_offset = shm_addr2offset(&(scanner_p[1]));
+ scanner_p->next = SHM_NOT_FREE_OFF;
+
+ /* end modification of shared mem */
+ shm_header_p->consistent = True;
+
+ global_unlock();
+
+ DEBUG(6,("shm_alloc : allocated %d bytes at offset %d\n",
+ size,result_offset));
+
+ return result_offset;
+}
+
+static void shm_solve_neighbors(struct ShmBlockDesc *head_p )
+{
+ struct ShmBlockDesc *next_p;
+
+ /* Check if head_p and head_p->next are neighbors and if so
+ join them */
+ if ( head_p == EOList_Addr ) return ;
+ if ( head_p->next == EOList_Off ) return ;
+
+ next_p = (struct ShmBlockDesc *)shm_offset2addr(head_p->next);
+ if ((head_p + head_p->size + 1) == next_p) {
+ head_p->size += next_p->size + 1; /* adapt size */
+ head_p->next = next_p->next; /* link out */
+
+ shm_header_p->statistics.cells_free += 1;
+ shm_header_p->statistics.cells_system -= 1;
+ }
+}
+
+
+static BOOL shm_free(int offset)
+{
+ struct ShmBlockDesc *header_p; /* pointer to header of
+ block to free */
+ struct ShmBlockDesc *scanner_p; /* used to scan the list */
+ struct ShmBlockDesc *prev_p; /* holds previous in the
+ list */
+
+ if (!shm_header_p) {
+ /* not mapped yet */
+ DEBUG(0,("ERROR shm_free : shmem not mapped\n"));
+ return False;
+ }
+
+ global_lock();
+
+ if (!shm_header_p->consistent) {
+ DEBUG(0,("ERROR shm_free : shmem not consistent\n"));
+ global_unlock();
+ return False;
+ }
+
+ /* make pointer to header of block */
+ header_p = ((struct ShmBlockDesc *)shm_offset2addr(offset) - 1);
+
+ if (header_p->next != SHM_NOT_FREE_OFF) {
+ DEBUG(0,("ERROR shm_free : bad offset (%d)\n",offset));
+ global_unlock();
+ return False;
+ }
+
+ /* find a place in the free_list to put the header in */
+
+ /* set scanner and previous pointer to start of list */
+ prev_p = (struct ShmBlockDesc *)
+ shm_offset2addr(shm_header_p->first_free_off);
+ scanner_p = prev_p ;
+
+ while ((scanner_p != EOList_Addr) &&
+ (scanner_p < header_p)) {
+ /* while we didn't scan past its position */
+ prev_p = scanner_p ;
+ scanner_p = (struct ShmBlockDesc *)
+ shm_offset2addr(scanner_p->next);
+ }
+
+ shm_header_p->consistent = False;
+
+ DEBUG(6,("shm_free : freeing %d bytes at offset %d\n",
+ header_p->size*CellSize,offset));
+
+ /* zero the area being freed - this allows us to find bugs faster */
+ memset(shm_offset2addr(offset), 0, header_p->size*CellSize);
+
+ if (scanner_p == prev_p) {
+ shm_header_p->statistics.cells_free += header_p->size;
+ shm_header_p->statistics.cells_used -= header_p->size;
+
+ /* we must free it at the beginning of the list */
+ shm_header_p->first_free_off = shm_addr2offset(header_p);
+ /* set the free_list_pointer to this block_header */
+
+ /* scanner is the one that was first in the list */
+ header_p->next = shm_addr2offset(scanner_p);
+ shm_solve_neighbors(header_p);
+
+ shm_header_p->consistent = True;
+ } else {
+ shm_header_p->statistics.cells_free += header_p->size;
+ shm_header_p->statistics.cells_used -= header_p->size;
+
+ prev_p->next = shm_addr2offset(header_p);
+ header_p->next = shm_addr2offset(scanner_p);
+ shm_solve_neighbors(header_p) ;
+ shm_solve_neighbors(prev_p) ;
+
+ shm_header_p->consistent = True;
+ }
+
+ global_unlock();
+ return True;
+}
+
+
+/*
+ * Function to create the hash table for the share mode entries. Called
+ * when smb shared memory is global locked.
+ */
+static BOOL shm_create_hash_table(unsigned int hash_entries)
+{
+ int size = hash_entries * sizeof(int);
+
+ global_lock();
+ shm_header_p->userdef_off = shm_alloc(size);
+
+ if(shm_header_p->userdef_off == 0) {
+ DEBUG(0,("shm_create_hash_table: Failed to create hash table of size %d\n",
+ size));
+ global_unlock();
+ return False;
+ }
+
+ /* Clear hash buckets. */
+ memset(shm_offset2addr(shm_header_p->userdef_off), '\0', size);
+ global_unlock();
+ return True;
+}
+
+
+static BOOL shm_validate_header(int size)
+{
+ if(!shm_header_p) {
+ /* not mapped yet */
+ DEBUG(0,("ERROR shm_validate_header : shmem not mapped\n"));
+ return False;
+ }
+
+ if(shm_header_p->shm_magic != SHM_MAGIC) {
+ DEBUG(0,("ERROR shm_validate_header : bad magic\n"));
+ return False;
+ }
+
+ if(shm_header_p->shm_version != SHM_VERSION) {
+ DEBUG(0,("ERROR shm_validate_header : bad version %X\n",
+ shm_header_p->shm_version));
+ return False;
+ }
+
+ if(shm_header_p->total_size != size) {
+ DEBUG(0,("ERROR shmem size mismatch (old = %d, new = %d)\n",
+ shm_header_p->total_size,size));
+ return False;
+ }
+
+ if(!shm_header_p->consistent) {
+ DEBUG(0,("ERROR shmem not consistent\n"));
+ return False;
+ }
+ return True;
+}
+
+
+static BOOL shm_initialize(int size)
+{
+ struct ShmBlockDesc * first_free_block_p;
+
+ DEBUG(5,("shm_initialize : initializing shmem size %d\n",size));
+
+ if( !shm_header_p ) {
+ /* not mapped yet */
+ DEBUG(0,("ERROR shm_initialize : shmem not mapped\n"));
+ return False;
+ }
+
+ shm_header_p->shm_magic = SHM_MAGIC;
+ shm_header_p->shm_version = SHM_VERSION;
+ shm_header_p->total_size = size;
+ shm_header_p->first_free_off = AlignedHeaderSize;
+ shm_header_p->userdef_off = 0;
+
+ first_free_block_p = (struct ShmBlockDesc *)
+ shm_offset2addr(shm_header_p->first_free_off);
+ first_free_block_p->next = EOList_Off;
+ first_free_block_p->size =
+ (size - (AlignedHeaderSize+CellSize))/CellSize;
+ shm_header_p->statistics.cells_free = first_free_block_p->size;
+ shm_header_p->statistics.cells_used = 0;
+ shm_header_p->statistics.cells_system = 1;
+
+ shm_header_p->consistent = True;
+
+ return True;
+}
+
+static BOOL shm_close( void )
+{
+ return True;
+}
+
+
+static int shm_get_userdef_off(void)
+{
+ if (!shm_header_p)
+ return 0;
+ else
+ return shm_header_p->userdef_off;
+}
+
+
+/*******************************************************************
+ Lock a particular hash bucket entry.
+ ******************************************************************/
+static BOOL shm_lock_hash_entry(unsigned int entry)
+{
+ return sem_change(entry+1, -1);
+}
+
+/*******************************************************************
+ Unlock a particular hash bucket entry.
+ ******************************************************************/
+static BOOL shm_unlock_hash_entry(unsigned int entry)
+{
+ return sem_change(entry+1, 1);
+}
+
+
+/*******************************************************************
+ Gather statistics on shared memory usage.
+ ******************************************************************/
+static BOOL shm_get_usage(int *bytes_free,
+ int *bytes_used,
+ int *bytes_overhead)
+{
+ if(!shm_header_p) {
+ /* not mapped yet */
+ DEBUG(0,("ERROR shm_free : shmem not mapped\n"));
+ return False;
+ }
+
+ *bytes_free = shm_header_p->statistics.cells_free * CellSize;
+ *bytes_used = shm_header_p->statistics.cells_used * CellSize;
+ *bytes_overhead = shm_header_p->statistics.cells_system * CellSize +
+ AlignedHeaderSize;
+
+ return True;
+}
+
+
+/*******************************************************************
+hash a number into a hash_entry
+ ******************************************************************/
+static unsigned shm_hash_size(void)
+{
+ return hash_size;
+}
+
+
+static struct shmem_ops shmops = {
+ shm_close,
+ shm_alloc,
+ shm_free,
+ shm_get_userdef_off,
+ shm_offset2addr,
+ shm_addr2offset,
+ shm_lock_hash_entry,
+ shm_unlock_hash_entry,
+ shm_get_usage,
+ shm_hash_size,
+};
+
+/*******************************************************************
+ open the shared memory
+ ******************************************************************/
+struct shmem_ops *sysv_shm_open(int ronly)
+{
+ BOOL other_processes;
+ struct shmid_ds shm_ds;
+ struct semid_ds sem_ds;
+ union semun su;
+ int i;
+ int pid;
+
+ read_only = ronly;
+
+ shm_size = lp_shmem_size();
+
+ DEBUG(4,("Trying sysv shmem open of size %d\n", shm_size));
+
+ /* first the semaphore */
+ sem_id = semget(SEMAPHORE_KEY, 0, 0);
+ if (sem_id == -1) {
+ if (read_only) return NULL;
+
+ hash_size = SHMEM_HASH_SIZE;
+
+ while (hash_size > 1) {
+ sem_id = semget(SEMAPHORE_KEY, hash_size+1,
+ IPC_CREAT|IPC_EXCL| SEMAPHORE_PERMS);
+ if (sem_id != -1 ||
+ (errno != EINVAL && errno != ENOSPC)) break;
+ hash_size -= 5;
+ }
+
+ if (sem_id == -1) {
+ DEBUG(0,("Can't create or use semaphore [1]. Error was %s\n",
+ strerror(errno)));
+ return NULL;
+ }
+
+ if (sem_id != -1) {
+ su.val = 1;
+ for (i=0;i<hash_size+1;i++) {
+ if (semctl(sem_id, i, SETVAL, su) != 0) {
+ DEBUG(1,("Failed to init semaphore %d. Error was %s\n",
+ i, strerror(errno)));
+ return NULL;
+ }
+ }
+ }
+ }
+ if (shm_id == -1) {
+ sem_id = semget(SEMAPHORE_KEY, 0, 0);
+ }
+ if (sem_id == -1) {
+ DEBUG(0,("Can't create or use semaphore [2]. Error was %s\n",
+ strerror(errno)));
+ return NULL;
+ }
+
+ su.buf = &sem_ds;
+ if (semctl(sem_id, 0, IPC_STAT, su) != 0) {
+ DEBUG(0,("ERROR semctl: can't IPC_STAT. Error was %s\n",
+ strerror(errno)));
+ return NULL;
+ }
+ hash_size = sem_ds.sem_nsems-1;
+
+ if (!read_only) {
+ if (sem_ds.sem_perm.cuid != 0 || sem_ds.sem_perm.cgid != 0) {
+ DEBUG(0,("ERROR: root did not create the semaphore\n"));
+ return NULL;
+ }
+
+ if (semctl(sem_id, 0, GETVAL, su) == 0 &&
+ !process_exists((pid=semctl(sem_id, 0, GETPID, su)))) {
+ DEBUG(0,("WARNING: clearing global IPC lock set by dead process %d\n",
+ pid));
+ su.val = 1;
+ if (semctl(sem_id, 0, SETVAL, su) != 0) {
+ DEBUG(0,("ERROR: Failed to clear global lock. Error was %s\n",
+ strerror(errno)));
+ return NULL;
+ }
+ }
+
+ sem_ds.sem_perm.mode = SEMAPHORE_PERMS;
+ if (semctl(sem_id, 0, IPC_SET, su) != 0) {
+ DEBUG(0,("ERROR shmctl : can't IPC_SET. Error was %s\n",
+ strerror(errno)));
+ return NULL;
+ }
+ }
+
+ if (!global_lock())
+ return NULL;
+
+
+ for (i=1;i<hash_size+1;i++) {
+ if (semctl(sem_id, i, GETVAL, su) == 0 &&
+ !process_exists((pid=semctl(sem_id, i, GETPID, su)))) {
+ DEBUG(1,("WARNING: clearing IPC lock %d set by dead process %d\n",
+ i, pid));
+ su.val = 1;
+ if (semctl(sem_id, i, SETVAL, su) != 0) {
+ DEBUG(0,("ERROR: Failed to clear IPC lock %d. Error was %s\n",
+ i, strerror(errno)));
+ global_unlock();
+ return NULL;
+ }
+ }
+ }
+
+ /*
+ * Try to use an existing key. Note that
+ * in order to use an existing key successfully
+ * size must be zero else shmget returns EINVAL.
+ * Thanks to Veselin Terzic <vterzic@systems.DHL.COM>
+ * for pointing this out.
+ */
+
+ shm_id = shmget(SHMEM_KEY, 0, 0);
+
+ /* if that failed then create one */
+ if (shm_id == -1) {
+ if (read_only) return NULL;
+ while (shm_size > MIN_SHM_SIZE) {
+ shm_id = shmget(SHMEM_KEY, shm_size,
+ IPC_CREAT | IPC_EXCL | IPC_PERMS);
+ if (shm_id != -1 ||
+ (errno != EINVAL && errno != ENOSPC)) break;
+ shm_size *= 0.8;
+ }
+ }
+
+ if (shm_id == -1) {
+ DEBUG(0,("Can't create or use IPC area. Error was %s\n", strerror(errno)));
+ global_unlock();
+ return NULL;
+ }
+
+
+ shm_header_p = (struct ShmHeader *)shmat(shm_id, 0,
+ read_only?SHM_RDONLY:0);
+ if ((long)shm_header_p == -1) {
+ DEBUG(0,("Can't attach to IPC area. Error was %s\n", strerror(errno)));
+ global_unlock();
+ return NULL;
+ }
+
+ /* to find out if some other process is already mapping the file,
+ we use a registration file containing the processids of the file
+ mapping processes */
+ if (shmctl(shm_id, IPC_STAT, &shm_ds) != 0) {
+ DEBUG(0,("ERROR shmctl : can't IPC_STAT. Error was %s\n", strerror(errno)));
+ global_unlock();
+ return NULL;
+ }
+
+ if (!read_only) {
+ if (shm_ds.shm_perm.cuid != 0 || shm_ds.shm_perm.cgid != 0) {
+ DEBUG(0,("ERROR: root did not create the shmem\n"));
+ global_unlock();
+ return NULL;
+ }
+ }
+
+ shm_size = shm_ds.shm_segsz;
+
+ other_processes = (shm_ds.shm_nattch > 1);
+
+ if (!read_only && !other_processes) {
+ memset((char *)shm_header_p, 0, shm_size);
+ shm_initialize(shm_size);
+ shm_create_hash_table(hash_size);
+ DEBUG(3,("Initialised IPC area of size %d\n", shm_size));
+ } else if (!shm_validate_header(shm_size)) {
+ /* existing file is corrupt, samba admin should remove
+ it by hand */
+ DEBUG(0,("ERROR shm_open : corrupt IPC area - remove it!\n"));
+ global_unlock();
+ return NULL;
+ }
+
+ global_unlock();
+ return &shmops;
+}
+
+
+
+#else
+ int ipc_dummy_procedure(void)
+{return 0;}
+#endif
diff --git a/source/lsarpcd/lsarpcd.c b/source/lsarpcd/lsarpcd.c
new file mode 100644
index 00000000000..15eeee20040
--- /dev/null
+++ b/source/lsarpcd/lsarpcd.c
@@ -0,0 +1,256 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "nterr.h"
+
+fstring pipe_name;
+
+pstring servicesf = CONFIGFILE;
+extern pstring debugf;
+extern BOOL append_log;
+extern int DEBUGLEVEL;
+
+/*****************************************************************************
+ initialise srv_auth_fns array
+ *****************************************************************************/
+static void auth_init(rpcsrv_struct * l)
+{
+}
+
+static void service_init(char *service_name)
+{
+ add_msrpc_command_processor(pipe_name, service_name, api_ntlsa_rpc);
+
+ if (!pwdb_initialise(True))
+ {
+ exit(-1);
+ }
+
+ if (!secret_init_db())
+ {
+ exit(-1);
+ }
+}
+
+/****************************************************************************
+ reload the services file
+ **************************************************************************/
+static void update_trust_account(void)
+{
+ BOOL trust_pwd_needs_changing = False;
+ uint8 old_trust[16];
+ NTTIME ntlct;
+ uint32 s2 = NT_STATUS_NOPROBLEMO;
+ uint32 s1 = NT_STATUS_NOPROBLEMO;
+ uint32 s = NT_STATUS_NOPROBLEMO;
+
+ POLICY_HND pol_sec;
+ POLICY_HND lsa_pol;
+ STRING2 secret;
+ STRING2 encsec;
+ UNISTR2 uni_sec_name;
+ char *name = "$MACHINE.ACC";
+ extern fstring global_myworkgroup;
+ time_t cur_time;
+ time_t sec_time;
+ uchar user_sess_key[16];
+
+ make_unistr2(&uni_sec_name, name, strlen(name));
+
+ s = _lsa_open_policy2(NULL, &lsa_pol, NULL, 0x02000000);
+
+ if (s == NT_STATUS_NOPROBLEMO)
+ {
+ s1 = _lsa_open_secret(&lsa_pol, &uni_sec_name, 0x02000000,
+ &pol_sec);
+ }
+
+ if (s1 == NT_STATUS_NOPROBLEMO)
+ {
+ if (!pol_get_usr_sesskey(get_global_hnd_cache(), &pol_sec,
+ user_sess_key))
+ {
+ s2 = NT_STATUS_INVALID_HANDLE;
+ }
+ }
+ if (s2 == NT_STATUS_NOPROBLEMO)
+ {
+ s2 = _lsa_query_secret(&pol_sec, &encsec, &ntlct, NULL, NULL);
+ }
+ if (s2 == NT_STATUS_NOPROBLEMO)
+ {
+ if (!nt_decrypt_string2(&secret, &encsec, user_sess_key))
+ {
+ s2 = NT_STATUS_INVALID_PARAMETER;
+ }
+ }
+ if (s2 == NT_STATUS_NOPROBLEMO)
+ {
+ int len;
+ if (!secret_get_data(&secret, old_trust, &len) || len != 16)
+ {
+ s2 = NT_STATUS_ACCESS_DENIED;
+ }
+ else
+ {
+ dump_data_pw("$MACHINE.ACC:", old_trust, 16);
+ }
+ }
+
+
+ cur_time = time(NULL);
+ sec_time = nt_time_to_unix(&ntlct);
+
+ if (DEBUGLVL(100))
+ {
+ DEBUG(100, ("secret time: %s\n", http_timestring(sec_time)));
+ DEBUG(100, ("current time: %s\n", http_timestring(cur_time)));
+ }
+
+ if (s2 == NT_STATUS_NOPROBLEMO
+ && cur_time > sec_time + lp_machine_password_timeout())
+ {
+ DEBUG(1, ("$MACHINE.ACC password being updated.\n"));
+ trust_pwd_needs_changing = True;
+ }
+
+ if (trust_pwd_needs_changing)
+ {
+ unsigned char trust_passwd_hash[16];
+ fstring srv_name;
+ BOOL res2;
+
+ res2 = get_any_dc_name(global_myworkgroup, srv_name);
+
+ generate_random_buffer(trust_passwd_hash, 16, True);
+ secret_store_data(&secret, trust_passwd_hash, 16);
+
+ res2 =
+ res2 ? nt_encrypt_string2(&encsec, &secret,
+ user_sess_key) : False;
+
+ if (!strequal("\\\\.", srv_name))
+ {
+ res2 =
+ res2 ?
+ modify_trust_password(global_myworkgroup,
+ srv_name, old_trust,
+ trust_passwd_hash,
+ SEC_CHAN_WKSTA) : False;
+ }
+
+ if (res2)
+ {
+ s2 = _lsa_set_secret(&pol_sec, &encsec, 0x0);
+ }
+ if (s2 != NT_STATUS_NOPROBLEMO)
+ {
+ DEBUG(0, ("$MACHINE.ACC password update FAILED\n"));
+ }
+ }
+
+ if (s1 == NT_STATUS_NOPROBLEMO)
+ {
+ _lsa_close(&pol_sec);
+ }
+ if (s == NT_STATUS_NOPROBLEMO)
+ {
+ _lsa_close(&lsa_pol);
+ }
+}
+
+/****************************************************************************
+ reload the services file
+ **************************************************************************/
+static BOOL reload_msrpc(BOOL test)
+{
+ BOOL ret;
+
+ if (lp_loaded())
+ {
+ pstring fname;
+ pstrcpy(fname, lp_configfile());
+ if (file_exist(fname, NULL) && !strcsequal(fname, servicesf))
+ {
+ pstrcpy(servicesf, fname);
+ test = False;
+ }
+ }
+
+ reopen_logs();
+
+ if (test && !lp_file_list_changed())
+ return (True);
+
+ lp_killunused(NULL);
+
+ ret = lp_load(servicesf, False, False, True);
+
+ /* perhaps the config filename is now set */
+ if (!test)
+ reload_msrpc(True);
+
+ reopen_logs();
+
+ load_interfaces();
+
+ return (ret);
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+static int main_init(int argc, char *argv[])
+{
+#ifdef HAVE_SET_AUTH_PARAMETERS
+ set_auth_parameters(argc, argv);
+#endif
+
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ append_log = True;
+
+ TimeInit();
+
+ fstrcpy(pipe_name, "lsarpc");
+ setup_logging(argv[0], False);
+ slprintf(debugf, sizeof(debugf), "%s/log.%s", LOGFILEBASE, pipe_name);
+
+ return 0;
+}
+
+static msrpc_service_fns fn_table = {
+ auth_init,
+ service_init,
+ reload_msrpc,
+ main_init,
+ update_trust_account
+};
+
+msrpc_service_fns *get_service_fns(void)
+{
+ return &fn_table;
+}
diff --git a/source/lsarpcd/secret_db.c b/source/lsarpcd/secret_db.c
new file mode 100644
index 00000000000..68ae3e707ec
--- /dev/null
+++ b/source/lsarpcd/secret_db.c
@@ -0,0 +1,222 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+BOOL tdb_delete_secret(TDB_CONTEXT * tdb, const UNISTR2 * uk)
+{
+ prs_struct key;
+ UNISTR2 k;
+ pstring tmp;
+
+ copy_unistr2(&k, uk);
+
+ unistr2_to_ascii(tmp, uk, sizeof(tmp) - 1);
+ DEBUG(10, ("delete secret %s\n", tmp));
+
+ prs_init(&key, 0, 4, False);
+ if (!smb_io_unistr2("key", &k, 1, &key, 0))
+ {
+ return False;
+ }
+
+ prs_tdb_delete(tdb, &key);
+
+ prs_free_data(&key);
+
+ return True;
+}
+
+BOOL tdb_lookup_secret(TDB_CONTEXT * tdb, const UNISTR2 * uk,
+ LSA_SECRET ** usr)
+{
+ prs_struct key;
+ prs_struct data;
+ UNISTR2 k = *uk;
+ pstring tmp;
+
+ copy_unistr2(&k, uk);
+
+ if (usr != NULL)
+ {
+ (*usr) = g_new(LSA_SECRET, 1);
+ if ((*usr) == NULL)
+ {
+ return False;
+ }
+ ZERO_STRUCTP((*usr));
+ }
+
+ unistr2_to_ascii(tmp, uk, sizeof(tmp) - 1);
+ DEBUG(10, ("lookup secret %s\n", tmp));
+
+ prs_init(&key, 0, 4, False);
+ if (!smb_io_unistr2("key", &k, 1, &key, 0))
+ {
+ prs_free_data(&key);
+ safe_free((*usr));
+ return False;
+ }
+
+ prs_tdb_fetch(tdb, &key, &data);
+
+ if (prs_buf_len(&data) == 0x0)
+ {
+ if (usr != NULL)
+ {
+ safe_free((*usr));
+ }
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+
+ if (usr != NULL)
+ {
+ if (!lsa_io_secret("usr", (*usr), &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ safe_free((*usr));
+ return False;
+ }
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+BOOL tdb_store_secret(TDB_CONTEXT * tdb, const UNISTR2 * uk, LSA_SECRET * usr)
+{
+ prs_struct key;
+ prs_struct data;
+ UNISTR2 k;
+ pstring tmp;
+
+ copy_unistr2(&k, uk);
+
+ unistr2_to_ascii(tmp, uk, sizeof(tmp) - 1);
+ DEBUG(10, ("storing secret %s\n", tmp));
+
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!smb_io_unistr2("key", &k, 1, &key, 0) ||
+ !lsa_io_secret("usr", usr, &data, 0) ||
+ prs_tdb_store(tdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+TDB_CONTEXT *open_secret_db(int perms)
+{
+ extern fstring global_myworkgroup;
+ extern pstring global_myname;
+ fstring domsec;
+ fstring domname;
+ fstring srvname;
+
+ fstrcpy(domname, global_myworkgroup);
+ fstrcpy(srvname, global_myname);
+ strupper(domname);
+ strupper(srvname);
+
+ slprintf(domsec, sizeof(domsec) - 1, "%s.%s.tdb", domname, srvname);
+
+ return tdb_open(lock_path(domsec), 0, 0, perms, 0600);
+}
+
+BOOL secret_init_db(void)
+{
+ extern fstring global_myworkgroup;
+ extern pstring global_myname;
+ uchar trust_passwd[16];
+ fstring domname;
+ fstring srvname;
+ NTTIME crt;
+ UNISTR2 name;
+ char *an = "$MACHINE.ACC";
+ LSA_SECRET sec;
+ TDB_CONTEXT *tdb;
+ BOOL ret = False;
+
+ fstrcpy(domname, global_myworkgroup);
+ fstrcpy(srvname, global_myname);
+ strupper(domname);
+ strupper(srvname);
+
+ tdb = open_secret_db(O_RDWR);
+
+ if (tdb != NULL)
+ {
+ DEBUG(10, ("secret_init_db: opened\n"));
+ return True;
+ }
+
+ tdb = open_secret_db(O_RDWR | O_CREAT);
+
+ if (tdb == NULL)
+ {
+ DEBUG(0, ("secret_init_db: failed\n"));
+ return False;
+ }
+
+ DEBUG(10, ("secret_init_db: opened first time: initialising.\n"));
+
+ generate_random_buffer(trust_passwd, 16, True);
+ unix_to_nt_time(&crt, time(NULL));
+
+ make_unistr2(&name, an, strlen(an));
+ ZERO_STRUCT(sec);
+
+ sec.curinfo.ptr_value = 1;
+ sec.curinfo.value.ptr_secret = 0x1;
+ make_strhdr2(&sec.curinfo.value.hdr_secret, 24, 24, 1);
+
+ secret_store_data( &sec.curinfo.value.enc_secret, trust_passwd, 16);
+
+ sec.oldinfo.ptr_update = 1;
+ sec.oldinfo.last_update = crt;
+
+ sec.curinfo.ptr_update = 1;
+ sec.curinfo.last_update = crt;
+
+ ret = tdb_store_secret(tdb, &name, &sec);
+
+ tdb_close(tdb);
+
+ return ret;
+}
diff --git a/source/lsarpcd/srv_lsa.c b/source/lsarpcd/srv_lsa.c
new file mode 100644
index 00000000000..3bf4b43cb83
--- /dev/null
+++ b/source/lsarpcd/srv_lsa.c
@@ -0,0 +1,609 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Jeremy Allison 1998-2000.
+ * Copyright (C) Elrond 2000.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+extern fstring global_myworkgroup;
+
+/***************************************************************************
+make_dom_query
+ ***************************************************************************/
+static void make_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
+{
+ fstring sid_str;
+ int domlen = strlen(dom_name);
+
+ d_q->uni_dom_str_len = (domlen+1) * 2;
+ d_q->uni_dom_max_len = domlen * 2;
+
+ d_q->buffer_dom_name = domlen != 0 ? 1 : 0; /* domain buffer pointer */
+ d_q->buffer_dom_sid = dom_sid != NULL ? 1 : 0; /* domain sid pointer */
+
+ /* this string is supposed to be character short */
+ make_unistr2(&(d_q->uni_domain_name), dom_name, domlen);
+ d_q->uni_domain_name.uni_max_len++;
+
+ sid_to_string(sid_str, dom_sid);
+ make_dom_sid2(&(d_q->dom_sid), dom_sid);
+}
+
+/***************************************************************************
+make_lsa_rid2s
+ ***************************************************************************/
+static uint32 get_remote_sid(const char *dom_name, char *find_name,
+ DOM_SID *sid, uint32 *rid, uint32 *sid_name_use)
+{
+ fstring srv_name;
+ fstring dummy;
+ uint32 status;
+
+ DEBUG(10, ("lookup remote name: %s %s\n",
+ dom_name, find_name));
+
+ if (! get_any_dc_name(dom_name, srv_name))
+ {
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
+ if (strequal(srv_name, "\\\\."))
+ {
+ DEBUG(0, ("WARNING: infinite loop in lsarpcd !\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
+
+ status = lookup_lsa_name(dom_name, find_name,
+ sid, sid_name_use);
+
+ if (status == 0x0 &&
+ (!sid_split_rid(sid, rid) ||
+ !map_domain_sid_to_name(sid, dummy)))
+ {
+ status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
+ return status;
+}
+
+static void make_lsa_rid2s(DOM_R_REF *ref,
+ DOM_RID2 *rid2,
+ int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS],
+ uint32 *mapped_count)
+{
+ int i;
+ int total = 0;
+ (*mapped_count) = 0;
+
+ SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ uint32 status = 0x0;
+ DOM_SID find_sid;
+ DOM_SID sid;
+ uint32 rid = 0xffffffff;
+ int dom_idx = -1;
+ char *find_name = NULL;
+ fstring dom_name;
+ fstring full_name;
+ uint32 sid_name_use = SID_NAME_UNKNOWN;
+
+ unistr2_to_ascii(full_name, &name[i], sizeof(full_name)-1);
+ find_name = strdup(full_name);
+
+ if (!split_domain_name(full_name, dom_name, find_name))
+ {
+ status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
+ if (status == 0x0 && map_domain_name_to_sid(&find_sid,
+ &find_name))
+ {
+ sid_name_use = SID_NAME_DOMAIN;
+ dom_idx = make_dom_ref(ref, dom_name, &find_sid);
+ rid = 0xffffffff;
+ sid_copy(&sid, &find_sid);
+ }
+ else if (status == 0x0)
+ {
+ uint32 ret;
+ ret = lookup_sam_domainname("\\\\.",
+ dom_name, &find_sid);
+
+ if (ret == 0x0)
+ {
+ pstring tmp;
+ sid_to_string(tmp, &find_sid);
+ DEBUG(10,("lookup sam name: %s %s\n",
+ tmp, find_name));
+ status = lookup_sam_name(NULL,
+ &find_sid,
+ find_name,
+ &rid, &sid_name_use);
+ sid_copy(&sid, &find_sid);
+ }
+ else
+ {
+ status = get_remote_sid(dom_name, find_name,
+ &sid, &rid,
+ &sid_name_use);
+ }
+ }
+
+ if (status == 0x0)
+ {
+ dom_idx = make_dom_ref(ref, find_name, &sid);
+ }
+
+ if (status == 0x0)
+ {
+ (*mapped_count)++;
+ }
+ else
+ {
+ dom_idx = -1;
+ rid = 0xffffffff;
+ sid_name_use = SID_NAME_UNKNOWN;
+ }
+
+ make_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
+ total++;
+
+ if (find_name != NULL)
+ {
+ free(find_name);
+ }
+ }
+}
+
+/***************************************************************************
+make_reply_lookup_names
+ ***************************************************************************/
+static void make_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
+ DOM_R_REF *ref, uint32 num_entries,
+ DOM_RID2 *rid2, uint32 mapped_count)
+{
+ r_l->ptr_dom_ref = 1;
+ r_l->dom_ref = ref;
+
+ r_l->num_entries = num_entries;
+ r_l->ptr_entries = 1;
+ r_l->num_entries2 = num_entries;
+ r_l->dom_rid = rid2;
+
+ r_l->mapped_count = mapped_count;
+
+ if (mapped_count == 0)
+ {
+ r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
+ else
+ {
+ r_l->status = 0x0;
+ }
+}
+
+/***************************************************************************
+make_reply_lookup_sids
+ ***************************************************************************/
+static void make_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
+ DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
+ uint32 mapped_count, uint32 status)
+{
+ r_l->ptr_dom_ref = 1;
+ r_l->dom_ref = ref;
+ r_l->names = names;
+ r_l->mapped_count = mapped_count;
+ r_l->status = status;
+}
+
+/***************************************************************************
+lsa_reply_lookup_sids
+ ***************************************************************************/
+static BOOL lsa_reply_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, prs_struct *rdata)
+{
+ LSA_R_LOOKUP_SIDS r_l;
+ DOM_R_REF ref;
+ LSA_TRANS_NAME_ENUM names;
+ uint32 mapped_count = 0;
+ DOM_SID2 *sid = q_l->sids.sid;
+ int num_entries = q_l->sids.num_entries;
+ uint32 status;
+
+ ZERO_STRUCT(r_l);
+ ZERO_STRUCT(ref);
+ ZERO_STRUCT(names);
+
+ /* set up the LSA Lookup SIDs response */
+ status = _lsa_lookup_sids(&q_l->pol,
+ num_entries, sid, &q_l->level,
+ &ref, &names, &mapped_count);
+ make_reply_lookup_sids(&r_l, &ref, &names, mapped_count, status);
+
+ /* store the response in the SMB stream */
+ return lsa_io_r_lookup_sids("", &r_l, rdata, 0);
+}
+
+/***************************************************************************
+lsa_reply_lookup_names
+ ***************************************************************************/
+static BOOL lsa_reply_lookup_names(prs_struct *rdata,
+ UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
+{
+ LSA_R_LOOKUP_NAMES r_l;
+ DOM_R_REF ref;
+ DOM_RID2 rids[MAX_LOOKUP_SIDS];
+ uint32 mapped_count = 0;
+
+ ZERO_STRUCT(r_l);
+ ZERO_STRUCT(ref);
+ ZERO_STRUCT(rids);
+
+ /* set up the LSA Lookup RIDs response */
+ make_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
+ make_reply_lookup_names(&r_l, &ref, num_entries, rids, mapped_count);
+
+ /* store the response in the SMB stream */
+ return lsa_io_r_lookup_names("", &r_l, rdata, 0);
+}
+
+/***************************************************************************
+api_lsa_open_policy
+ ***************************************************************************/
+static BOOL api_lsa_open_policy2( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_OPEN_POL2 q_o;
+ LSA_R_OPEN_POL2 r_o;
+
+ ZERO_STRUCT(q_o);
+ ZERO_STRUCT(r_o);
+
+ if (!lsa_io_q_open_pol2("", &q_o, data, 0))
+ {
+ return False;
+ }
+
+ r_o.status = _lsa_open_policy2(&q_o.uni_server_name, &r_o.pol,
+ &q_o.attr,
+ q_o.des_access);
+ return lsa_io_r_open_pol2("", &r_o, rdata, 0);
+}
+
+/***************************************************************************
+api_lsa_open_policy
+ ***************************************************************************/
+static BOOL api_lsa_open_policy( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_OPEN_POL q_o;
+ LSA_R_OPEN_POL r_o;
+
+ ZERO_STRUCT(r_o);
+ ZERO_STRUCT(q_o);
+
+ if (!lsa_io_q_open_pol("", &q_o, data, 0))
+ {
+ return False;
+ }
+
+ r_o.status = _lsa_open_policy(NULL, &r_o.pol,
+ &q_o.attr, q_o.des_access);
+ return lsa_io_r_open_pol("", &r_o, rdata, 0);
+}
+
+/***************************************************************************
+api_lsa_enum_trust_dom
+ ***************************************************************************/
+static BOOL api_lsa_enum_trust_dom( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ uint32 status;
+ uint32 enum_context;
+ uint32 num_doms = 0;
+ UNISTR2 *uni_names = NULL;
+ DOM_SID **sids = NULL;
+ LSA_R_ENUM_TRUST_DOM r_e;
+ LSA_Q_ENUM_TRUST_DOM q_e;
+ BOOL ret;
+
+ ZERO_STRUCT(r_e);
+ ZERO_STRUCT(q_e);
+
+ /* grab the enum trust domain context etc. */
+ if (!lsa_io_q_enum_trust_dom("", &q_e, data, 0))
+ {
+ return False;
+ }
+
+ /* construct reply. return status is always 0x0 */
+
+ status = _lsa_enum_trust_dom(NULL, &enum_context, &num_doms,
+ &uni_names, &sids);
+
+ make_r_enum_trust_dom(&r_e, enum_context,
+ num_doms, uni_names, sids,
+ status);
+
+ /* store the response in the SMB stream */
+ ret = lsa_io_r_enum_trust_dom("", &r_e, rdata, 0);
+
+ /* free names and sids */
+ free_sid_array(num_doms, sids);
+ safe_free(uni_names);
+
+ return ret;
+}
+
+/***************************************************************************
+api_lsa_query_info
+ ***************************************************************************/
+static BOOL api_lsa_query_info( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_QUERY_INFO q_i;
+ LSA_R_QUERY_INFO r_i;
+ fstring name;
+ DOM_SID sid;
+
+ memset(name, 0, sizeof(name));
+ ZERO_STRUCT(sid);
+ ZERO_STRUCT(q_i);
+ ZERO_STRUCT(r_i);
+
+ /* grab the info class and policy handle */
+ if (!lsa_io_q_query("", &q_i, data, 0))
+ {
+ return False;
+ }
+
+ r_i.status = _lsa_query_info_pol(&q_i.pol, q_i.info_class,
+ name, &sid);
+
+ if (r_i.status == 0x0)
+ {
+ /* set up the LSA QUERY INFO response */
+
+ r_i.undoc_buffer = 0x1;
+ r_i.info_class = q_i.info_class;
+
+ make_dom_query(&r_i.dom.id5, name, &sid);
+ }
+
+ /* store the response in the SMB stream */
+ return lsa_io_r_query("", &r_i, rdata, 0);
+}
+
+/***************************************************************************
+api_lsa_lookup_sids
+ ***************************************************************************/
+static BOOL api_lsa_lookup_sids( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_LOOKUP_SIDS q_l;
+ ZERO_STRUCT(q_l);
+
+ /* grab the info class and policy handle */
+ if (!lsa_io_q_lookup_sids("", &q_l, data, 0))
+ {
+ return False;
+ }
+
+
+ /* construct reply. return status is always 0x0 */
+ return lsa_reply_lookup_sids(&q_l, rdata);
+}
+
+/***************************************************************************
+api_lsa_lookup_names
+ ***************************************************************************/
+static BOOL api_lsa_lookup_names( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ LSA_Q_LOOKUP_NAMES q_l;
+ ZERO_STRUCT(q_l);
+
+ /* grab the info class and policy handle */
+ if (!lsa_io_q_lookup_names("", &q_l, data, 0))
+ {
+ return False;
+ }
+
+
+ SMB_ASSERT_ARRAY(q_l.uni_name, q_l.num_entries);
+
+ return lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
+}
+
+/***************************************************************************
+ api_lsa_close
+ ***************************************************************************/
+static BOOL api_lsa_close( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ LSA_R_CLOSE r_c;
+ LSA_Q_CLOSE q_c;
+
+ ZERO_STRUCT(q_c);
+ ZERO_STRUCT(r_c);
+
+ if (!lsa_io_q_close("", &q_c, data, 0))
+ {
+ return False;
+ }
+
+ r_c.pol = q_c.pol; /* in/out */
+ r_c.status = _lsa_close(&r_c.pol);
+ return lsa_io_r_close("", &r_c, rdata, 0);
+}
+
+/***************************************************************************
+ api_lsa_create_secret
+ ***************************************************************************/
+static BOOL api_lsa_create_secret( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ LSA_R_CREATE_SECRET r_o;
+ LSA_Q_CREATE_SECRET q_o;
+
+ ZERO_STRUCT(q_o);
+ ZERO_STRUCT(r_o);
+
+ if (!lsa_io_q_create_secret("", &q_o, data, 0))
+ {
+ return False;
+ }
+
+ r_o.status = _lsa_create_secret(&q_o.pol,
+ &q_o.uni_secret, q_o.des_access,
+ &r_o.pol);
+ return lsa_io_r_create_secret("", &r_o, rdata, 0);
+}
+
+/***************************************************************************
+ api_lsa_set_secret. AGH! HACK! :)
+ ***************************************************************************/
+static BOOL api_lsa_set_secret( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ LSA_Q_SET_SECRET q_o;
+ LSA_R_SET_SECRET r_o;
+ STRING2 *val = NULL;
+
+ ZERO_STRUCT(r_o);
+ ZERO_STRUCT(q_o);
+
+ if (!lsa_io_q_set_secret("", &q_o, data, 0))
+ {
+ return False;
+ }
+
+ if (q_o.value.ptr_secret) val = &q_o.value.enc_secret;
+
+ r_o.status = _lsa_set_secret(&q_o.pol, val, q_o.unknown);
+
+ return lsa_io_r_set_secret("", &r_o, rdata, 0);
+}
+
+/***************************************************************************
+ api_lsa_query_secret. AGH! HACK! :)
+ ***************************************************************************/
+static BOOL api_lsa_query_secret( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ LSA_R_QUERY_SECRET r_o;
+ LSA_Q_QUERY_SECRET q_o;
+ NTTIME *curtim = NULL;
+ NTTIME *oldtim = NULL;
+ STRING2 *curval = NULL;
+ STRING2 *oldval = NULL;
+
+ ZERO_STRUCT(r_o);
+ ZERO_STRUCT(q_o);
+
+ if (!lsa_io_q_query_secret("", &q_o, data, 0))
+ {
+ return False;
+ }
+
+ /* HACK! */
+ if (q_o.sec.curinfo.ptr_value != 0) curval = &q_o.sec.curinfo.value.enc_secret;
+ if (q_o.sec.curinfo.ptr_update != 0) curtim = &q_o.sec.curinfo.last_update;
+ if (q_o.sec.oldinfo.ptr_value != 0) oldval = &q_o.sec.oldinfo.value.enc_secret;
+ if (q_o.sec.oldinfo.ptr_update != 0) oldtim = &q_o.sec.oldinfo.last_update;
+
+ r_o.status = _lsa_query_secret(&q_o.pol,
+ curval, curtim,
+ oldval, oldtim);
+
+ memcpy(&r_o.sec, &q_o.sec, sizeof(r_o.sec)); /* urgh! HACK! */
+ if (r_o.sec.curinfo.ptr_value != 0) /* MORE HACK! */
+ {
+ r_o.sec.curinfo.value.ptr_secret = 1;
+ make_strhdr2(&r_o.sec.curinfo.value.hdr_secret,
+ r_o.sec.curinfo.value.enc_secret.str_str_len,
+ r_o.sec.curinfo.value.enc_secret.str_max_len, 1);
+ }
+ if (r_o.sec.oldinfo.ptr_value != 0) /* MORE HACK! */
+ {
+ r_o.sec.curinfo.value.ptr_secret = 1;
+ make_strhdr2(&r_o.sec.oldinfo.value.hdr_secret,
+ r_o.sec.oldinfo.value.enc_secret.str_str_len,
+ r_o.sec.oldinfo.value.enc_secret.str_max_len, 1);
+ }
+
+ return lsa_io_r_query_secret("", &r_o, rdata, 0);
+}
+
+/***************************************************************************
+ api_lsa_create_secret
+ ***************************************************************************/
+static BOOL api_lsa_open_secret( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
+{
+ LSA_R_OPEN_SECRET r_o;
+ LSA_Q_OPEN_SECRET q_o;
+
+ ZERO_STRUCT(r_o);
+ ZERO_STRUCT(q_o);
+
+ if (!lsa_io_q_open_secret("", &q_o, data, 0))
+ {
+ return False;
+ }
+
+ r_o.status = _lsa_open_secret(&q_o.pol,
+ &q_o.uni_secret, q_o.des_access,
+ &r_o.pol);
+ return lsa_io_r_open_secret("", &r_o, rdata, 0);
+}
+
+/***************************************************************************
+ \PIPE\ntlsa commands
+ ***************************************************************************/
+static const struct api_struct api_lsa_cmds[] =
+{
+ { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 },
+ { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
+ { "LSA_QUERYINFOPOLICY", LSA_QUERYINFOPOLICY, api_lsa_query_info },
+ { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom },
+ { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close },
+ { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
+ { "LSA_CREATESECRET" , LSA_CREATESECRET , api_lsa_create_secret },
+ { "LSA_QUERYSECRET" , LSA_QUERYSECRET , api_lsa_query_secret },
+ { "LSA_SETSECRET" , LSA_SETSECRET , api_lsa_set_secret },
+ { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
+ { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
+ { NULL , 0 , NULL }
+};
+
+/***************************************************************************
+ api_ntLsarpcTNP
+ ***************************************************************************/
+BOOL api_ntlsa_rpc(rpcsrv_struct *p)
+{
+ return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds);
+}
diff --git a/source/lsarpcd/srv_lsa_samdb.c b/source/lsarpcd/srv_lsa_samdb.c
new file mode 100644
index 00000000000..99e569dc7da
--- /dev/null
+++ b/source/lsarpcd/srv_lsa_samdb.c
@@ -0,0 +1,735 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Jeremy Allison 1998-2000.
+ * Copyright (C) Elrond 2000.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+ set secret tdb database
+****************************************************************************/
+static BOOL set_tdbsecdb(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT *tdb)
+{
+ if (tdb != NULL)
+ {
+ if (set_policy_state(cache, hnd, tdb_close, (void*)tdb))
+ {
+ return True;
+ }
+ tdb_close(tdb);
+ return False;
+ }
+ DEBUG(3,("Error setting policy secret database\n"));
+ return False;
+}
+
+/****************************************************************************
+ get tdb database handle
+****************************************************************************/
+static BOOL get_tdbsecdb(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT **tdb)
+{
+ (*tdb) = (TDB_CONTEXT*)get_policy_state_info(cache, hnd);
+
+ return True;
+}
+
+typedef struct tdb_sec_info
+{
+ UNISTR2 name;
+ TDB_CONTEXT *tdb;
+
+} TDB_SEC_INFO;
+
+static void secnamefree(void*inf)
+{
+ TDB_SEC_INFO *dev = (TDB_SEC_INFO*)inf;
+ if (dev != NULL)
+ {
+ tdb_close(dev->tdb);
+ }
+ safe_free(dev);
+}
+
+/****************************************************************************
+ set tdb secret name
+****************************************************************************/
+BOOL set_tdbsecname(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT *tdb,
+ const UNISTR2 *name)
+{
+ TDB_SEC_INFO *dev = malloc(sizeof(*dev));
+
+ if (dev != NULL)
+ {
+ copy_unistr2(&dev->name, name);
+ dev->tdb = tdb;
+ if (set_policy_state(cache, hnd, secnamefree, (void*)dev))
+ {
+ if (DEBUGLVL(3))
+ {
+ fstring tmp;
+ unistr2_to_ascii(tmp, name, sizeof(tmp)-1);
+ DEBUG(3,("setting tdb secret name=%s\n", tmp));
+ }
+ return True;
+ }
+ free(dev);
+ return False;
+ }
+ DEBUG(3,("Error setting tdb secret name\n"));
+ return False;
+}
+
+/****************************************************************************
+ get tdb secret name
+****************************************************************************/
+BOOL get_tdbsecname(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT **tdb,
+ UNISTR2 *name)
+{
+ TDB_SEC_INFO *dev = (TDB_SEC_INFO*)get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ if (name != NULL)
+ {
+ copy_unistr2(name, &dev->name);
+ }
+ if (tdb != NULL)
+ {
+ (*tdb) = dev->tdb;
+ }
+ return True;
+ }
+
+ DEBUG(3,("Error getting policy rid\n"));
+ return False;
+}
+/***************************************************************************
+lsa_reply_open_policy2
+ ***************************************************************************/
+uint32 _lsa_open_policy2(const UNISTR2 *server_name, POLICY_HND *hnd,
+ const LSA_OBJ_ATTR *attr,
+ uint32 des_access)
+{
+ if (hnd == NULL)
+ {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd(get_global_hnd_cache(),
+ get_sec_ctx(), hnd, des_access))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/***************************************************************************
+lsa_reply_open_policy
+ ***************************************************************************/
+uint32 _lsa_open_policy(const UNISTR2 *server_name, POLICY_HND *hnd,
+ const LSA_OBJ_ATTR *attr,
+ uint32 des_access)
+{
+ if (hnd == NULL)
+ {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd(get_global_hnd_cache(),
+ get_sec_ctx(), hnd, des_access))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/***************************************************************************
+_lsa_enum_trust_dom
+ ***************************************************************************/
+uint32 _lsa_enum_trust_dom(POLICY_HND *hnd, uint32 *enum_ctx,
+ uint32 *num_doms, UNISTR2 **uni_names,
+ DOM_SID ***sids)
+{
+ /* Should send on something good */
+
+ *enum_ctx = 0;
+ *num_doms = 0;
+ *uni_names = NULL;
+ *sids = NULL;
+
+ return 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM;
+}
+
+/***************************************************************************
+_lsa_lookup_names
+ ***************************************************************************/
+static uint32 get_remote_sid(const char *dom_name, char *find_name,
+ DOM_SID *sid, uint32 *rid, uint32 *sid_name_use)
+{
+ fstring srv_name;
+ fstring dummy;
+ uint32 status;
+
+ DEBUG(10, ("lookup remote name: %s %s\n",
+ dom_name, find_name));
+
+ if (! get_any_dc_name(dom_name, srv_name))
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+ if (strequal(srv_name, "\\\\."))
+ {
+ DEBUG(0, ("WARNING: infinite loop in lsarpcd !\n"));
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ status = lookup_lsa_name(dom_name, find_name,
+ sid, sid_name_use);
+
+ if (status == NT_STATUS_NOPROBLEMO &&
+ (!sid_split_rid(sid, rid) ||
+ !map_domain_sid_to_name(sid, dummy)))
+ {
+ status = NT_STATUS_NONE_MAPPED;
+ }
+ return status;
+}
+
+static uint32 _lsa_lookup_names(uint32 num_entries, const UNISTR2 *name,
+ DOM_R_REF *ref,
+ DOM_RID2 **ret_rid2,
+ uint32 *mapped_count)
+{
+ int i;
+ int total = 0;
+ DOM_RID2 *rid2;
+
+ (*mapped_count) = 0;
+
+ rid2 = g_new(DOM_RID2, num_entries);
+ (*ret_rid2) = rid2;
+
+ for (i = 0; i < num_entries; i++)
+ {
+ uint32 status1 = NT_STATUS_NOPROBLEMO;
+ DOM_SID find_sid;
+ DOM_SID sid;
+ uint32 rid = 0xffffffff;
+ int dom_idx = -1;
+ char *find_name = NULL;
+ fstring dom_name;
+ fstring full_name;
+ uint32 sid_name_use = SID_NAME_UNKNOWN;
+
+ unistr2_to_ascii(full_name, &name[i], sizeof(full_name)-1);
+ find_name = strdup(full_name);
+
+ if (!split_domain_name(full_name, dom_name, find_name))
+ {
+ status1 = NT_STATUS_NONE_MAPPED;
+ }
+ if (status1 == NT_STATUS_NOPROBLEMO && map_domain_name_to_sid(&find_sid,
+ &find_name))
+ {
+ sid_name_use = SID_NAME_DOMAIN;
+ dom_idx = make_dom_ref(ref, dom_name, &find_sid);
+ rid = 0xffffffff;
+ sid_copy(&sid, &find_sid);
+ }
+ else if (status1 == NT_STATUS_NOPROBLEMO)
+ {
+ uint32 ret;
+ ret = lookup_sam_domainname("\\\\.",
+ dom_name, &find_sid);
+
+ if (ret == NT_STATUS_NOPROBLEMO)
+ {
+ pstring tmp;
+ sid_to_string(tmp, &find_sid);
+ DEBUG(10,("lookup sam name: %s %s\n",
+ tmp, find_name));
+ status1 = lookup_sam_name(NULL,
+ &find_sid,
+ find_name,
+ &rid, &sid_name_use);
+ sid_copy(&sid, &find_sid);
+ }
+ else
+ {
+ status1 = get_remote_sid(dom_name, find_name,
+ &sid, &rid,
+ &sid_name_use);
+ }
+ }
+
+ if (status1 == NT_STATUS_NOPROBLEMO)
+ {
+ dom_idx = make_dom_ref(ref, find_name, &sid);
+ }
+
+ if (status1 == NT_STATUS_NOPROBLEMO)
+ {
+ (*mapped_count)++;
+ }
+ else
+ {
+ dom_idx = -1;
+ rid = 0xffffffff;
+ sid_name_use = SID_NAME_UNKNOWN;
+ }
+
+ make_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
+ total++;
+
+ if (find_name != NULL)
+ {
+ free(find_name);
+ }
+ }
+
+ if ((*mapped_count) == 0)
+ {
+ safe_free(rid2);
+ (*ret_rid2) = NULL;
+
+ return NT_STATUS_NONE_MAPPED;
+ }
+ else
+ {
+ return NT_STATUS_NOPROBLEMO;
+ }
+}
+
+/***************************************************************************
+_lsa_lookup_sids
+ ***************************************************************************/
+uint32 _lsa_lookup_sids(const POLICY_HND *hnd,
+ uint32 num_entries, DOM_SID2 *sid,
+ const LOOKUP_LEVEL *level,
+ DOM_R_REF *ref,
+ LSA_TRANS_NAME_ENUM *trn,
+ uint32 *mapped_count)
+{
+ int i;
+ int total = 0;
+ uint32 status = 0x0;
+
+ (*mapped_count) = 0;
+
+ if (find_policy_by_hnd(get_global_hnd_cache(), hnd) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ uint32 status1 = NT_STATUS_NOPROBLEMO;
+ DOM_SID find_sid = sid[i].sid;
+ DOM_SID tmp_sid = sid[i].sid;
+ uint32 rid = 0xffffffff;
+ int dom_idx = -1;
+ fstring name;
+ fstring dom_name;
+ uint32 sid_name_use = 0;
+
+ memset(dom_name, 0, sizeof(dom_name));
+ memset(name , 0, sizeof(name ));
+
+ if (map_domain_sid_to_name(&find_sid, dom_name))
+ {
+ sid_name_use = SID_NAME_DOMAIN;
+ name[0] = 0;
+ }
+ else if (sid_split_rid (&find_sid, &rid) &&
+ map_domain_sid_to_name(&find_sid, dom_name))
+ {
+ if (sid_equal(&find_sid, &global_sam_sid) ||
+ sid_equal(&find_sid, &global_sid_S_1_5_20))
+ {
+ status1 = lookup_sam_rid(dom_name,
+ &find_sid, rid,
+ name, &sid_name_use);
+ }
+ else
+ {
+ status1 = lookup_lsa_sid(dom_name,
+ &tmp_sid,
+ name, &sid_name_use);
+ }
+ }
+ else
+ {
+ status1 = NT_STATUS_NONE_MAPPED;
+ }
+
+ dom_idx = make_dom_ref(ref, dom_name, &find_sid);
+
+ if (status1 == NT_STATUS_NOPROBLEMO)
+ {
+ (*mapped_count)++;
+ }
+ else
+ {
+ snprintf(name, sizeof(name), "%08x", rid);
+ sid_name_use = SID_NAME_UNKNOWN;
+ }
+ make_lsa_trans_name(&(trn->name [total]),
+ &(trn->uni_name[total]),
+ sid_name_use, name, dom_idx);
+ total++;
+ }
+
+ trn->num_entries = total;
+ trn->ptr_trans_names = 1;
+ trn->num_entries2 = total;
+
+ if ((status == 0x0) && ((*mapped_count) == 0))
+ {
+ status = NT_STATUS_NONE_MAPPED;
+ }
+
+ return status;
+}
+
+/***************************************************************************
+_lsa_query_info
+ ***************************************************************************/
+uint32 _lsa_query_info_pol(POLICY_HND *hnd, uint16 info_class,
+ fstring domain_name, DOM_SID *domain_sid)
+{
+ fstring name;
+ uint32 status = NT_STATUS_NOPROBLEMO;
+ const DOM_SID *sid = NULL;
+
+ memset(name, 0, sizeof(name));
+
+ if (find_policy_by_hnd(get_global_hnd_cache(), hnd) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ switch (info_class)
+ {
+ case 0x03:
+ {
+ extern pstring global_myworkgroup;
+ fstrcpy(name, global_myworkgroup);
+ sid = &global_member_sid;
+ break;
+ }
+ case 0x05:
+ {
+ fstrcpy(name, global_sam_name);
+ sid = &global_sam_sid;
+ break;
+ }
+ default:
+ {
+ DEBUG(3, ("unknown info level in Lsa Query: %d\n",
+ info_class));
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+ if (domain_sid && sid)
+ {
+ sid_copy(domain_sid, sid);
+ }
+ if (domain_name)
+ {
+ fstrcpy(domain_name, name);
+ }
+
+ return status;
+}
+
+/***************************************************************************
+_lsa_close
+ ***************************************************************************/
+uint32 _lsa_close(POLICY_HND *hnd)
+{
+ if (!close_policy_hnd(get_global_hnd_cache(), hnd))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/***************************************************************************
+ _lsa_set_secret
+ ***************************************************************************/
+uint32 _lsa_set_secret(const POLICY_HND *hnd_secret,
+ const STRING2 *val,
+ uint32 unknown)
+{
+ TDB_CONTEXT *tdb = NULL;
+ UNISTR2 secret_name;
+ LSA_SECRET *sec = NULL;
+ uchar user_sess_key[16];
+ NTTIME ntt;
+
+ if (!pol_get_usr_sesskey(get_global_hnd_cache(), hnd_secret,
+ user_sess_key))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ dump_data_pw("sess_key:", user_sess_key, 16);
+
+ ZERO_STRUCT(sec);
+ ZERO_STRUCT(secret_name);
+
+ if (!get_tdbsecname(get_global_hnd_cache(), hnd_secret, &tdb,
+ &secret_name))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (tdb_writelock(tdb) != 0)
+ {
+ DEBUG(10,("_lsa_set_secret: write lock denied\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!tdb_lookup_secret(tdb, &secret_name, &sec))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (sec == NULL)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* store old info */
+ memcpy(&sec->oldinfo, &sec->curinfo, sizeof(sec->oldinfo));
+
+ /* decode and store new value, update time */
+ if (!nt_decrypt_string2(&sec->curinfo.value.enc_secret, val,
+ user_sess_key))
+ {
+ safe_free(sec);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ sec->curinfo.ptr_value = 1;
+ make_strhdr2(&sec->curinfo.value.hdr_secret,
+ sec->curinfo.value.enc_secret.str_max_len,
+ sec->curinfo.value.enc_secret.str_str_len, 1);
+ sec->curinfo.value.ptr_secret = 1;
+ }
+
+ unix_to_nt_time(&ntt, time(NULL));
+ sec->curinfo.ptr_update = 1;
+ sec->curinfo.last_update = ntt;
+
+ /* store new secret */
+ if (!tdb_store_secret(tdb, &secret_name, sec))
+ {
+ safe_free(sec);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ tdb_writeunlock(tdb);
+
+ safe_free(sec);
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/***************************************************************************
+ _lsa_query_secret
+ ***************************************************************************/
+uint32 _lsa_query_secret(const POLICY_HND *hnd_secret,
+ STRING2 *curval, NTTIME *curtime,
+ STRING2 *oldval, NTTIME *oldtime)
+{
+ TDB_CONTEXT *tdb = NULL;
+ UNISTR2 secret_name;
+ LSA_SECRET *sec = NULL;
+ uchar user_sess_key[16];
+
+ if (!pol_get_usr_sesskey(get_global_hnd_cache(), hnd_secret,
+ user_sess_key))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ dump_data_pw("sess_key:", user_sess_key, 16);
+
+ ZERO_STRUCT(sec);
+ ZERO_STRUCT(secret_name);
+
+ if (!get_tdbsecname(get_global_hnd_cache(), hnd_secret, &tdb,
+ &secret_name))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!tdb_lookup_secret(tdb, &secret_name, &sec))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (sec == NULL)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (curtime != NULL)
+ {
+ (*curtime) = sec->curinfo.last_update;
+ }
+ if (oldtime != NULL)
+ {
+ (*oldtime) = sec->oldinfo.last_update;
+ }
+ if (curval != NULL)
+ {
+ if (!nt_encrypt_string2(curval, &sec->curinfo.value.enc_secret,
+ user_sess_key))
+ {
+ safe_free(sec);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ }
+ if (oldval != NULL)
+ {
+ if (!nt_encrypt_string2(oldval, &sec->oldinfo.value.enc_secret,
+ user_sess_key))
+ {
+ safe_free(sec);
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ }
+ safe_free(sec);
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/***************************************************************************
+ _lsa_create_secret
+ ***************************************************************************/
+uint32 _lsa_create_secret(const POLICY_HND *hnd,
+ const UNISTR2 *secret_name, uint32 des_access,
+ POLICY_HND *hnd_secret)
+{
+ TDB_CONTEXT *tdb;
+ LSA_SECRET sec;
+ NTTIME ntt;
+
+ ZERO_STRUCT(sec);
+
+ tdb = open_secret_db(O_RDWR);
+ if (tdb == NULL)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (tdb_lookup_secret(tdb, secret_name, NULL))
+ {
+ DEBUG(10,("_lsa_create_secret: secret exists\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ hnd, hnd_secret, des_access))
+ {
+ tdb_close(tdb);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!set_tdbsecname(get_global_hnd_cache(), hnd_secret, tdb, secret_name))
+ {
+ close_policy_hnd(get_global_hnd_cache(), hnd_secret);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ unix_to_nt_time(&ntt, time(NULL));
+
+ sec.curinfo.ptr_update = 1;
+ sec.curinfo.last_update = ntt;
+
+ sec.oldinfo.ptr_update = 1;
+ sec.oldinfo.last_update = ntt;
+
+ if (!tdb_store_secret(tdb, secret_name, &sec))
+ {
+ close_policy_hnd(get_global_hnd_cache(), hnd_secret);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/***************************************************************************
+ _lsa_open_secret
+ ***************************************************************************/
+uint32 _lsa_open_secret(const POLICY_HND *hnd,
+ const UNISTR2 *secret_name, uint32 des_access,
+ POLICY_HND *hnd_secret)
+{
+ TDB_CONTEXT *tdb;
+
+ tdb = open_secret_db(O_RDWR);
+ if (tdb == NULL)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!tdb_lookup_secret(tdb, secret_name, NULL))
+ {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ hnd, hnd_secret, des_access))
+ {
+ tdb_close(tdb);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!set_tdbsecname(get_global_hnd_cache(), hnd_secret, tdb, secret_name))
+ {
+ close_policy_hnd(get_global_hnd_cache(), hnd_secret);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
diff --git a/source/ltconfig b/source/ltconfig
new file mode 100644
index 00000000000..e7b25105795
--- /dev/null
+++ b/source/ltconfig
@@ -0,0 +1,3078 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+echo=echo
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec "$SHELL" "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) PATH_SEPARATOR=';' ;;
+ *) PATH_SEPARATOR=':' ;;
+ esac
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test "X${echo_test_string+set}" != Xset; then
+ # find a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" != 'X\t' ||
+ test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH /usr/ucb; do
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't find a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running ltconfig again with it.
+ ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}"
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ echo='printf "%s\n"'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL"
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' &&
+ test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.3.4
+TIMESTAMP=" (1.385.2.196 1999/12/07 21:47:57)"
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+enable_static=yes
+enable_fast_install=yes
+enable_dlopen=unknown
+enable_win32_dll=no
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+ofile="$default_ofile"
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+need_locks=yes
+ac_ext=c
+objext=o
+libext=a
+exeext=
+cache_file=
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LDFLAGS="$LDFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_LIBS="$LIBS"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+old_DLLTOOL="$DLLTOOL"
+old_OBJDUMP="$OBJDUMP"
+old_AS="$AS"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+ case "$option" in
+ -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ eval "$prev=\$option"
+ prev=
+ continue
+ fi
+
+ case "$option" in
+ --help) cat <<EOM
+Usage: $progname [OPTION]... [HOST [LTMAIN]]
+
+Generate a system-specific libtool script.
+
+ --debug enable verbose shell tracing
+ --disable-shared do not build shared libraries
+ --disable-static do not build static libraries
+ --disable-fast-install do not optimize for fast installation
+ --enable-dlopen enable dlopen support
+ --enable-win32-dll enable building dlls on win32 hosts
+ --help display this help and exit
+ --no-verify do not verify that HOST is a valid host type
+-o, --output=FILE specify the output file [default=$default_ofile]
+ --quiet same as \`--silent'
+ --silent do not print informational messages
+ --srcdir=DIR find \`config.guess' in DIR
+ --version output version information and exit
+ --with-gcc assume that the GNU C compiler will be used
+ --with-gnu-ld assume that the C compiler uses the GNU linker
+ --disable-lock disable file locking
+ --cache-file=FILE configure cache file
+
+LTMAIN is the \`ltmain.sh' shell script fragment or \`ltmain.c' program
+that provides basic libtool functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --disable-shared) enable_shared=no ;;
+
+ --disable-static) enable_static=no ;;
+
+ --disable-fast-install) enable_fast_install=no ;;
+
+ --enable-dlopen) enable_dlopen=yes ;;
+
+ --enable-win32-dll) enable_win32_dll=yes ;;
+
+ --quiet | --silent) silent=yes ;;
+
+ --srcdir) prev=srcdir ;;
+ --srcdir=*) srcdir="$optarg" ;;
+
+ --no-verify) verify_host=no ;;
+
+ --output | -o) prev=ofile ;;
+ --output=*) ofile="$optarg" ;;
+
+ --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"; exit 0 ;;
+
+ --with-gcc) with_gcc=yes ;;
+ --with-gnu-ld) with_gnu_ld=yes ;;
+
+ --disable-lock) need_locks=no ;;
+
+ --cache-file=*) cache_file="$optarg" ;;
+
+ -*)
+ echo "$progname: unrecognized option \`$option'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ if test -z "$ltmain"; then
+ ltmain="$option"
+ elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+# echo "$progname: warning \`$option' is not a valid host type" 1>&2
+# fi
+ host="$option"
+ else
+ echo "$progname: too many arguments" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+done
+
+if test -z "$ltmain"; then
+ echo "$progname: you must specify a LTMAIN file" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+if test ! -f "$ltmain"; then
+ echo "$progname: \`$ltmain' does not exist" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+ case "$arg" in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ltconfig_args="$ltconfig_args '$arg'" ;;
+ *) ltconfig_args="$ltconfig_args $arg" ;;
+ esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "X${LC_ALL+set}" = Xset; then LC_ALL=C; export LC_ALL; fi
+if test "X${LANG+set}" = Xset; then LANG=C; export LANG; fi
+
+if test -n "$cache_file" && test -r "$cache_file"; then
+ echo "loading cache $cache_file within ltconfig"
+ . $cache_file
+fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+ # Assume the source directory is the same one as the path to LTMAIN.
+ srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+ test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+ # Check for config.guess and config.sub.
+ ac_aux_dir=
+ for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/config.guess; then
+ ac_aux_dir=$ac_dir
+ break
+ fi
+ done
+ if test -z "$ac_aux_dir"; then
+ echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+ ac_config_guess=$ac_aux_dir/config.guess
+ ac_config_sub=$ac_aux_dir/config.sub
+
+ # Make sure we can run config.sub.
+ if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then :
+ else
+ echo "$progname: cannot run $ac_config_sub" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+
+ echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+ host_alias=$host
+ case "$host_alias" in
+ "")
+ if host_alias=`$SHELL $ac_config_guess`; then :
+ else
+ echo "$progname: cannot guess host type; you must specify one" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+ host=`$SHELL $ac_config_sub $host_alias`
+ echo "$ac_t$host" 1>&6
+
+ # Make sure the host verified.
+ test -z "$host" && exit 1
+
+elif test -z "$host"; then
+ echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+else
+ host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# Set a sane default for `OBJDUMP'.
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+ result=no
+
+ echo $ac_n "checking for ranlib... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then
+ RANLIB="ranlib"
+ result="ranlib"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+fi
+
+# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin.
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$AS" && AS=as
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+ # If CC is not set, then try to find GCC or a usable CC.
+ if test -z "$CC"; then
+ echo $ac_n "checking for gcc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then
+ CC="gcc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+ fi
+
+ # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+ if test -z "$CC"; then
+ echo $ac_n "checking for cc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ cc_rejected=no
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/cc || test -f $dir/cc$ac_exeext; then
+ if test "$dir/cc" = "/usr/ucb/cc"; then
+ cc_rejected=yes
+ continue
+ fi
+ CC="cc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test $cc_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same name, so the bogon will be chosen
+ # first if we set CC to just the name; use the full file name.
+ shift
+ set dummy "$dir/cc" "$@"
+ shift
+ CC="$@"
+ fi
+ fi
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$CC"; then
+ echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+ exit 1
+ fi
+ fi
+
+ # Now see if the compiler is really GCC.
+ with_gcc=no
+ echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+ echo "$progname:581: checking whether we are using GNU C" >&5
+
+ $rm conftest.c
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+ if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ with_gcc=yes
+ fi
+ $rm conftest.c
+ echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for object suffix... $ac_c" 1>&6
+$rm conftest*
+echo 'int i = 1;' > conftest.c
+echo "$progname:603: checking for object suffix" >& 5
+if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+else
+ cat conftest.err 1>&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+fi
+$rm conftest*
+echo "$ac_t$objext" 1>&6
+
+echo $ac_n "checking for executable suffix... $ac_c" 1>&6
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_exeext="no"
+ $rm conftest*
+ echo 'main () { return 0; }' > conftest.c
+ echo "$progname:629: checking for executable suffix" >& 5
+ if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c | *.err | *.$objext ) ;;
+ *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+ else
+ cat conftest.err 1>&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ $rm conftest*
+fi
+if test "X$ac_cv_exeext" = Xno; then
+ exeext=""
+else
+ exeext="$ac_cv_exeext"
+fi
+echo "$ac_t$ac_cv_exeext" 1>&6
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+ wl='-Wl,'
+ link_static_flag='-static'
+
+ case "$host_os" in
+ beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ aix*)
+ # Below there is a dirty hack to force normal static linking with -ldl
+ # The problem is because libdl dynamically linked with both libc and
+ # libC (AIX C++ library), which obviously doesn't included in libraries
+ # list by gcc. This cause undefined symbols with -static flags.
+ # This hack allows C programs to be linked with "-static -ldl", but
+ # we not sure about C++ programs.
+ link_static_flag="$link_static_flag ${wl}-lC"
+ ;;
+ cygwin* | mingw* | os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ pic_flag='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ pic_flag=-Kconform_pic
+ fi
+ ;;
+ *)
+ pic_flag='-fPIC'
+ ;;
+ esac
+else
+ # PORTME Check for PIC flags for the system compiler.
+ case "$host_os" in
+ aix3* | aix4*)
+ # All AIX code is PIC.
+ link_static_flag='-bnso -bI:/lib/syscalls.exp'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ # Is there a better link_static_flag that works with the bundled CC?
+ wl='-Wl,'
+ link_static_flag="${wl}-a ${wl}archive"
+ pic_flag='+Z'
+ ;;
+
+ irix5* | irix6*)
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ cygwin* | mingw* | os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+
+ osf3* | osf4* | osf5*)
+ # All OSF/1 code is PIC.
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ pic_flag='-Kpic'
+ link_static_flag='-dn'
+ special_shlib_compile_flags='-belf'
+ ;;
+
+ solaris*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ sunos4*)
+ pic_flag='-PIC'
+ link_static_flag='-Bstatic'
+ wl='-Qoption ld '
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ uts4*)
+ pic_flag='-pic'
+ link_static_flag='-Bstatic'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ pic_flag='-Kconform_pic'
+ link_static_flag='-Bstatic'
+ fi
+ ;;
+ *)
+ can_build_shared=no
+ ;;
+ esac
+fi
+
+if test -n "$pic_flag"; then
+ echo "$ac_t$pic_flag" 1>&6
+
+ # Check to make sure the pic_flag actually works.
+ echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $pic_flag -DPIC"
+ echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5
+ if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ case "$host_os" in
+ hpux9* | hpux10* | hpux11*)
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+ # create non-PIC objects. So, if there were any warnings, we assume that
+ # PIC is not supported.
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ can_build_shared=no
+ pic_flag=
+ else
+ echo "$ac_t"yes 1>&6
+ pic_flag=" $pic_flag"
+ fi
+ ;;
+ *)
+ echo "$ac_t"yes 1>&6
+ pic_flag=" $pic_flag"
+ ;;
+ esac
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ can_build_shared=no
+ pic_flag=
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ echo "$ac_t"none 1>&6
+fi
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+$rm conftest*
+echo "int some_variable = 0;" > conftest.c
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory. Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.o"
+echo "$progname:829: checking if $compiler supports -c -o file.o" >&5
+if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_c_o=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat out/conftest.err 1>&5
+ compiler_c_o=no
+ echo "$ac_t"no 1>&6
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+if test x"$compiler_c_o" = x"yes"; then
+ # Check to see if we can write to a .lo
+ echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -c -o conftest.lo"
+ echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5
+if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_o_lo=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_o_lo=yes
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_o_lo=no
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ echo "$ac_t$hard_links" 1>&6
+ $rm conftest*
+ if test "$hard_links" = no; then
+ echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+if test "$with_gcc" = yes; then
+ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+ echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6
+ $rm conftest*
+ echo "int some_variable = 0;" > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c"
+ echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+ if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ compiler_rtti_exceptions=no
+ else
+ echo "$ac_t"yes 1>&6
+ compiler_rtti_exceptions=yes
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ compiler_rtti_exceptions=no
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+
+ if test "$compiler_rtti_exceptions" = "yes"; then
+ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+ else
+ no_builtin_flag=' -fno-builtin'
+ fi
+
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+ echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then :
+ else
+ echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+ can_build_shared=no
+ fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ echo "$ac_t$link_static_flag" 1>&6
+else
+ echo "$ac_t"none 1>&6
+ link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+ # Check to see if we can use ln -s, or we need hard links.
+ echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+ $rm conftest.dat
+ if ln -s X conftest.dat 2>/dev/null; then
+ $rm conftest.dat
+ LN_S="ln -s"
+ else
+ LN_S=ln
+ fi
+ if test "$LN_S" = "ln -s"; then
+ echo "$ac_t"yes 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+ ac_prog=ld
+ if test "$with_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+ echo "$progname:991: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we are not using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+ elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+ echo "$progname:1015: checking for GNU ld" >&5
+ else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+ echo "$progname:1018: checking for non-GNU ld" >&5
+ fi
+
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ fi
+
+ if test -n "$LD"; then
+ echo "$ac_t$LD" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$LD"; then
+ echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+ exit 1
+ fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that contains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced. Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+
+case "$host_os" in
+cygwin* | mingw*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$with_gcc" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # See if GNU ld supports shared libraries.
+ case "$host_os" in
+ aix3* | aix4*)
+ # On AIX, the GNU linker is very broken
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can use
+ # them.
+ ld_shlibs=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+
+ # Extract the symbol export list from an `--export-all' def file,
+ # then regenerate the def file from the symbol export list, so that
+ # the compiled dll only exports the symbol export list.
+ export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+ test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+ $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs $convenience~
+ sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols'
+
+ archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~
+ _lt_hint=1;
+ for symbol in `cat $export_symbols`; do
+ echo " \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def;
+ _lt_hint=`expr 1 + \$_lt_hint`;
+ done~
+ test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~
+ test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~
+ $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+ $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~
+ $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts'
+
+ old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a'
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib'
+ # can we support soname and/or expsyms with a.out? -oliva
+ fi
+ ;;
+
+ solaris* | sysv5*)
+ if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+ elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = yes; then
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ case $host_os in
+ cygwin* | mingw*)
+ # dlltool doesn't understand --whole-archive et. al.
+ whole_archive_flag_spec=
+ ;;
+ *)
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ ;;
+ esac
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case "$host_os" in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4*)
+ hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib'
+ hardcode_libdir_separator=':'
+ if test "$with_gcc" = yes; then
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ hardcode_direct=yes
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ shared_flag='-shared'
+ else
+ shared_flag='${wl}-bM:SRE'
+ hardcode_direct=yes
+ fi
+ allow_undefined_flag=' ${wl}-berok'
+ archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}'
+ archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}'
+ case "$host_os" in aix4.[01]|aix4.[01].*)
+ # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on
+ always_export_symbols=yes ;;
+ esac
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+
+ cygwin* | mingw*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs'
+ fix_srcfile_path='`cygpath -w $srcfile`'
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ case "$host_os" in
+ hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;;
+ *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;;
+ esac
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_minus_L=yes # Not in the search PATH, but as the default
+ # location of the library.
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6*)
+ if test "$with_gcc" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF
+ fi
+ hardcode_libdir_flag_spec='${wl}-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$with_gcc" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # As osf3* with the addition of the -msym flag
+ if test "$with_gcc" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case "$host_os" in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv5*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp'
+ hardcode_libdir_flag_spec=
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4.2uw2*)
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linkopts'
+ hardcode_direct=yes
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ hardcode_runpath_var=yes
+ runpath_var=LD_RUN_PATH
+ ;;
+
+ unixware7*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts'
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+if test -z "$NM"; then
+ echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+ case "$NM" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path.
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}"
+ for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -p"
+ break
+ else
+ NM=${NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$NM" && NM=nm
+ ;;
+ esac
+ echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ symcode='[BDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Write the raw and C identifiers.
+ global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+ $rm conftest*
+ cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ echo "$progname:1635: checking if global_symbol_pipe works" >&5
+ if { (eval echo $progname:1636: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { echo "$progname:1639: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$objext conftstm.$objext
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo $progname:1691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ pipe_works=yes
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$save_LIBS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ $rm conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ global_symbol_pipe=
+ fi
+done
+if test "$pipe_works" = yes; then
+ echo "${ac_t}ok" 1>&6
+else
+ echo "${ac_t}failed" 1>&6
+fi
+
+if test -z "$global_symbol_pipe"; then
+ global_symbol_to_cdecl=
+fi
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$hardcode_shlibpath_var" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+echo "$ac_t$hardcode_action" 1>&6
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linkers may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag" 1>&6
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+file_magic_cmd=
+file_magic_test_file=
+deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so$major'
+ ;;
+
+aix4*)
+ version_type=linux
+ # AIX has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ # We preserve .a as extension for shared libraries though AIX4.2
+ # and later linker supports .so
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a'
+ shlibpath_var=LIBPATH
+ deplibs_check_method=pass_all
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}.so'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ deplibs_check_method=pass_all
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+bsdi4*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/shlib/libc.so
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ export_dynamic_flag_spec=-rdynamic
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw*)
+ version_type=windows
+ need_version=no
+ need_lib_prefix=no
+ if test "$with_gcc" = yes; then
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a'
+ else
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+ fi
+ dynamic_linker='Win32 ld.exe'
+ deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ file_magic_cmd='${OBJDUMP} -f'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ case "$version_type" in
+ freebsd-elf*)
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /usr/lib/libc.so*`
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ deplibs_check_method=unknown
+ library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case "$host_os" in
+ freebsd2* | freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ *) # from 3.2 on
+ shlibpath_overrides_runpath=no
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+ soname_spec='${libname}${release}.sl$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5* | irix6*)
+ version_type=irix
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}.so.$major'
+ library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so'
+ case "$host_os" in
+ irix5*)
+ libsuff= shlibsuff=
+ # this will be overridden with pass_all, but let us keep it just in case
+ deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case "$LD" in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ deplibs_check_method='pass_all'
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+
+ if test -f /lib/ld.so.1; then
+ dynamic_linker='GNU ld.so'
+ else
+ # Only the GNU ld.so supports shared libraries on MkLinux.
+ case "$host_cpu" in
+ powerpc*) dynamic_linker=no ;;
+ *) dynamic_linker='Linux ld.so' ;;
+ esac
+ fi
+ ;;
+
+netbsd*)
+ version_type=sunos
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+openbsd*)
+ version_type=sunos
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ need_version=no
+ fi
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ need_lib_prefix=no
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_version=no
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ # this will be overridden with pass_all, but let us keep it just in case
+ deplibs_check_method='file_magic COFF format alpha shared library'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/shlib/libc.so
+ deplibs_check_method='pass_all'
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib"
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=/lib/libc.so
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case "$host_vendor" in
+ ncr)
+ deplibs_check_method='pass_all'
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ file_magic_cmd=/usr/bin/file
+ file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ esac
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+ soname_spec='$libname.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$ac_t$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in
+# configure.in, otherwise build static only libraries.
+case "$host_os" in
+cygwin* | mingw* | os2*)
+ if test x$can_build_shared = xyes; then
+ test x$enable_win32_dll = xno && can_build_shared=no
+ echo "checking if package supports dlls... $can_build_shared" 1>&6
+ fi
+;;
+esac
+
+if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then
+ case "$deplibs_check_method" in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+fi
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4*)
+ test "$enable_shared" = yes && enable_static=no
+ ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then
+ lt_cv_dlopen=no lt_cv_dlopen_libs=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "$progname:2212: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2220 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo $progname:2233: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "$progname:2252: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2257 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlopen(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2282: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "$progname:2299: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2307 "ltconfig"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo $progname:2320: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "$progname:2339: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2344 "ltconfig"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shl_load(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo $progname:2369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "$progname:2387: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2395 "ltconfig"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo $progname:2409: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+fi
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ fi
+
+ case "$lt_cv_dlopen" in
+ dlopen)
+for ac_hdr in dlfcn.h; do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "$progname:2452: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2457 "ltconfig"
+#include <$ac_hdr>
+int fnord = 0;
+EOF
+ac_try="$ac_compile >/dev/null 2>conftest.out"
+{ (eval echo $progname:2462: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ if test "x$ac_cv_header_dlfcn_h" = xyes; then
+ CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+ fi
+ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2490: checking whether a program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self+set}" = set; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ lt_cv_dlopen_self=cross
+ else
+ cat > conftest.c <<EOF
+#line 2498 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); }
+
+EOF
+if { (eval echo $progname:2544: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ lt_cv_dlopen_self=yes
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ lt_cv_dlopen_self=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+ if test "$lt_cv_dlopen_self" = yes; then
+ LDFLAGS="$LDFLAGS $link_static_flag"
+ echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "$progname:2563: checking whether a statically linked program can dlopen itself" >&5
+if test "${lt_cv_dlopen_self_static+set}" = set; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ lt_cv_dlopen_self_static=cross
+ else
+ cat > conftest.c <<EOF
+#line 2571 "ltconfig"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); }
+
+EOF
+if { (eval echo $progname:2617: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
+ lt_cv_dlopen_self_static=yes
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ lt_cv_dlopen_self_static=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+fi
+ ;;
+ esac
+
+ case "$lt_cv_dlopen_self" in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case "$lt_cv_dlopen_self_static" in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ ltecho="$CONFIG_SHELL \$0 --fallback-echo"
+fi
+LTSHELL="$SHELL"
+
+LTCONFIG_VERSION="$VERSION"
+
+# Only quote variables if we're using ltmain.sh.
+case "$ltmain" in
+*.sh)
+ # Now quote all the things that may contain metacharacters.
+ for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \
+ old_LD old_LDFLAGS old_LIBS \
+ old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \
+ AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \
+ reload_flag reload_cmds wl \
+ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+ library_names_spec soname_spec \
+ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \
+ file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+ hardcode_libdir_flag_spec hardcode_libdir_separator \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+ case "$var" in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ case "$ltecho" in
+ *'\$0 --fallback-echo"')
+ ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'`
+ ;;
+ esac
+
+ trap "$rm \"$ofile\"; exit 1" 1 2 15
+ echo "creating $ofile"
+ $rm "$ofile"
+ cat <<EOF > "$ofile"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+EOF
+ cfgfile="$ofile"
+ ;;
+
+*)
+ # Double-quote the variables that need it (for aesthetics).
+ for var in old_CC old_CFLAGS old_CPPFLAGS \
+ old_LD old_LDFLAGS old_LIBS \
+ old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do
+ eval "$var=\\\"\$var\\\""
+ done
+
+ # Just create a config file.
+ cfgfile="$ofile.cfg"
+ trap "$rm \"$cfgfile\"; exit 1" 1 2 15
+ echo "creating $cfgfile"
+ $rm "$cfgfile"
+ cat <<EOF > "$cfgfile"
+# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+EOF
+ ;;
+esac
+
+cat <<EOF >> "$cfgfile"
+# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\
+# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\
+# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\
+# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\
+# $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION=$LTCONFIG_VERSION
+
+# Shell to use when invoking shell scripts.
+SHELL=$LTSHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$ltecho
+
+# The archiver.
+AR=$AR
+
+# The default C compiler.
+CC=$CC
+
+# The linker used to build libraries.
+LD=$LD
+
+# Whether we need hard or soft links.
+LN_S=$LN_S
+
+# A BSD-compatible nm program.
+NM=$NM
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$reload_flag
+reload_cmds=$reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$wl
+
+# Object file suffix (normally "o").
+objext="$objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$pic_flag
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec=$library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$RANLIB
+old_archive_cmds=$old_archive_cmds
+old_postinstall_cmds=$old_postinstall_cmds
+old_postuninstall_cmds=$old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$old_archive_from_new_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$archive_cmds
+archive_expsym_cmds=$archive_expsym_cmds
+postinstall_cmds=$postinstall_cmds
+postuninstall_cmds=$postuninstall_cmds
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$global_symbol_to_cdecl
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$include_expsyms
+
+EOF
+
+case "$ltmain" in
+*.sh)
+ echo '### END LIBTOOL CONFIG' >> "$ofile"
+ echo >> "$ofile"
+ case "$host_os" in
+ aix3*)
+ cat <<\EOF >> "$ofile"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ # Append the ltmain.sh script.
+ sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1)
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+
+ chmod +x "$ofile"
+ ;;
+
+*)
+ # Compile the libtool program.
+ echo "FIXME: would compile $ltmain"
+ ;;
+esac
+
+test -n "$cache_file" || exit 0
+
+# AC_CACHE_SAVE
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/source/ltmain.sh b/source/ltmain.sh
new file mode 100644
index 00000000000..ba7a15576f9
--- /dev/null
+++ b/source/ltmain.sh
@@ -0,0 +1,4018 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell, and then maybe $echo will work.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.3.4
+TIMESTAMP=" (1.385.2.196 1999/12/07 21:47:57)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \015\012 \040\040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+ save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+ save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+ echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ echo "$modename: not configured to build any kind of library" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+ arg="$1"
+ shift
+
+ case "$arg" in
+ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ execute_dlfiles)
+ eval "$prev=\"\$$prev \$arg\""
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
+ prev=
+ prevopt=
+ continue
+ fi
+
+ # Have we seen a non-optional argument yet?
+ case "$arg" in
+ --help)
+ show_help=yes
+ ;;
+
+ --version)
+ echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+ exit 0
+ ;;
+
+ --config)
+ sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --dry-run | -n)
+ run=:
+ ;;
+
+ --features)
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+ exit 0
+ ;;
+
+ --finish) mode="finish" ;;
+
+ --mode) prevopt="--mode" prev=mode ;;
+ --mode=*) mode="$optarg" ;;
+
+ --quiet | --silent)
+ show=:
+ ;;
+
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
+ -*)
+ $echo "$modename: unrecognized option \`$arg'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ nonopt="$arg"
+ break
+ ;;
+ esac
+done
+
+if test -n "$prevopt"; then
+ $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+fi
+
+if test -z "$show_help"; then
+
+ # Infer the operation mode.
+ if test -z "$mode"; then
+ case "$nonopt" in
+ *cc | *++ | gcc* | *-gcc*)
+ mode=link
+ for arg
+ do
+ case "$arg" in
+ -c)
+ mode=compile
+ break
+ ;;
+ esac
+ done
+ ;;
+ *db | *dbx | *strace | *truss)
+ mode=execute
+ ;;
+ *install*|cp|mv)
+ mode=install
+ ;;
+ *rm)
+ mode=uninstall
+ ;;
+ *)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
+ # Just use the default operation mode.
+ if test -z "$mode"; then
+ if test -n "$nonopt"; then
+ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+ else
+ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+ fi
+ fi
+ ;;
+ esac
+ fi
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$modename --help --mode=$mode' for more information."
+
+ # These modes are in order of execution frequency so that they run quickly.
+ case "$mode" in
+ # libtool compile mode
+ compile)
+ modename="$modename: compile"
+ # Get the compilation command and the source file.
+ base_compile=
+ lastarg=
+ srcfile="$nonopt"
+ suppress_output=
+
+ user_target=no
+ for arg
+ do
+ # Accept any command-line options.
+ case "$arg" in
+ -o)
+ if test "$user_target" != "no"; then
+ $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+ exit 1
+ fi
+ user_target=next
+ ;;
+
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
+ esac
+
+ case "$user_target" in
+ next)
+ # The next one is the -o target name
+ user_target=yes
+ continue
+ ;;
+ yes)
+ # We got the output file
+ user_target=set
+ libobj="$arg"
+ continue
+ ;;
+ esac
+
+ # Accept the current argument as the source file.
+ lastarg="$srcfile"
+ srcfile="$arg"
+
+ # Aesthetically quote the previous argument.
+
+ # Backslashify any backslashes, double quotes, and dollar signs.
+ # These are the only characters that are still specially
+ # interpreted inside of double-quoted scrings.
+ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly in scan
+ # sets, so we specify it separately.
+ case "$lastarg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ lastarg="\"$lastarg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ done
+
+ case "$user_target" in
+ set)
+ ;;
+ no)
+ # Get the name of the library object.
+ libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ ;;
+ *)
+ $echo "$modename: you must specify a target with \`-o'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ xform='[cCFSfmso]'
+ case "$libobj" in
+ *.ada) xform=ada ;;
+ *.adb) xform=adb ;;
+ *.ads) xform=ads ;;
+ *.asm) xform=asm ;;
+ *.c++) xform=c++ ;;
+ *.cc) xform=cc ;;
+ *.cpp) xform=cpp ;;
+ *.cxx) xform=cxx ;;
+ *.f90) xform=f90 ;;
+ *.for) xform=for ;;
+ esac
+
+ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+ case "$libobj" in
+ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+ *)
+ $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$base_compile"; then
+ $echo "$modename: you must specify a compilation command" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $libobj"
+ else
+ removelist="$libobj"
+ fi
+
+ $run $rm $removelist
+ trap "$run $rm $removelist; exit 1" 1 2 15
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ removelist="$removelist $output_obj $lockfile"
+ trap "$run $rm $removelist; exit 1" 1 2 15
+ else
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until ln "$0" "$lockfile" 2>/dev/null; do
+ $show "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+ echo $srcfile > "$lockfile"
+ fi
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ command="$base_compile $srcfile $pic_flag -DPIC"
+ if test "$build_old_libs" = yes; then
+ lo_libobj="$libobj"
+ dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$libobj"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+ if test -d "$dir"; then
+ $show "$rm $libobj"
+ $run $rm $libobj
+ else
+ $show "$mkdir $dir"
+ $run $mkdir $dir
+ status=$?
+ if test $status -ne 0 && test ! -d $dir; then
+ exit $status
+ fi
+ fi
+ fi
+ if test "$compiler_o_lo" = yes; then
+ output_obj="$libobj"
+ command="$command -o $output_obj"
+ elif test "$compiler_c_o" = yes; then
+ output_obj="$obj"
+ command="$command -o $output_obj"
+ fi
+
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ test -n "$output_obj" && $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test x"$output_obj" != x"$libobj"; then
+ $show "$mv $output_obj $libobj"
+ if $run $mv $output_obj $libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # If we have no pic_flag, then copy the object into place and finish.
+ if test -z "$pic_flag" && test "$build_old_libs" = yes; then
+ # Rename the .lo from within objdir to obj
+ if test -f $obj; then
+ $show $rm $obj
+ $run $rm $obj
+ fi
+
+ $show "$mv $libobj $obj"
+ if $run $mv $libobj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
+ libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+ # Now arrange that obj and lo_libobj become the same file
+ $show "(cd $xdir && $LN_S $baseobj $libobj)"
+ if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
+ exit 0
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Allow error messages only from the first compilation.
+ suppress_output=' >/dev/null 2>&1'
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ command="$base_compile $srcfile"
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ output_obj="$obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed
+ if test x"$output_obj" != x"$obj"; then
+ $show "$mv $output_obj $obj"
+ if $run $mv $output_obj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we do not
+ # accidentally link it into a program.
+ if test "$build_libtool_libs" != yes; then
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > \$libobj" || exit $?
+ else
+ # Move the .lo from within objdir
+ $show "$mv $libobj $lo_libobj"
+ if $run $mv $libobj $lo_libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+ fi
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $rm "$lockfile"
+ fi
+
+ exit 0
+ ;;
+
+ # libtool link mode
+ link)
+ modename="$modename: link"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invokation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+
+ # This is a source program that is used to create dlls on Windows
+ # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+ # This is a source program that is used to create import libraries
+ # on Windows for dlls which lack them. Don't remove nor modify the
+ # starting and closing comments
+# /* impgen.c starts here */
+# /* Copyright (C) 1999 Free Software Foundation, Inc.
+#
+# This file is part of GNU libtool.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# */
+#
+# #include <stdio.h> /* for printf() */
+# #include <unistd.h> /* for open(), lseek(), read() */
+# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
+# #include <string.h> /* for strdup() */
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[2];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 2);
+# return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[4];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 4);
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+# void *ptr;
+# {
+# unsigned char *b = ptr;
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+# int argc;
+# char *argv[];
+# {
+# int dll;
+# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+# unsigned long export_rva, export_size, nsections, secptr, expptr;
+# unsigned long name_rvas, nexp;
+# unsigned char *expdata, *erva;
+# char *filename, *dll_name;
+#
+# filename = argv[1];
+#
+# dll = open(filename, O_RDONLY|O_BINARY);
+# if (!dll)
+# return 1;
+#
+# dll_name = filename;
+#
+# for (i=0; filename[i]; i++)
+# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+# dll_name = filename + i +1;
+#
+# pe_header_offset = pe_get32 (dll, 0x3c);
+# opthdr_ofs = pe_header_offset + 4 + 20;
+# num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+# if (num_entries < 1) /* no exports */
+# return 1;
+#
+# export_rva = pe_get32 (dll, opthdr_ofs + 96);
+# export_size = pe_get32 (dll, opthdr_ofs + 100);
+# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+# secptr = (pe_header_offset + 4 + 20 +
+# pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+# expptr = 0;
+# for (i = 0; i < nsections; i++)
+# {
+# char sname[8];
+# unsigned long secptr1 = secptr + 40 * i;
+# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# lseek(dll, secptr1, SEEK_SET);
+# read(dll, sname, 8);
+# if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# {
+# expptr = fptr + (export_rva - vaddr);
+# if (export_rva + export_size > vaddr + vsize)
+# export_size = vsize - (export_rva - vaddr);
+# break;
+# }
+# }
+#
+# expdata = (unsigned char*)malloc(export_size);
+# lseek (dll, expptr, SEEK_SET);
+# read (dll, expdata, export_size);
+# erva = expdata - export_rva;
+#
+# nexp = pe_as32 (expdata+24);
+# name_rvas = pe_as32 (expdata+32);
+#
+# printf ("EXPORTS\n");
+# for (i = 0; i<nexp; i++)
+# {
+# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+# }
+#
+# return 0;
+# }
+# /* impgen.c ends here */
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ compile_command="$nonopt"
+ finalize_command="$nonopt"
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ linkopts=
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ lib_search_path=
+ fi
+ # now prepend the system-specific ones
+ eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ link_against_libtool_libs=
+ ltlibs=
+ module=no
+ objs=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case "$arg" in
+ -all-static | -static)
+ if test "X$arg" = "X-all-static"; then
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ else
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ fi
+ build_libtool_libs=no
+ build_old_libs=yes
+ prefer_static_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test $# -gt 0; do
+ arg="$1"
+ shift
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ output)
+ compile_command="$compile_command @OUTPUT@"
+ finalize_command="$finalize_command @OUTPUT@"
+ ;;
+ esac
+
+ case "$prev" in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ compile_command="$compile_command @SYMFILE@"
+ finalize_command="$finalize_command @SYMFILE@"
+ preload=yes
+ fi
+ case "$arg" in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ if test ! -f "$arg"; then
+ $echo "$modename: symbol file \`$arg' does not exist"
+ exit 1
+ fi
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case "$arg" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi
+
+ prevarg="$arg"
+
+ case "$arg" in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+ continue
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: not more than one -exported-symbols argument allowed"
+ exit 1
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -L*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+ # We need an absolute path.
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ absdir="$dir"
+ fi
+ dir="$absdir"
+ ;;
+ esac
+ case " $deplibs " in
+ *" $arg "*) ;;
+ *) deplibs="$deplibs $arg";;
+ esac
+ case " $lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir";;
+ esac
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+ case ":$dllsearchpath:" in
+ ::) dllsearchpath="$dllsearchdir";;
+ *":$dllsearchdir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
+ esac
+ ;;
+ esac
+ ;;
+
+ -l*)
+ if test "$arg" = "-lc"; then
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+ # These systems don't actually have c library (as such)
+ continue
+ ;;
+ esac
+ elif test "$arg" = "-lm"; then
+ case "$host" in
+ *-*-cygwin* | *-*-beos*)
+ # These systems don't actually have math library (as such)
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+ # We need an absolute path.
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -static)
+ # If we have no pic_flag, then this is the same as -all-static.
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+
+ *.o | *.obj | *.a | *.lib)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A library object.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+ prev=
+ fi
+ libobjs="$libobjs $arg"
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ dlname=
+ libdir=
+ library_names=
+ old_library=
+
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variable installed.
+ installed=yes
+
+ # Read the .la file
+ # If there is no directory component, then add one.
+ case "$arg" in
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
+ esac
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+
+ if test -z "$linklib"; then
+ $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Find the relevant object directory and library name.
+ name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+ if test "X$installed" = Xyes; then
+ dir="$libdir"
+ else
+ dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$arg"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ fi
+
+ if test -n "$dependency_libs"; then
+ # Extract -R and -L from dependency_libs
+ temp_deplibs=
+ for deplib in $dependency_libs; do
+ case "$deplib" in
+ -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+ case " $rpath $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ -L*) case "$compile_command $temp_deplibs " in
+ *" $deplib "*) ;;
+ *) temp_deplibs="$temp_deplibs $deplib";;
+ esac
+ temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+ case " $lib_search_path " in
+ *" $temp_dir "*) ;;
+ *) lib_search_path="$lib_search_path $temp_dir";;
+ esac
+ ;;
+ *) temp_deplibs="$temp_deplibs $deplib";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ if test -z "$libdir"; then
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $dir/$old_library"
+ old_convenience="$old_convenience $dir/$old_library"
+ deplibs="$deplibs$dependency_libs"
+ compile_command="$compile_command $dir/$old_library$dependency_libs"
+ finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+ continue
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking statically,
+ # we need to preload.
+ prev=dlprefiles
+ else
+ # We should not create a dependency on this library, but we
+ # may need any libraries it requires.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ prev=
+ continue
+ fi
+ fi
+
+ # The library was specified with -dlpreopen.
+ if test "$prev" = dlprefiles; then
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ dlprefiles="$dlprefiles $dir/$old_library"
+ else
+ dlprefiles="$dlprefiles $dir/$linklib"
+ fi
+ prev=
+ fi
+
+ if test -n "$library_names" &&
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ link_against_libtool_libs="$link_against_libtool_libs $arg"
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
+
+ # We need an absolute path.
+ case "$dir" in
+ [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ absdir="$dir"
+ fi
+ ;;
+ esac
+
+ # This is the magic to use -rpath.
+ # Skip directories that are in the system default run-time
+ # search path, unless they have been requested with -R.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+
+ lib_linked=yes
+ case "$hardcode_action" in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ compile_command="$compile_command $dir/$linklib"
+ deplibs="$deplibs $dir/$linklib"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+ if test -n "$dllsearchpath"; then
+ dllsearchpath="$dllsearchpath:$dllsearchdir"
+ else
+ dllsearchpath="$dllsearchdir"
+ fi
+ ;;
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case "$host" in
+ *-*-sunos*)
+ compile_shlibpath="$compile_shlibpath$dir:"
+ ;;
+ esac
+ case "$compile_command " in
+ *" -L$dir "*) ;;
+ *) compile_command="$compile_command -L$dir";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -L$dir -l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ case ":$compile_shlibpath:" in
+ *":$dir:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$dir:";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ relink)
+ if test "$hardcode_direct" = yes; then
+ compile_command="$compile_command $absdir/$linklib"
+ deplibs="$deplibs $absdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ case "$compile_command " in
+ *" -L$absdir "*) ;;
+ *) compile_command="$compile_command -L$absdir";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -L$absdir -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case ":$compile_shlibpath:" in
+ *":$absdir:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$absdir:";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ *)
+ lib_linked=no
+ ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ $echo "$modename: configuration error: unsupported hardcode properties"
+ exit 1
+ fi
+
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes; then
+ finalize_command="$finalize_command $libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ case "$finalize_command " in
+ *" -L$libdir "*) ;;
+ *) finalize_command="$finalize_command -L$libdir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case ":$finalize_shlibpath:" in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ case "$finalize_command " in
+ *" -L$dir "*) ;;
+ *) finalize_command="$finalize_command -L$libdir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ fi
+ else
+ # Transform directly to old archives if we don't build new libraries.
+ if test -n "$pic_flag" && test -z "$old_library"; then
+ $echo "$modename: cannot find static library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_command="$compile_command $dir/$linklib"
+ finalize_command="$finalize_command $dir/$linklib"
+ else
+ case "$compile_command " in
+ *" -L$dir "*) ;;
+ *) compile_command="$compile_command -L$dir";;
+ esac
+ compile_command="$compile_command -l$name"
+ case "$finalize_command " in
+ *" -L$dir "*) ;;
+ *) finalize_command="$finalize_command -L$dir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ fi
+ fi
+
+ # Add in any libraries that this one depends upon.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+ esac
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+ done
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+ libobjs_save="$libobjs"
+
+ case "$output" in
+ "")
+ $echo "$modename: you must specify an output file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *.a | *.lib)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+ fi
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ ;;
+
+ *.la)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case "$outputname" in
+ lib*)
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ if test "$module" = no; then
+ $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ eval libname=\"$libname_spec\"
+ else
+ libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ fi
+ ;;
+ esac
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ if test -n "$objs"; then
+ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+ exit 1
+ fi
+
+ # How the heck are we supposed to write a wrapper for a shared library?
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+ exit 1
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+ fi
+
+ set dummy $rpath
+ if test $# -gt 2; then
+ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+ fi
+ install_libdir="$2"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ libext=al
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+ dependency_libs="$deplibs"
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+ fi
+ else
+
+ # Parse the version information argument.
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ IFS="$save_ifs"
+
+ if test -n "$8"; then
+ $echo "$modename: too many parameters to \`-version-info'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ current="$2"
+ revision="$3"
+ age="$4"
+
+ # Check that each of the things are valid numbers.
+ case "$current" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$revision" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$age" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test $age -gt $current; then
+ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case "$version_type" in
+ none) ;;
+
+ irix)
+ major=`expr $current - $age + 1`
+ versuffix="$major.$revision"
+ verstring="sgi$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test $loop != 0; do
+ iface=`expr $revision - $loop`
+ loop=`expr $loop - 1`
+ verstring="sgi$major.$iface:$verstring"
+ done
+ ;;
+
+ linux)
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ major=`expr $current - $age`
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test $loop != 0; do
+ iface=`expr $current - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current";
+ ;;
+
+ windows)
+ # Like Linux, but with '-' rather than '.', since we only
+ # want one extension on Windows 95.
+ major=`expr $current - $age`
+ versuffix="-$major-$age-$revision"
+ ;;
+
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ verstring="0.0"
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ dependency_libs="$deplibs"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *)
+ # Add libc to deplibs on all other systems.
+ deplibs="$deplibs -lc"
+ ;;
+ esac
+ fi
+
+ # Create the output directory, or remove our outputs if we need to.
+ if test -d $output_objdir; then
+ $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+ $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+ else
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ if test "$build_libtool_libs" = yes; then
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case "$deplibs_check_method" in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behaviour.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $rm conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $rm conftest
+ $CC -o conftest conftest.c $deplibs
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ else
+ # Error occured in the first compile. Let's try to salvage the situation:
+ # Compile a seperate program for each library.
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ $rm conftest
+ $CC -o conftest conftest.c $i
+ # Did it work?
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null \
+ | grep " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+ case "$potliblink" in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+ | sed 10q \
+ | egrep "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+ -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' |
+ grep . >/dev/null; then
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ echo "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ # Get the real and link names of the library.
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ lib="$output_objdir/$realname"
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Ensure that we have .o objects for linkers which dislike .lo
+ # (e.g. aix) in case we are running --disable-static
+ for obj in $libobjs; do
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+ oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+ if test ! -f $xdir/$oldobj; then
+ $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
+ $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
+ fi
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ $show "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $run $rm $export_symbols
+ eval cmds=\"$export_symbols_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex"; then
+ $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+ $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+ $run eval '$mv "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+ fi
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linkopts="$linkopts $flag"
+ fi
+
+ # Do each of the archive commands.
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval cmds=\"$archive_expsym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ *.lo | *.o | *.obj)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+ fi
+
+ case "$output" in
+ *.lo)
+ if test -n "$objs"; then
+ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+ exit 1
+ fi
+ libobj="$output"
+ obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $run $rm $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${obj}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs"
+
+ output="$obj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > $libobj" || exit $?
+ exit 0
+ fi
+
+ if test -n "$pic_flag"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ else
+ # Just create a symlink.
+ $show $rm $libobj
+ $run $rm $libobj
+ xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$libobj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+ oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+ $show "(cd $xdir && $LN_S $oldobj $baseobj)"
+ $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
+ fi
+
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ ;;
+
+ # Anything else should be a program.
+ *)
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+ fi
+
+ if test "$preload" = yes; then
+ if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
+ test "$dlopen_self_static" = unknown; then
+ $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+ fi
+ fi
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$compile_rpath " in
+ *" $libdir "*) ;;
+ *) compile_rpath="$compile_rpath $libdir" ;;
+ esac
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ # Create the binary in the object directory, then wrap it.
+ if test ! -d $output_objdir; then
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ dlsyms=
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ dlsyms="${outputname}S.c"
+ else
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+ fi
+ fi
+
+ if test -n "$dlsyms"; then
+ case "$dlsyms" in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${outputname}.nm"
+
+ $show "$rm $nlist ${nlist}S ${nlist}T"
+ $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+ # Parse the name list into a source file.
+ $show "creating $output_objdir/$dlsyms"
+
+ test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ $show "generating symbol list for \`$output'"
+
+ test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for arg in $progfiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$output.exp"
+ $run $rm $export_symbols
+ $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ else
+ $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+ $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+ $run eval 'mv "$nlist"T "$nlist"'
+ fi
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ name=`echo "$arg" | sed -e 's%^.*/%%'`
+ $run eval 'echo ": $name " >> "$nlist"'
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -z "$run"; then
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $mv "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+ :
+ else
+ grep -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+ sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \
+ -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \
+ < "$nlist" >> "$output_objdir/$dlsyms"
+
+ $echo >> "$output_objdir/$dlsyms" "\
+ {0, (lt_ptr_t) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ fi
+
+ pic_flag_for_symtable=
+ case "$host" in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+ esac;;
+ *-*-hpux*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC";;
+ esac
+ esac
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+ $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+ # Clean up the generated files.
+ $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+ $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+ # Transform the symbol file into the correct name.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ ;;
+ *)
+ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+ exit 1
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ $show "$link_command"
+ $run eval "$link_command"
+ status=$?
+
+ # Delete the generated files.
+ if test -n "$dlsyms"; then
+ $show "$rm $output_objdir/${outputname}S.${objext}"
+ $run $rm "$output_objdir/${outputname}S.${objext}"
+ fi
+
+ exit $status
+ fi
+
+ if test -n "$shlibpath_var"; then
+ # We should set the shlibpath_var
+ rpath=
+ for dir in $temp_rpath; do
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*)
+ # Absolute path.
+ rpath="$rpath$dir:"
+ ;;
+ *)
+ # Relative path: add a thisdir entry.
+ rpath="$rpath\$thisdir/$dir:"
+ ;;
+ esac
+ done
+ temp_rpath="$rpath"
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+ $echo "$modename: \`$output' will be relinked during installation" 1>&2
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+
+ # Now create the wrapper script.
+ $show "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $echo for shipping.
+ if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+ case "$0" in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+ esac
+ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if our run command is non-null.
+ if test -z "$run"; then
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+ esac
+ $rm $output
+ trap "$rm $output; exit 1" 1 2 15
+
+ # quick and dirty hack by Elrond <Elrond@Wunder-Nett.org>
+ # to get libtool work with paths in its
+ # output names.
+ relink_curdir="`pwd`"
+
+ $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_curdir=\"$relink_curdir\"
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variable:
+ link_against_libtool_libs='$link_against_libtool_libs'
+else
+ # When we are sourced in execute mode, \$file and \$echo are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ echo=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$echo works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$echo will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $echo >> $output "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+ done
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ echo >> $output "\
+ program=lt-'$outputname'
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" || \\
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $mkdir \"\$progdir\"
+ else
+ $rm \"\$progdir/\$file\"
+ fi"
+
+ echo >> $output "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if (cd \"\$relink_curdir\" && eval \$relink_command); then :
+ else
+ $rm \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $rm \"\$progdir/\$program\";
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $rm \"\$progdir/\$file\"
+ fi"
+ else
+ echo >> $output "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ echo >> $output "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $echo >> $output "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $echo >> $output "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $echo >> $output "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ *-*-cygwin* | *-*-mingw | *-*-os2*)
+ # win32 systems need to use the prog path for dll
+ # lookup to work
+ $echo >> $output "\
+ exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+ ;;
+ *)
+ $echo >> $output "\
+ # Export the path to the program.
+ PATH=\"\$progdir:\$PATH\"
+ export PATH
+
+ exec \$program \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $echo >> $output "\
+ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"This script is just a wrapper for \$program.\" 1>&2
+ echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+ chmod +x $output
+ fi
+ exit 0
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ # Add in members from convenience archives.
+ for xlib in $addlibs; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ eval cmds=\"$old_archive_from_new_cmds\"
+ else
+ # Ensure that we have .o objects in place in case we decided
+ # not to build a shared library, and have fallen back to building
+ # static libs even though --disable-static was passed!
+ for oldobj in $oldobjs; do
+ if test ! -f $oldobj; then
+ xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$oldobj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
+ obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+ $show "(cd $xdir && ${LN_S} $obj $baseobj)"
+ $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
+ fi
+ done
+
+ eval cmds=\"$old_archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$generated"; then
+ $show "${rm}r$generated"
+ $run ${rm}r$generated
+ fi
+
+ # Now create the libtool archive.
+ case "$output" in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ $show "creating $output"
+
+ if test -n "$xrpath"; then
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ done
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+
+ # Only create the output if not a dry run.
+ if test -z "$run"; then
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ fi
+ $rm $output
+ $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+ done
+ fi
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+ $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
+ ;;
+ esac
+ exit 0
+ ;;
+
+ # libtool install mode
+ install)
+ modename="$modename: install"
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+ # Aesthetically quote it.
+ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$arg "
+ arg="$1"
+ shift
+ else
+ install_prog=
+ arg="$nonopt"
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog$arg"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest="$arg"
+ continue
+ fi
+
+ case "$arg" in
+ -d) isdir=yes ;;
+ -f) prev="-f" ;;
+ -g) prev="-g" ;;
+ -m) prev="-m" ;;
+ -o) prev="-o" ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*) ;;
+
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest="$arg"
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog $arg"
+ done
+
+ if test -z "$install_prog"; then
+ $echo "$modename: you must specify an install program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prev' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ $echo "$modename: no file or destination specified" 1>&2
+ else
+ $echo "$modename: you must specify a destination" 1>&2
+ fi
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Strip any trailing slash from the destination.
+ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$destdir" = "X$dest" && destdir=.
+ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files
+ if test $# -gt 2; then
+ $echo "$modename: \`$dest' is not a directory" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ fi
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case "$file" in
+ *.lo) ;;
+ *)
+ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case "$file" in
+ *.a | *.lib)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ library_names=
+ old_library=
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+ test "X$dir" = "X$file/" && dir=
+ dir="$dir$objdir"
+
+ # See the names of the shared library.
+ set dummy $library_names
+ if test -n "$2"; then
+ realname="$2"
+ shift
+ shift
+
+ # Install the shared library and build the symlinks.
+ $show "$install_prog $dir/$realname $destdir/$realname"
+ $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+
+ if test $# -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ for linkname
+ do
+ if test "$linkname" != "$realname"; then
+ $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ fi
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ eval cmds=\"$postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Install the pseudo-library for information purposes.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ instname="$dir/$name"i
+ $show "$install_prog $instname $destdir/$name"
+ $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case "$destfile" in
+ *.lo)
+ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+ ;;
+ *.o | *.obj)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ if test -n "$destfile"; then
+ $show "$install_prog $file $destfile"
+ $run eval "$install_prog $file $destfile" || exit $?
+ fi
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+ $show "$install_prog $staticobj $staticdest"
+ $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+ fi
+ exit 0
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ link_against_libtool_libs=
+ relink_command=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Check the variables that should have been set.
+ if test -z "$link_against_libtool_libs"; then
+ $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+ exit 1
+ fi
+
+ finalize=yes
+ for lib in $link_against_libtool_libs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ # If there is no directory component, then add one.
+ case "$lib" in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ fi
+ libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+ finalize=no
+ fi
+ done
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ if test "$finalize" = yes && test -z "$run"; then
+ tmpdir="/tmp"
+ test -n "$TMPDIR" && tmpdir="$TMPDIR"
+ tmpdir="$tmpdir/libtool-$$"
+ if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+ else
+ $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+ continue
+ fi
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ ${rm}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ $echo "$modename: warning: cannot relink \`$file'" 1>&2
+ fi
+ else
+ # Install the binary that we compiled earlier.
+ file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ $show "$install_prog$stripme $file $destfile"
+ $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+ test -n "$outputname" && ${rm}r "$tmpdir"
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ $show "$install_prog $file $oldlib"
+ $run eval "$install_prog \$file \$oldlib" || exit $?
+
+ # Do each command in the postinstall commands.
+ eval cmds=\"$old_postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$future_libdirs"; then
+ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+ fi
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ test -n "$run" && current_libdirs=" -n$current_libdirs"
+ exec $SHELL $0 --finish$current_libdirs
+ exit 1
+ fi
+
+ exit 0
+ ;;
+
+ # libtool finish mode
+ finish)
+ modename="$modename: finish"
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ eval cmds=\"$finish_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || admincmds="$admincmds
+ $cmd"
+ done
+ IFS="$save_ifs"
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $run eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ test "$show" = : && exit 0
+
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ echo " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ echo " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ echo " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+ echo "See any operating system documentation about shared libraries for"
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ echo "----------------------------------------------------------------------"
+ exit 0
+ ;;
+
+ # libtool execute mode
+ execute)
+ modename="$modename: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ $echo "$modename: you must specify a COMMAND" 1>&2
+ $echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test ! -f "$file"; then
+ $echo "$modename: \`$file' is not a file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case "$file" in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case "$file" in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+ args="$args \"$file\""
+ done
+
+ if test -z "$run"; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved enviroment variables
+ if test "${save_LC_ALL+set}" = set; then
+ LC_ALL="$save_LC_ALL"; export LC_ALL
+ fi
+ if test "${save_LANG+set}" = set; then
+ LANG="$save_LANG"; export LANG
+ fi
+
+ # Now actually exec the command.
+ eval "exec \$cmd$args"
+
+ $echo "$modename: cannot exec \$cmd$args"
+ exit 1
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+ $echo "export $shlibpath_var"
+ fi
+ $echo "$cmd$args"
+ exit 0
+ fi
+ ;;
+
+ # libtool uninstall mode
+ uninstall)
+ modename="$modename: uninstall"
+ rm="$nonopt"
+ files=
+
+ for arg
+ do
+ case "$arg" in
+ -*) rm="$rm $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ if test -z "$rm"; then
+ $echo "$modename: you must specify an RM program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ for file in $files; do
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ rmfiles="$file"
+
+ case "$name" in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ . $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $dir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ eval cmds=\"$postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ eval cmds=\"$old_postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ # FIXME: should reinstall the best remaining shared library.
+ fi
+ ;;
+
+ *.lo)
+ if test "$build_old_libs" = yes; then
+ oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+ rmfiles="$rmfiles $dir/$oldobj"
+ fi
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+
+ *)
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+ esac
+ done
+ exit 0
+ ;;
+
+ "")
+ $echo "$modename: you must specify a MODE" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+-n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --finish same as \`--mode=finish'
+ --help display this help message and exit
+ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
+ --quiet same as \`--silent'
+ --silent don't print informational messages
+ --version print version information
+
+MODE must be one of the following:
+
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+ exit 0
+ ;;
+
+compile)
+ $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -static always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+execute)
+ $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+finish)
+ $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+install)
+ $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+link)
+ $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -static do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+uninstall)
+ $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+*)
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/source/mem_man/mem_man.c b/source/mem_man/mem_man.c
new file mode 100644
index 00000000000..ec0ac1dd5ff
--- /dev/null
+++ b/source/mem_man/mem_man.c
@@ -0,0 +1,742 @@
+#if MEM_MAN
+/* a simple memory manager. All allocates and frees should go through here */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define MEM_MAN_MAIN
+
+#include "mem_man.h"
+
+#ifdef MEM_SIGNAL_HANDLER
+#include <signal.h>
+#endif
+
+/*
+ this module is stand alone. typically a define will occur in a C file
+ like this
+
+ #define malloc(x) smb_mem_malloc(x,__FILE__,__LINE__)
+ #define free(x) smb_mem_free(x,__FILE__,__LINE__)
+
+ which redirects all calls to malloc and free through this module
+
+ Various configuration options can be set in mem_man.h. This file also
+ includes the defines above - so the complete system can be implemented
+ with just one include call.
+
+
+ */
+
+extern FILE *dbf;
+
+/*
+ ACCESSING the memory manager :
+
+ mem_init_memory_manager() :
+ initialises internal data structures of memory manager
+
+ void *malloc(size_t size) :
+ allocates memory as per usual. also records lots of info
+
+ int free(void *ptr) :
+ frees some memory as per usual. writes errors if necessary.
+
+ void *smb_mem_resize(void *ptr,size_t newsize) :
+ changes the memory assignment size of a pointer. note it may return a
+ different pointer than the one given. memory can be sized up or down.
+
+ int smb_mem_query_size(void *ptr) :
+ returns the size of the allocated memory.
+
+ int smb_mem_query_real_size(void *ptr) :
+ returns the actual amount of memory allocated to a pointer.
+
+ char *smb_mem_query_file(void *ptr) :
+ returns the name of the file where the pointer was allocated.
+
+ int smb_mem_query_line(void *ptr) :
+ returns the line of the file where the memory was allocated.
+
+ void smb_mem_write_status(FILE *outfile) :
+ writes short summary of memory stats on the stream.
+
+ void smb_mem_write_verbose(FILE *outfile) :
+ writes lots of info on current allocations to stream.
+
+ void smb_mem_write_errors(FILE *outfile) :
+ writes info on error blocks
+
+ void smb_mem_write_info(void *ptr,FILE *outfile)
+ writes info on one pointer to outfile
+
+ int smb_mem_test(void *ptr) :
+ returns true if the pointer is OK - false if it is not.
+
+ void smb_mem_set_multiplier(int multiplier) :
+ sets defaults amount of memory allocated to multiplier times
+ amount requested.
+
+ int smb_mem_total_errors(void) :
+ returns the total number of error blocks
+
+ void smb_mem_check_buffers(void) :
+ checks all buffers for corruption. It marks them as corrupt if they are.
+
+ kill -USR1 <pid> :
+ this will send a signal to the memory manager to do a mem_write_verbose
+ it also checks them for corruption. Note that the signal number can be
+ set in the header file mem_man.h. This can also be turned off.
+
+ */
+
+
+void smb_mem_write_errors(FILE *outfile);
+void smb_mem_write_verbose(FILE *outfile);
+void smb_mem_write_status(FILE *outfile);
+static void mem_check_buffers(void);
+
+
+#define FREE_FAILURE 0
+#define FREE_SUCCESS 1
+#define FN
+#define True (0==0)
+#define False (!True)
+#define BUF_SIZE (MEM_CORRUPT_BUFFER * sizeof(char) * 2)
+#define BUF_OFFSET (BUF_SIZE/2)
+
+typedef struct
+{
+ void *pointer;
+ size_t present_size;
+ size_t allocated_size;
+ unsigned char status;
+ short error_number;
+ char file[MEM_FILE_STR_LENGTH];
+ unsigned short line;
+} memory_struct;
+
+/* the order of this enum is important. everything greater than
+ S_ALLOCATED is considered an error */
+enum status_types {S_UNALLOCATED,S_ALLOCATED,
+ S_ERROR_UNALLOCATED,S_ERROR_FREEING,
+ S_CORRUPT_FRONT,S_CORRUPT_BACK,S_CORRUPT_FRONT_BACK};
+
+/* here is the data memory */
+
+static memory_struct *memory_blocks=NULL; /* these hold the allocation data */
+static int mem_blocks_allocated=0; /* how many mem blocks are allocated */
+static int mem_multiplier; /* this is the current multiplier mor over allocation */
+static int mem_manager_initialised=False; /* has it been initialised ? */
+static int last_block_allocated=0; /* a speed up method - this will contain the
+ index of the last block allocated or freed
+ to cut down searching time for a new block */
+
+
+typedef struct
+{
+ int status;
+ char *label;
+} stat_str_type;
+
+static stat_str_type stat_str_struct[] =
+{
+{S_UNALLOCATED,"S_UNALLOCATED"},
+{S_ALLOCATED,"S_ALLOCATED"},
+{S_ERROR_UNALLOCATED,"S_ERROR_UNALLOCATED"},
+{S_ERROR_FREEING,"S_ERROR_FREEING"},
+{S_CORRUPT_FRONT,"S_CORRUPT_FRONT"},
+{S_CORRUPT_BACK,"S_CORRUPT_BACK"},
+{S_CORRUPT_FRONT_BACK,"S_CORRUPT_FRONT_BACK"},
+{-1,NULL}
+};
+
+
+#define INIT_MANAGER() if (!mem_manager_initialised) mem_init_memory_manager()
+
+/*******************************************************************
+ returns a pointer to a static string for each status
+ ********************************************************************/
+static char *status_to_str(int status)
+{
+ int i=0;
+ while (stat_str_struct[i].label != NULL)
+ {
+ if (stat_str_struct[i].status == status)
+ return(stat_str_struct[i].label);
+ i++;
+ }
+ return(NULL);
+}
+
+
+
+#ifdef MEM_SIGNAL_HANDLER
+/*******************************************************************
+ this handles signals - causes a mem_write_verbose on stderr
+ ********************************************************************/
+static void mem_signal_handler()
+{
+ mem_check_buffers();
+ smb_mem_write_verbose(dbf);
+ signal(MEM_SIGNAL_VECTOR,mem_signal_handler);
+}
+#endif
+
+#ifdef MEM_SIGNAL_HANDLER
+/*******************************************************************
+ this handles error signals - causes a mem_write_verbose on stderr
+ ********************************************************************/
+static void error_signal_handler()
+{
+ fprintf(dbf,"Received error signal!\n");
+ mem_check_buffers();
+ smb_mem_write_status(dbf);
+ smb_mem_write_errors(dbf);
+}
+#endif
+
+
+/*******************************************************************
+ initialise memory manager data structures
+ ********************************************************************/
+static void mem_init_memory_manager(void)
+{
+ int i;
+ /* allocate the memory_blocks array */
+ mem_blocks_allocated = MEM_MAX_MEM_OBJECTS;
+
+ while (mem_blocks_allocated > 0)
+ {
+ memory_blocks = (memory_struct *)
+ calloc(mem_blocks_allocated,sizeof(memory_struct));
+ if (memory_blocks != NULL) break;
+ mem_blocks_allocated /= 2;
+ }
+
+ if (memory_blocks == NULL)
+ {
+ fprintf(dbf,"Panic ! can't allocate mem manager blocks!\n");
+ abort();
+ }
+
+ /* just loop setting status flag to unallocated */
+ for (i=0;i<mem_blocks_allocated;i++)
+ memory_blocks[i].status = S_UNALLOCATED;
+
+ /* also set default mem multiplier */
+ mem_multiplier = MEM_DEFAULT_MEM_MULTIPLIER;
+ mem_manager_initialised=True;
+
+#ifdef MEM_SIGNAL_HANDLER
+ signal(MEM_SIGNAL_VECTOR,mem_signal_handler);
+ signal(SIGSEGV,error_signal_handler);
+ signal(SIGBUS,error_signal_handler);
+#endif
+
+}
+
+
+/*******************************************************************
+ finds first available slot in memory blocks
+ ********************************************************************/
+static int mem_first_avail_slot(void)
+{
+ int i;
+ for (i=last_block_allocated;i<mem_blocks_allocated;i++)
+ if (memory_blocks[i].status == S_UNALLOCATED)
+ return(last_block_allocated=i);
+ for (i=0;i<last_block_allocated;i++)
+ if (memory_blocks[i].status == S_UNALLOCATED)
+ return(last_block_allocated=i);
+ return(-1);
+}
+
+
+/*******************************************************************
+ find which Index a pointer refers to
+ ********************************************************************/
+static int mem_find_Index(const void *ptr)
+{
+ int i;
+ int start = last_block_allocated+mem_blocks_allocated/50;
+ if (start > mem_blocks_allocated-1) start = mem_blocks_allocated-1;
+ for (i=start;i>=0;i--)
+ if ((memory_blocks[i].status == S_ALLOCATED) &&
+ (memory_blocks[i].pointer == ptr))
+ return(i);
+ for (i=(start+1);i<mem_blocks_allocated;i++)
+ if ((memory_blocks[i].status == S_ALLOCATED) &&
+ (memory_blocks[i].pointer == ptr))
+ return(i);
+ /* it's not there! */
+ return(-1);
+}
+
+/*******************************************************************
+ fill the buffer areas of a mem block
+ ********************************************************************/
+static void mem_fill_bytes(void *p,int size,int Index)
+{
+ memset(p,Index%256,size);
+}
+
+/*******************************************************************
+ fill the buffer areas of a mem block
+ ********************************************************************/
+static void mem_fill_buffer(int Index)
+{
+ char *iptr,*tailptr;
+ int i;
+ int seed;
+
+ /* fill the front and back ends */
+ seed = MEM_CORRUPT_SEED;
+ iptr = (char *)((char *)memory_blocks[Index].pointer - BUF_OFFSET);
+ tailptr = (char *)((char *)memory_blocks[Index].pointer +
+ memory_blocks[Index].present_size);
+
+ for (i=0;i<MEM_CORRUPT_BUFFER;i++)
+ {
+ iptr[i] = seed;
+ tailptr[i] = seed;
+ seed += MEM_SEED_INCREMENT;
+ }
+}
+
+/*******************************************************************
+ check if a mem block is corrupt
+ ********************************************************************/
+static int mem_buffer_ok(int Index)
+{
+ char *iptr;
+ int i;
+ int corrupt_front = False;
+ int corrupt_back = False;
+
+ /* check the front end */
+ iptr = (char *)((char *)memory_blocks[Index].pointer - BUF_OFFSET);
+ for (i=0;i<MEM_CORRUPT_BUFFER;i++)
+ if (iptr[i] != (char)(MEM_CORRUPT_SEED + i*MEM_SEED_INCREMENT))
+ corrupt_front = True;
+
+ /* now check the tail end */
+ iptr = (char *)((char *)memory_blocks[Index].pointer +
+ memory_blocks[Index].present_size);
+ for (i=0;i<MEM_CORRUPT_BUFFER;i++)
+ if (iptr[i] != (char)(MEM_CORRUPT_SEED + i*MEM_SEED_INCREMENT))
+ corrupt_back = True;
+
+ if (corrupt_front && !corrupt_back)
+ memory_blocks[Index].status = S_CORRUPT_FRONT;
+ if (corrupt_back && !corrupt_front)
+ memory_blocks[Index].status = S_CORRUPT_BACK;
+ if (corrupt_front && corrupt_back)
+ memory_blocks[Index].status = S_CORRUPT_FRONT_BACK;
+ if (!corrupt_front && !corrupt_back)
+ return(True);
+ return(False);
+}
+
+
+/*******************************************************************
+ check all buffers for corruption
+ ********************************************************************/
+static void mem_check_buffers(void)
+{
+ int i;
+ for (i=0;i<mem_blocks_allocated;i++)
+ if (memory_blocks[i].status == S_ALLOCATED)
+ mem_buffer_ok(i);
+}
+
+
+/*******************************************************************
+ record stats and alloc memory
+ ********************************************************************/
+void *smb_mem_malloc(size_t size,char *file,int line)
+{
+ int Index;
+ INIT_MANAGER();
+
+ /* find an open spot */
+
+ Index = mem_first_avail_slot();
+ if (Index<0) return(NULL);
+
+ /* record some info */
+ memory_blocks[Index].present_size = size;
+ memory_blocks[Index].allocated_size = size*mem_multiplier;
+ memory_blocks[Index].line = line;
+ strncpy(memory_blocks[Index].file,file,MEM_FILE_STR_LENGTH);
+ memory_blocks[Index].file[MEM_FILE_STR_LENGTH-1] = 0;
+ memory_blocks[Index].error_number = 0;
+
+ /* now try and actually get the memory */
+ memory_blocks[Index].pointer = malloc(size*mem_multiplier + BUF_SIZE);
+
+ /* if that failed then try and get exactly what was actually requested */
+ if (memory_blocks[Index].pointer == NULL)
+ {
+ memory_blocks[Index].allocated_size = size;
+ memory_blocks[Index].pointer = malloc(size + BUF_SIZE);
+ }
+
+ /* if it failed then return NULL */
+ if (memory_blocks[Index].pointer == NULL) return(NULL);
+
+
+ /* it succeeded - set status flag and return */
+ memory_blocks[Index].status = S_ALLOCATED;
+
+ /* add an offset */
+ memory_blocks[Index].pointer =
+ (void *)((char *)memory_blocks[Index].pointer + BUF_OFFSET);
+
+ /* fill the buffer appropriately */
+ mem_fill_buffer(Index);
+
+ /* and set the fill byte */
+ mem_fill_bytes(memory_blocks[Index].pointer,memory_blocks[Index].present_size,Index);
+
+ /* return the allocated memory */
+ return(memory_blocks[Index].pointer);
+}
+
+
+/*******************************************************************
+dup a string
+ ********************************************************************/
+char *smb_mem_strdup(const char *s, char *file, int line)
+{
+ char *ret = (char *)smb_mem_malloc(strlen(s)+1, file, line);
+ strcpy(ret, s);
+ return ret;
+}
+
+/*******************************************************************
+ free some memory
+ ********************************************************************/
+int smb_mem_free(void *ptr,char *file,int line)
+{
+ int Index;
+ int free_ret;
+ static int count;
+ INIT_MANAGER();
+
+ if (count % 100 == 0) {
+ smb_mem_write_errors(dbf);
+ }
+ count++;
+
+ Index = mem_find_Index(ptr);
+
+ if (Index<0) /* we are freeing a pointer that hasn't been allocated ! */
+ {
+ /* set up an error block */
+ Index = mem_first_avail_slot();
+ if (Index < 0) /* I can't even allocate an Error! */
+ {
+ fprintf(dbf,"Panic in memory manager - can't allocate error block!\n");
+ fprintf(dbf,"freeing un allocated pointer at %s(%d)\n",file,line);
+ abort();
+ }
+ /* fill in error block */
+ memory_blocks[Index].present_size = 0;
+ memory_blocks[Index].allocated_size = 0;
+ memory_blocks[Index].line = line;
+ strncpy(memory_blocks[Index].file,file,MEM_FILE_STR_LENGTH);
+ memory_blocks[Index].file[MEM_FILE_STR_LENGTH-1] = 0;
+ memory_blocks[Index].status = S_ERROR_UNALLOCATED;
+ memory_blocks[Index].pointer = ptr;
+ return(FREE_FAILURE);
+ }
+
+ /* it is a valid pointer - check for corruption */
+ if (!mem_buffer_ok(Index))
+ /* it's bad ! return an error */
+ return(FREE_FAILURE);
+
+ /* the pointer is OK - try to free it */
+#ifdef MEM_FREE_RETURNS_INT
+ free_ret = free((char *)ptr - BUF_OFFSET);
+#else
+ free((char *)ptr - BUF_OFFSET);
+ free_ret = FREE_SUCCESS;
+#endif
+
+
+ /* if this failed then make an error block again */
+ if (free_ret == FREE_FAILURE)
+ {
+ memory_blocks[Index].present_size = 0;
+ memory_blocks[Index].allocated_size = 0;
+ memory_blocks[Index].line = line;
+ strncpy(memory_blocks[Index].file,file,MEM_FILE_STR_LENGTH);
+ memory_blocks[Index].file[MEM_FILE_STR_LENGTH-1] = 0;
+ memory_blocks[Index].status = S_ERROR_FREEING;
+ memory_blocks[Index].pointer = ptr;
+ memory_blocks[Index].error_number = errno;
+ return(FREE_FAILURE);
+ }
+
+ /* all is OK - set status and return */
+ memory_blocks[Index].status = S_UNALLOCATED;
+
+ /* this is a speedup - if it is freed then it can be allocated again ! */
+ last_block_allocated = Index;
+
+ return(FREE_SUCCESS);
+}
+
+
+
+/*******************************************************************
+ writes info on just one Index
+ it must not be un allocated to do this
+ ********************************************************************/
+static void mem_write_Index_info(int Index,FILE *outfile)
+{
+ if (memory_blocks[Index].status != S_UNALLOCATED)
+ fprintf(outfile,"block %d file %s(%d) : ptr: %p size %d, alloc size %d, status %s\n",
+ Index,memory_blocks[Index].file,memory_blocks[Index].line,
+ memory_blocks[Index].pointer,
+ memory_blocks[Index].present_size,
+ memory_blocks[Index].allocated_size,
+ status_to_str(memory_blocks[Index].status));
+}
+
+
+
+/*******************************************************************
+ writes info on one pointer
+ ********************************************************************/
+void smb_mem_write_info(void *ptr,FILE *outfile)
+{
+ int Index;
+ INIT_MANAGER();
+ Index = mem_find_Index(ptr);
+ if (Index<0) return;
+ mem_write_Index_info(Index,outfile);
+}
+
+
+
+
+/*******************************************************************
+ return the size of the mem block
+ ********************************************************************/
+size_t smb_mem_query_size(void *ptr)
+{
+ int Index;
+ INIT_MANAGER();
+ Index = mem_find_Index(ptr);
+ if (Index<0) return(0);
+ return(memory_blocks[Index].present_size);
+}
+
+/*******************************************************************
+ return the allocated size of the mem block
+ ********************************************************************/
+size_t smb_mem_query_real_size(void *ptr)
+{
+ int Index;
+ INIT_MANAGER();
+ Index = mem_find_Index(ptr);
+ if (Index<0) return(0);
+ return(memory_blocks[Index].allocated_size);
+}
+
+
+
+
+/*******************************************************************
+ return the file of caller of the mem block
+ ********************************************************************/
+char *smb_mem_query_file(void *ptr)
+{
+ int Index;
+ INIT_MANAGER();
+ Index = mem_find_Index(ptr);
+ if (Index<0) return(NULL);
+ return(memory_blocks[Index].file);
+}
+
+
+
+/*******************************************************************
+ return the line in the file of caller of the mem block
+ ********************************************************************/
+int smb_mem_query_line(void *ptr)
+{
+ int Index;
+ INIT_MANAGER();
+ Index = mem_find_Index(ptr);
+ if (Index<0) return(0);
+ return(memory_blocks[Index].line);
+}
+
+/*******************************************************************
+ return True if the pointer is OK
+ ********************************************************************/
+int smb_mem_test(void *ptr)
+{
+ int Index;
+ INIT_MANAGER();
+ Index = mem_find_Index(ptr);
+ if (Index<0) return(False);
+
+ return(mem_buffer_ok(Index));
+}
+
+
+/*******************************************************************
+ write brief info on mem status
+ ********************************************************************/
+void smb_mem_write_status(FILE *outfile)
+{
+ int num_allocated=0;
+ int total_size=0;
+ int total_alloc_size=0;
+ int num_errors=0;
+ int i;
+ INIT_MANAGER();
+ mem_check_buffers();
+ for (i=0;i<mem_blocks_allocated;i++)
+ switch (memory_blocks[i].status)
+ {
+ case S_UNALLOCATED :
+ break;
+ case S_ALLOCATED :
+ num_allocated++;
+ total_size += memory_blocks[i].present_size;
+ total_alloc_size += memory_blocks[i].allocated_size;
+ break;
+ case S_ERROR_UNALLOCATED :
+ case S_ERROR_FREEING :
+ case S_CORRUPT_BACK :
+ case S_CORRUPT_FRONT :
+ num_errors++;
+ break;
+ }
+
+ fprintf(outfile,
+ "Mem Manager : %d blocks, allocation %dK, real allocation %dK, %d errors\n",
+ num_allocated,(int)(total_size/1024),(int)(total_alloc_size/1024),
+ num_errors);
+ fflush(outfile);
+}
+
+
+/*******************************************************************
+ write verbose info on allocated blocks
+ ********************************************************************/
+void smb_mem_write_verbose(FILE *outfile)
+{
+ int Index;
+ /* first write a summary */
+ INIT_MANAGER();
+ smb_mem_write_status(outfile);
+
+ /* just loop writing info on relevant indices */
+ for (Index=0;Index<mem_blocks_allocated;Index++)
+ if (memory_blocks[Index].status != S_UNALLOCATED)
+ mem_write_Index_info(Index,outfile);
+}
+
+/*******************************************************************
+ write verbose info on error blocks
+ ********************************************************************/
+void smb_mem_write_errors(FILE *outfile)
+{
+ int Index;
+ INIT_MANAGER();
+ mem_check_buffers();
+ /* just loop writing info on relevant indices */
+ for (Index=0;Index<mem_blocks_allocated;Index++)
+ if (((int)memory_blocks[Index].status) > ((int)S_ALLOCATED))
+ mem_write_Index_info(Index,outfile);
+}
+
+
+/*******************************************************************
+ sets the memory multiplier
+ ********************************************************************/
+void smb_mem_set_multiplier(int multiplier)
+{
+ /* check it is valid */
+ if (multiplier < 1) return;
+ mem_multiplier = multiplier;
+}
+
+/*******************************************************************
+ increases or decreases the memory assigned to a pointer
+ ********************************************************************/
+void *smb_mem_resize(void *ptr,size_t newsize)
+{
+ int Index;
+ size_t allocsize;
+ void *temp_ptr;
+ INIT_MANAGER();
+ Index = mem_find_Index(ptr);
+
+ /* if invalid return NULL */
+ if (Index<0)
+ {
+#ifdef BUG
+ int Error();
+ Error("Invalid mem_resize to size %d\n",newsize);
+#endif
+ return(NULL);
+ }
+
+ /* now - will it fit in the current allocation ? */
+ if (newsize <= memory_blocks[Index].allocated_size)
+ {
+ memory_blocks[Index].present_size = newsize;
+ mem_fill_buffer(Index);
+ return(ptr);
+ }
+
+ /* can it be allocated ? */
+ allocsize = newsize*mem_multiplier;
+ temp_ptr = malloc(newsize*mem_multiplier + BUF_SIZE);
+
+ /* no? try with just the size asked for */
+ if (temp_ptr == NULL)
+ {
+ allocsize=newsize;
+ temp_ptr = malloc(newsize + BUF_SIZE);
+ }
+
+ /* if it's still NULL give up */
+ if (temp_ptr == NULL)
+ return(NULL);
+
+ /* copy the old data to the new memory area */
+ memcpy(temp_ptr,(char *)memory_blocks[Index].pointer - BUF_OFFSET,
+ memory_blocks[Index].allocated_size + BUF_SIZE);
+
+ /* fill the extra space */
+ mem_fill_bytes((char *)temp_ptr + BUF_OFFSET + memory_blocks[Index].present_size,newsize - memory_blocks[Index].present_size,Index);
+
+
+ /* free the old mem and set vars */
+ free((char *)ptr - BUF_OFFSET);
+ memory_blocks[Index].pointer = (void *)((char *)temp_ptr + BUF_OFFSET);
+ memory_blocks[Index].present_size = newsize;
+ memory_blocks[Index].allocated_size = allocsize;
+
+ /* fill the buffer appropriately */
+ mem_fill_buffer(Index);
+
+
+ /* now return the new pointer */
+ return((char *)temp_ptr + BUF_OFFSET);
+}
+
+#else
+ void dummy_mem_man(void) {}
+#endif
diff --git a/source/mem_man/mem_man.h b/source/mem_man/mem_man.h
new file mode 100644
index 00000000000..eef281b2f91
--- /dev/null
+++ b/source/mem_man/mem_man.h
@@ -0,0 +1,92 @@
+#if (defined(NOMEMMAN) && !defined(MEM_MAN_MAIN) && defined(HAVE_MALLOC_H))
+#include <malloc.h>
+#else
+
+/* user settable parameters */
+
+#define MEM_MANAGER
+
+/*
+this is the maximum number of blocks that can be allocated at one
+time. Set this to more than the max number of mallocs you want possible
+*/
+#define MEM_MAX_MEM_OBJECTS 20000
+
+/*
+maximum length of a file name. This is for the source files only. This
+would normally be around 30 - increase it only if necessary
+*/
+#define MEM_FILE_STR_LENGTH 30
+
+/*
+default mem multiplier. All memory requests will be multiplied by
+this number, thus allowing fast resizing. High values chew lots of
+memory but allow for easy resizing
+*/
+#define MEM_DEFAULT_MEM_MULTIPLIER 1
+
+/*
+the length of the corruption buffers before and after each memory block.
+Using these can reduce memory overrun errors and catch bad code. The
+amount actually allocated is this times 2 times sizeof(char)
+*/
+#define MEM_CORRUPT_BUFFER 16
+
+/*
+the 'seed' to use for the corruption buffer. zero is a very bad choice
+*/
+#define MEM_CORRUPT_SEED 0x10
+
+
+/*
+seed increment. This is another precaution. This will be added to the
+'seed' for each adjacent element of the corruption buffer
+*/
+#define MEM_SEED_INCREMENT 0x1
+
+
+/*
+memory fill. This will be copied over all allocated memory - to aid in
+debugging memory dumps. It is one byte long
+*/
+#define MEM_FILL_BYTE 42
+
+
+/*
+this determines whether free() on your system returns an integer or
+nothing. If unsure then leave this un defined.
+*/
+/* #define MEM_FREE_RETURNS_INT */
+
+
+/*
+ This determines whether a signal handler will be instelled to do
+ a mem_write_verbose on request
+*/
+#define MEM_SIGNAL_HANDLER
+
+
+/*
+This sets which vector to use if MEM_SIGNAL_HANDLER is defined
+*/
+#define MEM_SIGNAL_VECTOR SIGUSR1
+
+#ifndef MEM_MAN_MAIN
+#ifdef malloc
+# undef malloc
+#endif
+#define malloc(x) smb_mem_malloc(x,__FILE__,__LINE__)
+#define free(x) smb_mem_free(x,__FILE__,__LINE__)
+#define realloc(ptr,newsize) smb_mem_resize(ptr,newsize)
+#ifdef calloc
+# undef calloc
+#endif
+#define calloc(nitems,size) malloc(((_mem_size)nitems)*((_mem_size)size))
+
+#ifdef strdup
+# undef strdup
+#endif
+#define strdup(s) smb_mem_strdup(s, __FILE__, __LINE__)
+#endif
+
+#endif
diff --git a/source/msrpc/msrpcd.c b/source/msrpc/msrpcd.c
new file mode 100644
index 00000000000..0e32e345acf
--- /dev/null
+++ b/source/msrpc/msrpcd.c
@@ -0,0 +1,577 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "trans2.h"
+
+extern pstring servicesf;
+extern pstring debugf;
+extern pstring global_myname;
+
+int am_parent = 1;
+
+/* the last message the was processed */
+int last_message = -1;
+
+/* a useful macro to debug the last message processed */
+#define LAST_MESSAGE() smb_fn_name(last_message)
+
+extern pstring scope;
+extern int DEBUGLEVEL;
+
+extern fstring remote_machine;
+extern pstring myhostname;
+extern pstring pipe_name;
+
+extern pstring OriginalDir;
+
+/****************************************************************************
+ when exiting, take the whole family
+****************************************************************************/
+static void *dflt_sig(void)
+{
+ exit_server("caught signal");
+ return NULL;
+}
+
+/****************************************************************************
+ Send a SIGTERM to our process group.
+*****************************************************************************/
+static void killkids(void)
+{
+ if(am_parent) kill(0,SIGTERM);
+}
+
+
+/****************************************************************************
+ open and listen to a socket
+****************************************************************************/
+static int open_server_socket(void)
+{
+ int s;
+ fstring dir;
+ fstring path;
+
+ slprintf(dir, sizeof(dir)-1, "%s/.msrpc", LOCKDIR);
+ slprintf(path, sizeof(path)-1, "%s/%s", dir, pipe_name);
+
+ s = create_pipe_socket(dir, 0700, path, 0700);
+
+ if (s == -1)
+ return -1;
+ /* ready to listen */
+ if (listen(s, 5) == -1) {
+ DEBUG(0,("listen: %s\n", strerror(errno)));
+ close(s);
+ return -1;
+ }
+ return s;
+}
+
+/****************************************************************************
+ open the socket communication
+****************************************************************************/
+static int open_sockets(BOOL is_daemon)
+{
+ int ClientMSRPC;
+ int num_interfaces = iface_count();
+ int fd_listenset;
+ fd_set listen_set;
+ int s;
+
+ memset(&fd_listenset, 0, sizeof(fd_listenset));
+
+#ifdef HAVE_ATEXIT
+ {
+ static int atexit_set;
+ if(atexit_set == 0) {
+ atexit_set=1;
+ atexit(killkids);
+ }
+ }
+#endif
+
+ /* Stop zombies */
+ CatchChild();
+
+
+ FD_ZERO(&listen_set);
+
+ /* Just bind to 0.0.0.0 - accept connections
+ from anywhere. */
+ num_interfaces = 1;
+
+ /* open an incoming socket */
+ s = open_server_socket();
+ if (s == -1)
+ return -1;
+ fd_listenset = s;
+ FD_SET(s,&listen_set);
+
+ /* now accept incoming connections - forking a new process
+ for each incoming connection */
+ DEBUG(2,("waiting for a connection\n"));
+ while (1)
+ {
+ struct sockaddr_un addr;
+ int in_addrlen = sizeof(addr);
+ fd_set lfds;
+ int num;
+
+ memcpy((char *)&lfds, (char *)&listen_set,
+ sizeof(listen_set));
+
+ num = sys_select(256,&lfds,NULL, NULL);
+
+ if (num == -1 && errno == EINTR)
+ continue;
+
+ /* Find the sockets that are read-ready -
+ accept on these. */
+
+ s = -1;
+ if(FD_ISSET(fd_listenset,&lfds))
+ {
+ s = fd_listenset;
+ }
+
+ /* Clear this so we don't look at it again. */
+ FD_CLR(s,&lfds);
+
+ ClientMSRPC = accept(s,(struct sockaddr*)&addr,&in_addrlen);
+
+ if (ClientMSRPC == -1 && errno == EINTR)
+ continue;
+
+ if (ClientMSRPC == -1)
+ {
+ DEBUG(0,("open_sockets: accept: %s\n",
+ strerror(errno)));
+ continue;
+ }
+
+ if (ClientMSRPC != -1 && fork()==0)
+ {
+ /* Child code ... */
+
+ /* close the listening socket(s) */
+ close(fd_listenset);
+
+ /* close our standard file
+ descriptors */
+ close_low_fds();
+ am_parent = 0;
+
+ /* Reset global variables in util.c so
+ that client substitutions will be
+ done correctly in the process. */
+ reset_globals_after_fork();
+
+ return ClientMSRPC;
+ }
+ /* The parent doesn't need this socket */
+ close(ClientMSRPC);
+
+ /* Force parent to check log size after
+ * spawning child. Fix from
+ * klausr@ITAP.Physik.Uni-Stuttgart.De. The
+ * parent daemon will log to logserver.smb. It
+ * writes only two messages for each child
+ * started/finished. But each child writes,
+ * say, 50 messages also in logserver.smb,
+ * begining with the debug_count of the
+ * parent, before the child opens its own log
+ * file logserver.client. In a worst case
+ * scenario the size of logserver.smb would be
+ * checked after about 50*50=2500 messages
+ * (ca. 100kb).
+ * */
+ force_check_log_size();
+
+ } /* end while 1 */
+
+/* NOTREACHED */
+}
+
+
+/****************************************************************************
+this prevents zombie child processes
+****************************************************************************/
+BOOL reload_after_sighup = False;
+
+static void sig_hup(int sig)
+{
+ BlockSignals(True,SIGHUP);
+ DEBUG(0,("Got SIGHUP\n"));
+
+ /*
+ * Fix from <branko.cibej@hermes.si> here.
+ * We used to reload in the signal handler - this
+ * is a *BIG* no-no.
+ */
+
+ reload_after_sighup = True;
+ BlockSignals(False,SIGHUP);
+}
+
+
+
+#if DUMP_CORE
+/*******************************************************************
+prepare to dump a core file - carefully!
+********************************************************************/
+static BOOL dump_core(void)
+{
+ char *p;
+ pstring dname;
+ pstrcpy(dname,debugf);
+ if ((p=strrchr(dname,'/'))) *p=0;
+ pstrcat(dname,"/corefiles");
+ mkdir(dname,0700);
+ sys_chown(dname,getuid(),getgid());
+ chmod(dname,0700);
+ if (chdir(dname)) return(False);
+ umask(~(0700));
+
+#ifdef HAVE_GETRLIMIT
+#ifdef RLIMIT_CORE
+ {
+ struct rlimit rlp;
+ getrlimit(RLIMIT_CORE, &rlp);
+ rlp.rlim_cur = MAX(4*1024*1024,rlp.rlim_cur);
+ setrlimit(RLIMIT_CORE, &rlp);
+ getrlimit(RLIMIT_CORE, &rlp);
+ DEBUG(3,("Core limits now %d %d\n",
+ (int)rlp.rlim_cur,(int)rlp.rlim_max));
+ }
+#endif
+#endif
+
+
+ DEBUG(0,("Dumping core in %s\n",dname));
+ abort();
+ return(True);
+}
+#endif
+
+
+/****************************************************************************
+exit the server
+****************************************************************************/
+void exit_server(char *reason)
+{
+ static int firsttime=1;
+
+ if (!firsttime) exit(0);
+ firsttime = 0;
+
+ unbecome_vuser();
+ DEBUG(2,("Closing connections\n"));
+
+#ifdef WITH_DFS
+ if (dcelogin_atmost_once) {
+ dfs_unlogin();
+ }
+#endif
+
+ if (!reason) {
+ DEBUG(0,("===============================================================\n"));
+#if DUMP_CORE
+ if (dump_core()) return;
+#endif
+ }
+
+ locking_end();
+
+ DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
+#ifdef MEM_MAN
+ {
+ extern FILE *dbf;
+ smb_mem_write_verbose(dbf);
+ dbgflush();
+ }
+#endif
+ exit(0);
+}
+
+
+
+/****************************************************************************
+ initialise connect, service and file structs
+****************************************************************************/
+static void init_structs(void)
+{
+#if 0
+ conn_init();
+#endif
+}
+
+/****************************************************************************
+usage on the program
+****************************************************************************/
+static void usage(char *pname)
+{
+ DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
+
+ printf("Usage: %s [-D] [-p port] [-d debuglevel] ", pname);
+ printf("[-l log basename] [-s services file]\n" );
+ printf("Version %s\n",VERSION);
+ printf("\t-D become a daemon\n");
+ printf("\t-p port listen on the specified port\n");
+ printf("\t-d debuglevel set the debuglevel\n");
+ printf("\t-l log basename. Basename for log/debug files\n");
+ printf("\t-s services file. Filename of services file\n");
+ printf("\t-P passive only\n");
+ printf("\t-a append to log file (default)\n");
+ printf("\t-o overwrite log file, don't append\n");
+ printf("\t-i scope NetBIOS scope to use (default none)\n");
+ printf("\n");
+}
+
+
+/****************************************************************************
+ main program
+****************************************************************************/
+ int main(int argc,char *argv[])
+{
+ msrpc_service_fns *fn = get_service_fns();
+ extern BOOL append_log;
+ /* shall I run as a daemon */
+ BOOL is_daemon = False;
+ int opt;
+ extern char *optarg;
+ int ClientMSRPC = -1;
+ pipes_struct p;
+ fstring service_name;
+
+ if (fn == NULL)
+ {
+ fprintf(stderr,"no services table!\n");
+ exit(-1);
+ }
+
+ if (fn->main_init(argc, argv) != 0)
+ {
+ exit_server("fn->main() initialisation failed!");
+ }
+
+ pstrcpy(remote_machine, pipe_name);
+ split_at_last_component(argv[0], NULL, '/', service_name);
+
+ charset_initialise();
+
+ /* make absolutely sure we run as root - to handle cases where people
+ are crazy enough to have it setuid */
+#ifdef HAVE_SETRESUID
+ setresuid(0,0,0);
+#else
+ setuid(0);
+ seteuid(0);
+ setuid(0);
+ seteuid(0);
+#endif
+
+ fault_setup((void (*)(void *))exit_server);
+ CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
+
+ /* we are never interested in SIGPIPE */
+ BlockSignals(True,SIGPIPE);
+
+ /* we want total control over the permissions on created files,
+ so set our umask to 0 */
+ umask(0);
+
+ dos_GetWd(OriginalDir);
+
+ init_vuid();
+
+ /* this is for people who can't start the program correctly */
+ while (argc > 1 && (*argv[1] != '-')) {
+ argv++;
+ argc--;
+ }
+
+ while ( EOF != (opt = getopt(argc, argv, "i:l:s:d:Dh?Paof:")) )
+ switch (opt) {
+ case 'i':
+ pstrcpy(scope,optarg);
+ break;
+
+ case 'P':
+ {
+ extern BOOL passive;
+ passive = True;
+ }
+ break;
+
+ case 's':
+ pstrcpy(servicesf,optarg);
+ break;
+
+ case 'l':
+ pstrcpy(debugf,optarg);
+ break;
+
+ case 'a':
+ append_log = True;
+ break;
+
+ case 'o':
+ append_log = False;
+ break;
+
+ case 'D':
+ is_daemon = True;
+ break;
+
+ case 'd':
+ if (*optarg == 'A')
+ DEBUGLEVEL = 10000;
+ else
+ DEBUGLEVEL = atoi(optarg);
+ break;
+
+ case 'h':
+ case '?':
+ usage(argv[0]);
+ exit(0);
+ break;
+
+ default:
+ usage(argv[0]);
+ exit(1);
+ }
+
+ reopen_logs();
+
+ DEBUG(1,( "%s version %s started.\n", service_name, VERSION));
+ DEBUGADD(1,( "Copyright Andrew Tridgell 1992-1999\n"));
+
+ DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
+ (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
+
+ if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
+ DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
+ exit(1);
+ }
+
+ get_myname(myhostname,NULL);
+
+ if (!fn->reload_services(False))
+ return(-1);
+
+ init_structs();
+
+#ifdef WITH_PROFILE
+ if (!profile_setup(False)) {
+ DEBUG(0,("ERROR: failed to setup profiling\n"));
+ return -1;
+ }
+#endif
+
+ /*
+ * Set the machine NETBIOS name if not already
+ * set from the config file.
+ */
+ if (!*global_myname)
+ {
+ fstrcpy(global_myname, dns_to_netbios_name(myhostname));
+ }
+ strupper(global_myname);
+
+ codepage_initialise(lp_client_code_page());
+
+ CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
+
+ /* Setup the signals that allow the debug log level
+ to by dynamically changed. */
+
+ /* If we are using the malloc debug code we can't use
+ SIGUSR1 and SIGUSR2 to do debug level changes. */
+
+#ifndef MEM_MAN
+#if defined(SIGUSR1)
+ CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
+#endif /* SIGUSR1 */
+
+#if defined(SIGUSR2)
+ CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
+#endif /* SIGUSR2 */
+#endif /* MEM_MAN */
+
+ DEBUG(3,( "loaded services\n"));
+
+ if (!is_daemon && !is_a_socket(0)) {
+ DEBUG(0,("standard input is not a socket, assuming -D option\n"));
+ is_daemon = True;
+ }
+
+ if (is_daemon) {
+ DEBUG( 3, ( "Becoming a daemon.\n" ) );
+ become_daemon();
+ }
+
+ if (!directory_exist(lp_lockdir(), NULL)) {
+ mkdir(lp_lockdir(), 0755);
+ }
+
+ if (is_daemon)
+ {
+ pidfile_create(service_name);
+ }
+
+ fn->service_init(service_name);
+ dbgflush();
+
+ ClientMSRPC = open_sockets(is_daemon);
+ if (ClientMSRPC == -1)
+ {
+ exit_server("open socket failed");
+ }
+
+ if (!locking_init(0))
+ exit(1);
+
+ /* possibly reload the services file. */
+ fn->reload_services(True);
+
+ if (*lp_rootdir()) {
+ if (sys_chroot(lp_rootdir()) == 0)
+ DEBUG(2,("Changed root to %s\n", lp_rootdir()));
+ }
+
+ ZERO_STRUCT(p);
+ fstrcpy(p.name, pipe_name);
+ if (msrpcd_init(ClientMSRPC, &p.l))
+ {
+ fn->auth_init(p.l);
+ fn->reload_services(True);
+ msrpcd_process(fn, p.l, p.name);
+ }
+ if (ClientMSRPC != -1)
+ {
+ close(ClientMSRPC);
+ }
+
+ exit_server("normal exit");
+ return(0);
+}
+
diff --git a/source/msrpc/msrpcd_process.c b/source/msrpc/msrpcd_process.c
new file mode 100644
index 00000000000..f8dda0b5281
--- /dev/null
+++ b/source/msrpc/msrpcd_process.c
@@ -0,0 +1,530 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ process incoming packets - main loop
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/*
+ * Size of data we can send to client. Set
+ * by the client for all protocols above CORE.
+ * Set by us for CORE protocol.
+ */
+int max_send = BUFFER_SIZE;
+/*
+ * Size of the data we can receive. Set by us.
+ * Can be modified by the max xmit parameter.
+ */
+int max_recv = BUFFER_SIZE;
+
+extern int last_message;
+extern pstring sesssetup_user;
+extern int smb_read_error;
+extern BOOL reload_after_sighup;
+extern int max_send;
+
+
+/****************************************************************************
+ Do a select on an two fd's - with timeout.
+
+ If a local udp message has been pushed onto the
+ queue (this can only happen during oplock break
+ processing) return this first.
+
+ If a pending smb message has been pushed onto the
+ queue (this can only happen during oplock break
+ processing) return this next.
+
+ If the first smbfd is ready then read an smb from it.
+ if the second (loopback UDP) fd is ready then read a message
+ from it and setup the buffer header to identify the length
+ and from address.
+ Returns False on timeout or error.
+ Else returns True.
+
+The timeout is in milli seconds
+****************************************************************************/
+
+static BOOL receive_message_or_msrpc(int c, prs_struct * ps,
+ int timeout, BOOL *got_msrpc)
+{
+ fd_set fds;
+ int selrtn;
+ struct timeval to;
+ int maxfd;
+
+ smb_read_error = 0;
+
+ *got_msrpc = False;
+
+ /*
+ * Check to see if we already have a message on the smb queue.
+ * If so - copy and return it.
+ */
+
+ /*
+ * Setup the select read fd set.
+ */
+
+ FD_ZERO(&fds);
+ FD_SET(c, &fds);
+ maxfd = 0;
+
+ to.tv_sec = timeout / 1000;
+ to.tv_usec = (timeout % 1000) * 1000;
+
+ selrtn =
+ sys_select(MAX(maxfd, c) + 1, &fds, NULL,
+ timeout > 0 ? &to : NULL);
+
+ /* Check if error */
+ if (selrtn == -1)
+ {
+ /* something is wrong. Maybe the socket is dead? */
+ smb_read_error = READ_ERROR;
+ return False;
+ }
+
+ /* Did we timeout ? */
+ if (selrtn == 0)
+ {
+ smb_read_error = READ_TIMEOUT;
+ return False;
+ }
+
+ if (FD_ISSET(c, &fds))
+ {
+ *got_msrpc = True;
+ return receive_msrpc(c, ps, 0);
+ }
+ return False;
+}
+
+
+/*
+These flags determine some of the permissions required to do an operation
+
+Note that I don't set NEED_WRITE on some write operations because they
+are used by some brain-dead clients when printing, and I don't want to
+force write permissions on print services.
+*/
+#define AS_USER (1<<0)
+#define NEED_WRITE (1<<1)
+#define TIME_INIT (1<<2)
+#define CAN_IPC (1<<3)
+#define AS_GUEST (1<<5)
+#define QUEUE_IN_OPLOCK (1<<6)
+
+/*
+ define a list of possible SMB messages and their corresponding
+ functions. Any message that has a NULL function is unimplemented -
+ please feel free to contribute implementations!
+*/
+
+
+/****************************************************************************
+ process an smb from the client - split out from the process() code so
+ it can be used by the oplock break code.
+****************************************************************************/
+static void process_msrpc(rpcsrv_struct * l, const char *name,
+ prs_struct * pdu)
+{
+ static int trans_num;
+ int32 len = prs_buf_len(pdu);
+
+ DEBUG(6, ("got message of len 0x%x\n", len));
+
+ dump_data(10, pdu->data, len);
+
+#ifdef WITH_VTP
+ if (trans_num == 1 && VT_Check(pdu->data))
+ {
+ VT_Process();
+ return;
+ }
+#endif
+
+ if (rpc_local(l, pdu->data, len, name) &&
+ msrpc_send(l->c, &l->rsmb_pdu))
+ {
+ prs_free_data(&l->rsmb_pdu);
+
+ while (rpc_local(l, NULL, 0, name))
+ {
+ fd_set fds;
+ int selrtn;
+ struct timeval to;
+ int maxfd;
+ int timeout = SMBD_SELECT_LOOP * 1000;
+
+ smb_read_error = 0;
+
+ FD_ZERO(&fds);
+ FD_SET(l->c, &fds);
+ maxfd = 0;
+
+ to.tv_sec = timeout / 1000;
+ to.tv_usec = (timeout % 1000) * 1000;
+
+ selrtn =
+ sys_select(MAX(maxfd, l->c) + 1, NULL, &fds,
+ timeout > 0 ? &to : NULL);
+
+ /* Check if error */
+ if (selrtn == -1)
+ {
+ smb_read_error = READ_ERROR;
+ return;
+ }
+
+ /* Did we timeout ? */
+ if (selrtn == 0)
+ {
+ smb_read_error = READ_TIMEOUT;
+ return;
+ }
+
+ if (FD_ISSET(l->c, &fds))
+ {
+ if (!msrpc_send(l->c, &l->rsmb_pdu))
+ prs_free_data(&l->rsmb_pdu);
+ break;
+ }
+ prs_free_data(&l->rsmb_pdu);
+ }
+ }
+ trans_num++;
+}
+
+/****************************************************************************
+ reads user credentials from the socket
+****************************************************************************/
+BOOL get_user_creds(int c, vuser_key * uk)
+{
+ pstring buf;
+ int rl;
+ uint32 len;
+ BOOL new_con = False;
+ uint32 status;
+
+ CREDS_CMD cmd;
+ prs_struct ps;
+
+ ZERO_STRUCT(cmd);
+
+ DEBUG(10, ("get_user_creds: first request\n"));
+
+ rl = read(c, &buf, sizeof(len));
+
+ if (rl != sizeof(len))
+ {
+ DEBUG(0, ("Unable to read length\n"));
+ dump_data(0, buf, sizeof(len));
+ return False;
+ }
+
+ len = IVAL(buf, 0);
+
+ if (len > sizeof(buf))
+ {
+ DEBUG(0, ("length %d too long\n", len));
+ return False;
+ }
+
+ rl = read(c, buf, len);
+
+ if (rl < 0)
+ {
+ DEBUG(0, ("Unable to read from connection\n"));
+ return False;
+ }
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, buf, rl);
+#endif
+
+ /* make a static data parsing structure from the api_fd_reply data */
+ prs_init(&ps, 0, 4, True);
+ prs_add_data(&ps, buf, len);
+
+ if (!creds_io_cmd("creds", &cmd, &ps, 0))
+ {
+ DEBUG(0, ("Unable to parse credentials\n"));
+ prs_free_data(&ps);
+ return False;
+ }
+
+ if (ps.offset != rl)
+ {
+ DEBUG(0, ("Buffer size %d %d!\n", ps.offset, rl));
+ prs_free_data(&ps);
+ return False;
+ }
+
+ prs_free_data(&ps);
+
+ switch (cmd.command)
+ {
+ case AGENT_CMD_CON:
+ case AGENT_CMD_CON_ANON:
+ {
+ new_con = True;
+ break;
+ }
+ case AGENT_CMD_CON_REUSE:
+ {
+ new_con = True;
+ break;
+ }
+ default:
+ {
+ DEBUG(0, ("unknown command %d\n", cmd.command));
+ return False;
+ }
+ }
+
+ /* obtain the remote process id and vuid */
+ (*uk) = cmd.key;
+
+ status = new_con ? 0x0 : 0x1;
+
+ if (write(c, &status, sizeof(status)) != sizeof(status))
+ {
+ return False;
+ }
+
+ return new_con;
+}
+
+static void free_srv_auth_fns_array(uint32 num_entries,
+ srv_auth_fns ** entries)
+{
+ free_void_array(num_entries, (void **)entries, NULL);
+}
+
+static srv_auth_fns *add_srv_auth_fns_to_array(uint32 * len,
+ srv_auth_fns *** array,
+ srv_auth_fns * name)
+{
+ return (srv_auth_fns *) add_item_to_array(len,
+ (void ***)array,
+ (void *)name);
+}
+
+void close_srv_auth_array(rpcsrv_struct * l)
+{
+ free_srv_auth_fns_array(l->num_auths, l->auth_fns);
+}
+
+void add_srv_auth_fn(rpcsrv_struct * l, srv_auth_fns * fn)
+{
+ add_srv_auth_fns_to_array(&l->num_auths, &l->auth_fns, fn);
+ DEBUG(10, ("add_srv_auth_fn: %d\n", l->num_auths));
+}
+
+/****************************************************************************
+ initialise from pipe
+****************************************************************************/
+BOOL msrpcd_init(int c, rpcsrv_struct ** l)
+{
+ vuser_key uk;
+ user_struct *vuser = NULL;
+
+ if (!get_user_creds(c, &uk))
+ {
+ DEBUG(0, ("authentication failed\n"));
+ return False;
+ }
+
+ if (uk.vuid != UID_FIELD_INVALID)
+ {
+ if (!become_vuser(&uk))
+ {
+ return False;
+ }
+
+ vuser = get_valid_user_struct(&uk);
+ if (vuser == NULL)
+ {
+ return False;
+ }
+ }
+ else
+ {
+ if (!become_guest())
+ {
+ return False;
+ }
+ }
+
+ (*l) = malloc(sizeof(*(*l)));
+ if ((*l) == NULL)
+ {
+ vuid_free_user_struct(vuser);
+ return False;
+ }
+
+ ZERO_STRUCTP((*l));
+
+ (*l)->key = uk;
+ (*l)->c = c;
+
+ if (vuser != NULL && !vuser->guest)
+ {
+ char *user = vuser->name;
+ if (!strequal(user, lp_guestaccount(-1)) &&
+ lp_servicenumber(user) < 0)
+ {
+ int homes = lp_servicenumber(HOMES_NAME);
+ char *home = get_unixhome_dir(user);
+ if (homes >= 0 && home)
+ {
+ pstring home_dir;
+ fstrcpy(home_dir, home);
+ lp_add_home(user, homes, home_dir);
+ }
+ }
+ }
+
+ vuid_free_user_struct(vuser);
+
+ return True;
+}
+
+/****************************************************************************
+ process commands from the client
+****************************************************************************/
+void msrpcd_process(msrpc_service_fns * fn, rpcsrv_struct * l,
+ const char *name)
+{
+ extern fstring remote_machine;
+ extern fstring local_machine;
+ extern pstring global_myname;
+
+ max_recv = MIN(lp_maxxmit(), BUFFER_SIZE);
+
+ /* re-initialise the timezone */
+ TimeInit();
+
+ fstrcpy(remote_machine, name);
+ fstrcpy(local_machine, global_myname);
+ local_machine[15] = 0;
+ strlower(local_machine);
+
+ DEBUG(2, ("msrpc_process: client_name: %s my_name: %s\n",
+ remote_machine, local_machine));
+
+ fn->reload_services(True);
+ reopen_logs();
+
+ while (True)
+ {
+ int counter;
+ int service_load_counter = 0;
+ BOOL got_msrpc = False;
+ prs_struct pdu;
+
+ errno = 0;
+
+ for (counter = SMBD_SELECT_LOOP;
+ !receive_message_or_msrpc(l->c, &pdu,
+ SMBD_SELECT_LOOP * 1000,
+ &got_msrpc);
+ counter += SMBD_SELECT_LOOP)
+ {
+ time_t t;
+
+ if (counter > 365 * 3600) /* big number of seconds. */
+ {
+ counter = 0;
+ service_load_counter = 0;
+ }
+
+ if (smb_read_error == READ_EOF)
+ {
+ DEBUG(3, ("end of file from client\n"));
+ if (fn->idle != NULL)
+ {
+ fn->idle();
+ }
+ return;
+ }
+
+ if (smb_read_error == READ_ERROR)
+ {
+ DEBUG(3, ("receive error (%s) exiting\n",
+ strerror(errno)));
+ if (fn->idle != NULL)
+ {
+ fn->idle();
+ }
+ return;
+ }
+
+ t = time(NULL);
+
+ /* check for smb.conf reload */
+ if (counter >=
+ service_load_counter + SMBD_RELOAD_CHECK)
+ {
+ service_load_counter = counter;
+
+ /* reload services, if files have changed. */
+ fn->reload_services(True);
+ }
+
+ /*
+ * If reload_after_sighup == True then we got a SIGHUP
+ * and are being asked to reload. Fix from <branko.cibej@hermes.si>
+ */
+
+ if (reload_after_sighup)
+ {
+ DEBUG(0,
+ ("Reloading services after SIGHUP\n"));
+ fn->reload_services(False);
+ reload_after_sighup = False;
+ /*
+ * Use this as an excuse to print some stats.
+ */
+ }
+
+ /* automatic timeout if all connections are closed */
+ if (counter >= IDLE_CLOSED_TIMEOUT)
+ {
+ DEBUG(2, ("Closing idle connection\n"));
+ if (fn->idle != NULL)
+ {
+ fn->idle();
+ }
+ return;
+ }
+
+ }
+
+ if (got_msrpc)
+ {
+ process_msrpc(l, name, &pdu);
+ }
+ prs_free_data(&pdu);
+ }
+}
diff --git a/source/netlogond/creds_db.c b/source/netlogond/creds_db.c
new file mode 100644
index 00000000000..3f26af147bd
--- /dev/null
+++ b/source/netlogond/creds_db.c
@@ -0,0 +1,137 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Groupname handling
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+static TDB_CONTEXT *db = NULL;
+
+static char *make_creds_key(uint32 pid, const char *domain, const char* wks, int *klen)
+{
+ char *k;
+ int domlen = strlen(domain);
+ int wkslen = strlen(wks);
+
+ (*klen) = domlen + wkslen + 2 + sizeof(pid);
+ k = malloc((*klen) * sizeof(char));
+
+ if (k != NULL)
+ {
+ *((uint32*)k) = pid;
+ safe_strcpy(k+sizeof(pid) , domain, domlen);
+ safe_strcpy(k+sizeof(pid)+domlen+1, wks , wkslen);
+ strlower(k+sizeof(pid));
+ strlower(k+sizeof(pid)+domlen+1);
+
+ DEBUG(10,("make_creds_key: pid: %x dom %s wks %s\n",
+ pid, domain, wks));
+ dump_data(10, k, (*klen));
+ }
+
+ return k;
+}
+
+BOOL cred_get(uint32 pid, const char *domain, const char* wks, struct dcinfo *dc)
+{
+ int klen;
+ char *k;
+ TDB_DATA key, data;
+
+ DEBUG(10,("cred_get:\n"));
+
+ k = make_creds_key(pid, domain, wks, &klen);
+
+ if (k == NULL) return False;
+
+ key.dptr = k;
+ key.dsize = klen;
+
+ data = tdb_fetch(db, key);
+
+ free(k);
+
+ if (data.dptr == NULL)
+ {
+ DEBUG(10,("cred_get: NULL data\n"));
+ return False;
+ }
+ if (data.dsize != sizeof(*dc))
+ {
+ DEBUG(10,("cred_get: data size mismatch\n"));
+ free(data.dptr);
+ return False;
+ }
+
+ memcpy(dc, data.dptr, sizeof(*dc));
+ free(data.dptr);
+
+ dump_data(100, (char*)dc, sizeof(*dc));
+ return True;
+}
+
+BOOL cred_store(uint32 pid, const char *domain, const char* wks, struct dcinfo *dc)
+{
+ int klen;
+ char *k;
+ TDB_DATA key, data;
+ BOOL ret;
+
+ DEBUG(10,("cred_store:\n"));
+
+ k = make_creds_key(pid, domain, wks, &klen);
+
+ if (k == NULL) return False;
+
+ key.dptr = k;
+ key.dsize = klen;
+
+ data.dptr = (char*)dc;
+ data.dsize = sizeof(*dc);
+
+ ret = (tdb_store(db, key, data, TDB_REPLACE) == 0);
+
+ free(k);
+
+ dump_data(100, (char*)dc, sizeof(*dc));
+
+ if (!ret)
+ {
+ DEBUG(0,("cred_store: failed\n"));
+ }
+ return ret;
+}
+
+BOOL cred_init_db(void)
+{
+ db = tdb_open(lock_path("netlogoncreds.tdb"), 0, 0,
+ O_RDWR | O_CREAT, 0600);
+
+ if (db == NULL)
+ {
+ DEBUG(0,("cred_init_db: failed\n"));
+ return False;
+ }
+
+ DEBUG(10,("cred_init_db: opened\n"));
+
+ return True;
+}
diff --git a/source/netlogond/netlogond.c b/source/netlogond/netlogond.c
new file mode 100644
index 00000000000..dcec6fbf110
--- /dev/null
+++ b/source/netlogond/netlogond.c
@@ -0,0 +1,134 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+fstring pipe_name;
+
+pstring servicesf = CONFIGFILE;
+extern pstring debugf;
+extern BOOL append_log;
+extern int DEBUGLEVEL;
+
+/*****************************************************************************
+ initialise srv_auth_fns array
+ *****************************************************************************/
+static void auth_init(rpcsrv_struct *l)
+{
+ extern srv_auth_fns netsec_fns;
+ add_srv_auth_fn(l, &netsec_fns);
+}
+
+/*************************************************************************
+ initialise an msrpc service
+ *************************************************************************/
+static void service_init(char* service_name)
+{
+ add_msrpc_command_processor( pipe_name, service_name, api_netlog_rpc );
+ if (!pwdb_initialise(True))
+ {
+ exit(-1);
+ }
+
+ if(!pwdbsam_initialise())
+ {
+ exit(-1);
+ }
+ if (!cred_init_db())
+ {
+ exit(-1);
+ }
+}
+
+/****************************************************************************
+ reload the services file
+ **************************************************************************/
+static BOOL reload_msrpc(BOOL test)
+{
+ BOOL ret;
+
+ if (lp_loaded()) {
+ pstring fname;
+ pstrcpy(fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
+ reopen_logs();
+
+ if (test && !lp_file_list_changed())
+ return(True);
+
+ lp_killunused(NULL);
+
+ ret = lp_load(servicesf,False,False,True);
+
+ /* perhaps the config filename is now set */
+ if (!test)
+ reload_msrpc(True);
+
+ reopen_logs();
+
+ load_interfaces();
+
+ return(ret);
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+static int main_init(int argc,char *argv[])
+{
+#ifdef HAVE_SET_AUTH_PARAMETERS
+ set_auth_parameters(argc,argv);
+#endif
+
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ append_log = True;
+
+ TimeInit();
+
+ setup_logging(argv[0],False);
+ fstrcpy(pipe_name, "NETLOGON");
+ slprintf(debugf, sizeof(debugf), "%s/log.%s", LOGFILEBASE, "netlogon");
+
+ return 0;
+}
+
+static msrpc_service_fns fn_table =
+{
+ auth_init,
+ service_init,
+ reload_msrpc,
+ main_init,
+ NULL
+};
+
+msrpc_service_fns *get_service_fns(void)
+{
+ return &fn_table;
+}
diff --git a/source/netlogond/srv_netlogon_nt.c b/source/netlogond/srv_netlogon_nt.c
new file mode 100644
index 00000000000..6dbc7fd1eba
--- /dev/null
+++ b/source/netlogond/srv_netlogon_nt.c
@@ -0,0 +1,1237 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Paul Ashton 1997-2000,
+ * Copyright (C) Jeremy Allison 1998-2000,
+ * Copyright (C) Sander Striker 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "nterr.h"
+#include "sids.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+extern pstring global_myname;
+
+/******************************************************************
+ gets a machine password entry. checks access rights of the host.
+ ******************************************************************/
+static uint32 direct_samr_userinfo(const UNISTR2 * uni_user,
+ uint16 level,
+ SAM_USERINFO_CTR * ctr,
+ DOM_GID ** gids,
+ uint32 * num_grps, BOOL set)
+{
+ POLICY_HND sam_pol;
+ POLICY_HND dom_pol;
+ POLICY_HND usr_pol;
+ uint32 user_rid = 0xffffffff;
+
+ uint32 status_sam = NT_STATUS_NOPROBLEMO;
+ uint32 status_dom = NT_STATUS_NOPROBLEMO;
+ uint32 status_usr = NT_STATUS_NOPROBLEMO;
+ uint32 status_pwd = NT_STATUS_NOPROBLEMO;
+ uint32 status_grp = NT_STATUS_NOPROBLEMO;
+
+ ZERO_STRUCTP(ctr);
+
+ status_sam = _samr_connect(NULL, 0x02000000, &sam_pol);
+ if (status_sam == NT_STATUS_NOPROBLEMO)
+ {
+ status_dom = _samr_open_domain(&sam_pol, 0x02000000,
+ &global_sam_sid, &dom_pol);
+ }
+ if (status_dom == NT_STATUS_NOPROBLEMO)
+ {
+ uint32 type;
+ uint32 num_rids;
+ uint32 num_types;
+
+ status_usr = _samr_lookup_names(&dom_pol, 1, 0x3e8,
+ 1, uni_user,
+ &num_rids, &user_rid,
+ &num_types, &type);
+ if (type != SID_NAME_USER)
+ {
+ status_usr = NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ if (status_usr == NT_STATUS_NOPROBLEMO)
+ {
+ status_usr = _samr_open_user(&dom_pol, 0x02000000,
+ user_rid, &usr_pol);
+ }
+ if (status_usr == NT_STATUS_NOPROBLEMO)
+ {
+ if (set && gids != NULL && num_grps != NULL)
+ {
+ status_grp = _samr_query_usergroups(&usr_pol,
+ num_grps, gids);
+ }
+ if (set)
+ {
+ status_pwd = _samr_set_userinfo(&usr_pol, level, ctr);
+ }
+ else
+ {
+ status_pwd =
+ _samr_query_userinfo(&usr_pol, level, ctr);
+ }
+ }
+ if (status_usr == NT_STATUS_NOPROBLEMO)
+ _samr_close(&usr_pol);
+ if (status_dom == NT_STATUS_NOPROBLEMO)
+ _samr_close(&dom_pol);
+ if (status_sam == NT_STATUS_NOPROBLEMO)
+ _samr_close(&sam_pol);
+
+ if (status_pwd != NT_STATUS_NOPROBLEMO)
+ {
+ return status_pwd;
+ }
+
+ if (status_grp != NT_STATUS_NOPROBLEMO)
+ {
+ return status_grp;
+ }
+
+ if (ctr->info.id == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/******************************************************************
+ gets a machine password entry. checks access rights of the host.
+ ******************************************************************/
+static BOOL get_md4pw(char *md4pw, char *trust_name, char *trust_acct)
+{
+ SAM_USERINFO_CTR ctr;
+ uint32 status_pwd = NT_STATUS_NOPROBLEMO;
+ UNISTR2 uni_trust_acct;
+
+ ZERO_STRUCT(ctr);
+
+ make_unistr2(&uni_trust_acct, trust_acct, strlen(trust_acct));
+
+#if 0
+ /*
+ * Currently this code is redundent as we already have a filter
+ * by hostname list. What this code really needs to do is to
+ * get a hosts allowed/hosts denied list from the SAM database
+ * on a per user basis, and make the access decision there.
+ * I will leave this code here for now as a reminder to implement
+ * this at a later date. JRA.
+ */
+
+ if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
+ client_connection_name(), client_connection_addr()))
+ {
+ DEBUG(0,
+ ("get_md4pw: Workstation %s denied access to domain\n",
+ trust_acct));
+ return False;
+ }
+#endif /* 0 */
+
+ if (strequal(trust_name, global_myname))
+ {
+ BOOL ret;
+ DEBUG(10, ("get_md4pw: loop-back, use $MACHINE.ACC\n"));
+ ret = msrpc_lsa_query_trust_passwd("\\\\.",
+ "$MACHINE.ACC", md4pw,
+ NULL);
+ return ret ? NT_STATUS_ACCESS_DENIED : NT_STATUS_NOPROBLEMO;
+ }
+
+ /*
+ * must do all this as root
+ */
+ become_root(True);
+ status_pwd = direct_samr_userinfo(&uni_trust_acct, 0x12, &ctr,
+ NULL, NULL, False);
+ unbecome_root(True);
+
+ if (status_pwd == NT_STATUS_NOPROBLEMO)
+ {
+ memcpy(md4pw, ctr.info.id12->nt_pwd, 16);
+ dump_data_pw("md4pw", md4pw, 16);
+ }
+
+ free_samr_userinfo_ctr(&ctr);
+
+ return status_pwd == NT_STATUS_NOPROBLEMO;
+}
+
+/*************************************************************************
+ net_login_interactive:
+ *************************************************************************/
+static uint32 net_login_interactive(NET_ID_INFO_1 * id1, struct dcinfo *dc)
+{
+ const UNISTR2 *uni_samusr = &id1->uni_user_name;
+ uint32 status = NT_STATUS_NOPROBLEMO;
+
+ char nt_pwd[16];
+ char lm_pwd[16];
+ unsigned char key[16];
+
+ SAM_USERINFO_CTR ctr;
+
+ become_root(True);
+ status = direct_samr_userinfo(uni_samusr, 0x12, &ctr,
+ NULL, NULL, False);
+ unbecome_root(True);
+
+ if (status != NT_STATUS_NOPROBLEMO)
+ {
+ free_samr_userinfo_ctr(&ctr);
+ return status;
+ }
+
+ memset(key, 0, 16);
+ memcpy(key, dc->sess_key, 8);
+
+ memcpy(lm_pwd, id1->lm_owf.data, 16);
+ memcpy(nt_pwd, id1->nt_owf.data, 16);
+
+ dump_data_pw("key:", key, 16);
+
+ dump_data_pw("lm owf password:", lm_pwd, 16);
+ dump_data_pw("nt owf password:", nt_pwd, 16);
+
+ SamOEMhash((uchar *) lm_pwd, key, 0);
+ SamOEMhash((uchar *) nt_pwd, key, 0);
+
+ dump_data_pw("decrypt of lm owf password:", lm_pwd, 16);
+ dump_data_pw("decrypt of nt owf password:", nt_pwd, 16);
+
+ if (memcmp(ctr.info.id12->lm_pwd, lm_pwd, 16) != 0 ||
+ memcmp(ctr.info.id12->nt_pwd, nt_pwd, 16) != 0)
+ {
+ status = NT_STATUS_WRONG_PASSWORD;
+ }
+
+ free_samr_userinfo_ctr(&ctr);
+
+ return status;
+}
+
+/*************************************************************************
+ net_login_network:
+ *************************************************************************/
+static uint32 net_login_general(NET_ID_INFO_4 * id4,
+ struct dcinfo *dc, char usr_sess_key[16])
+{
+ fstring user;
+ fstring domain;
+ char *general;
+
+ int pw_len = id4->str_general.str_str_len;
+
+ unistr2_to_ascii(user, &id4->uni_user_name, sizeof(user) - 1);
+ unistr2_to_ascii(domain, &id4->uni_domain_name, sizeof(domain) - 1);
+ general = id4->str_general.buffer;
+
+ DEBUG(5, ("net_login_general: user:%s domain:%s", user, domain));
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("password:%s", general));
+#endif
+ DEBUG(5, ("\n"));
+
+ DEBUG(0,
+ ("net_login_general: TODO - \"update encrypted\" disabled\n"));
+
+ if (pass_check(user, general, pw_len, NULL,
+#if 0
+ lp_update_encrypted()? update_smbpassword_file :
+#endif
+ NULL))
+ {
+ unsigned char key[16];
+
+ memset(key, 0, 16);
+ memcpy(key, dc->sess_key, 8);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("key:"));
+ dump_data(100, key, 16);
+
+ DEBUG(100, ("user sess key:"));
+ dump_data(100, usr_sess_key, 16);
+#endif
+ SamOEMhash((uchar *) usr_sess_key, key, 0);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("encrypt of user session key:"));
+ dump_data(100, usr_sess_key, 16);
+#endif
+
+ return NT_STATUS_NOPROBLEMO;
+ }
+
+ return NT_STATUS_WRONG_PASSWORD;
+}
+
+/*************************************************************************
+ net_login_network:
+ *************************************************************************/
+static uint32 net_login_network(NET_ID_INFO_2 * id2,
+ uint16 acb_info,
+ struct dcinfo *dc,
+ char usr_sess_key[16], char lm_pw8[8])
+{
+ const UNISTR2 *uni_samusr = &id2->uni_user_name;
+ fstring user;
+ fstring domain;
+
+ SAM_USERINFO_CTR ctr;
+
+ uint32 status;
+
+ int nt_pw_len = id2->hdr_nt_chal_resp.str_str_len;
+ int lm_pw_len = id2->hdr_lm_chal_resp.str_str_len;
+
+ unistr2_to_ascii(user, uni_samusr, sizeof(user) - 1);
+ unistr2_to_ascii(domain, &id2->uni_domain_name, sizeof(domain) - 1);
+
+ become_root(True);
+ status = direct_samr_userinfo(uni_samusr, 0x12, &ctr,
+ NULL, NULL, False);
+ unbecome_root(True);
+
+ if (status != NT_STATUS_NOPROBLEMO)
+ {
+ free_samr_userinfo_ctr(&ctr);
+ return status;
+ }
+
+ DEBUG(5,
+ ("net_login_network: lm_len:%d nt_len:%d user:%s domain:%s\n",
+ lm_pw_len, nt_pw_len, user, domain));
+
+ if (smb_password_ok(acb_info, ctr.info.id12->lm_pwd,
+ ctr.info.id12->nt_pwd,
+ id2->lm_chal,
+ user, domain,
+ (const uchar *)id2->lm_chal_resp.buffer,
+ lm_pw_len,
+ (const uchar *)id2->nt_chal_resp.buffer,
+ nt_pw_len, usr_sess_key))
+ {
+ unsigned char key[16];
+
+ memcpy(lm_pw8, ctr.info.id12->lm_pwd, 8);
+
+ memset(key, 0, 16);
+ memcpy(key, dc->sess_key, 8);
+
+ dump_data_pw("key:", key, 16);
+ dump_data_pw("user sess key:", usr_sess_key, 16);
+ dump_data_pw("lm_pw8:", lm_pw8, 16);
+
+ SamOEMhash((uchar *) lm_pw8, key, 3);
+ SamOEMhash((uchar *) usr_sess_key, key, 0);
+
+ dump_data_pw("encrypt of user session key:", usr_sess_key,
+ 16);
+ dump_data_pw("encrypt of lm_pw8:", lm_pw8, 16);
+
+ status = NT_STATUS_NOPROBLEMO;
+ }
+ else
+ {
+ status = NT_STATUS_WRONG_PASSWORD;
+ }
+ free_samr_userinfo_ctr(&ctr);
+ return status;
+}
+
+/*************************************************************************
+ _net_req_chal
+ *************************************************************************/
+uint32 _net_req_chal(const UNISTR2 * uni_logon_server,
+ const UNISTR2 * uni_logon_client,
+ const DOM_CHAL * clnt_chal,
+ DOM_CHAL * srv_chal, uint16 remote_pid)
+{
+ fstring trust_acct;
+ fstring trust_name;
+
+ struct dcinfo dc;
+
+ ZERO_STRUCT(dc);
+
+ unistr2_to_ascii(trust_acct, uni_logon_client,
+ sizeof(trust_acct) - 1);
+
+ fstrcpy(trust_name, trust_acct);
+ strlower(trust_name);
+
+ fstrcat(trust_acct, "$");
+
+ if (!get_md4pw((char *)dc.md4pw, trust_name, trust_acct))
+ {
+ /* lkclXXXX take a guess at a good error message to return :-) */
+ return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
+ }
+
+ /* copy the client credentials */
+ memcpy(dc.clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
+ memcpy(dc.clnt_cred.challenge.data, clnt_chal->data,
+ sizeof(clnt_chal->data));
+
+ /* create a server challenge for the client */
+ /* Set these to random values. */
+ generate_random_buffer(srv_chal->data, sizeof(srv_chal->data), False);
+
+ /* copy the server credentials */
+ memcpy(dc.srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
+ memcpy(dc.srv_cred.challenge.data, srv_chal->data,
+ sizeof(srv_chal->data));
+
+ bzero(dc.sess_key, sizeof(dc.sess_key));
+
+ /* from client / server challenges and md4 password, generate sess key */
+ cred_session_key(&(dc.clnt_chal), &(dc.srv_chal),
+ (char *)dc.md4pw, dc.sess_key);
+
+ if (!cred_store(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+/*************************************************************************
+ error messages cropping up when using nltest.exe...
+ *************************************************************************/
+#define ERROR_NO_SUCH_DOMAIN 0x54b
+#define ERROR_NO_LOGON_SERVERS 0x51f
+
+/*******************************************************************
+creates a NETLOGON_INFO_3 structure.
+********************************************************************/
+static BOOL make_netinfo_3(NETLOGON_INFO_3 * info, uint32 flags,
+ uint32 logon_attempts)
+{
+ info->flags = flags;
+ info->logon_attempts = logon_attempts;
+ info->reserved_1 = 0x0;
+ info->reserved_2 = 0x0;
+ info->reserved_3 = 0x0;
+ info->reserved_4 = 0x0;
+ info->reserved_5 = 0x0;
+
+ return True;
+}
+
+
+/*******************************************************************
+creates a NETLOGON_INFO_1 structure.
+********************************************************************/
+static BOOL make_netinfo_1(NETLOGON_INFO_1 * info, uint32 flags,
+ uint32 pdc_status)
+{
+ info->flags = flags;
+ info->pdc_status = pdc_status;
+
+ return True;
+}
+
+/*******************************************************************
+creates a NETLOGON_INFO_2 structure.
+********************************************************************/
+static BOOL make_netinfo_2(NETLOGON_INFO_2 * info, uint32 flags,
+ uint32 pdc_status, uint32 tc_status,
+ char *trusted_dc_name)
+{
+ int len_dc_name = strlen(trusted_dc_name);
+ info->flags = flags;
+ info->pdc_status = pdc_status;
+ info->ptr_trusted_dc_name = 1;
+ info->tc_status = tc_status;
+
+ if (trusted_dc_name != NULL)
+ {
+ make_unistr2(&(info->uni_trusted_dc_name), trusted_dc_name,
+ len_dc_name + 1);
+ }
+ else
+ {
+ make_unistr2(&(info->uni_trusted_dc_name), "", 1);
+ }
+
+ return True;
+}
+
+/*************************************************************************
+ _net_logon_ctrl2
+ *************************************************************************/
+uint32 _net_logon_ctrl2(const UNISTR2 * uni_server_name,
+ uint32 function_code,
+ uint32 query_level,
+ uint32 switch_value,
+ uint32 * reply_switch_value,
+ NETLOGON_INFO * logon_info)
+{
+ /* lkclXXXX - guess what - absolutely no idea what these are! */
+ uint32 flags = 0x0;
+ uint32 pdc_status = 0x0;
+ uint32 logon_attempts = 0x0;
+ uint32 tc_status = ERROR_NO_LOGON_SERVERS;
+ char *trusted_domain = "test_domain";
+
+ *reply_switch_value = query_level;
+
+ switch (query_level)
+ {
+ case 1:
+ {
+ make_netinfo_1(&logon_info->info1, flags, pdc_status);
+ break;
+ }
+ case 2:
+ {
+ make_netinfo_2(&logon_info->info2, flags, pdc_status,
+ tc_status, trusted_domain);
+ break;
+ }
+ case 3:
+ {
+ make_netinfo_3(&logon_info->info3, flags,
+ logon_attempts);
+ break;
+ }
+ default:
+ {
+ /* take a guess at an error code... */
+ return NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*************************************************************************
+ _net_trust_dom_list
+ *************************************************************************/
+uint32 _net_trust_dom_list(const UNISTR2 * uni_server_name,
+ uint32 function_code, BUFFER2 * uni_trust_dom_name)
+{
+ char **doms = NULL;
+ uint32 num_doms = 0;
+
+ enumtrustdoms(&doms, &num_doms);
+
+ make_buffer2_multi(uni_trust_dom_name, doms, num_doms);
+
+ if (num_doms == 0)
+ {
+ uni_trust_dom_name->buf_max_len = 0x2;
+ uni_trust_dom_name->buf_len = 0x2;
+ }
+ uni_trust_dom_name->undoc = 0x1;
+
+ free_char_array(num_doms, doms);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*************************************************************************
+ _net_auth
+ *************************************************************************/
+uint32 _net_auth(const DOM_LOG_INFO * clnt_id,
+ const DOM_CHAL * clnt_chal,
+ DOM_CHAL * srv_chal, uint16 remote_pid)
+{
+ UTIME srv_time;
+ fstring trust_name;
+ struct dcinfo dc;
+
+ ZERO_STRUCT(dc);
+
+ srv_time.time = 0;
+
+ unistr2_to_ascii(trust_name, &clnt_id->uni_comp_name,
+ sizeof(trust_name) - 1);
+
+ if (!cred_get(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* check that the client credentials are valid */
+ if (!cred_assert
+ (clnt_chal, dc.sess_key, &(dc.clnt_cred.challenge), srv_time))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* create server challenge for inclusion in the reply */
+ cred_create(dc.sess_key, &(dc.srv_cred.challenge), srv_time,
+ srv_chal);
+
+ /* copy the received client credentials for use next time */
+ memcpy(dc.clnt_cred.challenge.data, clnt_chal->data,
+ sizeof(clnt_chal->data));
+ memcpy(dc.srv_cred.challenge.data, clnt_chal->data,
+ sizeof(clnt_chal->data));
+
+ if (!cred_store(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*************************************************************************
+ _net_auth_2
+ *************************************************************************/
+uint32 _net_auth_2(const DOM_LOG_INFO * clnt_id,
+ const DOM_CHAL * clnt_chal,
+ const NEG_FLAGS * clnt_flgs,
+ DOM_CHAL * srv_chal,
+ NEG_FLAGS * srv_flgs, uint16 remote_pid)
+{
+ UTIME srv_time;
+ fstring trust_name;
+ struct dcinfo dc;
+
+ ZERO_STRUCT(dc);
+
+ srv_time.time = 0;
+
+ unistr2_to_ascii(trust_name, &(clnt_id->uni_comp_name),
+ sizeof(trust_name) - 1);
+
+ if (!cred_get(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* check that the client credentials are valid */
+ if (!cred_assert(clnt_chal, dc.sess_key,
+ &(dc.clnt_cred.challenge), srv_time))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* create server challenge for inclusion in the reply */
+ cred_create(dc.sess_key, &(dc.srv_cred.challenge), srv_time,
+ srv_chal);
+
+ /* copy the received client credentials for use next time */
+ memcpy(dc.clnt_cred.challenge.data, clnt_chal->data,
+ sizeof(clnt_chal->data));
+ memcpy(dc.srv_cred.challenge.data, clnt_chal->data,
+ sizeof(clnt_chal->data));
+
+ if (!cred_store(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* mask out unsupported bits */
+ srv_flgs->neg_flags = clnt_flgs->neg_flags & 0x400001ff;
+
+ /* minimum bits required */
+ if (!IS_BITS_SET_ALL(srv_flgs->neg_flags, 0x000000ff))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* secure channel NOT to be used */
+ if (!lp_server_schannel())
+ {
+ srv_flgs->neg_flags &= ~0x40000000;
+ }
+ else
+ {
+ /* secure channel MUST be used */
+ if (IS_BITS_CLR_ALL(srv_flgs->neg_flags, 0x40000000))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*************************************************************************
+ _net_srv_pwset
+ *************************************************************************/
+uint32 _net_srv_pwset(const DOM_CLNT_INFO * clnt_id,
+ const uint8 pwd[16],
+ DOM_CRED * srv_cred, uint16 remote_pid)
+{
+ pstring trust_acct;
+ unsigned char hash3_pwd[16];
+ uint32 status_pwd;
+
+ fstring trust_name;
+ struct dcinfo dc;
+ const UNISTR2 *uni_samusr;
+ SAM_USERINFO_CTR ctr;
+ uint16 acb_info;
+
+ ZERO_STRUCT(dc);
+
+ uni_samusr = &(clnt_id->login.uni_comp_name);
+ unistr2_to_ascii(trust_name, uni_samusr, sizeof(trust_name) - 1);
+
+ if (!cred_get(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* checks and updates credentials. creates reply credentials */
+ if (!deal_with_creds
+ (dc.sess_key, &(dc.clnt_cred), &(clnt_id->cred), srv_cred))
+ {
+ /* lkclXXXX take a guess at a sensible error code to return... */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ memcpy(&(dc.srv_cred), &(dc.clnt_cred), sizeof(dc.clnt_cred));
+
+ unistr2_to_ascii(trust_acct, &(clnt_id->login.uni_acct_name),
+ sizeof(trust_acct) - 1);
+
+ DEBUG(3, ("Server Password Set Wksta:[%s]\n", trust_acct));
+
+ become_root(True);
+ status_pwd = direct_samr_userinfo(uni_samusr, 0x12, &ctr,
+ NULL, NULL, False);
+ unbecome_root(True);
+
+ acb_info = ctr.info.id12->acb_info;
+
+ if (IS_BITS_SET_SOME
+ (acb_info, ACB_NORMAL | ACB_DISABLED | ACB_PWNOTREQ))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ switch (clnt_id->login.sec_chan)
+ {
+ case SEC_CHAN_DOMAIN:
+ {
+ if (!IS_BITS_SET_ALL(acb_info, ACB_DOMTRUST))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+ case SEC_CHAN_BDC:
+ {
+ if (!IS_BITS_SET_ALL(acb_info, ACB_SVRTRUST))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+ case SEC_CHAN_WKSTA:
+ {
+ if (!IS_BITS_SET_ALL(acb_info, ACB_WSTRUST))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+
+ if (status_pwd != NT_STATUS_NOPROBLEMO)
+ {
+ free_samr_userinfo_ctr(&ctr);
+ return status_pwd;
+ }
+
+ /* Some debug output, needed an iterater variable */
+ {
+ int i;
+
+ DEBUG(100, ("Server password set : new given value was :\n"));
+ for (i = 0; i < 16; i++)
+ {
+ DEBUG(100, ("%02X ", pwd[i]));
+ }
+ DEBUG(100, ("\n"));
+ }
+
+ cred_hash3(hash3_pwd, pwd, dc.sess_key, 0);
+
+ /* lies! nt and lm passwords are _not_ the same: don't care */
+ memcpy(ctr.info.id12->lm_pwd, hash3_pwd, sizeof(hash3_pwd));
+ memcpy(ctr.info.id12->nt_pwd, hash3_pwd, sizeof(hash3_pwd));
+
+ become_root(True);
+ status_pwd = direct_samr_userinfo(uni_samusr, 0x12, &ctr,
+ NULL, NULL, True);
+ unbecome_root(True);
+
+ if (status_pwd != NT_STATUS_NOPROBLEMO)
+ {
+ return status_pwd;
+ }
+
+ if (!cred_store(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*************************************************************************
+ _net_sam_logon
+ *************************************************************************/
+uint32 _net_sam_logon(const DOM_SAM_INFO * sam_id,
+ uint16 validation_level,
+ DOM_CRED * srv_creds,
+ uint16 * switch_value,
+ NET_USER_INFO_3 * user, uint16 remote_pid)
+{
+ UNISTR2 *uni_samusr = NULL;
+ UNISTR2 *uni_domain = NULL;
+ fstring nt_username;
+ char *enc_user_sess_key = NULL;
+ char usr_sess_key[16];
+ char lm_pw8[16];
+ char *padding = NULL;
+ uint32 status_pwd = 0x0;
+ SAM_USERINFO_CTR ctr;
+
+ NTTIME logon_time;
+ NTTIME logoff_time;
+ NTTIME kickoff_time;
+ NTTIME pass_last_set_time;
+ NTTIME pass_can_change_time;
+ NTTIME pass_must_change_time;
+
+ UNISTR2 *uni_nt_name;
+ UNISTR2 *uni_full_name;
+ UNISTR2 *uni_logon_script;
+ UNISTR2 *uni_profile_path;
+ UNISTR2 *uni_home_dir;
+ UNISTR2 *uni_dir_drive;
+
+ uint32 user_rid;
+ uint32 group_rid;
+
+ int num_gids = 0;
+ DOM_GID *gids = NULL;
+
+ fstring trust_name;
+ struct dcinfo dc;
+ uint16 acb_info;
+
+ UNISTR2 uni_myname;
+ UNISTR2 uni_sam_name;
+
+ unistr2_to_ascii(trust_name, &(sam_id->client.login.uni_comp_name),
+ sizeof(trust_name) - 1);
+
+ if (!cred_get(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* checks and updates credentials. creates reply credentials */
+ if (!deal_with_creds(dc.sess_key, &dc.clnt_cred,
+ &(sam_id->client.cred), srv_creds))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ memcpy(&dc.srv_cred, &dc.clnt_cred, sizeof(dc.clnt_cred));
+
+ /* find the username */
+
+ switch (sam_id->logon_level)
+ {
+ case INTERACTIVE_LOGON_TYPE:
+ {
+ uni_samusr = &(sam_id->ctr->auth.id1.uni_user_name);
+ uni_domain = &(sam_id->ctr->auth.id1.uni_domain_name);
+
+ DEBUG(3,
+ ("SAM Logon (Interactive). Domain:[%s]. ",
+ global_sam_name));
+ break;
+ }
+ case NETWORK_LOGON_TYPE:
+ {
+ uni_samusr = &(sam_id->ctr->auth.id2.uni_user_name);
+ uni_domain = &(sam_id->ctr->auth.id2.uni_domain_name);
+
+ DEBUG(3,
+ ("SAM Logon (Network). Domain:[%s]. ",
+ global_sam_name));
+ break;
+ }
+ case GENERAL_LOGON_TYPE:
+ {
+ uni_samusr = &(sam_id->ctr->auth.id4.uni_user_name);
+ uni_domain = &(sam_id->ctr->auth.id4.uni_domain_name);
+
+ DEBUG(3,
+ ("SAM Logon (General). Domain:[%s]. ",
+ global_sam_name));
+ break;
+ }
+ default:
+ {
+ DEBUG(2, ("SAM Logon: unsupported switch value\n"));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ /* check username exists */
+
+ unistr2_to_ascii(nt_username, uni_samusr, sizeof(nt_username) - 1);
+
+ DEBUG(3, ("User:[%s]\n", nt_username));
+
+ /*
+ * IMPORTANT: do a General Login BEFORE the others,
+ * because "update encrypted" may be enabled, which
+ * will result in the smb password entry being added.
+ *
+ * calling general login AFTER the getsampwntname() is
+ * not guaranteed to deliver.
+ */
+
+ if (sam_id->logon_level == GENERAL_LOGON_TYPE)
+ {
+ /* general login. cleartext password */
+ uint32 status = NT_STATUS_NOPROBLEMO;
+ status =
+ net_login_general(&(sam_id->ctr->auth.id4), &dc,
+ usr_sess_key);
+ enc_user_sess_key = usr_sess_key;
+
+ if (status != NT_STATUS_NOPROBLEMO)
+ {
+ return status;
+ }
+ }
+
+ /*
+ * now obtain smb passwd entry, which MAY have just been
+ * added by "update encrypted" in general login
+ */
+ become_root(True);
+ status_pwd = direct_samr_userinfo(uni_samusr, 21, &ctr,
+ &gids, &num_gids, False);
+ unbecome_root(True);
+
+ if (status_pwd != NT_STATUS_NOPROBLEMO)
+ {
+ free_samr_userinfo_ctr(&ctr);
+ return status_pwd;
+ }
+
+ acb_info = ctr.info.id21->acb_info;
+ if (IS_BITS_SET_ALL(acb_info, ACB_DISABLED))
+ {
+ return NT_STATUS_ACCOUNT_DISABLED;
+ }
+
+ if (IS_BITS_SET_ALL(acb_info, ACB_DOMTRUST))
+ {
+ return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
+ }
+
+ if (IS_BITS_SET_ALL(acb_info, ACB_SVRTRUST))
+ {
+ return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT;
+ }
+
+ if (IS_BITS_SET_ALL(acb_info, ACB_WSTRUST))
+ {
+ return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
+ }
+
+ logon_time = ctr.info.id21->logon_time;
+ logoff_time = ctr.info.id21->logoff_time;
+ kickoff_time = ctr.info.id21->kickoff_time;
+ pass_last_set_time = ctr.info.id21->pass_last_set_time;
+ pass_can_change_time = ctr.info.id21->pass_can_change_time;
+ pass_must_change_time = ctr.info.id21->pass_must_change_time;
+
+ uni_nt_name = &ctr.info.id21->uni_user_name;
+ uni_full_name = &ctr.info.id21->uni_full_name;
+ uni_home_dir = &ctr.info.id21->uni_home_dir;
+ uni_dir_drive = &ctr.info.id21->uni_dir_drive;
+ uni_logon_script = &ctr.info.id21->uni_logon_script;
+ uni_profile_path = &ctr.info.id21->uni_profile_path;
+
+ user_rid = ctr.info.id21->user_rid;
+ group_rid = ctr.info.id21->group_rid;
+
+ /* validate password - if required */
+
+ if (!(IS_BITS_SET_ALL(acb_info, ACB_PWNOTREQ)))
+ {
+ uint32 status = NT_STATUS_NOPROBLEMO;
+ switch (sam_id->logon_level)
+ {
+ case INTERACTIVE_LOGON_TYPE:
+ {
+ /* interactive login. */
+ status =
+ net_login_interactive(&
+ (sam_id->ctr->
+ auth.id1),
+ &dc);
+ break;
+ }
+ case NETWORK_LOGON_TYPE:
+ {
+ /* network login. lm challenge and 24 byte responses */
+ status =
+ net_login_network(&
+ (sam_id->ctr->auth.
+ id2), acb_info,
+&dc, usr_sess_key, lm_pw8);
+ padding = lm_pw8;
+ enc_user_sess_key = usr_sess_key;
+ break;
+ }
+ case GENERAL_LOGON_TYPE:
+ {
+ /* general login type ALREADY been checked */
+ break;
+ }
+ }
+ if (status != NT_STATUS_NOPROBLEMO)
+ {
+ safe_free(gids);
+ free_samr_userinfo_ctr(&ctr);
+ return status;
+ }
+ }
+
+ /* lkclXXXX this is the point at which, if the login was
+ successful, that the SAM Local Security Authority should
+ record that the user is logged in to the domain.
+ */
+
+ /* return the profile plus other bits :-) */
+
+ make_unistr2(&uni_myname, global_myname, strlen(global_myname));
+ make_unistr2(&uni_sam_name, global_sam_name, strlen(global_sam_name));
+
+ make_net_user_info3W(user, &logon_time, &logoff_time, &kickoff_time, &pass_last_set_time, &pass_can_change_time, &pass_must_change_time, uni_nt_name, /* user_name */
+ uni_full_name, /* full_name */
+ uni_logon_script, /* logon_script */
+ uni_profile_path, /* profile_path */
+ uni_home_dir, /* home_dir */
+ uni_dir_drive, /* dir_drive */
+ 0, /* logon_count */
+ 0, /* bad_pw_count */
+ user_rid, /* RID user_id */
+ group_rid, /* RID group_id */
+ num_gids, /* uint32 num_groups */
+ gids, /* DOM_GID *gids */
+ 0x20, /* uint32 user_flgs (?) */
+ enc_user_sess_key, /* char usr_sess_key[16] */
+ &uni_myname, /* char *logon_srv */
+ &uni_sam_name, /* char *logon_dom */
+ padding, &global_sam_sid, /* DOM_SID *dom_sid */
+ NULL); /* char *other_sids */
+
+ /* Free any allocated groups array. */
+ safe_free(gids);
+ free_samr_userinfo_ctr(&ctr);
+
+ if (!cred_store(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*************************************************************************
+ _net_sam_logoff
+ *************************************************************************/
+uint32 _net_sam_logoff(const DOM_SAM_INFO * sam_id,
+ DOM_CRED * srv_creds, uint16 remote_pid)
+{
+ fstring trust_name;
+ struct dcinfo dc;
+
+ ZERO_STRUCT(dc);
+
+ unistr2_to_ascii(trust_name, &(sam_id->client.login.uni_comp_name),
+ sizeof(trust_name) - 1);
+
+ if (!cred_get(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* checks and updates credentials. creates reply credentials */
+ if (!deal_with_creds(dc.sess_key, &(dc.clnt_cred),
+ &(sam_id->client.cred), srv_creds))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ memcpy(&(dc.srv_cred), &(dc.clnt_cred), sizeof(dc.clnt_cred));
+
+ if (!cred_store(remote_pid, global_sam_name, trust_name, &dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*************************************************************************
+ _net_sam_sync
+ *************************************************************************/
+uint32 _net_sam_sync(const UNISTR2 * uni_srv_name,
+ const UNISTR2 * uni_cli_name,
+ uint32 database_id,
+ uint32 restart_state,
+ uint32 * sync_context,
+ uint32 max_size,
+ uint32 * num_deltas,
+ uint32 * num_deltas2,
+ SAM_DELTA_HDR * hdr_deltas, SAM_DELTA_CTR * deltas)
+{
+ fstring trust_name;
+
+ int i = 0;
+
+ POLICY_HND sam_pol;
+ POLICY_HND dom_pol;
+
+ uint32 enum_status;
+
+ SAM_ENTRY *sam = NULL;
+ UNISTR2 *uni_acct_name = NULL;
+ uint32 start_idx = 0x0;
+ uint32 num_sam_users = 0;
+ uint32 idx;
+
+ unistr2_to_ascii(trust_name, uni_cli_name, sizeof(trust_name) - 1);
+
+ (*sync_context) = 1;
+
+ if (_samr_connect(NULL, 0x02000000, &sam_pol) != NT_STATUS_NOPROBLEMO)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ if (_samr_open_domain(&sam_pol, 0x02000000,
+ &global_sam_sid,
+ &dom_pol) != NT_STATUS_NOPROBLEMO)
+ {
+ _samr_close(&sam_pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /*
+ * enumerate users, first
+ */
+
+ do
+ {
+ enum_status = _samr_enum_dom_users(&dom_pol,
+ &start_idx,
+ 0x0, 0x0, 0x10000,
+ &sam,
+ &uni_acct_name,
+ &num_sam_users);
+
+ }
+ while (enum_status == STATUS_MORE_ENTRIES);
+
+ for (idx = 0; idx < num_sam_users; idx++)
+ {
+ SAM_USERINFO_CTR ctr;
+ POLICY_HND usr_pol;
+ uint32 status_usr = NT_STATUS_NOPROBLEMO;
+
+ ZERO_STRUCT(ctr);
+
+ status_usr =
+ _samr_open_user(&dom_pol, 0x02000000, sam[idx].rid,
+ &usr_pol);
+ if (status_usr == NT_STATUS_NOPROBLEMO
+ && _samr_query_userinfo(&usr_pol, 0x21,
+ &ctr) == NT_STATUS_NOPROBLEMO)
+ {
+ SAM_USER_INFO_21 *usr = ctr.info.id21;
+
+ make_sam_delta_hdr(&hdr_deltas[i], 5, usr->user_rid);
+ make_sam_account_info(&deltas[i].account_info,
+ &usr->uni_user_name,
+ &usr->uni_full_name,
+ usr->user_rid, usr->group_rid,
+ &usr->uni_home_dir,
+ &usr->uni_dir_drive,
+ &usr->uni_logon_script,
+ &usr->uni_acct_desc,
+ usr->acb_info,
+ &usr->uni_profile_path,
+ &usr->uni_workstations,
+ &usr->uni_unknown_str,
+ &usr->uni_munged_dial);
+
+ i++;
+ free_samr_userinfo_ctr(&ctr);
+ }
+
+ if (status_usr == NT_STATUS_NOPROBLEMO)
+ {
+ _samr_close(&usr_pol);
+ }
+ }
+
+ safe_free(sam);
+ safe_free(uni_acct_name);
+
+ sam = NULL;
+ uni_acct_name = NULL;
+ num_sam_users = 0;
+
+ _samr_close(&dom_pol);
+ _samr_close(&sam_pol);
+
+ (*num_deltas2) = i;
+ (*num_deltas) = i;
+
+ return NT_STATUS_NOPROBLEMO;
+}
diff --git a/source/nmbd/asyncdns.c b/source/nmbd/asyncdns.c
index 99e697b4705..67e55ebd508 100644
--- a/source/nmbd/asyncdns.c
+++ b/source/nmbd/asyncdns.c
@@ -52,7 +52,7 @@ static struct name_record *add_dns_result(struct nmb_name *question, struct in_a
#ifndef SYNC_DNS
static int fd_in = -1, fd_out = -1;
-static pid_t child_pid = -1;
+static int child_pid = -1;
static int in_dns;
/* this is the structure that is passed between the parent and child */
@@ -147,7 +147,7 @@ void start_async_dns(void)
fd_out = fd2[1];
close(fd1[1]);
close(fd2[0]);
- DEBUG(0,("started asyncdns process %d\n", (int)child_pid));
+ DEBUG(0,("started asyncdns process %d\n", child_pid));
return;
}
diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c
index cf472d579d7..e3be547c0aa 100644
--- a/source/nmbd/nmbd.c
+++ b/source/nmbd/nmbd.c
@@ -1,7 +1,7 @@
/*
- Unix SMB/Netbios implementation.
+ Unix SMB/NetBIOS implementation.
Version 1.9.
- NBT netbios routines and daemon - version 2
+ NBT NetBIOS routines and daemon - version 2
Copyright (C) Andrew Tridgell 1994-1998
This program is free software; you can redistribute it and/or modify
@@ -32,10 +32,13 @@ extern int DEBUGLEVEL;
extern pstring debugf;
pstring servicesf = CONFIGFILE;
+extern pstring scope;
+
int ClientNMB = -1;
int ClientDGRAM = -1;
int global_nmb_port = -1;
+extern pstring myhostname;
static pstring host_file;
extern pstring global_myname;
extern fstring global_myworkgroup;
@@ -56,6 +59,50 @@ time_t StartupTime = 0;
extern struct in_addr ipzero;
/**************************************************************************** **
+ reload the services file
+ **************************************************************************** */
+static BOOL reload_nmbd_services(BOOL test)
+{
+ BOOL ret;
+ extern fstring remote_machine;
+
+ fstrcpy( remote_machine, "nmb" );
+
+ if ( lp_loaded() )
+ {
+ pstring fname;
+ pstrcpy( fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
+ {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
+ if ( test && !lp_file_list_changed() )
+ return(True);
+
+ ret = lp_load( servicesf, True , False, False);
+
+ /* perhaps the config filename is now set */
+ if ( !test )
+ {
+ DEBUG( 3, ( "services not loaded\n" ) );
+ reload_nmbd_services( True );
+ }
+
+ /* Do a sanity check for a misconfigured nmbd */
+ if( lp_wins_support() && *lp_wins_server() )
+ {
+ DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
+cannot be set in the smb.conf file. nmbd aborting.\n"));
+ exit(10);
+ }
+
+ return(ret);
+} /* reload_nmbd_services */
+
+/**************************************************************************** **
catch a sigterm
**************************************************************************** */
static void sig_term(int sig)
@@ -83,8 +130,6 @@ static void sig_term(int sig)
/**************************************************************************** **
catch a sighup
**************************************************************************** */
-static VOLATILE SIG_ATOMIC_T reload_after_sighup = False;
-
static void sig_hup(int sig)
{
BlockSignals( True, SIGHUP );
@@ -94,8 +139,9 @@ static void sig_hup(int sig)
write_browse_list( 0, True );
dump_all_namelists();
+ reload_nmbd_services( True );
- reload_after_sighup = True;
+ set_samba_nb_type();
BlockSignals(False,SIGHUP);
@@ -182,111 +228,6 @@ static void expire_names_and_servers(time_t t)
expire_workgroups_and_servers(t);
} /* expire_names_and_servers */
-
-/************************************************************************** **
-reload the list of network interfaces
- ************************************************************************** */
-static void reload_interfaces(time_t t)
-{
- static time_t lastt;
- int n;
- struct subnet_record *subrec;
- extern BOOL rescan_listen_set;
-
- if (t && ((t - lastt) < NMBD_INTERFACES_RELOAD)) return;
- lastt = t;
-
- if (!interfaces_changed()) return;
-
- /* the list of probed interfaces has changed, we may need to add/remove
- some subnets */
- load_interfaces();
-
- /* find any interfaces that need adding */
- for (n=iface_count() - 1; n >= 0; n--) {
- struct interface *iface = get_interface(n);
- for (subrec=subnetlist; subrec; subrec=subrec->next) {
- if (ip_equal(iface->ip, subrec->myip) &&
- ip_equal(iface->nmask, subrec->mask_ip)) break;
- }
- if (!subrec) {
- /* it wasn't found! add it */
- DEBUG(2,("Found new interface %s\n",
- inet_ntoa(iface->ip)));
- subrec = make_normal_subnet(iface);
- if (subrec) register_my_workgroup_one_subnet(subrec);
- }
- }
-
- /* find any interfaces that need deleting */
- for (subrec=subnetlist; subrec; subrec=subrec->next) {
- for (n=iface_count() - 1; n >= 0; n--) {
- struct interface *iface = get_interface(n);
- if (ip_equal(iface->ip, subrec->myip) &&
- ip_equal(iface->nmask, subrec->mask_ip)) break;
- }
- if (n == -1) {
- /* oops, an interface has disapeared. This is
- tricky, we don't dare actually free the
- interface as it could be being used, so
- instead we just wear the memory leak and
- remove it from the list of interfaces without
- freeing it */
- DEBUG(2,("Deleting dead interface %s\n",
- inet_ntoa(subrec->myip)));
- close_subnet(subrec);
- }
- }
-
- rescan_listen_set = True;
-}
-
-
-
-/**************************************************************************** **
- reload the services file
- **************************************************************************** */
-BOOL reload_services(BOOL test)
-{
- BOOL ret;
- extern fstring remote_machine;
-
- fstrcpy( remote_machine, "nmb" );
-
- if ( lp_loaded() )
- {
- pstring fname;
- pstrcpy( fname,lp_configfile());
- if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
- {
- pstrcpy(servicesf,fname);
- test = False;
- }
- }
-
- if ( test && !lp_file_list_changed() )
- return(True);
-
- ret = lp_load( servicesf, True , False, False);
-
- /* perhaps the config filename is now set */
- if ( !test )
- {
- DEBUG( 3, ( "services not loaded\n" ) );
- reload_services( True );
- }
-
- /* Do a sanity check for a misconfigured nmbd */
- if( lp_wins_support() && *lp_wins_server() )
- {
- DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
-cannot be set in the smb.conf file. nmbd aborting.\n"));
- exit(10);
- }
-
- return(ret);
-} /* reload_services */
-
/**************************************************************************** **
The main select loop.
**************************************************************************** */
@@ -454,28 +395,6 @@ static void process(void)
* regularly sync with any other DMBs we know about
*/
sync_all_dmbs(t);
-
- /*
- * clear the unexpected packet queue
- */
- clear_unexpected(t);
-
- /*
- * Reload the services file if we got a sighup.
- */
-
- if(reload_after_sighup) {
- reload_services( True );
- reopen_logs();
- reload_interfaces(0);
- reload_after_sighup = False;
- }
-
- /* check for new network interfaces */
- reload_interfaces(t);
-
- /* free up temp memory */
- lp_talloc_free();
}
} /* process */
@@ -527,7 +446,7 @@ static BOOL init_structs(void)
if (! *global_myname)
{
- fstrcpy( global_myname, myhostname() );
+ fstrcpy( global_myname, myhostname );
p = strchr( global_myname, '.' );
if (p)
*p = 0;
@@ -590,7 +509,7 @@ static BOOL init_structs(void)
*p = 0;
strlower( local_machine );
- DEBUG( 5, ("Netbios name list:-\n") );
+ DEBUG( 5, ("NetBIOS name list:-\n") );
for( n=0; my_netbios_names[n]; n++ )
DEBUGADD( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) );
@@ -602,20 +521,20 @@ static BOOL init_structs(void)
**************************************************************************** */
static void usage(char *pname)
{
-
- printf( "Usage: %s [-DaohV] [-H lmhosts file] [-d debuglevel] [-l log basename]\n", pname );
- printf( " [-n name] [-p port] [-s configuration file]\n" );
- printf( "\t-D Become a daemon\n" );
- printf( "\t-a Append to log file (default)\n" );
- printf( "\t-o Overwrite log file, don't append\n" );
- printf( "\t-h Print usage\n" );
- printf( "\t-V Print version\n" );
- printf( "\t-H hosts file Load a netbios hosts file\n" );
- printf( "\t-d debuglevel Set the debuglevel\n" );
+ DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
+
+ printf( "Usage: %s [-n name] [-D] [-p port] [-d debuglevel] ", pname );
+ printf( "[-l log basename]\n" );
+ printf( "Version %s\n", VERSION );
+ printf( "\t-D become a daemon\n" );
+ printf( "\t-p port listen on the specified port\n" );
+ printf( "\t-d debuglevel set the debuglevel\n" );
printf( "\t-l log basename. Basename for log/debug files\n" );
- printf( "\t-n netbiosname. Primary netbios name\n" );
- printf( "\t-p port Listen on the specified port\n" );
- printf( "\t-s configuration file Configuration file name\n" );
+ printf( "\t-n netbiosname. " );
+ printf( "the netbios name to advertise for this host\n");
+ printf( "\t-H hosts file load a netbios hosts file\n" );
+ printf( "\t-a append to log file (default)\n" );
+ printf( "\t-o overwrite log file, don't append\n" );
printf( "\n");
} /* usage */
@@ -664,26 +583,23 @@ static void usage(char *pname)
CatchSignal( SIGHUP, SIGNAL_CAST sig_hup );
CatchSignal( SIGTERM, SIGNAL_CAST sig_term );
-#if defined(SIGFPE)
- /* we are never interested in SIGFPE */
- BlockSignals(True,SIGFPE);
-#endif
-
/* Setup the signals that allow the debug log level
to by dynamically changed. */
/* If we are using the malloc debug code we can't use
SIGUSR1 and SIGUSR2 to do debug level changes. */
+#ifndef MEM_MAN
#if defined(SIGUSR1)
- CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
+ CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
#endif /* SIGUSR1 */
#if defined(SIGUSR2)
- CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
+ CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
#endif /* SIGUSR2 */
+#endif /* MEM_MAN */
while( EOF !=
- (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dp:hSH:G:f:" )) )
+ (opt = getopt( argc, argv, "aos:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:f:" )) )
{
switch (opt)
{
@@ -707,6 +623,10 @@ static void usage(char *pname)
case 'l':
slprintf(debugf,sizeof(debugf)-1, "%s.nmb",optarg);
break;
+ case 'i':
+ pstrcpy(scope,optarg);
+ strupper(scope);
+ break;
case 'a':
append_log = True;
break;
@@ -726,14 +646,9 @@ static void usage(char *pname)
usage(argv[0]);
exit(0);
break;
- case 'V':
- printf( "Version %s\n", VERSION );
- exit(0);
- break;
default:
if( !is_a_socket(0) )
{
- DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
usage(argv[0]);
exit(0);
}
@@ -743,10 +658,16 @@ static void usage(char *pname)
reopen_logs();
- DEBUG( 1, ( "Netbios nameserver version %s started.\n", VERSION ) );
+ DEBUG( 1, ( "NetBIOS nameserver version %s started.\n", VERSION ) );
DEBUGADD( 1, ( "Copyright Andrew Tridgell 1994-1998\n" ) );
- if ( !reload_services(False) )
+ if( !get_myname( myhostname, NULL) )
+ {
+ DEBUG( 0, ( "Unable to get my hostname - exiting.\n" ) );
+ return -1;
+ }
+
+ if ( !reload_nmbd_services(False) )
return(-1);
codepage_initialise(lp_client_code_page());
@@ -754,15 +675,12 @@ static void usage(char *pname)
if(!init_structs())
return -1;
- reload_services( True );
-
- fstrcpy( global_myworkgroup, lp_workgroup() );
+ reload_nmbd_services( True );
- if (strequal(global_myworkgroup,"*"))
- {
- DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
- exit(1);
- }
+ if (!init_myworkgroup())
+ {
+ exit(1);
+ }
set_samba_nb_type();
@@ -778,14 +696,6 @@ static void usage(char *pname)
become_daemon();
}
-#ifndef SYNC_DNS
- /* Setup the async dns. We do it here so it doesn't have all the other
- stuff initialised and thus chewing memory and sockets */
- if(lp_we_are_a_wins_server()) {
- start_async_dns();
- }
-#endif
-
if (!directory_exist(lp_lockdir(), NULL)) {
mkdir(lp_lockdir(), 0755);
}
diff --git a/source/nmbd/nmbd_become_dmb.c b/source/nmbd/nmbd_become_dmb.c
index 76d92c2f3ed..cbef1db4b7e 100644
--- a/source/nmbd/nmbd_become_dmb.c
+++ b/source/nmbd/nmbd_become_dmb.c
@@ -26,6 +26,7 @@
extern int DEBUGLEVEL;
+extern pstring scope;
extern pstring global_myname;
extern fstring global_myworkgroup;
extern char **my_netbios_names;
@@ -132,7 +133,7 @@ in workgroup %s on subnet %s\n",
will stop us syncing with ourself if we are also
a local master browser. */
- make_nmb_name(&nmbname, global_myname, 0x20);
+ make_nmb_name(&nmbname, global_myname, 0x20, scope);
work->dmb_name = nmbname;
/* Pick the first interface ip address as the domain master browser ip. */
@@ -156,16 +157,6 @@ in workgroup %s on subnet %s\n",
*/
become_domain_master_browser_bcast(work->work_group);
}
- else
- {
- /*
- * Now we are a domain master on a broadcast subnet, we need to add
- * the WORKGROUP<1b> name to the unicast subnet so that we can answer
- * unicast requests sent to this name. This bug wasn't found for a while
- * as it is strange to have a DMB without using WINS. JRA.
- */
- insert_permanent_name_into_unicast(subrec, registered_name, nb_flags);
- }
}
/****************************************************************************
@@ -281,7 +272,7 @@ static void become_domain_master_browser_bcast(char *workgroup_name)
if (work && (work->dom_state == DOMAIN_NONE))
{
struct nmb_name nmbname;
- make_nmb_name(&nmbname,workgroup_name,0x1b);
+ make_nmb_name(&nmbname,workgroup_name,0x1b,scope);
/*
* Check for our name on the given broadcast subnet first, only initiate
@@ -329,7 +320,7 @@ static void become_domain_master_browser_wins(char *workgroup_name)
{
struct nmb_name nmbname;
- make_nmb_name(&nmbname,workgroup_name,0x1b);
+ make_nmb_name(&nmbname,workgroup_name,0x1b,scope);
/*
* Check for our name on the unicast subnet first, only initiate
diff --git a/source/nmbd/nmbd_become_lmb.c b/source/nmbd/nmbd_become_lmb.c
index 31c67ae7f3f..f3fa69132e9 100644
--- a/source/nmbd/nmbd_become_lmb.c
+++ b/source/nmbd/nmbd_become_lmb.c
@@ -25,6 +25,7 @@
#include "includes.h"
extern int DEBUGLEVEL;
+extern pstring scope;
extern pstring global_myname;
extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
@@ -125,7 +126,7 @@ in workgroup %s on subnet %s\n",
* master browser.
*/
- make_nmb_name(&nmbname, work->work_group, 0x1d);
+ make_nmb_name(&nmbname, work->work_group, 0x1d, scope);
remove_permanent_name_from_unicast( subrec, &nmbname);
@@ -207,7 +208,7 @@ static void release_1d_name( struct subnet_record *subrec, char *workgroup_name,
struct nmb_name nmbname;
struct name_record *namerec;
- make_nmb_name(&nmbname, workgroup_name, 0x1d);
+ make_nmb_name(&nmbname, workgroup_name, 0x1d, scope);
if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
{
struct userdata_struct *userdata;
@@ -307,7 +308,7 @@ in workgroup %s on subnet %s\n",
release_1d_name( subrec, work->work_group, force_new_election);
/* Deregister any browser names we may have. */
- make_nmb_name(&nmbname, MSBROWSE, 0x1);
+ make_nmb_name(&nmbname, MSBROWSE, 0x1, scope);
if((namerec = find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME))!=NULL)
{
release_name(subrec, namerec,
diff --git a/source/nmbd/nmbd_browserdb.c b/source/nmbd/nmbd_browserdb.c
index 10d22431e91..12ce00df4f2 100644
--- a/source/nmbd/nmbd_browserdb.c
+++ b/source/nmbd/nmbd_browserdb.c
@@ -99,7 +99,7 @@ struct browse_cache_record *create_browser_in_lmb_cache( char *work_name,
return( NULL );
}
- memset( (char *)browc, '\0', sizeof( *browc ) );
+ bzero( (char *)browc, sizeof( *browc ) );
/* For a new lmb entry we want to sync with it after one minute. This
will allow it time to send out a local announce and build its
diff --git a/source/nmbd/nmbd_browsesync.c b/source/nmbd/nmbd_browsesync.c
index 23ca0a398f5..eafcc79c0aa 100644
--- a/source/nmbd/nmbd_browsesync.c
+++ b/source/nmbd/nmbd_browsesync.c
@@ -26,12 +26,13 @@
#include "smb.h"
extern int DEBUGLEVEL;
+extern pstring scope;
extern struct in_addr ipzero;
extern pstring global_myname;
extern fstring global_myworkgroup;
/* This is our local master browser list database. */
-extern ubi_dlList lmb_browserlist[];
+extern struct ubi_dlList lmb_browserlist[];
/****************************************************************************
As a domain master browser, do a sync with a local master browser.
@@ -127,7 +128,7 @@ static void announce_local_master_browser_to_domain_master_browser( struct work_
return;
}
- memset(outbuf,'\0',sizeof(outbuf));
+ bzero(outbuf,sizeof(outbuf));
p = outbuf;
CVAL(p,0) = ANN_MasterAnnouncement;
p++;
@@ -225,7 +226,7 @@ static void domain_master_node_status_success(struct subnet_record *subrec,
{
struct nmb_name nmbname;
- make_nmb_name(&nmbname, qname, name_type);
+ make_nmb_name(&nmbname, qname, name_type, scope);
/* Copy the dmb name and IP address
into the workgroup struct. */
@@ -323,7 +324,8 @@ static void find_domain_master_name_query_success(struct subnet_record *subrec,
putip((char *)&work->dmb_addr, &ipzero);
/* Now initiate the node status request. */
- make_nmb_name(&nmbname,"*",0x0);
+ bzero((char *)&nmbname, sizeof(nmbname));
+ nmbname.name[0] = '*';
/* Put the workgroup name into the userdata so we know
what workgroup we're talking to when the reply comes
@@ -389,7 +391,7 @@ void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec,
return;
}
- make_nmb_name(&nmbname,work->work_group,0x1b);
+ make_nmb_name(&nmbname,work->work_group,0x1b,scope);
/* First, query for the WORKGROUP<1b> name from the WINS server. */
query_name(unicast_subnet, nmbname.name, nmbname.name_type,
@@ -484,7 +486,7 @@ static void get_domain_master_name_node_status_success(struct subnet_record *sub
/* remember who the master is */
fstrcpy(work->local_master_browser_name, server_name);
- make_nmb_name(&nmbname, server_name, 0x20);
+ make_nmb_name(&nmbname, server_name, 0x20, scope);
work->dmb_name = nmbname;
work->dmb_addr = from_ip;
}
@@ -547,7 +549,8 @@ static void find_all_domain_master_names_query_success(struct subnet_record *sub
for(i = 0; i < rrec->rdlength / 6; i++)
{
/* Initiate the node status requests. */
- make_nmb_name(&nmbname, "*", 0);
+ bzero((char *)&nmbname, sizeof(nmbname));
+ nmbname.name[0] = '*';
putip((char *)&send_ip, (char *)&rrec->rdata[(i*6) + 2]);
@@ -633,7 +636,7 @@ void collect_all_workgroup_names_from_wins_server(time_t t)
lastrun = t;
- make_nmb_name(&nmbname,"*",0x1b);
+ make_nmb_name(&nmbname,"*",0x1b,scope);
/* First, query for the *<1b> name from the WINS server. */
query_name(unicast_subnet, nmbname.name, nmbname.name_type,
@@ -691,7 +694,7 @@ void sync_all_dmbs(time_t t)
the same as the unicast local master */
make_nmb_name(&work->dmb_name,
work->local_master_browser_name,
- 0x20);
+ 0x20, scope);
}
DEBUG(3,("Initiating DMB<->DMB sync with %s(%s)\n",
diff --git a/source/nmbd/nmbd_elections.c b/source/nmbd/nmbd_elections.c
index be38b572f66..8f876eab0c5 100644
--- a/source/nmbd/nmbd_elections.c
+++ b/source/nmbd/nmbd_elections.c
@@ -26,6 +26,8 @@
extern int DEBUGLEVEL;
+extern pstring scope;
+
extern pstring global_myname;
extern fstring global_myworkgroup;
@@ -44,7 +46,7 @@ static void send_election_dgram(struct subnet_record *subrec, char *workgroup_na
DEBUG(2,("send_election_dgram: Sending election packet for workgroup %s on subnet %s\n",
workgroup_name, subrec->subnet_name ));
- memset(outbuf,'\0',sizeof(outbuf));
+ bzero(outbuf,sizeof(outbuf));
p = outbuf;
CVAL(p,0) = ANN_Election; /* Election opcode. */
p++;
@@ -133,9 +135,6 @@ void check_master_browser_exists(time_t t)
struct subnet_record *subrec;
char *workgroup_name = global_myworkgroup;
- if (!lastrun)
- lastrun = t;
-
if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60)))
return;
@@ -192,7 +191,7 @@ void run_elections(time_t t)
*/
struct nmb_name nmbname;
- make_nmb_name(&nmbname, work->work_group, 0x1e);
+ make_nmb_name(&nmbname, work->work_group, 0x1e, scope);
if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
DEBUG(8,("run_elections: Cannot send election packet yet as name %s not \
yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
@@ -363,7 +362,7 @@ BOOL check_elections(void)
*/
struct nmb_name nmbname;
- make_nmb_name(&nmbname, work->work_group, 0x1e);
+ make_nmb_name(&nmbname, work->work_group, 0x1e, scope);
if(find_name_on_subnet( subrec, &nmbname, FIND_SELF_NAME)==NULL) {
DEBUG(8,("check_elections: Cannot send election packet yet as name %s not \
yet registered on subnet %s\n", nmb_namestr(&nmbname), subrec->subnet_name ));
diff --git a/source/nmbd/nmbd_incomingdgrams.c b/source/nmbd/nmbd_incomingdgrams.c
index b8be579779f..41aaebd9b1b 100644
--- a/source/nmbd/nmbd_incomingdgrams.c
+++ b/source/nmbd/nmbd_incomingdgrams.c
@@ -546,11 +546,10 @@ static void send_backup_list_response(struct subnet_record *subrec,
char outbuf[1024];
char *p, *countptr;
unsigned int count = 0;
-#if 0
+ int len;
struct server_record *servrec;
-#endif
- memset(outbuf,'\0',sizeof(outbuf));
+ bzero(outbuf,sizeof(outbuf));
DEBUG(3,("send_backup_list_response: sending backup list for workgroup %s to %s IP %s\n",
work->work_group, nmb_namestr(send_to_name), inet_ntoa(sendto_ip)));
@@ -573,20 +572,9 @@ static void send_backup_list_response(struct subnet_record *subrec,
p = skip_string(p,1);
/* Look for backup browsers in this workgroup. */
-
-#if 0
- /* we don't currently send become_backup requests so we should never
- send any other servers names out as backups for our
- workgroup. That's why this is commented out (tridge) */
-
- /*
- * NB. Note that the struct work_record here is not neccessarily
- * attached to the subnet *subrec.
- */
-
for (servrec = work->serverlist; servrec; servrec = servrec->next)
{
- int len = PTR_DIFF(p, outbuf);
+ len = PTR_DIFF(p, outbuf);
if((sizeof(outbuf) - len) < 16)
break;
@@ -608,10 +596,11 @@ static void send_backup_list_response(struct subnet_record *subrec,
p = skip_string(p,1);
}
-#endif
SCVAL(countptr, 0, count);
+ len = PTR_DIFF(p, outbuf);
+
DEBUG(4,("send_backup_list_response: sending response to %s<00> IP %s with %d servers.\n",
send_to_name->name, inet_ntoa(sendto_ip), count));
@@ -641,7 +630,6 @@ void process_get_backup_list_request(struct subnet_record *subrec,
uint32 token = IVAL(buf,1); /* Sender's key index for the workgroup. */
int name_type = dgram->dest_name.name_type;
char *workgroup_name = dgram->dest_name.name;
- struct subnet_record *search_subrec = subrec;
DEBUG(3,("process_get_backup_list_request: request from %s IP %s to %s.\n",
nmb_namestr(&dgram->source_name), inet_ntoa(p->ip),
@@ -658,19 +646,13 @@ void process_get_backup_list_request(struct subnet_record *subrec,
return;
}
- if((work = find_workgroup_on_subnet(search_subrec, workgroup_name)) == NULL)
+ if((work = find_workgroup_on_subnet(subrec, workgroup_name)) == NULL)
{
DEBUG(0,("process_get_backup_list_request: Cannot find workgroup %s on \
-subnet %s.\n", workgroup_name, search_subrec->subnet_name));
+subnet %s.\n", workgroup_name, subrec->subnet_name));
return;
}
- /*
- * If the packet was sent to WORKGROUP<1b> instead
- * of WORKGROUP<1d> then it was unicast to us a domain master
- * browser. Change search subrec to unicast.
- */
-
if(name_type == 0x1b)
{
/* We must be a domain master browser in order to
@@ -682,8 +664,6 @@ subnet %s.\n", workgroup_name, search_subrec->subnet_name));
and I am not a domain master browser.\n", workgroup_name));
return;
}
-
- search_subrec = unicast_subnet;
}
else if (name_type == 0x1d)
{
diff --git a/source/nmbd/nmbd_incomingrequests.c b/source/nmbd/nmbd_incomingrequests.c
index 7c46204445c..dd5a23e0b0d 100644
--- a/source/nmbd/nmbd_incomingrequests.c
+++ b/source/nmbd/nmbd_incomingrequests.c
@@ -176,9 +176,8 @@ void process_name_refresh_request(struct subnet_record *subrec,
and send an error reply back.
*/
DEBUG(0,("process_name_refresh_request: unicast name registration request \
-received for name %s from IP %s on subnet %s.\n",
+received for name %s from IP %s on subnet %s. Error - should be sent to WINS server\n",
nmb_namestr(question), inet_ntoa(from_ip), subrec->subnet_name));
- DEBUG(0,("Error - should be sent to WINS server\n"));
send_name_registration_response(FMT_ERR, 0, p);
return;
@@ -367,7 +366,7 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
strequal(qname, namerec->name.name)))
{
/* Start with the name. */
- memset(buf,'\0',18);
+ bzero(buf,18);
slprintf(buf, 17, "%-15.15s",namerec->name.name);
strupper(buf);
@@ -422,7 +421,7 @@ subnet %s - name not found.\n", nmb_namestr(&nmb->question.question_name),
/* We don't send any stats as they could be used to attack
the protocol. */
- memset(buf,'\0',46);
+ bzero(buf,46);
buf += 46;
diff --git a/source/nmbd/nmbd_logonnames.c b/source/nmbd/nmbd_logonnames.c
index c63de56a34a..471a64377d7 100644
--- a/source/nmbd/nmbd_logonnames.c
+++ b/source/nmbd/nmbd_logonnames.c
@@ -26,6 +26,7 @@
extern int DEBUGLEVEL;
+extern pstring scope;
extern pstring global_myname;
extern fstring global_myworkgroup;
extern char **my_netbios_names;
@@ -151,7 +152,7 @@ void add_logon_names(void)
if (work && (work->log_state == LOGON_NONE))
{
struct nmb_name nmbname;
- make_nmb_name(&nmbname,global_myworkgroup,0x1c);
+ make_nmb_name(&nmbname,global_myworkgroup,0x1c,scope);
if (find_name_on_subnet(subrec, &nmbname, FIND_SELF_NAME) == NULL)
{
diff --git a/source/nmbd/nmbd_mynames.c b/source/nmbd/nmbd_mynames.c
index 7ea8ffc9465..64cb8ea9e93 100644
--- a/source/nmbd/nmbd_mynames.c
+++ b/source/nmbd/nmbd_mynames.c
@@ -28,6 +28,7 @@ extern int DEBUGLEVEL;
extern char **my_netbios_names;
extern fstring global_myworkgroup;
+extern pstring scope;
extern uint16 samba_nb_type; /* Samba's NetBIOS type. */
@@ -42,47 +43,6 @@ static void my_name_register_failed(struct subnet_record *subrec,
nmb_namestr(nmbname), subrec->subnet_name));
}
-
-/****************************************************************************
- Add my workgroup and my given names to one subnet
- Also add the magic Samba names.
- **************************************************************************/
-void register_my_workgroup_one_subnet(struct subnet_record *subrec)
-{
- int i;
-
- struct work_record *work;
-
- /* Create the workgroup on the subnet. */
- if((work = create_workgroup_on_subnet(subrec, global_myworkgroup,
- PERMANENT_TTL)) == NULL) {
- DEBUG(0,("register_my_workgroup_and_names: Failed to create my workgroup %s on subnet %s. \
-Exiting.\n", global_myworkgroup, subrec->subnet_name));
- return;
- }
-
- /* Each subnet entry, except for the wins_server_subnet has
- the magic Samba names. */
- add_samba_names_to_subnet(subrec);
-
- /* Register all our names including aliases. */
- for (i=0; my_netbios_names[i]; i++) {
- register_name(subrec, my_netbios_names[i],0x20,samba_nb_type,
- NULL,
- my_name_register_failed, NULL);
- register_name(subrec, my_netbios_names[i],0x03,samba_nb_type,
- NULL,
- my_name_register_failed, NULL);
- register_name(subrec, my_netbios_names[i],0x00,samba_nb_type,
- NULL,
- my_name_register_failed, NULL);
- }
-
- /* Initiate election processing, register the workgroup names etc. */
- initiate_myworkgroup_startup(subrec, work);
-}
-
-
/****************************************************************************
Add my workgroup and my given names to the subnet lists.
Also add the magic Samba names.
@@ -91,13 +51,38 @@ Exiting.\n", global_myworkgroup, subrec->subnet_name));
BOOL register_my_workgroup_and_names(void)
{
struct subnet_record *subrec;
+ struct work_record *work;
int i;
- for(subrec = FIRST_SUBNET;
- subrec;
- subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
+ for(subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec))
{
- register_my_workgroup_one_subnet(subrec);
+ /* Create the workgroup on the subnet. */
+ if((work = create_workgroup_on_subnet(subrec, global_myworkgroup, PERMANENT_TTL)) == NULL)
+ {
+ DEBUG(0,("register_my_workgroup_and_names: Failed to create my workgroup %s on subnet %s. \
+Exiting.\n", global_myworkgroup, subrec->subnet_name));
+ return False;
+ }
+
+ /* Each subnet entry, except for the wins_server_subnet has the magic Samba names. */
+ add_samba_names_to_subnet(subrec);
+
+ /* Register all our names including aliases. */
+ for (i=0; my_netbios_names[i]; i++)
+ {
+ register_name(subrec, my_netbios_names[i],0x20,samba_nb_type,
+ NULL,
+ my_name_register_failed, NULL);
+ register_name(subrec, my_netbios_names[i],0x03,samba_nb_type,
+ NULL,
+ my_name_register_failed, NULL);
+ register_name(subrec, my_netbios_names[i],0x00,samba_nb_type,
+ NULL,
+ my_name_register_failed, NULL);
+ }
+
+ /* Initiate election processing, register the workgroup names etc. */
+ initiate_myworkgroup_startup(subrec, work);
}
/* If we are not a WINS client, we still need to add the magic Samba
@@ -118,13 +103,13 @@ BOOL register_my_workgroup_and_names(void)
*/
struct nmb_name nmbname;
- make_nmb_name(&nmbname, my_netbios_names[i],0x20);
+ make_nmb_name(&nmbname, my_netbios_names[i],0x20, scope);
insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type);
- make_nmb_name(&nmbname, my_netbios_names[i],0x3);
+ make_nmb_name(&nmbname, my_netbios_names[i],0x3, scope);
insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type);
- make_nmb_name(&nmbname, my_netbios_names[i],0x0);
+ make_nmb_name(&nmbname, my_netbios_names[i],0x0, scope);
insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type);
}
}
@@ -141,10 +126,10 @@ BOOL register_my_workgroup_and_names(void)
*/
struct nmb_name nmbname;
- make_nmb_name(&nmbname, global_myworkgroup, 0x0);
+ make_nmb_name(&nmbname, global_myworkgroup, 0x0, scope);
insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
- make_nmb_name(&nmbname, global_myworkgroup, 0x1e);
+ make_nmb_name(&nmbname, global_myworkgroup, 0x1e, scope);
insert_permanent_name_into_unicast(subrec, &nmbname, samba_nb_type|NB_GROUP);
}
}
@@ -195,10 +180,6 @@ void refresh_my_names(time_t t)
{
struct name_record *namerec;
- /* B nodes don't send out name refresh requests, see RFC 1001, 15.5.1 */
- if (subrec != unicast_subnet)
- continue;
-
for( namerec = (struct name_record *)ubi_trFirst( subrec->namelist );
namerec;
namerec = (struct name_record *)ubi_trNext( namerec ) )
diff --git a/source/nmbd/nmbd_namelistdb.c b/source/nmbd/nmbd_namelistdb.c
index 15328af33eb..0bc5fd875a7 100644
--- a/source/nmbd/nmbd_namelistdb.c
+++ b/source/nmbd/nmbd_namelistdb.c
@@ -26,6 +26,7 @@
extern int DEBUGLEVEL;
+extern pstring scope;
extern char **my_netbios_names;
uint16 samba_nb_type = 0; /* samba's NetBIOS name type */
@@ -41,6 +42,8 @@ void set_samba_nb_type(void)
samba_nb_type = NB_MFLAG; /* samba is a 'hybrid' node type. */
else
samba_nb_type = NB_BFLAG; /* samba is broadcast-only node type. */
+
+ DEBUG(10,("set_samba_nb_type: %x\n", samba_nb_type));
} /* set_samba_nb_type */
/* ************************************************************************** **
@@ -198,7 +201,7 @@ struct name_record *add_name_to_subnet( struct subnet_record *subrec,
return( NULL );
}
- memset( (char *)namerec, '\0', sizeof(*namerec) );
+ bzero( (char *)namerec, sizeof(*namerec) );
namerec->data.ip = (struct in_addr *)malloc( sizeof(struct in_addr)
* num_ips );
if( NULL == namerec->data.ip )
@@ -212,8 +215,8 @@ struct name_record *add_name_to_subnet( struct subnet_record *subrec,
namerec->subnet = subrec;
- make_nmb_name(&namerec->name, name, type);
- upcase_name(&namerec->name, NULL );
+ make_nmb_name( &namerec->name, name, type, scope );
+ upcase_name( &namerec->name, NULL );
/* Enter the name as active. */
namerec->data.nb_flags = nb_flags | NB_ACTIVE;
@@ -601,15 +604,21 @@ static void dump_subnet_namelist( struct subnet_record *subrec, FILE *fp)
void dump_all_namelists(void)
{
+ pstring fname;
FILE *fp;
struct subnet_record *subrec;
- fp = sys_fopen(lock_path("namelist.debug"),"w");
+ pstrcpy(fname,lp_lockdir());
+ trim_string(fname,NULL,"/");
+ pstrcat(fname,"/");
+ pstrcat(fname,"namelist.debug");
+
+ fp = sys_fopen(fname,"w");
if (!fp)
{
DEBUG(0,("dump_all_namelists: Can't open file %s. Error was %s\n",
- "namelist.debug",strerror(errno)));
+ fname,strerror(errno)));
return;
}
diff --git a/source/nmbd/nmbd_namequery.c b/source/nmbd/nmbd_namequery.c
index 57baa4cb2f0..fae045882f2 100644
--- a/source/nmbd/nmbd_namequery.c
+++ b/source/nmbd/nmbd_namequery.c
@@ -26,6 +26,8 @@
extern int DEBUGLEVEL;
+extern pstring scope;
+
/****************************************************************************
Deal with a response packet when querying a name.
****************************************************************************/
@@ -178,7 +180,7 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type,
struct nmb_name nmbname;
struct name_record *namerec;
- make_nmb_name(&nmbname, name, type);
+ make_nmb_name(&nmbname, name, type, scope);
/*
* We need to check our local namelists first.
@@ -191,7 +193,7 @@ BOOL query_name(struct subnet_record *subrec, char *name, int type,
struct res_rec rrec;
int i;
- memset((char *)&rrec, '\0', sizeof(struct res_rec));
+ bzero((char *)&rrec, sizeof(struct res_rec));
/* Fake up the needed res_rec just in case it's used. */
rrec.rr_name = nmbname;
@@ -245,7 +247,7 @@ BOOL query_name_from_wins_server(struct in_addr ip_to,
{
struct nmb_name nmbname;
- make_nmb_name(&nmbname, name, type);
+ make_nmb_name(&nmbname, name, type, scope);
if(queue_query_name_from_wins_server( ip_to,
query_name_response,
diff --git a/source/nmbd/nmbd_nameregister.c b/source/nmbd/nmbd_nameregister.c
index 88057287372..069e262987e 100644
--- a/source/nmbd/nmbd_nameregister.c
+++ b/source/nmbd/nmbd_nameregister.c
@@ -26,6 +26,7 @@
extern int DEBUGLEVEL;
+extern pstring scope;
extern fstring global_myworkgroup;
/****************************************************************************
@@ -53,13 +54,6 @@ static void register_name_response(struct subnet_record *subrec,
/* Sanity check. Ensure that the answer name in the incoming packet is the
same as the requested name in the outgoing packet. */
- if(!question_name || !answer_name)
- {
- DEBUG(0,("register_name_response: malformed response (%s is NULL).\n",
- question_name ? "question_name" : "answer_name" ));
- return;
- }
-
if(!nmb_name_equal(question_name, answer_name))
{
DEBUG(0,("register_name_response: Answer name %s differs from question \
@@ -332,7 +326,7 @@ BOOL register_name(struct subnet_record *subrec,
{
struct nmb_name nmbname;
- make_nmb_name(&nmbname, name, type);
+ make_nmb_name(&nmbname, name, type, scope);
/* Always set the NB_ACTIVE flag on the name we are
registering. Doesn't make sense without it.
diff --git a/source/nmbd/nmbd_namerelease.c b/source/nmbd/nmbd_namerelease.c
index 2e3b4e8c6ac..1cdc78e6a0b 100644
--- a/source/nmbd/nmbd_namerelease.c
+++ b/source/nmbd/nmbd_namerelease.c
@@ -26,6 +26,8 @@
extern int DEBUGLEVEL;
+extern pstring scope;
+
/****************************************************************************
Deal with a response packet when releasing one of our names.
****************************************************************************/
diff --git a/source/nmbd/nmbd_nodestatus.c b/source/nmbd/nmbd_nodestatus.c
index d78f8a5547a..d8af09b3984 100644
--- a/source/nmbd/nmbd_nodestatus.c
+++ b/source/nmbd/nmbd_nodestatus.c
@@ -26,6 +26,8 @@
extern int DEBUGLEVEL;
+extern pstring scope;
+
/****************************************************************************
Deal with a successful node status response.
****************************************************************************/
diff --git a/source/nmbd/nmbd_packets.c b/source/nmbd/nmbd_packets.c
index 428758ada3c..40f9c9bcb35 100644
--- a/source/nmbd/nmbd_packets.c
+++ b/source/nmbd/nmbd_packets.c
@@ -32,13 +32,11 @@ extern int DEBUGLEVEL;
extern int num_response_packets;
+extern pstring scope;
extern struct in_addr loopback_ip;
static void queue_packet(struct packet_struct *packet);
-BOOL rescan_listen_set = False;
-
-
/*******************************************************************
The global packet linked-list. Incoming entries are
added to the end of this list. It is supposed to remain fairly
@@ -93,43 +91,6 @@ void set_nb_flags(char *buf, uint16 nb_flags)
}
/***************************************************************************
-Dumps out the browse packet data.
-**************************************************************************/
-
-static void debug_browse_data(char *outbuf, int len)
-{
- int i,j;
-
- DEBUG( 4, ( "debug_browse_data():\n" ) );
- for (i = 0; i < len; i+= 16)
- {
- DEBUGADD( 4, ( "%3x char ", i ) );
-
- for (j = 0; j < 16; j++)
- {
- unsigned char x = outbuf[i+j];
- if (x < 32 || x > 127)
- x = '.';
-
- if (i+j >= len)
- break;
- DEBUGADD( 4, ( "%c", x ) );
- }
-
- DEBUGADD( 4, ( "%*s hex", 16-j, "" ) );
-
- for (j = 0; j < 16; j++)
- {
- if (i+j >= len)
- break;
- DEBUGADD( 4, ( " %02x", (unsigned char)outbuf[i+j] ) );
- }
-
- DEBUGADD( 4, ("\n") );
- }
-}
-
-/***************************************************************************
Generates the unique transaction identifier
**************************************************************************/
@@ -182,6 +143,7 @@ static BOOL send_netbios_packet(struct packet_struct *p)
static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmbname,
BOOL bcast,
+ BOOL rec_des,
struct in_addr to_ip)
{
struct packet_struct *packet = NULL;
@@ -194,13 +156,13 @@ static struct packet_struct *create_and_init_netbios_packet(struct nmb_name *nmb
return NULL;
}
- memset((char *)packet,'\0',sizeof(*packet));
+ bzero((char *)packet,sizeof(*packet));
nmb = &packet->packet.nmb;
nmb->header.name_trn_id = generate_name_trn_id();
nmb->header.response = False;
- nmb->header.nm_flags.recursion_desired = False;
+ nmb->header.nm_flags.recursion_desired = rec_des;
nmb->header.nm_flags.recursion_available = False;
nmb->header.nm_flags.trunc = False;
nmb->header.nm_flags.authoritative = False;
@@ -241,17 +203,13 @@ static BOOL create_and_init_additional_record(struct packet_struct *packet,
return False;
}
- memset((char *)nmb->additional,'\0',sizeof(struct res_rec));
+ bzero((char *)nmb->additional,sizeof(struct res_rec));
nmb->additional->rr_name = nmb->question.question_name;
nmb->additional->rr_type = RR_TYPE_NB;
nmb->additional->rr_class = RR_CLASS_IN;
- /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */
- if (nmb->header.nm_flags.bcast)
- nmb->additional->ttl = PERMANENT_TTL;
- else
- nmb->additional->ttl = lp_max_ttl();
+ nmb->additional->ttl = lp_max_ttl();
nmb->additional->rdlength = 6;
@@ -473,11 +431,12 @@ struct response_record *queue_register_name( struct subnet_record *subrec,
struct packet_struct *p;
struct response_record *rrec;
BOOL bcast = (subrec == unicast_subnet) ? False : True;
+ BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
if(assert_check_subnet(subrec))
return NULL;
- if(( p = create_and_init_netbios_packet(nmbname, bcast,
+ if(( p = create_and_init_netbios_packet(nmbname, bcast, rec_des,
subrec->bcast_ip)) == NULL)
return NULL;
@@ -522,6 +481,7 @@ struct response_record *queue_register_multihomed_name( struct subnet_record *su
struct packet_struct *p;
struct response_record *rrec;
BOOL bcast = False;
+ BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
BOOL ret;
/* Sanity check. */
@@ -535,7 +495,7 @@ unicast subnet. subnet is %s\n.", subrec->subnet_name ));
if(assert_check_subnet(subrec))
return NULL;
- if(( p = create_and_init_netbios_packet(nmbname, bcast,
+ if(( p = create_and_init_netbios_packet(nmbname, bcast, rec_des,
subrec->bcast_ip)) == NULL)
return NULL;
@@ -582,13 +542,14 @@ struct response_record *queue_release_name( struct subnet_record *subrec,
struct in_addr release_ip)
{
BOOL bcast = (subrec == unicast_subnet) ? False : True;
+ BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
struct packet_struct *p;
struct response_record *rrec;
if(assert_check_subnet(subrec))
return NULL;
- if(( p = create_and_init_netbios_packet(nmbname, bcast,
+ if(( p = create_and_init_netbios_packet(nmbname, bcast, rec_des,
subrec->bcast_ip)) == NULL)
return NULL;
@@ -640,13 +601,14 @@ struct response_record *queue_refresh_name( struct subnet_record *subrec,
struct in_addr refresh_ip)
{
BOOL bcast = (subrec == unicast_subnet) ? False : True;
+ BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
struct packet_struct *p;
struct response_record *rrec;
if(assert_check_subnet(subrec))
return NULL;
- if(( p = create_and_init_netbios_packet(&namerec->name, bcast,
+ if(( p = create_and_init_netbios_packet(&namerec->name, bcast,rec_des,
subrec->bcast_ip)) == NULL)
return NULL;
@@ -688,6 +650,7 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
struct packet_struct *p;
struct response_record *rrec;
BOOL bcast = True;
+ BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
if ((subrec == unicast_subnet) || (subrec == wins_server_subnet))
bcast = False;
@@ -695,7 +658,7 @@ struct response_record *queue_query_name( struct subnet_record *subrec,
if(assert_check_subnet(subrec))
return NULL;
- if(( p = create_and_init_netbios_packet(nmbname, bcast,
+ if(( p = create_and_init_netbios_packet(nmbname, bcast,rec_des,
subrec->bcast_ip)) == NULL)
return NULL;
@@ -737,8 +700,10 @@ struct response_record *queue_query_name_from_wins_server( struct in_addr to_ip,
struct packet_struct *p;
struct response_record *rrec;
BOOL bcast = False;
+ BOOL rec_des = True;
- if(( p = create_and_init_netbios_packet(nmbname, bcast, to_ip)) == NULL)
+ if(( p = create_and_init_netbios_packet(nmbname, bcast, rec_des,
+ to_ip)) == NULL)
return NULL;
if(initiate_name_query_packet_from_wins_server( p ) == False)
@@ -780,6 +745,7 @@ struct response_record *queue_node_status( struct subnet_record *subrec,
struct packet_struct *p;
struct response_record *rrec;
BOOL bcast = False;
+ BOOL rec_des = (subrec == wins_server_subnet) ? True : False;
/* Sanity check. */
if(subrec != unicast_subnet)
@@ -792,7 +758,7 @@ unicast subnet. subnet is %s\n.", subrec->subnet_name ));
if(assert_check_subnet(subrec))
return NULL;
- if(( p = create_and_init_netbios_packet(nmbname, bcast,
+ if(( p = create_and_init_netbios_packet(nmbname, bcast,rec_des,
send_ip)) == NULL)
return NULL;
@@ -929,10 +895,10 @@ for id %hu\n",
nmb->header.nscount = 0;
nmb->header.arcount = 0;
- memset((char*)&nmb->question,'\0',sizeof(nmb->question));
+ bzero((char*)&nmb->question,sizeof(nmb->question));
nmb->answers = &answers;
- memset((char*)nmb->answers,'\0',sizeof(*nmb->answers));
+ bzero((char*)nmb->answers,sizeof(*nmb->answers));
nmb->answers->rr_name = orig_nmb->question.question_name;
nmb->answers->rr_type = orig_nmb->question.question_type;
@@ -1025,15 +991,14 @@ static void process_browse_packet(struct packet_struct *p, char *buf,int len)
struct dgram_packet *dgram = &p->packet.dgram;
int command = CVAL(buf,0);
struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
- extern pstring global_scope;
/* Drop the packet if it's a different NetBIOS scope, or
the source is from one of our names. */
- if (!strequal(dgram->dest_name.scope, global_scope))
+ if (!strequal(dgram->dest_name.scope,scope ))
{
DEBUG(7,("process_browse_packet: Discarding datagram from IP %s. Scope (%s) \
-mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, global_scope));
+mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, scope));
return;
}
@@ -1048,43 +1013,45 @@ mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, glob
{
case ANN_HostAnnouncement:
{
- debug_browse_data(buf, len);
process_host_announce(subrec, p, buf+1);
break;
}
case ANN_DomainAnnouncement:
{
- debug_browse_data(buf, len);
process_workgroup_announce(subrec, p, buf+1);
break;
}
case ANN_LocalMasterAnnouncement:
{
- debug_browse_data(buf, len);
process_local_master_announce(subrec, p, buf+1);
break;
}
case ANN_AnnouncementRequest:
{
- debug_browse_data(buf, len);
process_announce_request(subrec, p, buf+1);
break;
}
case ANN_Election:
{
- debug_browse_data(buf, len);
process_election(subrec, p, buf+1);
break;
}
case ANN_GetBackupListReq:
{
- debug_browse_data(buf, len);
+
+ /* This is one occasion where we change a subnet that is
+ given to us. If the packet was sent to WORKGROUP<1b> instead
+ of WORKGROUP<1d> then it was unicast to us a domain master
+ browser. Change subrec to unicast.
+ */
+ if(dgram->dest_name.name_type == 0x1b)
+ subrec = unicast_subnet;
+
process_get_backup_list_request(subrec, p, buf+1);
break;
}
case ANN_GetBackupListResp:
{
- debug_browse_data(buf, len);
/* We never send ANN_GetBackupListReq so we
should never get these. */
DEBUG(0,("process_browse_packet: Discarding GetBackupListResponse \
@@ -1093,7 +1060,6 @@ packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
}
case ANN_ResetBrowserState:
{
- debug_browse_data(buf, len);
process_reset_browser(subrec, p, buf+1);
break;
}
@@ -1103,7 +1069,6 @@ packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
on the unicast subnet. */
subrec = unicast_subnet;
- debug_browse_data(buf, len);
process_master_browser_announce(subrec, p, buf+1);
break;
}
@@ -1112,7 +1077,6 @@ packet from %s IP %s\n", nmb_namestr(&dgram->source_name), inet_ntoa(p->ip)));
/*
* We don't currently implement this. Log it just in case.
*/
- debug_browse_data(buf, len);
DEBUG(10,("process_browse_packet: On subnet %s ignoring browse packet \
command ANN_BecomeBackup from %s IP %s to %s\n",
subrec->subnet_name, nmb_namestr(&dgram->source_name),
@@ -1121,7 +1085,6 @@ command ANN_BecomeBackup from %s IP %s to %s\n",
}
default:
{
- debug_browse_data(buf, len);
DEBUG(0,("process_browse_packet: On subnet %s ignoring browse packet \
command code %d from %s IP %s to %s\n",
subrec->subnet_name, command, nmb_namestr(&dgram->source_name),
@@ -1138,15 +1101,14 @@ static void process_lanman_packet(struct packet_struct *p, char *buf,int len)
struct dgram_packet *dgram = &p->packet.dgram;
int command = SVAL(buf,0);
struct subnet_record *subrec = find_subnet_for_dgram_browse_packet(p);
- extern pstring global_scope;
/* Drop the packet if it's a different NetBIOS scope, or
the source is from one of our names. */
- if (!strequal(dgram->dest_name.scope, global_scope))
+ if (!strequal(dgram->dest_name.scope,scope ))
{
DEBUG(7,("process_lanman_packet: Discarding datagram from IP %s. Scope (%s) \
-mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, global_scope));
+mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, scope));
return;
}
@@ -1161,7 +1123,7 @@ mismatch with our scope (%s).\n", inet_ntoa(p->ip), dgram->dest_name.scope, glob
{
case ANN_HostAnnouncement:
{
- debug_browse_data(buf, len);
+ dump_data(4, buf, len);
process_lm_host_announce(subrec, p, buf+1);
break;
}
@@ -1205,6 +1167,7 @@ static BOOL listening(struct packet_struct *p,struct nmb_name *nbname)
/****************************************************************************
Process udp 138 datagrams
****************************************************************************/
+
static void process_dgram(struct packet_struct *p)
{
char *buf;
@@ -1215,22 +1178,20 @@ static void process_dgram(struct packet_struct *p)
/* If we aren't listening to the destination name then ignore the packet */
if (!listening(p,&dgram->dest_name))
{
- unexpected_packet(p);
- DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
- nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
- return;
+ DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from %s\n",
+ nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip)));
+ return;
}
if (dgram->header.msg_type != 0x10 &&
dgram->header.msg_type != 0x11 &&
dgram->header.msg_type != 0x12)
{
- unexpected_packet(p);
- /* Don't process error packets etc yet */
- DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
-an error packet of type %x\n",
- nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
- return;
+ /* Don't process error packets etc yet */
+ DEBUG(5,("process_dgram: ignoring dgram packet sent to name %s from IP %s as it is \
+ an error packet of type %x\n",
+ nmb_namestr(&dgram->dest_name), inet_ntoa(p->ip), dgram->header.msg_type));
+ return;
}
buf = &dgram->data[0];
@@ -1247,10 +1208,11 @@ an error packet of type %x\n",
nmb_namestr(&dgram->source_name),nmb_namestr(&dgram->dest_name),
inet_ntoa(p->ip), smb_buf(buf),CVAL(buf2,0),len));
-
if (len <= 0)
return;
+ dump_data(100, buf2, len);
+
/* Datagram packet received for the browser mailslot */
if (strequal(smb_buf(buf),BROWSE_MAILSLOT))
{
@@ -1277,8 +1239,6 @@ an error packet of type %x\n",
process_logon_packet(p,buf2,len,NT_LOGON_MAILSLOT);
return;
}
-
- unexpected_packet(p);
}
/****************************************************************************
@@ -1406,9 +1366,8 @@ static struct subnet_record *find_subnet_for_nmb_packet( struct packet_struct *p
rrec = find_response_record( &subrec, nmb->header.name_trn_id);
if(rrec == NULL)
{
- DEBUG(3,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
+ DEBUG(0,("find_subnet_for_nmb_packet: response record not found for response id %hu\n",
nmb->header.name_trn_id));
- unexpected_packet(p);
return NULL;
}
@@ -1581,6 +1540,7 @@ void run_packet_queue(void)
switch (p->packet_type)
{
case NMB_PACKET:
+ case NMB_SOCK_PACKET:
if(p->packet.nmb.header.response)
process_nmb_response(p);
else
@@ -1588,6 +1548,7 @@ void run_packet_queue(void)
break;
case DGRAM_PACKET:
+ case DGRAM_SOCK_PACKET:
process_dgram(p);
break;
}
@@ -1728,10 +1689,6 @@ only use %d.\n", (count*2) + 2, FD_SETSIZE));
}
*listen_number = (count*2) + 2;
-
- if (*ppset) free(*ppset);
- if (*psock_array) free(*psock_array);
-
*ppset = pset;
*psock_array = sock_array;
@@ -1755,14 +1712,13 @@ BOOL listen_for_packets(BOOL run_election)
int dns_fd;
#endif
- if(listen_set == NULL || rescan_listen_set)
+ if(listen_set == NULL)
{
if(create_listen_fdset(&listen_set, &sock_array, &listen_number))
{
DEBUG(0,("listen_for_packets: Fatal error. unable to create listen set. Exiting.\n"));
return True;
}
- rescan_listen_set = False;
}
memcpy((char *)&fds, (char *)listen_set, sizeof(fd_set));
@@ -1795,7 +1751,7 @@ BOOL listen_for_packets(BOOL run_election)
BlockSignals(False, SIGUSR2);
#endif /* SIGUSR2 */
- selrtn = sys_select(FD_SETSIZE,&fds,&timeout);
+ selrtn = sys_select(256,&fds,NULL, &timeout);
/* We can only take signals when we are in the select - block them again here. */
@@ -1910,7 +1866,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
char *ptr,*p2;
char tmp[4];
- memset((char *)&p,'\0',sizeof(p));
+ bzero((char *)&p,sizeof(p));
if(ismyip(dest_ip))
loopback_this_packet = True;
@@ -1919,7 +1875,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
/* DIRECT GROUP or UNIQUE datagram. */
dgram->header.msg_type = unique ? 0x10 : 0x11;
- dgram->header.flags.node_type = M_NODE;
+ dgram->header.flags.node_type = M_NODE | 0x40;
dgram->header.flags.first = True;
dgram->header.flags.more = False;
dgram->header.dgm_id = name_trn_id;
@@ -1928,8 +1884,8 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
dgram->header.packet_offset = 0;
- make_nmb_name(&dgram->source_name,srcname,src_type);
- make_nmb_name(&dgram->dest_name,dstname,dest_type);
+ make_nmb_name(&dgram->source_name,srcname,src_type,scope);
+ make_nmb_name(&dgram->dest_name,dstname,dest_type,scope);
ptr = &dgram->data[0];
@@ -1966,7 +1922,7 @@ BOOL send_mailslot(BOOL unique, char *mailslot,char *buf,int len,
nmb_namestr(&dgram->source_name), inet_ntoa(src_ip)));
DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip)));
- debug_browse_data(buf, len);
+ dump_data(4, buf, len);
if(loopback_this_packet)
{
diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c
index d3b7f92fc78..939e5b88bbf 100644
--- a/source/nmbd/nmbd_processlogon.c
+++ b/source/nmbd/nmbd_processlogon.c
@@ -48,10 +48,9 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len,
uint16 lmnttoken = 0;
uint16 lm20token = 0;
uint32 domainsidsize;
- BOOL short_request = False;
+ BOOL short_request = 0;
char *getdc;
char *uniuser; /* Unicode user name. */
- pstring ascuser;
char *unicomp; /* Unicode computer name. */
memset(outbuf, 0, sizeof(outbuf));
@@ -119,11 +118,11 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
q = align2(unicomp, buf);
- q = skip_unicode_string(q, 1);
+ q = skip_unibuf(q, buf+len-q);
if ((buf - q) >= len) { /* Check for a short request */
- short_request = True;
+ short_request = 1;
}
else { /* A full length request */
@@ -148,15 +147,15 @@ logons are not enabled.\n", inet_ntoa(p->ip) ));
q = skip_string(q, 1); /* PDC name */
/* PDC and domain name */
+
if (!short_request) /* Make a full reply */
{
q = align2(q, buf);
- dos_PutUniCode(q, my_name, sizeof(pstring)); /* PDC name */
- q = skip_unicode_string(q, 1);
+ q = ascii_to_unibuf(q, my_name, outbuf+sizeof(outbuf)-q-2);
+ q = ascii_to_unibuf(q, global_myworkgroup, outbuf+sizeof(outbuf)-q-2);
- dos_PutUniCode(q, global_myworkgroup,sizeof(pstring)); /* Domain name*/
- q = skip_unicode_string(q, 1);
+ ntversion = 0x01;
SIVAL(q, 0, ntversion);
q += 4;
@@ -178,10 +177,10 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
send_mailslot(True, getdc,
outbuf,PTR_DIFF(q,outbuf),
- dgram->dest_name.name,
- dgram->dest_name.name_type,
- dgram->source_name.name,
- dgram->source_name.name_type,
+ my_name,
+ 0x0,
+ dgram->source_name.name,
+ dgram->source_name.name_type,
p->ip, *iface_ip(p->ip), p->port);
return;
}
@@ -192,13 +191,20 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
q += 2;
unicomp = q;
- uniuser = skip_unicode_string(unicomp,1);
- getdc = skip_unicode_string(uniuser,1);
+ uniuser = skip_unibuf(unicomp, buf+len-q);
+ getdc = skip_unibuf(uniuser, buf+len-q);
q = skip_string(getdc,1);
- q += 4;
+ q += 4; /* skip Account Control Bits */
domainsidsize = IVAL(q, 0);
q += 4;
- q += domainsidsize + 3;
+
+ if (domainsidsize != 0)
+ {
+ q += domainsidsize;
+ q += 2;
+ q = align4(q, buf);
+ }
+
ntversion = IVAL(q, 0);
q += 4;
lmnttoken = SVAL(q, 0);
@@ -206,7 +212,7 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
lm20token = SVAL(q, 0);
q += 2;
- DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %d\n", domainsidsize, ntversion));
+ DEBUG(3,("process_logon_packet: SAMLOGON sidsize %d ntv %x\n", domainsidsize, ntversion));
/*
* we respond regadless of whether the machine is in our password
@@ -214,28 +220,43 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
* Let's ignore the SID.
*/
- pstrcpy(ascuser, dos_unistr(uniuser));
- DEBUG(3,("process_logon_packet: SAMLOGON user %s\n", ascuser));
-
fstrcpy(reply_name,"\\\\"); /* Here it wants \\LOGONSERVER. */
fstrcpy(reply_name+2,my_name);
- DEBUG(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
- dos_unistr(unicomp),inet_ntoa(p->ip), ascuser, reply_name, global_myworkgroup,
- SAMLOGON_R ,lmnttoken));
+ ntversion = 0x01;
+ lmnttoken = 0xffff;
+ lm20token = 0xffff;
+
+ if (DEBUGLVL(3))
+ {
+ fstring ascuser;
+ fstring asccomp;
+
+ unibuf_to_ascii(ascuser, uniuser, sizeof(ascuser)-1);
+ unibuf_to_ascii(asccomp, unicomp, sizeof(asccomp)-1);
+
+ DEBUGADD(3,("process_logon_packet: SAMLOGON request from %s(%s) for %s, returning logon svr %s domain %s code %x token=%x\n",
+ asccomp,inet_ntoa(p->ip), ascuser, reply_name,
+ global_myworkgroup, SAMLOGON_R, lmnttoken));
+ }
/* Construct reply. */
q = outbuf;
- SSVAL(q, 0, SAMLOGON_R);
+ if (uniuser[0] == 0)
+ {
+ SSVAL(q, 0, SAMLOGON_UNK_R); /* user unknown */
+ }
+ else
+ {
+ SSVAL(q, 0, SAMLOGON_R);
+ }
q += 2;
- dos_PutUniCode(q, reply_name,sizeof(pstring));
- q = skip_unicode_string(q, 1);
- unistrcpy(q, uniuser);
- q = skip_unicode_string(q, 1); /* User name (workstation trust account) */
- dos_PutUniCode(q, lp_workgroup(),sizeof(pstring));
- q = skip_unicode_string(q, 1); /* Domain name. */
+ /* Logon server, trust account, domain */
+ q = ascii_to_unibuf(q, reply_name, outbuf+sizeof(outbuf)-q-2);
+ q = uni_strncpy(q, uniuser, outbuf+sizeof(outbuf)-q-2);
+ q = ascii_to_unibuf(q, lp_workgroup(), outbuf+sizeof(outbuf)-q-2);
SIVAL(q, 0, ntversion);
q += 4;
@@ -248,10 +269,10 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n",
send_mailslot(True, getdc,
outbuf,PTR_DIFF(q,outbuf),
- dgram->dest_name.name,
- dgram->dest_name.name_type,
- dgram->source_name.name,
- dgram->source_name.name_type,
+ my_name,
+ 0x0,
+ dgram->source_name.name,
+ dgram->source_name.name_type,
p->ip, *iface_ip(p->ip), p->port);
break;
}
diff --git a/source/nmbd/nmbd_responserecordsdb.c b/source/nmbd/nmbd_responserecordsdb.c
index 1b6e1ca16db..0c698760bb6 100644
--- a/source/nmbd/nmbd_responserecordsdb.c
+++ b/source/nmbd/nmbd_responserecordsdb.c
@@ -28,6 +28,7 @@ extern int ClientNMB;
extern int DEBUGLEVEL;
+extern pstring scope;
extern struct in_addr ipzero;
int num_response_packets = 0;
@@ -118,7 +119,7 @@ struct response_record *make_response_record( struct subnet_record *subrec,
return NULL;
}
- memset((char *)rrec, '\0', sizeof(*rrec));
+ bzero((char *)rrec, sizeof(*rrec));
rrec->response_id = nmb->header.name_trn_id;
diff --git a/source/nmbd/nmbd_sendannounce.c b/source/nmbd/nmbd_sendannounce.c
index 87115a1eb0d..38c8deafe72 100644
--- a/source/nmbd/nmbd_sendannounce.c
+++ b/source/nmbd/nmbd_sendannounce.c
@@ -46,7 +46,7 @@ void send_browser_reset(int reset_type, char *to_name, int to_type, struct in_ad
DEBUG(3,("send_browser_reset: sending reset request type %d to %s<%02x> IP %s.\n",
reset_type, to_name, to_type, inet_ntoa(to_ip) ));
- memset(outbuf,'\0',sizeof(outbuf));
+ bzero(outbuf,sizeof(outbuf));
p = outbuf;
CVAL(p,0) = ANN_ResetBrowserState;
p++;
@@ -73,7 +73,7 @@ void broadcast_announce_request(struct subnet_record *subrec, struct work_record
DEBUG(3,("broadcast_announce_request: sending announce request for workgroup %s \
to subnet %s\n", work->work_group, subrec->subnet_name));
- memset(outbuf,'\0',sizeof(outbuf));
+ bzero(outbuf,sizeof(outbuf));
p = outbuf;
CVAL(p,0) = ANN_AnnouncementRequest;
p++;
@@ -101,7 +101,7 @@ static void send_announcement(struct subnet_record *subrec, int announce_type,
pstring outbuf;
char *p;
- memset(outbuf,'\0',sizeof(outbuf));
+ bzero(outbuf,sizeof(outbuf));
p = outbuf+1;
CVAL(outbuf,0) = announce_type;
@@ -142,7 +142,7 @@ static void send_lm_announcement(struct subnet_record *subrec, int announce_type
pstring outbuf;
char *p=outbuf;
- memset(outbuf,'\0',sizeof(outbuf));
+ bzero(outbuf,sizeof(outbuf));
SSVAL(p,0,announce_type);
SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
@@ -504,7 +504,7 @@ void announce_remote(time_t t)
if (!*s)
return;
- comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH);
+ comment = lp_serverstring();
for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); )
{
@@ -587,7 +587,7 @@ for workgroup %s on subnet %s.\n", global_myworkgroup, FIRST_SUBNET->subnet_name
return;
}
- memset(outbuf,'\0',sizeof(outbuf));
+ bzero(outbuf,sizeof(outbuf));
p = outbuf;
CVAL(p,0) = ANN_MasterAnnouncement;
p++;
diff --git a/source/nmbd/nmbd_serverlistdb.c b/source/nmbd/nmbd_serverlistdb.c
index 41009bc68f0..d30e8da64ce 100644
--- a/source/nmbd/nmbd_serverlistdb.c
+++ b/source/nmbd/nmbd_serverlistdb.c
@@ -156,7 +156,7 @@ workgroup %s. This is a bug.\n", name, work->work_group));
return NULL;
}
- memset((char *)servrec,'\0',sizeof(*servrec));
+ bzero((char *)servrec,sizeof(*servrec));
servrec->subnet = work->subnet;
@@ -399,8 +399,7 @@ void write_browse_list(time_t t, BOOL force_write)
slprintf(tmp, sizeof(tmp)-1, "\"%s\"", my_netbios_names[i]);
fprintf(fp, "%-25s ", tmp);
fprintf(fp, "%08x ", stype);
- slprintf(tmp, sizeof(tmp)-1, "\"%s\" ",
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
+ slprintf(tmp, sizeof(tmp)-1, "\"%s\" ", lp_serverstring());
fprintf(fp, "%-30s", tmp);
fprintf(fp, "\"%s\"\n", global_myworkgroup);
}
diff --git a/source/nmbd/nmbd_subnetdb.c b/source/nmbd/nmbd_subnetdb.c
index 37b50f85250..1b7b2b5da23 100644
--- a/source/nmbd/nmbd_subnetdb.c
+++ b/source/nmbd/nmbd_subnetdb.c
@@ -55,7 +55,22 @@ extern uint16 samba_nb_type; /* Samba's NetBIOS name type. */
static void add_subnet(struct subnet_record *subrec)
{
- DLIST_ADD(subnetlist, subrec);
+ struct subnet_record *subrec2;
+
+ if (!subnetlist)
+ {
+ subnetlist = subrec;
+ subrec->prev = NULL;
+ subrec->next = NULL;
+ return;
+ }
+
+ for (subrec2 = subnetlist; subrec2->next; subrec2 = subrec2->next)
+ ;
+
+ subrec2->next = subrec;
+ subrec->next = NULL;
+ subrec->prev = subrec2;
}
/* ************************************************************************** **
@@ -81,41 +96,19 @@ static int namelist_entry_compare( ubi_trItemPtr Item, ubi_trNodePtr Node )
Debug1( "nmbd_subnetdb:namelist_entry_compare()\n" );
Debug1( "%d == memcmp( \"%s\", \"%s\", %d )\n",
memcmp( Item, &(NR->name), sizeof(struct nmb_name) ),
- nmb_namestr(Iname), nmb_namestr(&NR->name), (int)sizeof(struct nmb_name) );
+ nmb_namestr(Iname), nmb_namestr(&NR->name), sizeof(struct nmb_name) );
}
return( memcmp( Item, &(NR->name), sizeof(struct nmb_name) ) );
} /* namelist_entry_compare */
-
-/****************************************************************************
-stop listening on a subnet
-we don't free the record as we don't have proper reference counting for it
-yet and it may be in use by a response record
- ****************************************************************************/
-void close_subnet(struct subnet_record *subrec)
-{
- DLIST_REMOVE(subnetlist, subrec);
-
- if (subrec->dgram_sock != -1) {
- close(subrec->dgram_sock);
- subrec->dgram_sock = -1;
- }
- if (subrec->nmb_sock != -1) {
- close(subrec->nmb_sock);
- subrec->nmb_sock = -1;
- }
-}
-
-
-
/****************************************************************************
Create a subnet entry.
****************************************************************************/
static struct subnet_record *make_subnet(char *name, enum subnet_type type,
- struct in_addr myip, struct in_addr bcast_ip,
- struct in_addr mask_ip)
+ struct in_addr myip, struct in_addr bcast_ip,
+ struct in_addr mask_ip)
{
struct subnet_record *subrec = NULL;
int nmb_sock, dgram_sock;
@@ -177,7 +170,7 @@ static struct subnet_record *make_subnet(char *name, enum subnet_type type,
return(NULL);
}
- memset( (char *)subrec, '\0', sizeof(*subrec) );
+ bzero( (char *)subrec, sizeof(*subrec) );
(void)ubi_trInitTree( subrec->namelist,
namelist_entry_compare,
ubi_trOVERWRITE );
@@ -209,23 +202,6 @@ static struct subnet_record *make_subnet(char *name, enum subnet_type type,
return subrec;
}
-
-/****************************************************************************
- Create a normal subnet
-**************************************************************************/
-struct subnet_record *make_normal_subnet(struct interface *iface)
-{
- struct subnet_record *subrec;
-
- subrec = make_subnet(inet_ntoa(iface->ip), NORMAL_SUBNET,
- iface->ip, iface->bcast, iface->nmask);
- if (subrec) {
- add_subnet(subrec);
- }
- return subrec;
-}
-
-
/****************************************************************************
Create subnet entries.
**************************************************************************/
@@ -249,9 +225,13 @@ BOOL create_subnets(void)
for (i = 0 ; i < num_interfaces; i++)
{
+ struct subnet_record *subrec;
struct interface *iface = get_interface(i);
- if (!make_normal_subnet(iface)) return False;
+ if((subrec = make_subnet(inet_ntoa(iface->ip), NORMAL_SUBNET,
+ iface->ip, iface->bcast,iface->nmask)) == NULL)
+ return False;
+ add_subnet(subrec);
}
/*
diff --git a/source/nmbd/nmbd_synclists.c b/source/nmbd/nmbd_synclists.c
index 7bf17903778..aab1e4349ca 100644
--- a/source/nmbd/nmbd_synclists.c
+++ b/source/nmbd/nmbd_synclists.c
@@ -32,6 +32,7 @@
#include "smb.h"
extern int DEBUGLEVEL;
+extern pstring scope;
struct sync_record {
struct sync_record *next, *prev;
@@ -39,7 +40,7 @@ struct sync_record {
fstring server;
pstring fname;
struct in_addr ip;
- pid_t pid;
+ int pid;
};
/* a linked list of current sync connections */
@@ -76,8 +77,8 @@ static void sync_child(char *name, int nm_type,
return;
}
- make_nmb_name(&calling, local_machine, 0x0);
- make_nmb_name(&called , name , nm_type);
+ make_nmb_name(&calling, local_machine, 0x0 , scope);
+ make_nmb_name(&called , name , nm_type, scope);
if (!cli_session_request(&cli, &calling, &called))
{
@@ -91,7 +92,7 @@ static void sync_child(char *name, int nm_type,
return;
}
- if (!cli_session_setup(&cli, "", "", 1, "", 0, workgroup)) {
+ if (!cli_session_setup(&cli, local_machine, "", "", 1, "", 0, workgroup)) {
cli_shutdown(&cli);
return;
}
@@ -102,7 +103,7 @@ static void sync_child(char *name, int nm_type,
}
/* Fetch a workgroup list. */
- cli_NetServerEnum(&cli, cli.server_domain?cli.server_domain:workgroup,
+ cli_NetServerEnum(&cli, workgroup,
local_type|SV_TYPE_DOMAIN_ENUM,
callback);
@@ -146,7 +147,7 @@ void sync_browse_lists(struct work_record *work,
slprintf(s->fname, sizeof(pstring)-1,
"%s/sync.%d", lp_lockdir(), counter++);
- all_string_sub(s->fname,"//", "/", 0);
+ string_sub(s->fname,"//", "/");
DLIST_ADD(syncs, s);
diff --git a/source/nmbd/nmbd_winsproxy.c b/source/nmbd/nmbd_winsproxy.c
index 24ba192cdb3..43beb9acd85 100644
--- a/source/nmbd/nmbd_winsproxy.c
+++ b/source/nmbd/nmbd_winsproxy.c
@@ -203,11 +203,11 @@ void make_wins_proxy_name_query_request( struct subnet_record *subrec,
struct packet_struct *incoming_packet,
struct nmb_name *question_name)
{
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct subrec *) +
- sizeof(struct packet_struct *))/sizeof(long *) + 1];
+ char ud[sizeof(struct userdata_struct) + sizeof(struct subrec *) +
+ sizeof(struct packet_struct *)];
struct userdata_struct *userdata = (struct userdata_struct *)ud;
- memset(ud, '\0', sizeof(ud));
+ bzero(ud, sizeof(ud));
userdata->copy_fn = wins_proxy_userdata_copy_fn;
userdata->free_fn = wins_proxy_userdata_free_fn;
diff --git a/source/nmbd/nmbd_winsserver.c b/source/nmbd/nmbd_winsserver.c
index e978718106a..35ca5af62c4 100644
--- a/source/nmbd/nmbd_winsserver.c
+++ b/source/nmbd/nmbd_winsserver.c
@@ -30,41 +30,6 @@ extern int DEBUGLEVEL;
extern struct in_addr ipzero;
-/****************************************************************************
-possibly call the WINS hook external program when a WINS change is made
-*****************************************************************************/
-static void wins_hook(char *operation, struct name_record *namerec, int ttl)
-{
- pstring command;
- char *cmd = lp_wins_hook();
- char *p;
- int i;
-
- if (!cmd || !*cmd) return;
-
- for (p=namerec->name.name; *p; p++) {
- if (!(isalnum((int)*p) || strchr("._-",*p))) {
- DEBUG(3,("not calling wins hook for invalid name %s\n", nmb_namestr(&namerec->name)));
- return;
- }
- }
-
- p = command;
- p += slprintf(p, sizeof(command), "%s %s %s %02x %d",
- cmd,
- operation,
- namerec->name.name,
- namerec->name.name_type,
- ttl);
-
- for (i=0;i<namerec->data.num_ips;i++) {
- p += slprintf(p, sizeof(command) - (p-command), " %s", inet_ntoa(namerec->data.ip[i]));
- }
-
- DEBUG(3,("calling wins hook for %s\n", nmb_namestr(&namerec->name)));
- smbrun(command, NULL, False);
-}
-
/****************************************************************************
hash our interfaces and netbios names settings
@@ -172,6 +137,7 @@ Load or create the WINS database.
BOOL initialise_wins(void)
{
+ pstring fname;
time_t time_now = time(NULL);
FILE *fp;
pstring line;
@@ -181,10 +147,20 @@ BOOL initialise_wins(void)
add_samba_names_to_subnet(wins_server_subnet);
- if((fp = sys_fopen(lock_path(WINS_LIST),"r")) == NULL)
+#ifndef SYNC_DNS
+ /* Setup the async dns. */
+ start_async_dns();
+#endif
+
+ pstrcpy(fname,lp_lockdir());
+ trim_string(fname,NULL,"/");
+ pstrcat(fname,"/");
+ pstrcat(fname,WINS_LIST);
+
+ if((fp = sys_fopen(fname,"r")) == NULL)
{
DEBUG(2,("initialise_wins: Can't open wins database file %s. Error was %s\n",
- WINS_LIST, strerror(errno) ));
+ fname, strerror(errno) ));
return True;
}
@@ -480,7 +456,6 @@ does not match group bit in WINS for this name.\n", nmb_namestr(question), group
*/
update_name_ttl(namerec, ttl);
send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
return;
}
else if(group)
@@ -661,7 +636,7 @@ void wins_process_name_registration_request(struct subnet_record *subrec,
int ttl = get_ttl_from_packet(nmb);
struct name_record *namerec = NULL;
struct in_addr from_ip;
- BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;
+ BOOL registering_group_name = (nb_flags & NB_GROUP) ? True : False;;
putip((char *)&from_ip,&nmb->additional->rdata[2]);
@@ -740,7 +715,7 @@ to register name %s. Name already exists in WINS with source type %d.\n",
if(!registering_group_name && (question->name_type == 0x1d))
{
DEBUG(3,("wins_process_name_registration_request: Ignoring request \
-to register name %s from IP %s.\n", nmb_namestr(question), inet_ntoa(p->ip) ));
+to register name %s from IP %s.", nmb_namestr(question), inet_ntoa(p->ip) ));
send_wins_name_registration_response(0, ttl, p);
return;
}
@@ -810,7 +785,6 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
*/
update_name_ttl(namerec, ttl);
send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
return;
}
}
@@ -827,7 +801,6 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
{
update_name_ttl( namerec, ttl );
send_wins_name_registration_response( 0, ttl, p );
- wins_hook("refresh", namerec, ttl);
return;
}
@@ -838,7 +811,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
if( namerec != NULL )
{
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
+ char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
struct userdata_struct *userdata = (struct userdata_struct *)ud;
/*
@@ -885,9 +858,6 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
(void)add_name_to_subnet( subrec, question->name, question->name_type,
nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
- if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
- wins_hook("add", namerec, ttl);
- }
send_wins_name_registration_response(0, ttl, p);
}
@@ -946,7 +916,6 @@ a subsequent IP addess.\n", nmb_namestr(question_name) ));
add_ip_to_name_record(namerec, from_ip);
update_name_ttl(namerec, ttl);
send_wins_name_registration_response(0, ttl, orig_reg_packet);
- wins_hook("add", namerec, ttl);
orig_reg_packet->locked = False;
free_packet(orig_reg_packet);
@@ -1113,16 +1082,11 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
* It's one of our names and one of our IP's. Ensure the IP is in the record and
* update the ttl.
*/
- if(!find_ip_in_name_record(namerec, from_ip)) {
- add_ip_to_name_record(namerec, from_ip);
- wins_hook("add", namerec, ttl);
- } else {
- wins_hook("refresh", namerec, ttl);
- }
-
- update_name_ttl(namerec, ttl);
- send_wins_name_registration_response(0, ttl, p);
- return;
+ if(!find_ip_in_name_record(namerec, from_ip))
+ add_ip_to_name_record(namerec, from_ip);
+ update_name_ttl(namerec, ttl);
+ send_wins_name_registration_response(0, ttl, p);
+ return;
}
}
@@ -1135,7 +1099,6 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
{
update_name_ttl(namerec, ttl);
send_wins_name_registration_response(0, ttl, p);
- wins_hook("refresh", namerec, ttl);
return;
}
@@ -1146,7 +1109,7 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
if(namerec != NULL)
{
- long *ud[(sizeof(struct userdata_struct) + sizeof(struct packet_struct *))/sizeof(long *) + 1];
+ char ud[sizeof(struct userdata_struct) + sizeof(struct packet_struct *)];
struct userdata_struct *userdata = (struct userdata_struct *)ud;
/*
@@ -1195,10 +1158,6 @@ is one of our (WINS server) names. Denying registration.\n", nmb_namestr(questio
(void)add_name_to_subnet( subrec, question->name, question->name_type,
nb_flags, ttl, REGISTER_NAME, 1, &from_ip );
- if ((namerec = find_name_on_subnet(subrec, question, FIND_ANY_NAME))) {
- wins_hook("add", namerec, ttl);
- }
-
send_wins_name_registration_response(0, ttl, p);
}
@@ -1294,7 +1253,7 @@ void send_wins_name_query_response(int rcode, struct packet_struct *p,
int ttl = 0;
int i;
- memset(rdata,'\0',6);
+ bzero(rdata,6);
if(rcode == 0)
{
@@ -1536,8 +1495,6 @@ release name %s as IP %s is not one of the known IP's for this name.\n",
send_wins_name_release_response(0, p);
remove_ip_from_name_record(namerec, from_ip);
- wins_hook("delete", namerec, 0);
-
/*
* Remove the name entirely if no IP addresses left.
*/
@@ -1595,7 +1552,7 @@ void wins_write_database(BOOL background)
}
slprintf(fname,sizeof(fname),"%s/%s", lp_lockdir(), WINS_LIST);
- all_string_sub(fname,"//", "/", 0);
+ string_sub(fname,"//", "/");
slprintf(fnamenew,sizeof(fnamenew),"%s.%u", fname, (unsigned int)getpid());
if((fp = sys_fopen(fnamenew,"w")) == NULL)
diff --git a/source/nmbd/nmbd_workgroupdb.c b/source/nmbd/nmbd_workgroupdb.c
index 5514e78dc1c..0f66b140a81 100644
--- a/source/nmbd/nmbd_workgroupdb.c
+++ b/source/nmbd/nmbd_workgroupdb.c
@@ -43,9 +43,26 @@ int workgroup_count = 0; /* unique index key: one for each workgroup */
static void add_workgroup(struct subnet_record *subrec, struct work_record *work)
{
- work->subnet = subrec;
- DLIST_ADD(subrec->workgrouplist, work);
- subrec->work_changed = True;
+ struct work_record *w2;
+
+ work->subnet = subrec;
+
+ if (!subrec->workgrouplist)
+ {
+ subrec->workgrouplist = work;
+ work->prev = NULL;
+ work->next = NULL;
+ return;
+ }
+
+ for (w2 = subrec->workgrouplist; w2->next; w2 = w2->next)
+ ;
+
+ w2->next = work;
+ work->next = NULL;
+ work->prev = w2;
+
+ subrec->work_changed = True;
}
/****************************************************************************
@@ -63,7 +80,7 @@ static struct work_record *create_workgroup(char *name, int ttl)
DEBUG(0,("create_workgroup: malloc fail !\n"));
return NULL;
}
- memset((char *)work, '\0', sizeof(*work));
+ bzero((char *)work, sizeof(*work));
StrnCpy(work->work_group,name,sizeof(work->work_group)-1);
work->serverlist = NULL;
@@ -237,8 +254,7 @@ void initiate_myworkgroup_startup(struct subnet_record *subrec, struct work_reco
if we are so configured. */
if ((subrec != unicast_subnet) && (subrec != remote_broadcast_subnet) &&
- (subrec != wins_server_subnet) && lp_preferred_master() &&
- lp_local_master())
+ (subrec != wins_server_subnet) && lp_preferred_master())
{
DEBUG(3, ("initiate_myworkgroup_startup: preferred master startup for \
workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
@@ -267,8 +283,7 @@ workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
SV_TYPE_DOMAIN_MASTER|SV_TYPE_DOMAIN_MEMBER);
create_server_on_workgroup(work,name,stype|SV_TYPE_LOCAL_LIST_ONLY,
- PERMANENT_TTL,
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
+ PERMANENT_TTL, lp_serverstring());
DEBUG(3,("initiate_myworkgroup_startup: Added server name entry %s \
on subnet %s\n", name, subrec->subnet_name));
}
diff --git a/source/nsswitch/.cvsignore b/source/nsswitch/.cvsignore
new file mode 100644
index 00000000000..6d609cec52b
--- /dev/null
+++ b/source/nsswitch/.cvsignore
@@ -0,0 +1 @@
+*.po
diff --git a/source/nsswitch/README b/source/nsswitch/README
deleted file mode 100644
index 9f0c581df60..00000000000
--- a/source/nsswitch/README
+++ /dev/null
@@ -1,13 +0,0 @@
-This extension provides a "wins" module for NSS on glibc2/Linux. This
-allows you to use a WINS entry in /etc/nsswitch.conf for hostname
-resolution, allowing you to resolve netbios names via start unix
-gethostbyname() calls. The end result is that you can use netbios
-names as host names in unix apps.
-
-1) run configure
-2) run "make nsswitch"
-3) cp nsswitch/libnss_wins.so /lib/libnss_wins.so.2
-4) add a wins entry to the hosts line in /etc/nsswitch.conf
-5) use it
-
-tridge@linuxcare.com
diff --git a/source/nsswitch/winbind_nss.c b/source/nsswitch/winbind_nss.c
new file mode 100644
index 00000000000..5e448344098
--- /dev/null
+++ b/source/nsswitch/winbind_nss.c
@@ -0,0 +1,238 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+ Windows NT Domain nsswitch module
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <nss.h>
+#include "includes.h"
+#include "winbindd.h"
+
+#define SPAMTEST 1
+
+int connect_sock(void)
+{
+ int sock;
+ struct sockaddr_un sunaddr;
+
+ sunaddr.sun_family = AF_UNIX;
+ strncpy(sunaddr.sun_path, SOCKET_NAME, sizeof(sunaddr.sun_path));
+
+ if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ return -1;
+ }
+
+ if (connect(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
+ return -1;
+ }
+
+ return sock;
+}
+
+/* Return (struct passwd *) given username */
+
+enum nss_status
+_nss_ntdom_getpwnam_r(const char *name,
+ struct passwd *result, char *buffer,
+ size_t buflen, int *errnop)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ int sock, len;
+
+ /* Connect to agent socket */
+
+ if ((sock = connect_sock()) < 0) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ /* Send query */
+
+ request.cmd = WINBINDD_GETPWNAM_FROM_USER;
+ strncpy(request.data.username, name, sizeof(request.data.username));
+
+ write(sock, &request, sizeof(request));
+
+ /* Wait for reply */
+
+ if ((len = read(sock, &response, sizeof(response))) < 0) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ close(sock);
+
+ if (response.result == WINBINDD_OK) {
+ struct winbindd_pw *pw = &response.data.pw;
+
+ result->pw_name = strdup(pw->pw_name);
+ result->pw_passwd = strdup(pw->pw_name);
+ result->pw_uid = pw->pw_uid;
+ result->pw_gid = pw->pw_gid;
+ result->pw_gecos = strdup(pw->pw_gecos);
+ result->pw_dir = strdup(pw->pw_dir);
+ result->pw_shell = strdup(pw->pw_shell);
+
+ return NSS_STATUS_SUCCESS;
+ }
+
+ return NSS_STATUS_NOTFOUND;
+}
+
+/* Return (struct passwd *) given uid */
+
+enum nss_status
+_nss_ntdom_getpwuid_r(uid_t uid,
+ struct passwd *result, char *buffer,
+ size_t buflen, int *errnop)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ int sock, len;
+
+ /* Connect to agent socket */
+
+ if ((sock = connect_sock()) < 0) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ /* Send query */
+
+ request.cmd = WINBINDD_GETPWNAM_FROM_UID;
+ request.data.uid = uid;
+
+ write(sock, &request, sizeof(request));
+
+ /* Wait for reply */
+
+ if ((len = read(sock, &response, sizeof(response))) < 0) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ close(sock);
+
+ if (response.result == WINBINDD_OK) {
+ struct winbindd_pw *pw = &response.data.pw;
+
+ result->pw_name = strdup(pw->pw_name);
+ result->pw_passwd = strdup(pw->pw_name);
+ result->pw_uid = pw->pw_uid;
+ result->pw_gid = pw->pw_gid;
+ result->pw_gecos = strdup(pw->pw_gecos);
+ result->pw_dir = strdup(pw->pw_dir);
+ result->pw_shell = strdup(pw->pw_shell);
+
+ return NSS_STATUS_SUCCESS;
+ }
+
+ return NSS_STATUS_NOTFOUND;
+}
+
+/*
+ * Functions for nss group database
+ */
+
+enum nss_status
+_nss_ntdom_getgrnam_r(const char *name,
+ struct group *result, char *buffer,
+ size_t buflen, int *errnop)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ int sock, len;
+
+ /* Connect to agent socket */
+
+ if ((sock = connect_sock()) < 0) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ /* Send query */
+
+ request.cmd = WINBINDD_GETGRNAM_FROM_GROUP;
+ strncpy(request.data.groupname, name, sizeof(request.data.groupname));
+
+ write(sock, &request, sizeof(request));
+
+ /* Wait for reply */
+
+ if ((len = read(sock, &response, sizeof(response))) < 0) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ close(sock);
+
+ if (response.result == WINBINDD_OK) {
+ struct winbindd_gr *gr = &response.data.gr;
+
+ result->gr_name = strdup(gr->gr_name);
+ result->gr_passwd = strdup(gr->gr_passwd);
+ result->gr_gid = gr->gr_gid;
+ result->gr_mem = NULL; /* ??? */
+
+ return NSS_STATUS_SUCCESS;
+ }
+
+ return NSS_STATUS_NOTFOUND;
+}
+
+enum nss_status
+_nss_ntdom_getgrgid_r(gid_t gid,
+ struct group *result, char *buffer,
+ size_t buflen, int *errnop)
+{
+ struct winbindd_request request;
+ struct winbindd_response response;
+ int sock, len;
+
+ /* Connect to agent socket */
+
+ if ((sock = connect_sock()) < 0) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ /* Send query */
+
+ request.cmd = WINBINDD_GETGRNAM_FROM_GID;
+ request.data.gid = gid;
+
+ write(sock, &request, sizeof(request));
+
+ /* Wait for reply */
+
+ if ((len = read(sock, &response, sizeof(response))) < 0) {
+ return NSS_STATUS_UNAVAIL;
+ }
+
+ close(sock);
+
+ if (response.result == WINBINDD_OK) {
+ struct winbindd_gr *gr = &response.data.gr;
+
+ result->gr_name = strdup(gr->gr_name);
+ result->gr_passwd = strdup(gr->gr_passwd);
+ result->gr_gid = gr->gr_gid;
+ result->gr_mem = NULL; /* ??? */
+
+ return NSS_STATUS_SUCCESS;
+ }
+
+ return NSS_STATUS_NOTFOUND;
+}
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
new file mode 100644
index 00000000000..6489674cf68
--- /dev/null
+++ b/source/nsswitch/winbindd.c
@@ -0,0 +1,371 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+ Winbind daemon for ntdom nss module
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+#include "sids.h"
+
+/****************************************************************************
+exit thy server
+****************************************************************************/
+void exit_server(char *reason)
+{
+ static int firsttime=1;
+
+ if (!firsttime) exit(0);
+ firsttime = 0;
+
+ unbecome_vuser();
+ DEBUG(0,("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% AARGH\n"));
+
+ if (!reason) {
+ DEBUG(0,("====================================\n"));
+ }
+
+ DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
+#ifdef MEM_MAN
+ {
+ extern FILE *dbf;
+ smb_mem_write_verbose(dbf);
+ dbgflush();
+ }
+#endif
+ exit(0);
+}
+
+/* Connect to a domain controller and return domain sid */
+
+int winbind_get_domain_sid(char *system_name, fstring domain_name,
+ DOM_SID *domain_sid)
+{
+ POLICY_HND lsa_handle;
+ DOM_SID level3_sid, level5_sid;
+ fstring level3_dom, level5_dom;
+ BOOL res = True;
+
+ /* Get SID from domain controller */
+
+ res = res ? lsa_open_policy(system_name, &lsa_handle, False,
+ 0x02000000) : False;
+
+ res = res ? lsa_query_info_pol(&lsa_handle, 0x03, level3_dom,
+ &level3_sid) : False;
+
+ res = res ? lsa_query_info_pol(&lsa_handle, 0x05, level5_dom,
+ &level5_sid) : False;
+
+ res = res ? lsa_close(&lsa_handle) : False;
+
+ /* Return domain sid if successful */
+
+ if (res && (domain_sid != NULL)) {
+ memcpy(domain_sid, &level5_sid, sizeof(level5_sid));
+ fstrcpy(domain_name, level5_dom);
+ }
+
+ return res;
+}
+
+/* Return a sid and type within a domain given a username */
+
+int winbind_lookup_by_name(char *system_name, DOM_SID *level5_sid,
+ fstring name, DOM_SID *sid,
+ enum SID_NAME_USE *type)
+{
+ POLICY_HND lsa_handle;
+ BOOL res = True;
+ DOM_SID *sids = NULL;
+ int num_sids = 0, num_names = 1;
+ uint32 *types = NULL;
+
+ if (name == NULL) {
+ return 0;
+ }
+
+ res = res ? lsa_open_policy(system_name, &lsa_handle, True,
+ 0x02000000) : False;
+
+ res = res ? lsa_lookup_names(&lsa_handle, num_names, (char **)&name,
+ &sids, &types, &num_sids) : False;
+
+ res = res ? lsa_close(&lsa_handle) : False;
+
+ /* Return rid and type if lookup successful */
+
+ if (res) {
+
+ if ((sid != NULL) && (sids != NULL)) {
+ sid_copy(sid, &sids[0]);
+ }
+
+ if ((type != NULL) && (types != NULL)) {
+ *type = types[0];
+ }
+ }
+
+ return res;
+}
+
+/* Return a name and type within a domain given a rid */
+int winbind_lookup_by_sid(char *system_name, DOM_SID *level5_sid,
+ DOM_SID *sid, char *name,
+ enum SID_NAME_USE *type)
+{
+ POLICY_HND lsa_handle;
+ int num_sids = 1, num_names = 0;
+ uint32 *types = NULL;
+ char **names;
+ BOOL res = True;
+
+
+ res = res ? lsa_open_policy(system_name, &lsa_handle, True,
+ 0x02000000) : False;
+
+ res = res ? lsa_lookup_sids(&lsa_handle, num_sids, (DOM_SID **)&sid,
+ &names, &types, &num_names) : False;
+
+ res = res ? lsa_close(&lsa_handle) : False;
+
+ /* Return name and type if successful */
+
+ if (res) {
+ if ((names != NULL) && (name != NULL)) {
+ fstrcpy(name, names[0]);
+ }
+
+ if ((type != NULL) && (types != NULL)) {
+ *type = types[0];
+ }
+ }
+
+ return res;
+}
+
+/* Lookup user information from rid */
+
+int winbind_lookup_userinfo(char *system_name, DOM_SID *level5_sid,
+ uint32 user_rid, SAM_USERINFO_CTR *info)
+{
+ POLICY_HND sam_handle, sam_dom_handle;
+ BOOL res = True;
+
+ /* Open connection to SAM pipe and SAM domain */
+
+ res = res ? samr_connect(system_name, 0x02000000, &sam_handle) : False;
+
+ res = res ? samr_open_domain(&sam_handle, 0x02000000, level5_sid,
+ &sam_dom_handle) : False;
+ /* Query user info */
+
+ res = res ? get_samr_query_userinfo(&sam_dom_handle, 0x15, user_rid,
+ info) : False;
+ /* Close up shop */
+
+ res = res ? samr_close(&sam_dom_handle) : False;
+
+ res = res ? samr_close(&sam_handle) : False;
+
+ return res;
+}
+
+int winbind_lookup_groupinfo(char *system_name, DOM_SID *level5_sid,
+ uint32 group_rid, GROUP_INFO_CTR *info)
+{
+ POLICY_HND sam_handle, sam_dom_handle;
+ BOOL res = True;
+
+ /* Open connection to SAM pipe and SAM domain */
+
+ res = res ? samr_connect(system_name, 0x02000000, &sam_handle) : False;
+
+ res = res ? samr_open_domain(&sam_handle, 0x02000000, level5_sid,
+ &sam_dom_handle) : False;
+ /* Query group info */
+
+ res = res ? get_samr_query_groupinfo(&sam_dom_handle, 1,
+ group_rid, info) : False;
+
+ /* Close up shop */
+
+ res = res ? samr_close(&sam_dom_handle) : False;
+
+ res = res ? samr_close(&sam_handle) : False;
+
+ return res;
+}
+
+/* Create ipc socket */
+
+int create_winbind_socket(void)
+{
+ struct sockaddr_un sunaddr;
+ struct stat st;
+ int ret, sock;
+
+ ret = stat(SOCKET_NAME, &st);
+ if (ret == -1 && errno != ENOENT) {
+ perror("stat");
+ return -1;
+ }
+
+ if (ret == 0) {
+ fprintf(stderr, "socket exists!\n");
+ return -1;
+ }
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+
+ if (sock < 0) {
+ perror("socket");
+ return -1;
+ }
+
+ memset(&sunaddr, 0, sizeof(sunaddr));
+ sunaddr.sun_family = AF_UNIX;
+ strncpy(sunaddr.sun_path, SOCKET_NAME, sizeof(sunaddr.sun_path));
+
+ if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
+ perror("bind");
+ close(sock);
+ return -1;
+ }
+
+ if (chmod(SOCKET_NAME, 0700) < 0) {
+ perror("chmod");
+ close(sock);
+ return -1;
+ }
+
+ if (listen(sock, 5) < 0) {
+ perror("listen");
+ close(sock);
+ return -1;
+ }
+
+ /* Success! */
+
+ return sock;
+}
+
+/*
+ * Main function
+ */
+
+int main(int argc, char **argv)
+{
+ DOM_SID domain_sid;
+ fstring domain_name, sid;
+ int sock;
+
+ /* Initialise samba/rpc client stuff */
+
+ lp_load(CONFIGFILE, True, False, False);
+ fstrcpy(debugf, "/tmp/winbindd.log");
+ setup_logging(debugf, 1);
+ reopen_logs();
+
+ charset_initialise();
+ codepage_initialise(lp_client_code_page());
+
+ /* Get the domain sid */
+
+ if (!winbind_get_domain_sid(SERVER, domain_name, &domain_sid)) {
+ DEBUG(0, ("Cannot get domain sid from %s\n", domain_name));
+ return 1;
+ }
+
+ sid_to_string(sid, &domain_sid);
+ DEBUG(3, ("Domain controller for domain %s has sid %s\n",
+ domain_name, sid));
+
+ sid_copy(&global_sam_sid, &domain_sid); /* ??? */
+ generate_wellknown_sids(); /* ??? */
+
+ /* Loop waiting for requests */
+
+ if ((sock = create_winbind_socket()) == -1) {
+ DEBUG(0, ("failed to create socket\n"));
+ return 1;
+ }
+
+ while (1) {
+ int len, sock2;
+ struct sockaddr_un sunaddr;
+ struct winbindd_request request;
+ struct winbindd_response response;
+
+ /* Accept connection */
+
+ len = sizeof(sunaddr);
+ sock2 = accept(sock, (struct sockaddr *)&sunaddr, &len);
+
+ /* Read command */
+
+ if ((len = read(sock2, &request, sizeof(request))) < 0) {
+ close(sock2);
+ continue;
+ }
+
+ response.result = WINBINDD_ERROR;
+
+ /* Process command */
+
+ switch(request.cmd) {
+
+ /* User functions */
+
+ case WINBINDD_GETPWNAM_FROM_USER:
+ DEBUG(1, ("getpwnam from user '%s'\n", request.data.username));
+ winbindd_getpwnam_from_user(&domain_sid, &request, &response);
+ break;
+
+ case WINBINDD_GETPWNAM_FROM_UID:
+ DEBUG(1, ("getpwnam from uid %d\n", request.data.uid));
+ winbindd_getpwnam_from_uid(&domain_sid, &request, &response);
+ break;
+
+ /* Group functions */
+
+ case WINBINDD_GETGRNAM_FROM_GROUP:
+ DEBUG(1, ("getgrnam from group '%s'\n", request.data.groupname));
+ winbindd_getgrnam_from_group(&domain_sid, &request, &response);
+ break;
+
+ case WINBINDD_GETGRNAM_FROM_GID:
+ DEBUG(1, ("getgrnam from gid %d\n", request.data.gid));
+ winbindd_getgrnam_from_gid(&domain_sid, &request, &response);
+ break;
+
+ /* Oops */
+
+ default:
+ DEBUG(0, ("oops - unknown command %d\n", request.cmd));
+ break;
+ }
+
+ /* Send response */
+
+ write(sock2, &response, sizeof(response));
+ close(sock2);
+ }
+
+ return 0;
+}
diff --git a/source/nsswitch/winbindd.h b/source/nsswitch/winbindd.h
new file mode 100644
index 00000000000..de9913eaaa3
--- /dev/null
+++ b/source/nsswitch/winbindd.h
@@ -0,0 +1,88 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+ Winbind daemon for ntdom nss module
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _WINBINDD_H
+#define _WINBINDD_H
+
+#define SOCKET_NAME "/tmp/winbindd"
+#define SERVER "controller"
+
+/* Naughty global stuff */
+
+extern int DEBUGLEVEL;
+extern pstring debugf;
+
+/* Socket commands */
+
+enum winbindd_cmd {
+ WINBINDD_GETPWNAM_FROM_USER,
+ WINBINDD_GETPWNAM_FROM_UID,
+ WINBINDD_GETGRNAM_FROM_GROUP,
+ WINBINDD_GETGRNAM_FROM_GID
+};
+
+/* Winbind request structure */
+
+struct winbindd_request {
+ enum winbindd_cmd cmd;
+
+ union {
+ char username[1024];
+ char groupname[1024];
+ uid_t uid;
+ gid_t gid;
+ } data;
+};
+
+/* Response values */
+
+enum winbindd_result {
+ WINBINDD_ERROR,
+ WINBINDD_OK
+};
+
+/* Winbind response structure */
+
+struct winbindd_response {
+ enum winbindd_result result;
+
+ union {
+ struct winbindd_pw {
+ char pw_name[1024];
+ char pw_passwd[1024];
+ uid_t pw_uid;
+ gid_t pw_gid;
+ char pw_gecos[1024];
+ char pw_dir[1024];
+ char pw_shell[1024];
+ } pw;
+ struct winbindd_gr {
+ char gr_name[1024];
+ char gr_passwd[1024];
+ gid_t gr_gid;
+ char gr_mem[1024];
+ } gr;
+ } data;
+};
+
+#include "winbindd_proto.h"
+
+#endif /* _WINBINDD_H */
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
new file mode 100644
index 00000000000..dd73f7c7051
--- /dev/null
+++ b/source/nsswitch/winbindd_group.c
@@ -0,0 +1,172 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+ Winbind daemon for ntdom nss module
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+
+/* Fill a grent structure from various other information */
+
+static void winbindd_fill_grent(struct winbindd_gr *gr)
+{
+ /* Fill in uid/gid */
+
+ gr->gr_gid = 0;
+
+ /* More complicated stuff */
+
+ strncpy(gr->gr_name, "spamgrp", sizeof(gr->gr_name) - 1);
+ strncpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1);
+ strncpy(gr->gr_mem, "", sizeof(gr->gr_mem) - 1); /* ??? */
+}
+
+/* Return a group structure from a group name */
+
+void winbindd_getgrnam_from_group(DOM_SID *domain_sid,
+ struct winbindd_request *request,
+ struct winbindd_response *response)
+{
+ DOM_SID domain_group_sid, temp;
+ uint32 name_type, group_rid;
+ gid_t unix_gid;
+ GROUP_INFO_CTR info;
+
+ /* Get rid and name type from NT server */
+
+ if (!winbind_lookup_by_name(SERVER, domain_sid,
+ request->data.groupname, &domain_group_sid,
+ &name_type)) {
+ DEBUG(1, ("name %s does not exist\n", request->data.groupname));
+ return;
+ }
+
+ if ((name_type != SID_NAME_ALIAS) && (name_type != SID_NAME_DOM_GRP)) {
+ DEBUG(1, ("name '%s' is not a local or domain group\n",
+ request->data.groupname));
+ return;
+ }
+
+ /* Get group info */
+
+ sid_copy(&temp, &domain_group_sid);
+ sid_split_rid(&temp, &group_rid);
+
+ if (!winbind_lookup_groupinfo(SERVER, domain_sid, group_rid, &info)) {
+ DEBUG(1, ("Could not lookup group info\n"));
+ return;
+ }
+
+ {
+ fstring str;
+
+ DEBUG(0, ("unknown_1 = %d\n", info.group.info1.unknown_1));
+ DEBUG(0, ("num_members = %d\n", info.group.info1.num_members));
+
+ unistr2_to_ascii(str, &info.group.info1.uni_acct_name,
+ sizeof(str) - 1);
+ DEBUG(0, ("acct_name = %s\n", str));
+
+ unistr2_to_ascii(str, &info.group.info1.uni_acct_desc,
+ sizeof(str) - 1);
+ DEBUG(0, ("acct_desc = %s\n", str));
+ }
+
+ /* Fill in group structure */
+
+ if (!(winbindd_surs_sam_sid_to_unixid(&domain_group_sid, SID_NAME_ALIAS,
+ &unix_gid) ||
+ winbindd_surs_sam_sid_to_unixid(&domain_group_sid, SID_NAME_DOM_GRP,
+ &unix_gid))) {
+ DEBUG(1, ("error sursing unix gid for sid\n"));
+ } else {
+
+ winbindd_fill_grent(&response->data.gr);
+ response->result = WINBINDD_OK;
+ }
+}
+
+/* Return a group structure from a gid number */
+
+void winbindd_getgrnam_from_gid(DOM_SID *domain_sid,
+ struct winbindd_request *request,
+ struct winbindd_response *response)
+{
+ DOM_SID domain_group_sid, temp;
+ uint32 group_rid;
+ uint32 name_type;
+ fstring group_name;
+ GROUP_INFO_CTR info;
+
+ /* Get sid from gid */
+
+ if (!(winbindd_surs_unixid_to_sam_sid(request->data.gid, SID_NAME_ALIAS,
+ &domain_group_sid, False) ||
+ winbindd_surs_unixid_to_sam_sid(request->data.gid, SID_NAME_DOM_GRP,
+ &domain_group_sid, False))) {
+ DEBUG(1, ("Could not convert gid %d to domain or local sid\n",
+ request->data.gid));
+ return;
+ }
+
+ /* Get name and name type from sid */
+
+ if (!winbind_lookup_by_sid(SERVER, domain_sid, &domain_group_sid,
+ group_name, &name_type)) {
+ DEBUG(1, ("Could not lookup sid\n"));
+ return;
+ }
+
+ if (!((name_type == SID_NAME_ALIAS) ||
+ (name_type == SID_NAME_DOM_GRP))) {
+ DEBUG(1, ("name '%s' is not a local or domain group\n",
+ request->data.groupname));
+ return;
+ }
+
+ /* Get some group info */
+
+ sid_copy(&temp, &domain_group_sid);
+ sid_split_rid(&temp, &group_rid);
+
+ if (!winbind_lookup_groupinfo(SERVER, domain_sid, group_rid, &info)) {
+ DEBUG(1, ("Could not lookup group info\n"));
+ return;
+ }
+
+ {
+ fstring str;
+
+ DEBUG(0, ("unknown_1 = %d\n", info.group.info1.unknown_1));
+ DEBUG(0, ("num_members = %d\n", info.group.info1.num_members));
+
+ unistr2_to_ascii(str, &info.group.info1.uni_acct_name,
+ sizeof(str) - 1);
+ DEBUG(0, ("acct_name = %s\n", str));
+
+ unistr2_to_ascii(str, &info.group.info1.uni_acct_desc,
+ sizeof(str) - 1);
+ DEBUG(0, ("acct_desc = %s\n", str));
+ }
+
+ /* Fill in group structure */
+
+ winbindd_fill_grent(&response->data.gr);
+ response->result = WINBINDD_OK;
+}
diff --git a/source/nsswitch/winbindd_surs.c b/source/nsswitch/winbindd_surs.c
new file mode 100644
index 00000000000..4482aeb0162
--- /dev/null
+++ b/source/nsswitch/winbindd_surs.c
@@ -0,0 +1,63 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+ Winbind daemon for ntdom nss module
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+
+/* Wrapper around "standard" surs sid to unixid function */
+
+BOOL winbindd_surs_sam_sid_to_unixid(DOM_SID *sid, uint32 type, uint32 *id)
+{
+ fstring sid_str;
+ BOOL result;
+
+ result = surs_sam_sid_to_unixid(sid, type, id, False);
+
+ sid_to_string(sid_str, sid);
+ DEBUG(0, ("surs_sam_sid_to_unixid: %s type %s -> %d\n", sid_str,
+ (type == SID_NAME_USER) ? "user" : (
+ (type == SID_NAME_ALIAS) ? "alias" : (
+ (type == SID_NAME_DOM_GRP) ? "domain group" : "?")),
+ (result ? ((id != NULL) ? *id : -2) : -1)));
+
+ return result;
+}
+
+/* Wrapper around "standard" surs unixd to sid function */
+
+BOOL winbindd_surs_unixid_to_sam_sid(uint32 id, uint32 type, DOM_SID *sid,
+ BOOL create)
+{
+ fstring sid_str;
+ BOOL result;
+
+ result = surs_unixid_to_sam_sid(id, type, sid, create);
+
+ if (sid) sid_to_string(sid_str, sid);
+
+ DEBUG(0, ("surs_unixid_to_sam_sid: %d type %s -> %s\n", id,
+ (type == SID_NAME_USER) ? "user" : (
+ (type == SID_NAME_ALIAS) ? "alias" : (
+ (type == SID_NAME_DOM_GRP) ? "domain group" : "?")),
+ sid ? sid_str : "NULL"));
+
+ return result;
+}
diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c
new file mode 100644
index 00000000000..a5babfff445
--- /dev/null
+++ b/source/nsswitch/winbindd_user.c
@@ -0,0 +1,202 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0
+ Winbind daemon for ntdom nss module
+ Copyright (C) Tim Potter 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+
+/* Fill a pwent structure from various other information */
+
+static void winbindd_fill_pwent(struct winbindd_pw *pw, uid_t unix_uid,
+ gid_t unix_gid, SAM_USERINFO_CTR *user_info)
+{
+ fstring temp;
+
+ /* Fill in uid/gid */
+
+ pw->pw_uid = unix_uid;
+ pw->pw_gid = unix_gid;
+
+ /* More complicated stuff */
+
+ unistr2_to_ascii(temp, &user_info->info.id21->uni_full_name,
+ sizeof(temp) - 1);
+ strncpy(pw->pw_gecos, temp, sizeof(pw->pw_gecos) - 1);
+
+ unistr2_to_ascii(temp, &user_info->info.id21->uni_dir_drive,
+ sizeof(temp));
+ strncpy(pw->pw_dir, temp, sizeof(pw->pw_dir) - 1);
+
+ strncpy(pw->pw_shell, "/dev/null", sizeof(pw->pw_shell) - 1);
+}
+
+/* Return a password structure from a username */
+
+void winbindd_getpwnam_from_user(DOM_SID *domain_sid,
+ struct winbindd_request *request,
+ struct winbindd_response *response)
+{
+ uint32 name_type, user_rid;
+ uid_t unix_uid;
+ gid_t unix_gid;
+ SAM_USERINFO_CTR user_info;
+ DOM_SID user_sid, group_sid, temp;
+ BOOL res;
+
+ /* Get rid and name type from name */
+
+ if (!winbind_lookup_by_name(SERVER, domain_sid,
+ request->data.username, &user_sid,
+ &name_type)) {
+ DEBUG(1, ("user '%s' does not exist\n", request->data.username));
+ return;
+ }
+
+ if (name_type != SID_NAME_USER) {
+ DEBUG(1, ("name '%s' is not a user name\n", request->data.username));
+ return;
+ }
+
+ /* Get some user info */
+
+ sid_copy(&temp, &user_sid);
+ sid_split_rid(&temp, &user_rid);
+
+ if (!winbind_lookup_userinfo(SERVER, domain_sid, user_rid, &user_info)) {
+ DEBUG(1, ("error getting user info for user '%s'\n",
+ request->data.username));
+ return;
+ }
+
+ /* Try and resolve uid and gid numbers for the name */
+
+ sid_copy(&user_sid, domain_sid);
+ sid_copy(&group_sid, domain_sid);
+
+ sid_append_rid(&user_sid, user_info.info.id21->user_rid);
+ sid_append_rid(&group_sid, user_info.info.id21->group_rid);
+
+ res = winbindd_surs_sam_sid_to_unixid(&user_sid, SID_NAME_USER, &unix_uid);
+
+ if (!res) {
+ DEBUG(1, ("error sursing unix uid for sid\n"));
+ } else {
+
+ res = res ? (winbindd_surs_sam_sid_to_unixid(&group_sid,
+ SID_NAME_ALIAS,
+ &unix_gid) ||
+ winbindd_surs_sam_sid_to_unixid(&group_sid,
+ SID_NAME_DOM_GRP,
+ &unix_gid)) : False;
+ if (!res) {
+ DEBUG(1, ("error sursing unix gid for sid\n"));
+ } else {
+
+ /* Fill in password structure */
+
+ winbindd_fill_pwent(&response->data.pw, unix_uid, unix_gid,
+ &user_info);
+
+ response->result = WINBINDD_OK;
+ }
+ }
+
+ /* Free user info */
+
+ free_samr_userinfo_ctr(&user_info);
+}
+
+/* Return a password structure given a uid number */
+
+void winbindd_getpwnam_from_uid(DOM_SID *domain_sid,
+ struct winbindd_request *request,
+ struct winbindd_response *response)
+{
+ DOM_SID domain_user_sid, temp;
+ uint32 user_rid;
+ fstring user_name;
+ enum SID_NAME_USE name_type;
+ SAM_USERINFO_CTR user_info;
+ uid_t unix_uid;
+ gid_t unix_gid;
+ BOOL res;
+
+ /* Get sid from uid */
+
+ if (!winbindd_surs_unixid_to_sam_sid(request->data.uid, SID_NAME_USER,
+ &domain_user_sid, False)) {
+ DEBUG(1, ("Could not convert uid %d to domain sid\n",
+ request->data.uid));
+ return;
+ }
+
+ /* Get name and name type from rid */
+
+ if (!winbind_lookup_by_sid(SERVER, domain_sid, &domain_user_sid,
+ user_name, &name_type)) {
+ DEBUG(1, ("Could not lookup sid\n"));
+ return;
+ }
+
+ if (name_type != SID_NAME_USER) {
+ DEBUG(1, ("name '%s' is not a user name\n", request->data.username));
+ return;
+ }
+
+ /* Get some user info */
+
+ sid_copy(&temp, &domain_user_sid);
+ sid_split_rid(&temp, &user_rid);
+
+ if (!winbind_lookup_userinfo(SERVER, domain_sid, user_rid, &user_info)) {
+ DEBUG(1, ("error getting user info for user '%s'\n",
+ request->data.username));
+ return;
+ }
+
+ res = winbindd_surs_sam_sid_to_unixid(&domain_user_sid, SID_NAME_USER,
+ &unix_uid);
+
+ if (!res) {
+ DEBUG(1, ("error sursing unix uid for sid\n"));
+ }
+
+ res = res ? (winbindd_surs_sam_sid_to_unixid(&domain_user_sid,
+ SID_NAME_ALIAS, &unix_gid) ||
+ winbindd_surs_sam_sid_to_unixid(&domain_user_sid,
+ SID_NAME_DOM_GRP, &unix_gid))
+ : False;
+
+ /* Fill in password structure */
+
+ if (!res) {
+ DEBUG(1, ("error sursing unix gid for sid\n"));
+ } else {
+
+ winbindd_fill_pwent(&response->data.pw, unix_uid, unix_gid,
+ &user_info);
+
+ response->result = WINBINDD_OK;
+ }
+
+ /* Free user info */
+
+ free_samr_userinfo_ctr(&user_info);
+}
diff --git a/source/nsswitch/wins.c b/source/nsswitch/wins.c
deleted file mode 100644
index f8a05a9fbf2..00000000000
--- a/source/nsswitch/wins.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 2.0
- a WINS nsswitch module
- Copyright (C) Andrew Tridgell 1999
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#define NO_SYSLOG
-
-#include "includes.h"
-#include <nss.h>
-
-extern int DEBUGLEVEL;
-
-#ifndef INADDRSZ
-#define INADDRSZ 4
-#endif
-
-struct in_addr *lookup_backend(const char *name, int *count)
-{
- int fd;
- static int initialised;
- struct in_addr *ret;
- char *p;
- int j;
-
- if (!initialised) {
- initialised = 1;
- DEBUGLEVEL = 0;
- TimeInit();
- setup_logging("nss_wins",True);
- charset_initialise();
- lp_load(CONFIGFILE,True,False,False);
- load_interfaces();
- }
-
- *count = 0;
-
- fd = open_socket_in(SOCK_DGRAM,0, 3, interpret_addr("0.0.0.0"), True);
- if (fd == -1) return NULL;
-
- set_socket_options(fd,"SO_BROADCAST");
-
- p = lp_wins_server();
- if (p && *p) {
- ret = name_query(fd,name,0x20,False,True, *interpret_addr2(p), count);
- goto out;
- }
-
- if (lp_wins_support()) {
- /* we are our own WINS server */
- ret = name_query(fd,name,0x20,False,True, *interpret_addr2("127.0.0.1"), count);
- goto out;
- }
-
- /* uggh, we have to broadcast to each interface in turn */
- for (j=iface_count() - 1;
- j >= 0;
- j--) {
- struct in_addr *bcast = iface_n_bcast(j);
- ret = name_query(fd,name,0x20,True,True,*bcast,count);
- if (ret) break;
- }
-
- out:
- close(fd);
- return ret;
-}
-
-
-/****************************************************************************
-gethostbyname() - we ignore any domain portion of the name and only
-handle names that are at most 15 characters long
- **************************************************************************/
-enum nss_status
-_nss_wins_gethostbyname_r(const char *name, struct hostent *he,
- char *buffer, size_t buflen, int *errnop,
- int *h_errnop)
-{
- char **host_addresses;
- struct in_addr *ip_list;
- int i, count;
-
- ip_list = lookup_backend(name, &count);
- if (!ip_list) {
- return NSS_STATUS_NOTFOUND;
- }
-
- if (buflen < (2*count+1)*INADDRSZ) {
- /* no ENOMEM error type?! */
- return NSS_STATUS_NOTFOUND;
- }
-
-
- host_addresses = (char **)buffer;
- he->h_addr_list = host_addresses;
- host_addresses[count] = NULL;
- buffer += (count + 1) * INADDRSZ;
- buflen += (count + 1) * INADDRSZ;
- he->h_addrtype = AF_INET;
- he->h_length = INADDRSZ;
-
- for (i=0;i<count;i++) {
- memcpy(buffer, &ip_list[i].s_addr, INADDRSZ);
- *host_addresses = buffer;
- buffer += INADDRSZ;
- buflen -= INADDRSZ;
- host_addresses++;
- }
-
- if (ip_list) free(ip_list);
-
- return NSS_STATUS_SUCCESS;
-}
diff --git a/source/param/.cvsignore b/source/param/.cvsignore
index 76e2d7ff3eb..1ab6832045e 100644
--- a/source/param/.cvsignore
+++ b/source/param/.cvsignore
@@ -1,3 +1,3 @@
+*.[pl]o
*.po32
-*.po
diff --git a/source/param/loadparm.c b/source/param/loadparm.c
index 7a225b035e6..5f6b0b5bdb1 100644
--- a/source/param/loadparm.c
+++ b/source/param/loadparm.c
@@ -71,7 +71,6 @@ BOOL bLoaded = False;
extern int DEBUGLEVEL;
extern pstring user_socket_options;
extern pstring global_myname;
-pstring global_scope = "";
#ifndef GLOBAL_NAME
#define GLOBAL_NAME "global"
@@ -117,20 +116,22 @@ typedef struct
char *szLogFile;
char *szConfigFile;
char *szSMBPasswdFile;
+ char *szSAMDirectory;
+ char *szSMBPassGroupFile;
+ char *szSMBGroupFile;
+ char *szSMBAliasFile;
char *szPasswordServer;
char *szSocketOptions;
char *szValidChars;
char *szWorkGroup;
- char *szDomainAdminGroup;
- char *szDomainGuestGroup;
- char *szDomainAdminUsers;
- char *szDomainGuestUsers;
- char *szDomainHostsallow;
- char *szDomainHostsdeny;
+ char *szTrustedDomains;
+ char *szTrustingDomains;
char *szUsernameMap;
-#ifdef USING_GROUPNAME_MAP
+ char *szAliasnameMap;
char *szGroupnameMap;
-#endif /* USING_GROUPNAME_MAP */
+ char *szBuiltinnameMap;
+ char *szBuiltinRidFile;
+ char *szNTusernameMap;
char *szCharacterSet;
char *szLogonScript;
char *szLogonPath;
@@ -147,24 +148,25 @@ typedef struct
char *szAnnounceVersion; /* This is initialised in init_globals */
char *szNetbiosAliases;
char *szDomainOtherSIDs;
- char *szDomainGroups;
char *szDriverFile;
char *szNameResolveOrder;
+ char *szDfsMap;
+#if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
char *szLdapServer;
+ char *szLdapBindAs;
+ char *szLdapPasswdFile;
char *szLdapSuffix;
- char *szLdapFilter;
- char *szLdapRoot;
- char *szLdapRootPassword;
+#endif /* WITH_LDAP */
+#ifdef WITH_NT5LDAP
+ char *szLdapUrl;
+ char *szLdapRealm;
+ char *szLdapComputersSubcontext;
+ char *szLdapUsersSubcontext;
+ char *szLdapBuiltinSubcontext;
+#endif /* WITH_NT5LDAP */
char *szPanicAction;
- char *szAddUserScript;
- char *szDelUserScript;
- char *szWINSHook;
char *szNtForms;
- char *szNtDriverFile;
-#ifdef WITH_UTMP
- char *szUtmpDir;
-#endif /* WITH_UTMP */
- char *szSourceEnv;
+ char *szNtDriverFile;
int max_log_size;
int mangled_stack;
int max_xmit;
@@ -193,10 +195,9 @@ typedef struct
int change_notify_timeout;
int stat_cache_size;
int map_to_guest;
- int min_passwd_length;
- int oplock_break_wait_time;
-#ifdef WITH_LDAP
+#if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
int ldap_port;
+ int ldap_protocol_version;
#endif /* WITH_LDAP */
#ifdef WITH_SSL
int sslVersion;
@@ -223,6 +224,10 @@ typedef struct
BOOL bDomainLogons;
BOOL bEncryptPasswords;
BOOL bUpdateEncrypt;
+ BOOL bServerSChannel;
+ BOOL bClientSChannel;
+ BOOL bServerNTLMv2;
+ BOOL bClientNTLMv2;
BOOL bStripDot;
BOOL bNullPasswords;
BOOL bLoadPrinters;
@@ -243,14 +248,15 @@ typedef struct
BOOL bTimestampLogs;
BOOL bNTSmbSupport;
BOOL bNTPipeSupport;
- BOOL bNTAclSupport;
BOOL bStatCache;
BOOL bKernelOplocks;
- BOOL bAllowTrustedDomains;
- BOOL bRestrictAnonymous;
- BOOL bDebugHiresTimestamp;
- BOOL bDebugPid;
- BOOL bDebugUid;
+#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
+ char *sMysqlDatabase;
+ char *sMysqlTable;
+ char *sMysqlUser;
+ char *sMysqlHost;
+ char *sMysqlPassFile;
+#endif
} global;
static global Globals;
@@ -302,25 +308,17 @@ typedef struct
char *writelist;
char *volume;
char *fstype;
- char *szVfsObjectFile;
- char *szVfsOptions;
+ char *vfsObjectFile;
+ struct vfs_options *vfsOptions;
int iMinPrintSpace;
- int iWriteCacheSize;
int iCreate_mask;
int iCreate_force_mode;
- int iSecurity_mask;
- int iSecurity_force_mode;
int iDir_mask;
int iDir_force_mode;
- int iDir_Security_mask;
- int iDir_Security_force_mode;
int iMaxConnections;
int iDefaultCase;
int iPrinting;
- int iOplockContentionLimit;
BOOL bAlternatePerm;
- BOOL bPreexecClose;
- BOOL bRootpreexecClose;
BOOL bRevalidate;
BOOL bCaseSensitive;
BOOL bCasePreserve;
@@ -341,12 +339,8 @@ typedef struct
BOOL bMap_archive;
BOOL bLocking;
BOOL bStrictLocking;
-#ifdef WITH_UTMP
- BOOL bUtmp;
-#endif
BOOL bShareModes;
BOOL bOpLocks;
- BOOL bLevel2OpLocks;
BOOL bOnlyUser;
BOOL bMangledNames;
BOOL bWidelinks;
@@ -362,7 +356,6 @@ typedef struct
BOOL bDosFiletimeResolution;
BOOL bFakeDirCreateTimes;
BOOL bBlockingLocks;
- BOOL bInheritPerms;
char dummy[3]; /* for alignment */
} service;
@@ -413,22 +406,14 @@ static service sDefault =
NULL, /* vfs object */
NULL, /* vfs options */
0, /* iMinPrintSpace */
- 0, /* iWriteCacheSize */
0744, /* iCreate_mask */
0000, /* iCreate_force_mode */
- -1, /* iSecurity_mask */
- -1, /* iSecurity_force_mode */
0755, /* iDir_mask */
0000, /* iDir_force_mode */
- -1, /* iDir_Security_mask */
- -1, /* iDir_Security_force_mode */
0, /* iMaxConnections */
CASE_LOWER, /* iDefaultCase */
DEFAULT_PRINTING, /* iPrinting */
- 2, /* iOplockContentionLimit */
False, /* bAlternatePerm */
- False, /* bPreexecClose */
- False, /* bRootpreexecClose */
False, /* revalidate */
False, /* case sensitive */
True, /* case preserve */
@@ -449,12 +434,8 @@ static service sDefault =
True, /* bMap_archive */
True, /* bLocking */
False, /* bStrictLocking */
-#ifdef WITH_UTMP
- False, /* bUtmp */
-#endif
True, /* bShareModes */
True, /* bOpLocks */
- True, /* bLevel2OpLocks */
False, /* bOnlyUser */
True, /* bMangledNames */
True, /* bWidelinks */
@@ -470,7 +451,6 @@ static service sDefault =
False, /* bDosFiletimeResolution */
False, /* bFakeDirCreateTimes */
True, /* bBlockingLocks */
- False, /* bInheritPerms */
"" /* dummy */
};
@@ -482,6 +462,7 @@ static int iNumServices = 0;
static int iServiceIndex = 0;
static BOOL bInGlobalSection = True;
static BOOL bGlobalOnly = False;
+static int server_role;
static int default_server_announce;
#define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct))
@@ -492,11 +473,10 @@ static BOOL handle_include(char *pszParmValue, char **ptr);
static BOOL handle_copy(char *pszParmValue, char **ptr);
static BOOL handle_character_set(char *pszParmValue,char **ptr);
static BOOL handle_coding_system(char *pszParmValue,char **ptr);
-static BOOL handle_client_code_page(char *pszParmValue,char **ptr);
static BOOL handle_vfs_object(char *pszParmValue, char **ptr);
-static BOOL handle_source_env(char *pszParmValue,char **ptr);
-static BOOL handle_netbios_name(char *pszParmValue,char **ptr);
+static BOOL handle_vfs_option(char *pszParmValue, char **ptr);
+static void set_server_role(void);
static void set_default_server_announce_type(void);
static struct enum_list enum_protocol[] = {{PROTOCOL_NT1, "NT1"}, {PROTOCOL_LANMAN2, "LANMAN2"},
@@ -512,19 +492,14 @@ static struct enum_list enum_printing[] = {{PRINT_SYSV, "sysv"}, {PRINT_AIX, "ai
{PRINT_HPUX, "hpux"}, {PRINT_BSD, "bsd"},
{PRINT_QNX, "qnx"}, {PRINT_PLP, "plp"},
{PRINT_LPRNG, "lprng"}, {PRINT_SOFTQ, "softq"},
- {PRINT_CUPS, "cups"}, {-1, NULL}};
+ {-1, NULL}};
-/* Types of machine we can announce as. */
-#define ANNOUNCE_AS_NT_SERVER 1
-#define ANNOUNCE_AS_WIN95 2
-#define ANNOUNCE_AS_WFW 3
-#define ANNOUNCE_AS_NT_WORKSTATION 4
-
-static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT_SERVER, "NT"}, {ANNOUNCE_AS_NT_SERVER, "NT Server"}, {ANNOUNCE_AS_NT_WORKSTATION, "NT Workstation"}, {ANNOUNCE_AS_WIN95, "win95"}, {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
+static struct enum_list enum_announce_as[] = {{ANNOUNCE_AS_NT, "NT"}, {ANNOUNCE_AS_WIN95, "win95"},
+ {ANNOUNCE_AS_WFW, "WfW"}, {-1, NULL}};
static struct enum_list enum_case[] = {{CASE_LOWER, "lower"}, {CASE_UPPER, "upper"}, {-1, NULL}};
-static struct enum_list enum_lm_announce[] = {{0, "False"}, {1, "True"}, {2, "Auto"}, {-1, NULL}};
+static struct enum_list enum_bool_auto[] = {{True, "True"}, {False, "False"}, {True, "Yes"}, {False, "No"}, {Auto, "Auto"}, {-1, NULL}};
/*
Do you want session setups at user level security with a invalid
@@ -558,32 +533,40 @@ static struct enum_list enum_ssl_version[] = {{SMB_SSL_V2, "ssl2"}, {SMB_SSL_V3,
static struct parm_struct parm_table[] =
{
{"Base Options", P_SEP, P_SEPARATOR},
- {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
- {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, handle_client_code_page, NULL, 0},
- {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_DOS_STRING},
- {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_DOS_STRING},
- {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_DOS_STRING},
- {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC|FLAG_DOS_STRING},
- {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC|FLAG_DOS_STRING},
- {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_DOS_STRING},
- {"netbios scope", P_UGSTRING,P_GLOBAL, global_scope, NULL, NULL, FLAG_DOS_STRING},
- {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC|FLAG_DOS_STRING},
+
+ {"comment", P_STRING, P_LOCAL, &sDefault.comment, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
+ {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
+ {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, 0},
+ {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC},
+ {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC},
+ {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, 0},
+ {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC},
{"interfaces", P_STRING, P_GLOBAL, &Globals.szInterfaces, NULL, NULL, FLAG_BASIC},
{"bind interfaces only", P_BOOL,P_GLOBAL, &Globals.bBindInterfacesOnly,NULL, NULL, 0},
{"Security Options", P_SEP, P_SEPARATOR},
+
{"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
{"encrypt passwords",P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
{"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC},
- {"allow trusted domains",P_BOOL,P_GLOBAL, &Globals.bAllowTrustedDomains,NULL, NULL, 0},
- {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL|FLAG_DEPRECATED},
- {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
- {"min passwd length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0},
- {"min password length", P_INTEGER, P_GLOBAL, &Globals.min_passwd_length, NULL, NULL, 0},
+ {"server schannel", P_ENUM, P_GLOBAL, &Globals.bServerSChannel, NULL, enum_bool_auto, FLAG_BASIC},
+ {"client schannel", P_ENUM, P_GLOBAL, &Globals.bClientSChannel, NULL, enum_bool_auto, FLAG_BASIC},
+ {"server ntlmv2", P_ENUM, P_GLOBAL, &Globals.bServerNTLMv2, NULL, enum_bool_auto, FLAG_BASIC},
+ {"client ntlmv2", P_ENUM, P_GLOBAL, &Globals.bClientNTLMv2, NULL, enum_bool_auto, FLAG_BASIC},
+ {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
{"map to guest", P_ENUM, P_GLOBAL, &Globals.map_to_guest, NULL, enum_map_to_guest, 0},
{"null passwords", P_BOOL, P_GLOBAL, &Globals.bNullPasswords, NULL, NULL, 0},
{"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, 0},
{"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, 0},
+ {"sam directory", P_STRING, P_GLOBAL, &Globals.szSAMDirectory, NULL, NULL, 0},
+#if USE_SMBFILE_DB
+ {"smb passgrp file", P_STRING, P_GLOBAL, &Globals.szSMBPassGroupFile, NULL, NULL, 0},
+#endif
+#if USE_SMBGROUP_DB
+ {"smb group file", P_STRING, P_GLOBAL, &Globals.szSMBGroupFile, NULL, NULL, 0},
+ {"smb alias file", P_STRING, P_GLOBAL, &Globals.szSMBAliasFile, NULL, NULL, 0},
+#endif
+ {"hosts equiv", P_STRING, P_GLOBAL, &Globals.szHostsEquiv, NULL, NULL, 0},
{"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
{"root dir", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
{"root", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, 0},
@@ -594,48 +577,43 @@ static struct parm_struct parm_table[] =
{"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL, NULL, 0},
{"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL, NULL, 0},
{"unix password sync", P_BOOL, P_GLOBAL, &Globals.bUnixPasswdSync, NULL, NULL, 0},
- {"restrict anonymous", P_BOOL, P_GLOBAL, &Globals.bRestrictAnonymous,NULL, NULL, 0},
- {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
- {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"dfs map", P_STRING, P_GLOBAL, &Globals.szDfsMap, NULL, NULL, 0},
+ {"alternate permissions",P_BOOL,P_LOCAL, &sDefault.bAlternatePerm, NULL, NULL, FLAG_GLOBAL|FLAG_DEPRECATED},
+ {"revalidate", P_BOOL, P_LOCAL, &sDefault.bRevalidate, NULL, NULL, FLAG_GLOBAL},
+ {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL},
{"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
{"users", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
- {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_GLOBAL},
- {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, FLAG_SHARE},
- {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, FLAG_SHARE},
+ {"guest account", P_STRING, P_LOCAL, &sDefault.szGuestaccount, NULL, NULL, FLAG_BASIC|FLAG_PRINT|FLAG_GLOBAL},
+ {"invalid users", P_STRING, P_LOCAL, &sDefault.szInvalidUsers, NULL, NULL, FLAG_GLOBAL},
+ {"valid users", P_STRING, P_LOCAL, &sDefault.szValidUsers, NULL, NULL, FLAG_GLOBAL},
+ {"admin users", P_STRING, P_LOCAL, &sDefault.szAdminUsers, NULL, NULL, FLAG_GLOBAL},
+ {"read list", P_STRING, P_LOCAL, &sDefault.readlist, NULL, NULL, FLAG_GLOBAL},
+ {"write list", P_STRING, P_LOCAL, &sDefault.writelist, NULL, NULL, FLAG_GLOBAL},
+ {"force user", P_STRING, P_LOCAL, &sDefault.force_user, NULL, NULL, 0},
+ {"force group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
{"group", P_STRING, P_LOCAL, &sDefault.force_group, NULL, NULL, 0},
- {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC|FLAG_SHARE},
+ {"read only", P_BOOL, P_LOCAL, &sDefault.bRead_only, NULL, NULL, FLAG_BASIC},
{"write ok", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
{"writeable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
{"writable", P_BOOLREV, P_LOCAL, &sDefault.bRead_only, NULL, NULL, 0},
- {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"create mask", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
{"create mode", P_OCTAL, P_LOCAL, &sDefault.iCreate_mask, NULL, NULL, FLAG_GLOBAL},
- {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"security mask", P_OCTAL, P_LOCAL, &sDefault.iSecurity_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"force security mode",P_OCTAL, P_LOCAL, &sDefault.iSecurity_force_mode,NULL,NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
+ {"force create mode",P_OCTAL, P_LOCAL, &sDefault.iCreate_force_mode, NULL, NULL, FLAG_GLOBAL},
+ {"directory mask", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
{"directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_mask, NULL, NULL, FLAG_GLOBAL},
- {"force directory mode", P_OCTAL,P_LOCAL,&sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"directory security mask",P_OCTAL,P_LOCAL,&sDefault.iDir_Security_mask,NULL, NULL, FLAG_GLOBAL|FLAG_SHARE},
- {"force directory security mode",P_OCTAL, P_LOCAL, &sDefault.iDir_Security_force_mode,NULL,NULL,FLAG_GLOBAL|FLAG_SHARE},
- {"inherit permissions",P_BOOL, P_LOCAL, &sDefault.bInheritPerms, NULL, NULL, FLAG_SHARE},
- {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, FLAG_SHARE},
+ {"force directory mode", P_OCTAL, P_LOCAL, &sDefault.iDir_force_mode, NULL, NULL, FLAG_GLOBAL},
+ {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
{"only guest", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL, NULL, 0},
- {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
+ {"guest ok", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, FLAG_BASIC|FLAG_PRINT},
{"public", P_BOOL, P_LOCAL, &sDefault.bGuest_ok, NULL, NULL, 0},
- {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, FLAG_SHARE},
- {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
+ {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL, NULL, 0},
+ {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
{"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL, NULL, 0},
- {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
+ {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, FLAG_GLOBAL|FLAG_BASIC|FLAG_PRINT},
{"deny hosts", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL, NULL, 0},
-
#ifdef WITH_SSL
{"Secure Socket Layer Options", P_SEP, P_SEPARATOR},
+
{"ssl", P_BOOL, P_GLOBAL, &Globals.sslEnabled, NULL, NULL, 0 },
{"ssl hosts", P_STRING, P_GLOBAL, &Globals.sslHostsRequire, NULL, NULL, 0 },
{"ssl hosts resign", P_STRING, P_GLOBAL, &Globals.sslHostsResign, NULL, NULL, 0} ,
@@ -653,6 +631,7 @@ static struct parm_struct parm_table[] =
#endif /* WITH_SSL */
{"Logging Options", P_SEP, P_SEPARATOR},
+
{"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
{"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
{"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
@@ -661,175 +640,185 @@ static struct parm_struct parm_table[] =
{"max log size", P_INTEGER, P_GLOBAL, &Globals.max_log_size, NULL, NULL, 0},
{"timestamp logs", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
{"debug timestamp", P_BOOL, P_GLOBAL, &Globals.bTimestampLogs, NULL, NULL, 0},
- {"debug hires timestamp", P_BOOL, P_GLOBAL, &Globals.bDebugHiresTimestamp, NULL, NULL, 0},
- {"debug pid", P_BOOL, P_GLOBAL, &Globals.bDebugPid, NULL, NULL, 0},
- {"debug uid", P_BOOL, P_GLOBAL, &Globals.bDebugUid, NULL, NULL, 0},
- {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL|FLAG_SHARE|FLAG_PRINT},
+ {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL, NULL, FLAG_GLOBAL},
{"Protocol Options", P_SEP, P_SEPARATOR},
+
{"protocol", P_ENUM, P_GLOBAL, &Globals.maxprotocol, NULL, enum_protocol, 0},
{"read bmpx", P_BOOL, P_GLOBAL, &Globals.bReadbmpx, NULL, NULL, 0},
{"read raw", P_BOOL, P_GLOBAL, &Globals.bReadRaw, NULL, NULL, 0},
{"write raw", P_BOOL, P_GLOBAL, &Globals.bWriteRaw, NULL, NULL, 0},
- {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0},
- {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0},
- {"nt acl support", P_BOOL, P_GLOBAL, &Globals.bNTAclSupport, NULL, NULL, 0},
+ {"nt smb support", P_BOOL, P_GLOBAL, &Globals.bNTSmbSupport, NULL, NULL, 0},
+ {"nt pipe support", P_BOOL, P_GLOBAL, &Globals.bNTPipeSupport, NULL, NULL, 0},
{"announce version", P_STRING, P_GLOBAL, &Globals.szAnnounceVersion, NULL, NULL, 0},
{"announce as", P_ENUM, P_GLOBAL, &Globals.announce_as, NULL, enum_announce_as, 0},
{"max mux", P_INTEGER, P_GLOBAL, &Globals.max_mux, NULL, NULL, 0},
{"max xmit", P_INTEGER, P_GLOBAL, &Globals.max_xmit, NULL, NULL, 0},
- {"name resolve order",P_STRING, P_GLOBAL, &Globals.szNameResolveOrder,NULL, NULL, 0},
+ {"name resolve order", P_STRING, P_GLOBAL, &Globals.szNameResolveOrder, NULL, NULL, 0},
{"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
{"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL, NULL, 0},
{"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL, NULL, 0},
{"max wins ttl", P_INTEGER, P_GLOBAL, &Globals.max_wins_ttl, NULL, NULL, 0},
{"min wins ttl", P_INTEGER, P_GLOBAL, &Globals.min_wins_ttl, NULL, NULL, 0},
- {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
+ {"time server", P_BOOL, P_GLOBAL, &Globals.bTimeServer, NULL, NULL, 0},
{"Tuning Options", P_SEP, P_SEPARATOR},
+
{"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0},
{"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0},
{"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0},
{"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
{"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
- {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
+ {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0},
{"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
{"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0},
- {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, FLAG_PRINT},
+ {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0},
{"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0},
{"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0},
{"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0},
{"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0},
{"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0},
- {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, FLAG_SHARE},
- {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, FLAG_SHARE},
- {"write cache size", P_INTEGER, P_LOCAL, &sDefault.iWriteCacheSize, NULL, NULL, FLAG_SHARE},
+ {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, 0},
+ {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0},
{"Printing Options", P_SEP, P_SEPARATOR},
- {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, FLAG_PRINT},
- {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, FLAG_PRINT},
+
+ {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0},
+ {"printcap name", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
{"printcap", P_STRING, P_GLOBAL, &Globals.szPrintcapname, NULL, NULL, 0},
- {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, FLAG_PRINT},
- {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, FLAG_PRINT},
+ {"printer driver file", P_STRING, P_GLOBAL, &Globals.szDriverFile, NULL, NULL, 0},
{"print ok", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
+ {"printable", P_BOOL, P_LOCAL, &sDefault.bPrint_ok, NULL, NULL, 0},
{"postscript", P_BOOL, P_LOCAL, &sDefault.bPostscript, NULL, NULL, FLAG_PRINT},
{"printing", P_ENUM, P_LOCAL, &sDefault.iPrinting, NULL, enum_printing, FLAG_PRINT|FLAG_GLOBAL},
{"print command", P_STRING, P_LOCAL, &sDefault.szPrintcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
{"lpq command", P_STRING, P_LOCAL, &sDefault.szLpqcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
{"lprm command", P_STRING, P_LOCAL, &sDefault.szLprmcommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
- {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
- {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
- {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
- {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
+ {"lppause command", P_STRING, P_LOCAL, &sDefault.szLppausecommand, NULL, NULL, FLAG_GLOBAL},
+ {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL, NULL, FLAG_GLOBAL},
+ {"queuepause command", P_STRING, P_LOCAL, &sDefault.szQueuepausecommand, NULL, NULL, FLAG_GLOBAL},
+ {"queueresume command", P_STRING, P_LOCAL, &sDefault.szQueueresumecommand, NULL, NULL, FLAG_GLOBAL},
{"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, FLAG_PRINT},
{"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0},
- {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT},
- {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL},
+ {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, 0},
+ {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_GLOBAL},
{"nt forms file", P_STRING, P_GLOBAL, &Globals.szNtForms, NULL, NULL, FLAG_GLOBAL},
{"nt printer driver",P_STRING, P_GLOBAL, &Globals.szNtDriverFile, NULL, NULL, FLAG_GLOBAL},
-
{"Filename Handling", P_SEP, P_SEPARATOR},
{"strip dot", P_BOOL, P_GLOBAL, &Globals.bStripDot, NULL, NULL, 0},
{"character set", P_STRING, P_GLOBAL, &Globals.szCharacterSet, handle_character_set, NULL, 0},
{"mangled stack", P_INTEGER, P_GLOBAL, &Globals.mangled_stack, NULL, NULL, 0},
- {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, FLAG_SHARE},
- {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"coding system", P_STRING, P_GLOBAL, &Globals.szCodingSystem, handle_coding_system, NULL, 0},
+ {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL, NULL, 0},
+ {"default case", P_ENUM, P_LOCAL, &sDefault.iDefaultCase, NULL, enum_case, 0},
+ {"case sensitive", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, FLAG_GLOBAL},
{"casesignames", P_BOOL, P_LOCAL, &sDefault.bCaseSensitive, NULL, NULL, 0},
- {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING},
- {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING},
- {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_SHARE|FLAG_GLOBAL|FLAG_DOS_STRING},
- {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"preserve case", P_BOOL, P_LOCAL, &sDefault.bCasePreserve, NULL, NULL, FLAG_GLOBAL},
+ {"short preserve case",P_BOOL, P_LOCAL, &sDefault.bShortCasePreserve,NULL, NULL, FLAG_GLOBAL},
+ {"mangle case", P_BOOL, P_LOCAL, &sDefault.bCaseMangle, NULL, NULL, FLAG_GLOBAL},
+ {"mangling char", P_CHAR, P_LOCAL, &sDefault.magic_char, NULL, NULL, FLAG_GLOBAL},
+ {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL, NULL, FLAG_GLOBAL},
+ {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL, NULL, FLAG_GLOBAL},
+ {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL, NULL, FLAG_GLOBAL},
+ {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL, NULL, FLAG_GLOBAL},
+ {"veto oplock files",P_STRING, P_LOCAL, &sDefault.szVetoOplockFiles,NULL, NULL, FLAG_GLOBAL},
+ {"map system", P_BOOL, P_LOCAL, &sDefault.bMap_system, NULL, NULL, FLAG_GLOBAL},
+ {"map hidden", P_BOOL, P_LOCAL, &sDefault.bMap_hidden, NULL, NULL, FLAG_GLOBAL},
+ {"map archive", P_BOOL, P_LOCAL, &sDefault.bMap_archive, NULL, NULL, FLAG_GLOBAL},
+ {"mangled names", P_BOOL, P_LOCAL, &sDefault.bMangledNames, NULL, NULL, FLAG_GLOBAL},
+ {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL, NULL, FLAG_GLOBAL},
{"stat cache", P_BOOL, P_GLOBAL, &Globals.bStatCache, NULL, NULL, 0},
{"Domain Options", P_SEP, P_SEPARATOR},
- {"domain groups", P_STRING, P_GLOBAL, &Globals.szDomainGroups, NULL, NULL, 0},
- {"domain admin group",P_STRING, P_GLOBAL, &Globals.szDomainAdminGroup, NULL, NULL, 0},
- {"domain guest group",P_STRING, P_GLOBAL, &Globals.szDomainGuestGroup, NULL, NULL, 0},
- {"domain admin users",P_STRING, P_GLOBAL, &Globals.szDomainAdminUsers, NULL, NULL, 0},
- {"domain guest users",P_STRING, P_GLOBAL, &Globals.szDomainGuestUsers, NULL, NULL, 0},
-#ifdef USING_GROUPNAME_MAP
- {"groupname map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0},
-#endif /* USING_GROUPNAME_MAP */
+
+ {"trusted domains", P_STRING, P_GLOBAL, &Globals.szTrustedDomains, NULL, NULL, 0},
+ {"trusting domains", P_STRING, P_GLOBAL, &Globals.szTrustingDomains, NULL, NULL, 0},
+ {"local group map", P_STRING, P_GLOBAL, &Globals.szAliasnameMap, NULL, NULL, 0},
+ {"domain alias map", P_STRING, P_GLOBAL, &Globals.szAliasnameMap, NULL, NULL, 0},
+ {"domain group map", P_STRING, P_GLOBAL, &Globals.szGroupnameMap, NULL, NULL, 0},
+ {"builtin group map", P_STRING, P_GLOBAL, &Globals.szBuiltinnameMap, NULL, NULL, 0},
+ {"domain builtin map", P_STRING, P_GLOBAL, &Globals.szBuiltinnameMap, NULL, NULL, 0},
+ {"builtin rid file", P_STRING, P_GLOBAL, &Globals.szBuiltinRidFile, NULL, NULL, 0},
+ {"domain user map", P_STRING, P_GLOBAL, &Globals.szNTusernameMap, NULL, NULL, 0},
{"machine password timeout", P_INTEGER, P_GLOBAL, &Globals.machine_password_timeout, NULL, NULL, 0},
{"Logon Options", P_SEP, P_SEPARATOR},
- {"add user script", P_STRING, P_GLOBAL, &Globals.szAddUserScript, NULL, NULL, 0},
- {"delete user script",P_STRING, P_GLOBAL, &Globals.szDelUserScript, NULL, NULL, 0},
- {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, FLAG_DOS_STRING},
- {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, FLAG_DOS_STRING},
+
+ {"logon script", P_STRING, P_GLOBAL, &Globals.szLogonScript, NULL, NULL, 0},
+ {"logon path", P_STRING, P_GLOBAL, &Globals.szLogonPath, NULL, NULL, 0},
{"logon drive", P_STRING, P_GLOBAL, &Globals.szLogonDrive, NULL, NULL, 0},
- {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, FLAG_DOS_STRING},
+ {"logon home", P_STRING, P_GLOBAL, &Globals.szLogonHome, NULL, NULL, 0},
{"domain logons", P_BOOL, P_GLOBAL, &Globals.bDomainLogons, NULL, NULL, 0},
{"Browse Options", P_SEP, P_SEPARATOR},
+
{"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL, NULL, FLAG_BASIC},
- {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_lm_announce, 0},
+ {"lm announce", P_ENUM, P_GLOBAL, &Globals.lm_announce, NULL, enum_bool_auto, 0},
{"lm interval", P_INTEGER, P_GLOBAL, &Globals.lm_interval, NULL, NULL, 0},
- {"preferred master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, FLAG_BASIC},
- {"prefered master", P_BOOL, P_GLOBAL, &Globals.bPreferredMaster, NULL, NULL, 0},
+ {"preferred master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_BASIC},
+ {"prefered master", P_ENUM, P_GLOBAL, &Globals.bPreferredMaster, NULL, enum_bool_auto, FLAG_HIDE},
{"local master", P_BOOL, P_GLOBAL, &Globals.bLocalMaster, NULL, NULL, FLAG_BASIC},
- {"domain master", P_BOOL, P_GLOBAL, &Globals.bDomainMaster, NULL, NULL, FLAG_BASIC},
+ {"domain master", P_ENUM, P_GLOBAL, &Globals.bDomainMaster, NULL, enum_bool_auto, FLAG_BASIC},
{"browse list", P_BOOL, P_GLOBAL, &Globals.bBrowseList, NULL, NULL, 0},
- {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
+ {"browseable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
{"browsable", P_BOOL, P_LOCAL, &sDefault.bBrowseable, NULL, NULL, 0},
{"WINS Options", P_SEP, P_SEPARATOR},
+
{"dns proxy", P_BOOL, P_GLOBAL, &Globals.bDNSproxy, NULL, NULL, 0},
{"wins proxy", P_BOOL, P_GLOBAL, &Globals.bWINSproxy, NULL, NULL, 0},
{"wins server", P_STRING, P_GLOBAL, &Globals.szWINSserver, NULL, NULL, FLAG_BASIC},
{"wins support", P_BOOL, P_GLOBAL, &Globals.bWINSsupport, NULL, NULL, FLAG_BASIC},
- {"wins hook", P_STRING, P_GLOBAL, &Globals.szWINSHook, NULL, NULL, 0},
{"Locking Options", P_SEP, P_SEPARATOR},
- {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, FLAG_SHARE},
+
+ {"blocking locks", P_BOOL, P_LOCAL, &sDefault.bBlockingLocks, NULL, NULL, 0},
+ {"fake oplocks", P_BOOL, P_LOCAL, &sDefault.bFakeOplocks, NULL, NULL, 0},
{"kernel oplocks", P_BOOL, P_GLOBAL, &Globals.bKernelOplocks, NULL, NULL, FLAG_GLOBAL},
- {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
-#ifdef WITH_UTMP
- {"utmp", P_BOOL, P_LOCAL, &sDefault.bUtmp, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
-#endif
+ {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL, NULL, FLAG_GLOBAL},
{"ole locking compatibility", P_BOOL, P_GLOBAL, &Globals.bOleLockingCompat, NULL, NULL, FLAG_GLOBAL},
- {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"level2 oplocks", P_BOOL, P_LOCAL, &sDefault.bLevel2OpLocks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"oplock break wait time",P_INTEGER,P_GLOBAL,&Globals.oplock_break_wait_time,NULL,NULL,FLAG_GLOBAL},
- {"oplock contention limit",P_INTEGER,P_LOCAL,&sDefault.iOplockContentionLimit,NULL,NULL,FLAG_SHARE|FLAG_GLOBAL},
- {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
-
-#ifdef WITH_LDAP
+ {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL, NULL, FLAG_GLOBAL},
+ {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL, NULL, FLAG_GLOBAL},
+ {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL, NULL, FLAG_GLOBAL},
+
+#if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
{"Ldap Options", P_SEP, P_SEPARATOR},
+
{"ldap server", P_STRING, P_GLOBAL, &Globals.szLdapServer, NULL, NULL, 0},
{"ldap port", P_INTEGER, P_GLOBAL, &Globals.ldap_port, NULL, NULL, 0},
{"ldap suffix", P_STRING, P_GLOBAL, &Globals.szLdapSuffix, NULL, NULL, 0},
- {"ldap filter", P_STRING, P_GLOBAL, &Globals.szLdapFilter, NULL, NULL, 0},
- {"ldap root", P_STRING, P_GLOBAL, &Globals.szLdapRoot, NULL, NULL, 0},
- {"ldap root passwd", P_STRING, P_GLOBAL, &Globals.szLdapRootPassword,NULL, NULL, 0},
+ {"ldap bind as", P_STRING, P_GLOBAL, &Globals.szLdapBindAs, NULL, NULL, 0},
+ {"ldap passwd file", P_STRING, P_GLOBAL, &Globals.szLdapPasswdFile, NULL, NULL, 0},
#endif /* WITH_LDAP */
+#ifdef WITH_NT5LDAP
+ {"ldap realm", P_STRING, P_GLOBAL, &Globals.szLdapRealm, NULL, NULL, 0},
+ {"ldap protocol version", P_INTEGER, P_GLOBAL, &Globals.ldap_protocol_version, NULL, NULL, 0},
+ {"ldap url", P_STRING, P_GLOBAL, &Globals.szLdapUrl, NULL, NULL, 0},
+ {"ldap users subcontext", P_STRING, P_GLOBAL, &Globals.szLdapComputersSubcontext, NULL, NULL, 0},
+ {"ldap builtin subcontext", P_STRING, P_GLOBAL, &Globals.szLdapUsersSubcontext, NULL, NULL, 0},
+ {"ldap computers subcontext", P_STRING, P_GLOBAL, &Globals.szLdapBuiltinSubcontext, NULL, NULL, 0},
+#endif /* WITH_NT5LDAP */
+
+#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
+ {"MySQL Options", P_SEP, P_SEPARATOR},
+ {"mysql host", P_STRING, P_GLOBAL, &Globals.sMysqlHost, NULL, NULL, 0},
+ {"mysql user", P_STRING, P_GLOBAL, &Globals.sMysqlUser, NULL, NULL, 0},
+ {"mysql pass file", P_STRING, P_GLOBAL, &Globals.sMysqlPassFile, NULL, NULL, 0},
+ {"mysql database", P_STRING, P_GLOBAL, &Globals.sMysqlDatabase, NULL, NULL, 0},
+ {"mysql table", P_STRING, P_GLOBAL, &Globals.sMysqlTable, NULL, NULL, 0},
+#endif /* MYSQL */
{"Miscellaneous Options", P_SEP, P_SEPARATOR},
+
{"smbrun", P_STRING, P_GLOBAL, &Globals.szSmbrun, NULL, NULL, 0},
{"config file", P_STRING, P_GLOBAL, &Globals.szConfigFile, NULL, NULL, FLAG_HIDE},
{"preload", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
{"auto services", P_STRING, P_GLOBAL, &Globals.szAutoServices, NULL, NULL, 0},
{"lock dir", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
{"lock directory", P_STRING, P_GLOBAL, &Globals.szLockDir, NULL, NULL, 0},
-#ifdef WITH_UTMP
- {"utmp dir", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
- {"utmp directory", P_STRING, P_GLOBAL, &Globals.szUtmpDir, NULL, NULL, 0},
-#endif /* WITH_UTMP */
{"default service", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
{"default", P_STRING, P_GLOBAL, &Globals.szDefaultService, NULL, NULL, 0},
{"message command", P_STRING, P_GLOBAL, &Globals.szMsgCommand, NULL, NULL, 0},
@@ -845,34 +834,31 @@ static struct parm_struct parm_table[] =
{"-valid", P_BOOL, P_LOCAL, &sDefault.valid, NULL, NULL, FLAG_HIDE},
{"copy", P_STRING, P_LOCAL, &sDefault.szCopy, handle_copy, NULL, FLAG_HIDE},
{"include", P_STRING, P_LOCAL, &sDefault.szInclude, handle_include, NULL, FLAG_HIDE},
- {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT},
+ {"exec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
{"preexec", P_STRING, P_LOCAL, &sDefault.szPreExec, NULL, NULL, 0},
- {"preexec close", P_BOOL, P_LOCAL, &sDefault.bPreexecClose, NULL, NULL, FLAG_SHARE},
- {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT},
- {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT},
- {"root preexec close", P_BOOL, P_LOCAL, &sDefault.bRootpreexecClose,NULL, NULL, FLAG_SHARE},
- {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, FLAG_SHARE|FLAG_PRINT},
- {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT},
- {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE},
- {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE},
- {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE},
- {"source environment",P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env,NULL,0},
- {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE},
- {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, FLAG_SHARE},
- {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, FLAG_SHARE},
- {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
- {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"postexec", P_STRING, P_LOCAL, &sDefault.szPostExec, NULL, NULL, 0},
+ {"root preexec", P_STRING, P_LOCAL, &sDefault.szRootPreExec, NULL, NULL, 0},
+ {"root postexec", P_STRING, P_LOCAL, &sDefault.szRootPostExec, NULL, NULL, 0},
+ {"available", P_BOOL, P_LOCAL, &sDefault.bAvailable, NULL, NULL, 0},
+ {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, 0},
+ {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, 0},
+ {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, 0},
+ {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_GLOBAL},
+ {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_GLOBAL},
+ {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, 0},
+ {"magic script", P_STRING, P_LOCAL, &sDefault.szMagicScript, NULL, NULL, 0},
+ {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL, NULL, 0},
+ {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL, NULL, FLAG_GLOBAL},
+ {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL, NULL, FLAG_GLOBAL},
+ {"dos filetime resolution",P_BOOL,P_LOCAL,&sDefault.bDosFiletimeResolution, NULL, NULL, FLAG_GLOBAL},
- {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL},
+ {"fake directory create times", P_BOOL,P_LOCAL, &sDefault.bFakeDirCreateTimes, NULL, NULL, FLAG_GLOBAL},
{"panic action", P_STRING, P_GLOBAL, &Globals.szPanicAction, NULL, NULL, 0},
{"VFS options", P_SEP, P_SEPARATOR},
- {"vfs object", P_STRING, P_LOCAL, &sDefault.szVfsObjectFile, handle_vfs_object, NULL, 0},
- {"vfs options", P_STRING, P_LOCAL, &sDefault.szVfsOptions, NULL, NULL, 0},
+ {"vfs object", P_STRING, P_LOCAL, &sDefault.vfsObjectFile, handle_vfs_object, NULL, 0},
+ {"vfs option", P_PTR, P_LOCAL, &sDefault.vfsOptions, handle_vfs_option, NULL, 0},
{NULL, P_BOOL, P_NONE, NULL, NULL, NULL, 0}
};
@@ -889,13 +875,13 @@ static void init_globals(void)
if (!done_init)
{
int i;
- memset((void *)&Globals,'\0',sizeof(Globals));
+ bzero((void *)&Globals,sizeof(Globals));
for (i = 0; parm_table[i].label; i++)
if ((parm_table[i].type == P_STRING ||
parm_table[i].type == P_USTRING) &&
parm_table[i].ptr)
- string_set(parm_table[i].ptr,"");
+ string_init(parm_table[i].ptr,"");
string_set(&sDefault.szGuestaccount, GUEST_ACCOUNT);
string_set(&sDefault.szPrinterDriver, "NULL");
@@ -908,10 +894,15 @@ static void init_globals(void)
DEBUG(3,("Initialising global parameters\n"));
string_set(&Globals.szSMBPasswdFile, SMB_PASSWD_FILE);
- /*
- * Allow the default PASSWD_CHAT to be overridden in local.h.
- */
- string_set(&Globals.szPasswdChat,DEFAULT_PASSWD_CHAT);
+ string_set(&Globals.szSAMDirectory, SAM_DIR);
+#if USE_SMBFILE_DB
+ string_set(&Globals.szSMBPassGroupFile, SMB_PASSGRP_FILE);
+#endif
+#if USE_SMBGROUP_DB
+ string_set(&Globals.szSMBGroupFile, SMB_GROUP_FILE);
+ string_set(&Globals.szSMBAliasFile, SMB_ALIAS_FILE);
+#endif
+ string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*");
string_set(&Globals.szWorkGroup, WORKGROUP);
string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM);
string_set(&Globals.szPrintcapname, PRINTCAP_NAME);
@@ -920,9 +911,6 @@ static void init_globals(void)
string_set(&Globals.szNtDriverFile, NTDRIVERSDIR);
string_set(&Globals.szLockDir, LOCKDIR);
string_set(&Globals.szRootdir, "/");
-#ifdef WITH_UTMP
- string_set(&Globals.szUtmpDir, "");
-#endif /* WITH_UTMP */
string_set(&Globals.szSmbrun, SMBRUN);
string_set(&Globals.szSocketAddress, "0.0.0.0");
pstrcpy(s, "Samba ");
@@ -959,15 +947,13 @@ static void init_globals(void)
Globals.bReadRaw = True;
Globals.bWriteRaw = True;
Globals.bReadPrediction = False;
- Globals.bReadbmpx = False;
+ Globals.bReadbmpx = True;
Globals.bNullPasswords = False;
Globals.bStripDot = False;
Globals.syslog = 1;
Globals.bSyslogOnly = False;
- Globals.bTimestampLogs = True;
- Globals.bDebugHiresTimestamp = False;
- Globals.bDebugPid = False;
- Globals.bDebugUid = False;
+ Globals.bTimestampLogs = False;
+ Globals.os_level = 32;
Globals.max_ttl = 60*60*24*3; /* 3 days default. */
Globals.max_wins_ttl = 60*60*24*6; /* 6 days default. */
Globals.min_wins_ttl = 60*60*6; /* 6 hours default. */
@@ -978,7 +964,7 @@ static void init_globals(void)
Globals.lm_interval = 60;
Globals.shmem_size = SHMEM_SIZE;
Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */
- Globals.announce_as = ANNOUNCE_AS_NT_SERVER;
+ Globals.announce_as = ANNOUNCE_AS_NT;
Globals.bUnixRealname = False;
#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
Globals.bNISHomeMap = False;
@@ -996,36 +982,56 @@ static void init_globals(void)
Globals.bOleLockingCompat = True;
Globals.bNTSmbSupport = True; /* Do NT SMB's by default. */
Globals.bNTPipeSupport = True; /* Do NT pipes by default. */
- Globals.bNTAclSupport = True; /* Use NT ACLs by default. */
Globals.bStatCache = True; /* use stat cache by default */
- Globals.bRestrictAnonymous = False;
Globals.map_to_guest = 0; /* By Default, "Never" */
- Globals.min_passwd_length = MINPASSWDLENGTH; /* By Default, 5. */
- Globals.oplock_break_wait_time = 10; /* By Default, 10 msecs. */
-#ifdef WITH_LDAP
+#if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
/* default values for ldap */
string_set(&Globals.szLdapServer, "localhost");
Globals.ldap_port=389;
+ Globals.ldap_protocol_version=LDAP_VERSION2;
#endif /* WITH_LDAP */
+#ifdef WITH_NT5LDAP
+ string_set(&Globals.szLdapUrl, NULL);
+ string_set(&Globals.szLdapRealm, NULL);
+ string_set(&Globals.szLdapComputersSubcontext, "cn=computers,");
+ string_set(&Globals.szLdapBuiltinSubcontext, "cn=builtin,");
+ string_set(&Globals.szLdapUsersSubcontext, "cn=users,");
+#endif /* WITH_NT5LDAP */
+
#ifdef WITH_SSL
Globals.sslVersion = SMB_SSL_V23;
- string_set(&Globals.sslHostsRequire, "");
- string_set(&Globals.sslHostsResign, "");
- string_set(&Globals.sslCaCertDir, "");
- string_set(&Globals.sslCaCertFile, "");
- string_set(&Globals.sslCert, "");
- string_set(&Globals.sslPrivKey, "");
- string_set(&Globals.sslClientCert, "");
- string_set(&Globals.sslClientPrivKey, "");
- string_set(&Globals.sslCiphers, "");
+
+ /*
+ * Most of the next variables should be string_set!
+ */
+
+ string_set(&Globals.sslHostsRequire, NULL);
+ string_set(&Globals.sslHostsResign, NULL);
+ string_set(&Globals.sslCaCertDir, NULL);
+ string_set(&Globals.sslCaCertFile, NULL);
+ string_set(&Globals.sslCert, NULL);
+ string_set(&Globals.sslPrivKey, NULL);
+ string_set(&Globals.sslClientCert, NULL);
+ string_set(&Globals.sslClientPrivKey, NULL);
+ string_set(&Globals.sslCiphers, NULL);
Globals.sslEnabled = False;
Globals.sslReqClientCert = False;
Globals.sslReqServerCert = False;
Globals.sslCompatibility = False;
#endif /* WITH_SSL */
+/* NETLOGON Secure Channel */
+
+ Globals.bClientSChannel = Auto;
+ Globals.bServerSChannel = False;
+
+/* NTLMv2 */
+
+ Globals.bClientNTLMv2 = False;
+ Globals.bServerNTLMv2 = Auto;
+
/* these parameters are set to defaults that are more appropriate
for the increasing samba install base:
@@ -1038,10 +1044,9 @@ static void init_globals(void)
*/
- Globals.os_level = 20;
- Globals.bPreferredMaster = False;
+ Globals.bPreferredMaster = Auto; /* depending on bDomainMaster */
Globals.bLocalMaster = True;
- Globals.bDomainMaster = False;
+ Globals.bDomainMaster = Auto; /* depending on bDomainLogons */
Globals.bDomainLogons = False;
Globals.bBrowseList = True;
Globals.bWINSsupport = False;
@@ -1055,7 +1060,13 @@ static void init_globals(void)
*/
Globals.bKernelOplocks = True;
- Globals.bAllowTrustedDomains = True;
+#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
+ string_set(&Globals.sMysqlHost,"localhost");
+ string_set(&Globals.sMysqlUser,"root");
+ string_set(&Globals.sMysqlPassFile,NULL);
+ string_set(&Globals.sMysqlDatabase,"samba");
+ string_set(&Globals.sMysqlTable,"smbpasswd");
+#endif
/*
* This must be done last as it checks the value in
@@ -1066,6 +1077,16 @@ static void init_globals(void)
}
/***************************************************************************
+check if a string is initialised and if not then initialise it
+***************************************************************************/
+static void string_initial(char **s,char *v)
+{
+ if (!*s || !**s)
+ string_init(s,v);
+}
+
+
+/***************************************************************************
Initialise the sDefault parameter structure.
***************************************************************************/
static void init_locals(void)
@@ -1075,88 +1096,154 @@ static void init_locals(void)
{
case PRINT_BSD:
case PRINT_AIX:
- case PRINT_LPRNG:
case PRINT_PLP:
- string_set(&sDefault.szLpqcommand,"lpq -P%p");
- string_set(&sDefault.szLprmcommand,"lprm -P%p %j");
- string_set(&sDefault.szPrintcommand,"lpr -r -P%p %s");
+ string_initial(&sDefault.szLpqcommand,"lpq -P%p");
+ string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
+ string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
break;
-
- case PRINT_CUPS:
- string_set(&sDefault.szLpqcommand,"/usr/bin/lpstat -o%p");
- string_set(&sDefault.szLprmcommand,"/usr/bin/cancel %p-%j");
- string_set(&sDefault.szPrintcommand,"/usr/bin/lp -d%p -oraw %s; rm %s");
- string_set(&sDefault.szQueuepausecommand, "/usr/bin/disable %p");
- string_set(&sDefault.szQueueresumecommand, "/usr/bin/enable %p");
+
+ case PRINT_LPRNG:
+ string_initial(&sDefault.szLpqcommand,"lpq -P%p");
+ string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
+ string_initial(&sDefault.szPrintcommand,"lpr -r -P%p %s");
+ string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
+ string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
+ string_initial(&sDefault.szLppausecommand,"lpc hold %p %j");
+ string_initial(&sDefault.szLpresumecommand,"lpc release %p %j");
break;
case PRINT_SYSV:
case PRINT_HPUX:
- string_set(&sDefault.szLpqcommand,"lpstat -o%p");
- string_set(&sDefault.szLprmcommand,"cancel %p-%j");
- string_set(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
- string_set(&sDefault.szQueuepausecommand, "disable %p");
- string_set(&sDefault.szQueueresumecommand, "enable %p");
-#ifndef HPUX
- string_set(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
- string_set(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
+ string_initial(&sDefault.szLpqcommand,"lpstat -o%p");
+ string_initial(&sDefault.szLprmcommand,"cancel %p-%j");
+ string_initial(&sDefault.szPrintcommand,"lp -c -d%p %s; rm %s");
+#ifdef SYSV
+ string_initial(&sDefault.szLppausecommand,"lp -i %p-%j -H hold");
+ string_initial(&sDefault.szLpresumecommand,"lp -i %p-%j -H resume");
+ string_initial(&sDefault.szQueuepausecommand, "lpc stop %p");
+ string_initial(&sDefault.szQueueresumecommand, "lpc start %p");
+#else /* SYSV */
+ string_initial(&sDefault.szQueuepausecommand, "disable %p");
+ string_initial(&sDefault.szQueueresumecommand, "enable %p");
#endif /* SYSV */
break;
case PRINT_QNX:
- string_set(&sDefault.szLpqcommand,"lpq -P%p");
- string_set(&sDefault.szLprmcommand,"lprm -P%p %j");
- string_set(&sDefault.szPrintcommand,"lp -r -P%p %s");
+ string_initial(&sDefault.szLpqcommand,"lpq -P%p");
+ string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
+ string_initial(&sDefault.szPrintcommand,"lp -r -P%p %s");
break;
case PRINT_SOFTQ:
- string_set(&sDefault.szLpqcommand,"qstat -l -d%p");
- string_set(&sDefault.szLprmcommand,"qstat -s -j%j -c");
- string_set(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
- string_set(&sDefault.szLppausecommand,"qstat -s -j%j -h");
- string_set(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
+ string_initial(&sDefault.szLpqcommand,"qstat -l -d%p");
+ string_initial(&sDefault.szLprmcommand,"qstat -s -j%j -c");
+ string_initial(&sDefault.szPrintcommand,"lp -d%p -s %s; rm %s");
+ string_initial(&sDefault.szLppausecommand,"qstat -s -j%j -h");
+ string_initial(&sDefault.szLpresumecommand,"qstat -s -j%j -r");
break;
}
}
-static TALLOC_CTX *lp_talloc;
/******************************************************************* a
-free up temporary memory - called from the main loop
+convenience routine to grab string parameters into a rotating buffer,
+and run standard_sub_basic on them. The buffers can be written to by
+callers without affecting the source string.
********************************************************************/
-void lp_talloc_free(void)
+static char *lp_user_string(const user_struct *vuser, char *s)
{
- if (!lp_talloc) return;
- talloc_destroy(lp_talloc);
- lp_talloc = NULL;
+ static char *bufs[10];
+ static int buflen[10];
+ static int next = -1;
+ char *ret;
+ int i;
+ int len = s?strlen(s):0;
+
+ if (next == -1) {
+ /* initialisation */
+ for (i=0;i<10;i++) {
+ bufs[i] = NULL;
+ buflen[i] = 0;
+ }
+ next = 0;
+ }
+
+ len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
+ substitution room */
+
+ if (buflen[next] != len) {
+ buflen[next] = len;
+ if (bufs[next]) free(bufs[next]);
+ bufs[next] = (char *)malloc(len);
+ if (!bufs[next]) {
+ DEBUG(0,("out of memory in lp_string()"));
+ exit(1);
+ }
+ }
+
+ ret = &bufs[next][0];
+ next = (next+1)%10;
+
+ if (!s)
+ *ret = 0;
+ else
+ StrCpy(ret,s);
+
+ trim_string(ret, "\"", "\"");
+
+ standard_sub_vuser(vuser, ret);
+ return(ret);
}
-/*******************************************************************
-convenience routine to grab string parameters into temporary memory
+/******************************************************************* a
+convenience routine to grab string parameters into a rotating buffer,
and run standard_sub_basic on them. The buffers can be written to by
callers without affecting the source string.
********************************************************************/
-static char *lp_string(const char *s)
+static char *lp_string(char *s)
{
- size_t len = s?strlen(s):0;
- char *ret;
+ static char *bufs[10];
+ static int buflen[10];
+ static int next = -1;
+ char *ret;
+ int i;
+ int len = s?strlen(s):0;
- if (!lp_talloc) lp_talloc = talloc_init();
-
- ret = (char *)talloc(lp_talloc, len + 100); /* leave room for substitution */
+ if (next == -1) {
+ /* initialisation */
+ for (i=0;i<10;i++) {
+ bufs[i] = NULL;
+ buflen[i] = 0;
+ }
+ next = 0;
+ }
- if (!ret) return NULL;
+ len = MAX(len+100,sizeof(pstring)); /* the +100 is for some
+ substitution room */
- if (!s)
- *ret = 0;
- else
- StrnCpy(ret,s,len);
+ if (buflen[next] != len) {
+ buflen[next] = len;
+ if (bufs[next]) free(bufs[next]);
+ bufs[next] = (char *)malloc(len);
+ if (!bufs[next]) {
+ DEBUG(0,("out of memory in lp_string()"));
+ exit(1);
+ }
+ }
- trim_string(ret, "\"", "\"");
+ ret = &bufs[next][0];
+ next = (next+1)%10;
- standard_sub_basic(ret);
- return(ret);
+ if (!s)
+ *ret = 0;
+ else
+ StrCpy(ret,s);
+
+ trim_string(ret, "\"", "\"");
+
+ standard_sub_basic(ret);
+ return(ret);
}
@@ -1183,21 +1270,30 @@ static char *lp_string(const char *s)
#define FN_LOCAL_INTEGER(fn_name,val) \
int fn_name(int i) {return(LP_SNUM_OK(i)? pSERVICE(i)->val : sDefault.val);}
+#define FN_VUSER_STRING(fn_name,ptr) \
+ char *fn_name(const user_struct *usr) {return(lp_user_string(usr, *(char **)(ptr) ? *(char **)(ptr) : ""));}
+
+struct vfs_options *lp_vfsoptions(int i)
+{ return(LP_SNUM_OK(i) ? pSERVICE(i)->vfsOptions : sDefault.vfsOptions); }
+
FN_GLOBAL_STRING(lp_logfile,&Globals.szLogFile)
FN_GLOBAL_STRING(lp_smbrun,&Globals.szSmbrun)
FN_GLOBAL_STRING(lp_configfile,&Globals.szConfigFile)
FN_GLOBAL_STRING(lp_smb_passwd_file,&Globals.szSMBPasswdFile)
+FN_GLOBAL_STRING(lp_sam_directory,&Globals.szSAMDirectory)
+#if USE_SMBFILE_DB
+FN_GLOBAL_STRING(lp_smb_passgrp_file,&Globals.szSMBPassGroupFile)
+#endif
+#if USE_SMBGROUP_DB
+FN_GLOBAL_STRING(lp_smb_group_file,&Globals.szSMBGroupFile)
+FN_GLOBAL_STRING(lp_smb_alias_file,&Globals.szSMBAliasFile)
+#endif
FN_GLOBAL_STRING(lp_serverstring,&Globals.szServerString)
FN_GLOBAL_STRING(lp_printcapname,&Globals.szPrintcapname)
FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir)
-#ifdef WITH_UTMP
-FN_GLOBAL_STRING(lp_utmpdir,&Globals.szUtmpDir)
-#endif /* WITH_UTMP */
FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir)
-FN_GLOBAL_STRING(lp_source_environment,&Globals.szSourceEnv)
FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService)
FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand)
-FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree)
FN_GLOBAL_STRING(lp_hosts_equiv,&Globals.szHostsEquiv)
FN_GLOBAL_STRING(lp_auto_services,&Globals.szAutoServices)
FN_GLOBAL_STRING(lp_passwd_program,&Globals.szPasswdProgram)
@@ -1205,14 +1301,14 @@ FN_GLOBAL_STRING(lp_passwd_chat,&Globals.szPasswdChat)
FN_GLOBAL_STRING(lp_passwordserver,&Globals.szPasswordServer)
FN_GLOBAL_STRING(lp_name_resolve_order,&Globals.szNameResolveOrder)
FN_GLOBAL_STRING(lp_workgroup,&Globals.szWorkGroup)
+FN_GLOBAL_STRING(lp_trusted_domains,&Globals.szTrustedDomains)
+FN_GLOBAL_STRING(lp_trusting_domains,&Globals.szTrustingDomains)
FN_GLOBAL_STRING(lp_username_map,&Globals.szUsernameMap)
-#ifdef USING_GROUPNAME_MAP
+FN_GLOBAL_STRING(lp_aliasname_map,&Globals.szAliasnameMap)
FN_GLOBAL_STRING(lp_groupname_map,&Globals.szGroupnameMap)
-#endif /* USING_GROUPNAME_MAP */
-FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
-FN_GLOBAL_STRING(lp_logon_path,&Globals.szLogonPath)
-FN_GLOBAL_STRING(lp_logon_drive,&Globals.szLogonDrive)
-FN_GLOBAL_STRING(lp_logon_home,&Globals.szLogonHome)
+FN_GLOBAL_STRING(lp_builtinname_map,&Globals.szBuiltinnameMap)
+FN_GLOBAL_STRING(lp_builtinrid_file,&Globals.szBuiltinRidFile)
+FN_GLOBAL_STRING(lp_ntusrname_map,&Globals.szNTusernameMap)
FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce)
FN_GLOBAL_STRING(lp_remote_browse_sync,&Globals.szRemoteBrowseSync)
FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
@@ -1223,27 +1319,25 @@ static FN_GLOBAL_STRING(lp_announce_version,&Globals.szAnnounceVersion)
FN_GLOBAL_STRING(lp_netbios_aliases,&Globals.szNetbiosAliases)
FN_GLOBAL_STRING(lp_driverfile,&Globals.szDriverFile)
FN_GLOBAL_STRING(lp_panic_action,&Globals.szPanicAction)
-FN_GLOBAL_STRING(lp_adduser_script,&Globals.szAddUserScript)
-FN_GLOBAL_STRING(lp_deluser_script,&Globals.szDelUserScript)
-FN_GLOBAL_STRING(lp_wins_hook,&Globals.szWINSHook)
-
-FN_GLOBAL_STRING(lp_domain_groups,&Globals.szDomainGroups)
-FN_GLOBAL_STRING(lp_domain_admin_group,&Globals.szDomainAdminGroup)
-FN_GLOBAL_STRING(lp_domain_guest_group,&Globals.szDomainGuestGroup)
-FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers)
-FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers)
-
FN_GLOBAL_STRING(lp_nt_forms,&Globals.szNtForms)
FN_GLOBAL_STRING(lp_nt_drivers_file,&Globals.szNtDriverFile)
+FN_GLOBAL_STRING(lp_dfs_map,&Globals.szDfsMap)
-#ifdef WITH_LDAP
+#if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer);
FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix);
-FN_GLOBAL_STRING(lp_ldap_filter,&Globals.szLdapFilter);
-FN_GLOBAL_STRING(lp_ldap_root,&Globals.szLdapRoot);
-FN_GLOBAL_STRING(lp_ldap_rootpasswd,&Globals.szLdapRootPassword);
+FN_GLOBAL_STRING(lp_ldap_bind_as,&Globals.szLdapBindAs);
+FN_GLOBAL_STRING(lp_ldap_passwd_file,&Globals.szLdapPasswdFile);
#endif /* WITH_LDAP */
+#ifdef WITH_NT5LDAP
+FN_GLOBAL_STRING(lp_ldap_url,&Globals.szLdapUrl);
+FN_GLOBAL_STRING(lp_ldap_realm,&Globals.szLdapRealm);
+FN_GLOBAL_STRING(lp_ldap_computers_subcontext,&Globals.szLdapComputersSubcontext);
+FN_GLOBAL_STRING(lp_ldap_users_subcontext,&Globals.szLdapUsersSubcontext);
+FN_GLOBAL_STRING(lp_ldap_builtin_subcontext,&Globals.szLdapBuiltinSubcontext);
+#endif /* WITH_NT5LDAP */
+
#ifdef WITH_SSL
FN_GLOBAL_INTEGER(lp_ssl_version,&Globals.sslVersion);
FN_GLOBAL_STRING(lp_ssl_hosts,&Globals.sslHostsRequire);
@@ -1266,9 +1360,7 @@ FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
FN_GLOBAL_BOOL(lp_we_are_a_wins_server,&Globals.bWINSsupport)
FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
FN_GLOBAL_BOOL(lp_local_master,&Globals.bLocalMaster)
-FN_GLOBAL_BOOL(lp_domain_master,&Globals.bDomainMaster)
FN_GLOBAL_BOOL(lp_domain_logons,&Globals.bDomainLogons)
-FN_GLOBAL_BOOL(lp_preferred_master,&Globals.bPreferredMaster)
FN_GLOBAL_BOOL(lp_load_printers,&Globals.bLoadPrinters)
FN_GLOBAL_BOOL(lp_use_rhosts,&Globals.bUseRhosts)
FN_GLOBAL_BOOL(lp_readprediction,&Globals.bReadPrediction)
@@ -1279,11 +1371,12 @@ FN_GLOBAL_BOOL(lp_null_passwords,&Globals.bNullPasswords)
FN_GLOBAL_BOOL(lp_strip_dot,&Globals.bStripDot)
FN_GLOBAL_BOOL(lp_encrypted_passwords,&Globals.bEncryptPasswords)
FN_GLOBAL_BOOL(lp_update_encrypted,&Globals.bUpdateEncrypt)
+FN_GLOBAL_BOOL(lp_client_ntlmv2,&Globals.bClientNTLMv2)
+FN_GLOBAL_BOOL(lp_server_ntlmv2,&Globals.bServerNTLMv2)
+FN_GLOBAL_BOOL(lp_client_schannel,&Globals.bClientSChannel)
+FN_GLOBAL_BOOL(lp_server_schannel,&Globals.bServerSChannel)
FN_GLOBAL_BOOL(lp_syslog_only,&Globals.bSyslogOnly)
FN_GLOBAL_BOOL(lp_timestamp_logs,&Globals.bTimestampLogs)
-FN_GLOBAL_BOOL(lp_debug_hires_timestamp,&Globals.bDebugHiresTimestamp)
-FN_GLOBAL_BOOL(lp_debug_pid,&Globals.bDebugPid)
-FN_GLOBAL_BOOL(lp_debug_uid,&Globals.bDebugUid)
FN_GLOBAL_BOOL(lp_browse_list,&Globals.bBrowseList)
FN_GLOBAL_BOOL(lp_unix_realname,&Globals.bUnixRealname)
FN_GLOBAL_BOOL(lp_nis_home_map,&Globals.bNISHomeMap)
@@ -1294,10 +1387,7 @@ FN_GLOBAL_BOOL(lp_passwd_chat_debug,&Globals.bPasswdChatDebug)
FN_GLOBAL_BOOL(lp_ole_locking_compat,&Globals.bOleLockingCompat)
FN_GLOBAL_BOOL(lp_nt_smb_support,&Globals.bNTSmbSupport)
FN_GLOBAL_BOOL(lp_nt_pipe_support,&Globals.bNTPipeSupport)
-FN_GLOBAL_BOOL(lp_nt_acl_support,&Globals.bNTAclSupport)
FN_GLOBAL_BOOL(lp_stat_cache,&Globals.bStatCache)
-FN_GLOBAL_BOOL(lp_allow_trusted_domains,&Globals.bAllowTrustedDomains)
-FN_GLOBAL_BOOL(lp_restrict_anonymous,&Globals.bRestrictAnonymous)
FN_GLOBAL_INTEGER(lp_os_level,&Globals.os_level)
FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
@@ -1325,13 +1415,21 @@ FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout)
FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout)
FN_GLOBAL_INTEGER(lp_stat_cache_size,&Globals.stat_cache_size)
FN_GLOBAL_INTEGER(lp_map_to_guest,&Globals.map_to_guest)
-FN_GLOBAL_INTEGER(lp_min_passwd_length,&Globals.min_passwd_length)
-FN_GLOBAL_INTEGER(lp_oplock_break_wait_time,&Globals.oplock_break_wait_time)
-#ifdef WITH_LDAP
+#if defined(WITH_LDAP) || defined(WITH_NT5LDAP)
FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port)
+FN_GLOBAL_INTEGER(lp_ldap_protocol_version,&Globals.ldap_protocol_version)
#endif /* WITH_LDAP */
+/* user-dependent parameters */
+
+FN_VUSER_STRING(lp_logon_script,&Globals.szLogonScript)
+FN_VUSER_STRING(lp_logon_path,&Globals.szLogonPath)
+FN_VUSER_STRING(lp_logon_drive,&Globals.szLogonDrive)
+FN_VUSER_STRING(lp_logon_home,&Globals.szLogonHome)
+
+/* local parameters */
+
FN_LOCAL_STRING(lp_preexec,szPreExec)
FN_LOCAL_STRING(lp_postexec,szPostExec)
FN_LOCAL_STRING(lp_rootpreexec,szRootPreExec)
@@ -1363,7 +1461,7 @@ FN_LOCAL_STRING(lp_force_group,force_group)
FN_LOCAL_STRING(lp_readlist,readlist)
FN_LOCAL_STRING(lp_writelist,writelist)
FN_LOCAL_STRING(lp_fstype,fstype)
-FN_LOCAL_STRING(lp_vfsobj,szVfsObjectFile)
+FN_LOCAL_STRING(lp_vfsobj,vfsObjectFile)
static FN_LOCAL_STRING(lp_volume,volume)
FN_LOCAL_STRING(lp_mangled_map,szMangledMap)
FN_LOCAL_STRING(lp_veto_files,szVetoFiles)
@@ -1371,8 +1469,6 @@ FN_LOCAL_STRING(lp_hide_files,szHideFiles)
FN_LOCAL_STRING(lp_veto_oplocks,szVetoOplockFiles)
FN_LOCAL_STRING(lp_driverlocation,szPrinterDriverLocation)
-FN_LOCAL_BOOL(lp_preexec_close,bPreexecClose)
-FN_LOCAL_BOOL(lp_rootpreexec_close,bRootpreexecClose)
FN_LOCAL_BOOL(lp_revalidate,bRevalidate)
FN_LOCAL_BOOL(lp_casesensitive,bCaseSensitive)
FN_LOCAL_BOOL(lp_preservecase,bCasePreserve)
@@ -1391,12 +1487,8 @@ FN_LOCAL_BOOL(lp_map_hidden,bMap_hidden)
FN_LOCAL_BOOL(lp_map_archive,bMap_archive)
FN_LOCAL_BOOL(lp_locking,bLocking)
FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking)
-#ifdef WITH_UTMP
-FN_LOCAL_BOOL(lp_utmp,bUtmp)
-#endif
FN_LOCAL_BOOL(lp_share_modes,bShareModes)
FN_LOCAL_BOOL(lp_oplocks,bOpLocks)
-FN_LOCAL_BOOL(lp_level2_oplocks,bLevel2OpLocks)
FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser)
FN_LOCAL_BOOL(lp_manglednames,bMangledNames)
FN_LOCAL_BOOL(lp_widelinks,bWidelinks)
@@ -1411,25 +1503,25 @@ FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes)
FN_LOCAL_BOOL(lp_dos_filetime_resolution,bDosFiletimeResolution)
FN_LOCAL_BOOL(lp_fake_dir_create_times,bFakeDirCreateTimes)
FN_LOCAL_BOOL(lp_blocking_locks,bBlockingLocks)
-FN_LOCAL_BOOL(lp_inherit_perms,bInheritPerms)
-FN_LOCAL_INTEGER(lp_create_mask,iCreate_mask)
+FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask)
FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode)
-FN_LOCAL_INTEGER(_lp_security_mask,iSecurity_mask)
-FN_LOCAL_INTEGER(_lp_force_security_mode,iSecurity_force_mode)
-FN_LOCAL_INTEGER(lp_dir_mask,iDir_mask)
+FN_LOCAL_INTEGER(lp_dir_mode,iDir_mask)
FN_LOCAL_INTEGER(lp_force_dir_mode,iDir_force_mode)
-FN_LOCAL_INTEGER(_lp_dir_security_mask,iDir_Security_mask)
-FN_LOCAL_INTEGER(_lp_force_dir_security_mode,iDir_Security_force_mode)
FN_LOCAL_INTEGER(lp_max_connections,iMaxConnections)
FN_LOCAL_INTEGER(lp_defaultcase,iDefaultCase)
FN_LOCAL_INTEGER(lp_minprintspace,iMinPrintSpace)
FN_LOCAL_INTEGER(lp_printing,iPrinting)
-FN_LOCAL_INTEGER(lp_oplock_contention_limit,iOplockContentionLimit)
-FN_LOCAL_INTEGER(lp_write_cache_size,iWriteCacheSize)
FN_LOCAL_CHAR(lp_magicchar,magic_char)
+#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
+FN_GLOBAL_STRING(lp_mysql_host,&Globals.sMysqlHost)
+FN_GLOBAL_STRING(lp_mysql_user,&Globals.sMysqlUser)
+FN_GLOBAL_STRING(lp_mysql_passfile,&Globals.sMysqlPassFile)
+FN_GLOBAL_STRING(lp_mysql_db,&Globals.sMysqlDatabase)
+FN_GLOBAL_STRING(lp_mysql_table,&Globals.sMysqlTable)
+#endif
/* local prototypes */
@@ -1451,7 +1543,7 @@ initialise a service to the defaults
***************************************************************************/
static void init_service(service *pservice)
{
- memset((char *)pservice,'\0',sizeof(service));
+ bzero((char *)pservice,sizeof(service));
copy_service(pservice,&sDefault,NULL);
}
@@ -1526,10 +1618,9 @@ static int add_a_service(service *pservice, char *name)
init_service(pSERVICE(i));
copy_service(pSERVICE(i),&tservice,NULL);
- if (name) {
+ if (name)
string_set(&iSERVICE(i).szService,name);
- unix_to_dos(iSERVICE(i).szService, True);
- }
+
return(i);
}
@@ -1912,146 +2003,75 @@ BOOL lp_file_list_changed(void)
}
/***************************************************************************
- Run standard_sub_basic on netbios name... needed because global_myname
- is not accessed through any lp_ macro.
-***************************************************************************/
-
-static BOOL handle_netbios_name(char *pszParmValue,char **ptr)
-{
- pstring netbios_name;
-
- pstrcpy(netbios_name,pszParmValue);
-
- standard_sub_basic(netbios_name);
- strupper(netbios_name);
- string_set(ptr,netbios_name);
-
- /*
- * Convert from UNIX to DOS string - the UNIX to DOS converter
- * isn't called on the special handlers.
- */
- unix_to_dos(netbios_name, True);
- pstrcpy(global_myname,netbios_name);
-
- DEBUG(4,("handle_netbios_name: set global_myname to: %s\n", global_myname));
-
- return(True);
-}
-
-/***************************************************************************
- Do the work of sourcing in environment variable/value pairs.
-***************************************************************************/
-
-static BOOL source_env(FILE *fenv)
+ handle the interpretation of the vfs object parameter
+ *************************************************************************/
+static BOOL handle_vfs_object(char *pszParmValue,char **ptr)
{
- pstring line;
- char *varval;
- size_t len;
- char *p;
-
- while (!feof(fenv)) {
- if (fgets(line, sizeof(line), fenv) == NULL)
- break;
-
- if(feof(fenv))
- break;
-
- if((len = strlen(line)) == 0)
- continue;
-
- if (line[len - 1] == '\n')
- line[--len] = '\0';
-
- if ((varval=malloc(len+1)) == NULL) {
- DEBUG(0,("source_env: Not enough memory!\n"));
- return(False);
- }
-
- DEBUG(4,("source_env: Adding to environment: %s\n", line));
- strncpy(varval, line, len);
- varval[len] = '\0';
-
- p=strchr(line, (int) '=');
- if (p == NULL) {
- DEBUG(4,("source_env: missing '=': %s\n", line));
- continue;
- }
+ /* Set string value */
- if (putenv(varval)) {
- DEBUG(0,("source_env: Failed to put environment variable %s\n", varval ));
- continue;
- }
+ string_set(ptr,pszParmValue);
- *p='\0';
- p++;
- DEBUG(4,("source_env: getting var %s = %s\n", line, getenv(line)));
- }
+ /* Do any other initialisation required for vfs. Note that
+ anything done here may have linking repercussions in nmbd. */
- DEBUG(4,("source_env: returning successfully\n"));
- return(True);
+ return True;
}
/***************************************************************************
- Handle the source environment operation
-***************************************************************************/
-
-static BOOL handle_source_env(char *pszParmValue,char **ptr)
+ handle the interpretation of the vfs option parameter
+ *************************************************************************/
+static BOOL handle_vfs_option(char *pszParmValue, char **ptr)
{
- pstring fname;
- char *p = fname;
- FILE *env;
- BOOL result;
-
- pstrcpy(fname,pszParmValue);
+ struct vfs_options *new_option, **options = (struct vfs_options **)ptr;
+ int i;
+
+ /* Create new vfs option */
- standard_sub_basic(fname);
+ new_option = (struct vfs_options *)malloc(sizeof(*new_option));
+ if (new_option == NULL) {
+ return False;
+ }
- string_set(ptr,pszParmValue);
+ ZERO_STRUCTP(new_option);
- DEBUG(4, ("handle_source_env: checking env type\n"));
+ /* Get name and value */
+
+ new_option->name = strtok(pszParmValue, "=");
- /*
- * Filename starting with '|' means popen and read from stdin.
- */
+ if (new_option->name == NULL) {
+ return False;
+ }
- if (*p == '|') {
+ while(isspace(*new_option->name)) {
+ new_option->name++;
+ }
- DEBUG(4, ("handle_source_env: source env from pipe\n"));
- p++;
+ for (i = strlen(new_option->name); i > 0; i--) {
+ if (!isspace(new_option->name[i - 1])) break;
+ }
- if ((env = sys_popen(p, "r")) == NULL) {
- DEBUG(0,("handle_source_env: Failed to popen %s. Error was %s\n", p, strerror(errno) ));
- return(False);
- }
+ new_option->name[i] = '\0';
+ new_option->name = strdup(new_option->name);
- DEBUG(4, ("handle_source_env: calling source_env()\n"));
- result = source_env(env);
- sys_pclose(env);
+ new_option->value = strtok(NULL, "=");
- } else {
+ if (new_option->value != NULL) {
- DEBUG(4, ("handle_source_env: source env from file %s\n", fname));
- if ((env = sys_fopen(fname, "r")) == NULL) {
- DEBUG(0,("handle_source_env: Failed to open file %s, Error was %s\n", fname, strerror(errno) ));
- return(False);
- }
- result=source_env(env);
- fclose(env);
+ while(isspace(*new_option->value)) {
+ new_option->value++;
}
- return(result);
-}
-
-/***************************************************************************
- handle the interpretation of the vfs object parameter
- *************************************************************************/
-static BOOL handle_vfs_object(char *pszParmValue,char **ptr)
-{
- /* Set string value */
+
+ for (i = strlen(new_option->value); i > 0; i--) {
+ if (!isspace(new_option->value[i - 1])) break;
+ }
+
+ new_option->value[i] = '\0';
+ new_option->value = strdup(new_option->value);
+ }
- string_set(ptr,pszParmValue);
+ /* Add to list */
- /* Do any other initialisation required for vfs. Note that
- anything done here may have linking repercussions in nmbd. */
+ DLIST_ADD(*options, new_option);
return True;
}
@@ -2067,41 +2087,19 @@ static BOOL handle_coding_system(char *pszParmValue,char **ptr)
}
/***************************************************************************
- Handle the interpretation of the character set system parameter.
+handle the interpretation of the character set system parameter
***************************************************************************/
-
-static char *saved_character_set = NULL;
-
static BOOL handle_character_set(char *pszParmValue,char **ptr)
{
- /* A dependency here is that the parameter client code page should be
- set before this is called.
- */
string_set(ptr,pszParmValue);
- strupper(*ptr);
- saved_character_set = strdup(*ptr);
- interpret_character_set(*ptr,lp_client_code_page());
+ interpret_character_set(pszParmValue);
return(True);
}
-/***************************************************************************
- Handle the interpretation of the client code page parameter.
- We handle this separately so that we can reset the character set
- parameter in case this came before 'client code page' in the smb.conf.
-***************************************************************************/
-
-static BOOL handle_client_code_page(char *pszParmValue,char **ptr)
-{
- Globals.client_code_page = atoi(pszParmValue);
- if (saved_character_set != NULL)
- interpret_character_set(saved_character_set,lp_client_code_page());
- return(True);
-}
/***************************************************************************
handle the valid chars lines
***************************************************************************/
-
static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
{
string_set(ptr,pszParmValue);
@@ -2116,10 +2114,10 @@ static BOOL handle_valid_chars(char *pszParmValue,char **ptr)
return(True);
}
+
/***************************************************************************
handle the include operation
***************************************************************************/
-
static BOOL handle_include(char *pszParmValue,char **ptr)
{
pstring fname;
@@ -2193,10 +2191,10 @@ static void init_copymap(service *pservice)
if (pservice->copymap) free(pservice->copymap);
pservice->copymap = (BOOL *)malloc(sizeof(BOOL)*NUMPARAMETERS);
if (!pservice->copymap)
- DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",(int)NUMPARAMETERS));
- else
- for (i=0;i<NUMPARAMETERS;i++)
- pservice->copymap[i] = True;
+ DEBUG(0,("Couldn't allocate copymap!! (size %d)\n",NUMPARAMETERS));
+
+ for (i=0;i<NUMPARAMETERS;i++)
+ pservice->copymap[i] = True;
}
@@ -2288,27 +2286,19 @@ BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
case P_STRING:
string_set(parm_ptr,pszParmValue);
- if (parm_table[parmnum].flags & FLAG_DOS_STRING)
- unix_to_dos(*(char **)parm_ptr, True);
break;
case P_USTRING:
string_set(parm_ptr,pszParmValue);
- if (parm_table[parmnum].flags & FLAG_DOS_STRING)
- unix_to_dos(*(char **)parm_ptr, True);
strupper(*(char **)parm_ptr);
break;
case P_GSTRING:
pstrcpy((char *)parm_ptr,pszParmValue);
- if (parm_table[parmnum].flags & FLAG_DOS_STRING)
- unix_to_dos((char *)parm_ptr, True);
break;
case P_UGSTRING:
pstrcpy((char *)parm_ptr,pszParmValue);
- if (parm_table[parmnum].flags & FLAG_DOS_STRING)
- unix_to_dos((char *)parm_ptr, True);
strupper((char *)parm_ptr);
break;
@@ -2320,7 +2310,8 @@ BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue)
}
}
break;
- case P_SEP:
+
+ default:
break;
}
@@ -2376,7 +2367,7 @@ static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
break;
case P_OCTAL:
- fprintf(f,"%s",octal_string(*(int *)ptr));
+ fprintf(f,"0%o",*(int *)ptr);
break;
case P_GSTRING:
@@ -2390,7 +2381,8 @@ static void print_parameter(struct parm_struct *p,void *ptr, FILE *f)
if (*(char **)ptr)
fprintf(f,"%s",*(char **)ptr);
break;
- case P_SEP:
+
+ default:
break;
}
}
@@ -2431,7 +2423,8 @@ static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
if (p2 && !*p2) p2 = NULL;
return(p1==p2 || strequal(p1,p2));
}
- case P_SEP:
+
+ default:
break;
}
return(False);
@@ -2511,7 +2504,7 @@ static BOOL is_default(int i)
case P_OCTAL:
case P_ENUM:
return parm_table[i].def.ivalue == *(int *)parm_table[i].ptr;
- case P_SEP:
+ default:
break;
}
return False;
@@ -2524,7 +2517,7 @@ Display the contents of the global structure.
static void dump_globals(FILE *f)
{
int i;
- fprintf(f, "# Global parameters\n[global]\n");
+ fprintf(f, "# Global parameters\n");
for (i=0;parm_table[i].label;i++)
if (parm_table[i].class == P_GLOBAL &&
@@ -2679,7 +2672,7 @@ static void lp_add_auto_services(char *str)
homes = lp_servicenumber(HOMES_NAME);
for (p=strtok(s,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
- char *home = get_user_home_dir(p);
+ char *home = get_unixhome_dir(p);
if (lp_servicenumber(p) >= 0) continue;
@@ -2759,7 +2752,7 @@ static void lp_save_defaults(void)
case P_ENUM:
parm_table[i].def.ivalue = *(int *)parm_table[i].ptr;
break;
- case P_SEP:
+ default:
break;
}
}
@@ -2775,7 +2768,7 @@ BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
{
pstring n2;
BOOL bRetval;
-
+
add_to_file_list(pszFname);
bRetval = False;
@@ -2808,6 +2801,7 @@ BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
if (add_ipc)
lp_add_ipc();
+ set_server_role();
set_default_server_announce_type();
bLoaded = True;
@@ -2826,14 +2820,6 @@ BOOL lp_load(char *pszFname,BOOL global_only, BOOL save_defaults, BOOL add_ipc)
/***************************************************************************
-reset the max number of services
-***************************************************************************/
-void lp_resetnumservices(void)
-{
- iNumServices = 0;
-}
-
-/***************************************************************************
return the max number of services
***************************************************************************/
int lp_numservices(void)
@@ -2844,7 +2830,7 @@ int lp_numservices(void)
/***************************************************************************
Display the contents of the services array in human-readable form.
***************************************************************************/
-void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
+void lp_dump(FILE *f, BOOL show_defaults)
{
int iService;
@@ -2856,21 +2842,15 @@ void lp_dump(FILE *f, BOOL show_defaults, int maxtoprint)
dump_a_service(&sDefault, f);
- for (iService = 0; iService < maxtoprint; iService++)
- lp_dump_one(f, show_defaults, iService);
-}
-
-/***************************************************************************
-Display the contents of one service in human-readable form.
-***************************************************************************/
-void lp_dump_one(FILE *f, BOOL show_defaults, int snum)
-{
- if (VALID(snum))
- {
- if (iSERVICE(snum).szService[0] == '\0')
- return;
- dump_a_service(pSERVICE(snum), f);
- }
+ for (iService = 0; iService < iNumServices; iService++)
+ {
+ if (VALID(iService))
+ {
+ if (iSERVICE(iService).szService[0] == '\0')
+ break;
+ dump_a_service(pSERVICE(iService), f);
+ }
+ }
}
@@ -2909,19 +2889,110 @@ char *volume_label(int snum)
/*******************************************************************
Set the server type we will announce as via nmbd.
********************************************************************/
+static void set_server_role(void)
+{
+ server_role = ROLE_DOMAIN_NONE;
+
+ switch (lp_security())
+ {
+ case SEC_SHARE:
+ {
+ if (lp_domain_logons())
+ {
+ DEBUG(0,("Server's Role (logon server) conflicts with share-level security\n"));
+ }
+ break;
+ }
+ case SEC_SERVER:
+ case SEC_DOMAIN:
+ {
+ if (lp_domain_logons())
+ {
+ server_role = ROLE_DOMAIN_BDC;
+ break;
+ }
+ server_role = ROLE_DOMAIN_MEMBER;
+ break;
+ }
+ case SEC_USER:
+ {
+ if (lp_domain_logons())
+ {
+ server_role = ROLE_DOMAIN_PDC;
+ break;
+ }
+ break;
+ }
+ default:
+ {
+ DEBUG(0,("Server's Role undefined due to unknown security mode\n"));
+ }
+ }
+}
+
+/*******************************************************************
+ Set the server type we will announce as via nmbd.
+********************************************************************/
static void set_default_server_announce_type(void)
{
- default_server_announce = (SV_TYPE_WORKSTATION | SV_TYPE_SERVER |
- SV_TYPE_SERVER_UNIX | SV_TYPE_PRINTQ_SERVER);
- if(lp_announce_as() == ANNOUNCE_AS_NT_SERVER)
- default_server_announce |= (SV_TYPE_SERVER_NT | SV_TYPE_NT);
- if(lp_announce_as() == ANNOUNCE_AS_NT_WORKSTATION)
- default_server_announce |= SV_TYPE_NT;
- else if(lp_announce_as() == ANNOUNCE_AS_WIN95)
- default_server_announce |= SV_TYPE_WIN95_PLUS;
- else if(lp_announce_as() == ANNOUNCE_AS_WFW)
- default_server_announce |= SV_TYPE_WFW;
- default_server_announce |= (lp_time_server() ? SV_TYPE_TIME_SOURCE : 0);
+ default_server_announce = 0;
+ default_server_announce |= SV_TYPE_WORKSTATION;
+ default_server_announce |= SV_TYPE_SERVER;
+ default_server_announce |= SV_TYPE_SERVER_UNIX;
+ default_server_announce |= SV_TYPE_PRINTQ_SERVER;
+
+ switch (lp_announce_as())
+ {
+ case ANNOUNCE_AS_NT:
+ {
+ default_server_announce |= SV_TYPE_SERVER_NT;
+ default_server_announce |= SV_TYPE_NT;
+ break;
+ }
+ case ANNOUNCE_AS_WIN95:
+ {
+ default_server_announce |= SV_TYPE_WIN95_PLUS;
+ break;
+ }
+ case ANNOUNCE_AS_WFW:
+ {
+ default_server_announce |= SV_TYPE_WFW;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ switch (lp_server_role())
+ {
+ case ROLE_DOMAIN_MEMBER:
+ {
+ default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
+ break;
+ }
+ case ROLE_DOMAIN_PDC:
+ {
+ default_server_announce |= SV_TYPE_DOMAIN_CTRL;
+ break;
+ }
+ case ROLE_DOMAIN_BDC:
+ {
+ default_server_announce |= SV_TYPE_DOMAIN_BAKCTRL;
+ break;
+ }
+ case ROLE_DOMAIN_NONE:
+ default:
+ {
+ break;
+ }
+ }
+
+ if (lp_time_server())
+ {
+ default_server_announce |= SV_TYPE_TIME_SOURCE;
+ }
}
@@ -3044,38 +3115,40 @@ BOOL lp_kernel_oplocks(void)
}
/***********************************************************
- Functions to return the current security masks/modes. If
- set to -1 then return the create mask/mode instead.
+ returns role of Samba server
************************************************************/
-int lp_security_mask(int snum)
+int lp_server_role(void)
{
- int val = _lp_security_mask(snum);
- if(val == -1)
- return lp_create_mask(snum);
- return val;
+ return server_role;
}
-int lp_force_security_mode(int snum)
-{
- int val = _lp_force_security_mode(snum);
- if(val == -1)
- return lp_force_create_mode(snum);
- return val;
-}
+/***********************************************************
+ If we are PDC then prefer us as DMB
+************************************************************/
-int lp_dir_security_mask(int snum)
+BOOL lp_domain_master(void)
{
- int val = _lp_dir_security_mask(snum);
- if(val == -1)
- return lp_dir_mask(snum);
- return val;
+ if (Globals.bDomainMaster == Auto)
+ {
+ return (lp_server_role() == ROLE_DOMAIN_PDC);
+ }
+
+ return Globals.bDomainMaster;
}
-int lp_force_dir_security_mode(int snum)
+/***********************************************************
+ If we are DMB then prefer us as LMB
+************************************************************/
+
+BOOL lp_preferred_master(void)
{
- int val = _lp_force_dir_security_mode(snum);
- if(val == -1)
- return lp_force_dir_mode(snum);
- return val;
+ if (Globals.bPreferredMaster == Auto)
+ {
+ return (lp_local_master() && lp_domain_master());
+ }
+
+ return Globals.bPreferredMaster;
}
+
+
diff --git a/source/param/params.c b/source/param/params.c
index 3ecdcdc92b3..74dd3d7a254 100644
--- a/source/param/params.c
+++ b/source/param/params.c
@@ -157,42 +157,28 @@ static int EatComment( FILE *InFile )
return( c );
} /* EatComment */
-/*****************************************************************************
- * Scan backards within a string to discover if the last non-whitespace
- * character is a line-continuation character ('\\').
- *
- * Input: line - A pointer to a buffer containing the string to be
- * scanned.
- * pos - This is taken to be the offset of the end of the
- * string. This position is *not* scanned.
- *
- * Output: The offset of the '\\' character if it was found, or -1 to
- * indicate that it was not.
- *
- *****************************************************************************/
-
static int Continuation( char *line, int pos )
-{
- int pos2 = 0;
-
+ /* ------------------------------------------------------------------------ **
+ * Scan backards within a string to discover if the last non-whitespace
+ * character is a line-continuation character ('\\').
+ *
+ * Input: line - A pointer to a buffer containing the string to be
+ * scanned.
+ * pos - This is taken to be the offset of the end of the
+ * string. This position is *not* scanned.
+ *
+ * Output: The offset of the '\\' character if it was found, or -1 to
+ * indicate that it was not.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
pos--;
while( (pos >= 0) && isspace(line[pos]) )
pos--;
- /* we should recognize if `\` is part of a multibyte character or not. */
- while(pos2 <= pos) {
- size_t skip = 0;
- skip = get_character_len(line[pos2]);
- if (skip) {
- pos2 += skip;
- } else if (pos == pos2) {
- return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
- } else {
- pos2++;
- }
- }
- return (-1);
-}
+ return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 );
+ } /* Continuation */
static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) )
diff --git a/source/passdb/.cvsignore b/source/passdb/.cvsignore
new file mode 100644
index 00000000000..af9d6be961b
--- /dev/null
+++ b/source/passdb/.cvsignore
@@ -0,0 +1 @@
+*.lo \ No newline at end of file
diff --git a/source/passdb/ldap.c b/source/passdb/ldap.c
index 54566e454b9..7bdbdab320e 100644
--- a/source/passdb/ldap.c
+++ b/source/passdb/ldap.c
@@ -1,8 +1,9 @@
/*
Unix SMB/Netbios implementation.
- Version 1.9.
+ Version 2.0.
LDAP protocol helper functions for SAMBA
Copyright (C) Jean François Micouleau 1998
+ Copyright (C) Matthew Chapman 1998
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,1011 +21,536 @@
*/
-#ifdef WITH_LDAP
-
#include "includes.h"
+#ifdef WITH_LDAP
+
#include <lber.h>
#include <ldap.h>
-#define ADD_USER 1
-#define MODIFY_USER 2
-
extern int DEBUGLEVEL;
-/*******************************************************************
- open a connection to the ldap serve.
-******************************************************************/
-static BOOL ldap_open_connection(LDAP **ldap_struct)
-{
- if ( (*ldap_struct = ldap_open(lp_ldap_server(),lp_ldap_port()) ) == NULL)
- {
- DEBUG( 0, ( "The LDAP server is not responding !\n" ) );
- return( False );
- }
- DEBUG(2,("ldap_open_connection: connection opened\n"));
- return (True);
-}
-
+/* Internal state */
+LDAP *ldap_struct;
+LDAPMessage *ldap_results;
+LDAPMessage *ldap_entry;
-/*******************************************************************
- connect anonymously to the ldap server.
- FIXME: later (jfm)
-******************************************************************/
-static BOOL ldap_connect_anonymous(LDAP *ldap_struct)
-{
- if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) ! = LDAP_SUCCESS)
- {
- DEBUG( 0, ( "Couldn't bind to the LDAP server !\n" ) );
- return(False);
- }
- return (True);
-}
+/* LDAP password */
+static pstring ldap_secret;
/*******************************************************************
- connect to the ldap server under system privileg.
-******************************************************************/
-static BOOL ldap_connect_system(LDAP *ldap_struct)
-{
- if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) ! = LDAP_SUCCESS)
- {
- DEBUG( 0, ( "Couldn't bind to the LDAP server!\n" ) );
- return(False);
- }
- DEBUG(2,("ldap_connect_system: succesful connection to the LDAP server\n"));
- return (True);
-}
+ Open connections to the LDAP server.
+ ******************************************************************/
-/*******************************************************************
- connect to the ldap server under a particular user.
-******************************************************************/
-static BOOL ldap_connect_user(LDAP *ldap_struct, char *user, char *password)
+BOOL ldap_connect(void)
{
- if ( ldap_simple_bind_s(ldap_struct,lp_ldap_root(),lp_ldap_rootpasswd()) ! = LDAP_SUCCESS)
- {
- DEBUG( 0, ( "Couldn't bind to the LDAP server !\n" ) );
- return(False);
- }
- DEBUG(2,("ldap_connect_user: succesful connection to the LDAP server\n"));
- return (True);
-}
+ int err;
-/*******************************************************************
- run the search by name.
-******************************************************************/
-static BOOL ldap_search_one_user(LDAP *ldap_struct, char *filter, LDAPMessage **result)
-{
- int scope = LDAP_SCOPE_ONELEVEL;
- int rc;
-
- DEBUG(2,("ldap_search_one_user: searching for:[%s]\n", filter));
-
- rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, result);
-
- if (rc ! = LDAP_SUCCESS )
- {
- DEBUG( 0, ( "Problem during the LDAP search\n" ) );
- return(False);
+ if (!(ldap_struct = ldap_open(lp_ldap_server(), lp_ldap_port()))) {
+ DEBUG(0, ("open: %s\n", strerror(errno)));
+ return (False);
}
- return (True);
-}
-/*******************************************************************
- run the search by name.
-******************************************************************/
-static BOOL ldap_search_one_user_by_name(LDAP *ldap_struct, char *user, LDAPMessage **result)
-{
- pstring filter;
- /*
- in the filter expression, replace %u with the real name
- so in ldap filter, %u MUST exist :-)
- */
- pstrcpy(filter,lp_ldap_filter());
- pstring_sub(filter,"%u",user);
-
- if ( !ldap_search_one_user(ldap_struct, filter, result) )
- {
- return(False);
+ err = ldap_simple_bind_s(ldap_struct, lp_ldap_bind_as(), ldap_secret);
+ if (err != LDAP_SUCCESS) {
+ DEBUG(0, ("bind: %s\n", ldap_err2string(err)));
+ return (False);
}
- return (True);
-}
-/*******************************************************************
- run the search by uid.
-******************************************************************/
-static BOOL ldap_search_one_user_by_uid(LDAP *ldap_struct, int uid, LDAPMessage **result)
-{
- pstring filter;
-
- slprintf(filter, sizeof(pstring)-1, "uidAccount = %d", uid);
-
- if ( !ldap_search_one_user(ldap_struct, filter, result) )
- {
- return(False);
- }
+ DEBUG(2,("Connected to LDAP server\n"));
return (True);
}
/*******************************************************************
- search an attribute and return the first value found.
-******************************************************************/
-static void get_single_attribute(LDAP *ldap_struct, LDAPMessage *entry, char *attribute, char *value)
-{
- char **valeurs;
-
- if ( (valeurs = ldap_get_values(ldap_struct, entry, attribute)) ! = NULL)
- {
- pstrcpy(value, valeurs[0]);
- ldap_value_free(valeurs);
- DEBUG(3,("get_single_attribute: [%s] = [%s]\n", attribute, value));
- }
- else
- {
- value = NULL;
- }
-}
+ close connections to the LDAP server.
+ ******************************************************************/
-/*******************************************************************
- check if the returned entry is a sambaAccount objectclass.
-******************************************************************/
-static BOOL ldap_check_user(LDAP *ldap_struct, LDAPMessage *entry)
+void ldap_disconnect(void)
{
- BOOL sambaAccount = False;
- char **valeur;
- int i;
+ if(!ldap_struct)
+ return;
- DEBUG(2,("ldap_check_user: "));
- valeur = ldap_get_values(ldap_struct, entry, "objectclass");
- if (valeur! = NULL)
- {
- for (i = 0;valeur[i]! = NULL;i++)
- {
- if (!strcmp(valeur[i],"sambaAccount")) sambaAccount = True;
- }
- }
- DEBUG(2,("%s\n",sambaAccount?"yes":"no"));
- ldap_value_free(valeur);
- return (sambaAccount);
-}
+ if(ldap_results) {
+ ldap_msgfree(ldap_results);
+ ldap_results = NULL; }
-/*******************************************************************
- check if the returned entry is a sambaTrust objectclass.
-******************************************************************/
-static BOOL ldap_check_trust(LDAP *ldap_struct, LDAPMessage *entry)
-{
- BOOL sambaTrust = False;
- char **valeur;
- int i;
+ ldap_unbind(ldap_struct);
+ ldap_struct = NULL;
- DEBUG(2,("ldap_check_trust: "));
- valeur = ldap_get_values(ldap_struct, entry, "objectclass");
- if (valeur! = NULL)
- {
- for (i = 0;valeur[i]! = NULL;i++)
- {
- if (!strcmp(valeur[i],"sambaTrust")) sambaTrust = True;
- }
- }
- DEBUG(2,("%s\n",sambaTrust?"yes":"no"));
- ldap_value_free(valeur);
- return (sambaTrust);
+ DEBUG(2,("Connection closed\n"));
}
+
/*******************************************************************
- retrieve the user's info and contruct a smb_passwd structure.
-******************************************************************/
-static void ldap_get_smb_passwd(LDAP *ldap_struct,LDAPMessage *entry,
- struct smb_passwd *user)
-{
- static pstring user_name;
- static pstring user_pass;
- static pstring temp;
- static unsigned char smblmpwd[16];
- static unsigned char smbntpwd[16];
+ Search the directory using a given filter.
+ ******************************************************************/
- pdb_init_smb(user);
+BOOL ldap_search_for(char *filter)
+{
+ int err;
- memset((char *)smblmpwd, '\0', sizeof(smblmpwd));
- memset((char *)smbntpwd, '\0', sizeof(smbntpwd));
+ DEBUG(2,("Searching in [%s] for [%s]\n", lp_ldap_suffix(), filter));
- get_single_attribute(ldap_struct, entry, "cn", user_name);
- DEBUG(2,("ldap_get_smb_passwd: user: %s\n",user_name));
-
-#ifdef LDAP_PLAINTEXT_PASSWORD
- get_single_attribute(ldap_struct, entry, "userPassword", temp);
- nt_lm_owf_gen(temp, user->smb_nt_passwd, user->smb_passwd);
- memset((char *)temp, '\0', sizeof(temp)); /* destroy local copy of the password */
-#else
- get_single_attribute(ldap_struct, entry, "unicodePwd", temp);
- pdb_gethexpwd(temp, smbntpwd);
- memset((char *)temp, '\0', sizeof(temp)); /* destroy local copy of the password */
+ err = ldap_search_s(ldap_struct, lp_ldap_suffix(), LDAP_SCOPE_ONELEVEL,
+ filter, NULL, 0, &ldap_results);
- get_single_attribute(ldap_struct, entry, "dBCSPwd", temp);
- pdb_gethexpwd(temp, smblmpwd);
- memset((char *)temp, '\0', sizeof(temp)); /* destroy local copy of the password */
-#endif
-
- get_single_attribute(ldap_struct, entry, "userAccountControl", temp);
- user->acct_ctrl = pdb_decode_acct_ctrl(temp);
+ if(err != LDAP_SUCCESS) {
+ DEBUG(0, ("search: %s\n", ldap_err2string(err)));
+ }
- get_single_attribute(ldap_struct, entry, "pwdLastSet", temp);
- user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
+ DEBUG(2, ("%d matching entries found\n",
+ ldap_count_entries(ldap_struct, ldap_results)));
- get_single_attribute(ldap_struct, entry, "rid", temp);
+ ldap_entry = ldap_first_entry(ldap_struct, ldap_results);
+ return (True);
+}
- /* the smb (unix) ids are not stored: they are created */
- user->smb_userid = pdb_user_rid_to_uid (atoi(temp));
+BOOL ldap_search_by_name(const char *user)
+{
+ fstring filter;
- if (user->acct_ctrl & (ACB_DOMTRUST|ACB_WSTRUST|ACB_SVRTRUST) )
- {
- DEBUG(0,("Inconsistency in the LDAP database\n"));
- }
- if (user->acct_ctrl & ACB_NORMAL)
- {
- user->smb_name = user_name;
- user->smb_passwd = smblmpwd;
- user->smb_nt_passwd = smbntpwd;
- }
+ slprintf(filter, sizeof(filter)-1,
+ "(&(uid=%s)(objectclass=sambaAccount))", user);
+ return ldap_search_for(filter);
}
-/*******************************************************************
- retrieve the user's info and contruct a sam_passwd structure.
-
- calls ldap_get_smb_passwd function first, though, to save code duplication.
-
-******************************************************************/
-static void ldap_get_sam_passwd(LDAP *ldap_struct, LDAPMessage *entry,
- struct sam_passwd *user)
-{
- static pstring user_name;
- static pstring fullname;
- static pstring home_dir;
- static pstring dir_drive;
- static pstring logon_script;
- static pstring profile_path;
- static pstring acct_desc;
- static pstring workstations;
- static pstring temp;
- static struct smb_passwd pw_buf;
-
- pdb_init_sam(user);
-
- ldap_get_smb_passwd(ldap_struct, entry, &pw_buf);
+BOOL ldap_search_by_uid(int uid)
+{
+ fstring filter;
- user->pass_last_set_time = pw_buf.pass_last_set_time;
-
- get_single_attribute(ldap_struct, entry, "logonTime", temp);
- user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
-
- get_single_attribute(ldap_struct, entry, "logoffTime", temp);
- user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
-
- get_single_attribute(ldap_struct, entry, "kickoffTime", temp);
- user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
-
- get_single_attribute(ldap_struct, entry, "pwdLastSet", temp);
- user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
-
- get_single_attribute(ldap_struct, entry, "pwdCanChange", temp);
- user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
-
- get_single_attribute(ldap_struct, entry, "pwdMustChange", temp);
- user->pass_last_set_time = (time_t)strtol(temp, NULL, 16);
-
- user->smb_name = pw_buf.smb_name;
+ slprintf(filter, sizeof(filter)-1,
+ "(&(uidNumber=%d)(objectclass=sambaAccount))", uid);
+ return ldap_search_for(filter);
+}
- DEBUG(2,("ldap_get_sam_passwd: user: %s\n", user_name));
-
- get_single_attribute(ldap_struct, entry, "userFullName", fullname);
- user->full_name = fullname;
- get_single_attribute(ldap_struct, entry, "homeDirectory", home_dir);
- user->home_dir = home_dir;
+/*******************************************************************
+ Get the first value of an attribute.
+ ******************************************************************/
- get_single_attribute(ldap_struct, entry, "homeDrive", dir_drive);
- user->dir_drive = dir_drive;
+BOOL ldap_get_attribute(char *attribute, char *value)
+{
+ char **values;
+
+ if(!(values = ldap_get_values(ldap_struct, ldap_entry, attribute)))
+ return (False);
- get_single_attribute(ldap_struct, entry, "scriptPath", logon_script);
- user->logon_script = logon_script;
+ pstrcpy(value, values[0]);
+ ldap_value_free(values);
+ DEBUG(3, ("get: [%s] = [%s]\n", attribute, value));
+
+ return (True);
+}
- get_single_attribute(ldap_struct, entry, "profilePath", profile_path);
- user->profile_path = profile_path;
- get_single_attribute(ldap_struct, entry, "comment", acct_desc);
- user->acct_desc = acct_desc;
+/*******************************************************************
+ Construct an smb_passwd structure
+ ******************************************************************/
+struct smb_passwd *ldap_getpw(void)
+{
+ static struct smb_passwd smbpw;
+ static pstring unix_name;
+ static pstring nt_name;
+ static unsigned char smblmpwd[16];
+ static unsigned char smbntpwd[16];
+ pstring temp;
- get_single_attribute(ldap_struct, entry, "userWorkstations", workstations);
- user->workstations = workstations;
+ if(!ldap_entry)
+ return NULL;
- user->unknown_str = NULL; /* don't know, yet! */
- user->munged_dial = NULL; /* "munged" dial-back telephone number */
+ if(!ldap_get_attribute("uid", unix_name)) {
+ DEBUG(0,("Missing uid\n"));
+ return NULL; }
+ smbpw.unix_name = unix_name;
- get_single_attribute(ldap_struct, entry, "rid", temp);
- user->user_rid = atoi(temp);
+ DEBUG(2,("Retrieving account [%s]\n",unix_name));
- get_single_attribute(ldap_struct, entry, "primaryGroupID", temp);
- user->group_rid = atoi(temp);
+ if(!ldap_get_attribute("uidNumber", temp)) {
+ DEBUG(0,("Missing uidNumber\n"));
+ return NULL; }
+ smbpw.unix_uid = atoi(temp);
- /* the smb (unix) ids are not stored: they are created */
- user->smb_userid = pw_buf.smb_userid;
- user->smb_grpid = group_rid_to_uid(user->group_rid);
+ if(!ldap_get_attribute("ntuid", nt_name)) {
+ DEBUG(0,("Missing ntuid\n"));
+ return NULL; }
+ smbpw.nt_name = nt_name;
- user->acct_ctrl = pw_buf.acct_ctrl;
+ if(!ldap_get_attribute("rid", temp)) {
+ DEBUG(0,("Missing rid\n"));
+ return NULL; }
+ smbpw.user_rid = strtol(temp, NULL, 16);
- user->unknown_3 = 0xffffff; /* don't know */
- user->logon_divs = 168; /* hours per week */
- user->hours_len = 21; /* 21 times 8 bits = 168 */
- memset(user->hours, 0xff, user->hours_len); /* available at all hours */
- user->unknown_5 = 0x00020000; /* don't know */
- user->unknown_5 = 0x000004ec; /* don't know */
+ if(ldap_get_attribute("acctFlags", temp))
+ smbpw.acct_ctrl = pwdb_decode_acct_ctrl(temp);
+ else
+ smbpw.acct_ctrl = ACB_NORMAL;
- if (user->acct_ctrl & (ACB_DOMTRUST|ACB_WSTRUST|ACB_SVRTRUST) )
- {
- DEBUG(0,("Inconsistency in the LDAP database\n"));
+ if(ldap_get_attribute("lmPassword", temp)) {
+ pwdb_gethexpwd(temp, smblmpwd, NULL);
+ smbpw.smb_passwd = smblmpwd;
+ } else {
+ smbpw.smb_passwd = NULL;
+ smbpw.acct_ctrl |= ACB_DISABLED;
}
- if (!(user->acct_ctrl & ACB_NORMAL))
- {
- DEBUG(0,("User's acct_ctrl bits not set to ACT_NORMAL in LDAP database\n"));
- return;
+ if(ldap_get_attribute("ntPassword", temp)) {
+ pwdb_gethexpwd(temp, smbntpwd, NULL);
+ smbpw.smb_nt_passwd = smbntpwd;
+ } else {
+ smbpw.smb_nt_passwd = NULL;
}
+
+ if(ldap_get_attribute("pwdLastSet", temp))
+ smbpw.pass_last_set_time = (time_t)strtol(temp, NULL, 16);
+ else
+ smbpw.pass_last_set_time = (time_t)(-1);
+
+ return &smbpw;
}
+
/************************************************************************
- Routine to manage the LDAPMod structure array
- manage memory used by the array, by each struct, and values
+ Adds a modification to a LDAPMod queue.
+ ************************************************************************/
-************************************************************************/
-static void make_a_mod(LDAPMod ***modlist,int modop, char *attribute, char *value)
+ void ldap_make_mod(LDAPMod ***modlist,int modop, char *attribute, char *value)
{
LDAPMod **mods;
int i;
int j;
+
+ DEBUG(3, ("set: [%s] = [%s]\n", attribute, value));
mods = *modlist;
- if (mods == NULL)
- {
- mods = (LDAPMod **)malloc( sizeof(LDAPMod *) );
- if (mods == NULL)
- {
- DEBUG(0,("make_a_mod: out of memory!\n"));
- return;
- }
+ if (mods == NULL) {
+ mods = (LDAPMod **)malloc(sizeof(LDAPMod *));
mods[0] = NULL;
}
- for ( i = 0; mods[ i ] ! = NULL; ++i )
- {
- if ( mods[ i ]->mod_op == modop &&
- !strcasecmp( mods[ i ]->mod_type, attribute ) )
- {
+ for (i = 0; mods[i] != NULL; ++i) {
+ if (mods[i]->mod_op == modop &&
+ !strcasecmp(mods[i]->mod_type, attribute)) {
break;
}
}
- if (mods[i] == NULL)
- {
- mods = (LDAPMod **)realloc( mods, (i+2) * sizeof( LDAPMod * ) );
- if (mods == NULL)
- {
- DEBUG(0,("make_a_mod: out of memory!\n"));
- return;
- }
- mods[i] = (LDAPMod *)malloc( sizeof( LDAPMod ) );
- if (mods[i] == NULL)
- {
- DEBUG(0,("make_a_mod: out of memory!\n"));
- return;
- }
+ if (mods[i] == NULL) {
+ mods = (LDAPMod **)realloc(mods, (i+2) * sizeof(LDAPMod *));
+ mods[i] = (LDAPMod *)malloc(sizeof(LDAPMod));
mods[i]->mod_op = modop;
mods[i]->mod_values = NULL;
- mods[i]->mod_type = strdup( attribute );
+ mods[i]->mod_type = strdup(attribute);
mods[i+1] = NULL;
}
- if (value ! = NULL )
- {
+ if (value) {
j = 0;
- if ( mods[ i ]->mod_values ! = NULL )
- {
- for ( ; mods[ i ]->mod_values[ j ] ! = NULL; j++ );
+ if (mods[i]->mod_values) {
+ for (; mods[i]->mod_values[j]; j++);
}
- mods[ i ]->mod_values = (char **)realloc(mods[ i ]->mod_values,
- (j+2) * sizeof( char * ));
- if ( mods[ i ]->mod_values == NULL)
- {
- DEBUG(0, "make_a_mod: Memory allocation failure!\n");
- return;
- }
- mods[ i ]->mod_values[ j ] = strdup(value);
- mods[ i ]->mod_values[ j + 1 ] = NULL;
+ mods[i]->mod_values = (char **)realloc(mods[i]->mod_values,
+ (j+2) * sizeof(char *));
+ mods[i]->mod_values[j] = strdup(value);
+ mods[i]->mod_values[j+1] = NULL;
}
+
*modlist = mods;
}
+
/************************************************************************
- Add or modify an entry. Only the smb struct values
+ Queues the necessary modifications to save a smb_passwd structure
+ ************************************************************************/
-*************************************************************************/
-static BOOL modadd_ldappwd_entry(struct smb_passwd *newpwd, int flag)
+ void ldap_smbpwmods(struct smb_passwd *newpwd, LDAPMod ***mods, int operation)
{
-
- /* assume the struct is correct and filled
- that's the job of passdb.c to check */
- int scope = LDAP_SCOPE_ONELEVEL;
- int rc;
- char *smb_name;
- int trust = False;
- int ldap_state;
- pstring filter;
- pstring dn;
- pstring lmhash;
- pstring nthash;
- pstring rid;
- pstring lst;
- pstring temp;
+ fstring temp;
+ int i;
- LDAP *ldap_struct;
- LDAPMessage *result;
- LDAPMod **mods;
-
- smb_name = newpwd->smb_name;
+ *mods = NULL;
+ if(operation == LDAP_MOD_ADD) { /* immutable attributes */
+ ldap_make_mod(mods, LDAP_MOD_ADD, "objectclass", "sambaAccount");
- if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
- {
- return False;
- }
+ ldap_make_mod(mods, LDAP_MOD_ADD, "uid", newpwd->unix_name);
+ slprintf(temp, sizeof(temp)-1, "%d", newpwd->unix_uid);
+ ldap_make_mod(mods, LDAP_MOD_ADD, "uidNumber", temp);
- if (!ldap_connect_system(ldap_struct)) /* connect as system account */
- {
- ldap_unbind(ldap_struct);
- return False;
- }
-
- if (smb_name[strlen(smb_name)-1] == '$' )
- {
- smb_name[strlen(smb_name)-1] = '\0';
- trust = True;
+ ldap_make_mod(mods, LDAP_MOD_ADD, "ntuid", newpwd->nt_name);
+ slprintf(temp, sizeof(temp)-1, "%x", newpwd->user_rid);
+ ldap_make_mod(mods, LDAP_MOD_ADD, "rid", temp);
}
- slprintf(filter, sizeof(filter)-1,
- "(&(cn = %s)(|(objectclass = sambaTrust)(objectclass = sambaAccount)))",
- smb_name);
-
- rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, &result);
-
- switch (flag)
- {
- case ADD_USER:
- {
- if (ldap_count_entries(ldap_struct, result) ! = 0)
- {
- DEBUG(0,("User already in the base, with samba properties\n"));
- ldap_unbind(ldap_struct);
- return False;
- }
- ldap_state = LDAP_MOD_ADD;
- break;
- }
- case MODIFY_USER:
- {
- if (ldap_count_entries(ldap_struct, result) ! = 1)
- {
- DEBUG(0,("No user to modify !\n"));
- ldap_unbind(ldap_struct);
- return False;
- }
- ldap_state = LDAP_MOD_REPLACE;
- break;
- }
- default:
- {
- DEBUG(0,("How did you come here? \n"));
- ldap_unbind(ldap_struct);
- return False;
- break;
- }
+ if (newpwd->smb_passwd) {
+ for( i = 0; i < 16; i++) {
+ slprintf(&temp[2*i], 3, "%02X", newpwd->smb_passwd[i]);
+ }
+ ldap_make_mod(mods, operation, "lmPassword", temp);
}
- slprintf(dn, sizeof(dn)-1, "cn = %s, %s",smb_name, lp_ldap_suffix() );
- if (newpwd->smb_passwd ! = NULL)
- {
- int i;
- for( i = 0; i < 16; i++)
- {
- slprintf(&temp[2*i], sizeof(temp) - 1, "%02X", newpwd->smb_passwd[i]);
- }
-
- }
- else
- {
- if (newpwd->acct_ctrl & ACB_PWNOTREQ)
- {
- slprintf(temp, sizeof(temp) - 1, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
- }
- else
- {
- slprintf(temp, sizeof(temp) - 1, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- }
- }
- slprintf(lmhash, sizeof(lmhash)-1, "%s", temp);
-
- if (newpwd->smb_nt_passwd ! = NULL)
- {
- int i;
- for( i = 0; i < 16; i++)
- {
- slprintf(&temp[2*i], sizeof(temp) - 1, "%02X", newpwd->smb_nt_passwd[i]);
- }
-
- }
- else
- {
- if (newpwd->acct_ctrl & ACB_PWNOTREQ)
- {
- slprintf(temp, sizeof(temp) - 1, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
- }
- else
- {
- slprintf(temp, sizeof(temp) - 1, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- }
+ if (newpwd->smb_nt_passwd) {
+ for( i = 0; i < 16; i++) {
+ slprintf(&temp[2*i], 3, "%02X", newpwd->smb_nt_passwd[i]);
+ }
+ ldap_make_mod(mods, operation, "ntPassword", temp);
}
- slprintf(nthash, sizeof(nthash)-1, "%s", temp);
- slprintf(rid, sizeof(rid)-1, "%d", uid_to_user_rid(newpwd->smb_userid) );
- slprintf(lst, sizeof(lst)-1, "%08X", newpwd->pass_last_set_time);
-
- mods = NULL;
+ newpwd->pass_last_set_time = time(NULL);
+ slprintf(temp, sizeof(temp)-1, "%08X", newpwd->pass_last_set_time);
+ ldap_make_mod(mods, operation, "pwdLastSet", temp);
- if (trust)
- {
- make_a_mod(&mods, ldap_state, "objectclass", "sambaTrust");
- make_a_mod(&mods, ldap_state, "netbiosTrustName", smb_name);
- make_a_mod(&mods, ldap_state, "trustPassword", nthash);
- }
- else
- {
- make_a_mod(&mods, ldap_state, "objectclass", "sambaAccount");
- make_a_mod(&mods, ldap_state, "dBCSPwd", lmhash);
- make_a_mod(&mods, ldap_state, "uid", smb_name);
- make_a_mod(&mods, ldap_state, "unicodePwd", nthash);
- }
-
- make_a_mod(&mods, ldap_state, "cn", smb_name);
-
- make_a_mod(&mods, ldap_state, "rid", rid);
- make_a_mod(&mods, ldap_state, "pwdLastSet", lst);
- make_a_mod(&mods, ldap_state, "userAccountControl", pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
-
- switch(flag)
- {
- case ADD_USER:
- {
- ldap_add_s(ldap_struct, dn, mods);
- DEBUG(2,("modadd_ldappwd_entry: added: cn = %s in the LDAP database\n",smb_name));
- break;
- }
- case MODIFY_USER:
- {
- ldap_modify_s(ldap_struct, dn, mods);
- DEBUG(2,("modadd_ldappwd_entry: changed: cn = %s in the LDAP database_n",smb_name));
- break;
- }
- default:
- {
- DEBUG(2,("modadd_ldappwd_entry: How did you come here? \n"));
- ldap_unbind(ldap_struct);
- return False;
- break;
- }
- }
-
- ldap_mods_free(mods, 1);
-
- ldap_unbind(ldap_struct);
-
- return True;
+ ldap_make_mod(mods, operation, "acctFlags",
+ pwdb_encode_acct_ctrl(newpwd->acct_ctrl,
+ NEW_PW_FORMAT_SPACE_PADDED_LEN));
}
-/************************************************************************
- Add or modify an entry. everything except the smb struct
-*************************************************************************/
-static BOOL modadd_ldap21pwd_entry(struct sam_passwd *newpwd, int flag)
+/************************************************************************
+ Commit changes to a directory entry.
+ *************************************************************************/
+ BOOL ldap_makemods(char *attribute, char *value, LDAPMod **mods, BOOL add)
{
-
- /* assume the struct is correct and filled
- that's the job of passdb.c to check */
- int scope = LDAP_SCOPE_ONELEVEL;
- int rc;
- char *smb_name;
- int trust = False;
- int ldap_state;
pstring filter;
- pstring dn;
- pstring lmhash;
- pstring nthash;
- pstring rid;
- pstring lst;
- pstring temp;
+ char *dn;
+ int entries;
+ int err = 0;
+ BOOL rc;
- LDAP *ldap_struct;
- LDAPMessage *result;
- LDAPMod **mods;
-
- smb_name = newpwd->smb_name;
+ slprintf(filter, sizeof(filter)-1, "%s=%s", attribute, value);
- if (!ldap_open_connection(&ldap_struct)) /* open a connection to the server */
- {
- return False;
- }
+ if (!ldap_connect())
+ return (False);
- if (!ldap_connect_system(ldap_struct)) /* connect as system account */
+ ldap_search_for(filter);
+
+ if (ldap_entry)
{
- ldap_unbind(ldap_struct);
- return False;
+ dn = ldap_get_dn(ldap_struct, ldap_entry);
+ err = ldap_modify_s(ldap_struct, dn, mods);
+ free(dn);
}
-
- if (smb_name[strlen(smb_name)-1] == '$' )
+ else if (add)
{
- smb_name[strlen(smb_name)-1] = '\0';
- trust = True;
+ pstrcat(filter, ", ");
+ pstrcat(filter, lp_ldap_suffix());
+ err = ldap_add_s(ldap_struct, filter, mods);
}
- slprintf(filter, sizeof(filter)-1,
- "(&(cn = %s)(|(objectclass = sambaTrust)(objectclass = sambaAccount)))",
- smb_name);
-
- rc = ldap_search_s(ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, &result);
-
- switch (flag)
+ if (err == LDAP_SUCCESS)
{
- case ADD_USER:
- {
- if (ldap_count_entries(ldap_struct, result) ! = 1)
- {
- DEBUG(2,("User already in the base, with samba properties\n"));
- ldap_unbind(ldap_struct);
- return False;
- }
- ldap_state = LDAP_MOD_ADD;
- break;
- }
-
- case MODIFY_USER:
- {
- if (ldap_count_entries(ldap_struct, result) ! = 1)
- {
- DEBUG(2,("No user to modify !\n"));
- ldap_unbind(ldap_struct);
- return False;
- }
- ldap_state = LDAP_MOD_REPLACE;
- break;
- }
-
- default:
- {
- DEBUG(2,("How did you come here? \n"));
- ldap_unbind(ldap_struct);
- return False;
- break;
- }
+ DEBUG(2,("Updated entry [%s]\n", value));
+ rc = True;
+ } else {
+ DEBUG(0,("update: %s\n", ldap_err2string(err)));
+ rc = False;
}
- slprintf(dn, sizeof(dn)-1, "cn = %s, %s",smb_name, lp_ldap_suffix() );
-
- mods = NULL;
- if (trust)
- {
- }
- else
- {
- }
-
- make_a_mod(&mods, ldap_state, "cn", smb_name);
-
- make_a_mod(&mods, ldap_state, "rid", rid);
- make_a_mod(&mods, ldap_state, "pwdLastSet", lst);
- make_a_mod(&mods, ldap_state, "userAccountControl", pdb_encode_acct_ctrl(newpwd->acct_ctrl,NEW_PW_FORMAT_SPACE_PADDED_LEN));
-
- ldap_modify_s(ldap_struct, dn, mods);
-
+ ldap_disconnect();
ldap_mods_free(mods, 1);
-
- ldap_unbind(ldap_struct);
-
- return True;
+ return rc;
}
-/************************************************************************
- Routine to add an entry to the ldap passwd file.
-
- do not call this function directly. use passdb.c instead.
-
-*************************************************************************/
-static BOOL add_ldappwd_entry(struct smb_passwd *newpwd)
-{
- return (modadd_ldappwd_entry(newpwd, ADD_USER) );
-}
-
-/************************************************************************
- Routine to search the ldap passwd file for an entry matching the username.
- and then modify its password entry. We can't use the startldappwent()/
- getldappwent()/endldappwent() interfaces here as we depend on looking
- in the actual file to decide how much room we have to write data.
- override = False, normal
- override = True, override XXXXXXXX'd out password or NO PASS
-
- do not call this function directly. use passdb.c instead.
-
-************************************************************************/
-static BOOL mod_ldappwd_entry(struct smb_passwd *pwd, BOOL override)
-{
- return (modadd_ldappwd_entry(pwd, MODIFY_USER) );
-}
/************************************************************************
- Routine to add an entry to the ldap passwd file.
-
- do not call this function directly. use passdb.c instead.
-
-*************************************************************************/
-static BOOL add_ldap21pwd_entry(struct sam_passwd *newpwd)
-{
- return( modadd_ldappwd_entry(newpwd, ADD_USER)?
- modadd_ldap21pwd_entry(newpwd, ADD_USER):False);
-}
-
-/************************************************************************
- Routine to search the ldap passwd file for an entry matching the username.
- and then modify its password entry. We can't use the startldappwent()/
- getldappwent()/endldappwent() interfaces here as we depend on looking
- in the actual file to decide how much room we have to write data.
- override = False, normal
- override = True, override XXXXXXXX'd out password or NO PASS
-
- do not call this function directly. use passdb.c instead.
-
-************************************************************************/
-static BOOL mod_ldap21pwd_entry(struct sam_passwd *pwd, BOOL override)
-{
- return( modadd_ldappwd_entry(pwd, MODIFY_USER)?
- modadd_ldap21pwd_entry(pwd, MODIFY_USER):False);
-}
+ Return next available RID, starting from 1000
+ ************************************************************************/
-struct ldap_enum_info
+BOOL ldap_allocaterid(uint32 *rid)
{
- LDAP *ldap_struct;
- LDAPMessage *result;
- LDAPMessage *entry;
-};
+ pstring newdn;
+ fstring rid_str;
+ LDAPMod **mods;
+ char *dn;
+ int err;
-static struct ldap_enum_info ldap_ent;
+ DEBUG(2, ("Allocating new RID\n"));
-/***************************************************************
- Start to enumerate the ldap passwd list. Returns a void pointer
- to ensure no modification outside this module.
+ if (!ldap_connect())
+ return (False);
- do not call this function directly. use passdb.c instead.
-
- ****************************************************************/
-static void *startldappwent(BOOL update)
-{
- int scope = LDAP_SCOPE_ONELEVEL;
- int rc;
+ ldap_search_for("(&(id=root)(objectClass=sambaConfig))");
- pstring filter;
+ if (ldap_entry && ldap_get_attribute("nextrid", rid_str))
+ *rid = strtol(rid_str, NULL, 16);
+ else
+ *rid = 1000;
- if (!ldap_open_connection(&ldap_ent.ldap_struct)) /* open a connection to the server */
+ mods = NULL;
+ if(!ldap_entry)
{
- return NULL;
+ ldap_make_mod(&mods, LDAP_MOD_ADD, "objectClass",
+ "sambaConfig");
+ ldap_make_mod(&mods, LDAP_MOD_ADD, "id", "root");
}
- if (!ldap_connect_system(ldap_ent.ldap_struct)) /* connect as system account */
- {
- return NULL;
- }
+ slprintf(rid_str, sizeof(fstring)-1, "%x", (*rid) + 1);
+ ldap_make_mod(&mods, LDAP_MOD_REPLACE, "nextrid", rid_str);
- /* when the class is known the search is much faster */
- switch (0)
+ if (ldap_entry)
{
- case 1:
- {
- pstrcpy(filter, "objectclass = sambaAccount");
- break;
- }
- case 2:
- {
- pstrcpy(filter, "objectclass = sambaTrust");
- break;
- }
- default:
- {
- pstrcpy(filter, "(|(objectclass = sambaTrust)(objectclass = sambaAccount))");
- break;
- }
+ dn = ldap_get_dn(ldap_struct, ldap_entry);
+ err = ldap_modify_s(ldap_struct, dn, mods);
+ free(dn);
+ } else {
+ pstrcpy(newdn, "id=root, ");
+ pstrcat(newdn, lp_ldap_suffix());
+ ldap_add_s(ldap_struct, newdn, mods);
}
- rc = ldap_search_s(ldap_ent.ldap_struct, lp_ldap_suffix(), scope, filter, NULL, 0, &ldap_ent.result);
+ ldap_disconnect();
- DEBUG(2,("%d entries in the base!\n", ldap_count_entries(ldap_ent.ldap_struct, ldap_ent.result) ));
-
- ldap_ent.entry = ldap_first_entry(ldap_ent.ldap_struct, ldap_ent.result);
+ if(err != LDAP_SUCCESS)
+ {
+ DEBUG(0,("nextrid update: %s\n", ldap_err2string(err)));
+ return (False);
+ }
- return &ldap_ent;
+ return (True);
}
-/*************************************************************************
- Routine to return the next entry in the ldap passwd list.
- do not call this function directly. use passdb.c instead.
+/***************************************************************
+ Begin/end account enumeration.
+ ****************************************************************/
- *************************************************************************/
-static struct smb_passwd *getldappwent(void *vp)
+static void *ldap_enumfirst(BOOL update)
{
- static struct smb_passwd user;
- struct ldap_enum_info *ldap_vp = (struct ldap_enum_info *)vp;
+ if (!ldap_connect())
+ return NULL;
- ldap_vp->entry = ldap_next_entry(ldap_vp->ldap_struct, ldap_vp->entry);
+ ldap_search_for("objectclass=sambaAccount");
- if (ldap_vp->entry ! = NULL)
- {
- ldap_get_smb_passwd(ldap_vp->ldap_struct, ldap_vp->entry, &user);
- return &user;
- }
- return NULL;
+ return ldap_struct;
}
-/*************************************************************************
- Routine to return the next entry in the ldap passwd list.
-
- do not call this function directly. use passdb.c instead.
-
- *************************************************************************/
-static struct sam_passwd *getldap21pwent(void *vp)
+static void ldap_enumclose(void *vp)
{
- static struct sam_passwd user;
- struct ldap_enum_info *ldap_vp = (struct ldap_enum_info *)vp;
-
- ldap_vp->entry = ldap_next_entry(ldap_vp->ldap_struct, ldap_vp->entry);
-
- if (ldap_vp->entry ! = NULL)
- {
- ldap_get_sam_passwd(ldap_vp->ldap_struct, ldap_vp->entry, &user);
- return &user;
- }
- return NULL;
+ ldap_disconnect();
}
-/***************************************************************
- End enumeration of the ldap passwd list.
- do not call this function directly. use passdb.c instead.
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
-****************************************************************/
-static void endldappwent(void *vp)
+static SMB_BIG_UINT ldap_getdbpos(void *vp)
{
- struct ldap_enum_info *ldap_vp = (struct ldap_enum_info *)vp;
- ldap_msgfree(ldap_vp->result);
- ldap_unbind(ldap_vp->ldap_struct);
+ return (SMB_BIG_UINT)((ulong)ldap_entry);
}
-/*************************************************************************
- Return the current position in the ldap passwd list as an SMB_BIG_UINT.
- This must be treated as an opaque token.
-
- do not call this function directly. use passdb.c instead.
-
-*************************************************************************/
-static SMB_BIG_UINT getldappwpos(void *vp)
+static BOOL ldap_setdbpos(void *vp, SMB_BIG_UINT tok)
{
- return (SMB_BIG_UINT)0;
+ ldap_entry = (LDAPMessage *)((ulong)tok);
+ return (True);
}
-/*************************************************************************
- Set the current position in the ldap passwd list from SMB_BIG_UINT.
- This must be treated as an opaque token.
- do not call this function directly. use passdb.c instead.
+/*************************************************************************
+ Return smb_passwd information.
+ *************************************************************************/
-*************************************************************************/
-static BOOL setldappwpos(void *vp, SMB_BIG_UINT tok)
+static struct smb_passwd *ldap_getpwbynam(const char *name)
{
- return False;
-}
+ struct smb_passwd *ret;
-/*
- * Ldap derived functions.
- */
+ if(!ldap_connect())
+ return NULL;
-static struct smb_passwd *getldappwnam(char *name)
-{
- return pdb_sam_to_smb(iterate_getsam21pwnam(name));
-}
+ ldap_search_by_name(name);
+ ret = ldap_getpw();
-static struct smb_passwd *getldappwuid(uid_t smb_userid)
-{
- return pdb_sam_to_smb(iterate_getsam21pwuid(smb_userid));
+ ldap_disconnect();
+ return ret;
}
-static struct smb_passwd *getldappwrid(uint32 user_rid)
+static struct smb_passwd *ldap_getpwbyuid(uid_t userid)
{
- return pdb_sam_to_smb(iterate_getsam21pwuid(pdb_user_rid_to_uid(user_rid)));
-}
+ struct smb_passwd *ret;
-static struct smb_passwd *getldappwent(void *vp)
-{
- return pdb_sam_to_smb(getldap21pwent(vp));
-}
+ if(!ldap_connect())
+ return NULL;
-static BOOL add_ldappwd_entry(struct smb_passwd *newpwd)
-{
- return add_ldap21pwd_entry(pdb_smb_to_sam(newpwd));
-}
+ ldap_search_by_uid(userid);
+ ret = ldap_getpw();
-static BOOL mod_ldappwd_entry(struct smb_passwd* pwd, BOOL override)
-{
- return mod_ldap21pwd_entry(pdb_smb_to_sam(pwd), override);
+ ldap_disconnect();
+ return ret;
}
-static BOOL del_ldappwd_entry(const char *name)
+static struct smb_passwd *ldap_getcurrentpw(void *vp)
{
- return False; /* Dummy... */
-}
+ struct smb_passwd *ret;
-static struct sam_disp_info *getldapdispnam(char *name)
-{
- return pdb_sam_to_dispinfo(getldap21pwnam(name));
+ ret = ldap_getpw();
+ ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
+ return ret;
}
-static struct sam_disp_info *getldapdisprid(uint32 rid)
-{
- return pdb_sam_to_dispinfo(getldap21pwrid(rid));
-}
-static struct sam_disp_info *getldapdispent(void *vp)
+/************************************************************************
+ Modify user information given an smb_passwd struct.
+ *************************************************************************/
+static BOOL ldap_addpw(struct smb_passwd *newpwd)
{
- return pdb_sam_to_dispinfo(getldap21pwent(vp));
+ LDAPMod **mods;
+
+ if (!newpwd || !ldap_allocaterid(&newpwd->user_rid))
+ return (False);
+
+ ldap_smbpwmods(newpwd, &mods, LDAP_MOD_ADD);
+ return ldap_makemods("uid", newpwd->unix_name, mods, True);
}
-static struct sam_passwd *getldap21pwuid(uid_t uid)
+static BOOL ldap_modpw(struct smb_passwd *pwd, BOOL override)
{
- return pdb_smb_to_sam(iterate_getsam21pwuid(pdb_uid_to_user_rid(uid)));
+ LDAPMod **mods;
+
+ if (!pwd)
+ return (False);
+
+ ldap_smbpwmods(pwd, &mods, LDAP_MOD_REPLACE);
+ return ldap_makemods("uid", pwd->unix_name, mods, False);
}
-static struct passdb_ops ldap_ops =
+
+static struct smb_passdb_ops ldap_ops =
{
- startldappwent,
- endldappwent,
- getldappwpos,
- setldappwpos,
- getldappwnam,
- getldappwuid,
- getldappwrid,
- getldappwent,
- add_ldappwd_entry,
- mod_ldappwd_entry,
- del_ldappwd_entry,
- getldap21pwent,
- iterate_getsam21pwnam, /* From passdb.c */
- iterate_getsam21pwuid, /* From passdb.c */
- iterate_getsam21pwrid, /* From passdb.c */
- add_ldap21pwd_entry,
- mod_ldap21pwd_entry,
- getldapdispnam,
- getldapdisprid,
- getldapdispent
+ ldap_enumfirst,
+ ldap_enumclose,
+ ldap_getdbpos,
+ ldap_setdbpos,
+
+ ldap_getpwbynam,
+ ldap_getpwbyuid,
+ ldap_getcurrentpw,
+ ldap_addpw,
+ ldap_modpw
};
-struct passdb_ops *ldap_initialize_password_db(void)
+struct smb_passdb_ops *ldap_initialise_password_db(void)
{
- return &ldap_ops;
+ FILE *pwdfile;
+ char *pwdfilename;
+ char *p;
+
+ pwdfilename = lp_ldap_passwd_file();
+
+ if(pwdfilename[0]) {
+ if(pwdfile = sys_fopen(pwdfilename, "r")) {
+ fgets(ldap_secret, sizeof(ldap_secret), pwdfile);
+ if(p = strchr(ldap_secret, '\n'))
+ *p = 0;
+ fclose(pwdfile);
+ } else {
+ DEBUG(0,("Failed to open LDAP passwd file\n"));
+ }
+ }
+
+ return &ldap_ops;
}
#else
- void dummy_function(void);
- void dummy_function(void) { } /* stop some compilers complaining */
+ void ldap_dummy_function(void);
+ void ldap_dummy_function(void) { } /* stop some compilers complaining */
#endif
diff --git a/source/passdb/ldapdb.c b/source/passdb/ldapdb.c
new file mode 100644
index 00000000000..a34227876c6
--- /dev/null
+++ b/source/passdb/ldapdb.c
@@ -0,0 +1,1920 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP protocol helper functions for SAMBA
+ Copyright (C) Jean François Micouleau 1998
+ Copyright (C) Matthew Chapman 1998
+ Copyright (C) Luke Howard (PADL Software Pty Ltd) 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include "includes.h"
+
+#ifdef WITH_NT5LDAP
+
+#include <lber.h>
+#include <ldap.h>
+#include "ldapdb.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/* LDAP password */
+static pstring ldap_secret;
+
+/* Internal search func */
+static BOOL __ldapdb_search (LDAPDB * hds, const char *dn, int scope, const char *filter, char *const *attrs, int sizelimit);
+/* Step through to next entry from a synchronous search result */
+static BOOL ldapdb_next_s (LDAPDB * hds);
+/* Step through to next entry from an asynchronous search result */
+static BOOL ldapdb_next (LDAPDB * hds);
+
+/* Use the synchronous API. This must be set for the life of the handle! */
+#define LDAPDB_RETRIEVE_SYNCHRONOUSLY 0x00000001
+
+struct ldapdb_conn_info
+{
+ LDAP *ld;
+ int refs;
+};
+
+typedef struct ldapdb_conn_info LDAPDBCONN, *PLDAPDBCONN;
+
+/* we should eventually use this to make things reentrant. globals are bad */
+struct ldapdb_handle_info
+{
+ LDAPDBCONN *conn;
+ union
+ {
+ int msgid; /* msgid of request */
+ LDAPMessage *chain; /* chain, for LDAPDB_RETRIEVE_SYNCHRONOUSLY */
+ }
+ res;
+ LDAPMessage *entry; /* entry */
+ uint32 flags;
+};
+
+BOOL ldapdb_init(void)
+{
+ FILE *pwdfile;
+ char *pwdfilename;
+ char *p;
+
+ pwdfilename = lp_ldap_passwd_file();
+
+ if (pwdfilename[0])
+ {
+ if((pwdfile = sys_fopen(pwdfilename, "r")))
+ {
+ fgets(ldap_secret, sizeof(ldap_secret), pwdfile);
+ if((p = strchr(ldap_secret, '\n')))
+ *p = 0;
+ fclose(pwdfile);
+ return True;
+ }
+ else
+ {
+ DEBUG(0,("Failed to open LDAP passwd file\n"));
+ return False;
+ }
+ }
+
+#if 0
+ if (!pwdb_initialise(True))
+ {
+ return False;
+ }
+#endif
+
+ return True;
+}
+
+/*******************************************************************
+ Create a handle sharing the same session as another handle
+ ******************************************************************/
+BOOL
+ldapdb_dup (LDAPDB * in, LDAPDB ** out)
+{
+ *out = calloc (1, sizeof (LDAPDB));
+ if (*out == NULL)
+ {
+ return False;
+ }
+ if (in)
+ {
+ /* struct copy */
+ (*out)->conn = in->conn;
+ in->conn->refs++;
+ if (in->flags & LDAPDB_RETRIEVE_SYNCHRONOUSLY)
+ {
+ (*out)->res.chain = NULL; /* clone? */
+ (*out)->entry = NULL; /* in->entry; */
+ }
+ else
+ {
+ (*out)->res.msgid = -1; /* in->res.msgid; */
+ (*out)->entry = NULL;
+ }
+ (*out)->flags = in->flags;
+ }
+ else
+ {
+ (*out)->conn = calloc (1, sizeof (LDAPDBCONN));
+ if ((*out)->conn == NULL)
+ {
+ free (*out);
+ return False;
+ }
+ (*out)->conn->ld = NULL;
+ (*out)->conn->refs = 1;
+ (*out)->res.msgid = -1;
+ (*out)->flags = 0;
+ (*out)->entry = NULL;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ Create a new connection to the LDAP server (or return a cached
+ one)
+ ******************************************************************/
+BOOL
+ldapdb_open (LDAPDB ** phds)
+{
+ int err, version = lp_ldap_protocol_version ();
+ LDAPDB *hds;
+ static LDAPDB *__ldapdb_handle = NULL;
+ static pid_t __ldapdb_pid = -1;
+ pid_t pid;
+
+ DEBUG(3,("ldapdb_open\n"));
+
+ if (*phds != NULL)
+ {
+ /* we've got a handle, so let's just use it! */
+ hds = *phds;
+ }
+ else
+ {
+ /* try and use the cached handle, otherwise alloc one which we will cache */
+ if (!ldapdb_dup (__ldapdb_handle, &hds))
+ {
+ DEBUG (0, ("ldapdb_dup failed"));
+ return False; /* malloc failed */
+ }
+ }
+
+ /* If we've forked, close the connection but don't send an unbind. */
+ pid = getpid ();
+ if (__ldapdb_pid != pid && __ldapdb_handle != NULL)
+ {
+ int sd = -1;
+ if (ldap_get_option (__ldapdb_handle->conn->ld, LDAP_OPT_DESC, &sd) == 0)
+ {
+ close (sd);
+ sd = -1;
+ (void) ldap_set_option (__ldapdb_handle->conn->ld, LDAP_OPT_DESC, &sd);
+ }
+ ldap_unbind (__ldapdb_handle->conn->ld);
+ __ldapdb_handle->conn->ld = NULL;
+ }
+
+ /* only try to open the connection if it's not already opened */
+ if (hds->conn->ld == NULL)
+ {
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+ /* can support LDAP URLs. */
+ char *url = lp_ldap_url ();
+
+ if (url != NULL && url[0] != '\0' &&
+ ((err = ldap_initialize (&hds->conn->ld, url)) != LDAP_SUCCESS))
+ {
+ DEBUG (0, ("ldap_initialize: %s\n", ldap_err2string (err)));
+ ldapdb_close (&hds);
+ return False;
+ }
+ else
+#endif
+ if (!(hds->conn->ld = ldap_open (lp_ldap_server (), lp_ldap_port ())))
+ {
+ DEBUG (0, ("ldap_open: %s\n", strerror (errno)));
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ ldap_set_option (hds->conn->ld, LDAP_OPT_PROTOCOL_VERSION, &version);
+
+ if (strcmp (lp_ldap_bind_as (), "") != 0 || version < 3)
+ {
+ err = ldap_simple_bind_s (hds->conn->ld, lp_ldap_bind_as (), ldap_secret);
+ if (err != LDAP_SUCCESS)
+ {
+ DEBUG (0, ("ldap_simple_bind_s: %s\n", ldap_err2string (err)));
+ ldapdb_close (&hds);
+ return False;
+ }
+ } /* otherwise, using V3 and anonymous credentials; avoid binding at all */
+
+ DEBUG (2, ("Connected to LDAP server\n"));
+ }
+
+ if (__ldapdb_handle == NULL)
+ {
+ /* we created a handle, cache it */
+ __ldapdb_handle = hds;
+ return ldapdb_dup (__ldapdb_handle, phds);
+ }
+ else
+ {
+ /* return the dupped handle */
+ *phds = hds;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ close connections to the LDAP server.
+ ******************************************************************/
+
+void
+ldapdb_close (LDAPDB ** phds)
+{
+ LDAPDB *hds;
+
+ DEBUG(3,("ldapdb_close\n"));
+
+ if (*phds == NULL)
+ {
+ return;
+ }
+
+ hds = *phds;
+
+ if (hds->flags & LDAPDB_RETRIEVE_SYNCHRONOUSLY)
+ {
+ if (hds->res.chain != NULL)
+ {
+ ldap_msgfree (hds->res.chain);
+ }
+ }
+ else
+ {
+ if (hds->res.msgid > -1)
+ {
+ ldap_abandon (hds->conn->ld, hds->res.msgid);
+ }
+ if (hds->entry != NULL)
+ {
+ ldap_msgfree (hds->entry);
+ }
+ }
+
+ hds->conn->refs--;
+ if (hds->conn->refs < 1)
+ {
+ ldap_unbind (hds->conn->ld);
+ free (hds->conn);
+ DEBUG (2, ("LDAP connection closed\n"));
+ }
+
+ free (hds);
+ *phds = NULL;
+
+ DEBUG (2, ("LDAPDB handle deallocated\n"));
+ return;
+}
+
+/*******************************************************************
+ Fetch the next result from the server
+ ******************************************************************/
+static BOOL
+ldapdb_next (LDAPDB * hds)
+{
+ int rc, parserc;
+ BOOL ret = False;
+ LDAPMessage *entry;
+
+ DEBUG(3,("ldapdb_next\n"));
+
+ if (hds->res.msgid < 0)
+ {
+ return False;
+ }
+
+ do
+ {
+ rc = ldap_result (hds->conn->ld, hds->res.msgid, LDAP_MSG_ONE, NULL, &entry);
+ switch (rc)
+ {
+ case LDAP_RES_SEARCH_ENTRY:
+ ret = True;
+ break;
+ case LDAP_RES_SEARCH_RESULT:
+ parserc = ldap_parse_result (hds->conn->ld, entry, NULL, NULL, NULL, NULL, NULL, 1);
+ if (parserc != LDAP_SUCCESS)
+ {
+ ldap_abandon (hds->conn->ld, hds->res.msgid);
+ DEBUG (2, ("ldap_parse_result: %s\n", ldap_err2string (parserc)));
+ hds->res.msgid = -1;
+ }
+ ret = False;
+ break;
+ case 0:
+ case -1:
+ /* here perhaps we should reopen the conn? */
+ default:
+ ldap_msgfree (entry);
+ ldap_abandon (hds->conn->ld, hds->res.msgid);
+ hds->res.msgid = -1;
+ ret = False;
+ break;
+ }
+ }
+#ifdef LDAP_RES_SEARCH_REFERENCE
+ while (rc == LDAP_RES_SEARCH_REFERENCE);
+#else
+ while (0);
+#endif
+
+ if (hds->entry != NULL)
+ {
+ ldap_msgfree (hds->entry);
+ hds->entry = NULL;
+ }
+
+ if (ret == True)
+ {
+ hds->entry = entry;
+ }
+
+ return ret;
+}
+
+/*******************************************************************
+ Fetch the next result off an already-fetched result chain
+ ******************************************************************/
+static BOOL
+ldapdb_next_s (LDAPDB * hds)
+{
+ DEBUG(3,("ldapdb_next_s\n"));
+
+ if (hds->res.chain == NULL)
+ {
+ return False;
+ }
+
+ if (hds->entry == NULL)
+ {
+ hds->entry = ldap_first_entry (hds->conn->ld, hds->res.chain);
+ }
+ else
+ {
+ hds->entry = ldap_next_entry (hds->conn->ld, hds->entry);
+ }
+
+ if (hds->entry == NULL)
+ {
+ /* No more data. */
+ ldap_msgfree (hds->res.chain);
+ hds->res.chain = NULL;
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ Fetch the next result as appropriate to the search method
+ ******************************************************************/
+BOOL
+ldapdb_seq (LDAPDB * hds)
+{
+ DEBUG(3,("ldapdb_seq flags=[%08x]\n", hds->flags));
+
+ if (hds->flags & LDAPDB_RETRIEVE_SYNCHRONOUSLY)
+ {
+ return ldapdb_next_s (hds);
+ }
+ else
+ {
+ return ldapdb_next (hds);
+ }
+}
+
+/*******************************************************************
+ Count search results, if we retrieved them all
+ ******************************************************************/
+BOOL
+ldapdb_count_entries (LDAPDB * hds, int *n)
+{
+ DEBUG(3,("ldapdb_count_entries flags=[%08x]\n", hds->flags));
+
+ if (hds->flags & LDAPDB_RETRIEVE_SYNCHRONOUSLY && hds->res.chain)
+ {
+ *n = ldap_count_entries (hds->conn->ld, hds->res.chain);
+ return True;
+ }
+ return False;
+}
+
+/*******************************************************************
+ Set synchronous flag
+ ******************************************************************/
+BOOL
+ldapdb_set_synchronous (LDAPDB * hds, BOOL how)
+{
+ BOOL old;
+
+ old = (hds->flags & LDAPDB_RETRIEVE_SYNCHRONOUSLY);
+ if (how)
+ {
+ hds->flags |= LDAPDB_RETRIEVE_SYNCHRONOUSLY;
+ }
+ else
+ {
+ hds->flags &= ~LDAPDB_RETRIEVE_SYNCHRONOUSLY;
+ }
+
+ return old;
+}
+
+/*******************************************************************
+ Check whether we have an entry waiting
+ ******************************************************************/
+BOOL
+ldapdb_peek (LDAPDB * hds)
+{
+ return (hds->entry == NULL) ? False : True;
+}
+
+/*******************************************************************
+ Delete an entry from the directory
+ ******************************************************************/
+BOOL
+ldapdb_delete (LDAPDB * hds, const char *dn)
+{
+ DEBUG(3,("ldapdb_delete dn=[%s]\n", dn));
+
+ return (ldap_delete_s (hds->conn->ld, dn) == LDAP_SUCCESS) ? True : False;
+}
+
+/*******************************************************************
+ Wrapper around dn
+ ******************************************************************/
+
+BOOL
+ldapdb_get_dn (LDAPDB * hds, char **dn)
+{
+ *dn = ldap_get_dn (hds->conn->ld, hds->entry);
+ if (*dn == NULL)
+ {
+ return False;
+ }
+ return True;
+}
+
+/*******************************************************************
+ Read an entry from the directory
+ ******************************************************************/
+BOOL
+ldapdb_read (LDAPDB * hds, const char *dn, char *const *attrs)
+{
+ return __ldapdb_search (hds, dn, LDAP_SCOPE_BASE, "(objectClass=*)", attrs, 1);
+}
+
+/*******************************************************************
+ Compose a DN from the global suffix + relative DN
+ ******************************************************************/
+const char *
+__ldapdb_compose_dn (const char *context, pstring out_str)
+{
+ if (context != NULL)
+ {
+ pstrcpy (out_str, context);
+ if (context[strlen (context) - 1] == ',')
+ {
+ pstrcat (out_str, lp_ldap_suffix ());
+ }
+ return out_str;
+ }
+ else
+ {
+ return lp_ldap_suffix ();
+ }
+}
+
+/*******************************************************************
+ Search in the directory
+ ******************************************************************/
+BOOL
+ldapdb_search (LDAPDB * hds, const char *context, const char *filter, char *const *attrs, int sizelimit)
+{
+ pstring base;
+ int scope;
+
+ if (context != NULL)
+ {
+ if (context[0] != '\0')
+ {
+ scope = LDAP_SCOPE_ONELEVEL;
+ }
+ else
+ {
+ scope = LDAP_SCOPE_BASE;
+ }
+ }
+ else
+ {
+ scope = LDAP_SCOPE_SUBTREE;
+ }
+
+ return __ldapdb_search (hds, __ldapdb_compose_dn (context, base), scope, filter, attrs, sizelimit);
+}
+
+/*******************************************************************
+ Search implementation
+ ******************************************************************/
+static BOOL
+__ldapdb_search (LDAPDB * hds, const char *dn, int scope, const char *filter, char *const *attrs, int sizelimit)
+{
+ int err;
+
+ ldap_set_option (hds->conn->ld, LDAP_OPT_SIZELIMIT, &sizelimit);
+
+ DEBUG (2, ("Searching in [%s] for [%s], scope [%d], sizelimit [%d]\n", dn, filter, scope, sizelimit));
+
+ if (hds->flags & LDAPDB_RETRIEVE_SYNCHRONOUSLY)
+ {
+ if (hds->res.chain != NULL)
+ {
+ ldap_msgfree (hds->res.chain);
+ hds->res.chain = NULL;
+ }
+ hds->entry = NULL;
+ err = ldap_search_s (hds->conn->ld, dn, scope, filter, (char **) attrs, 0, &hds->res.chain);
+ if (err != LDAP_SUCCESS)
+ {
+ DEBUG (0, ("ldap_search_s: %s\n", ldap_err2string (err)));
+ return False;
+ }
+ }
+ else
+ {
+ if (hds->res.msgid > 0)
+ {
+ ldap_abandon (hds->conn->ld, hds->res.msgid);
+ }
+ if (hds->entry != NULL)
+ {
+ ldap_msgfree (hds->entry);
+ hds->entry = NULL;
+ }
+ hds->res.msgid = ldap_search (hds->conn->ld, dn, scope, filter, (char **) attrs, 0);
+ if (hds->res.msgid < 0)
+ {
+ int err2 = ldap_get_option (hds->conn->ld, LDAP_OPT_ERROR_NUMBER, &err);
+ if (err2 != LDAP_SUCCESS)
+ {
+ err = err2;
+ }
+ DEBUG (0, ("ldap_search: %s\n", ldap_err2string (err)));
+ return False;
+ }
+ }
+
+ return ldapdb_seq (hds);
+}
+
+/*******************************************************************
+ Get the entry
+ ******************************************************************/
+BOOL
+ldapdb_get_entry (LDAPDB * hds, LDAPMessage ** res)
+{
+ if (hds->entry)
+ {
+ *res = hds->entry;
+ return True;
+ }
+
+ return False;
+}
+
+/*******************************************************************
+ Copy an attribute single value into a user supplied buffer
+ ******************************************************************/
+BOOL
+ldapdb_get_value (LDAPDB * hds, const char *attribute, char *buf, size_t len)
+{
+ char **values;
+
+ values = ldap_get_values (hds->conn->ld, hds->entry, attribute);
+ if (values == NULL)
+ {
+ return False;
+ }
+ if (values[0] == NULL)
+ {
+ ldap_value_free (values);
+ return False;
+ }
+
+ safe_strcpy (buf, values[0], len);
+ DEBUG (3, ("ldapdb_get_value: [%s] = [%s]\n", attribute, buf));
+
+ ldap_value_free (values);
+
+ return True;
+}
+
+BOOL ldapdb_get_uint32(LDAPDB *hds, const char *attribute, uint32 *val)
+{
+ fstring temp;
+ BOOL ret;
+
+ ret = ldapdb_get_value(hds, attribute, temp, sizeof(temp)-1);
+ if (ret)
+ {
+ *val = strtol(temp, NULL, 10);
+ if ((*val == LONG_MAX || *val == LONG_MIN) && errno == ERANGE)
+ ret = False;
+ else
+ ret = True;
+ }
+
+ return ret;
+}
+
+BOOL ldapdb_get_unistr_value(LDAPDB *hds, const char *attribute, UNISTR2 *buf)
+{
+ char **values;
+
+ values = ldap_get_values (hds->conn->ld, hds->entry, attribute);
+ if (values == NULL)
+ {
+ return False;
+ }
+ if (values[0] == NULL)
+ {
+ ldap_value_free (values);
+ return False;
+ }
+
+ utf8_to_unistr2(buf, values[0]);
+ DEBUG (3, ("ldapdb_get_unistr_value: [%s] = [%s]\n", attribute, values[0]));
+
+ ldap_value_free (values);
+
+ return True;
+}
+
+/*******************************************************************
+ Get values for an attribute, caller frees data
+ ******************************************************************/
+BOOL
+ldapdb_get_values (LDAPDB * hds, const char *attribute, char ***valuesp)
+{
+ char **values;
+
+ values = ldap_get_values (hds->conn->ld, hds->entry, attribute);
+ if (values == NULL)
+ {
+ return False;
+ }
+
+ if (values[0] == NULL)
+ {
+ ldap_value_free (values);
+ return False;
+ }
+
+ DEBUG (3, ("ldap_get_values: [%s] = [%s] ... \n", attribute, values[0]));
+ *valuesp = values;
+
+ return True;
+}
+
+BOOL ldapdb_oc_check(LDAPDB *hds, const char *ocname)
+{
+ char **values;
+ char **p;
+
+ if (!ldapdb_get_values(hds, "objectClass", &values))
+ {
+ return False;
+ }
+
+ for (p = values; *p != NULL; p++)
+ {
+ if (!strcasecmp(*p, ocname))
+ {
+ ldap_value_free(values);
+ return True;
+ }
+ }
+
+ ldap_value_free(values);
+ return False;
+}
+
+BOOL
+ldapdb_get_value_len (LDAPDB * hds, const char *attribute, struct berval ** value)
+{
+ struct berval **values;
+
+ values = ldap_get_values_len (hds->conn->ld, hds->entry, attribute);
+ if (values == NULL)
+ {
+ return False;
+ }
+
+ if (values[0] == NULL)
+ {
+ ldap_value_free_len (values);
+ return False;
+ }
+
+ *value = ber_bvdup (values[0]);
+ if (*value == NULL)
+ {
+ ldap_value_free_len (values);
+ return False;
+ }
+
+ ldap_value_free_len (values);
+
+ return True;
+}
+
+
+BOOL
+ldapdb_get_values_len (LDAPDB * hds, const char *attribute, struct berval *** valuep)
+{
+ struct berval **values;
+
+ values = ldap_get_values_len (hds->conn->ld, hds->entry, attribute);
+ if (values == NULL)
+ {
+ return False;
+ }
+
+ if (values[0] == NULL)
+ {
+ ldap_value_free_len (values);
+ return False;
+ }
+
+ *valuep = values;
+
+ return True;
+}
+
+/*******************************************************************
+ Get the "objectSid" attribute and decode into a DOM_SID
+ ******************************************************************/
+BOOL
+ldapdb_get_sid (LDAPDB * hds, const char *attribute, DOM_SID * sid)
+{
+ struct berval **bv;
+ BOOL ret;
+
+ bv = ldap_get_values_len (hds->conn->ld, hds->entry, attribute);
+ if (bv == NULL)
+ {
+ return False;
+ }
+
+ ret = berval_to_sid (bv[0], sid);
+ ldap_value_free_len (bv);
+
+ return ret;
+}
+
+BOOL
+ldapdb_get_sids (LDAPDB * hds, const char *attribute, DOM_SID *** sid)
+{
+ struct berval **bv;
+ int i, nsids;
+
+ bv = ldap_get_values_len (hds->conn->ld, hds->entry, attribute);
+ if (bv == NULL)
+ {
+ return False;
+ }
+
+ nsids = ldap_count_values_len (bv);
+ *sid = calloc (nsids, sizeof (DOM_SID *));
+ if (*sid == NULL)
+ {
+ ldap_value_free_len (bv);
+ return False;
+ }
+
+ for (i = 0; i < nsids; i++)
+ {
+ (*sid)[i] = malloc (sizeof (DOM_SID));
+ if ((*sid)[i] == NULL)
+ {
+ ldap_value_free_len (bv);
+ return False;
+ }
+ if (!berval_to_sid (bv[i], (*sid)[i]))
+ {
+ ldap_value_free_len (bv);
+ /* leaks */
+ return False;
+ }
+ }
+
+ ldap_value_free_len (bv);
+ return True;
+}
+
+/*******************************************************************
+ Get the "objectSid" attribute and decode into a RID
+ ******************************************************************/
+BOOL
+ldapdb_get_rid (LDAPDB * hds, const char *attribute, uint32 * rid)
+{
+ struct berval **bv;
+ BOOL ret;
+
+ bv = ldap_get_values_len (hds->conn->ld, hds->entry, attribute);
+ if (bv == NULL)
+ {
+ return False;
+ }
+
+ ret = berval_to_rid (bv[0], rid);
+ ldap_value_free_len (bv);
+
+ return ret;
+}
+
+/************************************************************************
+Adds a binary modification to a LDAPMod queue.
+************************************************************************/
+
+BOOL
+ldapdb_queue_mod_len (LDAPMod *** modlist, int modop, const char *attribute, struct berval * value)
+{
+ LDAPMod **mods;
+ int i;
+ int j;
+
+ mods = *modlist;
+
+ if (mods == NULL)
+ {
+ mods = (LDAPMod **) malloc (sizeof (LDAPMod *));
+ if (mods == NULL)
+ {
+ return False;
+ }
+ mods[0] = NULL;
+ }
+
+ for (i = 0; mods[i] != NULL; ++i)
+ {
+ if ((mods[i]->mod_op & (~LDAP_MOD_BVALUES)) == modop &&
+ !strcasecmp (mods[i]->mod_type, attribute))
+ {
+ break;
+ }
+ }
+
+ if (mods[i] == NULL)
+ {
+ mods = (LDAPMod **) realloc (mods, (i + 2) * sizeof (LDAPMod *));
+ if (mods == NULL)
+ {
+ if (*modlist)
+ {
+ ldap_mods_free(*modlist, 1);
+ *modlist = NULL;
+ }
+ return False;
+ }
+ mods[i] = (LDAPMod *) malloc (sizeof (LDAPMod));
+ if (mods[i] == NULL)
+ {
+ if (*modlist)
+ {
+ ldap_mods_free(*modlist, 1);
+ *modlist = NULL;
+ }
+ return False;
+ }
+ mods[i]->mod_op = modop | LDAP_MOD_BVALUES;
+ mods[i]->mod_bvalues = NULL;
+ mods[i]->mod_type = strdup (attribute);
+ mods[i + 1] = NULL;
+ }
+
+ if (value)
+ {
+ j = 0;
+ if (mods[i]->mod_values)
+ {
+ for (; mods[i]->mod_values[j]; j++);
+ }
+ mods[i]->mod_bvalues = (struct berval **) realloc (mods[i]->mod_values,
+ (j + 2) * sizeof (struct berval *));
+ if (mods[i]->mod_bvalues == NULL)
+ {
+ if (*modlist)
+ {
+ ldap_mods_free(*modlist, 1);
+ *modlist = NULL;
+ }
+ return False;
+ }
+ /* caller relinquishes ownership of value */
+ mods[i]->mod_bvalues[j] = value;
+ mods[i]->mod_bvalues[j + 1] = NULL;
+ }
+
+ *modlist = mods;
+ return True;
+}
+
+/************************************************************************
+Adds a modification to a LDAPMod queue.
+************************************************************************/
+BOOL
+ldapdb_queue_mod (LDAPMod *** modlist, int modop, const char *attribute, const char *value)
+{
+ LDAPMod **mods;
+ int i;
+ int j;
+
+ DEBUG (3, ("set: [%s] = [%s]\n", attribute, value));
+
+ mods = *modlist;
+
+ if (mods == NULL)
+ {
+ mods = (LDAPMod **) malloc (sizeof (LDAPMod *));
+ if (mods == NULL)
+ {
+ return False;
+ }
+ mods[0] = NULL;
+ }
+
+ for (i = 0; mods[i] != NULL; ++i)
+ {
+ if (mods[i]->mod_op == modop &&
+ !strcasecmp (mods[i]->mod_type, attribute))
+ {
+ break;
+ }
+ }
+
+ if (mods[i] == NULL)
+ {
+ mods = (LDAPMod **) realloc (mods, (i + 2) * sizeof (LDAPMod *));
+ if (mods == NULL)
+ {
+ if (*modlist)
+ {
+ ldap_mods_free(*modlist, 1);
+ *modlist = NULL;
+ }
+ return False;
+ }
+ mods[i] = (LDAPMod *) malloc (sizeof (LDAPMod));
+ if (mods[i] == NULL)
+ {
+ if (*modlist)
+ {
+ ldap_mods_free(*modlist, 1);
+ *modlist = NULL;
+ }
+ return False;
+ }
+ mods[i]->mod_op = modop;
+ mods[i]->mod_values = NULL;
+ mods[i]->mod_type = strdup (attribute);
+ mods[i + 1] = NULL;
+ }
+
+ if (value)
+ {
+ j = 0;
+ if (mods[i]->mod_values)
+ {
+ for (; mods[i]->mod_values[j]; j++);
+ }
+ mods[i]->mod_values = (char **) realloc (mods[i]->mod_values,
+ (j + 2) * sizeof (char *));
+ if (mods[i]->mod_values == NULL)
+ {
+ if (*modlist)
+ {
+ ldap_mods_free(*modlist, 1);
+ *modlist = NULL;
+ }
+ return False;
+ }
+ mods[i]->mod_values[j] = strdup (value);
+ if (mods[i]->mod_values[j] == NULL)
+ {
+ if (*modlist)
+ {
+ ldap_mods_free(*modlist, 1);
+ *modlist = NULL;
+ }
+ return False;
+ }
+ mods[i]->mod_values[j + 1] = NULL;
+ }
+
+ *modlist = mods;
+
+ return True;
+}
+
+BOOL ldapdb_queue_unistr_mod(LDAPMod ***modlist,int modop, const char *attribute, const UNISTR2 *value)
+{
+ pstring buffer;
+
+ if (value == NULL)
+ {
+ /* silently fail */
+ return True;
+ }
+
+ unistr2_to_utf8(buffer, value, sizeof(buffer)-1);
+
+ return ldapdb_queue_mod(modlist, modop, attribute, buffer);
+}
+
+BOOL ldapdb_queue_uint32_mod(LDAPMod ***modlist, int modop, const char *attribute, uint32 value)
+{
+ fstring buffer;
+
+ slprintf(buffer, sizeof(buffer)-1, "%u", value);
+
+ return ldapdb_queue_mod(modlist, modop, attribute, buffer);
+}
+
+/************************************************************************
+ Update a directory entry, creating if needed / desired. Creates
+ the DN based on the supplied attribute/value, if we're creating an
+ entry.
+*************************************************************************/
+BOOL
+ldapdb_update (PLDAPDB _hds, const char *where, const char *rdnattr, const char *rdnvalue, LDAPMod ** mods, BOOL isadd)
+{
+ pstring filter;
+ LDAPDB *hds;
+ BOOL ret;
+ BOOL create;
+ char *dn;
+ pstring pdn;
+
+ if (!LDAPDB_OPEN (_hds, &hds))
+ {
+ return False;
+ }
+
+ slprintf (filter, sizeof (filter) - 1, "(%s=%s)", rdnattr, rdnvalue);
+ if (!ldapdb_search (hds, where, filter, NULL, 1))
+ {
+ pstring dnbuf;
+
+ if (isadd == False)
+ {
+ /* The entry doesn't exist, we don't want to create it. */
+ DEBUG (3, ("update: [%s] in [%s] doesn't exist, isadd=[%d]\n", filter, where, isadd));
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ /* create */
+ slprintf (pdn, sizeof (pdn) - 1, "%s=%s,%s", rdnattr, rdnvalue, __ldapdb_compose_dn (where, dnbuf));
+ DEBUG (3, ("update: composed dn [%s]\n", pdn));
+ create = True;
+ dn = pdn;
+ }
+ else
+ {
+ create = False;
+ dn = ldap_get_dn (hds->conn->ld, hds->entry);
+ DEBUG (3, ("update: using dn [%s]", dn));
+ }
+
+ ret = ldapdb_commit (hds, dn, mods, create);
+ if (!create)
+ {
+ free (dn);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+/************************************************************************
+ Update/create an entry in the directory
+*************************************************************************/
+BOOL
+ldapdb_commit (LDAPDB * hds, const char *dn, LDAPMod ** mods, BOOL add)
+{
+ int err;
+ BOOL ret;
+
+ if (add)
+ {
+ /* Generate a GUID. */
+ struct berval *uuid;
+
+ uuid = (struct berval *)malloc(sizeof(*uuid));
+ if (uuid == NULL)
+ {
+ free(uuid);
+ }
+
+ /* this isn't strictly correct, it will have to do for now */
+ uuid->bv_len = 16;
+ uuid->bv_val = malloc(uuid->bv_len);
+ if (uuid->bv_val == NULL)
+ {
+ free(uuid);
+ return False;
+ }
+
+ generate_random_buffer(uuid->bv_val, uuid->bv_len, False);
+ if (!ldapdb_queue_mod_len(&mods, LDAP_MOD_ADD, "objectGuid", uuid))
+ {
+ ber_bvfree(uuid);
+ return False;
+ }
+
+ err = ldap_add_s (hds->conn->ld, dn, mods);
+ }
+ else
+ {
+ err = ldap_modify_s (hds->conn->ld, dn, mods);
+ }
+
+ if (err == LDAP_SUCCESS)
+ {
+ DEBUG (2, ("%s entry [%s]\n", (add ? "Added" : "Modified"), dn));
+ ret = True;
+ }
+ else
+ {
+ DEBUG (0, ("%s: %s\n", (add ? "ldap_add_s" : "ldap_modify_s"), ldap_err2string (err)));
+ ret = False;
+ }
+
+ ldap_mods_free (mods, 1);
+
+ return ret;
+}
+
+/************************************************************************
+Return next available RID, starting from 1000
+************************************************************************/
+
+BOOL
+ldapdb_allocate_rid (PLDAPDB _hds, uint32 * rid)
+{
+ fstring rid_str;
+ LDAPMod **mods = NULL;
+ LDAPDB *hds;
+ char *attrs[] =
+ {"nextRid", NULL};
+ BOOL newdomain, ret;
+
+ DEBUG (2, ("Allocating new RID\n"));
+
+ if (!LDAPDB_OPEN (_hds, &hds))
+ {
+ return False;
+ }
+
+ if (__ldapdb_search (hds, lp_ldap_suffix (), LDAP_SCOPE_BASE, "(objectClass=domain)", attrs, 1) &&
+ ldapdb_get_fvalue (hds, "nextRid", rid_str))
+ {
+ *rid = strtol (rid_str, NULL, 10);
+ newdomain = False;
+ }
+ else
+ {
+ *rid = 1000;
+ newdomain = True;
+ }
+
+ if (newdomain)
+ {
+ if (!ldapdb_queue_mod (&mods, LDAP_MOD_ADD, "objectClass", "top") ||
+ !ldapdb_queue_mod (&mods, LDAP_MOD_ADD, "objectClass", "samDomain"))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+ }
+
+ slprintf (rid_str, sizeof (fstring) - 1, "%u", (*rid) + 1);
+ if (!ldapdb_queue_mod (&mods, LDAP_MOD_REPLACE, "nextRid", rid_str))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ ret = ldapdb_commit (hds, lp_ldap_suffix (), mods, newdomain);
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+/*******************************************************************
+ Decode an objectSid attribute
+ ******************************************************************/
+
+BOOL
+berval_to_sid (const struct berval * bv, DOM_SID * sid)
+{
+
+ prs_struct ps;
+ BOOL ret;
+
+ if (bv == NULL)
+ {
+ return False;
+ }
+
+ memset (sid, 0, sizeof(*sid));
+
+ /* True for reading */
+ prs_create (&ps, bv->bv_val, bv->bv_len, 4, True);
+
+ ret = smb_io_dom_sid ("berval_to_sid", sid, &ps, 0);
+
+ if (ret)
+ {
+ fstring sid_str;
+ sid_to_string (sid_str, sid);
+ DEBUG (3, ("berval_to_sid: bv->len = [%ld] SID = [%s]\n", bv->bv_len, sid_str));
+ }
+ else
+ {
+ DEBUG (3, ("berval_to_sid: smb_io_dom_sid failed\n"));
+ }
+
+ return ret;
+}
+
+BOOL
+sid_to_berval (const DOM_SID * sid, struct berval ** siddata)
+{
+ prs_struct ps;
+ struct berval *bv;
+ BOOL ret;
+
+ bv = (struct berval *) malloc (sizeof (struct berval));
+ if (bv == NULL)
+ {
+ return False;
+ }
+
+ prs_init (&ps, 0, 4, False);
+ ret = smb_io_dom_sid ("sid_to_berval", (DOM_SID *) sid, &ps, 0);
+ if (ret == False)
+ {
+ prs_free_data(&ps);
+ free (bv);
+ return False;
+ }
+
+ bv->bv_val = prs_data (&ps, 0);
+ bv->bv_len = prs_buf_len (&ps); /* ps.offset */
+
+ *siddata = bv;
+
+ return True;
+}
+
+BOOL
+berval_to_rid (struct berval * siddata, uint32 * rid)
+{
+ DOM_SID sid;
+
+ if (berval_to_sid (siddata, &sid) == False)
+ {
+ return False;
+ }
+
+ if (!sid_front_equal (&global_sam_sid, &sid))
+ {
+ fstring sid_str;
+ sid_to_string (sid_str, &sid);
+ DEBUG (0, ("berval_to_rid: SID %s is in the wrong domain\n", sid_str));
+ return False;
+ }
+
+
+ sid_split_rid (&sid, rid);
+
+ return True;
+}
+
+BOOL
+rid_to_berval (uint32 rid, struct berval ** siddata)
+{
+ DOM_SID sid;
+
+ sid_copy (&sid, &global_sam_sid);
+ if (sid_append_rid (&sid, rid) == False)
+ {
+ return False;
+ }
+
+ return sid_to_berval (&sid, siddata);
+}
+
+/*
+ * XXX This is most likely VERY broken
+ */
+BOOL
+berval_to_unicodepwd (const struct berval * bv, uint8 smbntpwd[16])
+{
+ if (bv->bv_len != 16)
+ {
+ return False;
+ }
+
+ memcpy (smbntpwd, bv->bv_val, bv->bv_len);
+
+ return True;
+}
+
+BOOL
+berval_to_dbcspwd (const struct berval * bv, uint8 smblmpwd[16])
+{
+ return berval_to_unicodepwd (bv, smblmpwd);
+}
+
+BOOL
+unicodepwd_to_berval (const uint8 smbntpwd[16], struct berval ** bvp)
+{
+ struct berval *bv = (struct berval *) malloc (sizeof (struct berval));
+ if (bv == NULL)
+ {
+ return False;
+ }
+
+ bv->bv_len = 16;
+ bv->bv_val = malloc (16);
+ if (bv->bv_val == NULL)
+ {
+ free (bv);
+ return False;
+ }
+
+ memcpy (bv->bv_val, smbntpwd, 16);
+ *bvp = bv;
+
+ return True;
+}
+
+BOOL
+dbcspwd_to_berval (const uint8 smblmpwd[16], struct berval ** bvp)
+{
+ return unicodepwd_to_berval (smblmpwd, bvp);
+}
+
+/*******************************************************************
+ dc=foo,dc=tld to foo.tld mapping
+ ******************************************************************/
+BOOL
+ldapdb_dnsdomain_to_dn (const char *domain_in, pstring dn)
+{
+ char *domain, *s;
+ BOOL comma;
+
+ if (domain_in == NULL)
+ {
+ return False;
+ }
+
+ domain = strdup (domain_in);
+ if (domain == NULL)
+ {
+ return False;
+ }
+
+ dn = NULL;
+ comma = False;
+
+ for (s = strtok (domain, "."); s != NULL; s = strtok (NULL, "."))
+ {
+ if (comma)
+ {
+ pstrcat (dn, ",");
+ }
+ else
+ {
+ comma = True;
+ }
+
+ pstrcat (dn, "dc=");
+ pstrcat (dn, s);
+ }
+
+ free (domain);
+
+ DEBUG (3, ("ldapdb_dnsdomain_to_dn [%s] -> [%s]\n", domain_in, dn));
+
+ return True;
+}
+
+BOOL
+ldapdb_dn_to_dnsdomain (const char *dn, pstring dnsdomain)
+{
+ char **dnc, **p;
+ BOOL dot = False;
+
+ dnc = ldap_explode_dn (dn, 0);
+ if (dnc == NULL)
+ {
+ return False;
+ }
+
+ dnsdomain[0] = '\0';
+
+ for (p = dnc; *p != NULL; p++)
+ {
+ if (!strncasecmp (*p, "dc=", 3))
+ {
+ if (dot)
+ {
+ pstrcat (dnsdomain, ".");
+ }
+ else
+ {
+ dot = True;
+ }
+ pstrcat (dnsdomain, *p + 3);
+ }
+ }
+
+ ldap_value_free (dnc);
+
+ DEBUG (3, ("ldapdb_dn_to_dnsdomain [%s] -> [%s]\n", dn, dnsdomain));
+
+ return True;
+}
+
+/*******************************************************************
+ Lookup the SAM account name for a DN
+ ******************************************************************/
+BOOL
+ldapdb_dn_to_ntname (PLDAPDB _hds, const char *dn, pstring ntname)
+{
+ char *attrs[] =
+ {"sAMAccountName", NULL};
+ LDAPDB *hds;
+ BOOL ret;
+
+ if (!LDAPDB_OPEN (_hds, &hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_read (hds, dn, attrs))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ ret = ldapdb_get_pvalue (hds, "sAMAccountName", ntname);
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+
+/*******************************************************************
+ Lookup the domain SID and NetBIOS name
+ ******************************************************************/
+BOOL ldapdb_get_domain_info(PLDAPDB _hds, const char *realm, DOM_SID *sid, fstring nbname)
+{
+ LDAPDB *hds;
+ char *attrs[] = {"objectSid", NULL};
+ BOOL ret;
+
+ if (!LDAPDB_OPEN (_hds, &hds))
+ {
+ return False;
+ }
+
+ if (!__ldapdb_search (hds, realm, LDAP_SCOPE_BASE, "(objectClass=samDomain)", attrs, 1))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ ret = True;
+ if ( sid )
+ {
+ ret = ldapdb_get_sid (hds, "objectSid", sid);
+ }
+ if ( ret )
+ {
+ ret = ldapdb_get_pvalue (hds, "nETBIOSName", nbname );
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+/*******************************************************************
+ Lookup DN for a filter
+ ******************************************************************/
+BOOL
+ldapdb_lookup_name (PLDAPDB _hds, const char *context, const char *filter, pstring dn)
+{
+ char *tdn;
+ LDAPDB *hds;
+ char *const *nothing =
+ {NULL};
+
+ if (!LDAPDB_OPEN (_hds, &hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_search (hds, context, filter, nothing, 1))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!ldapdb_get_dn (hds, &tdn))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ pstrcpy (dn, tdn);
+ free (tdn);
+ ldapdb_close (&hds);
+
+ return True;
+}
+
+/*******************************************************************
+ Lookup DN for a SAM accoun
+ ******************************************************************/
+BOOL
+ldapdb_ntname_to_dn (PLDAPDB hds, const char *ntname, pstring dn)
+{
+ pstring filter;
+
+ slprintf (filter, sizeof (filter) - 1, "(sAMAccountName=%s)", ntname);
+
+ return ldapdb_lookup_name (hds, NULL, filter, dn);
+}
+
+/*******************************************************************
+ Lookup DN for a SID
+ ******************************************************************/
+static void
+berval_to_filter(struct berval *bv, pstring data_out)
+{
+ int i;
+
+ for (i = 0; i < bv->bv_len; i++)
+ {
+ slprintf (&data_out[3 * i], sizeof (data_out) - 1 - 3 * (bv->bv_len - i), "\\%02x", bv->bv_val[i]);
+ }
+}
+
+BOOL
+ldapdb_make_sid_filter (const char *attribute, const DOM_SID * sid, fstring filter)
+{
+ struct berval *bv;
+ pstring binsid;
+
+ if (!sid_to_berval (sid, &bv))
+ {
+ return False;
+ }
+
+ berval_to_filter(bv, binsid);
+
+ slprintf (filter, sizeof (fstring) - 1, "%s=%s", attribute, binsid);
+ ber_bvfree (bv);
+
+ return True;
+}
+
+BOOL
+ldapdb_make_rid_filter (const char *attribute, uint32 rid, fstring filter)
+{
+ DOM_SID sid;
+
+ sid_copy (&sid, &global_sam_sid);
+ if (sid_append_rid (&sid, rid) == False)
+ {
+ return False;
+ }
+
+ return ldapdb_make_sid_filter (attribute, &sid, filter);
+}
+
+BOOL
+ldapdb_sid_to_dn (PLDAPDB hds, const DOM_SID * sid, pstring dn)
+{
+ pstring filter;
+
+ if (ldapdb_make_sid_filter ("objectSid", sid, filter))
+ {
+ return False;
+ }
+
+ return ldapdb_lookup_name (hds, NULL, filter, dn);
+}
+
+BOOL
+ldapdb_rid_to_dn (PLDAPDB hds, uint32 rid, pstring dn)
+{
+ DOM_SID sid;
+
+ sid_copy (&sid, &global_sam_sid);
+ if (sid_append_rid (&sid, rid) == False)
+ {
+ return False;
+ }
+
+ return ldapdb_sid_to_dn (hds, &sid, dn);
+}
+
+const char *
+ldapdb_get_realm_name (void)
+{
+ static pstring dnsRealm;
+ static char *cachedRealm = NULL;
+ char *lpRealm;
+ char *ret = NULL;
+
+ if (cachedRealm)
+ {
+ ret = cachedRealm;
+ }
+ else if ((lpRealm = lp_ldap_realm ()) && lpRealm[0] != '\0')
+ {
+ ret = (cachedRealm = lpRealm);
+ }
+ else if (ldapdb_dn_to_dnsdomain (lp_ldap_suffix (), dnsRealm))
+ {
+ ret = (cachedRealm = dnsRealm);
+ }
+
+ if (ret)
+ {
+ DEBUG (3, ("ldapdb_get_realm_name() [%s]\n", ret));
+ }
+
+ return ret;
+}
+
+BOOL
+ldapdb_lookup_by_sid (LDAPDB * hds, const DOM_SID * sid)
+{
+ /* hmm. how do we do this? */
+ fstring filter, sidfilter;
+
+ if (!ldapdb_make_sid_filter ("objectSid", sid, sidfilter))
+ {
+ return False;
+ }
+
+ slprintf (filter, sizeof (filter) - 1, "(%s)", sidfilter);
+
+ return ldapdb_search (hds, NULL, filter, NULL, 1);
+}
+
+BOOL
+ldapdb_lookup_by_rid (LDAPDB * hds, uint32 rid)
+{
+ DOM_SID sid;
+
+ sid_copy (&sid, &global_sam_sid);
+ if (sid_append_rid (&sid, rid) == False)
+ {
+ return False;
+ }
+
+ return ldapdb_lookup_by_sid(hds, &sid);
+}
+
+BOOL
+ldapdb_lookup_by_netbiosname (LDAPDB *hds, const char *nbname)
+{
+ fstring filter;
+
+ slprintf (filter, sizeof (filter) - 1, "(nETBIOSName=%s)", nbname);
+
+ return ldapdb_search (hds, NULL, filter, NULL, 1);
+}
+
+BOOL
+ldapdb_lookup_by_ntname (LDAPDB * hds, const char *ntname)
+{
+ fstring filter;
+
+ slprintf (filter, sizeof (filter) - 1, "(sAMAccountName=%s)", ntname);
+
+ return ldapdb_search (hds, NULL, filter, NULL, 1);
+}
+
+BOOL
+ldapdb_lookup_by_posix_name (LDAPDB * hds, const char *user)
+{
+ fstring filter;
+
+ slprintf (filter, sizeof (filter) - 1, "(&(objectClass=User)(|(mSSFUName=%s)(uid=%s)))", user, user);
+
+ return ldapdb_search (hds, NULL, filter, NULL, 1);
+}
+
+BOOL
+ldapdb_lookup_by_posix_uid (LDAPDB * hds, uid_t uid)
+{
+ fstring filter;
+
+ slprintf (filter, sizeof (filter) - 1, "(&(objectClass=User)(uidNumber=%d))", uid);
+
+ return ldapdb_search (hds, NULL, filter, NULL, 1);
+}
+
+BOOL
+ldapdb_lookup_by_posix_gid (LDAPDB * hds, gid_t gid)
+{
+ fstring filter;
+
+ slprintf (filter, sizeof (filter) - 1, "(&(objectClass=User)(gidNumber=%d))", gid);
+
+ return ldapdb_search (hds, NULL, filter, NULL, 1);
+}
+BOOL
+ldapdb_queue_time (LDAPMod *** modlist, int modop, const char *attribute,
+ NTTIME * nttime)
+{
+ SMB_BIG_UINT tval;
+ fstring tstr;
+ NTTIME tmp;
+ size_t len;
+
+ if (nttime == NULL)
+ {
+ unix_to_nt_time (&tmp, time (NULL));
+ nttime = &tmp;
+ }
+
+ /* XXX needs fixing */
+ len = (sizeof (SMB_BIG_UINT) < sizeof (NTTIME)) ? sizeof (SMB_BIG_UINT) : sizeof (NTTIME);
+ memcpy (&tval, nttime, len);
+
+ /* XXX non portable */
+ slprintf (tstr, sizeof (tstr) - 1, "%Lu", tval);
+
+ return ldapdb_queue_mod (modlist, modop, attribute, tstr);
+}
+
+BOOL
+ldapdb_parse_time (const char *timestr, NTTIME * nttime)
+{
+ SMB_BIG_UINT tval;
+ size_t len;
+
+ /* set it to some reasonable value */
+ init_nt_time (nttime);
+
+ len = (sizeof (SMB_BIG_UINT) < sizeof (NTTIME)) ? sizeof (SMB_BIG_UINT) : sizeof (NTTIME);
+
+ tval = strtouq (timestr, NULL, 10);
+ memcpy (nttime, &tval, len);
+
+ return True;
+}
+
+BOOL
+ldapdb_get_time (LDAPDB * hds, const char *attr, NTTIME * nttime)
+{
+ fstring timestr;
+
+ if (!ldapdb_get_fvalue (hds, attr, timestr))
+ {
+ return False;
+ }
+
+ return ldapdb_parse_time (timestr, nttime);
+}
+
+void unistr2_to_utf8(char *dest, const UNISTR2 *str, size_t maxlen)
+{
+#ifdef LDAP_UNICODE
+ char *end = dest + maxlen;
+ uint16 *ubuf;
+
+ ubuf = str->buffer;
+
+ while (dest < end)
+ {
+ if (*ubuf < 0x100)
+ {
+ /* ASCII */
+ *(dest++) =
+ }
+ else
+ {
+ /* Not ASCII */
+ }
+ ++ubuf;
+ }
+
+#else
+ unistr2_to_ascii(dest, str, maxlen);
+#endif /* LDAP_UNICODE */
+}
+
+void utf8_to_unistr2(UNISTR2 *unistr, const char *str)
+{
+#ifdef LDAP_UNICODE
+ extern unsigned long ldap_utf8_chars(const char *);
+ extern int ldap_utf8_charlen(const char *);
+ ZERO_STRUCTP(str);
+ char *dest, *end;
+ size_t maxlen = ldap_utf8_chars(str);
+
+ if (maxlen > MAX_UNISTRLEN - 1)
+ {
+ maxlen = MAX_UNISTRLEN - 1;
+ }
+
+ unistr->uni_max_len = maxlen;
+ unistr->undoc = 0;
+ unistr->uni_str_len = maxlen;
+
+ dest = unistr->buffer;
+ end = dest + unistr->uni_max_len;
+
+ while (dest < end)
+ {
+ switch ( ldap_utf8_charlen(utf) )
+ {
+ case 0:
+ break;
+ case 1:
+ *(dest++) = *utf;
+ *(dest++) = 0;
+ break;
+ case 2:
+ *(dest++) = *utf;
+ *(dest++) = *(utf + 1);
+ break;
+ default
+ break;
+ }
+ utf = ldap_utf8_next(utf);
+ }
+
+ *dest++ = 0;
+ *dest++ = 0;
+#else
+ ascii_to_unistr(unistr->buffer, str, sizeof(unistr->buffer)-1);
+#endif /* LDAP_UNICODE */
+}
+
+#else
+void ldapdb_dummy_function (void);
+void
+ldapdb_dummy_function (void)
+{
+} /* stop some compilers complaining */
+#endif
diff --git a/source/passdb/mysqlpass.c b/source/passdb/mysqlpass.c
new file mode 100644
index 00000000000..75be8b638b9
--- /dev/null
+++ b/source/passdb/mysqlpass.c
@@ -0,0 +1,673 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * Samba MYSQL SAM Database, by Benjamin Kuit.
+ * Copyright (C) Benjamin Kuit 1999,
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+#define UNIX_NAME(row) ((*row)[0])
+#define UNIX_UID(row) ((*row)[1])
+#define NT_NAME(row) ((*row)[2])
+#define RID(row) ((*row)[3])
+#define LM_HASH(row) ((*row)[4])
+#define NT_HASH(row) ((*row)[5])
+#define FLAGS(row) ((*row)[6])
+#define CHANGE_TIME(row) ((*row)[7])
+
+static fstring mysql_table = { 0 };
+
+struct mysql_struct {
+ MYSQL handle;
+ MYSQL_RES *result;
+ uint current_row;
+};
+typedef struct mysql_struct mysql_ctrl;
+
+static char *mysql_retrieve_password(char *passfile)
+{
+ static fstring pass;
+ static time_t last_checked = (time_t)0;
+ static char pass_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+=|~`\\{}[]:;\"'?/>.<,";
+ fstring temppass;
+ FILE *filep;
+ int length;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( passfile == NULL ) {
+ pass[0]=0;
+ return pass;
+ }
+
+ if ( time(NULL) - last_checked <= 60 ) {
+ return pass;
+ }
+
+ if ( file_modtime(passfile) < last_checked ) {
+ return pass;
+ }
+
+ filep = sys_fopen(passfile,"r");
+
+ if ( filep == NULL ) {
+ return pass;
+ }
+
+ memset(temppass,0,sizeof(temppass));
+
+ if ( fgets( temppass, sizeof(temppass)-1, filep) == NULL ) {
+ fclose(filep);
+ return pass;
+ }
+
+ fclose(filep);
+
+ length = strspn( temppass, pass_chars );
+ temppass[length<sizeof(temppass)-1?length:sizeof(temppass)-1] = '\0';
+
+ fstrcpy( pass, temppass );
+
+ last_checked = time(NULL);
+
+ return pass;
+}
+
+static int mysql_db_connect( MYSQL *handle )
+{
+ char *password;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ password = mysql_retrieve_password(lp_mysql_passfile());
+
+ if ( !mysql_connect(handle, lp_mysql_host(), lp_mysql_user(), password) ) {
+ DEBUG(0,("mysql_connect: %s\n",mysql_error(handle)));
+ return -1;
+ }
+
+ if ( mysql_select_db( handle, lp_mysql_db()) ) {
+ DEBUG(0,("mysql_connect: %s\n",mysql_error(handle)));
+ mysql_close(handle);
+ return -1;
+ }
+
+ fstrcpy(mysql_table,lp_mysql_table());
+
+ return 0;
+}
+
+static int mysql_lock_table( MYSQL *handle, BOOL write_access )
+{
+ fstring query;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ slprintf( query, sizeof(query), "lock tables %s %s", mysql_table, write_access==True?"write":"read");
+
+ if ( mysql_query( handle, query ) ) {
+ DEBUG(0,("Cannot get lock: %s: %s\n",query,mysql_error(handle) ));
+ return -1;
+ }
+
+ return 0;
+}
+
+int mysql_db_lock_connect( MYSQL *handle )
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( mysql_db_connect( handle ) ) {
+ return -1;
+ }
+
+ if ( mysql_lock_table( handle, True ) ) {
+ mysql_close( handle );
+ return -1;
+ }
+
+ return 0;
+}
+
+static MYSQL_RES *mysql_select_results( MYSQL *handle, char *selection )
+{
+ MYSQL_RES *result;
+ pstring query;
+ int query_length;
+ char select[] = "select ";
+ char where[] = " where ";
+ char from[] = " from ";
+ char mysql_query_string[] = "unix_name, unix_uid, nt_name, user_rid, smb_passwd, smb_nt_passwd, acct_ctrl, pass_last_set_time";
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ query_length = sizeof( select ) + sizeof( mysql_query_string ) + sizeof(from ) + strlen( mysql_table );
+
+ if ( selection != NULL && *selection != '\0' ) {
+ query_length += sizeof( where ) + strlen( selection );
+ }
+
+ if ( query_length >= sizeof( query ) ) {
+ DEBUG(0,("Query string too long\n"));
+ return NULL;
+ }
+
+ pstrcpy( query, select);
+ pstrcat( query, mysql_query_string );
+ pstrcat( query, from );
+ pstrcat( query, mysql_table );
+
+ if ( selection != NULL && *selection != '\0' ) {
+ pstrcat( query, where );
+ pstrcat( query, selection );
+ }
+
+ DEBUG(5,("mysql> %s\n",query));
+ if ( mysql_query( handle, query ) ) {
+ DEBUG(0,("%s: %s\n", query, mysql_error(handle) ));
+ return NULL;
+ }
+
+ result = mysql_store_result( handle );
+
+ if ( mysql_num_fields( result ) != 8 ) {
+ DEBUG(0,("mysql_num_result = %d (!=8)\n",mysql_num_fields( result )));
+ return NULL;
+ }
+
+ if ( result == NULL ) {
+ DEBUG(0,("mysql_store_result: %s\n",mysql_error(handle)));
+ return NULL;
+ }
+
+ return result;
+}
+
+void *mysql_startpwent( BOOL update )
+{
+ mysql_ctrl *mysql;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ mysql = (mysql_ctrl *)malloc( sizeof(mysql_ctrl) );
+ if ( mysql == NULL ) {
+ DEBUG(0,("malloc: Out of memory\n"));
+ return NULL;
+ }
+
+ memset( mysql, 0, sizeof(mysql_ctrl) );
+
+ if ( mysql_db_connect( &mysql->handle ) ) {
+ return NULL;
+ }
+
+ if ( mysql_lock_table( &mysql->handle, update ) ) {
+ mysql_close( &mysql->handle );
+ return NULL;
+ }
+
+ mysql->result = mysql_select_results( &mysql->handle, NULL );
+
+ if ( mysql->result == NULL ) {
+ mysql_close( &mysql->handle );
+ return NULL;
+ }
+
+ mysql->current_row = 0;
+
+ return (void*)mysql;
+}
+
+void mysql_endpwent( void *ptr )
+{
+ mysql_ctrl *handle;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+ handle = (mysql_ctrl *)ptr;
+
+ mysql_free_result( handle->result );
+
+ mysql_close( &handle->handle );
+
+ free( handle );
+}
+
+SMB_BIG_UINT mysql_getpwpos(void *vp)
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return ((mysql_ctrl *)vp)->current_row;
+}
+
+BOOL mysql_setpwpos(void *vp, SMB_BIG_UINT pos)
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ mysql_data_seek( ((mysql_ctrl*)vp)->result, (uint)pos );
+ ((mysql_ctrl *)vp)->current_row=(uint)pos;
+
+ return True;
+}
+
+static void quote_hash( char *target, unsigned char *passwd )
+{
+ char hex[] = "0123456789ABCDEF";
+ int i;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( passwd == NULL ) {
+ fstrcpy(target,"NULL");
+ }
+ else {
+ target[0]='\'';
+ for (i=0;i<32;i++) {
+ target[i+1] = hex[(passwd[i>>1]>>(((~i)&1)<<2))&15];
+ }
+ target[33] = '\'';
+ target[34] = '\0';
+ }
+}
+
+static unsigned char *decode_hash( char *hash, unsigned char *buffer )
+{
+ char hex[] = "0123456789ABCDEF";
+ int pos, v1, v2;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( hash == NULL ) {
+ return NULL;
+ }
+
+ for (pos=0;pos<16;pos++) {
+ for( v1 = 0; v1 < sizeof(hex) && hash[0] != hex[v1]; v1++ );
+ for( v2 = 0; v2 < sizeof(hex) && hash[1] != hex[v2]; v2++ );
+
+ if ( v1 == sizeof(hex) || v2 == sizeof(hex) ) {
+ return NULL;
+ }
+
+ buffer[pos] = (v1<<4)|v2;
+ hash += 2;
+ }
+
+ return buffer;
+}
+
+void *mysql_fill_smb_passwd( MYSQL_ROW *row )
+{
+ static struct smb_passwd pw_buf;
+ static fstring unix_name;
+ static fstring nt_name;
+ static unsigned char smbpwd[16];
+ static unsigned char smbntpwd[16];
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ pwdb_init_smb(&pw_buf);
+
+ fstrcpy( unix_name, UNIX_NAME(row) );
+ pw_buf.unix_name = unix_name;
+ pw_buf.unix_uid = get_number( UNIX_UID(row) );
+
+ if ( NT_NAME(row) != NULL ) {
+ fstrcpy( nt_name, NT_NAME(row) );
+ pw_buf.nt_name = nt_name;
+ }
+
+ if ( RID(row) != NULL ) {
+ pw_buf.user_rid = get_number( RID(row) );
+ }
+
+ pw_buf.smb_passwd = decode_hash( LM_HASH(row), smbpwd );
+ if ( !pw_buf.smb_passwd ) {
+ DEBUG(4, ("entry invalidated for unix user %s\n", unix_name ));
+ return NULL;
+ }
+
+ pw_buf.smb_nt_passwd = decode_hash( NT_HASH(row), smbntpwd );
+
+ if ( FLAGS(row) != NULL ) {
+ pw_buf.acct_ctrl = get_number( FLAGS(row) );
+ }
+
+ if ( pw_buf.acct_ctrl == 0 ) {
+ pw_buf.acct_ctrl = ACB_NORMAL;
+ }
+
+ pw_buf.pass_last_set_time = get_number( CHANGE_TIME(row) );
+
+ return (void*)&pw_buf;
+}
+
+MYSQL_ROW *mysql_getpwent(void *vp)
+{
+ mysql_ctrl *mysql;
+ static MYSQL_ROW row;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ mysql = (mysql_ctrl*)vp;
+ row = mysql_fetch_row( mysql->result );
+
+ if ( row == NULL ) {
+ return NULL;
+ }
+
+ mysql->current_row++;
+
+ return &row;
+}
+
+struct smb_passwd *mysql_getsmbpwent(void *vp)
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return (struct smb_passwd*)mysql_fill_smb_passwd( mysql_getpwent(vp) );
+}
+
+void *mysql_fetch_passwd( void *(*filler)(MYSQL_ROW*), char *where )
+{
+ void *retval;
+ MYSQL handle;
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( filler == NULL ) {
+ return NULL;
+ }
+
+ if ( where == NULL || *where == '\0' ) {
+ DEBUG(0,("Null or empty query\n"));
+ return NULL;
+ }
+
+ if ( mysql_db_connect( &handle ) ) {
+ return NULL;
+ }
+
+ result = mysql_select_results( &handle, where );
+ if ( result == NULL ) {
+ mysql_close( &handle );
+ return NULL;
+ }
+
+ row = mysql_fetch_row ( result );
+ if ( row == NULL ) {
+ mysql_free_result( result );
+ mysql_close( &handle );
+ return NULL;
+ }
+
+ if ( DEBUGLEVEL >= 7 ) {
+ int field;
+ for (field=0; field< mysql_num_fields( result ); field++ ) {
+ DEBUG(7,(" row[%d] = \"%s\"\n",field,row[field]?row[field]:"NULL"));
+ }
+ }
+
+ retval = (*filler)( &row );
+
+ mysql_free_result( result );
+ mysql_close( &handle );
+
+ return retval;
+}
+
+void *mysql_getpwuid(void *(*filler)(MYSQL_ROW *), uid_t uid)
+{
+ fstring where;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ slprintf( where, sizeof(where), "unix_uid=%lu", uid);
+
+ return mysql_fetch_passwd(filler,where);
+}
+
+struct smb_passwd *mysql_getsmbpwuid(uid_t uid)
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return (struct smb_passwd *)mysql_getpwuid( mysql_fill_smb_passwd, uid );
+}
+
+void *mysql_getpwnam(void *(*filler)(MYSQL_ROW *), char *field, const char *name)
+{
+ fstring where;
+ char format[] = "%s='%s'";
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( filler == NULL ) {
+ DEBUG(0,("Empty fill opteration\n"));
+ return NULL;
+ }
+
+ if ( field == NULL || *field == '\0' ) {
+ DEBUG(0,("Empty or NULL field name\n"));
+ return NULL;
+ }
+
+ if ( name == NULL || *name == '\0' ) {
+ DEBUG(0,("Empty or NULL query\n"));
+ return NULL;
+ }
+
+ if ( sizeof(format) + strlen(name) + strlen(field) > sizeof(where) ) {
+ DEBUG(0,("Query string too long\n"));
+ return NULL;
+ }
+
+ slprintf(where, sizeof( where ), format, field, name );
+
+ return mysql_fetch_passwd( filler, where );
+}
+
+struct smb_passwd *mysql_getsmbpwnam(const char *unix_name)
+{
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return mysql_getpwnam( mysql_fill_smb_passwd, "unix_name", unix_name );
+}
+
+static void quote_string(char *target, char *string)
+{
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( string == NULL ) {
+ fstrcpy( target, "NULL" );
+ }
+ else {
+ target[0] = '\'';
+ safe_strcpy(&target[1],string,sizeof(fstring)-2);
+ safe_strcpy(&target[strlen(target)],"'",2);
+ }
+}
+
+BOOL mysql_del_smb( MYSQL *handle, char *unix_name )
+{
+ pstring query;
+ char format[] = "delete from %s where unix_name='%s'";
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if (strlen( format ) + strlen(mysql_table) + strlen(unix_name)) {
+ return False;
+ }
+
+ slprintf( query, sizeof(query), format, mysql_table, unix_name);
+
+ if ( mysql_query( handle, query ) ) {
+ DEBUG(0,("%s: %s\n", query, mysql_error(handle) ));
+ return False;
+ }
+
+ return True;
+}
+
+BOOL mysql_add_smb( MYSQL *handle, struct smb_passwd *smb )
+{
+ pstring query;
+ char format[] = "insert into %s (unix_name, unix_uid) values ( '%s', %lu )";
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( strlen(format) + strlen(mysql_table) + strlen(smb->unix_name) + 10 > sizeof(query) ) {
+ DEBUG(0,("Query too long\n"));
+ return False;
+ }
+
+ slprintf( query, sizeof(query), "insert into %s (unix_name,unix_uid) values ('%s', %lu)", mysql_table, smb->unix_name, smb->unix_uid);
+
+ if ( mysql_query( handle, query ) ) {
+ DEBUG(0,("%s: %s\n",query,mysql_error(handle) ));
+ return False;
+ }
+
+ return True;
+}
+
+BOOL mysql_mod_smb( MYSQL *handle, struct smb_passwd *smb, BOOL override )
+{
+ pstring query;
+ fstring smb_passwd;
+ fstring smb_nt_passwd;
+ fstring nt_name;
+
+ char format[] = "update %s set nt_name=%s, user_rid=%lu, smb_passwd=%s, smb_nt_passwd=%s, acct_ctrl=%u, pass_last_set_time=unix_timestamp() where unix_name='%s'";
+ char extra[] = " and not ISNULL(smb_passwd)";
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( strlen(format) + 2*20 + 3*10 + 2*32 + strlen(mysql_table) >= sizeof( query ) + strlen( extra ) ) {
+ DEBUG(0,("Query string too long\n"));
+ return False;
+ }
+
+ quote_hash(smb_passwd, smb->smb_passwd);
+ quote_hash(smb_nt_passwd, smb->smb_nt_passwd);
+
+ quote_string(nt_name, smb->nt_name);
+
+ slprintf( query, sizeof(query), format, mysql_table, nt_name, (long unsigned)smb->user_rid, smb_passwd, smb_nt_passwd, smb->acct_ctrl, smb->unix_name);
+
+ if ( override != True ) {
+ pstrcat( query, extra );
+ }
+
+ if ( mysql_query( handle, query ) ) {
+ DEBUG(0,("%s: %s\n",query,mysql_error(handle) ));
+ return False;
+ }
+
+ if ( mysql_affected_rows( handle ) < 1 ) {
+ DEBUG(3,("No entries changed\n"));
+ return False;
+ }
+
+ return True;
+}
+
+BOOL mysql_add_smbpwd_entry(struct smb_passwd *smb)
+{
+ MYSQL handle;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( smb == NULL ) {
+ return False;
+ }
+
+ if ( mysql_db_lock_connect( &handle ) ) {
+ return False;
+ }
+
+ if ( !mysql_add_smb( &handle, smb ) ) {
+ mysql_close( &handle );
+ return False;
+ }
+
+ if ( !mysql_mod_smb( &handle, smb, True ) ) {
+ mysql_del_smb( &handle, smb->unix_name );
+ mysql_close( &handle );
+ return False;
+ }
+
+ mysql_close(&handle);
+ return True;
+}
+
+BOOL mysql_mod_smbpwd_entry(struct smb_passwd *smb, BOOL override)
+{
+ MYSQL handle;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ if ( smb == NULL ) {
+ return False;
+ }
+
+ if ( mysql_db_lock_connect( &handle ) ) {
+ return False;
+ }
+
+ if ( !mysql_mod_smb( &handle, smb, override ) ) {
+ mysql_close(&handle);
+ return False;
+ }
+
+ mysql_close(&handle);
+ return True;
+}
+
+static struct smb_passdb_ops mysql_ops = {
+ mysql_startpwent,
+ mysql_endpwent,
+ mysql_getpwpos,
+ mysql_setpwpos,
+ mysql_getsmbpwnam,
+ mysql_getsmbpwuid,
+ mysql_getsmbpwent,
+ mysql_add_smbpwd_entry,
+ mysql_mod_smbpwd_entry
+};
+
+struct smb_passdb_ops *mysql_initialise_password_db(void)
+{
+ (void*)mysql_retrieve_password(NULL);
+ return &mysql_ops;
+}
+
+#else
+ void mysql_dummy_smb_function(void) { }
+#endif
diff --git a/source/passdb/mysqlsampass.c b/source/passdb/mysqlsampass.c
new file mode 100644
index 00000000000..11d3142d9b6
--- /dev/null
+++ b/source/passdb/mysqlsampass.c
@@ -0,0 +1,241 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * Samba MYSQL SAM Database, by Benjamin Kuit.
+ * Copyright (C) Benjamin Kuit 1999,
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
+
+#include "includes.h"
+
+MYSQL_ROW *mysql_getpwent(void *vp);
+
+extern int DEBUGLEVEL;
+
+void *mysql_fill_sam_passwd( MYSQL_ROW *row )
+{
+ static struct sam_passwd *user;
+
+ static pstring full_name;
+ static pstring home_dir;
+ static pstring home_drive;
+ static pstring logon_script;
+ static pstring profile_path;
+ static pstring acct_desc;
+ static pstring workstations;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ user = pwdb_smb_to_sam((struct smb_passwd *)mysql_fill_smb_passwd(row));
+
+ if ( user == NULL ) {
+ return NULL;
+ }
+
+ /* 'Researched' from sampass.c =) */
+
+ pstrcpy(logon_script , lp_logon_script (NULL));
+ pstrcpy(profile_path , lp_logon_path (NULL));
+ pstrcpy(home_drive , lp_logon_drive (NULL));
+ pstrcpy(home_dir , lp_logon_home (NULL));
+ pstrcpy(workstations , "");
+
+ user->full_name = full_name;
+ user->home_dir = home_dir;
+ user->dir_drive = home_drive;
+ user->logon_script = logon_script;
+ user->profile_path = profile_path;
+ user->acct_desc = acct_desc;
+ user->workstations = workstations;
+
+ user->unknown_str = NULL; /* don't know, yet! */
+ user->munged_dial = NULL; /* "munged" dial-back telephone number */
+
+ user->unknown_3 = 0xffffff; /* don't know */
+ user->logon_divs = 168; /* hours per week */
+ user->hours_len = 21; /* 21 times 8 bits = 168 */
+ memset(user->hours, 0xff, user->hours_len); /* available at all hours */
+ user->unknown_5 = 0x00020000; /* don't know */
+ user->unknown_6 = 0x000004ec; /* don't know */
+
+ return (void*)user;
+}
+
+struct sam_passwd *mysql_getsampwent(void *vp)
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return (struct sam_passwd*)mysql_fill_sam_passwd( mysql_getpwent(vp) );
+}
+
+struct sam_passwd *mysql_getsampwrid(uint32 rid)
+{
+ fstring where;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ slprintf( where, sizeof(where), "user_rid=%lu", (long unsigned)rid);
+
+ return (struct sam_passwd *)mysql_fetch_passwd( mysql_fill_sam_passwd, where );
+}
+
+struct sam_passwd *mysql_getsampwuid(uid_t uid)
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return (struct sam_passwd *)mysql_getpwuid( mysql_fill_sam_passwd, uid );
+}
+
+struct sam_passwd *mysql_getsampwntnam(const char *nt_name)
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return (struct sam_passwd *)mysql_getpwnam( mysql_fill_sam_passwd, "nt_name", nt_name);
+}
+
+struct sam_disp_info *mysql_getsamdispntnam(const char *nt_name)
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return pwdb_sam_to_dispinfo(mysql_getsampwntnam(nt_name));
+}
+
+struct sam_disp_info *mysql_getsamdisprid(uint32 rid)
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return pwdb_sam_to_dispinfo(mysql_getsampwrid(rid));
+}
+
+struct sam_disp_info *mysql_getsamdispent(void *vp)
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return pwdb_sam_to_dispinfo(mysql_getsampwent(vp));
+}
+
+static BOOL mysql_mod_sam( MYSQL *handle, struct sam_passwd *sam, BOOL override )
+{
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ return True;
+}
+
+BOOL mysql_add_sampwd_entry(struct sam_passwd *sam)
+{
+ MYSQL handle;
+ struct smb_passwd *smb;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ smb = pwdb_sam_to_smb( sam );
+
+ if ( smb == NULL ) {
+ return False;
+ }
+
+ if ( mysql_db_lock_connect( &handle ) ) {
+ return False;
+ }
+
+ if ( !mysql_add_smb( &handle, smb ) ) {
+ mysql_close(&handle);
+ return False;
+ }
+
+ if ( !mysql_mod_smb( &handle, smb, True ) ) {
+ mysql_del_smb( &handle, smb->unix_name );
+ mysql_close(&handle);
+ return False;
+ }
+
+ if ( !mysql_mod_sam( &handle, sam, True ) ) {
+ mysql_del_smb( &handle, smb->unix_name );
+ mysql_close(&handle);
+ return False;
+ }
+
+ mysql_close(&handle);
+ return True;
+}
+
+BOOL mysql_mod_sampwd_entry(struct sam_passwd *sam, BOOL override)
+{
+ MYSQL handle;
+ struct smb_passwd *smb;
+
+ DEBUG(5,("%s\n",FUNCTION_MACRO));
+
+ smb = pwdb_sam_to_smb(sam);
+
+ if ( smb == NULL ) {
+ return False;
+ }
+
+ if ( mysql_db_lock_connect( &handle ) ) {
+ return False;
+ }
+
+ if ( !mysql_mod_smb( &handle, smb, override ) ) {
+ mysql_close(&handle);
+ return False;
+ }
+
+ if ( !mysql_mod_sam( &handle, sam, override ) ) {
+ mysql_close(&handle);
+ return False;
+ }
+
+ mysql_close(&handle);
+ return True;
+}
+
+static struct sam_passdb_ops sam_mysql_ops =
+{
+ mysql_startpwent,
+ mysql_endpwent,
+ mysql_getpwpos,
+ mysql_setpwpos,
+ mysql_getsampwntnam,
+ mysql_getsampwuid,
+ mysql_getsampwrid,
+ mysql_getsampwent,
+ mysql_add_sampwd_entry,
+ mysql_mod_sampwd_entry,
+ mysql_getsamdispntnam,
+ mysql_getsamdisprid,
+ mysql_getsamdispent
+};
+
+struct sam_passdb_ops *mysql_initialise_sam_password_db(void)
+{
+ return &sam_mysql_ops;
+}
+
+#else
+ void mysql_dummy_sam_function(void) { }
+#endif
diff --git a/source/passdb/nispass.c b/source/passdb/nispass.c
index 4b4e281c29d..f554958adeb 100644
--- a/source/passdb/nispass.c
+++ b/source/passdb/nispass.c
@@ -19,37 +19,14 @@
* Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "includes.h"
-
#ifdef WITH_NISPLUS
-#ifdef BROKEN_NISPLUS_INCLUDE_FILES
-
-/*
- * The following lines are needed due to buggy include files
- * in Solaris 2.6 which define GROUP in both /usr/include/sys/acl.h and
- * also in /usr/include/rpcsvc/nis.h. The definitions conflict. JRA.
- * Also GROUP_OBJ is defined as 0x4 in /usr/include/sys/acl.h and as
- * an enum in /usr/include/rpcsvc/nis.h.
- */
-
-#if defined(GROUP)
-#undef GROUP
-#endif
-
-#if defined(GROUP_OBJ)
-#undef GROUP_OBJ
-#endif
-
-#endif
-
+#include "includes.h"
#include <rpcsvc/nis.h>
extern int DEBUGLEVEL;
-extern pstring samlogon_user;
-extern BOOL sam_logon_in_ssb;
-static VOLATILE SIG_ATOMIC_T gotalarm;
+static int gotalarm;
/***************************************************************
@@ -177,218 +154,9 @@ static void get_single_attribute(nis_object *new_obj, int col,
len = entry_len;
}
- safe_strcpy(val, ENTRY_VAL(new_obj, col), len-1);
+ safe_strcpy(val, len, ENTRY_VAL(new_obj, col));
}
-/************************************************************************
- makes a struct sam_passwd from a NIS+ object.
- ************************************************************************/
-static BOOL make_sam_from_nisp_object(struct sam_passwd *pw_buf, nis_object *obj)
-{
- int uidval;
- static pstring user_name;
- static pstring full_name;
- static pstring home_dir;
- static pstring home_drive;
- static pstring logon_script;
- static pstring profile_path;
- static pstring acct_desc;
- static pstring workstations;
- static pstring temp;
- static unsigned char smbpwd[16];
- static unsigned char smbntpwd[16];
-
- char *p;
-
- pdb_init_sam(pw_buf);
- pw_buf->acct_ctrl = ACB_NORMAL;
-
- pstrcpy(user_name, ENTRY_VAL(obj, NPF_NAME));
- pw_buf->smb_name = user_name;
-
- uidval = atoi(ENTRY_VAL(obj, NPF_UID));
- pw_buf->smb_userid = uidval;
-
- /* Check the lanman password column. */
- p = (char *)ENTRY_VAL(obj, NPF_LMPWD);
- if (*p == '*' || *p == 'X') {
- /* Password deliberately invalid - end here. */
- DEBUG(10, ("make_sam_from_nisp_object: entry invalidated for user %s\n", user_name));
- pw_buf->smb_nt_passwd = NULL;
- pw_buf->smb_passwd = NULL;
- pw_buf->acct_ctrl |= ACB_DISABLED;
- return True;
- }
- if (!strncasecmp(p, "NO PASSWORD", 11)) {
- pw_buf->smb_passwd = NULL;
- pw_buf->acct_ctrl |= ACB_PWNOTREQ;
- } else {
- if (strlen(p) != 32 || !pdb_gethexpwd(p, smbpwd))
- {
- DEBUG(0, ("make_sam_from_nisp_object: malformed LM pwd entry.\n"));
- return False;
- }
- }
-
- pw_buf->smb_passwd = smbpwd;
-
- /* Check the NT password column. */
- p = ENTRY_VAL(obj, NPF_NTPWD);
- if (*p != '*' && *p != 'X') {
- if (strlen(p) != 32 || !pdb_gethexpwd(p, smbntpwd))
- {
- DEBUG(0, ("make_smb_from_nisp_object: malformed NT pwd entry\n"));
- return False;
- }
- pw_buf->smb_nt_passwd = smbntpwd;
- }
-
- p = (char *)ENTRY_VAL(obj, NPF_ACB);
- if (*p == '[')
- {
- pw_buf->acct_ctrl = pdb_decode_acct_ctrl(p);
-
- /* Must have some account type set. */
- if(pw_buf->acct_ctrl == 0)
- pw_buf->acct_ctrl = ACB_NORMAL;
-
- /* Now try and get the last change time. */
- if(*p == ']')
- p++;
- if(*p == ':') {
- p++;
- if(*p && (StrnCaseCmp(p, "LCT-", 4)==0)) {
- int i;
- p += 4;
- for(i = 0; i < 8; i++) {
- if(p[i] == '\0' || !isxdigit(p[i]))
- break;
- }
- if(i == 8) {
- /*
- * p points at 8 characters of hex digits -
- * read into a time_t as the seconds since
- * 1970 that the password was last changed.
- */
- pw_buf->pass_last_set_time = (time_t)strtol(p, NULL, 16);
- }
- }
- }
- } else {
- /* 'Old' style file. Fake up based on user name. */
- /*
- * Currently trust accounts are kept in the same
- * password file as 'normal accounts'. If this changes
- * we will have to fix this code. JRA.
- */
- if(pw_buf->smb_name[strlen(pw_buf->smb_name) - 1] == '$') {
- pw_buf->acct_ctrl &= ~ACB_NORMAL;
- pw_buf->acct_ctrl |= ACB_WSTRUST;
- }
- }
-
- get_single_attribute(obj, NPF_SMB_GRPID, temp, sizeof(pstring));
- pw_buf->smb_grpid = atoi(temp);
-
- get_single_attribute(obj, NPF_USER_RID, temp, sizeof(pstring));
- pw_buf->user_rid = (strlen(temp) > 0) ?
- strtol(temp, NULL, 16) : pdb_uid_to_user_rid (pw_buf->smb_userid);
-
- if (pw_buf->smb_name[strlen(pw_buf->smb_name)-1] != '$') {
-
- /* XXXX hack to get standard_sub_basic() to use sam logon username */
- /* possibly a better way would be to do a become_user() call */
- pstrcpy(samlogon_user, pw_buf->smb_name);
- sam_logon_in_ssb = True;
-
- get_single_attribute(obj, NPF_GROUP_RID, temp, sizeof(pstring));
- pw_buf->group_rid = (strlen(temp) > 0) ?
- strtol(temp, NULL, 16) : pdb_gid_to_group_rid (pw_buf->smb_grpid);
-
- get_single_attribute(obj, NPF_FULL_NAME, full_name, sizeof(pstring));
-#if 1
- /* It seems correct to use the global values - but in that case why
- * do we want these NIS+ entries anyway ??
- */
- pstrcpy(logon_script , lp_logon_script ());
- pstrcpy(profile_path , lp_logon_path ());
- pstrcpy(home_drive , lp_logon_drive ());
- pstrcpy(home_dir , lp_logon_home ());
-#else
- get_single_attribute(obj, NPF_LOGON_SCRIPT, logon_script, sizeof(pstring));
- get_single_attribute(obj, NPF_PROFILE_PATH, profile_path, sizeof(pstring));
- get_single_attribute(obj, NPF_DIR_DRIVE, home_drive, sizeof(pstring));
- get_single_attribute(obj, NPF_HOME_DIR, home_dir, sizeof(pstring));
-#endif
- get_single_attribute(obj, NPF_ACCT_DESC, acct_desc, sizeof(pstring));
- get_single_attribute(obj, NPF_WORKSTATIONS, workstations, sizeof(pstring));
-
- sam_logon_in_ssb = False;
-
- } else {
-
- pw_buf->group_rid = DOMAIN_GROUP_RID_USERS; /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
-
- pstrcpy(full_name , "");
- pstrcpy(logon_script , "");
- pstrcpy(profile_path , "");
- pstrcpy(home_drive , "");
- pstrcpy(home_dir , "");
- pstrcpy(acct_desc , "");
- pstrcpy(workstations , "");
- }
-
- pw_buf->full_name = full_name;
- pw_buf->home_dir = home_dir;
- pw_buf->dir_drive = home_drive;
- pw_buf->logon_script = logon_script;
- pw_buf->profile_path = profile_path;
- pw_buf->acct_desc = acct_desc;
- pw_buf->workstations = workstations;
-
- pw_buf->unknown_str = NULL; /* don't know, yet! */
- pw_buf->munged_dial = NULL; /* "munged" dial-back telephone number */
-
- pw_buf->unknown_3 = 0xffffff; /* don't know */
- pw_buf->logon_divs = 168; /* hours per week */
- pw_buf->hours_len = 21; /* 21 times 8 bits = 168 */
- memset(pw_buf->hours, 0xff, pw_buf->hours_len); /* available at all hours */
- pw_buf->unknown_5 = 0x00020000; /* don't know */
- pw_buf->unknown_6 = 0x000004ec; /* don't know */
-
- return True;
-}
-
-/************************************************************************
- makes a struct sam_passwd from a NIS+ result.
- ************************************************************************/
-static BOOL make_sam_from_nisresult(struct sam_passwd *pw_buf, nis_result *result)
-{
- if (pw_buf == NULL || result == NULL) return False;
-
- if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND)
- {
- DEBUG(0, ("make_sam_from_nisresult: NIS+ lookup failure: %s\n",
- nis_sperrno(result->status)));
- return False;
- }
-
- /* User not found. */
- if (NIS_RES_NUMOBJ(result) <= 0)
- {
- DEBUG(10, ("make_sam_from_nisresult: user not found in NIS+\n"));
- return False;
- }
-
- if (NIS_RES_NUMOBJ(result) > 1)
- {
- DEBUG(10, ("make_sam_from_nisresult: WARNING: Multiple entries for user in NIS+ table!\n"));
- }
-
- /* Grab the first hit. */
- return make_sam_from_nisp_object(pw_buf, &NIS_RES_OBJECT(result)[0]);
- }
-
/***************************************************************
calls nis_list, returns results.
****************************************************************/
@@ -437,36 +205,21 @@ static void *startnisppwent(BOOL update)
****************************************************************/
static void endnisppwent(void *vp)
{
- struct nisp_enum_info *res = (struct nisp_enum_info *)vp;
- nis_freeresult(res->result);
- DEBUG(7,("endnisppwent: freed enumeration list\n"));
}
/*************************************************************************
Routine to return the next entry in the nisplus passwd list.
+ this function is a nice, messy combination of reading:
+ - the nisplus passwd file
+ - the unix password database
+ - nisp.conf options (not done at present).
do not call this function directly. use passdb.c instead.
*************************************************************************/
static struct sam_passwd *getnisp21pwent(void *vp)
{
- struct nisp_enum_info *res = (struct nisp_enum_info *)vp;
- static struct sam_passwd pw_buf;
- int which;
- BOOL ret;
-
- if (res == NULL || (int)(res->enum_entry) < 0 ||
- (int)(res->enum_entry) > (NIS_RES_NUMOBJ(res->result) - 1)) {
- ret = False;
- } else {
- which = (int)(res->enum_entry);
- ret = make_sam_from_nisp_object(&pw_buf,
- &NIS_RES_OBJECT(res->result)[which]);
- if (ret && which < (NIS_RES_NUMOBJ(res->result) - 1))
- (int)(res->enum_entry)++;
- }
-
- return ret ? &pw_buf : NULL;
+ return NULL;
}
/*************************************************************************
@@ -478,8 +231,7 @@ static struct sam_passwd *getnisp21pwent(void *vp)
*************************************************************************/
static SMB_BIG_UINT getnisppwpos(void *vp)
{
- struct nisp_enum_info *res = (struct nisp_enum_info *)vp;
- return (SMB_BIG_UINT)(res->enum_entry);
+ return (SMB_BIG_UINT)0;
}
/*************************************************************************
@@ -491,13 +243,7 @@ static SMB_BIG_UINT getnisppwpos(void *vp)
*************************************************************************/
static BOOL setnisppwpos(void *vp, SMB_BIG_UINT tok)
{
- struct nisp_enum_info *res = (struct nisp_enum_info *)vp;
- if (tok < (NIS_RES_NUMOBJ(res->result) - 1)) {
- res->enum_entry = tok;
- return True;
- } else {
- return False;
- }
+ return False;
}
/*************************************************************************
@@ -509,7 +255,7 @@ static void set_single_attribute(nis_object *new_obj, int col,
if (new_obj == NULL) return;
ENTRY_VAL(new_obj, col) = val;
- ENTRY_LEN(new_obj, col) = len+1;
+ ENTRY_LEN(new_obj, col) = len;
if (flags != 0)
{
@@ -549,12 +295,12 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
fstring pwdlchg_t;
fstring pwdmchg_t;
- memset((char *)logon_t , '\0', sizeof(logon_t ));
- memset((char *)logoff_t , '\0', sizeof(logoff_t ));
- memset((char *)kickoff_t, '\0', sizeof(kickoff_t));
- memset((char *)pwdlset_t, '\0', sizeof(pwdlset_t));
- memset((char *)pwdlchg_t, '\0', sizeof(pwdlchg_t));
- memset((char *)pwdmchg_t, '\0', sizeof(pwdmchg_t));
+ bzero(logon_t , sizeof(logon_t ));
+ bzero(logoff_t , sizeof(logoff_t ));
+ bzero(kickoff_t, sizeof(kickoff_t));
+ bzero(pwdlset_t, sizeof(pwdlset_t));
+ bzero(pwdlchg_t, sizeof(pwdlchg_t));
+ bzero(pwdmchg_t, sizeof(pwdmchg_t));
pfile = lp_smb_passwd_file();
@@ -562,17 +308,19 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
result = nisp_get_nis_list(nisname);
if (result->status != NIS_SUCCESS && result->status != NIS_NOTFOUND)
{
- DEBUG(3, ( "add_nis21ppwd_entry: nis_list failure: %s: %s\n",
+ DEBUG(3, ( "add_nisppwd_entry: nis_list failure: %s: %s\n",
nisname, nis_sperrno(result->status)));
+ nis_freeresult(nis_user);
nis_freeresult(result);
return False;
}
if (result->status == NIS_SUCCESS && NIS_RES_NUMOBJ(result) > 0)
{
- DEBUG(3, ("add_nisp21pwd_entry: User already exists in NIS+ password db: %s\n",
+ DEBUG(3, ("add_nisppwd_entry: User already exists in NIS+ password db: %s\n",
pfile));
nis_freeresult(result);
+ nis_freeresult(nis_user);
return False;
}
@@ -580,9 +328,10 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
/* User not found. */
if (!add_user)
{
- DEBUG(3, ("add_nisp21pwd_entry: User not found in NIS+ password db: %s\n",
+ DEBUG(3, ("add_nisppwd_entry: User not found in NIS+ password db: %s\n",
pfile));
nis_freeresult(result);
+ nis_freeresult(nis_user);
return False;
}
@@ -592,8 +341,9 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
if (tblresult->status != NIS_SUCCESS)
{
nis_freeresult(result);
+ nis_freeresult(nis_user);
nis_freeresult(tblresult);
- DEBUG(3, ( "add_nisp21pwd_entry: nis_lookup failure: %s\n",
+ DEBUG(3, ( "add_nisppwd_entry: nis_lookup failure: %s\n",
nis_sperrno(tblresult->status)));
return False;
}
@@ -611,37 +361,22 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_len = NIS_RES_OBJECT(tblresult)->zo_data.objdata_u.ta_data.ta_maxcol;
new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_val = calloc(new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_len, sizeof(entry_col));
- if (new_obj.zo_data.objdata_u.en_data.en_cols.en_cols_val == NULL)
- {
- DEBUG(0, ("add_nisp21pwd_entry: memory allocation failure\n"));
- nis_freeresult(result);
- nis_freeresult(tblresult);
- return False;
- }
+ pwdb_sethexpwd(smb_passwd , newpwd->smb_passwd , newpwd->acct_ctrl);
+ pwdb_sethexpwd(smb_nt_passwd, newpwd->smb_nt_passwd, newpwd->acct_ctrl);
- pdb_sethexpwd(smb_passwd , newpwd->smb_passwd , newpwd->acct_ctrl);
- pdb_sethexpwd(smb_nt_passwd, newpwd->smb_nt_passwd, newpwd->acct_ctrl);
+ pwdb_set_logon_time (logon_t , sizeof(logon_t ), newpwd->logon_time );
+ pwdb_set_logoff_time (logoff_t , sizeof(logoff_t ), newpwd->logoff_time );
+ pwdb_set_kickoff_time (kickoff_t, sizeof(kickoff_t), newpwd->kickoff_time );
+ pwdb_set_last_set_time (pwdlset_t, sizeof(pwdlset_t), newpwd->pass_last_set_time );
+ pwdb_set_can_change_time (pwdlchg_t, sizeof(pwdlchg_t), newpwd->pass_can_change_time );
+ pwdb_set_must_change_time(pwdmchg_t, sizeof(pwdmchg_t), newpwd->pass_must_change_time);
- newpwd->pass_last_set_time = (time_t)time(NULL);
- newpwd->logon_time = (time_t)-1;
- newpwd->logoff_time = (time_t)-1;
- newpwd->kickoff_time = (time_t)-1;
- newpwd->pass_can_change_time = (time_t)-1;
- newpwd->pass_must_change_time = (time_t)-1;
-
- slprintf(logon_t, 13, "LNT-%08X", (uint32)newpwd->logon_time);
- slprintf(logoff_t, 13, "LOT-%08X", (uint32)newpwd->logoff_time);
- slprintf(kickoff_t, 13, "KOT-%08X", (uint32)newpwd->kickoff_time);
- slprintf(pwdlset_t, 13, "LCT-%08X", (uint32)newpwd->pass_last_set_time);
- slprintf(pwdlchg_t, 13, "CCT-%08X", (uint32)newpwd->pass_can_change_time);
- slprintf(pwdmchg_t, 13, "MCT-%08X", (uint32)newpwd->pass_must_change_time);
-
- slprintf(uid, sizeof(uid), "%u", newpwd->smb_userid);
+ slprintf(uid, sizeof(uid), "%u", newpwd->unix_uid);
slprintf(user_rid, sizeof(user_rid), "0x%x", newpwd->user_rid);
slprintf(smb_grpid, sizeof(smb_grpid), "%u", newpwd->smb_grpid);
slprintf(group_rid, sizeof(group_rid), "0x%x", newpwd->group_rid);
- safe_strcpy(acb, pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), sizeof(acb)-1);
+ safe_strcpy(acb, pwdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), sizeof(acb));
set_single_attribute(&new_obj, NPF_NAME , newpwd->smb_name , strlen(newpwd->smb_name) , 0);
set_single_attribute(&new_obj, NPF_UID , uid , strlen(uid) , 0);
@@ -657,7 +392,6 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
set_single_attribute(&new_obj, NPF_PWDLSET_T , pwdlset_t , strlen(pwdlset_t) , 0);
set_single_attribute(&new_obj, NPF_PWDLCHG_T , pwdlchg_t , strlen(pwdlchg_t) , 0);
set_single_attribute(&new_obj, NPF_PWDMCHG_T , pwdmchg_t , strlen(pwdmchg_t) , 0);
-#if 0
set_single_attribute(&new_obj, NPF_FULL_NAME , newpwd->full_name , strlen(newpwd->full_name) , 0);
set_single_attribute(&new_obj, NPF_HOME_DIR , newpwd->home_dir , strlen(newpwd->home_dir) , 0);
set_single_attribute(&new_obj, NPF_DIR_DRIVE , newpwd->dir_drive , strlen(newpwd->dir_drive) , 0);
@@ -666,24 +400,26 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
set_single_attribute(&new_obj, NPF_ACCT_DESC , newpwd->acct_desc , strlen(newpwd->acct_desc) , 0);
set_single_attribute(&new_obj, NPF_WORKSTATIONS , newpwd->workstations , strlen(newpwd->workstations) , 0);
set_single_attribute(&new_obj, NPF_HOURS , newpwd->hours , newpwd->hours_len , 0);
-#endif
obj = &new_obj;
addresult = nis_add_entry(pfile, obj, ADD_OVERWRITE | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
+ nis_freeresult(nis_user);
+ if (tblresult)
+ {
+ nis_freeresult(tblresult);
+ }
if (addresult->status != NIS_SUCCESS)
{
- DEBUG(3, ( "add_nisp21pwd_entry: NIS+ table update failed: %s\n",
+ DEBUG(3, ( "add_nisppwd_entry: NIS+ table update failed: %s\n",
nisname, nis_sperrno(addresult->status)));
- nis_freeresult(tblresult);
nis_freeresult(addresult);
nis_freeresult(result);
return False;
}
- nis_freeresult(tblresult);
nis_freeresult(addresult);
nis_freeresult(result);
@@ -703,198 +439,73 @@ static BOOL add_nisp21pwd_entry(struct sam_passwd *newpwd)
************************************************************************/
static BOOL mod_nisp21pwd_entry(struct sam_passwd* pwd, BOOL override)
{
- char *oldnislmpwd, *oldnisntpwd, *oldnisacb, *oldnislct, *user_name;
- char lmpwd[33], ntpwd[33], lct[13];
- nis_result *result, *addresult;
- nis_object *obj;
- fstring acb;
- pstring nisname;
- BOOL got_pass_last_set_time, ret;
- int i;
-
- if (!*lp_smb_passwd_file())
- {
- DEBUG(0, ("mod_getnisp21pwd_entry: no SMB password file set\n"));
- return False;
- }
-
- DEBUG(10, ("mod_getnisp21pwd_entry: search by name: %s\n", pwd->smb_name));
- DEBUG(10, ("mod_getnisp21pwd_entry: using NIS+ table %s\n", lp_smb_passwd_file()));
-
- slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", pwd->smb_name, lp_smb_passwd_file());
-
- /* Search the table. */
- gotalarm = 0;
- CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
- alarm(5);
-
- result = nis_list(nisname, FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP, NULL, NULL);
-
- alarm(0);
- CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
-
- if (gotalarm)
- {
- DEBUG(0,("mod_getnisp21pwd_entry: NIS+ lookup time out\n"));
- nis_freeresult(result);
- return False;
- }
-
- if(result->status != NIS_SUCCESS || NIS_RES_NUMOBJ(result) <= 0) {
- /* User not found. */
- DEBUG(0,("mod_getnisp21pwd_entry: user not found in NIS+\n"));
- nis_freeresult(result);
- return False;
- }
-
- DEBUG(6,("mod_getnisp21pwd_entry: entry exists\n"));
-
- obj = NIS_RES_OBJECT(result);
-
- user_name = ENTRY_VAL(obj, NPF_NAME);
- oldnislmpwd = ENTRY_VAL(obj, NPF_LMPWD);
- oldnisntpwd = ENTRY_VAL(obj, NPF_NTPWD);
- oldnisacb = ENTRY_VAL(obj, NPF_ACB);
- oldnislct = ENTRY_VAL(obj, NPF_PWDLSET_T);
-
-
- if (!override && (*oldnislmpwd == '*' || *oldnislmpwd == 'X' ||
- *oldnisntpwd == '*' || *oldnisntpwd == 'X')) {
- /* Password deliberately invalid - end here. */
- DEBUG(10, ("mod_nisp21pwd_entry: entry invalidated for user %s\n", user_name));
- nis_freeresult(result);
- return False;
- }
-
- if (strlen(oldnislmpwd) != 32 || strlen(oldnisntpwd) != 32) {
- DEBUG(0, ("mod_nisp21pwd_entry: malformed password entry (incorrect length)\n"));
- nis_freeresult(result);
- return False;
- }
-
-
-
- /*
- * Now check if the account info and the password last
- * change time is available.
- */
-
- /*
- * If both NT and lanman passwords are provided - reset password
- * not required flag.
- */
-
- if(pwd->smb_passwd != NULL || pwd->smb_nt_passwd != NULL) {
- /* Require password in the future (should ACB_DISABLED also be reset?) */
- pwd->acct_ctrl &= ~(ACB_PWNOTREQ);
- }
-
- if (*oldnisacb == '[') {
-
- i = 0;
- acb[i++] = oldnisacb[i];
- while(i < (sizeof(fstring) - 2) && (oldnisacb[i] != ']'))
- acb[i] = oldnisacb[i++];
-
- acb[i++] = ']';
- acb[i++] = '\0';
-
- if (i == NEW_PW_FORMAT_SPACE_PADDED_LEN) {
- /*
- * We are using a new format, space padded
- * acct ctrl field. Encode the given acct ctrl
- * bits into it.
- */
- fstrcpy(acb, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
- } else {
- /*
- * If using the old format and the ACB_DISABLED or
- * ACB_PWNOTREQ are set then set the lanman and NT passwords to NULL
- * here as we have no space to encode the change.
- */
- if(pwd->acct_ctrl & (ACB_DISABLED|ACB_PWNOTREQ)) {
- pwd->smb_passwd = NULL;
- pwd->smb_nt_passwd = NULL;
- }
- }
-
- /* Now do the LCT stuff. */
- if (StrnCaseCmp(oldnislct, "LCT-", 4) == 0) {
-
- for(i = 0; i < 8; i++) {
- if(oldnislct[i+4] == '\0' || !isxdigit(oldnislct[i+4]))
- break;
- }
- if (i == 8) {
- /*
- * p points at 8 characters of hex digits -
- * read into a time_t as the seconds since
- * 1970 that the password was last changed.
- */
- got_pass_last_set_time = True;
- } /* i == 8 */
- } /* StrnCaseCmp() */
-
- } /* p == '[' */
-
- /* Entry is correctly formed. */
-
-
-
- /* Create the 32 byte representation of the new p16 */
- if(pwd->smb_passwd != NULL) {
- for (i = 0; i < 16; i++) {
- slprintf(&lmpwd[i*2], 32, "%02X", (uchar) pwd->smb_passwd[i]);
- }
- } else {
- if(pwd->acct_ctrl & ACB_PWNOTREQ)
- fstrcpy(lmpwd, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
- else
- fstrcpy(lmpwd, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- }
-
- /* Add on the NT md4 hash */
- if (pwd->smb_nt_passwd != NULL) {
- for (i = 0; i < 16; i++) {
- slprintf(&ntpwd[i*2], 32, "%02X", (uchar) pwd->smb_nt_passwd[i]);
- }
- } else {
- if(pwd->acct_ctrl & ACB_PWNOTREQ)
- fstrcpy(ntpwd, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX");
- else
- fstrcpy(ntpwd, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
- }
-
- pwd->pass_last_set_time = time(NULL);
-
- if(got_pass_last_set_time) {
- slprintf(lct, 12, "LCT-%08X", (uint32)pwd->pass_last_set_time);
- }
-
- set_single_attribute(obj, NPF_LMPWD, lmpwd, strlen(lmpwd), EN_CRYPT);
- set_single_attribute(obj, NPF_NTPWD, ntpwd, strlen(ntpwd), EN_CRYPT);
- set_single_attribute(obj, NPF_ACB, acb, strlen(acb), 0);
- set_single_attribute(obj, NPF_PWDLSET_T, lct, strlen(lct), 0);
-
- addresult =
- nis_add_entry(lp_smb_passwd_file(), obj,
- ADD_OVERWRITE | FOLLOW_PATH | EXPAND_NAME | HARD_LOOKUP);
-
- if(addresult->status != NIS_SUCCESS) {
- DEBUG(0, ("mod_nisp21pwd_entry: NIS+ table update failed: %s %s\n", nisname, nis_sperrno(addresult->status)));
- nis_freeresult(addresult);
- nis_freeresult(result);
- return False;
- }
-
- DEBUG(6,("mod_nisp21pwd_entry: password changed\n"));
-
- nis_freeresult(addresult);
- nis_freeresult(result);
-
- return True;
+ return False;
}
+/************************************************************************
+ makes a struct sam_passwd from a NIS+ result.
+ ************************************************************************/
+static BOOL make_sam_from_nisp(struct sam_passwd *pw_buf, nis_result *result)
+{
+ int uidval;
+ static pstring user_name;
+ static unsigned char smbpwd[16];
+ static unsigned char smbntpwd[16];
+ nis_object *obj;
+ uchar *p;
+
+ if (pw_buf == NULL || result == NULL) return False;
+
+ pwdb_init_sam(pw_buf);
+
+ if (result->status != NIS_SUCCESS)
+ {
+ DEBUG(0, ("make_smb_from_nisp: NIS+ lookup failure: %s\n",
+ nis_sperrno(result->status)));
+ return False;
+ }
+
+ /* User not found. */
+ if (NIS_RES_NUMOBJ(result) <= 0)
+ {
+ DEBUG(10, ("make_smb_from_nisp: user not found in NIS+\n"));
+ return False;
+ }
+
+ if (NIS_RES_NUMOBJ(result) > 1)
+ {
+ DEBUG(10, ("make_smb_from_nisp: WARNING: Multiple entries for user in NIS+ table!\n"));
+ }
+
+ /* Grab the first hit. */
+ obj = &NIS_RES_OBJECT(result)[0];
+
+ /* Check the lanman password column. */
+ p = (uchar *)ENTRY_VAL(obj, NPF_LMPWD);
+ if (strlen((char *)p) != 32 || !pwdb_gethexpwd((char *)p, (char *)smbpwd))
+ {
+ DEBUG(0, ("make_smb_from_nisp: malformed LM pwd entry.\n"));
+ return False;
+ }
+
+ /* Check the NT password column. */
+ p = (uchar *)ENTRY_VAL(obj, NPF_NTPWD);
+ if (strlen((char *)p) != 32 || !pwdb_gethexpwd((char *)p, (char *)smbntpwd))
+ {
+ DEBUG(0, ("make_smb_from_nisp: malformed NT pwd entry\n"));
+ return False;
+ }
+
+ strncpy(user_name, ENTRY_VAL(obj, NPF_NAME), sizeof(user_name));
+ uidval = atoi(ENTRY_VAL(obj, NPF_UID));
+
+ pw_buf->smb_name = user_name;
+ pw_buf->unix_uid = uidval;
+ pw_buf->smb_passwd = smbpwd;
+ pw_buf->smb_nt_passwd = smbntpwd;
+
+ return True;
+}
/*************************************************************************
Routine to search the nisplus passwd file for an entry matching the username
@@ -913,8 +524,8 @@ static struct sam_passwd *getnisp21pwnam(char *name)
return NULL;
}
- DEBUG(10, ("getnisp21pwnam: search by name: %s\n", name));
- DEBUG(10, ("getnisp21pwnam: using NIS+ table %s\n", lp_smb_passwd_file()));
+ DEBUG(10, ("getnisppwnam: search by name: %s\n", name));
+ DEBUG(10, ("getnisppwnam: using NIS+ table %s\n", lp_smb_passwd_file()));
slprintf(nisname, sizeof(nisname)-1, "[name=%s],%s", name, lp_smb_passwd_file());
@@ -930,12 +541,12 @@ static struct sam_passwd *getnisp21pwnam(char *name)
if (gotalarm)
{
- DEBUG(0,("getnisp21pwnam: NIS+ lookup time out\n"));
+ DEBUG(0,("getnisppwnam: NIS+ lookup time out\n"));
nis_freeresult(result);
return NULL;
}
- ret = make_sam_from_nisresult(&pw_buf, result);
+ ret = make_sam_from_nisp(&pw_buf, result);
nis_freeresult(result);
return ret ? &pw_buf : NULL;
@@ -954,7 +565,7 @@ static struct sam_passwd *getnisp21pwrid(uint32 rid)
if (!*lp_smb_passwd_file())
{
- DEBUG(0, ("getnisp21pwrid: no SMB password file set\n"));
+ DEBUG(0, ("No SMB password file set\n"));
return NULL;
}
@@ -980,7 +591,7 @@ static struct sam_passwd *getnisp21pwrid(uint32 rid)
return NULL;
}
- ret = make_sam_from_nisresult(&pw_buf, result);
+ ret = make_sam_from_nisp(&pw_buf, result);
nis_freeresult(result);
return ret ? &pw_buf : NULL;
@@ -992,57 +603,52 @@ static struct sam_passwd *getnisp21pwrid(uint32 rid)
static struct smb_passwd *getnisppwent(void *vp)
{
- return pdb_sam_to_smb(getnisp21pwent(vp));
+ return pwdb_sam_to_smb(getnisp21pwent(vp));
}
static BOOL add_nisppwd_entry(struct smb_passwd *newpwd)
{
- return add_nisp21pwd_entry(pdb_smb_to_sam(newpwd));
+ return add_nisp21pwd_entry(pwdb_smb_to_sam(newpwd));
}
static BOOL mod_nisppwd_entry(struct smb_passwd* pwd, BOOL override)
{
- return mod_nisp21pwd_entry(pdb_smb_to_sam(pwd), override);
-}
-
-static BOOL del_nisppwd_entry(const char *name)
-{
- return False; /* Dummy. */
+ return mod_nisp21pwd_entry(pwdb_smb_to_sam(pwd), override);
}
static struct smb_passwd *getnisppwnam(char *name)
{
- return pdb_sam_to_smb(getnisp21pwnam(name));
+ return pwdb_sam_to_smb(getnisp21pwnam(name));
}
-static struct sam_passwd *getnisp21pwuid(uid_t smb_userid)
+static struct sam_passwd *getnisp21pwuid(uid_t unix_uid)
{
- return getnisp21pwrid(pdb_uid_to_user_rid(smb_userid));
+ return getnisp21pwrid(pwdb_uid_to_user_rid(unix_uid));
}
-static struct smb_passwd *getnisppwrid(uint32 user_rid)
+static struct smb_passwd *getnisppwrid(uid_t user_rid)
{
- return pdb_sam_to_smb(getnisp21pwuid(pdb_user_rid_to_uid(user_rid)));
+ return pwdb_sam_to_smb(getnisp21pwuid(pwdb_user_rid_to_uid(user_rid)));
}
-static struct smb_passwd *getnisppwuid(uid_t smb_userid)
+static struct smb_passwd *getnisppwuid(uid_t unix_uid)
{
- return pdb_sam_to_smb(getnisp21pwuid(smb_userid));
+ return pwdb_sam_to_smb(getnisp21pwuid(unix_uid));
}
static struct sam_disp_info *getnispdispnam(char *name)
{
- return pdb_sam_to_dispinfo(getnisp21pwnam(name));
+ return pwdb_sam_to_dispinfo(getnisp21pwnam(name));
}
static struct sam_disp_info *getnispdisprid(uint32 rid)
{
- return pdb_sam_to_dispinfo(getnisp21pwrid(rid));
+ return pwdb_sam_to_dispinfo(getnisp21pwrid(rid));
}
static struct sam_disp_info *getnispdispent(void *vp)
{
- return pdb_sam_to_dispinfo(getnisp21pwent(vp));
+ return pwdb_sam_to_dispinfo(getnisp21pwent(vp));
}
static struct passdb_ops nispasswd_ops = {
@@ -1056,7 +662,6 @@ static struct passdb_ops nispasswd_ops = {
getnisppwent,
add_nisppwd_entry,
mod_nisppwd_entry,
- del_nisppwd_entry,
getnisp21pwent,
getnisp21pwnam,
getnisp21pwuid,
@@ -1068,7 +673,7 @@ static struct passdb_ops nispasswd_ops = {
getnispdispent
};
-struct passdb_ops *nisplus_initialize_password_db(void)
+struct passdb_ops *nisplus_initialise_password_db(void)
{
return &nispasswd_ops;
}
@@ -1088,7 +693,7 @@ static void useful_code(void) {
if (nis_user->status != NIS_SUCCESS || NIS_RES_NUMOBJ(nis_user) <= 0)
{
- DEBUG(3, ("useful_code: Unable to get NIS+ passwd entry for user: %s.\n",
+ DEBUG(3, ("add_nisppwd_entry: Unable to get NIS+ passwd entry for user: %s.\n",
nis_sperrno(nis_user->status)));
return False;
}
diff --git a/source/passdb/nt5ldap.c b/source/passdb/nt5ldap.c
new file mode 100644
index 00000000000..45436ae6b91
--- /dev/null
+++ b/source/passdb/nt5ldap.c
@@ -0,0 +1,751 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ Common nt5ldap stuff shared between passdb and samrd
+ Copyright (C) Luke Howard 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include "includes.h"
+
+#ifdef WITH_NT5LDAP
+
+#include <lber.h>
+#include <ldap.h>
+
+#include "ldapdb.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/***************************************************************
+ Get group and membership information.
+ ****************************************************************/
+
+BOOL nt5ldap_make_local_grp(LDAPDB * hds, LOCAL_GRP * group,
+ LOCAL_GRP_MEMBER ** members, int *num_membs, uint32 req_type)
+{
+ char **values;
+ LOCAL_GRP_MEMBER *memblist;
+ int i;
+ fstring grouptype;
+
+ if (!ldapdb_peek (hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_get_fvalue (hds, "sAMAccountName", group->name))
+ {
+ DEBUG (0, ("Missing sAMAccountName\n"));
+ return False;
+ }
+
+ DEBUG (2, ("Retrieving alias [%s]\n", group->name));
+
+ if (!ldapdb_get_fvalue (hds, "groupType", grouptype))
+ {
+ uint32 type = strtol (grouptype, NULL, 10);
+ if (!(type & (req_type | NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED)))
+ {
+ DEBUG (0, ("Invalid groupType\n"));
+ return False;
+ }
+ }
+
+ if (!ldapdb_get_rid (hds, "objectSid", &group->rid))
+ {
+ DEBUG (0, ("Missing objectSid\n"));
+ return False;
+ }
+
+ if (!ldapdb_get_fvalue (hds, "description", group->comment))
+ {
+ group->comment[0] = 0;
+ }
+
+ if (!members || !num_membs)
+ {
+ return True;
+ }
+
+ if (ldapdb_get_values (hds, "member", &values))
+ {
+ int ngroups;
+
+ ngroups = ldap_count_values (values);
+
+ memblist = calloc (ngroups, sizeof (LOCAL_GRP_MEMBER));
+ if (memblist == NULL)
+ {
+ return False;
+ }
+
+ *num_membs = 0;
+ *members = memblist;
+
+ for (i = 0; i < ngroups; i++)
+ {
+ if (nt5ldap_make_local_grp_member (hds, values[i], &memblist[*num_membs]))
+ {
+ (*num_membs)++;
+ }
+ }
+ ldap_value_free (values);
+ }
+ else
+ {
+ *num_membs = 0;
+ *members = NULL;
+ }
+
+ return True;
+}
+
+/************************************************************************
+ Queues the necessary modifications to save a LOCAL_GRP structure
+ ************************************************************************/
+
+BOOL
+nt5ldap_local_grp_mods (const LOCAL_GRP * group, LDAPMod *** mods, int operation, uint32 req_type)
+{
+ struct berval *bv;
+
+ *mods = NULL;
+
+ if (operation == LDAP_MOD_ADD)
+ {
+ /* immutable attributes */
+ fstring temp;
+
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "top") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "group") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "securityPrincipal") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "cn", group->name) ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "sAMAccountName", group->name))
+ {
+ return False;
+ }
+
+ slprintf (temp, sizeof (temp) - 1, "%d",
+ req_type | NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "groupType", temp))
+ {
+ return False;
+ }
+
+ /* Put the RID in for good measure. */
+ if (!ldapdb_queue_uint32_mod (mods, LDAP_MOD_ADD, "rid", group->rid) ||
+ !rid_to_berval (group->rid, &bv))
+ {
+ return False;
+ }
+
+ if (!ldapdb_queue_mod_len (mods, LDAP_MOD_ADD, "objectSid", bv))
+ {
+ ber_bvfree (bv);
+ return False;
+ }
+ }
+
+ return ldapdb_queue_mod (mods, operation, "description", group->comment);
+}
+
+/************************************************************************
+ Create a alias member entry
+ ************************************************************************/
+
+BOOL
+nt5ldap_local_grp_member_mods (const DOM_SID * user_sid, LDAPMod *** mods,
+ int operation, pstring member)
+{
+ if (ldapdb_sid_to_dn (NULL, user_sid, member) == False)
+ {
+ return False;
+ }
+
+ *mods = NULL;
+
+ return ldapdb_queue_mod (mods, operation, "member", member);
+}
+
+BOOL
+nt5ldap_make_local_grp_member (LDAPDB * _hds, const char *dn, LOCAL_GRP_MEMBER * member)
+{
+ char *attrs[] =
+ {"sAMAccountName", "userAccountFlags", "objectSid", NULL};
+ LDAPDB_DECLARE_HANDLE (hds);
+ fstring user;
+ fstring domain;
+
+ if (!LDAPDB_OPEN (_hds, &hds))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!ldapdb_read (hds, dn, attrs) ||
+ !ldapdb_get_sid (hds, "objectSid", &member->sid) ||
+ !ldapdb_get_fvalue (hds, "sAMAccountName", user) ||
+ !map_domain_sid_to_name (&member->sid, domain))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ slprintf (member->name, sizeof (member->name), "%s\\%s", domain, user);
+ member->sid_use = SID_NAME_ALIAS;
+
+ ldapdb_close (&hds);
+
+ return True;
+}
+
+BOOL
+nt5ldap_make_domain_grp_member (LDAPDB * _hds, const char *dn, DOMAIN_GRP_MEMBER * member)
+{
+ char *attrs[] =
+ {"sAMAccountName", "userAccountFlags", "objectSid", NULL};
+ LDAPDB_DECLARE_HANDLE (hds);
+ fstring user;
+
+ if (!LDAPDB_OPEN (_hds, &hds))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (!ldapdb_read (hds, dn, attrs) ||
+ !ldapdb_get_rid (hds, "objectSid", &member->rid) ||
+ !ldapdb_get_fvalue (hds, "sAMAccountName", user))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ slprintf (member->name, sizeof (member->name), "%s\\%s", global_sam_name, user);
+ member->sid_use = SID_NAME_DOM_GRP;
+ member->attr = 0x7;
+
+ ldapdb_close (&hds);
+
+ return True;
+}
+
+/***************************************************************
+ Get group and membership information.
+ ****************************************************************/
+
+BOOL
+nt5ldap_make_domain_grp (LDAPDB * hds, DOMAIN_GRP * group,
+ DOMAIN_GRP_MEMBER ** members, int *num_membs)
+{
+ char **values;
+ DOMAIN_GRP_MEMBER *memblist;
+ int i;
+ fstring grouptype;
+
+ if (!ldapdb_peek (hds))
+ {
+ return False;
+ }
+
+ if (!ldapdb_get_fvalue (hds, "sAMAccountName", group->name))
+ {
+ DEBUG (0, ("Domain group missing sAMAccountName\n"));
+ return False;
+ }
+
+ DEBUG (2, ("Retrieving domain group [%s]\n", group->name));
+
+ if (!ldapdb_get_fvalue (hds, "groupType", grouptype))
+ {
+ uint32 type = strtol (grouptype, NULL, 10);
+ if (!(type & (NTDS_GROUP_TYPE_GLOBAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED)))
+ {
+ DEBUG (0, ("Domain group has invalid groupType\n"));
+ return False;
+ }
+ }
+
+ if (!ldapdb_get_rid (hds, "objectSid", &group->rid))
+ {
+ DEBUG (0, ("Domain group missing objectSid\n"));
+ return False;
+ }
+
+ if (!ldapdb_get_fvalue (hds, "description", group->comment))
+ {
+ group->comment[0] = 0;
+ }
+
+ group->attr = 0x7;
+
+ if (!members || !num_membs)
+ {
+ return True;
+ }
+
+ if (ldapdb_get_values (hds, "member", &values) == True)
+ {
+ int ngroups;
+
+ ngroups = ldap_count_values (values);
+
+ memblist = calloc (ngroups, sizeof (DOMAIN_GRP_MEMBER));
+ if (memblist == NULL)
+ {
+ return False;
+ }
+
+ *num_membs = 0;
+ *members = memblist;
+
+ for (i = 0; i < ngroups; i++)
+ {
+ if (nt5ldap_make_domain_grp_member (hds, values[i], &memblist[*num_membs]) == TRUE)
+ {
+ (*num_membs)++;
+ }
+ }
+ ldap_value_free (values);
+ }
+ else
+ {
+ *num_membs = 0;
+ *members = NULL;
+ }
+
+ return True;
+}
+
+
+/************************************************************************
+ Queues the necessary modifications to save a DOMAIN_GRP structure
+ ************************************************************************/
+
+BOOL
+nt5ldap_domain_grp_mods (const DOMAIN_GRP * group, LDAPMod *** mods,
+ int operation)
+{
+ struct berval *bv = NULL;
+
+ *mods = NULL;
+
+ if (operation == LDAP_MOD_ADD)
+ {
+ /* immutable attributes */
+ fstring temp;
+
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "top") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "group") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "securityPrincipal") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "sAMAccountName", group->name) ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "cn", group->name))
+ {
+ return False;
+ }
+
+ slprintf (temp, sizeof (temp) - 1, "%d", NTDS_GROUP_TYPE_GLOBAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "groupType", temp))
+ {
+ return False;
+ }
+
+ /* Put the RID in for good measure. */
+ if (!ldapdb_queue_uint32_mod (mods, LDAP_MOD_ADD, "rid", group->rid) ||
+ !rid_to_berval (group->rid, &bv))
+ {
+ return False;
+ }
+
+ if (!ldapdb_queue_mod_len (mods, LDAP_MOD_ADD, "objectSid", bv))
+ {
+ ber_bvfree (bv);
+ return False;
+ }
+ }
+
+ return ldapdb_queue_mod (mods, operation, "description", group->comment);
+}
+
+
+/************************************************************************
+ Create a group member entry
+ ************************************************************************/
+
+BOOL
+nt5ldap_domain_grp_member_mods (uint32 user_rid, LDAPMod *** mods, int operation, pstring member)
+{
+ if (ldapdb_rid_to_dn (NULL, user_rid, member) == False)
+ {
+ return False;
+ }
+
+ *mods = NULL;
+
+ return ldapdb_queue_mod (mods, operation, "member", member);
+}
+
+/*
+ * Parse the current entry into a SAM_USER_INFO_21 structure.
+ */
+BOOL nt5ldap_make_sam_user_info21(LDAPDB *hds, SAM_USER_INFO_21 *usr)
+{
+ struct berval *bv;
+ NTDS_USER_FLAG_ENUM uac;
+
+ if (!ldapdb_peek(hds))
+ {
+ return False;
+ }
+
+ memset(usr, 0, sizeof(*usr));
+
+ (void) ldapdb_get_time(hds, "lastLogon", &usr->logon_time);
+ (void) ldapdb_get_time(hds, "lastLogoff", &usr->logoff_time);
+ (void) ldapdb_get_time(hds, "accountExpires", &usr->pass_must_change_time);
+ (void) ldapdb_get_time(hds, "pwdLastSet", &usr->pass_last_set_time);
+ /* TODO: kickoff_time */
+ /* TODO: pass_must_change_time */
+
+ if (!ldapdb_get_rid(hds, "objectSid", &usr->user_rid))
+ {
+ DEBUG(0,("SAM account missing objectSid\n"));
+ return False;
+ }
+
+ (void) ldapdb_get_uint32(hds, "primaryGroupId", &usr->group_rid);
+
+ if (ldapdb_get_uint32(hds, "userAccountControl", &uac))
+ {
+ usr->acb_info = pwdb_acct_ctrl_from_ad(uac);
+ }
+ else
+ {
+ usr->acb_info = ACB_NORMAL;
+ }
+
+ if (ldapdb_get_value_len(hds, "dBCSPwd", &bv))
+ {
+ if (!berval_to_unicodepwd(bv, usr->lm_pwd))
+ {
+ usr->acb_info |= ACB_DISABLED;
+ }
+ ber_bvfree(bv);
+ }
+
+ if (ldapdb_get_value_len(hds, "unicodePwd", &bv))
+ {
+ (void) berval_to_unicodepwd(bv, usr->nt_pwd);
+ ber_bvfree(bv);
+ }
+
+ memset(usr->logon_hrs.hours, 0, sizeof(usr->logon_hrs.hours));
+ usr->logon_hrs.len = 0;
+
+ if (ldapdb_get_value_len(hds, "logonHours", &bv))
+ {
+ if (bv->bv_len <= sizeof(usr->logon_hrs.hours))
+ {
+ memcpy(usr->logon_hrs.hours, bv->bv_val, bv->bv_len);
+ usr->logon_hrs.len = bv->bv_len;
+ }
+ ber_bvfree(bv);
+ }
+
+ usr->unknown_3 = 0x00ffffff;
+ usr->logon_divs = 168;
+ usr->ptr_logon_hrs = 0;
+ usr->unknown_5 = 0x00020000;
+ usr->unknown_6 = 0x000004ec;
+
+ if (!ldapdb_get_unistr_value(hds, "sAMAccountName", &usr->uni_user_name))
+ {
+ DEBUG(0,("SAM account missing sAMAccountName\n"));
+ return False;
+ }
+
+ if (!ldapdb_get_unistr_value(hds, "displayName", &usr->uni_full_name))
+ {
+ (void) ldapdb_get_unistr_value(hds, "cn", &usr->uni_full_name);
+ }
+
+ (void) ldapdb_get_unistr_value(hds, "homeDirectory", &usr->uni_home_dir);
+ (void) ldapdb_get_unistr_value(hds, "homeDrive", &usr->uni_dir_drive);
+ (void) ldapdb_get_unistr_value(hds, "scriptPath", &usr->uni_logon_script);
+ (void) ldapdb_get_unistr_value(hds, "profilePath", &usr->uni_profile_path);
+ (void) ldapdb_get_unistr_value(hds, "description", &usr->uni_acct_desc);
+ (void) ldapdb_get_unistr_value(hds, "userWorkstations", &usr->uni_workstations);
+
+ return True;
+}
+
+/*
+ * Parse a SAM_USER_INFO_21 structure into a set of LDAP modifications.
+ * Doesn't actually commit them to the directory.
+ */
+BOOL nt5ldap_sam_user_info21_mods(const SAM_USER_INFO_21 *usr, LDAPMod ***mods, int op,
+ char *rdn, size_t rdnmaxlen, BOOL *iscomputer_p)
+{
+ const UNISTR2 *c_name;
+ UNISTR2 uni_hostname;
+ fstring upn, spn, hostname;
+ struct berval *bv;
+
+ c_name = NULL;
+
+ if (op == LDAP_MOD_ADD)
+ {
+ BOOL iscomputer;
+ int hostname_len;
+ const char *realm = ldapdb_get_realm_name();
+
+ unistr2_to_ascii(hostname, &usr->uni_user_name, sizeof(hostname)-1);
+ hostname_len = strlen(hostname);
+ iscomputer = (hostname[hostname_len - 1] == '$');
+
+ if (iscomputer)
+ {
+ /* Chop '$' sign */
+ hostname[hostname_len - 1] = '\0';
+ slprintf(spn, sizeof(spn)-1, "host/%s", hostname);
+
+ if (!ldapdb_queue_mod(mods, LDAP_MOD_ADD, "dNSHostName", hostname) ||
+ !ldapdb_queue_mod(mods, LDAP_MOD_ADD, "servicePrincipalName", spn))
+ {
+ return False;
+ }
+
+ if (realm)
+ {
+ slprintf(upn, sizeof(upn)-1, "%s@%s", spn, realm);
+ }
+
+ ascii_to_unistr(uni_hostname.buffer, hostname, sizeof(uni_hostname.buffer)-1);
+ c_name = &uni_hostname;
+ }
+ else
+ {
+ if (realm)
+ {
+ fstring username;
+
+ unistr2_to_ascii(username, &usr->uni_user_name, sizeof(username)-1);
+ slprintf(upn, sizeof(upn)-1, "%s@%s", username, realm);
+ }
+ }
+
+ if (iscomputer_p)
+ {
+ *iscomputer_p = iscomputer;
+ }
+
+ if (realm)
+ {
+#ifdef KRB5_AUTH
+ char *p, *q;
+#endif /* KRB5_AUTH */
+ if (!ldapdb_queue_mod(mods, LDAP_MOD_ADD, "userPrincipalName", upn))
+ {
+ return False;
+ }
+
+#ifdef KRB5_AUTH
+ p = strchr(upn, '@');
+ if (p == NULL)
+ {
+ return False;
+ }
+ ++p;
+ for (q = p; *q != '\0'; q++)
+ {
+ *q = toupper(*q);
+ }
+ if (!ldapdb_queue_mod(mods, LDAP_MOD_ADD, "krbName", upn) ||
+ !ldapdb_queue_mod(mods, LDAP_MOD_ADD, "krb5PrincipalName", upn) ||
+ !ldapdb_queue_mod(mods, LDAP_MOD_ADD, "objectclass", "kerberosSecurityObject") ||
+ !ldapdb_queue_mod(mods, LDAP_MOD_ADD, "objectclass", "krb5Principal"))
+ {
+ return False;
+ }
+#endif /* KRB5_AUTH */
+ }
+
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "top") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "person") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "organizationalPerson") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "securityPrincipal") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "user"))
+ {
+ return False;
+ }
+
+ if (iscomputer && !ldapdb_queue_mod(mods, LDAP_MOD_ADD, "objectClass", "computer"))
+ {
+ return False;
+ }
+
+ if (!ldapdb_queue_unistr_mod(mods, LDAP_MOD_ADD, "sAMAccountName", &usr->uni_user_name))
+ {
+ return False;
+ }
+
+ if (!rid_to_berval(usr->user_rid, &bv))
+ {
+ return False;
+ }
+ if (!ldapdb_queue_mod_len (mods, LDAP_MOD_ADD, "objectSid", bv))
+ {
+ ber_bvfree(bv);
+ return False;
+ }
+
+ if (!ldapdb_queue_uint32_mod(mods, LDAP_MOD_ADD, "primaryGroupId", usr->group_rid))
+ {
+ return False;
+ }
+
+ }
+
+ if (c_name == NULL)
+ {
+ c_name = usr->uni_full_name.uni_str_len ? &usr->uni_full_name : &usr->uni_user_name;
+ }
+
+ if (rdn)
+ {
+ unistr2_to_ascii(rdn, c_name, rdnmaxlen);
+ }
+
+ if (!ldapdb_queue_unistr_mod(mods, op, "cn", c_name) ||
+ !ldapdb_queue_unistr_mod(mods, op, "name", c_name) ||
+ !ldapdb_queue_unistr_mod(mods, op, "displayName", c_name) ||
+ !ldapdb_queue_unistr_mod(mods, op, "homeDirectory", &usr->uni_home_dir) ||
+ !ldapdb_queue_unistr_mod(mods, op, "homeDrive", &usr->uni_dir_drive) ||
+ !ldapdb_queue_unistr_mod(mods, op, "scriptPath", &usr->uni_logon_script) ||
+ !ldapdb_queue_unistr_mod(mods, op, "profilePath", &usr->uni_profile_path) ||
+ !ldapdb_queue_unistr_mod(mods, op, "description", &usr->uni_acct_desc) ||
+ !ldapdb_queue_unistr_mod(mods, op, "userWorkstations", &usr->uni_workstations) ||
+ !ldapdb_queue_time (mods, op, "lastLogon", &usr->logon_time) ||
+ !ldapdb_queue_time (mods, op, "lastLogoff", &usr->logoff_time) ||
+ /* kickoff_time */
+ !ldapdb_queue_time (mods, op, "pwdLastSet", &usr->pass_last_set_time) ||
+ /* pass_can_change_time */
+ !ldapdb_queue_time (mods, op, "accountExpires", &usr->pass_must_change_time))
+ {
+ return False;
+ }
+
+ if (dbcspwd_to_berval(usr->lm_pwd, &bv))
+ {
+ if (!ldapdb_queue_mod_len(mods, op, "dBCSPwd", bv))
+ {
+ ber_bvfree(bv);
+ return False;
+ }
+ }
+
+ if (unicodepwd_to_berval(usr->nt_pwd, &bv))
+ {
+ if (!ldapdb_queue_mod_len(mods, op, "unicodePwd", bv))
+ {
+ ber_bvfree(bv);
+ return False;
+ }
+ }
+
+ if (usr->logon_hrs.len)
+ {
+ bv = (struct berval *)malloc(sizeof(*bv));
+ if (bv == NULL)
+ {
+ return False;
+ }
+ bv->bv_len = usr->logon_hrs.len;
+ bv->bv_val = malloc(usr->logon_hrs.len);
+ if (bv->bv_val == NULL)
+ {
+ free(bv);
+ return False;
+ }
+
+ memcpy(bv->bv_val, usr->logon_hrs.hours, bv->bv_len);
+ if (!ldapdb_queue_mod_len(mods, op, "logonHours", bv))
+ {
+ ber_bvfree(bv);
+ return False;
+ }
+ }
+
+ return ldapdb_queue_uint32_mod(mods, op, "userAccountControl", pwdb_acct_ctrl_to_ad(usr->acb_info));
+}
+
+
+/***************************************************************
+ Enumerate RIDs of groups which user is a member of, of type
+ given by attribute.
+ ****************************************************************/
+
+BOOL
+nt5ldap_make_group_rids (LDAPDB * _hds, const char *dn, uint32 ** rids, int *numrids, uint32 req_type)
+{
+ LDAPDB_DECLARE_HANDLE (hds);
+ pstring filter;
+ int i, ngroups;
+
+ if (!LDAPDB_OPEN (_hds, &hds))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ slprintf (filter, sizeof (filter) - 1, "(&(objectClass=Group)(member=%s)(groupType=%d))",
+ dn, req_type | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+ (void) ldapdb_set_synchronous (hds, True);
+ if (!ldapdb_search (hds, NULL, filter, NULL, LDAP_NO_LIMIT) ||
+ !ldapdb_count_entries (hds, &ngroups))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ *rids = (uint32 *) calloc (ngroups, sizeof (uint32));
+ if (*rids == NULL)
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ *numrids = 0;
+ for (i = 0; i < ngroups; i++)
+ {
+ if (ldapdb_get_rid (hds, "objectSid", &(*rids)[i]) == True)
+ {
+ (*numrids)++;
+ }
+ if (!ldapdb_seq (hds))
+ {
+ break;
+ }
+ }
+ ldapdb_close (&hds);
+
+ return True;
+}
+#endif /* WITH_NT5LDAP */
+
diff --git a/source/passdb/pass_check.c b/source/passdb/pass_check.c
index 11ce0d754e8..d89ef2e6c9d 100644
--- a/source/passdb/pass_check.c
+++ b/source/passdb/pass_check.c
@@ -32,7 +32,7 @@ static char this_salt[100]="";
static char this_crypted[100]="";
-#ifdef WITH_PAM
+#ifdef HAVE_PAM
/*******************************************************************
check on PAM authentication
********************************************************************/
@@ -136,10 +136,6 @@ static BOOL pam_auth(char *user,char *password)
#ifdef WITH_AFS
-
-#include <afs/stds.h>
-#include <afs/kautils.h>
-
/*******************************************************************
check on AFS authentication
********************************************************************/
@@ -162,7 +158,6 @@ static BOOL afs_auth(char *user,char *password)
&reason) == 0) {
return(True);
}
- DEBUG(1,("AFS authentication for \"%s\" failed (%s)\n", user, reason));
return(False);
}
#endif
@@ -170,9 +165,6 @@ static BOOL afs_auth(char *user,char *password)
#ifdef WITH_DFS
-#include <dce/dce_error.h>
-#include <dce/sec_login.h>
-
/*****************************************************************
This new version of the DFS_AUTH code was donated by Karsten Muuss
<muuss@or.uni-bonn.de>. It fixes the following problems with the
@@ -203,7 +195,6 @@ static BOOL dfs_auth(char *user,char *password)
sec_passwd_rec_t passwd_rec;
sec_login_auth_src_t auth_src = sec_login_auth_src_network;
unsigned char dce_errstr[dce_c_error_string_len];
- gid_t egid;
if (dcelogin_atmost_once) return(False);
@@ -331,16 +322,14 @@ static BOOL dfs_auth(char *user,char *password)
* back to being root on error though. JRA.
*/
- egid = getegid();
-
- if (set_effective_gid(pw->pw_gid) != 0) {
+ if (setregid(-1, pw->pw_gid) != 0) {
DEBUG(0,("Can't set egid to %d (%s)\n",
pw->pw_gid, strerror(errno)));
return False;
}
- if (set_effective_uid(pw->pw_uid) != 0) {
- set_effective_gid(egid);
+ if (setreuid(-1, pw->pw_uid) != 0) {
+ setgid(0);
DEBUG(0,("Can't set euid to %d (%s)\n",
pw->pw_uid, strerror(errno)));
return False;
@@ -351,17 +340,24 @@ static BOOL dfs_auth(char *user,char *password)
&my_dce_sec_context,
&err) == 0) {
dce_error_inq_text(err, dce_errstr, &err2);
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE Setup Identity for %s failed: %s\n",
user,dce_errstr));
- goto err;
+ return(False);
}
sec_login_get_pwent(my_dce_sec_context,
(sec_login_passwd_t*)&pw, &err);
if (err != error_status_ok ) {
dce_error_inq_text(err, dce_errstr, &err2);
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr));
- goto err;
+
+ return(False);
}
passwd_rec.version_number = sec_passwd_c_version_none;
@@ -374,16 +370,24 @@ static BOOL dfs_auth(char *user,char *password)
&auth_src, &err);
if (err != error_status_ok ) {
dce_error_inq_text(err, dce_errstr, &err2);
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE Identity Validation failed for principal %s: %s\n",
user,dce_errstr));
- goto err;
+
+ return(False);
}
sec_login_certify_identity(my_dce_sec_context, &err);
if (err != error_status_ok) {
dce_error_inq_text(err, dce_errstr, &err2);
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE certify identity failed: %s\n", dce_errstr));
- goto err;
+
+ return(False);
}
if (auth_src != sec_login_auth_src_network) {
@@ -397,7 +401,10 @@ static BOOL dfs_auth(char *user,char *password)
user,dce_errstr));
sec_login_purge_context(&my_dce_sec_context, &err);
- goto err;
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
+ return(False);
}
sec_login_get_pwent(my_dce_sec_context,
@@ -405,7 +412,11 @@ static BOOL dfs_auth(char *user,char *password)
if (err != error_status_ok) {
dce_error_inq_text(err, dce_errstr, &err2);
DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr));
- goto err;
+
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
+ return(False);
}
DEBUG(0,("DCE login succeeded for principal %s on pid %d\n",
@@ -423,24 +434,21 @@ static BOOL dfs_auth(char *user,char *password)
sec_login_get_expiration(my_dce_sec_context, &expire_time, &err);
if (err != error_status_ok) {
dce_error_inq_text(err, dce_errstr, &err2);
+ /* Go back to root, JRA. */
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE can't get expiration. %s\n", dce_errstr));
- goto err;
+
+ return(False);
}
- set_effective_uid(0);
- set_effective_gid(0);
+ setuid(0);
+ setgid(0);
DEBUG(0,("DCE context expires: %s",asctime(localtime(&expire_time))));
dcelogin_atmost_once = 1;
return (True);
-
-err:
-
- /* Go back to root, JRA. */
- set_effective_uid(0);
- set_effective_gid(egid);
- return(False);
}
void dfs_unlogin(void)
@@ -459,9 +467,6 @@ void dfs_unlogin(void)
#endif
#ifdef KRB5_AUTH
-
-#include <krb5.h>
-
/*******************************************************************
check on Kerberos authentication
********************************************************************/
@@ -609,7 +614,6 @@ static char *osf1_bigcrypt(char *password,char *salt1)
StrnCpy(salt,salt1,2);
StrnCpy(result,salt1,2);
- result[2]='\0';
for (i=0; i<parts;i++) {
p1 = crypt(p2,salt);
@@ -676,7 +680,7 @@ core of password checking routine
static BOOL password_check(char *password)
{
-#ifdef WITH_PAM
+#ifdef HAVE_PAM
/* This falls through if the password check fails
- if HAVE_CRYPT is not defined this causes an error msg
saying Warning - no crypt available
@@ -687,23 +691,23 @@ static BOOL password_check(char *password)
Hence we make a direct return to avoid a second chance!!!
*/
return (pam_auth(this_user,password));
-#endif /* WITH_PAM */
+#endif
#ifdef WITH_AFS
if (afs_auth(this_user,password)) return(True);
-#endif /* WITH_AFS */
+#endif
#ifdef WITH_DFS
if (dfs_auth(this_user,password)) return(True);
-#endif /* WITH_DFS */
+#endif
#ifdef KRB5_AUTH
if (krb5_auth(this_user,password)) return(True);
-#endif /* KRB5_AUTH */
+#endif
#ifdef KRB4_AUTH
if (krb4_auth(this_user,password)) return(True);
-#endif /* KRB4_AUTH */
+#endif
#ifdef OSF1_ENH_SEC
{
@@ -714,42 +718,26 @@ static BOOL password_check(char *password)
}
return ret;
}
-#endif /* OSF1_ENH_SEC */
+#endif
#ifdef ULTRIX_AUTH
return (strcmp((char *)crypt16(password, this_salt ),this_crypted) == 0);
-#endif /* ULTRIX_AUTH */
+#endif
#ifdef LINUX_BIGCRYPT
return(linux_bigcrypt(password,this_salt,this_crypted));
-#endif /* LINUX_BIGCRYPT */
-
-#if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS)
-
- /*
- * Some systems have bigcrypt in the C library but might not
- * actually use it for the password hashes (HPUX 10.20) is
- * a noteable example. So we try bigcrypt first, followed
- * by crypt.
- */
-
- if(strcmp(bigcrypt(password,this_salt),this_crypted) == 0)
- return True;
- else
- return (strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
-#else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
+#endif
#ifdef HAVE_BIGCRYPT
return(strcmp(bigcrypt(password,this_salt),this_crypted) == 0);
-#endif /* HAVE_BIGCRYPT */
+#endif
#ifndef HAVE_CRYPT
DEBUG(1,("Warning - no crypt available\n"));
return(False);
-#else /* HAVE_CRYPT */
+#else
return(strcmp((char *)crypt(password,this_salt),this_crypted) == 0);
-#endif /* HAVE_CRYPT */
-#endif /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */
+#endif
}
@@ -760,112 +748,61 @@ the function pointer fn() points to a function to call when a successful
match is found and is used to update the encrypted password file
return True on correct match, False otherwise
****************************************************************************/
-BOOL pass_check(char *user,char *password, int pwlen, struct passwd *pwd,
- BOOL (*fn)(char *, char *))
+BOOL pass_check(const char *_user, const char *_password,
+ int pwlen, const struct passwd *pwd,
+ BOOL (*fn)(const char *, const char *))
{
pstring pass2;
int level = lp_passwordlevel();
- struct passwd *pass;
+ const struct passwd *pass;
+ fstring password;
+ fstring user;
- if (password) password[pwlen] = 0;
+ fstrcpy(user, _user);
#if DEBUG_PASSWORD
- DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password));
+ DEBUG(100,("checking user=[%s] pass=",user));
+ dump_data(100, password, strlen(password));
#endif
- if (!password) {
- return(False);
- }
-
- if (((!*password) || (!pwlen)) && !lp_null_passwords()) {
+ if (!_password)
+ {
return(False);
}
- if (pwd && !user) {
- pass = (struct passwd *) pwd;
- user = pass->pw_name;
- } else {
- pass = Get_Pwnam(user,True);
- }
-
+ pwlen = MIN(sizeof(password)-1, pwlen);
+ memset(password, 0, sizeof(password));
+ memcpy(password, _password, pwlen);
- DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen));
-
- if (!pass) {
- DEBUG(3,("Couldn't find user %s\n",user));
+ if (((!*password) || (!pwlen)) && !lp_null_passwords()) {
return(False);
}
-#ifdef HAVE_GETSPNAM
+ if (pwd != NULL && _user == NULL)
{
- struct spwd *spass;
-
- /* many shadow systems require you to be root to get
- the password, in most cases this should already be
- the case when this function is called, except
- perhaps for IPC password changing requests */
-
- spass = getspnam(pass->pw_name);
- if (spass && spass->sp_pwdp) {
- pstrcpy(pass->pw_passwd,spass->sp_pwdp);
- }
+ pass = (const struct passwd *) pwd;
+ fstrcpy(user, pass->pw_name);
}
-#elif defined(IA_UINFO)
+ else
{
- /* Need to get password with SVR4.2's ia_ functions
- instead of get{sp,pw}ent functions. Required by
- UnixWare 2.x, tested on version
- 2.1. (tangent@cyberport.com) */
- uinfo_t uinfo;
- if (ia_openinfo(pass->pw_name, &uinfo) != -1) {
- ia_get_logpwd(uinfo, &(pass->pw_passwd));
- }
+ pass = Get_Pwnam(user,True);
}
-#endif
-#ifdef HAVE_GETPRPWNAM
- {
- struct pr_passwd *pr_pw = getprpwnam(pass->pw_name);
- if (pr_pw && pr_pw->ufld.fd_encrypt)
- pstrcpy(pass->pw_passwd,pr_pw->ufld.fd_encrypt);
- }
-#endif
-#ifdef OSF1_ENH_SEC
- {
- struct pr_passwd *mypasswd;
- DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n",
- user));
- mypasswd = getprpwnam (user);
- if (mypasswd) {
- fstrcpy(pass->pw_name,mypasswd->ufld.fd_name);
- fstrcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt);
- } else {
- DEBUG(5,("OSF1_ENH_SEC: No entry for user %s in protected database !\n",
- user));
- }
- }
-#endif
+ DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen));
-#ifdef ULTRIX_AUTH
+ if (pass == NULL)
{
- AUTHORIZATION *ap = getauthuid(pass->pw_uid);
- if (ap) {
- fstrcpy(pass->pw_passwd, ap->a_password);
- endauthent();
- }
+ DEBUG(3,("Couldn't find user %s\n",user));
+ return(False);
}
-#endif
/* extract relevant info */
fstrcpy(this_user,pass->pw_name);
fstrcpy(this_salt,pass->pw_passwd);
-
-#if defined(HAVE_TRUNCATED_SALT)
/* crypt on some platforms (HPUX in particular)
won't work with more than 2 salt characters. */
this_salt[2] = 0;
-#endif
fstrcpy(this_crypted,pass->pw_passwd);
diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c
index 30ea1d9bd6e..8c596f96acb 100644
--- a/source/passdb/passdb.c
+++ b/source/passdb/passdb.c
@@ -22,20 +22,11 @@
#include "includes.h"
#include "nterr.h"
+#include "sids.h"
extern int DEBUGLEVEL;
/*
- * This is set on startup - it defines the SID for this
- * machine, and therefore the SAM database for which it is
- * responsible.
- */
-
-extern DOM_SID global_sam_sid;
-extern pstring global_myname;
-extern fstring global_myworkgroup;
-
-/*
* NOTE. All these functions are abstracted into a structure
* that points to the correct function for the selected database. JRA.
*
@@ -51,36 +42,43 @@ extern fstring global_myworkgroup;
* functions in a first pass, as struct sam_passwd contains more
* information, needed by the NT Domain support.
*
- * a full example set of derivative functions are listed below. an API
- * writer is expected to cut/paste these into their module, replace
- * either one set (struct smb_passwd) or the other (struct sam_passwd)
- * OR both, and optionally also to write display info routines
- * (struct sam_disp_info). lkcl
+ * an API writer is expected to create either one set (struct smb_passwd) or
+ * the other (struct sam_passwd) OR both, and optionally also to write display
+ * info routines * (struct sam_disp_info). functions which the API writer
+ * chooses NOT to write must be wrapped in conversion functions (pwdb_x_to_y)
+ * such that API users can call any function and still get valid results.
+ *
+ * the password API does NOT fill in the gaps if you set an API function
+ * to NULL: it will deliberately attempt to call the NULL function.
*
*/
-static struct passdb_ops *pdb_ops;
+static struct smb_passdb_ops *pwdb_ops;
/***************************************************************
- Initialize the password db operations.
+ Initialise the password db operations.
***************************************************************/
-BOOL initialize_password_db(void)
+BOOL initialise_password_db(void)
{
- if (pdb_ops)
+ if (pwdb_ops)
{
return True;
}
#ifdef WITH_NISPLUS
- pdb_ops = nisplus_initialize_password_db();
+ pwdb_ops = nisplus_initialise_password_db();
+#elif defined(WITH_NT5LDAP)
+ pwdb_ops = nt5ldap_initialise_password_db();
#elif defined(WITH_LDAP)
- pdb_ops = ldap_initialize_password_db();
-#else
- pdb_ops = file_initialize_password_db();
+ pwdb_ops = ldap_initialise_password_db();
+#elif defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
+ pwdb_ops = mysql_initialise_password_db();
+#elif defined(USE_SMBPASS_DB)
+ pwdb_ops = file_initialise_password_db();
#endif
- return (pdb_ops != NULL);
+ return pwdb_ops != NULL;
}
/*
@@ -88,25 +86,16 @@ BOOL initialize_password_db(void)
*/
/************************************************************************
- Utility function to search smb passwd by rid.
-*************************************************************************/
-
-struct smb_passwd *iterate_getsmbpwrid(uint32 user_rid)
-{
- return iterate_getsmbpwuid(pdb_user_rid_to_uid(user_rid));
-}
-
-/************************************************************************
Utility function to search smb passwd by uid. use this if your database
does not have search facilities.
*************************************************************************/
-struct smb_passwd *iterate_getsmbpwuid(uid_t smb_userid)
+struct smb_passwd *iterate_getsmbpwuid(uid_t unix_uid)
{
struct smb_passwd *pwd = NULL;
void *fp = NULL;
- DEBUG(10, ("search by smb_userid: %x\n", (int)smb_userid));
+ DEBUG(10, ("search by unix_uid: %x\n", (int)unix_uid));
/* Open the smb password database - not for update. */
fp = startsmbpwent(False);
@@ -117,12 +106,13 @@ struct smb_passwd *iterate_getsmbpwuid(uid_t smb_userid)
return NULL;
}
- while ((pwd = getsmbpwent(fp)) != NULL && pwd->smb_userid != smb_userid)
- ;
+ while ((pwd = getsmbpwent(fp)) != NULL && pwd->unix_uid != unix_uid)
+ {
+ }
if (pwd != NULL)
{
- DEBUG(10, ("found by smb_userid: %x\n", (int)smb_userid));
+ DEBUG(10, ("found by unix_uid: %x\n", (int)unix_uid));
}
endsmbpwent(fp);
@@ -134,7 +124,7 @@ struct smb_passwd *iterate_getsmbpwuid(uid_t smb_userid)
does not have search facilities.
*************************************************************************/
-struct smb_passwd *iterate_getsmbpwnam(char *name)
+struct smb_passwd *iterate_getsmbpwnam(const char *name)
{
struct smb_passwd *pwd = NULL;
void *fp = NULL;
@@ -150,8 +140,10 @@ struct smb_passwd *iterate_getsmbpwnam(char *name)
return NULL;
}
- while ((pwd = getsmbpwent(fp)) != NULL && !strequal(pwd->smb_name, name))
- ;
+ while ((pwd = getsmbpwent(fp)) != NULL && !strequal(pwd->unix_name, name))
+ {
+ DEBUG(10, ("iterate: %s 0x%x\n", pwd->unix_name, pwd->unix_uid));
+ }
if (pwd != NULL)
{
@@ -175,7 +167,7 @@ struct smb_passwd *iterate_getsmbpwnam(char *name)
void *startsmbpwent(BOOL update)
{
- return pdb_ops->startsmbpwent(update);
+ return pwdb_ops->startsmbpwent(update);
}
/***************************************************************
@@ -190,7 +182,17 @@ void *startsmbpwent(BOOL update)
void endsmbpwent(void *vp)
{
- pdb_ops->endsmbpwent(vp);
+ pwdb_ops->endsmbpwent(vp);
+}
+
+SMB_BIG_UINT getsmbpwpos(void *vp)
+{
+ return pwdb_ops->getsmbpwpos(vp);
+}
+
+BOOL setsmbpwpos(void *vp, SMB_BIG_UINT tok)
+{
+ return pwdb_ops->setsmbpwpos(vp, tok);
}
/*************************************************************************
@@ -199,7 +201,7 @@ void endsmbpwent(void *vp)
struct smb_passwd *getsmbpwent(void *vp)
{
- return pdb_ops->getsmbpwent(vp);
+ return pwdb_smb_map_names(pwdb_ops->getsmbpwent(vp));
}
/************************************************************************
@@ -208,7 +210,12 @@ struct smb_passwd *getsmbpwent(void *vp)
BOOL add_smbpwd_entry(struct smb_passwd *newpwd)
{
- return pdb_ops->add_smbpwd_entry(newpwd);
+ struct smb_passwd *mapped = pwdb_smb_map_names(newpwd);
+ if (mapped)
+ {
+ return pwdb_ops->add_smbpwd_entry(mapped);
+ }
+ return False;
}
/************************************************************************
@@ -222,849 +229,121 @@ BOOL add_smbpwd_entry(struct smb_passwd *newpwd)
BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override)
{
- return pdb_ops->mod_smbpwd_entry(pwd, override);
-}
-
-/************************************************************************
- Routine to delete an entry from the smb passwd file.
-*************************************************************************/
-
-BOOL del_smbpwd_entry(const char *name)
-{
- return pdb_ops->del_smbpwd_entry(name);
-}
-
-/************************************************************************
- Routine to search smb passwd by name.
-*************************************************************************/
-
-struct smb_passwd *getsmbpwnam(char *name)
-{
- return pdb_ops->getsmbpwnam(name);
-}
-
-/************************************************************************
- Routine to search smb passwd by user rid.
-*************************************************************************/
-
-struct smb_passwd *getsmbpwrid(uint32 user_rid)
-{
- return pdb_ops->getsmbpwrid(user_rid);
-}
-
-/************************************************************************
- Routine to search smb passwd by uid.
-*************************************************************************/
-
-struct smb_passwd *getsmbpwuid(uid_t smb_userid)
-{
- return pdb_ops->getsmbpwuid(smb_userid);
-}
-
-/*
- * Functions that manupulate a struct sam_passwd.
- */
-
-/************************************************************************
- Utility function to search sam passwd by name. use this if your database
- does not have search facilities.
-*************************************************************************/
-
-struct sam_passwd *iterate_getsam21pwnam(char *name)
-{
- struct sam_passwd *pwd = NULL;
- void *fp = NULL;
-
- DEBUG(10, ("search by name: %s\n", name));
-
- /* Open the smb password database - not for update. */
- fp = startsmbpwent(False);
-
- if (fp == NULL)
- {
- DEBUG(0, ("unable to open sam password database.\n"));
- return NULL;
- }
-
- while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->smb_name, name))
- {
- DEBUG(10, ("iterate: %s 0x%x\n", pwd->smb_name, pwd->user_rid));
- }
-
- if (pwd != NULL)
- {
- DEBUG(10, ("found by name: %s\n", name));
- }
-
- endsmbpwent(fp);
- return pwd;
-}
-
-/************************************************************************
- Utility function to search sam passwd by rid. use this if your database
- does not have search facilities.
-
- search capability by both rid and uid are needed as the rid <-> uid
- mapping may be non-monotonic.
-
-*************************************************************************/
-
-struct sam_passwd *iterate_getsam21pwrid(uint32 rid)
-{
- struct sam_passwd *pwd = NULL;
- void *fp = NULL;
-
- DEBUG(10, ("search by rid: %x\n", rid));
-
- /* Open the smb password file - not for update. */
- fp = startsmbpwent(False);
-
- if (fp == NULL)
- {
- DEBUG(0, ("unable to open sam password database.\n"));
- return NULL;
- }
-
- while ((pwd = getsam21pwent(fp)) != NULL && pwd->user_rid != rid)
- {
- DEBUG(10, ("iterate: %s 0x%x\n", pwd->smb_name, pwd->user_rid));
- }
-
- if (pwd != NULL)
+ struct smb_passwd *mapped = pwdb_smb_map_names(pwd);
+ if (mapped)
{
- DEBUG(10, ("found by user_rid: %x\n", rid));
+ return pwdb_ops->mod_smbpwd_entry(mapped, override);
}
-
- endsmbpwent(fp);
- return pwd;
+ return False;
}
/************************************************************************
- Utility function to search sam passwd by uid. use this if your database
- does not have search facilities.
-
- search capability by both rid and uid are needed as the rid <-> uid
- mapping may be non-monotonic.
-
-*************************************************************************/
-
-struct sam_passwd *iterate_getsam21pwuid(uid_t uid)
-{
- struct sam_passwd *pwd = NULL;
- void *fp = NULL;
-
- DEBUG(10, ("search by uid: %x\n", (int)uid));
-
- /* Open the smb password file - not for update. */
- fp = startsmbpwent(False);
-
- if (fp == NULL)
- {
- DEBUG(0, ("unable to open sam password database.\n"));
- return NULL;
- }
-
- while ((pwd = getsam21pwent(fp)) != NULL && pwd->smb_userid != uid)
- ;
-
- if (pwd != NULL)
- {
- DEBUG(10, ("found by smb_userid: %x\n", (int)uid));
- }
-
- endsmbpwent(fp);
- return pwd;
-}
-
-/*************************************************************************
- Routine to return a display info structure, by rid
- *************************************************************************/
-struct sam_disp_info *getsamdisprid(uint32 rid)
-{
- return pdb_ops->getsamdisprid(rid);
-}
-
-/*************************************************************************
- Routine to return the next entry in the sam passwd list.
- *************************************************************************/
-
-struct sam_passwd *getsam21pwent(void *vp)
-{
- return pdb_ops->getsam21pwent(vp);
-}
-
-
-/************************************************************************
- Routine to search sam passwd by name.
+ Routine to search smb passwd by name.
*************************************************************************/
-struct sam_passwd *getsam21pwnam(char *name)
+struct smb_passwd *getsmbpwnam(const char *name)
{
- return pdb_ops->getsam21pwnam(name);
+ return pwdb_smb_map_names(pwdb_ops->getsmbpwnam(name));
}
/************************************************************************
- Routine to search sam passwd by rid.
+ Routine to search smb passwd by uid.
*************************************************************************/
-struct sam_passwd *getsam21pwrid(uint32 rid)
+struct smb_passwd *getsmbpwuid(uid_t unix_uid)
{
- return pdb_ops->getsam21pwrid(rid);
-}
-
-
-/**********************************************************
- **********************************************************
-
- utility routines which are likely to be useful to all password
- databases
-
- **********************************************************
- **********************************************************/
-
-/*************************************************************
- initialises a struct sam_disp_info.
- **************************************************************/
-
-static void pdb_init_dispinfo(struct sam_disp_info *user)
-{
- if (user == NULL) return;
- memset((char *)user, '\0', sizeof(*user));
+ return pwdb_smb_map_names(pwdb_ops->getsmbpwuid(unix_uid));
}
/*************************************************************
initialises a struct smb_passwd.
**************************************************************/
-
-void pdb_init_smb(struct smb_passwd *user)
+void pwdb_init_smb(struct smb_passwd *user)
{
if (user == NULL) return;
- memset((char *)user, '\0', sizeof(*user));
+ bzero(user, sizeof(*user));
user->pass_last_set_time = (time_t)-1;
+ user->unix_uid = (uid_t)-1;
+ user->user_rid = 0xffffffff;
}
/*************************************************************
- initialises a struct sam_passwd.
+ fills in missing details. one set of details _must_ exist.
**************************************************************/
-void pdb_init_sam(struct sam_passwd *user)
+struct smb_passwd *pwdb_smb_map_names(struct smb_passwd *smb)
{
- if (user == NULL) return;
- memset((char *)user, '\0', sizeof(*user));
- user->logon_time = (time_t)-1;
- user->logoff_time = (time_t)-1;
- user->kickoff_time = (time_t)-1;
- user->pass_last_set_time = (time_t)-1;
- user->pass_can_change_time = (time_t)-1;
- user->pass_must_change_time = (time_t)-1;
-}
+ DOM_NAME_MAP gmep;
+ BOOL found = False;
+ DOM_SID sid;
+ static fstring unix_name;
+ static fstring nt_name;
-/*************************************************************************
- Routine to return the next entry in the sam passwd list.
- *************************************************************************/
-
-struct sam_disp_info *pdb_sam_to_dispinfo(struct sam_passwd *user)
-{
- static struct sam_disp_info disp_info;
-
- if (user == NULL) return NULL;
-
- pdb_init_dispinfo(&disp_info);
-
- disp_info.smb_name = user->smb_name;
- disp_info.full_name = user->full_name;
- disp_info.user_rid = user->user_rid;
-
- return &disp_info;
-}
-
-/*************************************************************
- converts a sam_passwd structure to a smb_passwd structure.
- **************************************************************/
-
-struct smb_passwd *pdb_sam_to_smb(struct sam_passwd *user)
-{
- static struct smb_passwd pw_buf;
-
- if (user == NULL) return NULL;
-
- pdb_init_smb(&pw_buf);
-
- pw_buf.smb_userid = user->smb_userid;
- pw_buf.smb_name = user->smb_name;
- pw_buf.smb_passwd = user->smb_passwd;
- pw_buf.smb_nt_passwd = user->smb_nt_passwd;
- pw_buf.acct_ctrl = user->acct_ctrl;
- pw_buf.pass_last_set_time = user->pass_last_set_time;
-
- return &pw_buf;
-}
-
-
-/*************************************************************
- converts a smb_passwd structure to a sam_passwd structure.
- **************************************************************/
-
-struct sam_passwd *pdb_smb_to_sam(struct smb_passwd *user)
-{
- static struct sam_passwd pw_buf;
-
- if (user == NULL) return NULL;
-
- pdb_init_sam(&pw_buf);
-
- pw_buf.smb_userid = user->smb_userid;
- pw_buf.smb_name = user->smb_name;
- pw_buf.smb_passwd = user->smb_passwd;
- pw_buf.smb_nt_passwd = user->smb_nt_passwd;
- pw_buf.acct_ctrl = user->acct_ctrl;
- pw_buf.pass_last_set_time = user->pass_last_set_time;
-
- return &pw_buf;
-}
-
-/**********************************************************
- Encode the account control bits into a string.
- length = length of string to encode into (including terminating
- null). length *MUST BE MORE THAN 2* !
- **********************************************************/
-
-char *pdb_encode_acct_ctrl(uint16 acct_ctrl, size_t length)
-{
- static fstring acct_str;
- size_t i = 0;
-
- acct_str[i++] = '[';
-
- if (acct_ctrl & ACB_PWNOTREQ ) acct_str[i++] = 'N';
- if (acct_ctrl & ACB_DISABLED ) acct_str[i++] = 'D';
- if (acct_ctrl & ACB_HOMDIRREQ) acct_str[i++] = 'H';
- if (acct_ctrl & ACB_TEMPDUP ) acct_str[i++] = 'T';
- if (acct_ctrl & ACB_NORMAL ) acct_str[i++] = 'U';
- if (acct_ctrl & ACB_MNS ) acct_str[i++] = 'M';
- if (acct_ctrl & ACB_WSTRUST ) acct_str[i++] = 'W';
- if (acct_ctrl & ACB_SVRTRUST ) acct_str[i++] = 'S';
- if (acct_ctrl & ACB_AUTOLOCK ) acct_str[i++] = 'L';
- if (acct_ctrl & ACB_PWNOEXP ) acct_str[i++] = 'X';
- if (acct_ctrl & ACB_DOMTRUST ) acct_str[i++] = 'I';
-
- for ( ; i < length - 2 ; i++ ) { acct_str[i] = ' '; }
-
- i = length - 2;
- acct_str[i++] = ']';
- acct_str[i++] = '\0';
-
- return acct_str;
-}
-
-/**********************************************************
- Decode the account control bits from a string.
-
- this function breaks coding standards minimum line width of 80 chars.
- reason: vertical line-up code clarity - all case statements fit into
- 15 lines, which is more important.
- **********************************************************/
-
-uint16 pdb_decode_acct_ctrl(const char *p)
-{
- uint16 acct_ctrl = 0;
- BOOL finished = False;
-
- /*
- * Check if the account type bits have been encoded after the
- * NT password (in the form [NDHTUWSLXI]).
- */
-
- if (*p != '[') return 0;
-
- for (p++; *p && !finished; p++)
- {
- switch (*p)
- {
- case 'N': { acct_ctrl |= ACB_PWNOTREQ ; break; /* 'N'o password. */ }
- case 'D': { acct_ctrl |= ACB_DISABLED ; break; /* 'D'isabled. */ }
- case 'H': { acct_ctrl |= ACB_HOMDIRREQ; break; /* 'H'omedir required. */ }
- case 'T': { acct_ctrl |= ACB_TEMPDUP ; break; /* 'T'emp account. */ }
- case 'U': { acct_ctrl |= ACB_NORMAL ; break; /* 'U'ser account (normal). */ }
- case 'M': { acct_ctrl |= ACB_MNS ; break; /* 'M'NS logon user account. What is this ? */ }
- case 'W': { acct_ctrl |= ACB_WSTRUST ; break; /* 'W'orkstation account. */ }
- case 'S': { acct_ctrl |= ACB_SVRTRUST ; break; /* 'S'erver account. */ }
- case 'L': { acct_ctrl |= ACB_AUTOLOCK ; break; /* 'L'ocked account. */ }
- case 'X': { acct_ctrl |= ACB_PWNOEXP ; break; /* No 'X'piry on password */ }
- case 'I': { acct_ctrl |= ACB_DOMTRUST ; break; /* 'I'nterdomain trust account. */ }
- case ' ': { break; }
- case ':':
- case '\n':
- case '\0':
- case ']':
- default: { finished = True; }
- }
- }
-
- return acct_ctrl;
-}
-
-/*******************************************************************
- gets password-database-format time from a string.
- ********************************************************************/
-
-static time_t get_time_from_string(const char *p)
-{
- int i;
-
- for (i = 0; i < 8; i++)
- {
- if (p[i] == '\0' || !isxdigit((int)(p[i]&0xFF)))
- break;
- }
- if (i == 8)
- {
- /*
- * p points at 8 characters of hex digits -
- * read into a time_t as the seconds since
- * 1970 that the password was last changed.
- */
- return (time_t)strtol(p, NULL, 16);
- }
- return (time_t)-1;
-}
-
-/*******************************************************************
- gets password last set time
- ********************************************************************/
-
-time_t pdb_get_last_set_time(const char *p)
-{
- if (*p && StrnCaseCmp(p, "LCT-", 4))
- {
- return get_time_from_string(p + 4);
- }
- return (time_t)-1;
-}
-
-
-/*******************************************************************
- sets password-database-format time in a string.
- ********************************************************************/
-static void set_time_in_string(char *p, int max_len, char *type, time_t t)
-{
- slprintf(p, max_len, ":%s-%08X:", type, (uint32)t);
-}
-
-/*******************************************************************
- sets logon time
- ********************************************************************/
-void pdb_set_logon_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "LNT", t);
-}
-
-/*******************************************************************
- sets logoff time
- ********************************************************************/
-void pdb_set_logoff_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "LOT", t);
-}
-
-/*******************************************************************
- sets kickoff time
- ********************************************************************/
-void pdb_set_kickoff_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "KOT", t);
-}
-
-/*******************************************************************
- sets password can change time
- ********************************************************************/
-void pdb_set_can_change_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "CCT", t);
-}
-
-/*******************************************************************
- sets password last set time
- ********************************************************************/
-void pdb_set_must_change_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "MCT", t);
-}
-
-/*******************************************************************
- sets password last set time
- ********************************************************************/
-void pdb_set_last_set_time(char *p, int max_len, time_t t)
-{
- set_time_in_string(p, max_len, "LCT", t);
-}
-
-
-/*************************************************************
- Routine to set 32 hex password characters from a 16 byte array.
-**************************************************************/
-void pdb_sethexpwd(char *p, unsigned char *pwd, uint16 acct_ctrl)
-{
- if (pwd != NULL)
- {
- int i;
- for (i = 0; i < 16; i++)
- {
- slprintf(&p[i*2], 3, "%02X", pwd[i]);
- }
- }
- else
- {
- if (IS_BITS_SET_ALL(acct_ctrl, ACB_PWNOTREQ))
- {
- safe_strcpy(p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", 33);
- }
- else
- {
- safe_strcpy(p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 33);
- }
- }
-}
-/*************************************************************
- Routine to get the 32 hex characters and turn them
- into a 16 byte array.
-**************************************************************/
-BOOL pdb_gethexpwd(char *p, unsigned char *pwd)
-{
- int i;
- unsigned char lonybble, hinybble;
- char *hexchars = "0123456789ABCDEF";
- char *p1, *p2;
-
- for (i = 0; i < 32; i += 2)
+ if (smb == NULL)
{
- hinybble = toupper(p[i]);
- lonybble = toupper(p[i + 1]);
-
- p1 = strchr(hexchars, hinybble);
- p2 = strchr(hexchars, lonybble);
-
- if (!p1 || !p2)
- {
- return (False);
- }
-
- hinybble = PTR_DIFF(p1, hexchars);
- lonybble = PTR_DIFF(p2, hexchars);
-
- pwd[i / 2] = (hinybble << 4) | lonybble;
+ DEBUG(10,("pwdb_smb_map_names: NULL\n"));
+ return NULL;
}
- return (True);
-}
-/*******************************************************************
- Group and User RID username mapping function
- ********************************************************************/
+ DEBUG(10,("pwdb_smb_map_names: unix %s nt %s unix %d nt%d\n",
+ smb->unix_name != NULL ? smb->unix_name : "NULL",
+ smb->nt_name != NULL ? smb->nt_name : "NULL",
+ smb->unix_uid, smb->user_rid));
-BOOL pdb_name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid)
-{
- struct passwd *pw = Get_Pwnam(user_name, False);
-
- if (u_rid == NULL || g_rid == NULL || user_name == NULL)
+ if (smb->unix_name == NULL && smb->nt_name == NULL &&
+ smb->unix_uid == (uid_t)-1 && smb->user_rid == 0xffffffff)
{
- return False;
+ return NULL;
}
-
- if (!pw)
+ if (smb->unix_name != NULL && smb->nt_name != NULL &&
+ smb->unix_uid != (uid_t)-1 && smb->user_rid != 0xffffffff)
{
- DEBUG(1,("Username %s is invalid on this system\n", user_name));
- return False;
+ return smb;
}
- if (user_in_list(user_name, lp_domain_guest_users()))
- {
- *u_rid = DOMAIN_USER_RID_GUEST;
- }
- else if (user_in_list(user_name, lp_domain_admin_users()))
+ if (!found && smb->unix_name != NULL)
{
- *u_rid = DOMAIN_USER_RID_ADMIN;
+ found = lookupsmbpwnam(smb->unix_name, &gmep);
}
- else
+ if (!found && smb->unix_uid != (uid_t)-1)
{
- /* turn the unix UID into a Domain RID. this is what the posix
- sub-system does (adds 1000 to the uid) */
- *u_rid = pdb_uid_to_user_rid(pw->pw_uid);
+ found = lookupsmbpwuid(smb->unix_uid , &gmep);
}
- /* absolutely no idea what to do about the unix GID to Domain RID mapping */
- *g_rid = pdb_gid_to_group_rid(pw->pw_gid);
-
- return True;
-}
-
-/****************************************************************************
- Generate the global machine sid. Look for the DOMAINNAME.SID file first, if
- not found then look in smb.conf and use it to create the DOMAINNAME.SID file.
-****************************************************************************/
-BOOL pdb_generate_sam_sid(char *domain_name, DOM_SID *sid)
-{
- char *p;
- pstring sid_file;
- pstring machine_sid_file;
- fstring file_name;
-
- if (sid == NULL)
+ if (!found)
{
- sid = &global_sam_sid;
+ sid_copy(&sid, &global_sam_sid);
+ sid_append_rid(&sid, smb->user_rid);
}
- pstrcpy(sid_file, lp_smb_passwd_file());
-
- if (sid_file[0] == 0)
+ if (!found && smb->user_rid != 0xffffffff)
{
- DEBUG(0,("cannot find smb passwd file\n"));
- return False;
+ found = lookupsmbpwsid (&sid , &gmep);
}
-
- p = strrchr(sid_file, '/');
- if (p != NULL)
+ if (!found && smb->nt_name != NULL)
{
- *++p = '\0';
+ found = lookupsmbpwntnam(smb->nt_name, &gmep);
}
- if (!directory_exist(sid_file, NULL)) {
- if (mkdir(sid_file, 0700) != 0) {
- DEBUG(0,("can't create private directory %s : %s\n",
- sid_file, strerror(errno)));
- return False;
- }
- }
-
- pstrcpy(machine_sid_file, sid_file);
- pstrcat(machine_sid_file, "MACHINE.SID");
-
- slprintf(file_name, sizeof(file_name)-1, "%s.SID", domain_name);
- strupper(file_name);
- pstrcat(sid_file, file_name);
-
- if (file_exist(machine_sid_file, NULL))
+ if (!found)
{
- if (file_exist(sid_file, NULL))
- {
- DEBUG(0,("both %s and %s exist when only one should, unable to continue\n",
- machine_sid_file, sid_file));
- return False;
- }
- if (file_rename(machine_sid_file, sid_file))
- {
- DEBUG(0,("could not rename %s to %s. Error was %s\n",
- machine_sid_file, sid_file, strerror(errno)));
- return False;
- }
- }
-
- /* attempt to read the SID from the file */
- if (read_sid(domain_name, sid))
- {
- return True;
- }
-
- if (!create_new_sid(sid))
- {
- return False;
- }
- /* attempt to read the SID from the file */
- if (!write_sid(domain_name, sid))
- {
- return True;
+ return NULL;
}
-
- /* during the attempt to write, someone else wrote? */
- /* attempt to read the SID from the file */
- if (read_sid(domain_name, sid))
+ if (!sid_front_equal(&global_sam_sid, &gmep.sid))
{
- return True;
- }
-
- return True;
-}
-/*******************************************************************
- Converts NT user RID to a UNIX uid.
- ********************************************************************/
-
-uid_t pdb_user_rid_to_uid(uint32 user_rid)
-{
- return (uid_t)(((user_rid & (~USER_RID_TYPE))- 1000)/RID_MULTIPLIER);
-}
-
-/*******************************************************************
- Converts NT user RID to a UNIX gid.
- ********************************************************************/
-
-gid_t pdb_user_rid_to_gid(uint32 user_rid)
-{
- return (uid_t)(((user_rid & (~GROUP_RID_TYPE))- 1000)/RID_MULTIPLIER);
-}
-
-/*******************************************************************
- converts UNIX uid to an NT User RID.
- ********************************************************************/
-
-uint32 pdb_uid_to_user_rid(uid_t uid)
-{
- return (((((uint32)uid)*RID_MULTIPLIER) + 1000) | USER_RID_TYPE);
-}
-
-/*******************************************************************
- converts NT Group RID to a UNIX uid.
- ********************************************************************/
-
-uint32 pdb_gid_to_group_rid(gid_t gid)
-{
- return (((((uint32)gid)*RID_MULTIPLIER) + 1000) | GROUP_RID_TYPE);
-}
-
-/*******************************************************************
- Decides if a RID is a well known RID.
- ********************************************************************/
-
-static BOOL pdb_rid_is_well_known(uint32 rid)
-{
- return (rid < 1000);
-}
-
-/*******************************************************************
- Decides if a RID is a user or group RID.
- ********************************************************************/
-
-BOOL pdb_rid_is_user(uint32 rid)
-{
- /* lkcl i understand that NT attaches an enumeration to a RID
- * such that it can be identified as either a user, group etc
- * type. there are 5 such categories, and they are documented.
- */
- if(pdb_rid_is_well_known(rid)) {
- /*
- * The only well known user RIDs are DOMAIN_USER_RID_ADMIN
- * and DOMAIN_USER_RID_GUEST.
- */
- if(rid == DOMAIN_USER_RID_ADMIN || rid == DOMAIN_USER_RID_GUEST)
- return True;
- } else if((rid & RID_TYPE_MASK) == USER_RID_TYPE) {
- return True;
- }
- return False;
-}
-
-/*******************************************************************
- Convert a rid into a name. Used in the lookup SID rpc.
- ********************************************************************/
-
-BOOL lookup_local_rid(uint32 rid, char *name, uint8 *psid_name_use)
-{
-
- BOOL is_user = pdb_rid_is_user(rid);
-
- DEBUG(5,("lookup_local_rid: looking up %s RID %u.\n", is_user ? "user" :
- "group", (unsigned int)rid));
-
- if(is_user) {
- if(rid == DOMAIN_USER_RID_ADMIN) {
- pstring admin_users;
- char *p = admin_users;
- pstrcpy( admin_users, lp_domain_admin_users());
- if(!next_token(&p, name, NULL, sizeof(fstring)))
- fstrcpy(name, "Administrator");
- } else if (rid == DOMAIN_USER_RID_GUEST) {
- pstring guest_users;
- char *p = guest_users;
- pstrcpy( guest_users, lp_domain_guest_users());
- if(!next_token(&p, name, NULL, sizeof(fstring)))
- fstrcpy(name, "Guest");
- } else {
- uid_t uid = pdb_user_rid_to_uid(rid);
- struct passwd *pass = sys_getpwuid(uid);
-
- *psid_name_use = SID_NAME_USER;
-
- DEBUG(5,("lookup_local_rid: looking up uid %u %s\n", (unsigned int)uid,
- pass ? "succeeded" : "failed" ));
-
- if(!pass) {
- slprintf(name, sizeof(fstring)-1, "unix_user.%u", (unsigned int)uid);
- return True;
- }
-
- fstrcpy(name, pass->pw_name);
-
- DEBUG(5,("lookup_local_rid: found user %s for rid %u\n", name,
- (unsigned int)rid ));
- }
-
- } else {
- gid_t gid = pdb_user_rid_to_gid(rid);
- struct group *gr = getgrgid(gid);
-
- *psid_name_use = SID_NAME_ALIAS;
-
- DEBUG(5,("lookup_local_rid: looking up gid %u %s\n", (unsigned int)gid,
- gr ? "succeeded" : "failed" ));
-
- if(!gr) {
- slprintf(name, sizeof(fstring)-1, "unix_group.%u", (unsigned int)gid);
- return True;
- }
-
- fstrcpy( name, gr->gr_name);
-
- DEBUG(5,("lookup_local_rid: found group %s for rid %u\n", name,
- (unsigned int)rid ));
- }
-
- return True;
-}
-
-/*******************************************************************
- Convert a name into a SID. Used in the lookup name rpc.
- ********************************************************************/
-
-BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name_use)
-{
- extern DOM_SID global_sid_World_Domain;
- struct passwd *pass = NULL;
- DOM_SID local_sid;
-
- sid_copy(&local_sid, &global_sam_sid);
-
- if(!strequal(global_myname, domain) && !strequal(global_myworkgroup, domain))
- return False;
-
- /*
- * Special case for MACHINE\Everyone. Map to the world_sid.
- */
-
- if(strequal(user, "Everyone")) {
- sid_copy( psid, &global_sid_World_Domain);
- sid_append_rid(psid, 0);
- *psid_name_use = SID_NAME_ALIAS;
- return True;
- }
-
- (void)map_username(user);
-
- if(!(pass = Get_Pwnam(user, False))) {
- /*
- * Maybe it was a group ?
- */
- struct group *grp = getgrnam(user);
-
- if(!grp)
- return False;
-
- sid_append_rid( &local_sid, pdb_gid_to_group_rid(grp->gr_gid));
- *psid_name_use = SID_NAME_ALIAS;
- } else {
-
- sid_append_rid( &local_sid, pdb_uid_to_user_rid(pass->pw_uid));
- *psid_name_use = SID_NAME_USER;
+ fstring sid_str;
+ sid_to_string(sid_str, &gmep.sid);
+ DEBUG(0,("UNIX User %s Primary Group is in the wrong domain! %s\n",
+ smb->unix_name, sid_str));
+ return NULL;
}
- sid_copy( psid, &local_sid);
+ fstrcpy(unix_name, gmep.unix_name);
+ fstrcpy(nt_name , gmep.nt_name );
+ if (smb->unix_name == NULL ) smb->unix_name = unix_name;
+ if (smb->nt_name == NULL ) smb->nt_name = nt_name ;
+ if (smb->unix_uid == (uid_t)-1 ) smb->unix_uid = (uid_t)gmep.unix_id;
+ if (smb->user_rid == 0xffffffff) sid_split_rid(&gmep.sid, &smb->user_rid);
- return True;
+ return smb;
}
diff --git a/source/passdb/passgrp.c b/source/passdb/passgrp.c
index f578d9a20ea..9a5c1f8a7d9 100644
--- a/source/passdb/passgrp.c
+++ b/source/passdb/passgrp.c
@@ -34,7 +34,7 @@ extern int DEBUGLEVEL;
*
*/
-static struct passgrp_ops *pwgrp_ops;
+static struct passgrp_ops *pwgrp_ops = NULL;
/***************************************************************
Initialise the passgrp operations.
@@ -49,9 +49,13 @@ BOOL initialise_passgrp_db(void)
#ifdef WITH_NISPLUS
pwgrp_ops = nisplus_initialise_password_grp();
+#elif defined(WITH_NT5LDAP)
+ pwgrp_ops = nt5ldap_initialise_password_grp();
#elif defined(WITH_LDAP)
- pwgrp_ops = ldap_initialize_password_grp();
-#else
+ pwgrp_ops = ldap_initialise_password_grp();
+#elif defined(USE_SMBUNIX_DB)
+ pwgrp_ops = unix_initialise_password_grp();
+#elif defined(USE_SMBPASS_DB)
pwgrp_ops = file_initialise_password_grp();
#endif
@@ -70,8 +74,30 @@ struct smb_passwd *iterate_getsmbgrprid(uint32 user_rid,
uint32 **grps, int *num_grps,
uint32 **alss, int *num_alss)
{
- return iterate_getsmbgrpuid(pwdb_user_rid_to_uid(user_rid),
- grps, num_grps, alss, num_alss);
+ struct smb_passwd *pwd = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by user_rid: 0x%x\n", user_rid));
+
+ /* Open the smb password database - not for update. */
+ fp = startsmbgrpent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open smb passgrp database.\n"));
+ return NULL;
+ }
+
+ while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && pwd->user_rid != user_rid)
+ ;
+
+ if (pwd != NULL)
+ {
+ DEBUG(10, ("found by user_rid: 0x%x\n", user_rid));
+ }
+
+ endsmbgrpent(fp);
+ return pwd;
}
/************************************************************************
@@ -79,14 +105,14 @@ struct smb_passwd *iterate_getsmbgrprid(uint32 user_rid,
does not have search facilities.
*************************************************************************/
-struct smb_passwd *iterate_getsmbgrpuid(uid_t smb_userid,
+struct smb_passwd *iterate_getsmbgrpuid(uid_t unix_uid,
uint32 **grps, int *num_grps,
uint32 **alss, int *num_alss)
{
struct smb_passwd *pwd = NULL;
void *fp = NULL;
- DEBUG(10, ("search by smb_userid: %x\n", (int)smb_userid));
+ DEBUG(10, ("search by unix_uid: %x\n", (int)unix_uid));
/* Open the smb password database - not for update. */
fp = startsmbgrpent(False);
@@ -97,12 +123,12 @@ struct smb_passwd *iterate_getsmbgrpuid(uid_t smb_userid,
return NULL;
}
- while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && pwd->smb_userid != smb_userid)
+ while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && pwd->unix_uid != unix_uid)
;
if (pwd != NULL)
{
- DEBUG(10, ("found by smb_userid: %x\n", (int)smb_userid));
+ DEBUG(10, ("found by unix_uid: %x\n", (int)unix_uid));
}
endsmbgrpent(fp);
@@ -114,12 +140,14 @@ struct smb_passwd *iterate_getsmbgrpuid(uid_t smb_userid,
does not have search facilities.
*************************************************************************/
-struct smb_passwd *iterate_getsmbgrpnam(char *name,
+struct smb_passwd *iterate_getsmbgrpntnam(const char *nt_name,
uint32 **grps, int *num_grps,
uint32 **alss, int *num_alss)
{
struct smb_passwd *pwd = NULL;
+ fstring name;
void *fp = NULL;
+ fstrcpy(name, nt_name);
DEBUG(10, ("search by name: %s\n", name));
@@ -132,7 +160,7 @@ struct smb_passwd *iterate_getsmbgrpnam(char *name,
return NULL;
}
- while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && !strequal(pwd->smb_name, name))
+ while ((pwd = getsmbgrpent(fp, grps, num_grps, alss, num_alss)) != NULL && !strequal(pwd->nt_name, name))
;
if (pwd != NULL)
@@ -190,11 +218,11 @@ struct smb_passwd *getsmbgrpent(void *vp,
Routine to search smb passwd by name.
*************************************************************************/
-struct smb_passwd *getsmbgrpnam(char *name,
+struct smb_passwd *getsmbgrpntnam(char *name,
uint32 **grps, int *num_grps,
uint32 **alss, int *num_alss)
{
- return pwgrp_ops->getsmbgrpnam(name, grps, num_grps, alss, num_alss);
+ return pwgrp_ops->getsmbgrpntnam(name, grps, num_grps, alss, num_alss);
}
/************************************************************************
@@ -212,10 +240,10 @@ struct smb_passwd *getsmbgrprid(uint32 user_rid,
Routine to search smb passwd by uid.
*************************************************************************/
-struct smb_passwd *getsmbgrpuid(uid_t smb_userid,
+struct smb_passwd *getsmbgrpuid(uid_t unix_uid,
uint32 **grps, int *num_grps,
uint32 **alss, int *num_alss)
{
- return pwgrp_ops->getsmbgrpuid(smb_userid, grps, num_grps, alss, num_alss);
+ return pwgrp_ops->getsmbgrpuid(unix_uid, grps, num_grps, alss, num_alss);
}
diff --git a/source/passdb/passgrpldap.c b/source/passdb/passgrpldap.c
new file mode 100644
index 00000000000..1092a3c5b16
--- /dev/null
+++ b/source/passdb/passgrpldap.c
@@ -0,0 +1,190 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP passgrp database for SAMBA
+ Copyright (C) Matthew Chapman 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+
+#ifdef WITH_LDAP
+
+#include <lber.h>
+#include <ldap.h>
+
+extern int DEBUGLEVEL;
+
+/* Internal state */
+extern LDAP *ldap_struct;
+extern LDAPMessage *ldap_results;
+extern LDAPMessage *ldap_entry;
+
+
+/***************************************************************
+ Enumerate RIDs of groups which user is a member of, of type
+ given by attribute.
+ ****************************************************************/
+
+static void ldappassgrp_member(char *attribute, uint32 **rids, int *numrids)
+{
+ char **values;
+ uint32 *ridlist;
+ int i;
+
+ if((values = ldap_get_values(ldap_struct, ldap_entry, attribute))) {
+ *numrids = i = ldap_count_values(values);
+ *rids = ridlist = malloc(i * sizeof(uint32));
+ do {
+ ridlist[--i] = atoi(values[i]);
+ } while(i > 0);
+ ldap_value_free(values);
+ } else {
+ *numrids = 0;
+ *rids = NULL;
+ }
+}
+
+
+/***************************************************************
+ Begin/end smbgrp enumeration.
+ ****************************************************************/
+
+static void *ldappassgrp_enumfirst(BOOL update)
+{
+ if (!ldap_connect())
+ return NULL;
+
+ ldap_search_for("&(objectclass=sambaAccount)(|(group=*)(alias=*))");
+
+ return ldap_struct;
+}
+
+static void ldappassgrp_enumclose(void *vp)
+{
+ ldap_disconnect();
+}
+
+
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
+
+static SMB_BIG_UINT ldappassgrp_getdbpos(void *vp)
+{
+ return (SMB_BIG_UINT)((ulong)ldap_entry);
+}
+
+static BOOL ldappassgrp_setdbpos(void *vp, SMB_BIG_UINT tok)
+{
+ ldap_entry = (LDAPMessage *)((ulong)tok);
+ return (True);
+}
+
+
+/*************************************************************************
+ Return limited smb_passwd information, and group membership.
+ *************************************************************************/
+
+static struct smb_passwd *ldappassgrp_getpwbynam(const char *name,
+ uint32 **grp_rids, int *num_grps,
+ uint32 **als_rids, int *num_alss)
+{
+ struct smb_passwd *ret;
+
+ if(!ldap_connect())
+ return NULL;
+
+ ldap_search_by_ntname(name);
+ ldappassgrp_member("group", grp_rids, num_grps);
+ ldappassgrp_member("alias", als_rids, num_alss);
+ ret = ldap_getpw();
+
+ ldap_disconnect();
+ return ret;
+}
+
+static struct smb_passwd *ldappassgrp_getpwbyuid(uid_t userid,
+ uint32 **grp_rids, int *num_grps,
+ uint32 **als_rids, int *num_alss)
+{
+ struct smb_passwd *ret;
+
+ if(!ldap_connect())
+ return NULL;
+
+ ldap_search_by_uid(userid);
+ ldappassgrp_member("group", grp_rids, num_grps);
+ ldappassgrp_member("alias", als_rids, num_alss);
+ ret = ldap_getpw();
+
+ ldap_disconnect();
+ return ret;
+}
+
+static struct smb_passwd *ldappassgrp_getpwbyrid(uint32 user_rid,
+ uint32 **grp_rids, int *num_grps,
+ uint32 **als_rids, int *num_alss)
+{
+ struct smb_passwd *ret;
+
+ if(!ldap_connect())
+ return NULL;
+
+ ldap_search_by_rid(user_rid);
+ ldappassgrp_member("group", grp_rids, num_grps);
+ ldappassgrp_member("alias", als_rids, num_alss);
+ ret = ldap_getpw();
+
+ ldap_disconnect();
+ return ret;
+}
+
+static struct smb_passwd *ldappassgrp_getcurrentpw(void *vp,
+ uint32 **grp_rids, int *num_grps,
+ uint32 **als_rids, int *num_alss)
+{
+ ldappassgrp_member("group", grp_rids, num_grps);
+ ldappassgrp_member("alias", als_rids, num_alss);
+ return ldap_getpw();
+}
+
+
+
+static struct passgrp_ops ldappassgrp_ops =
+{
+ ldappassgrp_enumfirst,
+ ldappassgrp_enumclose,
+ ldappassgrp_getdbpos,
+ ldappassgrp_setdbpos,
+
+ ldappassgrp_getpwbynam,
+ ldappassgrp_getpwbyuid,
+ ldappassgrp_getpwbyrid,
+ ldappassgrp_getcurrentpw,
+};
+
+struct passgrp_ops *ldap_initialise_password_grp(void)
+{
+ return &ldappassgrp_ops;
+}
+
+#else
+ void passgrpldap_dummy_function(void);
+ void passgrpldap_dummy_function(void) { } /* stop some compilers complaining */
+#endif
+
diff --git a/source/passdb/passgrpnt5ldap.c b/source/passdb/passgrpnt5ldap.c
new file mode 100644
index 00000000000..563e21c1f44
--- /dev/null
+++ b/source/passdb/passgrpnt5ldap.c
@@ -0,0 +1,243 @@
+
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP passgrp database for SAMBA
+ Copyright (C) Matthew Chapman 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include "includes.h"
+
+#ifdef WITH_NT5LDAP
+
+#include <lber.h>
+#include <ldap.h>
+#include "ldapdb.h"
+
+extern int DEBUGLEVEL;
+
+/***************************************************************
+ Begin/end smbgrp enumeration.
+ ****************************************************************/
+
+static void *
+nt5ldappassgrp_enumfirst (BOOL update)
+{
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_search (hds, NULL, "(objectclass=User)", NULL, LDAP_NO_LIMIT))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ return hds;
+}
+
+static void
+nt5ldappassgrp_enumclose (void *vp)
+{
+ LDAPDB *hds = (LDAPDB *) vp;
+
+ ldapdb_close (&hds);
+
+ return;
+}
+
+
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
+
+static SMB_BIG_UINT
+nt5ldappassgrp_getdbpos (void *vp)
+{
+ return 0;
+}
+
+static BOOL
+nt5ldappassgrp_setdbpos (void *vp, SMB_BIG_UINT tok)
+{
+ return False;
+}
+
+
+/*************************************************************************
+ Return limited smb_passwd information, and group membership.
+ *************************************************************************/
+
+static struct smb_passwd *
+nt5ldappassgrp_getpwbynam (const char *name,
+ uint32 ** grp_rids, int *num_grps,
+ uint32 ** als_rids, int *num_alss)
+{
+ struct smb_passwd *ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+ char *dn;
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_lookup_by_posix_name (hds, name) ||
+ !ldapdb_get_dn (hds, &dn))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldapsmb_getent (hds);
+
+ (void) nt5ldap_make_group_rids (hds, dn, grp_rids, num_grps, NTDS_GROUP_TYPE_GLOBAL_GROUP);
+ (void) nt5ldap_make_group_rids (hds, dn, grp_rids, num_grps, NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP);
+
+ free (dn);
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static struct smb_passwd *
+nt5ldappassgrp_getpwbyuid (uid_t userid,
+ uint32 ** grp_rids, int *num_grps,
+ uint32 ** als_rids, int *num_alss)
+{
+ struct smb_passwd *ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+ char *dn;
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_lookup_by_posix_uid (hds, userid) ||
+ !ldapdb_get_dn (hds, &dn))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldapsmb_getent (hds);
+
+ (void) nt5ldap_make_group_rids (hds, dn, grp_rids, num_grps, NTDS_GROUP_TYPE_GLOBAL_GROUP);
+ (void) nt5ldap_make_group_rids (hds, dn, grp_rids, num_grps, NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP);
+
+ free (dn);
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static struct smb_passwd *
+nt5ldappassgrp_getpwbyrid (uint32 user_rid,
+ uint32 ** grp_rids, int *num_grps,
+ uint32 ** als_rids, int *num_alss)
+{
+ struct smb_passwd *ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+ char *dn;
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_lookup_by_rid (hds, user_rid) ||
+ !ldapdb_get_dn (hds, &dn))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldapsmb_getent (hds);
+
+ (void) nt5ldap_make_group_rids (hds, dn, grp_rids, num_grps, NTDS_GROUP_TYPE_GLOBAL_GROUP);
+ (void) nt5ldap_make_group_rids (hds, dn, grp_rids, num_grps, NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP);
+
+ free (dn);
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static struct smb_passwd *
+nt5ldappassgrp_getcurrentpw (void *vp,
+ uint32 ** grp_rids, int *num_grps,
+ uint32 ** als_rids, int *num_alss)
+{
+ struct smb_passwd *ret = NULL;
+ LDAPDB_DECLARE_HANDLE (hds);
+ char *dn = NULL;
+
+ hds = (LDAPDB *) vp;
+
+ do
+ {
+ if (dn != NULL)
+ free (dn);
+
+ if ( ldapdb_peek (hds) == True &&
+ ldapdb_get_dn (hds, &dn) == True &&
+ ((ret = nt5ldapsmb_getent (hds)) != NULL))
+ {
+ /* Got the entry */
+ (void) nt5ldap_make_group_rids (hds, dn, grp_rids, num_grps, NTDS_GROUP_TYPE_GLOBAL_GROUP);
+ (void) nt5ldap_make_group_rids (hds, dn, grp_rids, num_grps, NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP);
+ break;
+ }
+ }
+ while (ldapdb_seq(hds) == True);
+
+ return ret;
+}
+
+
+
+static struct passgrp_ops nt5ldappassgrp_ops =
+{
+ nt5ldappassgrp_enumfirst,
+ nt5ldappassgrp_enumclose,
+ nt5ldappassgrp_getdbpos,
+ nt5ldappassgrp_setdbpos,
+
+ nt5ldappassgrp_getpwbynam,
+ nt5ldappassgrp_getpwbyuid,
+ nt5ldappassgrp_getpwbyrid,
+ nt5ldappassgrp_getcurrentpw,
+};
+
+struct passgrp_ops *
+nt5ldap_initialise_password_grp (void)
+{
+ return &nt5ldappassgrp_ops;
+}
+
+#else
+void passgrpnt5ldap_dummy_function (void);
+void
+passgrpnt5ldap_dummy_function (void)
+{
+} /* stop some compilers complaining */
+#endif
diff --git a/source/passdb/sampass.c b/source/passdb/sampass.c
new file mode 100644
index 00000000000..c64525d9552
--- /dev/null
+++ b/source/passdb/sampass.c
@@ -0,0 +1,283 @@
+/*
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "sids.h"
+
+#ifdef USE_SMBPASS_DB
+
+extern int DEBUGLEVEL;
+
+/***************************************************************
+ Start to enumerate the smbpasswd list. Returns a void pointer
+ to ensure no modification outside this module.
+****************************************************************/
+
+static void *startsamfilepwent(BOOL update)
+{
+ return startsmbpwent(update);
+}
+
+/***************************************************************
+ End enumeration of the smbpasswd list.
+****************************************************************/
+
+static void endsamfilepwent(void *vp)
+{
+ endsmbpwent(vp);
+}
+
+/*************************************************************************
+ Return the current position in the smbpasswd list as an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+
+static SMB_BIG_UINT getsamfilepwpos(void *vp)
+{
+ return getsmbpwpos(vp);
+}
+
+/*************************************************************************
+ Set the current position in the smbpasswd list from an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+
+static BOOL setsamfilepwpos(void *vp, SMB_BIG_UINT tok)
+{
+ return setsmbpwpos(vp, tok);
+}
+
+static BOOL string_empty (const char *str)
+{
+ return str == NULL || *str == '\0';
+}
+
+
+/*************************************************************************
+ Routine to return the next entry in the smbpasswd list.
+ this function is a nice, messy combination of reading:
+ - the smbpasswd file
+ - the unix password database
+ - smb.conf options (not done at present).
+ *************************************************************************/
+
+static struct sam_passwd *getsamfile21pwent(void *vp)
+{
+ struct sam_passwd *user;
+ user_struct bogus_user_struct;
+#if 0
+ user_struct *vuser;
+#endif
+
+ static pstring full_name;
+ static pstring home_dir;
+ static pstring home_drive;
+ static pstring logon_script;
+ static pstring profile_path;
+ static pstring acct_desc;
+ static pstring workstations;
+
+ DEBUG(5,("getsamfile21pwent\n"));
+
+ ZERO_STRUCT(bogus_user_struct);
+
+ user = pwdb_smb_to_sam(getsmbfilepwent(vp));
+ if (user == NULL)
+ {
+ return NULL;
+ }
+
+ /*
+ * get all the other gubbins we need. substitute unix name for %U
+ */
+
+#if 0
+ vuser = get_valid_user_struct(get_sec_ctx());
+#endif
+
+ /* HACK to make %U work in substitutions below */
+ fstrcpy(bogus_user_struct.requested_name, user->nt_name);
+ fstrcpy(bogus_user_struct.name , user->unix_name);
+
+ pstrcpy(full_name , "");
+ pstrcpy(logon_script , lp_logon_script (&bogus_user_struct));
+ pstrcpy(profile_path , lp_logon_path (&bogus_user_struct));
+ pstrcpy(home_drive , lp_logon_drive (&bogus_user_struct));
+ pstrcpy(home_dir , lp_logon_home (&bogus_user_struct));
+ pstrcpy(acct_desc , "");
+ pstrcpy(workstations , "");
+
+#if 0
+ vuid_free_user_struct(vuser);
+#endif
+
+ /*
+ only overwrite values with defaults IIF specific backend
+ didn't filled the values
+ */
+
+ if (string_empty (user->full_name))
+ user->full_name = full_name;
+ if (string_empty (user->home_dir))
+ user->home_dir = home_dir;
+ if (string_empty (user->dir_drive))
+ user->dir_drive = home_drive;
+ if (string_empty (user->logon_script))
+ user->logon_script = logon_script;
+ if (string_empty (user->profile_path))
+ user->profile_path = profile_path;
+ if (string_empty (user->acct_desc))
+ user->acct_desc = acct_desc;
+ if (string_empty (user->workstations))
+ user->workstations = workstations;
+
+ user->unknown_str = NULL; /* don't know, yet! */
+ user->munged_dial = NULL; /* "munged" dial-back telephone number */
+
+ user->unknown_3 = 0xffffff; /* don't know */
+ user->logon_divs = 168; /* hours per week */
+ user->hours_len = 21; /* 21 times 8 bits = 168 */
+ memset(user->hours, 0xff, user->hours_len); /* available at all hours */
+ user->unknown_5 = 0x00020000; /* don't know */
+ user->unknown_6 = 0x000004ec; /* don't know */
+
+ return user;
+}
+
+/************************************************************************
+search sam db by uid.
+*************************************************************************/
+static struct sam_passwd *getsamfilepwuid(uid_t uid)
+{
+ struct sam_passwd *pwd = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by uid: %x\n", (int)uid));
+
+ /* Open the smb password file - not for update. */
+ fp = startsam21pwent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open sam password database.\n"));
+ return NULL;
+ }
+
+ while ((pwd = getsamfile21pwent(fp)) != NULL && pwd->unix_uid != uid)
+ {
+ }
+
+ if (pwd != NULL)
+ {
+ DEBUG(10, ("found by unix_uid: %x\n", (int)uid));
+ }
+
+ endsam21pwent(fp);
+
+ return pwd;
+}
+
+/************************************************************************
+search sam db by rid.
+*************************************************************************/
+static struct sam_passwd *getsamfilepwrid(uint32 user_rid)
+{
+ DOM_NAME_MAP gmep;
+ DOM_SID sid;
+ sid_copy(&sid, &global_sam_sid);
+ sid_append_rid(&sid, user_rid);
+
+ if (!lookupsmbpwsid(&sid, &gmep))
+ {
+ return NULL;
+ }
+
+ return getsamfilepwuid((uid_t)gmep.unix_id);
+}
+
+/************************************************************************
+search sam db by nt name.
+*************************************************************************/
+static struct sam_passwd *getsamfilepwntnam(const char *nt_name)
+{
+ DOM_NAME_MAP gmep;
+
+ if (!lookupsmbpwntnam(nt_name, &gmep))
+ {
+ return NULL;
+ }
+
+ return getsamfilepwuid((uid_t)gmep.unix_id);
+}
+
+/*
+ * Stub functions - implemented in terms of others.
+ */
+
+static BOOL mod_samfile21pwd_entry(struct sam_passwd* pwd, BOOL override)
+{
+ return mod_smbpwd_entry(pwdb_sam_to_smb(pwd), override);
+}
+
+static BOOL add_samfile21pwd_entry(struct sam_passwd *newpwd)
+{
+ return add_smbpwd_entry(pwdb_sam_to_smb(newpwd));
+}
+
+static struct sam_disp_info *getsamfiledispntnam(const char *ntname)
+{
+ return pwdb_sam_to_dispinfo(getsam21pwntnam(ntname));
+}
+
+static struct sam_disp_info *getsamfiledisprid(uint32 rid)
+{
+ return pwdb_sam_to_dispinfo(getsam21pwrid(rid));
+}
+
+static struct sam_disp_info *getsamfiledispent(void *vp)
+{
+ return pwdb_sam_to_dispinfo(getsam21pwent(vp));
+}
+
+static struct sam_passdb_ops sam_file_ops =
+{
+ startsamfilepwent,
+ endsamfilepwent,
+ getsamfilepwpos,
+ setsamfilepwpos,
+ getsamfilepwntnam,
+ getsamfilepwuid,
+ getsamfilepwrid,
+ getsamfile21pwent,
+ add_samfile21pwd_entry,
+ mod_samfile21pwd_entry,
+ getsamfiledispntnam,
+ getsamfiledisprid,
+ getsamfiledispent
+};
+
+struct sam_passdb_ops *file_initialise_sam_password_db(void)
+{
+ return &sam_file_ops;
+}
+
+#else
+ /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
+ void sampass_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* USE_SMBPASS_DB */
diff --git a/source/passdb/sampassdb.c b/source/passdb/sampassdb.c
new file mode 100644
index 00000000000..cb9bacdb718
--- /dev/null
+++ b/source/passdb/sampassdb.c
@@ -0,0 +1,818 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Password and authentication handling
+ Copyright (C) Jeremy Allison 1996-1998
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/*
+ * NOTE. All these functions are abstracted into a structure
+ * that points to the correct function for the selected database. JRA.
+ *
+ * NOTE. for the get/mod/add functions, there are two sets of functions.
+ * one supports struct sam_passwd, the other supports struct smb_passwd.
+ * for speed optimisation it is best to support both these sets.
+ *
+ * it is, however, optional to support one set but not the other: there
+ * is conversion-capability built in to passdb.c, and run-time error
+ * detection for when neither are supported.
+ *
+ * password database writers are recommended to implement the sam_passwd
+ * functions in a first pass, as struct sam_passwd contains more
+ * information, needed by the NT Domain support.
+ *
+ * an API writer is expected to create either one set (struct smb_passwd) or
+ * the other (struct sam_passwd) OR both, and optionally also to write display
+ * info routines * (struct sam_disp_info). functions which the API writer
+ * chooses NOT to write must be wrapped in conversion functions (pwdb_x_to_y)
+ * such that API users can call any function and still get valid results.
+ *
+ * the password API does NOT fill in the gaps if you set an API function
+ * to NULL: it will deliberately attempt to call the NULL function.
+ *
+ */
+
+static struct sam_passdb_ops *pwdb_ops;
+
+/***************************************************************
+ Initialise the password db operations.
+***************************************************************/
+
+BOOL initialise_sam_password_db(void)
+{
+ if (pwdb_ops)
+ {
+ return True;
+ }
+
+#ifdef WITH_NISPLUS
+ pwdb_ops = nisplus_initialise_sam_password_db();
+#elif defined(WITH_NT5LDAP)
+ pwdb_ops = nt5ldap_initialise_sam_password_db();
+#elif defined(WITH_LDAP)
+ pwdb_ops = ldap_initialise_sam_password_db();
+#elif defined(HAVE_MYSQL_H) && defined(WITH_MYSQLSAM)
+ pwdb_ops = mysql_initialise_sam_password_db();
+#elif defined(USE_SMBPASS_DB)
+ pwdb_ops = file_initialise_sam_password_db();
+#endif
+
+ return (pwdb_ops != NULL);
+}
+
+/*
+ * Functions that return/manipulate a struct sam_passwd.
+ */
+
+/***************************************************************
+ Start to enumerate the smb or sam passwd list. Returns a void pointer
+ to ensure no modification outside this module.
+
+ Note that currently it is being assumed that a pointer returned
+ from this function may be used to enumerate struct sam_passwd
+ entries as well as struct smb_passwd entries. This may need
+ to change. JRA.
+
+****************************************************************/
+
+void *startsam21pwent(BOOL update)
+{
+ return pwdb_ops->startsam21pwent(update);
+}
+
+/***************************************************************
+ End enumeration of the sam passwd list.
+
+ Note that currently it is being assumed that a pointer returned
+ from this function may be used to enumerate struct sam_passwd
+ entries as well as struct smb_passwd entries. This may need
+ to change. JRA.
+
+****************************************************************/
+
+void endsam21pwent(void *vp)
+{
+ pwdb_ops->endsam21pwent(vp);
+}
+
+/*************************************************************************
+ Routine to return the next entry in the smb passwd list.
+ *************************************************************************/
+
+struct sam_passwd *getsam21pwent(void *vp)
+{
+ return pwdb_sam_map_names(pwdb_ops->getsam21pwent(vp));
+}
+
+/************************************************************************
+ Routine to search the smb passwd file for an entry matching the username.
+ and then modify its password entry. We can't use the startsampwent()/
+ getsampwent()/endsampwent() interfaces here as we depend on looking
+ in the actual file to decide how much room we have to write data.
+ override = False, normal
+ override = True, override XXXXXXXX'd out password or NO PASS
+************************************************************************/
+
+BOOL mod_sam21pwd_entry(struct sam_passwd* pwd, BOOL override)
+{
+ struct sam_passwd *mapped;
+
+ DEBUG(10,("mod_sam21pwd_entry: unix user %s rid %d\n",
+ pwd->unix_name, pwd->user_rid));
+
+ mapped = pwdb_sam_map_names(pwd);
+ if (mapped != NULL)
+ {
+ return pwdb_ops->mod_sam21pwd_entry(mapped, override);
+ }
+ return False;
+}
+
+/************************************************************************
+ Utility function to search sam passwd by name. use this if your database
+ does not have search facilities.
+*************************************************************************/
+
+struct sam_passwd *iterate_getsam21pwntnam(const char *ntname)
+{
+ fstring nt_name;
+ struct sam_passwd *pwd = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by name: %s\n", ntname));
+
+ fstrcpy(nt_name, ntname);
+
+ /* Open the smb password database - not for update. */
+ fp = startsmbpwent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open sam password database.\n"));
+ return NULL;
+ }
+
+ while ((pwd = getsam21pwent(fp)) != NULL && !strequal(pwd->nt_name, nt_name))
+ {
+ DEBUG(10, ("iterate: %s 0x%x\n", pwd->nt_name, pwd->user_rid));
+ }
+
+ if (pwd != NULL)
+ {
+ DEBUG(10, ("found by name: %s\n", nt_name));
+ }
+
+ endsmbpwent(fp);
+ return pwd;
+}
+
+/************************************************************************
+ Utility function to search sam passwd by rid. use this if your database
+ does not have search facilities.
+
+ search capability by both rid and uid are needed as the rid <-> uid
+ mapping may be non-monotonic.
+
+*************************************************************************/
+
+struct sam_passwd *iterate_getsam21pwrid(uint32 rid)
+{
+ struct sam_passwd *pwd = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by rid: %x\n", rid));
+
+ /* Open the smb password file - not for update. */
+ fp = startsmbpwent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open sam password database.\n"));
+ return NULL;
+ }
+
+ while ((pwd = getsam21pwent(fp)) != NULL && pwd->user_rid != rid)
+ {
+ DEBUG(10, ("iterate: %s 0x%x\n", pwd->nt_name, pwd->user_rid));
+ }
+
+ if (pwd != NULL)
+ {
+ DEBUG(10, ("found by user_rid: %x\n", rid));
+ }
+
+ endsmbpwent(fp);
+ return pwd;
+}
+
+/************************************************************************
+ Utility function to search sam passwd by uid. use this if your database
+ does not have search facilities.
+
+ search capability by both rid and uid are needed as the rid <-> uid
+ mapping may be non-monotonic.
+
+*************************************************************************/
+
+struct sam_passwd *iterate_getsam21pwuid(uid_t uid)
+{
+ struct sam_passwd *pwd = NULL;
+ void *fp = NULL;
+
+ DEBUG(10, ("search by uid: %x\n", (int)uid));
+
+ /* Open the smb password file - not for update. */
+ fp = startsmbpwent(False);
+
+ if (fp == NULL)
+ {
+ DEBUG(0, ("unable to open sam password database.\n"));
+ return NULL;
+ }
+
+ while ((pwd = getsam21pwent(fp)) != NULL && pwd->unix_uid != uid)
+ {
+ }
+
+ if (pwd != NULL)
+ {
+ DEBUG(10, ("found by unix_uid: %x\n", (int)uid));
+ }
+
+ endsmbpwent(fp);
+ return pwd;
+}
+
+/*************************************************************************
+ Routine to return a display info structure, by rid
+ *************************************************************************/
+struct sam_disp_info *getsamdisprid(uint32 rid)
+{
+ return pwdb_ops->getsamdisprid(rid);
+}
+
+/************************************************************************
+ Routine to search sam passwd by name.
+*************************************************************************/
+
+struct sam_passwd *getsam21pwntnam(const char *name)
+{
+ return pwdb_sam_map_names(pwdb_ops->getsam21pwntnam(name));
+}
+
+/************************************************************************
+ Routine to search sam passwd by rid.
+*************************************************************************/
+
+struct sam_passwd *getsam21pwrid(uint32 rid)
+{
+ return pwdb_sam_map_names(pwdb_ops->getsam21pwrid(rid));
+}
+
+
+/**********************************************************
+ **********************************************************
+
+ utility routines which are likely to be useful to all password
+ databases
+
+ **********************************************************
+ **********************************************************/
+
+/*************************************************************
+ initialises a struct sam_disp_info.
+ **************************************************************/
+
+static void pwdb_init_dispinfo(struct sam_disp_info *user)
+{
+ if (user == NULL) return;
+ bzero(user, sizeof(*user));
+ user->user_rid = 0xffffffff;
+}
+
+/*************************************************************
+ initialises a struct sam_passwd.
+ **************************************************************/
+void pwdb_init_sam(struct sam_passwd *user)
+{
+ if (user == NULL) return;
+ bzero(user, sizeof(*user));
+
+ init_nt_time(&user->logon_time);
+ init_nt_time(&user->logoff_time);
+ init_nt_time(&user->kickoff_time);
+ init_nt_time(&user->pass_last_set_time);
+ init_nt_time(&user->pass_can_change_time);
+ init_nt_time(&user->pass_must_change_time);
+
+ user->unix_uid = (uid_t)-1;
+ user->unix_gid = (gid_t)-1;
+ user->user_rid = 0xffffffff;
+ user->group_rid = 0xffffffff;
+}
+
+/*************************************************************************
+ Routine to return the next entry in the sam passwd list.
+ *************************************************************************/
+
+struct sam_disp_info *pwdb_sam_to_dispinfo(struct sam_passwd *user)
+{
+ static struct sam_disp_info disp_info;
+
+ if (user == NULL) return NULL;
+
+ pwdb_init_dispinfo(&disp_info);
+
+ disp_info.nt_name = user->nt_name;
+ disp_info.full_name = user->full_name;
+ disp_info.user_rid = user->user_rid;
+
+ return &disp_info;
+}
+
+static void select_name(fstring *string, char **name, const UNISTR2 *from)
+{
+ if (from->buffer != 0)
+ {
+ unistr2_to_ascii(*string, from, sizeof(*string));
+ *name = *string;
+ }
+}
+
+/*************************************************************
+ copies a sam passwd.
+ **************************************************************/
+void copy_id23_to_sam_passwd(struct sam_passwd *to, const SAM_USER_INFO_23 *from)
+{
+ static fstring nt_name;
+ static fstring full_name;
+ static fstring home_dir;
+ static fstring dir_drive;
+ static fstring logon_script;
+ static fstring profile_path;
+ static fstring acct_desc;
+ static fstring workstations;
+ static fstring unknown_str;
+ static fstring munged_dial;
+
+ if (from == NULL || to == NULL) return;
+
+ to->logon_time = from->logon_time;
+ to->logoff_time = from->logoff_time;
+ to->kickoff_time = from->kickoff_time;
+ to->pass_last_set_time = from->pass_last_set_time;
+ to->pass_can_change_time = from->pass_can_change_time;
+ to->pass_must_change_time = from->pass_must_change_time;
+
+ select_name(&nt_name , &to->nt_name , &from->uni_user_name );
+ select_name(&full_name , &to->full_name , &from->uni_full_name );
+ select_name(&home_dir , &to->home_dir , &from->uni_home_dir );
+ select_name(&dir_drive , &to->dir_drive , &from->uni_dir_drive );
+ select_name(&logon_script, &to->logon_script, &from->uni_logon_script);
+ select_name(&profile_path, &to->profile_path, &from->uni_profile_path);
+ select_name(&acct_desc , &to->acct_desc , &from->uni_acct_desc );
+ select_name(&workstations, &to->workstations, &from->uni_workstations);
+ select_name(&unknown_str , &to->unknown_str , &from->uni_unknown_str );
+ select_name(&munged_dial , &to->munged_dial , &from->uni_munged_dial );
+
+ to->unix_uid = (uid_t)-1;
+ to->unix_gid = (gid_t)-1;
+ to->user_rid = from->user_rid;
+ to->group_rid = from->group_rid;
+
+ to->smb_passwd = NULL;
+ to->smb_nt_passwd = NULL;
+
+ to->acct_ctrl = from->acb_info;
+ to->unknown_3 = from->unknown_3;
+
+ to->logon_divs = from->logon_divs;
+ to->hours_len = from->logon_hrs.len;
+ memcpy(to->hours, from->logon_hrs.hours, MAX_HOURS_LEN);
+
+ to->unknown_5 = from->unknown_5;
+#if 0
+ to->unknown_6 = from->unknown_6;
+#endif
+}
+
+
+/*************************************************************
+ copies a sam passwd.
+ **************************************************************/
+void copy_sam_passwd(struct sam_passwd *to, const struct sam_passwd *from)
+{
+ static fstring nt_name;
+ static fstring unix_name;
+ static fstring full_name;
+ static fstring home_dir;
+ static fstring dir_drive;
+ static fstring logon_script;
+ static fstring profile_path;
+ static fstring acct_desc;
+ static fstring workstations;
+ static fstring unknown_str;
+ static fstring munged_dial;
+
+ if (from == NULL || to == NULL) return;
+
+ memcpy(to, from, sizeof(*from));
+
+ if (from->nt_name != NULL)
+ {
+ fstrcpy(nt_name , from->nt_name);
+ to->nt_name = nt_name;
+ }
+ else if (to->nt_name != NULL)
+ {
+ fstrcpy(nt_name , to->nt_name);
+ to->nt_name = nt_name;
+ }
+
+ if (from->unix_name != NULL)
+ {
+ fstrcpy(unix_name, from->unix_name);
+ to->unix_name = unix_name;
+ }
+ else if (to->unix_name != NULL)
+ {
+ fstrcpy(unix_name, to->unix_name);
+ to->unix_name = unix_name;
+ }
+
+ if (from->full_name != NULL)
+ {
+ fstrcpy(full_name, from->full_name);
+ to->full_name = full_name;
+ }
+ else if (to->full_name != NULL)
+ {
+ fstrcpy(full_name, to->full_name);
+ to->full_name = full_name;
+ }
+
+ if (from->home_dir != NULL)
+ {
+ fstrcpy(home_dir , from->home_dir);
+ to->home_dir = home_dir;
+ }
+ else if (to->home_dir != NULL)
+ {
+ fstrcpy(home_dir , to->home_dir);
+ to->home_dir = home_dir;
+ }
+
+ if (from->dir_drive != NULL)
+ {
+ fstrcpy(dir_drive , from->dir_drive);
+ to->dir_drive = dir_drive;
+ }
+ else if (to->dir_drive != NULL)
+ {
+ fstrcpy(dir_drive , to->dir_drive);
+ to->dir_drive = dir_drive;
+ }
+
+ if (from->logon_script != NULL)
+ {
+ fstrcpy(logon_script , from->logon_script);
+ to->logon_script = logon_script;
+ }
+ else if (to->logon_script != NULL)
+ {
+ fstrcpy(logon_script , to->logon_script);
+ to->logon_script = logon_script;
+ }
+
+ if (from->profile_path != NULL)
+ {
+ fstrcpy(profile_path , from->profile_path);
+ to->profile_path = profile_path;
+ }
+ else if (to->profile_path != NULL)
+ {
+ fstrcpy(profile_path , to->profile_path);
+ to->profile_path = profile_path;
+ }
+
+ if (from->acct_desc != NULL)
+ {
+ fstrcpy(acct_desc , from->acct_desc);
+ to->acct_desc = acct_desc;
+ }
+ else if (to->acct_desc != NULL)
+ {
+ fstrcpy(acct_desc , to->acct_desc);
+ to->acct_desc = acct_desc;
+ }
+
+ if (from->workstations != NULL)
+ {
+ fstrcpy(workstations , from->workstations);
+ to->workstations = workstations;
+ }
+ else if (to->workstations != NULL)
+ {
+ fstrcpy(workstations , to->workstations);
+ to->workstations = workstations;
+ }
+
+ if (from->unknown_str != NULL)
+ {
+ fstrcpy(unknown_str , from->unknown_str);
+ to->unknown_str = unknown_str;
+ }
+ else if (to->unknown_str != NULL)
+ {
+ fstrcpy(unknown_str , to->unknown_str);
+ to->unknown_str = unknown_str;
+ }
+
+ if (from->munged_dial != NULL)
+ {
+ fstrcpy(munged_dial , from->munged_dial);
+ to->munged_dial = munged_dial;
+ }
+ else if (to->munged_dial != NULL)
+ {
+ fstrcpy(munged_dial , to->munged_dial);
+ to->munged_dial = munged_dial;
+ }
+}
+
+
+/*************************************************************
+ converts a sam_passwd structure to a smb_passwd structure.
+ **************************************************************/
+struct smb_passwd *pwdb_sam_to_smb(struct sam_passwd *user)
+{
+ static struct smb_passwd pw_buf;
+ static fstring nt_name;
+ static fstring unix_name;
+
+ if (user == NULL) return NULL;
+
+ pwdb_init_smb(&pw_buf);
+
+ if (user->nt_name != NULL)
+ {
+ fstrcpy(nt_name , user->nt_name);
+ pw_buf.nt_name = nt_name;
+ }
+ if (user->unix_name != NULL)
+ {
+ fstrcpy(unix_name, user->unix_name);
+ pw_buf.unix_name = unix_name;
+ }
+ pw_buf.unix_uid = user->unix_uid;
+ pw_buf.user_rid = user->user_rid;
+ pw_buf.smb_passwd = user->smb_passwd;
+ pw_buf.smb_nt_passwd = user->smb_nt_passwd;
+ pw_buf.acct_ctrl = user->acct_ctrl;
+ pw_buf.pass_last_set_time = nt_time_to_unix(&user->pass_last_set_time);
+
+ return &pw_buf;
+}
+
+
+/*************************************************************
+ converts a smb_passwd structure to a sam_passwd structure.
+ **************************************************************/
+struct sam_passwd *pwdb_smb_to_sam(struct smb_passwd *user)
+{
+ static struct sam_passwd pw_buf;
+ struct passwd *pass=NULL;
+ static fstring nt_name;
+ static fstring unix_name;
+ static pstring unix_gecos;
+
+ static pstring home_dir;
+ static pstring home_drive;
+ static pstring logon_script;
+ static pstring profile_path;
+ static pstring acct_desc;
+ static pstring workstations;
+
+ if (user == NULL) return NULL;
+
+ pwdb_init_sam(&pw_buf);
+
+ if (user->nt_name != NULL)
+ {
+ fstrcpy(nt_name , user->nt_name);
+ pw_buf.nt_name = nt_name;
+ }
+ if (user->unix_name != NULL)
+ {
+ fstrcpy(unix_name, user->unix_name);
+ pw_buf.unix_name = unix_name;
+ }
+ pw_buf.unix_uid = user->unix_uid;
+ pw_buf.user_rid = user->user_rid;
+ pw_buf.smb_passwd = user->smb_passwd;
+ pw_buf.smb_nt_passwd = user->smb_nt_passwd;
+ pw_buf.acct_ctrl = user->acct_ctrl;
+
+ pass = hashed_getpwnam(unix_name);
+ if (pass != NULL)
+ {
+ pstrcpy(unix_gecos, pass->pw_gecos);
+ pw_buf.full_name=unix_gecos;
+ }
+
+ if ( user->pass_last_set_time != (time_t)-1 )
+ {
+ unix_to_nt_time(&pw_buf.pass_last_set_time, user->pass_last_set_time);
+ unix_to_nt_time(&pw_buf.pass_can_change_time, user->pass_last_set_time);
+ }
+
+ DEBUG(5,("getsamfile21pwent\n"));
+
+ if (pw_buf.home_dir == NULL)
+ pw_buf.home_dir = home_dir;
+ if (pw_buf.dir_drive == NULL)
+ pw_buf.dir_drive = home_drive;
+ if (pw_buf.logon_script == NULL)
+ pw_buf.logon_script = logon_script;
+ if (pw_buf.profile_path == NULL)
+ pw_buf.profile_path = profile_path;
+ if (pw_buf.acct_desc == NULL)
+ pw_buf.acct_desc = acct_desc;
+ if (pw_buf.workstations == NULL)
+ pw_buf.workstations = workstations;
+
+ return &pw_buf;
+}
+
+static BOOL trust_account_warning_done = False;
+
+/*************************************************************
+ fills in missing details. one set of details _must_ exist.
+ **************************************************************/
+struct sam_passwd *pwdb_sam_map_names(struct sam_passwd *sam)
+{
+ DOM_NAME_MAP gmep;
+ BOOL found = False;
+ DOM_SID sid;
+ static fstring unix_name;
+ static fstring nt_name;
+
+ /*
+ * name details
+ */
+
+ if (sam == NULL)
+ {
+ DEBUG(10,("pwdb_sam_map_names: NULL\n"));
+ return NULL;
+ }
+
+ DEBUG(10,("pwdb_sam_map_names: unix %s nt %s unix %d nt%d\n",
+ sam->unix_name != NULL ? sam->unix_name : "NULL",
+ sam->nt_name != NULL ? sam->nt_name : "NULL",
+ sam->unix_uid, sam->user_rid));
+
+ if (!found && sam->unix_name != NULL)
+ {
+ found = lookupsmbpwnam(sam->unix_name, &gmep);
+ }
+ if (!found && sam->unix_uid != (uid_t)-1)
+ {
+ found = lookupsmbpwuid(sam->unix_uid , &gmep);
+ }
+ if (!found && sam->user_rid != 0xffffffff)
+ {
+ sid_copy(&sid, &global_sam_sid);
+ sid_append_rid(&sid, sam->user_rid);
+ found = lookupsmbpwsid (&sid , &gmep);
+ }
+ if (!found && sam->nt_name != NULL)
+ {
+ found = lookupsmbpwntnam(sam->nt_name, &gmep);
+ }
+
+ if (!found)
+ {
+ return NULL;
+ }
+
+ if (!sid_front_equal(&global_sam_sid, &gmep.sid))
+ {
+ return NULL;
+ }
+
+ fstrcpy(unix_name, gmep.unix_name);
+ fstrcpy(nt_name , gmep.nt_name );
+ if (sam->unix_name == NULL ) sam->unix_name = unix_name;
+ if (sam->nt_name == NULL ) sam->nt_name = nt_name ;
+ if (sam->unix_uid == (uid_t)-1 ) sam->unix_uid = (uid_t)gmep.unix_id;
+ if (sam->user_rid == 0xffffffff) sid_split_rid(&gmep.sid, &sam->user_rid);
+
+ DEBUG(10,("pwdb_sam_map_name: found unix user %s nt %s uid %d rid 0x%x\n",
+ sam->unix_name, sam->nt_name, sam->unix_uid, sam->user_rid));
+
+ /*
+ * group details
+ */
+
+ found = False;
+
+ if (sam->unix_gid != (gid_t)-1 && sam->group_rid != 0xffffffff)
+ {
+ return sam;
+ }
+
+ if (sam->unix_gid == (gid_t)-1 && sam->group_rid == 0xffffffff)
+ {
+ struct passwd *pass = hashed_getpwnam(unix_name);
+ if (pass != NULL)
+ {
+ sam->unix_gid = pass->pw_gid;
+ }
+ else
+ {
+ DEBUG(0,("pwdb_sam_map_names: no unix password entry for %s\n",
+ unix_name));
+ }
+ }
+
+ if (!found && sam->unix_gid != (gid_t)-1)
+ {
+ found = lookupsmbgrpgid(sam->unix_gid , &gmep);
+ }
+ if (!found && sam->group_rid != 0xffffffff)
+ {
+ sid_copy(&sid, &global_sam_sid);
+ sid_append_rid(&sid, sam->group_rid);
+ found = lookupsmbgrpsid(&sid , &gmep);
+ }
+
+ if (!found)
+ {
+ if (IS_BITS_SET_SOME(sam->acct_ctrl, ACB_WSTRUST|ACB_DOMTRUST|ACB_SVRTRUST))
+ {
+ if (!trust_account_warning_done)
+ {
+ trust_account_warning_done = True;
+ DEBUG(0, ("\
+pwdb_sam_map_names: your unix password database appears to have difficulties\n\
+resolving trust account %s, probably because it ends in a '$'.\n\
+you will get this warning only once (for all trust accounts)\n", unix_name));
+ }
+ /*
+ * oh, dear.
+ */
+ if (sam->unix_gid != (gid_t)-1)
+ {
+ sam->unix_gid = (gid_t)-1;
+ }
+ sam->group_rid = DOMAIN_GROUP_RID_USERS;
+
+ return sam;
+ }
+ else
+ {
+ DEBUG(0, ("pwdb_sam_map_names: could not find Primary Group for %s\n",
+ unix_name));
+ return NULL;
+ }
+ }
+
+ if (!sid_front_equal(&global_sam_sid, &gmep.sid))
+ {
+ fstring sid_str;
+ sid_to_string(sid_str, &gmep.sid);
+ DEBUG(0,("UNIX User %s Primary Group is in the wrong domain! %s\n",
+ sam->unix_name, sid_str));
+ return NULL;
+ }
+
+ if (sam->unix_gid == (gid_t)-1 ) sam->unix_gid = (gid_t)gmep.unix_id;
+ if (sam->group_rid == 0xffffffff) sid_split_rid(&gmep.sid, &sam->group_rid);
+
+ DEBUG(10,("pwdb_sam_map_name: found gid %d and group rid 0x%x for unix user %s\n",
+ sam->unix_gid, sam->group_rid, sam->unix_name));
+
+ return sam;
+}
diff --git a/source/passdb/sampassldap.c b/source/passdb/sampassldap.c
new file mode 100644
index 00000000000..1991f92b09f
--- /dev/null
+++ b/source/passdb/sampassldap.c
@@ -0,0 +1,428 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP protocol helper functions for SAMBA
+ Copyright (C) Matthew Chapman 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "includes.h"
+
+#ifdef WITH_LDAP
+
+#include <lber.h>
+#include <ldap.h>
+
+extern int DEBUGLEVEL;
+
+/* Internal state */
+extern LDAP *ldap_struct;
+extern LDAPMessage *ldap_results;
+extern LDAPMessage *ldap_entry;
+
+
+/*******************************************************************
+ NT name/RID search functions.
+ ******************************************************************/
+
+BOOL ldap_search_by_rid(uint32 rid)
+{
+ fstring filter;
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(rid=%x)(objectclass=sambaAccount))", rid);
+ return ldap_search_for(filter);
+}
+
+BOOL ldap_search_by_ntname(const char *ntname)
+{
+ fstring filter;
+
+ slprintf(filter, sizeof(filter)-1,
+ "(&(ntuid=%s)(objectclass=sambaAccount))", ntname);
+ return ldap_search_for(filter);
+}
+
+
+/*******************************************************************
+ Store NTTIMEs as time_t's.
+ ******************************************************************/
+
+static void ldap_save_time(LDAPMod ***modlist, int modop, char *attribute,
+ NTTIME *nttime)
+{
+ fstring tstr;
+ time_t t;
+
+ t = nt_time_to_unix(nttime);
+
+ if(t == -1)
+ return;
+
+ slprintf(tstr, sizeof(tstr)-1, "%08X", t);
+ ldap_make_mod(modlist, modop, attribute, tstr);
+}
+
+static void ldap_read_time(char *attribute, NTTIME *nttime)
+{
+ fstring timestr;
+ time_t t;
+
+ if(ldap_get_attribute(attribute, timestr))
+ {
+ t = (time_t)strtol(timestr, NULL, 16);
+ unix_to_nt_time(nttime, t);
+ }
+}
+
+
+/*******************************************************************
+ Contruct a sam_passwd structure.
+ ******************************************************************/
+
+static struct sam_passwd *ldapsam_getsam()
+{
+ static pstring full_name;
+ static pstring acct_desc;
+ static pstring home_dir;
+ static pstring home_drive;
+ static pstring logon_script;
+ static pstring profile_path;
+ static pstring workstations;
+ pstring temp;
+ struct sam_passwd *sam21;
+ struct smb_passwd *smbpw;
+
+ if(!ldap_entry)
+ return NULL;
+
+ smbpw = ldap_getpw();
+ sam21 = pwdb_smb_to_sam(smbpw);
+
+ if(ldap_get_attribute("gidNumber", temp))
+ sam21->unix_gid = atoi(temp);
+
+ if(ldap_get_attribute("grouprid", temp))
+ sam21->group_rid = strtol(temp, NULL, 16);
+
+ if(ldap_get_attribute("cn", full_name))
+ sam21->full_name = full_name;
+
+ if(ldap_get_attribute("description", acct_desc))
+ sam21->acct_desc = acct_desc;
+
+ if(ldap_get_attribute("smbHome", home_dir))
+ sam21->home_dir = home_dir;
+
+ if(ldap_get_attribute("homeDrive", home_drive))
+ sam21->dir_drive = home_drive;
+
+ if(ldap_get_attribute("script", logon_script))
+ sam21->logon_script = logon_script;
+
+ if(ldap_get_attribute("profile", profile_path))
+ sam21->profile_path = profile_path;
+
+ if(ldap_get_attribute("workstations", workstations))
+ sam21->workstations = workstations;
+
+ ldap_read_time("pwdCanChange", &sam21->pass_can_change_time);
+ ldap_read_time("pwdMustChange", &sam21->pass_must_change_time);
+ ldap_read_time("logonTime", &sam21->logon_time);
+ ldap_read_time("logoffTime", &sam21->logoff_time);
+ ldap_read_time("kickoffTime", &sam21->kickoff_time);
+
+ sam21->unknown_3 = 0xffffff; /* don't know */
+ sam21->logon_divs = 168; /* hours per week */
+ sam21->hours_len = 21; /* 21 times 8 bits = 168 */
+ memset(sam21->hours, 0xff, sam21->hours_len); /* all hours */
+ sam21->unknown_5 = 0x00020000; /* don't know */
+ sam21->unknown_6 = 0x000004ec; /* don't know */
+ sam21->unknown_str = NULL;
+ sam21->munged_dial = NULL;
+
+ standard_sub_vuser(logon_script, NULL);
+ standard_sub_vuser(profile_path, NULL);
+ standard_sub_vuser(home_drive, NULL);
+ standard_sub_vuser(home_dir, NULL);
+ standard_sub_vuser(workstations, NULL);
+
+ ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
+ return sam21;
+}
+
+
+/*******************************************************************
+ Contruct a sam_disp_info structure.
+ ******************************************************************/
+
+static struct sam_disp_info *ldapsam_getdispinfo()
+{
+ static struct sam_disp_info dispinfo;
+ static pstring nt_name;
+ static pstring full_name;
+ pstring temp;
+
+ if(!ldap_entry)
+ return NULL;
+
+ if(!ldap_get_attribute("ntuid", nt_name) &&
+ !ldap_get_attribute("uid", nt_name)) {
+ DEBUG(0,("Missing uid\n"));
+ return NULL; }
+ dispinfo.nt_name = nt_name;
+
+ DEBUG(2,("Retrieving account [%s]\n",nt_name));
+
+ if(ldap_get_attribute("rid", temp))
+ dispinfo.user_rid = strtol(temp, NULL, 16);
+ else {
+ DEBUG(0,("Missing rid\n"));
+ return NULL; }
+
+ if(ldap_get_attribute("cn", full_name))
+ dispinfo.full_name = full_name;
+ else
+ dispinfo.full_name = NULL;
+
+ ldap_entry = ldap_next_entry(ldap_struct, ldap_entry);
+ return &dispinfo;
+}
+
+
+/************************************************************************
+ Queues the necessary modifications to save a sam_passwd structure
+ ************************************************************************/
+
+static void ldapsam_sammods(struct sam_passwd *newpwd, LDAPMod ***mods,
+ int operation)
+{
+ struct smb_passwd *smbpw;
+ pstring temp;
+
+ smbpw = pwdb_sam_to_smb(newpwd);
+ ldap_smbpwmods(smbpw, mods, operation);
+
+ slprintf(temp, sizeof(temp)-1, "%d", newpwd->unix_gid);
+ ldap_make_mod(mods, operation, "gidNumber", temp);
+
+ slprintf(temp, sizeof(temp)-1, "%x", newpwd->group_rid);
+ ldap_make_mod(mods, operation, "grouprid", temp);
+
+ ldap_make_mod(mods, operation, "cn", newpwd->full_name);
+ ldap_make_mod(mods, operation, "description", newpwd->acct_desc);
+ ldap_make_mod(mods, operation, "smbHome", newpwd->home_dir);
+ ldap_make_mod(mods, operation, "homeDrive", newpwd->dir_drive);
+ ldap_make_mod(mods, operation, "script", newpwd->logon_script);
+ ldap_make_mod(mods, operation, "profile", newpwd->profile_path);
+ ldap_make_mod(mods, operation, "workstations", newpwd->workstations);
+
+ ldap_save_time(mods, operation, "pwdCanChange",
+ &newpwd->pass_can_change_time);
+ ldap_save_time(mods, operation, "pwdMustChange",
+ &newpwd->pass_must_change_time);
+ ldap_save_time(mods, operation, "logonTime",
+ &newpwd->logon_time);
+ ldap_save_time(mods, operation, "logoffTime",
+ &newpwd->logoff_time);
+ ldap_save_time(mods, operation, "kickoffTime",
+ &newpwd->kickoff_time);
+}
+
+
+/***************************************************************
+ Begin/end account enumeration.
+ ****************************************************************/
+
+static void *ldapsam_enumfirst(BOOL update)
+{
+ if (!ldap_connect())
+ return NULL;
+
+ ldap_search_for("objectclass=sambaAccount");
+
+ return ldap_struct;
+}
+
+static void ldapsam_enumclose(void *vp)
+{
+ ldap_disconnect();
+}
+
+
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
+
+static SMB_BIG_UINT ldapsam_getdbpos(void *vp)
+{
+ return (SMB_BIG_UINT)((ulong)ldap_entry);
+}
+
+static BOOL ldapsam_setdbpos(void *vp, SMB_BIG_UINT tok)
+{
+ ldap_entry = (LDAPMessage *)((ulong)tok);
+ return (True);
+}
+
+
+/*************************************************************************
+ Return sam_passwd information.
+ *************************************************************************/
+
+static struct sam_passwd *ldapsam_getsambynam(const char *name)
+{
+ struct sam_passwd *ret;
+
+ if(!ldap_connect())
+ return NULL;
+
+ ldap_search_by_ntname(name);
+ ret = ldapsam_getsam();
+
+ ldap_disconnect();
+ return ret;
+}
+
+static struct sam_passwd *ldapsam_getsambyuid(uid_t userid)
+{
+ struct sam_passwd *ret;
+
+ if(!ldap_connect())
+ return NULL;
+
+ ldap_search_by_uid(userid);
+ ret = ldapsam_getsam();
+
+ ldap_disconnect();
+ return ret;
+}
+
+static struct sam_passwd *ldapsam_getsambyrid(uint32 user_rid)
+{
+ struct sam_passwd *ret;
+
+ if(!ldap_connect())
+ return NULL;
+
+ ldap_search_by_rid(user_rid);
+ ret = ldapsam_getsam();
+
+ ldap_disconnect();
+ return ret;
+}
+
+static struct sam_passwd *ldapsam_getcurrentsam(void *vp)
+{
+ return ldapsam_getsam();
+}
+
+
+/************************************************************************
+ Modify user information given a sam_passwd struct.
+ *************************************************************************/
+
+static BOOL ldapsam_addsam(struct sam_passwd *newpwd)
+{
+ LDAPMod **mods;
+
+ if (!newpwd || !ldap_allocaterid(&newpwd->user_rid))
+ return (False);
+
+ ldapsam_sammods(newpwd, &mods, LDAP_MOD_ADD);
+ return ldap_makemods("uid", newpwd->unix_name, mods, True);
+}
+
+static BOOL ldapsam_modsam(struct sam_passwd *pwd, BOOL override)
+{
+ LDAPMod **mods;
+
+ if (!pwd)
+ return (False);
+
+ ldapsam_sammods(pwd, &mods, LDAP_MOD_REPLACE);
+ return ldap_makemods("uid", pwd->unix_name, mods, False);
+}
+
+
+/*************************************************************************
+ Return sam_disp_info information.
+ *************************************************************************/
+
+static struct sam_disp_info *ldapsam_getdispbynam(const char *name)
+{
+ struct sam_disp_info *ret;
+
+ if(!ldap_connect())
+ return NULL;
+
+ ldap_search_by_ntname(name);
+ ret = ldapsam_getdispinfo();
+
+ ldap_disconnect();
+ return ret;
+}
+
+static struct sam_disp_info *ldapsam_getdispbyrid(uint32 user_rid)
+{
+ struct sam_disp_info *ret;
+
+ if(!ldap_connect())
+ return NULL;
+
+ ldap_search_by_rid(user_rid);
+ ret = ldapsam_getdispinfo();
+
+ ldap_disconnect();
+ return ret;
+}
+
+static struct sam_disp_info *ldapsam_getcurrentdisp(void *vp)
+{
+ return ldapsam_getdispinfo();
+}
+
+
+
+static struct sam_passdb_ops ldapsam_ops =
+{
+ ldapsam_enumfirst,
+ ldapsam_enumclose,
+ ldapsam_getdbpos,
+ ldapsam_setdbpos,
+
+ ldapsam_getsambynam,
+ ldapsam_getsambyuid,
+ ldapsam_getsambyrid,
+ ldapsam_getcurrentsam,
+ ldapsam_addsam,
+ ldapsam_modsam,
+
+ ldapsam_getdispbynam,
+ ldapsam_getdispbyrid,
+ ldapsam_getcurrentdisp
+};
+
+struct sam_passdb_ops *ldap_initialise_sam_password_db(void)
+{
+ return &ldapsam_ops;
+}
+
+#else
+ void sampassldap_dummy_function(void);
+ void sampassldap_dummy_function(void) { } /* stop some compilers complaining */
+#endif
diff --git a/source/passdb/sampassnt5ldap.c b/source/passdb/sampassnt5ldap.c
new file mode 100644
index 00000000000..6d8586a2924
--- /dev/null
+++ b/source/passdb/sampassnt5ldap.c
@@ -0,0 +1,598 @@
+
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP protocol helper functions for SAMBA
+ Copyright (C) Matthew Chapman 1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include "includes.h"
+
+#ifdef WITH_NT5LDAP
+
+#include <lber.h>
+#include <ldap.h>
+#include "ldapdb.h"
+
+extern int DEBUGLEVEL;
+extern DOM_SID global_sam_sid;
+
+/*******************************************************************
+ NT name/RID search functions.
+ ******************************************************************/
+
+/*******************************************************************
+ Contruct a sam_passwd structure.
+ ******************************************************************/
+
+struct sam_passwd *
+nt5ldapsam_getent (LDAPDB * hds)
+{
+ static pstring full_name;
+ static pstring acct_desc;
+ static pstring home_dir;
+ static pstring home_drive;
+ static pstring logon_script;
+ static pstring profile_path;
+ static pstring workstations;
+ struct sam_passwd *sam21;
+ struct smb_passwd *smbpw;
+ struct berval *bv;
+ pstring temp;
+
+ extern BOOL sam_logon_in_ssb;
+ extern pstring samlogon_user;
+
+ if (!ldapdb_peek (hds))
+ {
+ return NULL;
+ }
+
+ smbpw = nt5ldapsmb_getent (hds);
+ if (smbpw == NULL)
+ {
+ return NULL;
+ }
+
+ sam21 = pwdb_smb_to_sam (smbpw);
+
+ /* uid/mSSFUName from smbpw */
+
+ /* sAMAccountName from smbpw */
+
+ if (ldapdb_get_pvalue (hds, "displayName", full_name) ||
+ ldapdb_get_pvalue (hds, "cn", full_name))
+ sam21->full_name = full_name;
+
+ /* XXX rfc2307 conflict */
+ if (ldapdb_get_pvalue (hds, "homeDirectory", home_dir))
+ sam21->home_dir = home_dir;
+
+ if (ldapdb_get_pvalue (hds, "homeDrive", home_drive))
+ sam21->dir_drive = home_drive;
+
+ if (ldapdb_get_pvalue (hds, "scriptPath", logon_script))
+ sam21->logon_script = logon_script;
+
+ if (ldapdb_get_pvalue (hds, "profilePath", profile_path))
+ sam21->profile_path = profile_path;
+
+ if (ldapdb_get_pvalue (hds, "description", acct_desc))
+ sam21->acct_desc = acct_desc;
+
+ if (ldapdb_get_pvalue (hds, "userWorkstations", workstations))
+ sam21->workstations = workstations;
+
+ /* uidNumber from smbpw */
+
+ if (ldapdb_get_pvalue (hds, "gidNumber", temp))
+ sam21->unix_gid = atoi (temp);
+
+ /* objectSid from smbpw */
+
+ if (ldapdb_get_pvalue (hds, "primaryGroupId", temp))
+ sam21->group_rid = strtol (temp, NULL, 10);
+
+ /* dBCSPwd/unicodePwd from smbpw */
+
+ (void) ldapdb_get_time (hds, "lastLogon", &sam21->logon_time);
+ (void) ldapdb_get_time (hds, "lastLogoff", &sam21->logoff_time);
+ (void) ldapdb_get_time (hds, "accountExpires", &sam21->pass_must_change_time);
+#if 0
+ /* not sure about this */
+ (void) ldapdb_get_time (hds, "pwdCanChange", &sam21->pass_can_change_time);
+ (void) ldapdb_get_time (hds, "kickoffTime", &sam21->kickoff_time);
+#endif
+
+ if (ldapdb_get_value_len(hds, "logonHours", &bv))
+ {
+ if (bv->bv_len <= MAX_HOURS_LEN)
+ {
+ memcpy(sam21->hours, bv->bv_val, bv->bv_len);
+ sam21->hours_len = bv->bv_len;
+ }
+ ber_bvfree(bv);
+ }
+
+ sam21->unknown_3 = 0xffffff; /* don't know */
+ sam21->logon_divs = 168; /* hours per week */
+ sam21->unknown_5 = 0x00020000; /* don't know */
+ sam21->unknown_6 = 0x000004ec; /* don't know */
+ sam21->unknown_str = NULL;
+ sam21->munged_dial = NULL;
+
+ /* XXXX hack to get standard_sub_basic() to use sam logon username */
+ /* possibly a better way would be to do a become_user() call */
+
+ sam_logon_in_ssb = True;
+
+ pstrcpy (samlogon_user, sam21->unix_name);
+
+ standard_sub_basic (logon_script);
+ standard_sub_basic (profile_path);
+ standard_sub_basic (home_drive);
+ standard_sub_basic (home_dir);
+ standard_sub_basic (workstations);
+
+ sam_logon_in_ssb = False;
+
+ return sam21;
+}
+
+
+/*******************************************************************
+ Contruct a sam_disp_info structure.
+ ******************************************************************/
+
+static struct sam_disp_info *
+nt5ldapsam_getdispinfo (LDAPDB * hds)
+{
+ static struct sam_disp_info dispinfo;
+ static pstring nt_name;
+ static pstring full_name;
+
+ if (!ldapdb_peek (hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_get_pvalue (hds, "sAMAccountName", nt_name))
+ {
+ DEBUG (0, ("SAM user missing sAMAccountName\n"));
+ return NULL;
+ }
+ dispinfo.nt_name = nt_name;
+
+ DEBUG (2, ("Retrieving account [%s]\n", nt_name));
+
+ if (!ldapdb_get_rid (hds, "objectSid", &dispinfo.user_rid))
+ {
+ DEBUG (0, ("SAM user missing objectSid\n"));
+ return NULL;
+ }
+
+ if (ldapdb_get_pvalue (hds, "displayName", full_name) ||
+ ldapdb_get_pvalue (hds, "cn", full_name))
+ {
+ dispinfo.full_name = full_name;
+ }
+ else
+ {
+ dispinfo.full_name = nt_name;
+ }
+
+ return &dispinfo;
+}
+
+
+/************************************************************************
+ Queues the necessary modifications to save a sam_passwd structure
+ ************************************************************************/
+
+BOOL
+nt5ldapsam_sammods (struct sam_passwd * newpwd, LDAPMod *** mods, int operation)
+{
+ struct smb_passwd *smbpw;
+ pstring temp;
+ struct berval *bv;
+
+ smbpw = pwdb_sam_to_smb (newpwd);
+ if (!nt5ldapsmb_smbmods (smbpw, mods, operation))
+ {
+ return False;
+ }
+
+ slprintf (temp, sizeof (temp) - 1, "%d", newpwd->unix_gid);
+ if (!ldapdb_queue_mod (mods, operation, "gidNumber", temp) ||
+ !ldapdb_queue_mod (mods, operation, "cn", newpwd->full_name) ||
+ !ldapdb_queue_mod (mods, operation, "name", newpwd->full_name) ||
+ !ldapdb_queue_mod (mods, operation, "displayName", newpwd->full_name) ||
+ !ldapdb_queue_mod (mods, operation, "description", newpwd->acct_desc) ||
+ !ldapdb_queue_mod (mods, operation, "homeDirectory", newpwd->home_dir) ||
+ !ldapdb_queue_mod (mods, operation, "homeDrive", newpwd->dir_drive) ||
+ !ldapdb_queue_mod (mods, operation, "scriptPath", newpwd->logon_script) ||
+ !ldapdb_queue_mod (mods, operation, "profilePath", newpwd->profile_path) ||
+ !ldapdb_queue_mod (mods, operation, "userWorkstations", newpwd->workstations) ||
+ !ldapdb_queue_time (mods, operation, "lastLogon", &newpwd->logon_time) ||
+ !ldapdb_queue_time (mods, operation, "lastLogoff", &newpwd->logoff_time) ||
+ !ldapdb_queue_time (mods, operation, "accountExpires", &newpwd->pass_must_change_time))
+ {
+ return False;
+ }
+
+ if (newpwd->hours_len)
+ {
+ bv = (struct berval *)malloc(sizeof(*bv));
+ if (bv == NULL)
+ {
+ return False;
+ }
+ bv->bv_len = newpwd->hours_len;
+ bv->bv_val = malloc(newpwd->hours_len);
+ if (bv->bv_val == NULL)
+ {
+ free(bv);
+ return False;
+ }
+
+ memcpy(bv->bv_val, newpwd->hours, newpwd->hours_len);
+ if (!ldapdb_queue_mod_len(mods, operation, "logonHours", bv))
+ {
+ ber_bvfree(bv);
+ return False;
+ }
+ }
+
+#if 0
+ /* not sure about this */
+ if (!ldapdb_queue_time (mods, operation, "pwdCanChange", &newpwd->pass_can_change_time) ||
+ !ldapdb_queue_time (mods, operation, "kickoffTime", &newpwd->kickoff_time))
+ {
+ return False;
+ }
+#endif
+
+ return True;
+}
+
+
+/***************************************************************
+ Begin/end account enumeration.
+ ****************************************************************/
+
+static void *
+nt5ldapsam_enumfirst (BOOL update)
+{
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_search (hds, NULL, "(objectClass=User)", NULL, LDAP_NO_LIMIT))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ return hds;
+}
+
+static void
+nt5ldapsam_enumclose (void *vp)
+{
+ LDAPDB *hds = (LDAPDB *) vp;
+
+ ldapdb_close (&hds);
+
+ return;
+}
+
+
+/*************************************************************************
+ Save/restore the current position in a query
+ *************************************************************************/
+
+static SMB_BIG_UINT
+nt5ldapsam_getdbpos (void *vp)
+{
+ return 0;
+}
+
+static BOOL
+nt5ldapsam_setdbpos (void *vp, SMB_BIG_UINT tok)
+{
+ return False;
+}
+
+
+/*************************************************************************
+ Return sam_passwd information.
+ *************************************************************************/
+
+static struct sam_passwd *
+nt5ldapsam_getsambynam (const char *name)
+{
+ struct sam_passwd *ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_lookup_by_ntname (hds, name))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldapsam_getent (hds);
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static struct sam_passwd *
+nt5ldapsam_getsambyuid (uid_t userid)
+{
+ struct sam_passwd *ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_lookup_by_posix_uid (hds, userid))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldapsam_getent (hds);
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static struct sam_passwd *
+nt5ldapsam_getsambyrid (uint32 user_rid)
+{
+ struct sam_passwd *ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_lookup_by_rid (hds, user_rid))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldapsam_getent (hds);
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static struct sam_passwd *
+nt5ldapsam_getcurrentsam (void *vp)
+{
+ struct sam_passwd *ret = NULL;
+
+ do
+ {
+ if ((ret = nt5ldapsam_getent ((LDAPDB *)vp)) != NULL)
+ break;
+ }
+ while (ldapdb_seq((LDAPDB *)vp) == True);
+
+ return ret;
+}
+
+
+/************************************************************************
+ Modify user information given a sam_passwd struct.
+ *************************************************************************/
+
+static BOOL
+nt5ldapsam_addsam (struct sam_passwd *newpwd)
+{
+ LDAPMod **mods = NULL;
+ char *container, *cname;
+ pstring hostname;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!newpwd || !ldapdb_allocate_rid (hds, &newpwd->user_rid))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (newpwd->unix_name[strlen (newpwd->unix_name) - 2] == '$')
+ {
+ container = lp_ldap_computers_subcontext ();
+ pstrcpy (hostname, newpwd->nt_name);
+ hostname[strlen (hostname) - 1] = '\0';
+ cname = hostname;
+ }
+ else
+ {
+ container = lp_ldap_users_subcontext ();
+ cname = newpwd->full_name;
+ }
+
+ if (!nt5ldapsam_sammods (newpwd, &mods, LDAP_MOD_ADD))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_update (hds, container, "cn", cname, mods, True);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapsam_modsam (struct sam_passwd *pwd, BOOL override)
+{
+ LDAPMod **mods = NULL;
+ LDAPDB_DECLARE_HANDLE (hds);
+ BOOL ret;
+
+ if (!pwd)
+ {
+ return False;
+ }
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!nt5ldapsam_sammods (pwd, &mods, LDAP_MOD_REPLACE))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_update (hds, NULL, "cn", pwd->full_name, mods, False);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+
+/*************************************************************************
+ Return sam_disp_info information.
+ *************************************************************************/
+
+static struct sam_disp_info *
+nt5ldapsam_getdispbynam (const char *name)
+{
+ struct sam_disp_info *ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_lookup_by_ntname (hds, name))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldapsam_getdispinfo (hds);
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static struct sam_disp_info *
+nt5ldapsam_getdispbyrid (uint32 user_rid)
+{
+ struct sam_disp_info *ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_lookup_by_rid (hds, user_rid))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldapsam_getdispinfo (hds);
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static struct sam_disp_info *
+nt5ldapsam_getcurrentdisp (void *vp)
+{
+ struct sam_disp_info *ret = NULL;
+
+ do
+ {
+ if ((ret = nt5ldapsam_getdispinfo ((LDAPDB *)vp)) != NULL)
+ break;
+ }
+ while (ldapdb_seq((LDAPDB *)vp) == True);
+
+ return ret;
+}
+
+static struct sam_passdb_ops nt5ldapsam_ops =
+{
+ nt5ldapsam_enumfirst,
+ nt5ldapsam_enumclose,
+ nt5ldapsam_getdbpos,
+ nt5ldapsam_setdbpos,
+
+ nt5ldapsam_getsambynam,
+ nt5ldapsam_getsambyuid,
+ nt5ldapsam_getsambyrid,
+ nt5ldapsam_getcurrentsam,
+ nt5ldapsam_addsam,
+ nt5ldapsam_modsam,
+
+ nt5ldapsam_getdispbynam,
+ nt5ldapsam_getdispbyrid,
+ nt5ldapsam_getcurrentdisp
+};
+
+struct sam_passdb_ops *
+nt5ldap_initialise_sam_password_db (void)
+{
+ return &nt5ldapsam_ops;
+}
+
+#else
+void sampassnt5ldap_dummy_function (void);
+void
+sampassnt5ldap_dummy_function (void)
+{
+} /* stop some compilers complaining */
+#endif
diff --git a/source/passdb/smbpass.c b/source/passdb/smbpass.c
index 4ca37a92965..e3c6a5da441 100644
--- a/source/passdb/smbpass.c
+++ b/source/passdb/smbpass.c
@@ -21,140 +21,10 @@
#ifdef USE_SMBPASS_DB
+static int pw_file_lock_depth = 0;
extern int DEBUGLEVEL;
-extern pstring samlogon_user;
-extern BOOL sam_logon_in_ssb;
static char s_readbuf[1024];
-static int pw_file_lock_depth;
-
-enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE };
-
-/***************************************************************
- Internal fn to enumerate the smbpasswd list. Returns a void pointer
- to ensure no modification outside this module. Checks for atomic
- rename of smbpasswd file on update or create once the lock has
- been granted to prevent race conditions. JRA.
-****************************************************************/
-
-static void *startsmbfilepwent_internal(const char *pfile, enum pwf_access_type type, int *lock_depth)
-{
- FILE *fp = NULL;
- const char *open_mode = NULL;
- int race_loop = 0;
- int lock_type;
-
- if (!*pfile) {
- DEBUG(0, ("startsmbfilepwent: No SMB password file set\n"));
- return (NULL);
- }
-
- switch(type) {
- case PWF_READ:
- open_mode = "rb";
- lock_type = F_RDLCK;
- break;
- case PWF_UPDATE:
- open_mode = "r+b";
- lock_type = F_WRLCK;
- break;
- case PWF_CREATE:
- /*
- * Ensure atomic file creation.
- */
- {
- int i, fd = -1;
-
- for(i = 0; i < 5; i++) {
- if((fd = sys_open(pfile, O_CREAT|O_TRUNC|O_EXCL|O_RDWR, 0600))!=-1)
- break;
- sys_usleep(200); /* Spin, spin... */
- }
- if(fd == -1) {
- DEBUG(0,("startsmbfilepwent_internal: too many race conditions creating file %s\n", pfile));
- return NULL;
- }
- close(fd);
- open_mode = "r+b";
- lock_type = F_WRLCK;
- break;
- }
- }
-
- for(race_loop = 0; race_loop < 5; race_loop++) {
- DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile));
-
- if((fp = sys_fopen(pfile, open_mode)) == NULL) {
- DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) ));
- return NULL;
- }
-
- if (!pw_file_lock(fileno(fp), lock_type, 5, lock_depth)) {
- DEBUG(0, ("startsmbfilepwent_internal: unable to lock file %s. Error was %s\n", pfile, strerror(errno) ));
- fclose(fp);
- return NULL;
- }
-
- /*
- * Only check for replacement races on update or create.
- * For read we don't mind if the data is one record out of date.
- */
-
- if(type == PWF_READ) {
- break;
- } else {
- SMB_STRUCT_STAT sbuf1, sbuf2;
-
- /*
- * Avoid the potential race condition between the open and the lock
- * by doing a stat on the filename and an fstat on the fd. If the
- * two inodes differ then someone did a rename between the open and
- * the lock. Back off and try the open again. Only do this 5 times to
- * prevent infinate loops. JRA.
- */
-
- if (sys_stat(pfile,&sbuf1) != 0) {
- DEBUG(0, ("startsmbfilepwent_internal: unable to stat file %s. Error was %s\n", pfile, strerror(errno)));
- pw_file_unlock(fileno(fp), lock_depth);
- fclose(fp);
- return False;
- }
-
- if (sys_fstat(fileno(fp),&sbuf2) != 0) {
- DEBUG(0, ("startsmbfilepwent_internal: unable to fstat file %s. Error was %s\n", pfile, strerror(errno)));
- pw_file_unlock(fileno(fp), lock_depth);
- fclose(fp);
- return False;
- }
-
- if( sbuf1.st_ino == sbuf2.st_ino) {
- /* No race. */
- break;
- }
-
- /*
- * Race occurred - back off and try again...
- */
-
- pw_file_unlock(fileno(fp), lock_depth);
- fclose(fp);
- }
- }
-
- if(race_loop == 5) {
- DEBUG(0, ("startsmbfilepwent_internal: too many race conditions opening file %s\n", pfile));
- return NULL;
- }
-
- /* Set a buffer to do more efficient reads */
- setvbuf(fp, s_readbuf, _IOFBF, sizeof(s_readbuf));
-
- /* Make sure it is only rw by the owner */
- chmod(pfile, 0600);
-
- /* We have a lock on the file. */
- return (void *)fp;
-}
/***************************************************************
Start to enumerate the smbpasswd list. Returns a void pointer
@@ -163,361 +33,17 @@ static void *startsmbfilepwent_internal(const char *pfile, enum pwf_access_type
static void *startsmbfilepwent(BOOL update)
{
- return startsmbfilepwent_internal(lp_smb_passwd_file(), update ? PWF_UPDATE : PWF_READ, &pw_file_lock_depth);
+ return startfileent(lp_smb_passwd_file(), s_readbuf, sizeof(s_readbuf),
+ &pw_file_lock_depth, update);
}
/***************************************************************
End enumeration of the smbpasswd list.
****************************************************************/
-static void endsmbfilepwent_internal(void *vp, int *lock_depth)
-{
- FILE *fp = (FILE *)vp;
-
- pw_file_unlock(fileno(fp), lock_depth);
- fclose(fp);
- DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n"));
-}
-
-/***************************************************************
- End enumeration of the smbpasswd list - operate on the default
- lock_depth.
-****************************************************************/
-
static void endsmbfilepwent(void *vp)
{
- endsmbfilepwent_internal(vp, &pw_file_lock_depth);
-}
-
-/*************************************************************************
- Routine to return the next entry in the smbpasswd list.
- *************************************************************************/
-
-static struct smb_passwd *getsmbfilepwent(void *vp)
-{
- /* Static buffers we will return. */
- static struct smb_passwd pw_buf;
- static pstring user_name;
- static unsigned char smbpwd[16];
- static unsigned char smbntpwd[16];
- FILE *fp = (FILE *)vp;
- char linebuf[256];
- unsigned char c;
- unsigned char *p;
- long uidval;
- size_t linebuf_len;
-
- if(fp == NULL) {
- DEBUG(0,("getsmbfilepwent: Bad password file pointer.\n"));
- return NULL;
- }
-
- pdb_init_smb(&pw_buf);
-
- pw_buf.acct_ctrl = ACB_NORMAL;
-
- /*
- * Scan the file, a line at a time and check if the name matches.
- */
- while (!feof(fp)) {
- linebuf[0] = '\0';
-
- fgets(linebuf, 256, fp);
- if (ferror(fp)) {
- return NULL;
- }
-
- /*
- * Check if the string is terminated with a newline - if not
- * then we must keep reading and discard until we get one.
- */
- linebuf_len = strlen(linebuf);
- if (linebuf[linebuf_len - 1] != '\n') {
- c = '\0';
- while (!ferror(fp) && !feof(fp)) {
- c = fgetc(fp);
- if (c == '\n')
- break;
- }
- } else
- linebuf[linebuf_len - 1] = '\0';
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100, ("getsmbfilepwent: got line |%s|\n", linebuf));
-#endif
- if ((linebuf[0] == 0) && feof(fp)) {
- DEBUG(4, ("getsmbfilepwent: end of file reached\n"));
- break;
- }
- /*
- * The line we have should be of the form :-
- *
- * username:uid:32hex bytes:[Account type]:LCT-12345678....other flags presently
- * ignored....
- *
- * or,
- *
- * username:uid:32hex bytes:32hex bytes:[Account type]:LCT-12345678....ignored....
- *
- * if Windows NT compatible passwords are also present.
- * [Account type] is an ascii encoding of the type of account.
- * LCT-(8 hex digits) is the time_t value of the last change time.
- */
-
- if (linebuf[0] == '#' || linebuf[0] == '\0') {
- DEBUG(6, ("getsmbfilepwent: skipping comment or blank line\n"));
- continue;
- }
- p = (unsigned char *) strchr(linebuf, ':');
- if (p == NULL) {
- DEBUG(0, ("getsmbfilepwent: malformed password entry (no :)\n"));
- continue;
- }
- /*
- * As 256 is shorter than a pstring we don't need to check
- * length here - if this ever changes....
- */
- strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
- user_name[PTR_DIFF(p, linebuf)] = '\0';
-
- /* Get smb uid. */
-
- p++; /* Go past ':' */
-
- if(*p == '-') {
- DEBUG(0, ("getsmbfilepwent: uids in the smbpasswd file must not be negative.\n"));
- continue;
- }
-
- if (!isdigit(*p)) {
- DEBUG(0, ("getsmbfilepwent: malformed password entry (uid not number)\n"));
- continue;
- }
-
- uidval = atoi((char *) p);
-
- while (*p && isdigit(*p))
- p++;
-
- if (*p != ':') {
- DEBUG(0, ("getsmbfilepwent: malformed password entry (no : after uid)\n"));
- continue;
- }
-
- pw_buf.smb_name = user_name;
- pw_buf.smb_userid = uidval;
-
- /*
- * Now get the password value - this should be 32 hex digits
- * which are the ascii representations of a 16 byte string.
- * Get two at a time and put them into the password.
- */
-
- /* Skip the ':' */
- p++;
-
- if (*p == '*' || *p == 'X') {
- /* Password deliberately invalid - end here. */
- DEBUG(10, ("getsmbfilepwent: entry invalidated for user %s\n", user_name));
- pw_buf.smb_nt_passwd = NULL;
- pw_buf.smb_passwd = NULL;
- pw_buf.acct_ctrl |= ACB_DISABLED;
- return &pw_buf;
- }
-
- if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
- DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n"));
- continue;
- }
-
- if (p[32] != ':') {
- DEBUG(0, ("getsmbfilepwent: malformed password entry (no terminating :)\n"));
- continue;
- }
-
- if (!strncasecmp((char *) p, "NO PASSWORD", 11)) {
- pw_buf.smb_passwd = NULL;
- pw_buf.acct_ctrl |= ACB_PWNOTREQ;
- } else {
- if (!pdb_gethexpwd((char *)p, smbpwd)) {
- DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
- continue;
- }
- pw_buf.smb_passwd = smbpwd;
- }
-
- /*
- * Now check if the NT compatible password is
- * available.
- */
- pw_buf.smb_nt_passwd = NULL;
-
- p += 33; /* Move to the first character of the line after
- the lanman password. */
- if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':')) {
- if (*p != '*' && *p != 'X') {
- if(pdb_gethexpwd((char *)p,smbntpwd))
- pw_buf.smb_nt_passwd = smbntpwd;
- }
- p += 33; /* Move to the first character of the line after
- the NT password. */
- }
-
- DEBUG(5,("getsmbfilepwent: returning passwd entry for user %s, uid %ld\n",
- user_name, uidval));
-
- if (*p == '[')
- {
- pw_buf.acct_ctrl = pdb_decode_acct_ctrl((char*)p);
-
- /* Must have some account type set. */
- if(pw_buf.acct_ctrl == 0)
- pw_buf.acct_ctrl = ACB_NORMAL;
-
- /* Now try and get the last change time. */
- if(*p == ']')
- p++;
- if(*p == ':') {
- p++;
- if(*p && (StrnCaseCmp((char *)p, "LCT-", 4)==0)) {
- int i;
- p += 4;
- for(i = 0; i < 8; i++) {
- if(p[i] == '\0' || !isxdigit(p[i]))
- break;
- }
- if(i == 8) {
- /*
- * p points at 8 characters of hex digits -
- * read into a time_t as the seconds since
- * 1970 that the password was last changed.
- */
- pw_buf.pass_last_set_time = (time_t)strtol((char *)p, NULL, 16);
- }
- }
- }
- } else {
- /* 'Old' style file. Fake up based on user name. */
- /*
- * Currently trust accounts are kept in the same
- * password file as 'normal accounts'. If this changes
- * we will have to fix this code. JRA.
- */
- if(pw_buf.smb_name[strlen(pw_buf.smb_name) - 1] == '$') {
- pw_buf.acct_ctrl &= ~ACB_NORMAL;
- pw_buf.acct_ctrl |= ACB_WSTRUST;
- }
- }
-
- return &pw_buf;
- }
-
- DEBUG(5,("getsmbfilepwent: end of file reached.\n"));
- return NULL;
-}
-
-/*************************************************************************
- Routine to return the next entry in the smbpasswd list.
- this function is a nice, messy combination of reading:
- - the smbpasswd file
- - the unix password database
- - smb.conf options (not done at present).
- *************************************************************************/
-
-static struct sam_passwd *getsmbfile21pwent(void *vp)
-{
- struct smb_passwd *pw_buf = getsmbfilepwent(vp);
- static struct sam_passwd user;
- struct passwd *pwfile;
-
- static pstring full_name;
- static pstring home_dir;
- static pstring home_drive;
- static pstring logon_script;
- static pstring profile_path;
- static pstring acct_desc;
- static pstring workstations;
-
- DEBUG(5,("getsmbfile21pwent\n"));
-
- if (pw_buf == NULL) return NULL;
-
- pwfile = sys_getpwnam(pw_buf->smb_name);
- if (pwfile == NULL)
- {
- DEBUG(0,("getsmbfile21pwent: smbpasswd database is corrupt!\n"));
- DEBUG(0,("getsmbfile21pwent: username %s not in unix passwd database!\n", pw_buf->smb_name));
- return NULL;
- }
-
- pdb_init_sam(&user);
-
- pstrcpy(samlogon_user, pw_buf->smb_name);
-
- if (samlogon_user[strlen(samlogon_user)-1] != '$')
- {
- /* XXXX hack to get standard_sub_basic() to use sam logon username */
- /* possibly a better way would be to do a become_user() call */
- sam_logon_in_ssb = True;
-
- user.smb_userid = pw_buf->smb_userid;
- user.smb_grpid = pwfile->pw_gid;
-
- user.user_rid = pdb_uid_to_user_rid (user.smb_userid);
- user.group_rid = pdb_gid_to_group_rid(user.smb_grpid );
-
- pstrcpy(full_name , pwfile->pw_gecos );
- pstrcpy(logon_script , lp_logon_script ());
- pstrcpy(profile_path , lp_logon_path ());
- pstrcpy(home_drive , lp_logon_drive ());
- pstrcpy(home_dir , lp_logon_home ());
- pstrcpy(acct_desc , "");
- pstrcpy(workstations , "");
-
- sam_logon_in_ssb = False;
- }
- else
- {
- user.smb_userid = pw_buf->smb_userid;
- user.smb_grpid = pwfile->pw_gid;
-
- user.user_rid = pdb_uid_to_user_rid (user.smb_userid);
- user.group_rid = DOMAIN_GROUP_RID_USERS; /* lkclXXXX this is OBSERVED behaviour by NT PDCs, enforced here. */
-
- pstrcpy(full_name , "");
- pstrcpy(logon_script , "");
- pstrcpy(profile_path , "");
- pstrcpy(home_drive , "");
- pstrcpy(home_dir , "");
- pstrcpy(acct_desc , "");
- pstrcpy(workstations , "");
- }
-
- user.smb_name = pw_buf->smb_name;
- user.full_name = full_name;
- user.home_dir = home_dir;
- user.dir_drive = home_drive;
- user.logon_script = logon_script;
- user.profile_path = profile_path;
- user.acct_desc = acct_desc;
- user.workstations = workstations;
-
- user.unknown_str = NULL; /* don't know, yet! */
- user.munged_dial = NULL; /* "munged" dial-back telephone number */
-
- user.smb_nt_passwd = pw_buf->smb_nt_passwd;
- user.smb_passwd = pw_buf->smb_passwd;
-
- user.acct_ctrl = pw_buf->acct_ctrl;
-
- user.unknown_3 = 0xffffff; /* don't know */
- user.logon_divs = 168; /* hours per week */
- user.hours_len = 21; /* 21 times 8 bits = 168 */
- memset(user.hours, 0xff, user.hours_len); /* available at all hours */
- user.unknown_5 = 0x00020000; /* don't know */
- user.unknown_5 = 0x000004ec; /* don't know */
-
- return &user;
+ endfileent(vp, &pw_file_lock_depth);
}
/*************************************************************************
@@ -527,7 +53,7 @@ static struct sam_passwd *getsmbfile21pwent(void *vp)
static SMB_BIG_UINT getsmbfilepwpos(void *vp)
{
- return (SMB_BIG_UINT)sys_ftell((FILE *)vp);
+ return getfilepwpos(vp);
}
/*************************************************************************
@@ -537,66 +63,196 @@ static SMB_BIG_UINT getsmbfilepwpos(void *vp)
static BOOL setsmbfilepwpos(void *vp, SMB_BIG_UINT tok)
{
- return !sys_fseek((FILE *)vp, (SMB_OFF_T)tok, SEEK_SET);
+ return setfilepwpos(vp, tok);
}
-/************************************************************************
- Create a new smbpasswd entry - malloced space returned.
-*************************************************************************/
+/*************************************************************************
+ Routine to return the next entry in the smbpasswd list.
-char *format_new_smbpasswd_entry(struct smb_passwd *newpwd)
+ this function is non-static as it is called (exclusively and only)
+ from getsamfile21pwent().
+ *************************************************************************/
+struct smb_passwd *getsmbfilepwent(void *vp)
{
- int new_entry_length;
- char *new_entry;
- char *p;
- int i;
-
- new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2;
-
- if((new_entry = (char *)malloc( new_entry_length )) == NULL) {
- DEBUG(0, ("format_new_smbpasswd_entry: Malloc failed adding entry for user %s.\n", newpwd->smb_name ));
- return NULL;
- }
-
- slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid);
- p = &new_entry[strlen(new_entry)];
-
- if(newpwd->smb_passwd != NULL) {
- for( i = 0; i < 16; i++) {
- slprintf((char *)&p[i*2], new_entry_length - (p - new_entry) - 1, "%02X", newpwd->smb_passwd[i]);
- }
- } else {
- i=0;
- if(newpwd->acct_ctrl & ACB_PWNOTREQ)
- safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
- else
- safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
- }
-
- p += 32;
-
- *p++ = ':';
-
- if(newpwd->smb_nt_passwd != NULL) {
- for( i = 0; i < 16; i++) {
- slprintf((char *)&p[i*2], new_entry_length - 1 - (p - new_entry), "%02X", newpwd->smb_nt_passwd[i]);
- }
- } else {
- if(newpwd->acct_ctrl & ACB_PWNOTREQ)
- safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
- else
- safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
- }
+ /* Static buffers we will return. */
+ static struct smb_passwd pw_buf;
+ static pstring unix_name;
+ static unsigned char smbpwd[16];
+ static unsigned char smbntpwd[16];
+ char linebuf[256];
+ char *p;
+ int uidval;
+ size_t linebuf_len;
+
+ if (vp == NULL)
+ {
+ DEBUG(0,("getsmbfilepwent: Bad password file pointer.\n"));
+ return NULL;
+ }
- p += 32;
+ pwdb_init_smb(&pw_buf);
- *p++ = ':';
+ pw_buf.acct_ctrl = ACB_NORMAL;
- /* Add the account encoding and the last change time. */
- slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n",
- pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32)time(NULL));
+ /*
+ * Scan the file, a line at a time.
+ */
+ while ((linebuf_len = getfileline(vp, linebuf, sizeof(linebuf))) > 0)
+ {
+ /*
+ * The line we have should be of the form :-
+ *
+ * username:uid:32hex bytes:[Account type]:LCT-12345678....other flags presently
+ * ignored....
+ *
+ * or,
+ *
+ * username:uid:32hex bytes:32hex bytes:[Account type]:LCT-12345678....ignored....
+ *
+ * if Windows NT compatible passwords are also present.
+ * [Account type] is an ascii encoding of the type of account.
+ * LCT-(8 hex digits) is the time_t value of the last change time.
+ */
+
+ /*
+ * As 256 is shorter than a pstring we don't need to check
+ * length here - if this ever changes....
+ */
+ p = strncpyn(unix_name, linebuf, sizeof(unix_name), ':');
+
+ if (p == NULL)
+ {
+ DEBUG(0,("getsmbfilepwent: no ':' separator found\n"));
+ continue;
+ }
+
+ /* Go past ':' */
+ p++;
+
+ /* Get smb uid. */
+
+ p = Atoic( p, &uidval, ":");
+
+ pw_buf.unix_name = unix_name;
+ pw_buf.unix_uid = uidval;
+
+ /*
+ * Now get the password value - this should be 32 hex digits
+ * which are the ascii representations of a 16 byte string.
+ * Get two at a time and put them into the password.
+ */
+
+ /* Skip the ':' */
+ p++;
+
+ if (linebuf_len < (PTR_DIFF(p, linebuf) + 33))
+ {
+ DEBUG(0, ("getsmbfilepwent: malformed password entry (passwd too short)\n"));
+ continue;
+ }
+
+ if (p[32] != ':')
+ {
+ DEBUG(0, ("getsmbfilepwent: malformed password entry (no terminating :)\n"));
+ continue;
+ }
+
+ if (!strncasecmp( p, "NO PASSWORD", 11))
+ {
+ pw_buf.smb_passwd = NULL;
+ pw_buf.acct_ctrl |= ACB_PWNOTREQ;
+ }
+ else
+ {
+ if (!pwdb_gethexpwd(p, (char *)smbpwd, NULL))
+ {
+ DEBUG(0, ("getsmbfilepwent: Malformed Lanman password entry (non hex chars)\n"));
+ continue;
+ }
+ pw_buf.smb_passwd = smbpwd;
+ }
+
+ /*
+ * Now check if the NT compatible password is
+ * available.
+ */
+ pw_buf.smb_nt_passwd = NULL;
+
+ /* Move to the first character of the line after the lanman password. */
+ p += 33;
+ if ((linebuf_len >= (PTR_DIFF(p, linebuf) + 33)) && (p[32] == ':'))
+ {
+ if (*p != '*' && *p != 'X')
+ {
+ if(pwdb_gethexpwd(p,(char *)smbntpwd, NULL))
+ {
+ pw_buf.smb_nt_passwd = smbntpwd;
+ }
+ }
+ /* Move to the first character of the line after the NT password. */
+ p += 33;
+ }
+
+ DEBUG(5,("getsmbfilepwent: returning passwd entry for unix user %s, unix uid %d\n",
+ unix_name, uidval));
+
+ if (*p == '[')
+ {
+ pw_buf.acct_ctrl = pwdb_decode_acct_ctrl((char*)p);
+
+ /* Must have some account type set. */
+ if (pw_buf.acct_ctrl == 0)
+ {
+ pw_buf.acct_ctrl = ACB_NORMAL;
+ }
+
+ /* Now try and get the last change time. */
+ while (*p != ']' && *p != ':')
+ {
+ p++;
+ }
+ if (*p == ']')
+ {
+ p++;
+ }
+ if (*p == ':')
+ {
+ p++;
+ pw_buf.pass_last_set_time = pwdb_get_last_set_time(p);
+ }
+ }
+ else
+ {
+ /* 'Old' style file. Fake up based on user name. */
+ /*
+ * Currently trust accounts are kept in the same
+ * password file as 'normal accounts'. If this changes
+ * we will have to fix this code. JRA.
+ */
+ if (pw_buf.unix_name[strlen(pw_buf.unix_name) - 1] == '$')
+ {
+ pw_buf.acct_ctrl &= ~ACB_NORMAL;
+ pw_buf.acct_ctrl |= ACB_WSTRUST;
+ }
+ }
+
+ if (*p == '*' || *p == 'X')
+ {
+ /* Password deliberately invalid - end here. */
+ DEBUG(10, ("getsmbfilepwent: entry invalidated for unix user %s\n", unix_name));
+ pw_buf.smb_nt_passwd = NULL;
+ pw_buf.smb_passwd = NULL;
+ pw_buf.acct_ctrl |= ACB_DISABLED;
+ }
+
+ DEBUG(6,("unixuser:%s uid:%d acb:%x\n",
+ pw_buf.unix_name, pw_buf.unix_uid, pw_buf.acct_ctrl));
+
+ return &pw_buf;
+ }
- return new_entry;
+ DEBUG(5,("getsmbfilepwent: end of file reached.\n"));
+ return NULL;
}
/************************************************************************
@@ -608,11 +264,15 @@ static BOOL add_smbfilepwd_entry(struct smb_passwd *newpwd)
char *pfile = lp_smb_passwd_file();
struct smb_passwd *pwd = NULL;
FILE *fp = NULL;
+
+ int i;
int wr_len;
+
int fd;
- size_t new_entry_length;
+ int new_entry_length;
char *new_entry;
SMB_OFF_T offpos;
+ char *p;
/* Open the smbpassword file - for update. */
fp = startsmbfilepwent(True);
@@ -627,8 +287,8 @@ static BOOL add_smbfilepwd_entry(struct smb_passwd *newpwd)
*/
while ((pwd = getsmbfilepwent(fp)) != NULL) {
- if (strequal(newpwd->smb_name, pwd->smb_name)) {
- DEBUG(0, ("add_smbfilepwd_entry: entry with name %s already exists\n", pwd->smb_name));
+ if (strequal(newpwd->unix_name, pwd->unix_name)) {
+ DEBUG(0, ("add_smbfilepwd_entry: entry with unix name %s already exists\n", pwd->unix_name));
endsmbfilepwent(fp);
return False;
}
@@ -645,34 +305,72 @@ static BOOL add_smbfilepwd_entry(struct smb_passwd *newpwd)
if((offpos = sys_lseek(fd, 0, SEEK_END)) == -1) {
DEBUG(0, ("add_smbfilepwd_entry(sys_lseek): Failed to add entry for user %s to file %s. \
-Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
+Error was %s\n", newpwd->unix_name, pfile, strerror(errno)));
endsmbfilepwent(fp);
return False;
}
- if((new_entry = format_new_smbpasswd_entry(newpwd)) == NULL) {
+ new_entry_length = strlen(newpwd->unix_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2;
+
+ if((new_entry = (char *)malloc( new_entry_length )) == NULL) {
DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \
-Error was %s\n", newpwd->smb_name, pfile, strerror(errno)));
+Error was %s\n", newpwd->unix_name, pfile, strerror(errno)));
endsmbfilepwent(fp);
return False;
}
- new_entry_length = strlen(new_entry);
+ slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->unix_name, (unsigned)newpwd->unix_uid);
+ p = &new_entry[strlen(new_entry)];
+
+ if(newpwd->smb_passwd != NULL) {
+ for( i = 0; i < 16; i++) {
+ slprintf((char *)&p[i*2], new_entry_length - (p - new_entry) - 1, "%02X", newpwd->smb_passwd[i]);
+ }
+ } else {
+ i=0;
+ if(newpwd->acct_ctrl & ACB_PWNOTREQ)
+ safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
+ else
+ safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
+ }
+
+ p += 32;
+
+ *p++ = ':';
+
+ if(newpwd->smb_nt_passwd != NULL) {
+ for( i = 0; i < 16; i++) {
+ slprintf((char *)&p[i*2], new_entry_length - 1 - (p - new_entry), "%02X", newpwd->smb_nt_passwd[i]);
+ }
+ } else {
+ if(newpwd->acct_ctrl & ACB_PWNOTREQ)
+ safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
+ else
+ safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry));
+ }
+
+ p += 32;
+
+ *p++ = ':';
+
+ /* Add the account encoding and the last change time. */
+ slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n",
+ pwdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32)time(NULL));
#ifdef DEBUG_PASSWORD
- DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d made line |%s|",
- fd, new_entry_length, new_entry));
+ DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d entry_len %d made line |%s|",
+ fd, new_entry_length, strlen(new_entry), new_entry));
#endif
- if ((wr_len = write(fd, new_entry, new_entry_length)) != new_entry_length) {
+ if ((wr_len = write(fd, new_entry, strlen(new_entry))) != strlen(new_entry)) {
DEBUG(0, ("add_smbfilepwd_entry(write): %d Failed to add entry for user %s to file %s. \
-Error was %s\n", wr_len, newpwd->smb_name, pfile, strerror(errno)));
+Error was %s\n", wr_len, newpwd->unix_name, pfile, strerror(errno)));
/* Remove the entry we just wrote. */
if(sys_ftruncate(fd, offpos) == -1) {
DEBUG(0, ("add_smbfilepwd_entry: ERROR failed to ftruncate file %s. \
Error was %s. Password file may be corrupt ! Please examine by hand !\n",
- newpwd->smb_name, strerror(errno)));
+ newpwd->unix_name, strerror(errno)));
}
endsmbfilepwent(fp);
@@ -697,7 +395,7 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n",
static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
{
/* Static buffers we will return. */
- static pstring user_name;
+ static pstring unix_name;
char linebuf[256];
char readbuf[1024];
@@ -718,6 +416,17 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
int wr_len;
int fd;
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("mod_smbfilepwd_entry: password entries\n"));
+ if (pwd->smb_passwd != NULL)
+ {
+ dump_data(100, pwd->smb_passwd, 16);
+ }
+ if (pwd->smb_nt_passwd != NULL)
+ {
+ dump_data(100, pwd->smb_nt_passwd, 16);
+ }
+#endif
if (!*pfile) {
DEBUG(0, ("No SMB password file set\n"));
return False;
@@ -735,7 +444,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
lockfd = fileno(fp);
- if (!pw_file_lock(lockfd, F_WRLCK, 5, &pw_file_lock_depth)) {
+ if (!file_lock(lockfd, F_WRLCK, 5, &pw_file_lock_depth)) {
DEBUG(0, ("mod_smbfilepwd_entry: unable to lock file %s\n", pfile));
fclose(fp);
return False;
@@ -755,7 +464,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
fgets(linebuf, sizeof(linebuf), fp);
if (ferror(fp)) {
- pw_file_unlock(lockfd, &pw_file_lock_depth);
+ file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -815,16 +524,16 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
* As 256 is shorter than a pstring we don't need to check
* length here - if this ever changes....
*/
- strncpy(user_name, linebuf, PTR_DIFF(p, linebuf));
- user_name[PTR_DIFF(p, linebuf)] = '\0';
- if (strequal(user_name, pwd->smb_name)) {
+ strncpy(unix_name, linebuf, PTR_DIFF(p, linebuf));
+ unix_name[PTR_DIFF(p, linebuf)] = '\0';
+ if (strequal(unix_name, pwd->unix_name)) {
found_entry = True;
break;
}
}
if (!found_entry) {
- pw_file_unlock(lockfd, &pw_file_lock_depth);
+ file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -836,7 +545,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
if (!isdigit(*p)) {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (uid not number)\n"));
- pw_file_unlock(lockfd, &pw_file_lock_depth);
+ file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -845,7 +554,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
p++;
if (*p != ':') {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no : after uid)\n"));
- pw_file_unlock(lockfd, &pw_file_lock_depth);
+ file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -862,28 +571,28 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
if (!override && (*p == '*' || *p == 'X')) {
/* Password deliberately invalid - end here. */
- DEBUG(10, ("mod_smbfilepwd_entry: entry invalidated for user %s\n", user_name));
- pw_file_unlock(lockfd, &pw_file_lock_depth);
+ DEBUG(10, ("mod_smbfilepwd_entry: entry invalidated for unix user %s\n", unix_name));
+ file_unlock(lockfd, &pw_file_lock_depth);
fclose(fp);
return False;
}
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n"));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return (False);
}
if (p[32] != ':') {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n"));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
if (!override && (*p == '*' || *p == 'X')) {
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -894,14 +603,14 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
the lanman password. */
if (linebuf_len < (PTR_DIFF(p, linebuf) + 33)) {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (passwd too short)\n"));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return (False);
}
if (p[32] != ':') {
DEBUG(0, ("mod_smbfilepwd_entry: malformed password entry (no terminating :)\n"));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -939,7 +648,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
* acct ctrl field. Encode the given acct ctrl
* bits into it.
*/
- fstrcpy(encode_bits, pdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
+ fstrcpy(encode_bits, pwdb_encode_acct_ctrl(pwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN));
} else {
/*
* If using the old format and the ACB_DISABLED or
@@ -1029,7 +738,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
if(wr_len > sizeof(linebuf)) {
DEBUG(0, ("mod_smbfilepwd_entry: line to write (%d) is too long.\n", wr_len+1));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return (False);
}
@@ -1047,7 +756,7 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
if (sys_lseek(fd, pwd_seekpos - 1, SEEK_SET) != pwd_seekpos - 1) {
DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
@@ -1055,189 +764,50 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override)
/* Sanity check - ensure the areas we are writing are framed by ':' */
if (read(fd, linebuf, wr_len+1) != wr_len+1) {
DEBUG(0, ("mod_smbfilepwd_entry: read fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
if ((linebuf[0] != ':') || (linebuf[wr_len] != ':')) {
DEBUG(0, ("mod_smbfilepwd_entry: check on passwd file %s failed.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
if (sys_lseek(fd, pwd_seekpos, SEEK_SET) != pwd_seekpos) {
DEBUG(0, ("mod_smbfilepwd_entry: seek fail on file %s.\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
if (write(fd, ascii_p16, wr_len) != wr_len) {
DEBUG(0, ("mod_smbfilepwd_entry: write failed in passwd file %s\n", pfile));
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return False;
}
- pw_file_unlock(lockfd,&pw_file_lock_depth);
+ file_unlock(lockfd,&pw_file_lock_depth);
fclose(fp);
return True;
}
-/************************************************************************
- Routine to delete an entry in the smbpasswd file by name.
-*************************************************************************/
-
-static BOOL del_smbfilepwd_entry(const char *name)
-{
- char *pfile = lp_smb_passwd_file();
- pstring pfile2;
- struct smb_passwd *pwd = NULL;
- FILE *fp = NULL;
- FILE *fp_write = NULL;
- int pfile2_lockdepth = 0;
-
- slprintf(pfile2, sizeof(pfile2)-1, "%s.%u", pfile, (unsigned)getpid() );
-
- /*
- * Open the smbpassword file - for update. It needs to be update
- * as we need any other processes to wait until we have replaced
- * it.
- */
-
- if((fp = startsmbfilepwent(True)) == NULL) {
- DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));
- return False;
- }
-
- /*
- * Create the replacement password file.
- */
- if((fp_write = startsmbfilepwent_internal(pfile2, PWF_CREATE, &pfile2_lockdepth)) == NULL) {
- DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile));
- endsmbfilepwent(fp);
- return False;
- }
-
- /*
- * Scan the file, a line at a time and check if the name matches.
- */
-
- while ((pwd = getsmbfilepwent(fp)) != NULL) {
- char *new_entry;
- size_t new_entry_length;
-
- if (strequal(name, pwd->smb_name)) {
- DEBUG(10, ("add_smbfilepwd_entry: found entry with name %s - deleting it.\n", name));
- continue;
- }
-
- /*
- * We need to copy the entry out into the second file.
- */
-
- if((new_entry = format_new_smbpasswd_entry(pwd)) == NULL) {
- DEBUG(0, ("del_smbfilepwd_entry(malloc): Failed to copy entry for user %s to file %s. \
-Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
- unlink(pfile2);
- endsmbfilepwent(fp);
- endsmbfilepwent_internal(fp_write,&pfile2_lockdepth);
- return False;
- }
-
- new_entry_length = strlen(new_entry);
-
- if(fwrite(new_entry, 1, new_entry_length, fp_write) != new_entry_length) {
- DEBUG(0, ("del_smbfilepwd_entry(write): Failed to copy entry for user %s to file %s. \
-Error was %s\n", pwd->smb_name, pfile2, strerror(errno)));
- unlink(pfile2);
- endsmbfilepwent(fp);
- endsmbfilepwent_internal(fp_write,&pfile2_lockdepth);
- free(new_entry);
- return False;
- }
-
- free(new_entry);
- }
-
- /*
- * Ensure pfile2 is flushed before rename.
- */
-
- if(fflush(fp_write) != 0) {
- DEBUG(0, ("del_smbfilepwd_entry: Failed to flush file %s. Error was %s\n", pfile2, strerror(errno)));
- endsmbfilepwent(fp);
- endsmbfilepwent_internal(fp_write,&pfile2_lockdepth);
- return False;
- }
-
- /*
- * Do an atomic rename - then release the locks.
- */
-
- if(rename(pfile2,pfile) != 0) {
- unlink(pfile2);
- }
- endsmbfilepwent(fp);
- endsmbfilepwent_internal(fp_write,&pfile2_lockdepth);
- return True;
-}
-
-/*
- * Stub functions - implemented in terms of others.
- */
-
-static BOOL mod_smbfile21pwd_entry(struct sam_passwd* pwd, BOOL override)
-{
- return mod_smbfilepwd_entry(pdb_sam_to_smb(pwd), override);
-}
-
-static BOOL add_smbfile21pwd_entry(struct sam_passwd *newpwd)
-{
- return add_smbfilepwd_entry(pdb_sam_to_smb(newpwd));
-}
-
-static struct sam_disp_info *getsmbfiledispnam(char *name)
-{
- return pdb_sam_to_dispinfo(getsam21pwnam(name));
-}
-
-static struct sam_disp_info *getsmbfiledisprid(uint32 rid)
-{
- return pdb_sam_to_dispinfo(getsam21pwrid(rid));
-}
-
-static struct sam_disp_info *getsmbfiledispent(void *vp)
-{
- return pdb_sam_to_dispinfo(getsam21pwent(vp));
-}
-
-static struct passdb_ops file_ops = {
+static struct smb_passdb_ops file_ops = {
startsmbfilepwent,
endsmbfilepwent,
getsmbfilepwpos,
setsmbfilepwpos,
iterate_getsmbpwnam, /* In passdb.c */
iterate_getsmbpwuid, /* In passdb.c */
- iterate_getsmbpwrid, /* In passdb.c */
getsmbfilepwent,
add_smbfilepwd_entry,
- mod_smbfilepwd_entry,
- del_smbfilepwd_entry,
- getsmbfile21pwent,
- iterate_getsam21pwnam,
- iterate_getsam21pwuid,
- iterate_getsam21pwrid,
- add_smbfile21pwd_entry,
- mod_smbfile21pwd_entry,
- getsmbfiledispnam,
- getsmbfiledisprid,
- getsmbfiledispent
+ mod_smbfilepwd_entry
};
-struct passdb_ops *file_initialize_password_db(void)
+struct smb_passdb_ops *file_initialise_password_db(void)
{
return &file_ops;
}
diff --git a/source/passdb/smbpasschange.c b/source/passdb/smbpasschange.c
index 0348a2b97b1..a0d9b1b1435 100644
--- a/source/passdb/smbpasschange.c
+++ b/source/passdb/smbpasschange.c
@@ -25,112 +25,121 @@
/*************************************************************
add a new user to the local smbpasswd file
*************************************************************/
-
-static BOOL add_new_user(char *user_name, uid_t uid, int local_flags,
- uchar *new_p16, uchar *new_nt_p16)
+static BOOL add_new_user(char *user_name, uid_t uid,
+ uint16 acb_info,
+ uchar *new_p16, uchar *new_nt_p16)
{
struct smb_passwd new_smb_pwent;
+ pwdb_init_smb(&new_smb_pwent);
+
/* Create a new smb passwd entry and set it to the given password. */
- new_smb_pwent.smb_userid = uid;
- new_smb_pwent.smb_name = user_name;
+ new_smb_pwent.unix_uid = uid;
+ new_smb_pwent.nt_name = user_name;
new_smb_pwent.smb_passwd = NULL;
new_smb_pwent.smb_nt_passwd = NULL;
- new_smb_pwent.acct_ctrl = ((local_flags & LOCAL_TRUST_ACCOUNT) ? ACB_WSTRUST : ACB_NORMAL);
+ new_smb_pwent.acct_ctrl = acb_info;
- if(local_flags & LOCAL_DISABLE_USER) {
- new_smb_pwent.acct_ctrl |= ACB_DISABLED;
- } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
- new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ;
- } else {
+ if (IS_BITS_CLR_ALL(acb_info, ACB_DISABLED | ACB_PWNOTREQ))
+ {
new_smb_pwent.smb_passwd = new_p16;
new_smb_pwent.smb_nt_passwd = new_nt_p16;
}
-
return add_smbpwd_entry(&new_smb_pwent);
}
/*************************************************************
-change a password entry in the local smbpasswd file
-*************************************************************/
+change a password entry in the local smbpasswd file.
-BOOL local_password_change(char *user_name, int local_flags,
- char *new_passwd,
- char *err_str, size_t err_str_len,
- char *msg_str, size_t msg_str_len)
+when modifying an account, set acb_mask to those bits that
+require changing (to zero or one) and set acb_info to the
+value required in those bits. all bits NOT set in acb_mask
+will NOT be modified.
+
+when _adding_ an account, acb_mask must be set to 0xFFFF and
+it is ignored, btw :-)
+
+*************************************************************/
+BOOL local_password_change(char *user_name,
+ BOOL add_user,
+ uint16 acb_info, uint16 acb_mask,
+ char *new_passwd,
+ char *err_str, size_t err_str_len,
+ char *msg_str, size_t msg_str_len)
{
- struct passwd *pwd = NULL;
- void *vp;
+ const struct passwd *pwd;
struct smb_passwd *smb_pwent;
- uchar new_p16[16];
- uchar new_nt_p16[16];
+ static struct smb_passwd new_pwent;
+ static uchar new_p16[16];
+ static uchar new_nt_p16[16];
+ fstring unix_name;
+ uid_t unix_uid;
*err_str = '\0';
*msg_str = '\0';
- if (local_flags & LOCAL_ADD_USER) {
+ pwd = Get_Pwnam(user_name, False);
- /*
- * Check for a local account - if we're adding only.
- */
+ /*
+ * Check for a trust account.
+ */
- if(!(pwd = sys_getpwnam(user_name))) {
+ if ((acb_info & acb_mask) != acb_info)
+ {
+ slprintf(err_str, err_str_len - 1, "programmer error: acb_info (%x) requests bits to be set outside of acb_mask (%x) range\n", acb_info, acb_mask);
+ }
+
+ if (pwd == NULL)
+ {
+ if (!IS_BITS_SET_ALL(acb_info, ACB_NORMAL))
+ {
slprintf(err_str, err_str_len - 1, "User %s does not \
-exist in system password file (usually /etc/passwd). Cannot add \
-account without a valid local system user.\n", user_name);
- return False;
+exist in system password file (usually /etc/passwd). \
+Cannot add trust account without a valid system user.\n", user_name);
}
+ else
+ {
+ slprintf(err_str, err_str_len - 1, "User %s does not \
+exist in system password file (usually /etc/passwd).\n", user_name);
+ }
+ return False;
}
+ unix_uid = pwd->pw_uid;
+ fstrcpy(unix_name, pwd->pw_name);
+
/* Calculate the MD4 hash (NT compatible) of the new password. */
nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
- /*
- * Open the smbpaswd file.
- */
- vp = startsmbpwent(True);
- if (!vp && errno == ENOENT) {
- FILE *fp;
- slprintf(msg_str,msg_str_len-1,
- "smbpasswd file did not exist - attempting to create it.\n");
- fp = sys_fopen(lp_smb_passwd_file(), "w");
- if (fp) {
- fprintf(fp, "# Samba SMB password file\n");
- fclose(fp);
- vp = startsmbpwent(True);
- }
- }
-
- if (!vp) {
- slprintf(err_str, err_str_len-1, "Cannot open file %s. Error was %s\n",
- lp_smb_passwd_file(), strerror(errno) );
- return False;
- }
-
/* Get the smb passwd entry for this user */
smb_pwent = getsmbpwnam(user_name);
- if (smb_pwent == NULL) {
- if(!(local_flags & LOCAL_ADD_USER)) {
+ if (smb_pwent == NULL)
+ {
+ if (!add_user)
+ {
slprintf(err_str, err_str_len-1,
- "Failed to find entry for user %s.\n", user_name);
- endsmbpwent(vp);
+ "Failed to find entry for user %s.\n", unix_name);
return False;
}
- if (add_new_user(user_name, pwd->pw_uid, local_flags, new_p16, new_nt_p16)) {
+ if (add_new_user(user_name, unix_uid, acb_info,
+ new_p16, new_nt_p16))
+ {
slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name);
- endsmbpwent(vp);
return True;
- } else {
+ }
+ else
+ {
slprintf(err_str, err_str_len-1, "Failed to add entry for user %s.\n", user_name);
- endsmbpwent(vp);
return False;
}
- } else {
+ }
+ else
+ {
/* the entry already existed */
- local_flags &= ~LOCAL_ADD_USER;
+ add_user = False;
}
/*
@@ -138,58 +147,25 @@ account without a valid local system user.\n", user_name);
* and the valid last change time.
*/
- if(local_flags & LOCAL_DISABLE_USER) {
- smb_pwent->acct_ctrl |= ACB_DISABLED;
- } else if (local_flags & LOCAL_ENABLE_USER) {
- if(smb_pwent->smb_passwd == NULL) {
- smb_pwent->smb_passwd = new_p16;
- smb_pwent->smb_nt_passwd = new_nt_p16;
- }
- smb_pwent->acct_ctrl &= ~ACB_DISABLED;
- } else if (local_flags & LOCAL_SET_NO_PASSWORD) {
- smb_pwent->acct_ctrl |= ACB_PWNOTREQ;
- /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */
- smb_pwent->smb_passwd = NULL;
- smb_pwent->smb_nt_passwd = NULL;
- } else {
- /*
- * If we're dealing with setting a completely empty user account
- * ie. One with a password of 'XXXX', but not set disabled (like
- * an account created from scratch) then if the old password was
- * 'XX's then getsmbpwent will have set the ACB_DISABLED flag.
- * We remove that as we're giving this user their first password
- * and the decision hasn't really been made to disable them (ie.
- * don't create them disabled). JRA.
- */
- if((smb_pwent->smb_passwd == NULL) && (smb_pwent->acct_ctrl & ACB_DISABLED))
- smb_pwent->acct_ctrl &= ~ACB_DISABLED;
- smb_pwent->acct_ctrl &= ~ACB_PWNOTREQ;
- smb_pwent->smb_passwd = new_p16;
- smb_pwent->smb_nt_passwd = new_nt_p16;
+ memcpy(&new_pwent, smb_pwent, sizeof(new_pwent));
+ new_pwent.nt_name = user_name;
+ new_pwent.acct_ctrl &= ~acb_mask;
+ new_pwent.acct_ctrl |= (acb_info & acb_mask);
+ new_pwent.smb_passwd = NULL;
+ new_pwent.smb_nt_passwd = NULL;
+
+ if (IS_BITS_CLR_ALL(acb_info, ACB_DISABLED | ACB_PWNOTREQ))
+ {
+ new_pwent.smb_passwd = new_p16;
+ new_pwent.smb_nt_passwd = new_nt_p16;
}
- if(local_flags & LOCAL_DELETE_USER) {
- if (del_smbpwd_entry(user_name)==False) {
- slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name);
- endsmbpwent(vp);
- return False;
- }
- slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name);
- } else {
- if(mod_smbpwd_entry(smb_pwent,True) == False) {
- slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name);
- endsmbpwent(vp);
- return False;
- }
- if(local_flags & LOCAL_DISABLE_USER)
- slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name);
- else if (local_flags & LOCAL_ENABLE_USER)
- slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name);
- else if (local_flags & LOCAL_SET_NO_PASSWORD)
- slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name);
+ if (!mod_smbpwd_entry(&new_pwent, True))
+ {
+ slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n",
+ unix_name);
+ return False;
}
- endsmbpwent(vp);
-
return True;
}
diff --git a/source/passdb/smbpassfile.c b/source/passdb/smbpassfile.c
index bbe24131b8e..806932fe351 100644
--- a/source/passdb/smbpassfile.c
+++ b/source/passdb/smbpassfile.c
@@ -22,60 +22,20 @@
extern int DEBUGLEVEL;
BOOL global_machine_password_needs_changing = False;
-
-/***************************************************************
- Lock an fd. Abandon after waitsecs seconds.
-****************************************************************/
-
-BOOL pw_file_lock(int fd, int type, int secs, int *plock_depth)
-{
- if (fd < 0)
- return False;
-
- if(*plock_depth == 0) {
- if (!do_file_lock(fd, secs, type)) {
- DEBUG(10,("pw_file_lock: locking file failed, error = %s.\n",
- strerror(errno)));
- return False;
- }
- }
-
- (*plock_depth)++;
-
- return True;
-}
-
-/***************************************************************
- Unlock an fd. Abandon after waitsecs seconds.
-****************************************************************/
-
-BOOL pw_file_unlock(int fd, int *plock_depth)
-{
- BOOL ret=True;
-
- if(*plock_depth == 1)
- ret = do_file_lock(fd, 5, F_UNLCK);
-
- if (*plock_depth > 0)
- (*plock_depth)--;
-
- if(!ret)
- DEBUG(10,("pw_file_unlock: unlocking file failed, error = %s.\n",
- strerror(errno)));
- return ret;
-}
-
-static int mach_passwd_lock_depth;
-static FILE *mach_passwd_fp;
+static int mach_passwd_lock_depth = 0;
+static FILE *mach_passwd_fp = NULL;
/************************************************************************
Routine to get the name for a trust account file.
************************************************************************/
-static void get_trust_account_file_name( char *domain, char *name, char *mac_file)
+static void get_trust_account_file_name( const char *domain, const char *name,
+ char *mac_file)
{
unsigned int mac_file_len;
char *p;
+ fstring dom_name;
+ fstring trust_name;
pstrcpy(mac_file, lp_smb_passwd_file());
p = strrchr(mac_file, '/');
@@ -86,22 +46,29 @@ static void get_trust_account_file_name( char *domain, char *name, char *mac_fil
if ((int)(sizeof(pstring) - mac_file_len - strlen(domain) - strlen(name) - 6) < 0)
{
- DEBUG(0,("trust_password_lock: path %s too long to add trust details.\n",
+ DEBUG(0,("get_trust_account_file_name: path %s too long to add trust details.\n",
mac_file));
return;
}
- pstrcat(mac_file, domain);
+ fstrcpy(dom_name, domain);
+ strupper(dom_name);
+ fstrcpy(trust_name, name);
+ strupper(trust_name);
+
+ pstrcat(mac_file, dom_name);
pstrcat(mac_file, ".");
- pstrcat(mac_file, name);
+ pstrcat(mac_file, trust_name);
pstrcat(mac_file, ".mac");
+
+ DEBUG(5,("trust_account_file_name: %s\n", mac_file));
}
/************************************************************************
Routine to lock the trust account password file for a domain.
************************************************************************/
-BOOL trust_password_lock( char *domain, char *name, BOOL update)
+BOOL trust_password_lock( const char *domain, const char *name, BOOL update)
{
pstring mac_file;
@@ -123,7 +90,7 @@ BOOL trust_password_lock( char *domain, char *name, BOOL update)
chmod(mac_file, 0600);
- if(!pw_file_lock(fileno(mach_passwd_fp), (update ? F_WRLCK : F_RDLCK),
+ if(!file_lock(fileno(mach_passwd_fp), (update ? F_WRLCK : F_RDLCK),
60, &mach_passwd_lock_depth))
{
DEBUG(0,("trust_password_lock: cannot lock file %s\n", mac_file));
@@ -142,7 +109,7 @@ BOOL trust_password_lock( char *domain, char *name, BOOL update)
BOOL trust_password_unlock(void)
{
- BOOL ret = pw_file_unlock(fileno(mach_passwd_fp), &mach_passwd_lock_depth);
+ BOOL ret = file_unlock(fileno(mach_passwd_fp), &mach_passwd_lock_depth);
if(mach_passwd_lock_depth == 0)
fclose(mach_passwd_fp);
return ret;
@@ -165,11 +132,9 @@ BOOL trust_password_delete( char *domain, char *name )
The user of this function must have locked the trust password file.
************************************************************************/
-BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_time)
+BOOL get_trust_account_password( uchar *ret_pwd, time_t *pass_last_set_time)
{
char linebuf[256];
- char *p;
- int i;
linebuf[0] = '\0';
@@ -199,7 +164,7 @@ BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_t
if(strlen(linebuf) != 45) {
DEBUG(0,("get_trust_account_password: Malformed trust password file (wrong length \
-- was %d, should be 45).\n", (int)strlen(linebuf)));
+- was %d, should be 45).\n", strlen(linebuf)));
#ifdef DEBUG_PASSWORD
DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
#endif
@@ -210,8 +175,9 @@ BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_t
* Get the hex password.
*/
- if (!pdb_gethexpwd((char *)linebuf, ret_pwd) || linebuf[32] != ':' ||
- strncmp(&linebuf[33], "TLC-", 4)) {
+ if (!pwdb_gethexpwd((char *)linebuf, (char *)ret_pwd, NULL) ||
+ linebuf[32] != ':')
+ {
DEBUG(0,("get_trust_account_password: Malformed trust password file (incorrect format).\n"));
#ifdef DEBUG_PASSWORD
DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
@@ -219,29 +185,25 @@ BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_t
return False;
}
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("get_trust_account_password:"));
+ dump_data(100, ret_pwd, 16);
+#endif
/*
* Get the last changed time.
*/
- p = &linebuf[37];
- for(i = 0; i < 8; i++) {
- if(p[i] == '\0' || !isxdigit((int)p[i])) {
+ (*pass_last_set_time) = pwdb_get_time_last_changed(&linebuf[33]);
+
+ if ((*pass_last_set_time) == -1)
+ {
DEBUG(0,("get_trust_account_password: Malformed trust password file (no timestamp).\n"));
#ifdef DEBUG_PASSWORD
DEBUG(100,("get_trust_account_password: line = |%s|\n", linebuf));
#endif
return False;
- }
}
- /*
- * p points at 8 characters of hex digits -
- * read into a time_t as the seconds since
- * 1970 that the password was last changed.
- */
-
- *pass_last_set_time = (time_t)strtol(p, NULL, 16);
-
return True;
}
@@ -250,10 +212,9 @@ BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_t
The user of this function must have locked the trust password file.
************************************************************************/
-BOOL set_trust_account_password( unsigned char *md4_new_pwd)
+BOOL set_trust_account_password( uchar *md4_new_pwd)
{
char linebuf[64];
- int i;
if(sys_fseek( mach_passwd_fp, (SMB_OFF_T)0, SEEK_SET) == -1) {
DEBUG(0,("set_trust_account_password: Failed to seek to start of file. Error was %s.\n",
@@ -261,10 +222,9 @@ BOOL set_trust_account_password( unsigned char *md4_new_pwd)
return False;
}
- for (i = 0; i < 16; i++)
- slprintf(&linebuf[(i*2)], sizeof(linebuf) - (i*2) - 1, "%02X", md4_new_pwd[i]);
-
- slprintf(&linebuf[32], 32, ":TLC-%08X\n", (unsigned)time(NULL));
+ pwdb_sethexpwd((char *)linebuf, (uchar*)md4_new_pwd, 0);
+ pwdb_set_time_last_changed(&linebuf[32], 32, (unsigned)time(NULL));
+ linebuf[45] = '\n';
if(fwrite( linebuf, 1, 46, mach_passwd_fp)!= 46) {
DEBUG(0,("set_trust_account_password: Failed to write file. Warning - the trust \
@@ -276,22 +236,52 @@ account is now invalid. Please recreate. Error was %s.\n", strerror(errno) ));
return True;
}
-BOOL trust_get_passwd( unsigned char trust_passwd[16], char *domain, char *myname)
+BOOL trust_get_passwd_time( uchar trust_passwd[16],
+ const char *domain, const char *myname,
+ NTTIME *modtime)
+{
+ time_t lct;
+
+ /*
+ * Get the trust account password.
+ */
+ if(!trust_password_lock( domain, myname, False)) {
+ DEBUG(0,("trust_get_passwd: unable to open the trust account password file for \
+trust %s in domain %s.\n", myname, domain ));
+ return False;
+ }
+
+ if(get_trust_account_password( trust_passwd, &lct) == False) {
+ DEBUG(0,("trust_get_passwd: unable to read the trust account password for \
+trust %s in domain %s.\n", myname, domain ));
+ trust_password_unlock();
+ return False;
+ }
+
+ trust_password_unlock();
+
+ unix_to_nt_time(modtime, lct);
+
+ return True;
+}
+
+BOOL trust_get_passwd( uchar trust_passwd[16],
+ const char *domain, const char *myname)
{
time_t lct;
/*
- * Get the machine account password.
+ * Get the trust account password.
*/
if(!trust_password_lock( domain, myname, False)) {
- DEBUG(0,("domain_client_validate: unable to open the machine account password file for \
-machine %s in domain %s.\n", myname, domain ));
+ DEBUG(0,("trust_get_passwd: unable to open the trust account password file for \
+trust %s in domain %s.\n", myname, domain ));
return False;
}
if(get_trust_account_password( trust_passwd, &lct) == False) {
- DEBUG(0,("domain_client_validate: unable to read the machine account password for \
-machine %s in domain %s.\n", myname, domain ));
+ DEBUG(0,("trust_get_passwd: unable to read the trust account password for \
+trust %s in domain %s.\n", myname, domain ));
trust_password_unlock();
return False;
}
@@ -299,7 +289,7 @@ machine %s in domain %s.\n", myname, domain ));
trust_password_unlock();
/*
- * Here we check the last change time to see if the machine
+ * Here we check the last change time to see if the trust
* password needs changing. JRA.
*/
@@ -309,3 +299,36 @@ machine %s in domain %s.\n", myname, domain ));
}
return True;
}
+
+/*********************************************************
+record Trust Account password.
+**********************************************************/
+BOOL create_trust_account_file(char *domain, char *name, uchar pass[16])
+{
+ /*
+ * Create the machine account password file.
+ */
+
+ if (!trust_password_lock( domain, name, True))
+ {
+ DEBUG(0,("unable to open the trust account password file for \
+account %s in domain %s.\n", name, domain));
+ return False;
+ }
+
+ /*
+ * Write the old machine account password.
+ */
+
+ if (!set_trust_account_password( pass))
+ {
+ DEBUG(0,("unable to write the trust account password for \
+%s in domain %s.\n", name, domain));
+ trust_password_unlock();
+ return False;
+ }
+
+ trust_password_unlock();
+
+ return True;
+}
diff --git a/source/passdb/smbpassgroup.c b/source/passdb/smbpassgroup.c
index 4636c08c949..8991cad9783 100644
--- a/source/passdb/smbpassgroup.c
+++ b/source/passdb/smbpassgroup.c
@@ -19,7 +19,7 @@
#include "includes.h"
-#ifdef USE_SMBPASS_DB
+#ifdef USE_SMBGROUP_DB
static int grp_file_lock_depth = 0;
extern int DEBUGLEVEL;
@@ -32,7 +32,7 @@ extern int DEBUGLEVEL;
static void *startsmbfilegrpent(BOOL update)
{
static char s_readbuf[1024];
- return startfilepwent(lp_smb_passgrp_file(), s_readbuf, sizeof(s_readbuf),
+ return startfileent(lp_smb_passgrp_file(), s_readbuf, sizeof(s_readbuf),
&grp_file_lock_depth, update);
}
@@ -42,7 +42,7 @@ static void *startsmbfilegrpent(BOOL update)
static void endsmbfilegrpent(void *vp)
{
- endfilepwent(vp, &grp_file_lock_depth);
+ endfileent(vp, &grp_file_lock_depth);
}
/*************************************************************************
@@ -77,9 +77,8 @@ static struct smb_passwd *getsmbfilegrpent(void *vp,
static pstring user_name;
struct passwd *pwfile;
pstring linebuf;
- unsigned char *p;
+ char *p;
int uidval;
- size_t linebuf_len;
if (vp == NULL)
{
@@ -92,12 +91,12 @@ static struct smb_passwd *getsmbfilegrpent(void *vp,
/*
* Scan the file, a line at a time.
*/
- while ((linebuf_len = getfileline(vp, linebuf, sizeof(linebuf))) > 0)
+ while (getfileline(vp, linebuf, sizeof(linebuf)) > 0)
{
/*
* The line we have should be of the form :-
*
- * username:uid:domainrid1,domainrid2..:aliasrid1,aliasrid2..:
+ * username:uid:aliasrid1,aliasrid2..:domainrid1,domainrid2..:
*/
/*
@@ -106,6 +105,12 @@ static struct smb_passwd *getsmbfilegrpent(void *vp,
*/
p = strncpyn(user_name, linebuf, sizeof(user_name), ':');
+ if (p == NULL)
+ {
+ DEBUG(0,("getsmbfilegrpent: no ':' separator found\n"));
+ continue;
+ }
+
/* Go past ':' */
p++;
@@ -114,48 +119,42 @@ static struct smb_passwd *getsmbfilegrpent(void *vp,
p = Atoic((char *) p, &uidval, ":");
pw_buf.smb_name = user_name;
- pw_buf.smb_userid = uidval;
+ pw_buf.unix_uid = uidval;
/*
- * Now get the password value - this should be 32 hex digits
- * which are the ascii representations of a 16 byte string.
- * Get two at a time and put them into the password.
+ * Now get a list of alias RIDs
*/
/* Skip the ':' */
p++;
- if (grp_rids != NULL && num_grps != NULL)
+ if (als_rids != NULL && num_alss != NULL)
{
int i;
- p = get_numlist(p, grp_rids, num_grps);
+ p = get_numlist(p, als_rids, num_alss);
if (p == NULL)
{
DEBUG(0,("getsmbfilegrpent: invalid line\n"));
return NULL;
}
- for (i = 0; i < (*num_grps); i++)
- {
- (*grp_rids)[i] = pwdb_gid_to_group_rid((*grp_rids)[i]);
- }
}
+ /*
+ * Now get a list of group RIDs
+ */
+
/* Skip the ':' */
p++;
- if (als_rids != NULL && num_alss != NULL)
+ if (grp_rids != NULL && num_grps != NULL)
{
int i;
- p = get_numlist(p, als_rids, num_alss);
+ p = get_numlist(p, grp_rids, num_grps);
if (p == NULL)
{
DEBUG(0,("getsmbfilegrpent: invalid line\n"));
return NULL;
}
- for (i = 0; i < (*num_alss); i++)
- {
- (*als_rids)[i] = pwdb_gid_to_alias_rid((*als_rids)[i]);
- }
}
pwfile = Get_Pwnam(pw_buf.smb_name, False);
@@ -192,5 +191,5 @@ struct passgrp_ops *file_initialise_password_grp(void)
#else
/* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
- void smbpass_dummy_function(void) { } /* stop some compilers complaining */
+ void smbpassgroup_dummy_function(void) { } /* stop some compilers complaining */
#endif /* USE_SMBPASS_DB */
diff --git a/source/passdb/smbpassgroupunix.c b/source/passdb/smbpassgroupunix.c
new file mode 100644
index 00000000000..6898269e6db
--- /dev/null
+++ b/source/passdb/smbpassgroupunix.c
@@ -0,0 +1,227 @@
+/*
+ * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup
+ * Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 675
+ * Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "sids.h"
+
+#ifdef USE_SMBUNIX_DB
+
+extern int DEBUGLEVEL;
+
+/***************************************************************
+ Start to enumerate the smbpasswd list. Returns a void pointer
+ to ensure no modification outside this module.
+****************************************************************/
+
+static void *startsmbunixgrpent(BOOL update)
+{
+ return startsmbpwent(False);
+}
+
+/***************************************************************
+ End enumeration of the smbpasswd list.
+****************************************************************/
+
+static void endsmbunixgrpent(void *vp)
+{
+ endsmbpwent(vp);
+}
+
+/*************************************************************************
+ Return the current position in the smbpasswd list as an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+
+static SMB_BIG_UINT getsmbunixgrppos(void *vp)
+{
+ return getsmbpwpos(vp);
+}
+
+/*************************************************************************
+ Set the current position in the smbpasswd list from an SMB_BIG_UINT.
+ This must be treated as an opaque token.
+*************************************************************************/
+
+static BOOL setsmbunixgrppos(void *vp, SMB_BIG_UINT tok)
+{
+ return setsmbpwpos(vp, tok);
+}
+
+/*************************************************************************
+ Routine to return the next smbpassgroup entry
+ *************************************************************************/
+static struct smb_passwd *getsmbunixgrpent(void *vp,
+ uint32 **grp_rids, int *num_grps,
+ uint32 **als_rids, int *num_alss)
+{
+ /* Static buffers we will return. */
+ struct sam_passwd *pw_buf;
+ fstring unix_name;
+ int i;
+ int unixgrps;
+ gid_t *grps;
+ BOOL failed = False;
+
+ if (vp == NULL)
+ {
+ DEBUG(0,("getsmbunixgrpent: Bad password file pointer.\n"));
+ return NULL;
+ }
+
+ pw_buf = getsam21pwent(vp);
+
+ if (pw_buf == NULL)
+ {
+ return NULL;
+ }
+
+ fstrcpy(unix_name, pw_buf->unix_name);
+
+ if (grp_rids != NULL)
+ {
+ (*grp_rids) = NULL;
+ (*num_grps) = 0;
+ }
+
+ if (als_rids != NULL)
+ {
+ (*als_rids) = NULL;
+ (*num_alss) = 0;
+ }
+
+ if (als_rids == NULL && grp_rids == NULL)
+ {
+ /* they didn't want to know the members. */
+ return pwdb_sam_to_smb(pw_buf);
+ }
+
+ /*
+ * find all unix groups
+ */
+
+ if (get_unixgroups(unix_name, pw_buf->unix_uid, pw_buf->unix_gid, &unixgrps, &grps))
+ {
+ return NULL;
+ }
+
+ /*
+ * check each unix group for a mapping as an nt alias or an nt group
+ */
+
+ for (i = 0; i < unixgrps && !failed; i++)
+ {
+ uint32 rid;
+
+ /*
+ * find the unix name for each user's group.
+ * assume the unix group is an nt name (alias? group? user?)
+ * (user or not our own domain will be an error).
+ *
+ * oh, oh, can anyone spot what's missing heeere?
+ * you guessed it: built-in aliases. those are in
+ * Domain S-1-5-20, and NT Domain Users can only
+ * have lists of RIDs as groups.
+ *
+ * doesn't stop you making NT Domain Users a member
+ * of a BUILTIN Alias (e.g "Administrators" or "Power Users")
+ * it's just that there's no way to tell that from this
+ * API call: wrong domain, sorry.
+ *
+ */
+
+ DOM_NAME_MAP gmep;
+
+ if (!lookupsmbgrpgid(grps[i], &gmep))
+ {
+ continue;
+ }
+
+ sid_split_rid(&gmep.sid, &rid);
+ if (!sid_equal(&global_sam_sid, &gmep.sid))
+ {
+ continue;
+ }
+
+ switch (gmep.type)
+ {
+ case SID_NAME_ALIAS:
+ {
+ if (als_rids != NULL && add_num_to_list(als_rids, num_alss, rid) == NULL)
+ {
+ failed = True;
+ }
+ break;
+ }
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ {
+ if (grp_rids != NULL && add_num_to_list(grp_rids, num_grps, rid) == NULL)
+ {
+ failed = True;
+ }
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ if (failed)
+ {
+ if (grp_rids != NULL && (*grp_rids) != NULL)
+ {
+ free(*grp_rids);
+ (*num_grps) = 0;
+ }
+
+ if (als_rids != NULL && (*als_rids) != NULL)
+ {
+ free(*als_rids);
+ (*num_alss) = 0;
+ }
+
+ return NULL;
+ }
+
+ return pwdb_sam_to_smb(pw_buf);
+}
+
+static struct passgrp_ops smbunixgrp_ops =
+{
+ startsmbunixgrpent,
+ endsmbunixgrpent,
+ getsmbunixgrppos,
+ setsmbunixgrppos,
+ iterate_getsmbgrpntnam, /* In passgrp.c */
+ iterate_getsmbgrpuid, /* In passgrp.c */
+ iterate_getsmbgrprid, /* In passgrp.c */
+ getsmbunixgrpent
+};
+
+struct passgrp_ops *unix_initialise_password_grp(void)
+{
+ return &smbunixgrp_ops;
+}
+
+#else
+ /* Do *NOT* make this function static. It breaks the compile on gcc. JRA */
+ void smbpassgroupunix_dummy_function(void) { } /* stop some compilers complaining */
+#endif /* USE_SMBPASS_DB */
diff --git a/source/passdb/smbpassnt5ldap.c b/source/passdb/smbpassnt5ldap.c
new file mode 100644
index 00000000000..f16be955f9e
--- /dev/null
+++ b/source/passdb/smbpassnt5ldap.c
@@ -0,0 +1,542 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.0.
+ LDAP protocol helper functions for SAMBA
+ Copyright (C) Jean François Micouleau 1998
+ Copyright (C) Matthew Chapman 1998
+ Copyright (C) Luke Howard (PADL Software Pty Ltd) 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+
+#include "includes.h"
+
+#ifdef WITH_NT5LDAP
+
+#include <lber.h>
+#include <ldap.h>
+#include "ldapdb.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+Construct an smb_passwd structure
+******************************************************************/
+struct smb_passwd *
+nt5ldapsmb_getent (LDAPDB * hds)
+{
+ static struct smb_passwd smbpw;
+ static pstring unix_name;
+ static pstring nt_name;
+ static unsigned char smblmpwd[16];
+ static unsigned char smbntpwd[16];
+ pstring temp;
+ NTDS_USER_FLAG_ENUM adac;
+ NTTIME nttime;
+ struct berval *bv = NULL;
+
+ if (!ldapdb_peek (hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_get_pvalue (hds, "uid", unix_name) &&
+ !ldapdb_get_pvalue (hds, "mSSFUName", unix_name))
+ {
+ DEBUG (0, ("SMB user missing uid\n"));
+ return NULL;
+ }
+ else
+ {
+ smbpw.unix_name = unix_name;
+ }
+ DEBUG (2, ("Retrieving account [%s]\n", unix_name));
+
+ if (!ldapdb_get_pvalue (hds, "uidNumber", temp))
+ {
+ DEBUG (0, ("Missing uidNumber\n"));
+ return NULL;
+ }
+ else
+ {
+ smbpw.unix_uid = atoi (temp);
+ }
+
+ if (!ldapdb_get_pvalue (hds, "sAMAccountName", nt_name))
+ {
+ DEBUG (0, ("Missing sAMAccountName\n"));
+ return NULL;
+ }
+ else
+ {
+ smbpw.nt_name = nt_name;
+ }
+
+ if (!ldapdb_get_rid (hds, "objectSid", &smbpw.user_rid))
+ {
+ DEBUG (0, ("Missing objectSid\n"));
+ return NULL;
+ }
+
+ if (ldapdb_get_pvalue (hds, "userAccountControl", temp))
+ {
+ adac = strtol (temp, NULL, 10);
+ smbpw.acct_ctrl = pwdb_acct_ctrl_from_ad (adac);
+ }
+ else
+ {
+ smbpw.acct_ctrl = ACB_NORMAL;
+ }
+
+ if (ldapdb_get_value_len (hds, "dBCSPwd", &bv) &&
+ berval_to_dbcspwd (bv, smblmpwd))
+ {
+ smbpw.smb_passwd = smblmpwd;
+ }
+ else
+ {
+ smbpw.smb_passwd = NULL;
+ smbpw.acct_ctrl |= ACB_DISABLED;
+ }
+
+ if (bv != NULL)
+ {
+ ber_bvfree(bv);
+ bv = NULL;
+ }
+
+ if (ldapdb_get_value_len (hds, "unicodePwd", &bv) &&
+ berval_to_unicodepwd (bv, smblmpwd))
+ {
+ smbpw.smb_nt_passwd = smbntpwd;
+ ber_bvfree (bv);
+ }
+ else
+ {
+ smbpw.smb_nt_passwd = NULL;
+ }
+
+ if (bv != NULL)
+ {
+ ber_bvfree(bv);
+ }
+
+ if (ldapdb_get_time (hds, "pwdLastSet", &nttime))
+ {
+ smbpw.pass_last_set_time = nt_time_to_unix (&nttime);
+ }
+ else
+ {
+ smbpw.pass_last_set_time = (time_t) (-1);
+ }
+
+ return &smbpw;
+}
+
+/************************************************************************
+Queues the necessary modifications to save a smb_passwd structure
+************************************************************************/
+
+BOOL
+nt5ldapsmb_smbmods (struct smb_passwd * newpwd, LDAPMod *** mods, int operation)
+{
+ fstring temp;
+ pstring upn, spn, hostname;
+ struct berval *bv;
+ char *cname;
+
+ *mods = NULL;
+ if (operation == LDAP_MOD_ADD)
+ {
+ BOOL iscomputer = (newpwd->nt_name[strlen (newpwd->nt_name) - 1] == '$');
+
+ /* immutable attributes */
+ const char *realm = ldapdb_get_realm_name ();
+
+ if (iscomputer)
+ {
+ pstrcpy (hostname, newpwd->nt_name);
+ hostname[strlen (hostname) - 1] = '\0';
+
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "dNSHostName", hostname))
+ return False;
+
+ slprintf (spn, sizeof (spn) - 1, "host/%s", hostname);
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "servicePrincipalName", spn))
+ return False;
+
+ if (realm)
+ {
+ slprintf (upn, sizeof (upn) - 1, "%s@%s", spn, realm);
+ }
+
+ cname = hostname;
+ }
+ else
+ {
+ if (realm)
+ {
+ slprintf (upn, sizeof (upn) - 1, "%s@%s", newpwd->nt_name, realm);
+ }
+
+ cname = newpwd->nt_name;
+ }
+
+ if (realm)
+ {
+#ifdef KRB5_AUTH
+ char *p, *q;
+#endif /* KRB5_AUTH */
+
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "userPrincipalName", upn))
+ {
+ return False;
+ }
+
+#ifdef KRB5_AUTH
+ /*
+ * Stick the Kerberos attributes in for good measure, they come in handy
+ * without Heimdal LDAP backend and LDAP servers that do Kerberos authzn.
+ */
+ p = strchr (upn, '@');
+ if (p == NULL)
+ {
+ return False;
+ }
+ ++p;
+ for (q = p; *q != '\0'; q++)
+ {
+ *q = toupper (*q);
+ }
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "krbName", upn) ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "krb5PrincipalName", upn) ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectclass", "kerberosSecurityObject") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectclass", "krb5Principal"))
+ {
+ return False;
+ }
+#endif /* KRB5_AUTH */
+ }
+
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectclass", "top") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectclass", "person") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectclass", "organizationalPerson") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectclass", "posixAccount") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectClass", "securityPrincipal") ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectclass", "user"))
+ {
+ return False;
+ }
+
+ if (iscomputer && !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "objectclass", "computer"))
+ {
+ return False;
+ }
+
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "uid", newpwd->unix_name) ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "mSSFUName", newpwd->unix_name) ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "sAMAccountName", newpwd->nt_name) ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "cn", cname) ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "name", cname) ||
+ !ldapdb_queue_mod (mods, LDAP_MOD_ADD, "displayName", cname))
+ {
+ return False;
+ }
+
+ slprintf (temp, sizeof (temp) - 1, "%d", newpwd->unix_uid);
+ if (!ldapdb_queue_mod (mods, LDAP_MOD_ADD, "uidNumber", temp))
+ return False;
+
+ if (!rid_to_berval (newpwd->user_rid, &bv))
+ return False;
+
+ /* we need to _not_ do this with an NT5 DC because it's auto generated */
+ if (!ldapdb_queue_mod_len (mods, LDAP_MOD_ADD, "objectSid", bv))
+ {
+ ber_bvfree(bv);
+ return False;
+ }
+ }
+
+ if (newpwd->smb_passwd)
+ {
+ if (!dbcspwd_to_berval (newpwd->smb_passwd, &bv))
+ {
+ return False;
+ }
+ if (!ldapdb_queue_mod_len (mods, operation, "dBCSPwd", bv))
+ {
+ ber_bvfree (bv);
+ return False;
+ }
+ }
+
+ if (newpwd->smb_nt_passwd)
+ {
+ if (!unicodepwd_to_berval (newpwd->smb_nt_passwd, &bv))
+ {
+ return False;
+ }
+ if (!ldapdb_queue_mod_len (mods, operation, "unicodePwd", bv))
+ {
+ ber_bvfree (bv);
+ return False;
+ }
+ }
+
+ if (!ldapdb_queue_time (mods, operation, "pwdLastSet", NULL))
+ {
+ return False;
+ }
+
+ if (!ldapdb_queue_uint32_mod (mods, operation, "userAccountControl", pwdb_acct_ctrl_to_ad(newpwd->acct_ctrl)))
+ {
+ return False;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ Contruct a sam_passwd structure.
+ ******************************************************************/
+/***************************************************************
+Begin/end account enumeration.
+****************************************************************/
+
+static void *
+nt5ldapsmb_enumfirst (BOOL update)
+{
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_search (hds, NULL, "(objectClass=User)", NULL, LDAP_NO_LIMIT))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ return hds;
+}
+
+static void
+nt5ldapsmb_enumclose (void *vp)
+{
+ LDAPDB *hds = (LDAPDB *) vp;
+
+ ldapdb_close (&hds);
+
+ return;
+}
+
+
+/*************************************************************************
+Save/restore the current position in a query
+*************************************************************************/
+
+static SMB_BIG_UINT
+nt5ldapsmb_getdbpos (void *vp)
+{
+ return 0;
+}
+
+static BOOL
+nt5ldapsmb_setdbpos (void *vp, SMB_BIG_UINT tok)
+{
+ return False;
+}
+
+/*************************************************************************
+Return smb_passwd information.
+*************************************************************************/
+
+static struct smb_passwd *
+nt5ldapsmb_getpwbynam (const char *name)
+{
+ struct smb_passwd *ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_lookup_by_posix_name (hds, name))
+ {
+ ldapdb_close (&hds);
+ return NULL;
+ }
+
+ ret = nt5ldapsmb_getent (hds);
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static struct smb_passwd *
+nt5ldapsmb_getpwbyuid (uid_t userid)
+{
+ struct smb_passwd *ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return NULL;
+ }
+
+ if (!ldapdb_lookup_by_posix_uid (hds, userid))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ ret = nt5ldapsmb_getent (hds);
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static struct smb_passwd *
+nt5ldapsmb_getcurrentpw (void *vp)
+{
+ struct smb_passwd *ret;
+ LDAPDB *hds = (LDAPDB *) vp;
+
+ ret = nt5ldapsmb_getent (hds);
+ (void) ldapdb_seq (hds);
+
+ return ret;
+}
+
+
+/************************************************************************
+Modify user information given an smb_passwd struct.
+*************************************************************************/
+static BOOL
+nt5ldapsmb_addpw (struct smb_passwd *newpwd)
+{
+ LDAPMod **mods = NULL;
+ char *container, *cname;
+ pstring hostname;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!newpwd || !ldapdb_allocate_rid (hds, &newpwd->user_rid))
+ {
+ ldapdb_close (&hds);
+ return False;
+ }
+
+ if (newpwd->unix_name[strlen (newpwd->nt_name) - 1] == '$')
+ {
+ container = lp_ldap_computers_subcontext ();
+ pstrcpy (hostname, newpwd->nt_name);
+ hostname[strlen (hostname) - 1] = '\0';
+ cname = hostname;
+ }
+ else
+ {
+ container = lp_ldap_users_subcontext ();
+ cname = newpwd->nt_name;
+ }
+
+ if (!nt5ldapsmb_smbmods (newpwd, &mods, LDAP_MOD_ADD))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_update (hds, container, "cn", cname, mods, True);
+ }
+
+ ldapdb_close (&hds);
+
+ return ret;
+}
+
+static BOOL
+nt5ldapsmb_modpw (struct smb_passwd *pwd, BOOL override)
+{
+ LDAPMod **mods = NULL;
+ BOOL ret;
+ LDAPDB_DECLARE_HANDLE (hds);
+
+ if (!pwd)
+ {
+ return False;
+ }
+
+ if (!ldapdb_open (&hds))
+ {
+ return False;
+ }
+
+ if (!nt5ldapsmb_smbmods (pwd, &mods, LDAP_MOD_REPLACE))
+ {
+ ret = False;
+ }
+ else
+ {
+ ret = ldapdb_update (hds, NULL, "cn", pwd->unix_name, mods, False);
+ }
+
+ ldapdb_close (&hds);
+ return ret;
+}
+
+static struct smb_passdb_ops nt5ldapsmb_ops =
+{
+ nt5ldapsmb_enumfirst,
+ nt5ldapsmb_enumclose,
+ nt5ldapsmb_getdbpos,
+ nt5ldapsmb_setdbpos,
+
+ nt5ldapsmb_getpwbynam,
+ nt5ldapsmb_getpwbyuid,
+ nt5ldapsmb_getcurrentpw,
+ nt5ldapsmb_addpw,
+ nt5ldapsmb_modpw
+};
+
+struct smb_passdb_ops *
+nt5ldap_initialise_password_db (void)
+{
+ if (!ldapdb_init ())
+ {
+ return NULL;
+ }
+
+ return &nt5ldapsmb_ops;
+}
+
+#else
+void nt5ldapsmb_dummy_function (void);
+void
+nt5ldapsmb_dummy_function (void)
+{
+} /* stop some compilers complaining */
+#endif
diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c
index a880184f3df..8d55b3844ee 100644
--- a/source/printing/nt_printing.c
+++ b/source/printing/nt_printing.c
@@ -31,7 +31,7 @@ static BOOL parse_form_entry(char *line, nt_forms_struct *buf)
count++;
}
- DEBUG(106,("Found [%d] tokens\n", count));
+ DEBUG(6,("Found [%d] tokens\n", count));
StrnCpy(buf->name,tok[NAMETOK],sizeof(buf->name)-1);
buf->flag=atoi(tok[FLAGTOK]);
@@ -65,7 +65,7 @@ int get_ntforms(nt_forms_struct **list)
while ( fgets(line, sizeof(pstring), f) )
{
- DEBUG(105,("%s\n",line));
+ DEBUG(5,("%s\n",line));
*list = Realloc(*list, sizeof(nt_forms_struct)*(total+1));
if (! *list)
@@ -82,7 +82,7 @@ int get_ntforms(nt_forms_struct **list)
}
fclose(f);
- DEBUG(104,("%d info lines on %d\n",total, grandtotal));
+ DEBUG(4,("%d info lines on %d\n",total, grandtotal));
return(total);
}
@@ -100,7 +100,7 @@ int write_ntforms(nt_forms_struct **list, int number)
*line=0;
- DEBUG(106,("write_ntforms\n"));
+ DEBUG(6,("write_ntforms\n"));
if((f = sys_fopen(file, "w")) == NULL)
{
@@ -115,11 +115,11 @@ int write_ntforms(nt_forms_struct **list, int number)
(*list)[i].flag, (*list)[i].width, (*list)[i].length,
(*list)[i].left, (*list)[i].top, (*list)[i].right, (*list)[i].bottom);
- DEBUGADD(107,("adding entry [%s]\n", (*list)[i].name));
+ DEBUGADD(7,("adding entry [%s]\n", (*list)[i].name));
}
fclose(f);
- DEBUGADD(106,("closing file\n"));
+ DEBUGADD(6,("closing file\n"));
return(total);
}
@@ -145,7 +145,7 @@ void add_a_form(nt_forms_struct **list, const FORM *form, int *count)
{
if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
{
- DEBUG(103, ("NT workaround, [%s] already exists\n", form_name));
+ DEBUG(3, ("NT workaround, [%s] already exists\n", form_name));
update=True;
}
}
@@ -175,10 +175,10 @@ void update_a_form(nt_forms_struct **list, const FORM *form, int count)
fstring form_name;
unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
- DEBUG(106, ("[%s]\n", form_name));
+ DEBUG(6, ("[%s]\n", form_name));
for (n=0; n<count; n++)
{
- DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
+ DEBUGADD(6, ("n [%d]:[%s]\n", n, (*list)[n].name));
if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
break;
}
@@ -209,7 +209,7 @@ int get_ntdrivers(fstring **list, char *architecture)
int match_len;
int total=0;
- DEBUG(105,("Getting the driver list from directory: [%s]\n", lp_nt_drivers_file()));
+ DEBUG(5,("Getting the driver list from directory: [%s]\n", lp_nt_drivers_file()));
*list=NULL;
dirp = opendir(lp_nt_drivers_file());
@@ -228,13 +228,13 @@ int get_ntdrivers(fstring **list, char *architecture)
{
if (strncmp(dpname, name_match, match_len)==0)
{
- DEBUGADD(107,("Found: [%s]\n", dpname));
+ DEBUGADD(7,("Found: [%s]\n", dpname));
- fstrcpy(driver_name, dpname+match_len);
+ StrCpy(driver_name, dpname+match_len);
all_string_sub(driver_name, "#", "/", 0);
*list = Realloc(*list, sizeof(fstring)*(total+1));
StrnCpy((*list)[total], driver_name, strlen(driver_name));
- DEBUGADD(106,("Added: [%s]\n", driver_name));
+ DEBUGADD(6,("Added: [%s]\n", driver_name));
total++;
}
}
@@ -266,20 +266,20 @@ void get_short_archi(char *short_archi, char *long_archi)
int i=-1;
- DEBUG(107,("Getting architecture dependant directory\n"));
+ DEBUG(7,("Getting architecture dependant directory\n"));
do {
i++;
} while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
if (archi_table[i].long_archi==NULL)
{
- DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
+ DEBUGADD(7,("Unknown architecture [%s] !\n", long_archi));
}
StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
- DEBUGADD(108,("index: [%d]\n", i));
- DEBUGADD(108,("long architecture: [%s]\n", long_archi));
- DEBUGADD(108,("short architecture: [%s]\n", short_archi));
+ DEBUGADD(8,("index: [%d]\n", i));
+ DEBUGADD(8,("long architecture: [%s]\n", long_archi));
+ DEBUGADD(8,("short architecture: [%s]\n", short_archi));
}
/****************************************************************************
@@ -471,7 +471,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
char **dependentfiles;
- DEBUG(106,("Dumping printer driver at level [%d]\n", level));
+ DEBUG(6,("Dumping printer driver at level [%d]\n", level));
switch (level)
{
@@ -479,28 +479,28 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
{
if (driver.info_3 == NULL)
{
- DEBUGADD(103,("NULL pointer, memory not alloced ?\n"));
+ DEBUGADD(3,("NULL pointer, memory not alloced ?\n"));
success=5;
}
else
{
info3=driver.info_3;
- DEBUGADD(106,("version:[%d]\n", info3->cversion));
- DEBUGADD(106,("name:[%s]\n", info3->name));
- DEBUGADD(106,("environment:[%s]\n", info3->environment));
- DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath));
- DEBUGADD(106,("datafile:[%s]\n", info3->datafile));
- DEBUGADD(106,("configfile:[%s]\n", info3->configfile));
- DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile));
- DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname));
- DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
+ DEBUGADD(6,("version:[%d]\n", info3->cversion));
+ DEBUGADD(6,("name:[%s]\n", info3->name));
+ DEBUGADD(6,("environment:[%s]\n", info3->environment));
+ DEBUGADD(6,("driverpath:[%s]\n", info3->driverpath));
+ DEBUGADD(6,("datafile:[%s]\n", info3->datafile));
+ DEBUGADD(6,("configfile:[%s]\n", info3->configfile));
+ DEBUGADD(6,("helpfile:[%s]\n", info3->helpfile));
+ DEBUGADD(6,("monitorname:[%s]\n", info3->monitorname));
+ DEBUGADD(6,("defaultdatatype:[%s]\n", info3->defaultdatatype));
dependentfiles=info3->dependentfiles;
while ( **dependentfiles != '\0' )
{
- DEBUGADD(106,("dependentfile:[%s]\n", *dependentfiles));
+ DEBUGADD(6,("dependentfile:[%s]\n", *dependentfiles));
dependentfiles++;
}
success=0;
@@ -676,7 +676,7 @@ static void dissect_and_fill_a_param(NT_PRINTER_PARAM *param, char *v)
char *tok[5];
int count = 0;
- DEBUG(105,("dissect_and_fill_a_param\n"));
+ DEBUG(5,("dissect_and_fill_a_param\n"));
tok[count] = strtok(v,"#");
count++;
@@ -693,7 +693,7 @@ static void dissect_and_fill_a_param(NT_PRINTER_PARAM *param, char *v)
strhex_to_str(param->data, 2*(param->data_len), tok[3]);
param->next=NULL;
- DEBUGADD(105,("value:[%s], len:[%d]\n", param->value, param->data_len));
+ DEBUGADD(5,("value:[%s], len:[%d]\n", param->value, param->data_len));
}
/****************************************************************************
@@ -703,10 +703,10 @@ used when reading from disk.
****************************************************************************/
void dump_a_param(NT_PRINTER_PARAM *param)
{
- DEBUG(105,("dump_a_param\n"));
- DEBUGADD(106,("value [%s]\n", param->value));
- DEBUGADD(106,("type [%d]\n", param->type));
- DEBUGADD(106,("data len [%d]\n", param->data_len));
+ DEBUG(5,("dump_a_param\n"));
+ DEBUGADD(6,("value [%s]\n", param->value));
+ DEBUGADD(6,("type [%d]\n", param->type));
+ DEBUGADD(6,("data len [%d]\n", param->data_len));
}
/****************************************************************************
@@ -715,7 +715,7 @@ BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *par
{
NT_PRINTER_PARAM *current;
- DEBUG(108,("add_a_specific_param\n"));
+ DEBUG(8,("add_a_specific_param\n"));
param->next=NULL;
@@ -749,10 +749,10 @@ BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_
if ( !strcmp(current->value, param->value) &&
(strlen(current->value)==strlen(param->value)) )
{
- DEBUG(109,("deleting first value\n"));
+ DEBUG(9,("deleting first value\n"));
info_2->specific=current->next;
free(current);
- DEBUG(109,("deleted first value\n"));
+ DEBUG(9,("deleted first value\n"));
return (True);
}
@@ -763,10 +763,10 @@ BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_
if (!strcmp(current->value, param->value) &&
strlen(current->value)==strlen(param->value) )
{
- DEBUG(109,("deleting current value\n"));
+ DEBUG(9,("deleting current value\n"));
previous->next=current->next;
free(current);
- DEBUG(109,("deleted current value\n"));
+ DEBUG(9,("deleted current value\n"));
return(True);
}
@@ -835,7 +835,7 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
/* don't check if v==NULL as an empty arg is valid */
- DEBUGADD(115, ("[%s]:[%s]\n", p, v));
+ DEBUGADD(15, ("[%s]:[%s]\n", p, v));
/*
* The PRINTER_INFO_2 fields
@@ -1008,7 +1008,7 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
uint32 success;
NT_PRINTER_INFO_LEVEL_2 *info2;
- DEBUG(106,("Dumping printer at level [%d]\n", level));
+ DEBUG(6,("Dumping printer at level [%d]\n", level));
switch (level)
{
@@ -1023,26 +1023,26 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
{
info2=printer.info_2;
- DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
- DEBUGADD(106,("priority:[%d]\n", info2->priority));
- DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
- DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
- DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
- DEBUGADD(106,("status:[%d]\n", info2->status));
- DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
- DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
-
- DEBUGADD(106,("servername:[%s]\n", info2->servername));
- DEBUGADD(106,("printername:[%s]\n", info2->printername));
- DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
- DEBUGADD(106,("portname:[%s]\n", info2->portname));
- DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
- DEBUGADD(106,("comment:[%s]\n", info2->comment));
- DEBUGADD(106,("location:[%s]\n", info2->location));
- DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
- DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
- DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
- DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
+ DEBUGADD(6,("attributes:[%d]\n", info2->attributes));
+ DEBUGADD(6,("priority:[%d]\n", info2->priority));
+ DEBUGADD(6,("default_priority:[%d]\n", info2->default_priority));
+ DEBUGADD(6,("starttime:[%d]\n", info2->starttime));
+ DEBUGADD(6,("untiltime:[%d]\n", info2->untiltime));
+ DEBUGADD(6,("status:[%d]\n", info2->status));
+ DEBUGADD(6,("cjobs:[%d]\n", info2->cjobs));
+ DEBUGADD(6,("averageppm:[%d]\n", info2->averageppm));
+
+ DEBUGADD(6,("servername:[%s]\n", info2->servername));
+ DEBUGADD(6,("printername:[%s]\n", info2->printername));
+ DEBUGADD(6,("sharename:[%s]\n", info2->sharename));
+ DEBUGADD(6,("portname:[%s]\n", info2->portname));
+ DEBUGADD(6,("drivername:[%s]\n", info2->drivername));
+ DEBUGADD(6,("comment:[%s]\n", info2->comment));
+ DEBUGADD(6,("location:[%s]\n", info2->location));
+ DEBUGADD(6,("sepfile:[%s]\n", info2->sepfile));
+ DEBUGADD(6,("printprocessor:[%s]\n", info2->printprocessor));
+ DEBUGADD(6,("datatype:[%s]\n", info2->datatype));
+ DEBUGADD(6,("parameters:[%s]\n", info2->parameters));
success=0;
}
break;
@@ -1114,7 +1114,7 @@ uint32 get_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level, fstring share
uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
{
uint32 success;
- DEBUG(104,("freeing a printer at level [%d]\n", level));
+ DEBUG(4,("freeing a printer at level [%d]\n", level));
switch (level)
{
@@ -1124,7 +1124,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
{
if ((printer.info_2)->devmode != NULL)
{
- DEBUG(106,("deleting DEVMODE\n"));
+ DEBUG(6,("deleting DEVMODE\n"));
if ((printer.info_2)->devmode->private !=NULL )
free((printer.info_2)->devmode->private);
free((printer.info_2)->devmode);
@@ -1140,7 +1140,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
while ( param != NULL)
{
next_param=param->next;
- DEBUG(106,("deleting param [%s]\n", param->value));
+ DEBUG(6,("deleting param [%s]\n", param->value));
free(param->data);
free(param);
param=next_param;
@@ -1168,7 +1168,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
{
uint32 success;
- DEBUG(104,("adding a printer at level [%d]\n", level));
+ DEBUG(4,("adding a printer at level [%d]\n", level));
dump_a_printer_driver(driver, level);
switch (level)
@@ -1293,7 +1293,7 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
/* right now that's enough ! */
NT_PRINTER_PARAM *param;
- DEBUG(105, ("get_specific_param\n"));
+ DEBUG(5, ("get_specific_param\n"));
param=printer.info_2->specific;
@@ -1306,7 +1306,7 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
param=param->next;
}
- DEBUG(106, ("found one param\n"));
+ DEBUG(6, ("found one param\n"));
if (param != NULL)
{
/* exited because it exist */
@@ -1316,10 +1316,10 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level,
memcpy(*data, param->data, param->data_len);
*len=param->data_len;
- DEBUG(106, ("exit of get_specific_param:true\n"));
+ DEBUG(6, ("exit of get_specific_param:true\n"));
return (True);
}
- DEBUG(106, ("exit of get_specific_param:false\n"));
+ DEBUG(6, ("exit of get_specific_param:false\n"));
return (False);
}
@@ -1331,7 +1331,7 @@ void init_devicemode(NT_DEVICEMODE *nt_devmode)
* should I init this ones ???
nt_devmode->devicename
*/
- fstrcpy(nt_devmode->formname, "A4");
+ StrCpy(nt_devmode->formname, "A4");
nt_devmode->specversion = 0x0401;
nt_devmode->driverversion = 0x0400;
diff --git a/source/printing/pcap.c b/source/printing/pcap.c
index 62010706bb3..242406c9748 100644
--- a/source/printing/pcap.c
+++ b/source/printing/pcap.c
@@ -9,8 +9,6 @@
Re-written again by Andrew Tridgell
Modified for SVID support by Norm Jacobs, 1997
-
- Modified for CUPS support by Michael Sweet, 1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -56,9 +54,6 @@
*
* Modified to call SVID/XPG4 support if printcap name is set to "lpstat"
* in smb.conf under Solaris.
- *
- * Modified to call CUPS support if printcap name is set to "cups"
- * in smb.conf.
*/
#include "includes.h"
@@ -74,7 +69,7 @@ extern int DEBUGLEVEL;
****************************************** */
static int strlocate(char *xpLine,char *xpS)
{
- int iS,iL,iRet;
+ int iS,iL,i,iRet;
char *p;
iS = strlen(xpS);
iL = strlen(xpLine);
@@ -96,9 +91,9 @@ static int strlocate(char *xpLine,char *xpS)
/* ******************************************************************* */
/* * Scan qconfig and search all virtual printer (device printer) * */
/* ******************************************************************* */
-static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
+static void ScanQconfig_fn(char *psz,void (*fn)())
{
- int iEtat;
+ int iLg,iEtat;
FILE *pfile;
char *line,*p;
pstring name,comment;
@@ -267,11 +262,6 @@ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname)
return(False);
}
-#ifdef HAVE_LIBCUPS
- if (strequal(psz, "cups"))
- return (cups_printername_ok(pszPrintername));
-#endif /* HAVE_LIBCUPS */
-
#ifdef SYSV
if (strequal(psz, "lpstat"))
return (sysv_printername_ok(pszPrintername));
@@ -339,13 +329,6 @@ void pcap_printer_fn(void (*fn)(char *, char *))
return;
}
-#ifdef HAVE_LIBCUPS
- if (strequal(psz, "cups")) {
- cups_printer_fn(fn);
- return;
- }
-#endif /* HAVE_LIBCUPS */
-
#ifdef SYSV
if (strequal(psz, "lpstat")) {
sysv_printer_fn(fn);
diff --git a/source/printing/print_svid.c b/source/printing/print_svid.c
index 9891e158a27..5c5eebeb502 100644
--- a/source/printing/print_svid.c
+++ b/source/printing/print_svid.c
@@ -49,7 +49,7 @@ static void populate_printers(void)
{
FILE *fp;
- if ((fp = sys_popen("/usr/bin/lpstat -v", "r")) != NULL) {
+ if ((fp = popen("/usr/bin/lpstat -v", "r")) != NULL) {
char buf[BUFSIZ];
while (fgets(buf, sizeof (buf), fp) != NULL) {
@@ -60,17 +60,7 @@ static void populate_printers(void)
if (((tmp = strchr(buf, ' ')) == NULL) ||
((tmp = strchr(++tmp, ' ')) == NULL))
continue;
-
- /*
- * In case we're only at the "for ".
- */
-
- if(!strncmp("for ",++tmp,4))
- {
- tmp=strchr(tmp, ' ');
- tmp++;
- }
- name = tmp;
+ name = ++tmp;
/* truncate the ": ..." */
if ((tmp = strchr(name, ':')) != NULL)
@@ -79,15 +69,12 @@ static void populate_printers(void)
/* add it to the cache */
if ((ptmp = malloc(sizeof (*ptmp))) != NULL) {
ZERO_STRUCTP(ptmp);
- if((ptmp->name = strdup(name)) == NULL)
- DEBUG(0,("populate_printers: malloc fail in strdup !\n"));
+ ptmp->name = strdup(name);
ptmp->next = printers;
printers = ptmp;
- } else {
- DEBUG(0,("populate_printers: malloc fail for ptmp\n"));
}
}
- sys_pclose(fp);
+ pclose(fp);
} else {
DEBUG(0,( "Unable to run lpstat!\n"));
}
diff --git a/source/printing/printing.c b/source/printing/printing.c
index 134a5946300..c7f50388db8 100644
--- a/source/printing/printing.c
+++ b/source/printing/printing.c
@@ -20,6 +20,8 @@
*/
#include "includes.h"
+#include "nterr.h"
+
extern int DEBUGLEVEL;
static BOOL * lpq_cache_reset=NULL;
@@ -49,12 +51,13 @@ Build the print command in the supplied buffer. This means getting the
print command for the service and inserting the printer name and the
print file name. Return NULL on error, else the passed buffer pointer.
****************************************************************************/
-static char *build_print_command(connection_struct *conn,
+static char *build_print_command(connection_struct *conn, const vuser_key *key,
+ int snum,
char *command,
- char *syscmd, char *filename)
+ char *syscmd, char *filename1)
{
- int snum = SNUM(conn);
char *tstr;
+ pstring filename;
/* get the print command for the service. */
tstr = command;
@@ -72,8 +75,13 @@ static char *build_print_command(connection_struct *conn,
DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum)));
}
- pstring_sub(syscmd, "%s", filename);
- pstring_sub(syscmd, "%f", filename);
+ if (strstr(syscmd,"%s")) {
+ pstrcpy(filename,filename1);
+
+ string_sub(syscmd, "%s", filename);
+ }
+
+ string_sub(syscmd, "%f", filename1);
/* Does the service have a printername? If not, make a fake
and empty */
@@ -85,10 +93,14 @@ static char *build_print_command(connection_struct *conn,
tstr = SERVICE(snum);
}
- pstring_sub(syscmd, "%p", tstr);
-
- standard_sub(conn,syscmd);
+ string_sub(syscmd, "%p", tstr);
+ {
+ user_struct *vuser = get_valid_user_struct(key);
+ standard_sub(conn, vuser, syscmd);
+ vuid_free_user_struct(vuser);
+ }
+
return (syscmd);
}
@@ -96,10 +108,10 @@ static char *build_print_command(connection_struct *conn,
/****************************************************************************
print a file - called on closing the file
****************************************************************************/
-void print_file(connection_struct *conn, files_struct *file)
+void print_file(connection_struct *conn, const vuser_key *key,
+ int snum, files_struct *file)
{
pstring syscmd;
- int snum = SNUM(conn);
char *tempstr;
*syscmd = 0;
@@ -110,7 +122,7 @@ void print_file(connection_struct *conn, files_struct *file)
return;
}
- tempstr = build_print_command(conn,
+ tempstr = build_print_command(conn, key, snum,
PRINTCOMMAND(snum),
syscmd, file->fsp_name);
if (tempstr != NULL) {
@@ -241,7 +253,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
return(False);
/* the Job and Total columns must be integer */
- if (!isdigit((int)*tok[JOBTOK]) || !isdigit((int)*tok[TOTALTOK])) return(False);
+ if (!isdigit(*tok[JOBTOK]) || !isdigit(*tok[TOTALTOK])) return(False);
buf->job = atoi(tok[JOBTOK]);
buf->size = atoi(tok[TOTALTOK]);
@@ -264,8 +276,6 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
break;
}
}
- /* Ensure null termination. */
- buf->file[sizeof(buf->file)-1] = '\0';
}
#ifdef PRIOTOK
@@ -336,7 +346,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
return(False);
}
- if (!isdigit((int)*tokarr[LPRNG_JOBTOK]) || !isdigit((int)*tokarr[LPRNG_TOTALTOK])) {
+ if (!isdigit(*tokarr[LPRNG_JOBTOK]) || !isdigit(*tokarr[LPRNG_TOTALTOK])) {
return(False);
}
@@ -345,7 +355,7 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
if (strequal(tokarr[LPRNG_RANKTOK],"active")) {
buf->status = LPQ_PRINTING;
- } else if (isdigit((int)*tokarr[LPRNG_RANKTOK])) {
+ } else if (isdigit(*tokarr[LPRNG_RANKTOK])) {
buf->status = LPQ_QUEUED;
} else {
buf->status = LPQ_PAUSED;
@@ -381,8 +391,6 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
break;
}
}
- /* Ensure null termination. */
- buf->file[sizeof(buf->file)-1] = '\0';
}
return(True);
@@ -408,9 +416,9 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
int count=0;
/* handle the case of "(standard input)" as a filename */
- pstring_sub(line,"standard input","STDIN");
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
+ string_sub(line,"standard input","STDIN");
+ all_string_sub(line,"(","\"", 0);
+ all_string_sub(line,")","\"", 0);
for (count=0;
count<10 &&
@@ -525,9 +533,9 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
}
if (!header_line_ok) return (False); /* incorrect header line */
/* handle the case of "(standard input)" as a filename */
- pstring_sub(line,"standard input","STDIN");
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
+ string_sub(line,"standard input","STDIN");
+ all_string_sub(line,"(","\"", 0);
+ all_string_sub(line,")","\"", 0);
for (count=0; count<2 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
/* we must get 2 tokens */
@@ -563,7 +571,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
else if (base_prio) base_prio_reset=False;
/* handle the dash in the job id */
- pstring_sub(line,"-"," ");
+ string_sub(line,"-"," ");
for (count=0; count<12 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
@@ -598,7 +606,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
/****************************************************************************
-parse a lpstat line
+parse a lpq line
here is an example of "lpstat -o dcslw" output under sysv
@@ -612,47 +620,27 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
int count=0;
char *p;
- /*
- * Handle the dash in the job id, but make sure that we skip over
- * the printer name in case we have a dash in that.
- * Patch from Dom.Mitchell@palmerharvey.co.uk.
- */
-
- /*
- * Move to the first space.
- */
- for (p = line ; !isspace(*p) && *p; p++)
- ;
-
- /*
- * Back up until the last '-' character or
- * start of line.
- */
- for (; (p >= line) && (*p != '-'); p--)
- ;
-
- if((p >= line) && (*p == '-'))
- *p = ' ';
-
- for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++)
- ;
+ /* handle the dash in the job id */
+ string_sub(line,"-"," ");
+
+ for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
/* we must get 7 tokens */
if (count < 7)
return(False);
/* the 2nd and 4th, 6th columns must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3]))
- return(False);
- if (!isdigit((int)*tok[5]))
- return(False);
+ if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3])) return(False);
+ if (!isdigit((int)*tok[5])) return(False);
/* if the user contains a ! then trim the first part of it */
- if ((p=strchr(tok[2],'!'))) {
+ if ((p=strchr(tok[2],'!')))
+ {
fstring tmp;
fstrcpy(tmp,p+1);
fstrcpy(tok[2],tmp);
- }
+ }
+
buf->job = atoi(tok[1]);
buf->size = atoi(tok[3]);
@@ -687,14 +675,14 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
DEBUG(4,("antes [%s]\n", line));
/* handle the case of "-- standard input --" as a filename */
- pstring_sub(line,"standard input","STDIN");
+ string_sub(line,"standard input","STDIN");
DEBUG(4,("despues [%s]\n", line));
- all_string_sub(line,"-- ","\"",0);
- all_string_sub(line," --","\"",0);
+ all_string_sub(line,"-- ","\"", 0);
+ all_string_sub(line," --","\"", 0);
DEBUG(4,("despues 1 [%s]\n", line));
- pstring_sub(line,"[job #","");
- pstring_sub(line,"]","");
+ string_sub(line,"[job #","");
+ string_sub(line,"]","");
DEBUG(4,("despues 2 [%s]\n", line));
@@ -750,9 +738,9 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
int count=0;
/* handle the case of "(standard input)" as a filename */
- pstring_sub(line,"stdin","STDIN");
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
+ string_sub(line,"stdin","STDIN");
+ all_string_sub(line,"(","\"", 0);
+ all_string_sub(line,")","\"", 0);
for (count=0; count<11 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
@@ -820,7 +808,7 @@ static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first)
int count=0;
/* mung all the ":"s to spaces*/
- pstring_sub(line,":"," ");
+ string_sub(line,":"," ");
for (count=0; count<10 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
@@ -864,8 +852,8 @@ static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first)
t->tm_mon = atoi(tok[count+2]+3);
switch (*tok[count+2])
{
- case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]); break;
- default: t->tm_year = atoi(tok[count+2]); break;
+ case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]) + 1900; break;
+ default: t->tm_year = atoi(tok[count+2]) + 2000; break;
}
t->tm_hour = atoi(tok[count+3]);
@@ -977,8 +965,8 @@ static BOOL parse_lpq_entry(int snum,char *line,
/****************************************************************************
get a printer queue
****************************************************************************/
-int get_printqueue(int snum,
- connection_struct *conn,print_queue_struct **queue,
+int get_printqueue(int snum, connection_struct *conn, const vuser_key *key,
+ print_queue_struct **queue,
print_status_struct *status)
{
char *lpq_command = lp_lpqcommand(snum);
@@ -1007,9 +995,13 @@ int get_printqueue(int snum,
}
pstrcpy(syscmd,lpq_command);
- pstring_sub(syscmd,"%p",printername);
+ string_sub(syscmd,"%p",printername);
- standard_sub(conn,syscmd);
+ {
+ user_struct *vuser = get_valid_user_struct(key);
+ standard_sub(conn, vuser, syscmd);
+ vuid_free_user_struct(vuser);
+ }
slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd));
@@ -1046,7 +1038,7 @@ int get_printqueue(int snum,
break;
}
- memset((char *)&(*queue)[count],'\0',sizeof(**queue));
+ bzero((char *)&(*queue)[count],sizeof(**queue));
/* parse it */
if (!parse_lpq_entry(snum,line,
@@ -1072,7 +1064,8 @@ int get_printqueue(int snum,
/****************************************************************************
delete a printer queue entry
****************************************************************************/
-void del_printqueue(connection_struct *conn,int snum,int jobid)
+void del_printqueue(connection_struct *conn,const vuser_key *key,
+ int snum,int jobid)
{
char *lprm_command = lp_lprmcommand(snum);
char *printername = PRINTERNAME(snum);
@@ -1096,9 +1089,13 @@ void del_printqueue(connection_struct *conn,int snum,int jobid)
slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);
pstrcpy(syscmd,lprm_command);
- pstring_sub(syscmd,"%p",printername);
- pstring_sub(syscmd,"%j",jobstr);
- standard_sub(conn,syscmd);
+ string_sub(syscmd,"%p",printername);
+ string_sub(syscmd,"%j",jobstr);
+ {
+ user_struct *vuser = get_valid_user_struct(key);
+ standard_sub(conn, vuser, syscmd);
+ vuid_free_user_struct(vuser);
+ }
ret = smbrun(syscmd,NULL,False);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
@@ -1108,7 +1105,8 @@ void del_printqueue(connection_struct *conn,int snum,int jobid)
/****************************************************************************
change status of a printer queue entry
****************************************************************************/
-void status_printjob(connection_struct *conn,int snum,int jobid,int status)
+void status_printjob(connection_struct *conn,const vuser_key *key,
+ int snum,int jobid,int status)
{
char *lpstatus_command =
(status==LPQ_PAUSED?lp_lppausecommand(snum):lp_lpresumecommand(snum));
@@ -1134,9 +1132,13 @@ void status_printjob(connection_struct *conn,int snum,int jobid,int status)
slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);
pstrcpy(syscmd,lpstatus_command);
- pstring_sub(syscmd,"%p",printername);
- pstring_sub(syscmd,"%j",jobstr);
- standard_sub(conn,syscmd);
+ string_sub(syscmd,"%p",printername);
+ string_sub(syscmd,"%j",jobstr);
+ {
+ user_struct *vuser = get_valid_user_struct(key);
+ standard_sub(conn, vuser, syscmd);
+ vuid_free_user_struct(vuser);
+ }
ret = smbrun(syscmd,NULL,False);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
@@ -1168,8 +1170,8 @@ void printjob_decode(int jobid, int *snum, int *job)
/****************************************************************************
Change status of a printer queue
****************************************************************************/
-
-void status_printqueue(connection_struct *conn,int snum,int status)
+uint32 status_printqueue(connection_struct *conn,const vuser_key *key,
+ int snum,int status)
{
char *queuestatus_command = (status==LPSTAT_STOPPED ?
lp_queuepausecommand(snum):lp_queueresumecommand(snum));
@@ -1186,16 +1188,24 @@ void status_printqueue(connection_struct *conn,int snum,int status)
if (!queuestatus_command || !(*queuestatus_command)) {
DEBUG(5,("No queuestatus command to %s job\n",
(status==LPSTAT_STOPPED?"pause":"resume")));
- return;
+ return NT_STATUS_INVALID_PARAMETER;
}
pstrcpy(syscmd,queuestatus_command);
- pstring_sub(syscmd,"%p",printername);
- standard_sub(conn,syscmd);
+ string_sub(syscmd,"%p",printername);
+ {
+ user_struct *vuser = get_valid_user_struct(key);
+ standard_sub(conn, vuser, syscmd);
+ vuid_free_user_struct(vuser);
+ }
+
+
ret = smbrun(syscmd,NULL,False);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
lpq_reset(snum); /* queue has changed */
+
+ return ret == 0 ? 0x0 : NT_STATUS_INVALID_PARAMETER;
}
diff --git a/source/profile/profile.c b/source/profile/profile.c
index 72954f90c9f..b685b119169 100644
--- a/source/profile/profile.c
+++ b/source/profile/profile.c
@@ -30,6 +30,10 @@
extern int DEBUGLEVEL;
+#define SHMEM_KEY ((key_t)0x07021999)
+#define SHM_MAGIC 0x6349985
+#define SHM_VERSION 1
+
#define IPC_PERMS ((SHM_R | SHM_W) | (SHM_R>>3) | (SHM_R>>6))
static int shm_id;
@@ -48,13 +52,13 @@ BOOL profile_setup(BOOL rdonly)
again:
/* try to use an existing key */
- shm_id = shmget(PROF_SHMEM_KEY, 0, 0);
+ shm_id = shmget(SHMEM_KEY, 0, 0);
/* if that failed then create one. There is a race condition here
if we are running from inetd. Bad luck. */
if (shm_id == -1) {
if (read_only) return False;
- shm_id = shmget(PROF_SHMEM_KEY, sizeof(*profile_p),
+ shm_id = shmget(SHMEM_KEY, sizeof(*profile_p),
IPC_CREAT | IPC_EXCL | IPC_PERMS);
}
@@ -97,8 +101,6 @@ BOOL profile_setup(BOOL rdonly)
if (!read_only && (shm_ds.shm_nattch == 1)) {
memset((char *)profile_p, 0, sizeof(*profile_p));
- profile_p->prof_shm_magic = PROF_SHM_MAGIC;
- profile_p->prof_shm_version = PROF_SHM_VERSION;
DEBUG(3,("Initialised profile area\n"));
}
diff --git a/source/rpc_client/.cvsignore b/source/rpc_client/.cvsignore
new file mode 100644
index 00000000000..af9d6be961b
--- /dev/null
+++ b/source/rpc_client/.cvsignore
@@ -0,0 +1 @@
+*.lo \ No newline at end of file
diff --git a/source/rpc_client/cli_atsvc.c b/source/rpc_client/cli_atsvc.c
new file mode 100644
index 00000000000..1abb9e83037
--- /dev/null
+++ b/source/rpc_client/cli_atsvc.c
@@ -0,0 +1,270 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 2.1.
+ * RPC client routines: scheduler service
+ * Copyright (C) Matthew Chapman 1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Andrew Tridgell 1992-1999.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+add a job to the scheduler
+****************************************************************************/
+BOOL at_add_job(
+ char *srv_name, AT_JOB_INFO *info, char *command,
+ uint32 *jobid)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ AT_Q_ADD_JOB q_a;
+ BOOL p = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_ATSVC, &con))
+ {
+ return False;
+ }
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api AT_ADD_JOB */
+
+ DEBUG(4,("Scheduler Add Job\n"));
+
+ /* store the parameters */
+ make_at_q_add_job(&q_a, srv_name, info, command);
+
+ /* turn parameters into data stream */
+ if (at_io_q_add_job("", &q_a, &buf, 0) &&
+ rpc_con_pipe_req(con, AT_ADD_JOB, &buf, &rbuf))
+ {
+ AT_R_ADD_JOB r_a;
+
+ at_io_r_add_job("", &r_a, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_a.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("AT_R_ADD_JOB: %s\n", get_nt_error_msg(r_a.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ *jobid = r_a.jobid;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ cli_connection_unlink(con);
+
+ return p;
+}
+
+/****************************************************************************
+dequeue a job
+****************************************************************************/
+BOOL at_del_job( char *srv_name, uint32 min_jobid, uint32 max_jobid)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ AT_Q_DEL_JOB q_d;
+ BOOL p = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_ATSVC, &con))
+ {
+ return False;
+ }
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api AT_DEL_JOB */
+
+ DEBUG(4,("Scheduler Delete Job\n"));
+
+ /* store the parameters */
+ make_at_q_del_job(&q_d, srv_name, min_jobid, max_jobid);
+
+ /* turn parameters into data stream */
+ if (at_io_q_del_job("", &q_d, &buf, 0) &&
+ rpc_con_pipe_req(con, AT_DEL_JOB, &buf, &rbuf))
+ {
+ AT_R_DEL_JOB r_d;
+
+ at_io_r_del_job("", &r_d, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_d.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("AT_R_DEL_JOB: %s\n", get_nt_error_msg(r_d.status)));
+ p = False;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ cli_connection_unlink(con);
+
+ return p;
+}
+
+/****************************************************************************
+enumerate scheduled jobs
+****************************************************************************/
+BOOL at_enum_jobs( char *srv_name, uint32 *num_jobs,
+ AT_ENUM_INFO *jobs, char ***commands)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ AT_Q_ENUM_JOBS q_e;
+ BOOL p = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_ATSVC, &con))
+ {
+ return False;
+ }
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api AT_DEL_JOB */
+
+ DEBUG(4,("Scheduler Enumerate Jobs\n"));
+
+ /* store the parameters */
+ make_at_q_enum_jobs(&q_e, srv_name);
+
+ /* turn parameters into data stream */
+ if (at_io_q_enum_jobs("", &q_e, &buf, 0) &&
+ rpc_con_pipe_req(con, AT_ENUM_JOBS, &buf, &rbuf))
+ {
+ AT_R_ENUM_JOBS r_e;
+
+ at_io_r_enum_jobs("", &r_e, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("AT_R_ENUM_JOBS: %s\n", get_nt_error_msg(r_e.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ int i;
+
+ *num_jobs = 0;
+ memcpy(jobs, &r_e.info, r_e.num_entries * sizeof(AT_ENUM_INFO));
+
+ for (i = 0; i < r_e.num_entries; i++)
+ {
+ fstring cmd;
+ unistr2_to_ascii(cmd, &r_e.command[i], sizeof(cmd));
+ add_chars_to_array(num_jobs, commands, cmd);
+ }
+ if ((*num_jobs) != r_e.num_entries)
+ {
+ p = False;
+ }
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ cli_connection_unlink(con);
+
+ return p;
+}
+
+/****************************************************************************
+query job information
+****************************************************************************/
+BOOL at_query_job(char *srv_name,
+ uint32 jobid, AT_JOB_INFO *job, fstring command)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ AT_Q_QUERY_JOB q_q;
+ BOOL p = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_ATSVC, &con))
+ {
+ return False;
+ }
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api AT_QUERY_JOB */
+
+ DEBUG(4,("Scheduler Query Job\n"));
+
+ /* store the parameters */
+ make_at_q_query_job(&q_q, srv_name, jobid);
+
+ /* turn parameters into data stream */
+ if (at_io_q_query_job("", &q_q, &buf, 0) &&
+ rpc_con_pipe_req(con, AT_QUERY_JOB, &buf, &rbuf))
+ {
+ AT_R_QUERY_JOB r_q;
+
+ at_io_r_query_job("", &r_q, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_q.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("AT_R_QUERY_JOB: %s\n", get_nt_error_msg(r_q.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(job, &r_q.info, sizeof(AT_JOB_INFO));
+ unistr2_to_ascii(command, &r_q.command,
+ sizeof(fstring)-1);
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ cli_connection_unlink(con);
+
+ return p;
+}
diff --git a/source/rpc_client/cli_brs.c b/source/rpc_client/cli_brs.c
new file mode 100644
index 00000000000..8f18d0c9e11
--- /dev/null
+++ b/source/rpc_client/cli_brs.c
@@ -0,0 +1,96 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+do a BRS Query
+****************************************************************************/
+BOOL brs_query_info( const char *srv_name, uint32 switch_value,
+ void *id)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ BRS_Q_QUERY_INFO q_o;
+ BOOL valid_info = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_BROWSER, &con))
+ {
+ return False;
+ }
+
+ if (id == NULL) return False;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api BRS_QUERY_INFO */
+
+ DEBUG(4,("BRS Query Info\n"));
+
+ /* store the parameters */
+ make_brs_q_query_info(&q_o, srv_name, switch_value);
+
+ /* turn parameters into data stream */
+ if (brs_io_q_query_info("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, BRS_QUERY_INFO, &buf, &rbuf))
+ {
+ BRS_R_QUERY_INFO r_o;
+ BOOL p;
+
+ r_o.info.id = id;
+
+ brs_io_r_query_info("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("BRS_R_QUERY_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_info = True;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ cli_connection_unlink(con);
+
+ return valid_info;
+}
+
diff --git a/source/rpc_client/cli_connect.c b/source/rpc_client/cli_connect.c
new file mode 100644
index 00000000000..d9e72a52cc2
--- /dev/null
+++ b/source/rpc_client/cli_connect.c
@@ -0,0 +1,859 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client generic functions
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define NO_SYSLOG
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+struct user_creds *usr_creds = NULL;
+vuser_key *user_key = NULL;
+
+extern int DEBUGLEVEL;
+
+enum
+{ MSRPC_NONE, MSRPC_LOCAL, MSRPC_SMB };
+
+struct cli_connection
+{
+ uint32 num_connections;
+ char *srv_name;
+ char *pipe_name;
+ struct user_creds usr_creds;
+
+ int type;
+
+ union
+ {
+ struct ncacn_np *smb;
+ struct msrpc_local *local;
+ void *cli;
+ }
+ msrpc;
+
+ cli_auth_fns *auth;
+ void *auth_info;
+ void *auth_creds;
+};
+
+static struct cli_connection **con_list = NULL;
+uint32 num_cons = 0;
+
+void init_connections(void)
+{
+ con_list = NULL;
+ num_cons = 0;
+
+ init_cli_use();
+}
+
+static void free_con_array(uint32 num_entries,
+ struct cli_connection **entries)
+{
+ void (*fn) (void *) = (void (*)(void *))&cli_connection_free;
+ free_void_array(num_entries, (void **)entries, *fn);
+}
+
+static struct cli_connection *add_con_to_array(uint32 * len,
+ struct cli_connection ***array,
+ struct cli_connection *con)
+{
+ return (struct cli_connection *)add_item_to_array(len,
+ (void ***)array,
+ (void *)con);
+
+}
+void free_connections(void)
+{
+ DEBUG(3, ("free_connections: closing all MSRPC connections\n"));
+ free_con_array(num_cons, con_list);
+ free_cli_use();
+
+ init_connections();
+}
+
+static struct cli_connection *cli_con_get(const char *srv_name,
+ const char *pipe_name,
+ cli_auth_fns * auth,
+ void *auth_creds, BOOL reuse)
+{
+ struct cli_connection *con = NULL;
+ BOOL is_new_connection = False;
+
+ vuser_key key;
+
+ con = (struct cli_connection *)malloc(sizeof(*con));
+
+ if (con == NULL)
+ {
+ return NULL;
+ }
+
+ memset(con, 0, sizeof(*con));
+ con->type = MSRPC_NONE;
+
+ copy_user_creds(&con->usr_creds, usr_creds);
+ con->usr_creds.reuse = reuse;
+
+ if (srv_name != NULL)
+ {
+ con->srv_name = strdup(srv_name);
+ }
+ if (pipe_name != NULL)
+ {
+ con->pipe_name = strdup(pipe_name);
+ }
+
+ con->auth_info = NULL;
+ con->auth_creds = auth_creds;
+
+ if (auth != NULL)
+ {
+ con->auth = auth;
+ }
+ else
+ {
+ extern cli_auth_fns cli_noauth_fns;
+ con->auth = &cli_noauth_fns;
+ }
+
+ if (strequal(srv_name, "\\\\."))
+ {
+ con->type = MSRPC_LOCAL;
+ become_root(False);
+ con->msrpc.local = ncalrpc_l_use_add(pipe_name, user_key,
+ True, reuse,
+ &is_new_connection);
+ unbecome_root(False);
+ }
+ else
+ {
+ con->type = MSRPC_SMB;
+ con->msrpc.smb =
+ ncacn_np_use_add(pipe_name, user_key, srv_name,
+ &con->usr_creds.ntc, True, reuse,
+ &is_new_connection);
+ if (con->msrpc.smb != NULL)
+ {
+ key = con->msrpc.smb->smb->nt.key;
+ con->msrpc.smb->smb->nt.key.pid = 0;
+ con->msrpc.smb->smb->nt.key.vuid = UID_FIELD_INVALID;
+ }
+ }
+
+ if (is_new_connection && con->msrpc.cli != NULL)
+ {
+ RPC_IFACE abstract;
+ RPC_IFACE transfer;
+
+ if (!rpc_pipe_bind(con, pipe_name, &abstract, &transfer))
+ {
+ DEBUG(0, ("rpc_pipe_bind failed\n"));
+ cli_connection_free(con);
+ return NULL;
+ }
+ }
+
+ if (con->msrpc.cli == NULL)
+ {
+ cli_connection_free(con);
+ return NULL;
+ }
+
+ if (con->type == MSRPC_SMB)
+ {
+ con->msrpc.smb->smb->nt.key = key;
+ }
+ add_con_to_array(&num_cons, &con_list, con);
+ return con;
+}
+
+/****************************************************************************
+terminate client connection
+****************************************************************************/
+void cli_connection_free(struct cli_connection *con)
+{
+ BOOL closed = False;
+ void *oldcli = NULL;
+ int i;
+
+ DEBUG(10, ("cli_connection_free: %d\n", __LINE__));
+
+ if (con->msrpc.cli != NULL)
+ {
+ switch (con->type)
+ {
+ case MSRPC_LOCAL:
+ {
+ DEBUG(10, ("msrpc local connection\n"));
+ ncalrpc_l_use_del(con->pipe_name,
+ &con->msrpc.local->nt.key,
+ False, &closed);
+ oldcli = con->msrpc.local;
+ con->msrpc.local = NULL;
+ break;
+ }
+ case MSRPC_SMB:
+ {
+ DEBUG(10, ("msrpc smb connection\n"));
+ ncacn_np_use_del(con->pipe_name,
+ &con->msrpc.smb->smb->nt.key,
+ False, &closed);
+ oldcli = con->msrpc.local;
+ con->msrpc.smb = NULL;
+ break;
+ }
+ }
+ }
+
+ DEBUG(10, ("cli_connection_free: closed: %s\n", BOOLSTR(closed)));
+
+ if (closed)
+ {
+ for (i = 0; i < num_cons; i++)
+ {
+ struct cli_connection *c = con_list[i];
+ if (c != NULL && con != c && c->msrpc.cli == oldcli)
+ {
+ /* WHOOPS! fnum already open: too bad!!!
+ get rid of all other connections that
+ were using that connection
+ */
+ switch (c->type)
+ {
+ case MSRPC_LOCAL:
+ {
+ c->msrpc.local = NULL;
+ break;
+ }
+ case MSRPC_SMB:
+ {
+ c->msrpc.smb = NULL;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (con->msrpc.cli != NULL)
+ {
+ free(con->msrpc.cli);
+ }
+ con->msrpc.cli = NULL;
+
+ if (con->srv_name != NULL)
+ {
+ free(con->srv_name);
+ con->srv_name = NULL;
+ }
+ if (con->pipe_name != NULL)
+ {
+ free(con->pipe_name);
+ con->pipe_name = NULL;
+ }
+
+ if (con->auth_info != NULL)
+ {
+ free(con->auth_info);
+ con->auth_info = NULL;
+ }
+
+ memset(&con->usr_creds, 0, sizeof(con->usr_creds));
+
+ for (i = 0; i < num_cons; i++)
+ {
+ if (con == con_list[i])
+ {
+ con_list[i] = NULL;
+ }
+ }
+
+ free(con);
+}
+
+/****************************************************************************
+terminate client state
+****************************************************************************/
+void cli_connection_unlink(struct cli_connection *con)
+{
+ if (con != NULL)
+ {
+ cli_connection_free(con);
+ }
+ return;
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+BOOL cli_connection_init(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con)
+{
+ return cli_connection_init_auth(srv_name, pipe_name, con, NULL, NULL);
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+BOOL cli_connection_init_auth(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con,
+ cli_auth_fns * auth, void *auth_creds)
+{
+ BOOL res = True;
+ BOOL reuse = False;
+
+ /*
+ * allocate
+ */
+
+ DEBUG(10, ("cli_connection_init_auth: %s %s\n",
+ srv_name != NULL ? srv_name : "<null>", pipe_name));
+
+ *con = cli_con_get(srv_name, pipe_name, auth, auth_creds, reuse);
+
+ if ((*con) == NULL)
+ {
+ return False;
+ }
+
+ return res;
+}
+
+/****************************************************************************
+obtain client state
+****************************************************************************/
+BOOL cli_connection_getsrv(const char *srv_name, const char *pipe_name,
+ struct cli_connection **con)
+{
+ int i;
+ struct cli_connection *auth_con = NULL;
+
+ if (con_list == NULL || num_cons == 0)
+ {
+ return False;
+ }
+
+ (*con) = NULL;
+
+ for (i = 0; i < num_cons; i++)
+ {
+ if (con_list[i] != NULL &&
+ strequal(con_list[i]->srv_name, srv_name) &&
+ strequal(con_list[i]->pipe_name, pipe_name))
+ {
+ extern cli_auth_fns cli_noauth_fns;
+ (*con) = con_list[i];
+ /* authenticated connections take priority. HACK! */
+ if ((*con)->auth != &cli_noauth_fns)
+ {
+ auth_con = (*con);
+ }
+ }
+ }
+
+ if (auth_con != NULL)
+ {
+ (*con) = auth_con;
+ }
+
+ return (*con) != NULL;
+}
+
+/****************************************************************************
+obtain client state
+****************************************************************************/
+BOOL cli_connection_get(const POLICY_HND * pol, struct cli_connection **con)
+{
+ return get_policy_con(get_global_hnd_cache(), pol, con);
+}
+
+/****************************************************************************
+link a child policy handle to a parent one
+****************************************************************************/
+BOOL cli_pol_link(POLICY_HND * to, const POLICY_HND * from)
+{
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(from, &con))
+ {
+ DEBUG(0, ("cli_pol_link: no connection\n"));
+ return False;
+ }
+
+ /* fix this when access masks are actually working! */
+ DEBUG(10, ("cli_pol_link: lkclXXXX - MAXIMUM_ALLOWED access_mask\n"));
+
+ return dup_policy_hnd(get_global_hnd_cache(), to, from) &&
+ set_policy_con(get_global_hnd_cache(), to, con, NULL);
+}
+
+/****************************************************************************
+set a user session key associated with a connection
+****************************************************************************/
+BOOL cli_get_usr_sesskey(const POLICY_HND * pol, uchar usr_sess_key[16])
+{
+ struct ntdom_info *nt;
+ struct cli_connection *con;
+ if (!cli_connection_get(pol, &con))
+ {
+ return False;
+ }
+ if (con == NULL)
+ {
+ DEBUG(0, ("cli_get_usr_sesskey: no connection\n"));
+ return False;
+ }
+ nt = cli_conn_get_ntinfo(con);
+ if (nt == NULL)
+ {
+ DEBUG(0, ("cli_get_usr_sesskey: no ntdom_info\n"));
+ return False;
+ }
+
+ memcpy(usr_sess_key, nt->usr_sess_key, sizeof(nt->usr_sess_key));
+
+ return True;
+}
+
+/****************************************************************************
+set a user session key associated with a connection
+****************************************************************************/
+BOOL cli_set_con_usr_sesskey(struct cli_connection *con,
+ const uchar usr_sess_key[16])
+{
+ struct ntdom_info *nt;
+ if (con == NULL)
+ {
+ return False;
+ }
+ nt = cli_conn_get_ntinfo(con);
+ if (nt != NULL)
+ {
+ memcpy(nt->usr_sess_key, usr_sess_key,
+ sizeof(nt->usr_sess_key));
+ }
+
+
+ return True;
+}
+
+/****************************************************************************
+ get auth functions associated with an msrpc session.
+****************************************************************************/
+const vuser_key *cli_con_sec_ctx(struct cli_connection *con)
+{
+ struct ntdom_info *nt;
+ if (con == NULL)
+ {
+ return False;
+ }
+ nt = cli_conn_get_ntinfo(con);
+ if (nt != NULL && nt->key.vuid != UID_FIELD_INVALID)
+ {
+ return &nt->key;
+ }
+ return NULL;
+}
+
+/****************************************************************************
+ get auth functions associated with an msrpc session.
+****************************************************************************/
+struct cli_auth_fns *cli_conn_get_authfns(struct cli_connection *con)
+{
+ return con != NULL ? con->auth : NULL;
+}
+
+/****************************************************************************
+ get auth info associated with an msrpc session.
+****************************************************************************/
+void *cli_conn_get_auth_creds(struct cli_connection *con)
+{
+ return con != NULL ? con->auth_creds : NULL;
+}
+
+/****************************************************************************
+ get auth info associated with an msrpc session.
+****************************************************************************/
+void *cli_conn_get_auth_info(struct cli_connection *con)
+{
+ return con != NULL ? con->auth_info : NULL;
+}
+
+/****************************************************************************
+ set auth info associated with an msrpc session.
+****************************************************************************/
+BOOL cli_conn_set_auth_info(struct cli_connection *con, void *auth_info)
+{
+ con->auth_info = auth_info;
+ return auth_info != NULL;
+}
+
+/****************************************************************************
+ get nt creds (HACK ALERT!) associated with an msrpc session.
+****************************************************************************/
+struct ntdom_info *cli_conn_get_ntinfo(struct cli_connection *con)
+{
+ if (con == NULL)
+ {
+ return NULL;
+ }
+ if (con->msrpc.cli == NULL)
+ {
+ DEBUG(1, ("cli_conn_get_ntinfo: NULL msrpc (closed)\n"));
+ return NULL;
+ }
+
+ switch (con->type)
+ {
+ case MSRPC_LOCAL:
+ {
+ return &con->msrpc.local->nt;
+ }
+ case MSRPC_SMB:
+ {
+ return &con->msrpc.smb->smb->nt;
+ }
+ }
+ return NULL;
+}
+
+/****************************************************************************
+get a user session key associated with a connection associated with a
+policy handle.
+****************************************************************************/
+BOOL cli_get_con_sesskey(struct cli_connection *con, uchar sess_key[16])
+{
+ struct ntdom_info *nt;
+ if (con == NULL)
+ {
+ return False;
+ }
+ nt = cli_conn_get_ntinfo(con);
+ memcpy(sess_key, nt->sess_key, sizeof(nt->sess_key));
+
+ dump_data_pw("sess_key:", sess_key, 16);
+
+ return True;
+}
+
+/****************************************************************************
+get a server name associated with a connection associated with a
+policy handle.
+****************************************************************************/
+BOOL cli_con_get_srvname(struct cli_connection *con, char *srv_name)
+{
+ char *desthost = NULL;
+
+ if (con == NULL)
+ {
+ return False;
+ }
+
+ switch (con->type)
+ {
+ case MSRPC_SMB:
+ {
+ desthost = con->msrpc.smb->smb->desthost;
+ break;
+ }
+ case MSRPC_LOCAL:
+ {
+ desthost = con->srv_name;
+ break;
+ }
+ }
+
+ if (strnequal("\\\\", desthost, 2))
+ {
+ fstrcpy(srv_name, desthost);
+ }
+ else
+ {
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, desthost);
+ }
+
+ return True;
+}
+
+/****************************************************************************
+get a user session key associated with a connection associated with a
+policy handle.
+****************************************************************************/
+BOOL cli_get_sesskey(const POLICY_HND * pol, uchar sess_key[16])
+{
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(pol, &con))
+ {
+ return False;
+ }
+
+ return cli_get_con_sesskey(con, sess_key);
+}
+
+/****************************************************************************
+get a user session key associated with a connection associated with a
+policy handle.
+****************************************************************************/
+BOOL cli_get_sesskey_srv(const char *srv_name, uchar sess_key[16])
+{
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
+ {
+ return False;
+ }
+
+ return cli_get_con_sesskey(con, sess_key);
+}
+
+/****************************************************************************
+get a user session key associated with a connection associated with a
+policy handle.
+****************************************************************************/
+void cli_con_gen_next_creds(struct cli_connection *con,
+ DOM_CRED * new_clnt_cred)
+{
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+ gen_next_creds(nt, new_clnt_cred);
+}
+
+/****************************************************************************
+get a user session key associated with a connection associated with a
+policy handle.
+****************************************************************************/
+void cli_con_get_cli_cred(struct cli_connection *con, DOM_CRED * clnt_cred)
+{
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+ memcpy(clnt_cred, &nt->clnt_cred, sizeof(*clnt_cred));
+}
+
+/****************************************************************************
+get a user session key associated with a connection associated with a
+policy handle.
+****************************************************************************/
+BOOL cli_con_deal_with_creds(struct cli_connection *con,
+ DOM_CRED * rcv_srv_cred)
+{
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+ return clnt_deal_with_creds(nt->sess_key, &nt->clnt_cred,
+ rcv_srv_cred);
+}
+
+/****************************************************************************
+get a user session key associated with a connection associated with a
+policy handle.
+****************************************************************************/
+BOOL cli_con_set_creds(const char *srv_name, const uchar sess_key[16],
+ DOM_CRED * cred)
+{
+ struct cli_connection *con = NULL;
+ struct ntdom_info *nt;
+
+ if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
+ {
+ return False;
+ }
+
+ nt = cli_conn_get_ntinfo(con);
+
+ memcpy(nt->sess_key, sess_key, 16);
+ memcpy(&nt->clnt_cred, cred, sizeof(*cred));
+
+ return True;
+}
+
+/****************************************************************************
+ send a request on an rpc pipe.
+ ****************************************************************************/
+BOOL rpc_hnd_pipe_req(const POLICY_HND * hnd, uint8 op_num,
+ prs_struct * data, prs_struct * rdata)
+{
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(hnd, &con))
+ {
+ return False;
+ }
+
+ return rpc_con_pipe_req(con, op_num, data, rdata);
+}
+
+/****************************************************************************
+ send a request on an rpc pipe.
+ ****************************************************************************/
+BOOL rpc_con_pipe_req(struct cli_connection *con, uint8 op_num,
+ prs_struct * data, prs_struct * rdata)
+{
+ DEBUG(10, ("rpc_con_pipe_req: op_num %d offset %d used: %d\n",
+ op_num, data->offset, data->data_size));
+ prs_realloc_data(data, data->offset);
+ return rpc_api_pipe_req(con, op_num, data, rdata);
+}
+
+/****************************************************************************
+ write to a pipe
+****************************************************************************/
+BOOL rpc_api_write(struct cli_connection *con, prs_struct * data)
+{
+ switch (con->type)
+ {
+ case MSRPC_SMB:
+ {
+ struct cli_state *cli = con->msrpc.smb->smb;
+ int fnum = con->msrpc.smb->fnum;
+ return cli_write(cli, fnum, 0x0008,
+ data->data, 0,
+ data->data_size,
+ data->data_size) > 0;
+ }
+ case MSRPC_LOCAL:
+ {
+ data->offset = data->data_size;
+ prs_link(NULL, data, NULL);
+ return msrpc_send(con->msrpc.local->fd, data);
+ }
+ }
+ return False;
+}
+
+BOOL rpc_api_rcv_pdu(struct cli_connection *con, prs_struct * rdata)
+{
+ switch (con->type)
+ {
+ case MSRPC_SMB:
+ {
+ struct cli_state *cli = con->msrpc.smb->smb;
+ int fnum = con->msrpc.smb->fnum;
+ return cli_rcv_pdu(con, cli, fnum, rdata);
+ }
+ case MSRPC_LOCAL:
+ {
+ BOOL ret;
+ ret = msrpc_send(con->msrpc.local->fd, NULL);
+ ret = msrpc_receive(con->msrpc.local->fd, rdata);
+ rdata->io = True;
+ rdata->offset = 0;
+ rdata->start = 0;
+ rdata->end = rdata->data_size;
+ return ret;
+ }
+ }
+ return False;
+}
+
+BOOL rpc_api_send_rcv_pdu(struct cli_connection *con, prs_struct * data,
+ prs_struct * rdata)
+{
+ switch (con->type)
+ {
+ case MSRPC_SMB:
+ {
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+ struct cli_state *cli = con->msrpc.smb->smb;
+ int fnum = con->msrpc.smb->fnum;
+ return cli_send_and_rcv_pdu(con, cli, fnum, data,
+ rdata, nt->max_xmit_frag);
+ }
+ case MSRPC_LOCAL:
+ {
+ BOOL ret;
+ data->offset = data->data_size;
+ prs_link(NULL, data, NULL);
+ ret = msrpc_send(con->msrpc.local->fd, data) &&
+ msrpc_receive(con->msrpc.local->fd, rdata);
+ rdata->io = True;
+ rdata->offset = 0;
+ rdata->start = 0;
+ rdata->end = rdata->data_size;
+ return ret;
+ }
+ }
+ return False;
+}
+
+/* connection policy state-info */
+
+struct con_info
+{
+ struct cli_connection *con;
+ void (*free_con) (struct cli_connection *);
+};
+
+static void free_policy_con(void *dev)
+{
+ struct con_info *con = (struct con_info *)dev;
+ DEBUG(10, ("free policy connection\n"));
+ if (con->free_con != NULL)
+ {
+ con->free_con(con->con);
+ }
+ free(dev);
+}
+
+/****************************************************************************
+ set con state
+****************************************************************************/
+BOOL set_policy_con(struct policy_cache *cache, POLICY_HND * hnd,
+ struct cli_connection *con,
+ void (*free_fn) (struct cli_connection *))
+{
+ struct con_info *dev = (struct con_info *)malloc(sizeof(*dev));
+
+ if (dev != NULL)
+ {
+ dev->con = con;
+ dev->free_con = free_fn;
+ if (set_policy_state
+ (cache, hnd, free_policy_con, (void *)dev))
+ {
+ DEBUG(3, ("setting policy con\n"));
+ return True;
+ }
+ free(dev);
+ }
+
+ DEBUG(3, ("Error setting policy con state\n"));
+ return False;
+}
+
+/****************************************************************************
+ get con state
+****************************************************************************/
+BOOL get_policy_con(struct policy_cache *cache, const POLICY_HND * hnd,
+ struct cli_connection **con)
+{
+ struct con_info *dev;
+ dev = (struct con_info *)get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ DEBUG(3, ("Getting policy con state\n"));
+ (*con) = dev->con;
+ return True;
+ }
+
+ DEBUG(3, ("Error getting policy con state\n"));
+ return False;
+}
diff --git a/source/rpc_client/cli_eventlog.c b/source/rpc_client/cli_eventlog.c
new file mode 100644
index 00000000000..435c125cf98
--- /dev/null
+++ b/source/rpc_client/cli_eventlog.c
@@ -0,0 +1,207 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 2.1.
+ * RPC client routines: scheduler service
+ * Copyright (C) Jean Francois Micouleau 1998-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Andrew Tridgell 1992-1999.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+****************************************************************************/
+BOOL event_open(const char* srv_name, const char *log, POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ EVENTLOG_Q_OPEN q;
+ BOOL p = False;
+ BOOL valid_pol = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_EVENTLOG, &con))
+ {
+ return False;
+ }
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* store the parameters */
+ make_eventlog_q_open(&q, log, NULL);
+
+ /* turn parameters into data stream */
+ if (eventlog_io_q_open("", &q, &buf, 0) &&
+ rpc_con_pipe_req(con, EVENTLOG_OPEN, &buf, &rbuf))
+ {
+ EVENTLOG_R_OPEN r;
+
+ eventlog_io_r_open("", &r, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("event_open: %s\n", get_nt_error_msg(r.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ DEBUG(0,("event_open: unk_6 or unk_7 is an access mask\n"));
+ /*copy handle */
+ *hnd->data = *r.pol.data;
+ valid_pol = register_policy_hnd(get_global_hnd_cache(), cli_con_sec_ctx(con),
+ hnd, 0x01) &&
+ set_policy_con(get_global_hnd_cache(), hnd, con,
+ cli_connection_unlink);
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return p;
+}
+
+/****************************************************************************
+****************************************************************************/
+BOOL event_close( POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ EVENTLOG_Q_CLOSE q;
+ BOOL p = False;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* store the parameters */
+ make_eventlog_q_close(&q, hnd);
+
+ /* turn parameters into data stream */
+ if (eventlog_io_q_close("", &q, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, EVENTLOG_CLOSE, &buf, &rbuf))
+ {
+ EVENTLOG_R_CLOSE r;
+
+ eventlog_io_r_close("", &r, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("event_close: %s\n", get_nt_error_msg(r.status)));
+ p = False;
+ }
+
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ close_policy_hnd(get_global_hnd_cache(), hnd);
+
+ return p;
+}
+
+/****************************************************************************
+****************************************************************************/
+BOOL event_numofeventlogrec( POLICY_HND *hnd, uint32 *number)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ EVENTLOG_Q_NUMOFEVENTLOGREC q;
+ BOOL p = False;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* store the parameters */
+ make_eventlog_q_numofeventlogrec(&q, hnd);
+
+ /* turn parameters into data stream */
+ if (eventlog_io_q_numofeventlogrec("", &q, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, EVENTLOG_NUMOFEVENTLOGRECORDS, &buf, &rbuf))
+ {
+ EVENTLOG_R_NUMOFEVENTLOGREC r;
+
+ eventlog_io_r_numofeventlogrec("", &r, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("event_close: %s\n", get_nt_error_msg(r.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ *number=r.number;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return p;
+}
+
+/****************************************************************************
+****************************************************************************/
+BOOL event_readeventlog(POLICY_HND *hnd,
+ uint32 number, uint32 flags, uint32 offset,
+ uint32 *number_of_bytes, EVENTLOGRECORD *ev)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ EVENTLOG_Q_READEVENTLOG q;
+ EVENTLOG_R_READEVENTLOG r;
+ BOOL p = False;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* store the parameters */
+ make_eventlog_q_readeventlog(&q, hnd, flags, offset, *number_of_bytes);
+
+ /* turn parameters into data stream */
+ if (eventlog_io_q_readeventlog("", &q, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, EVENTLOG_READEVENTLOG, &buf, &rbuf))
+ {
+ r.event=ev;
+ eventlog_io_r_readeventlog("", &r, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p)
+ {
+ *number_of_bytes=r.real_size;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return p;
+}
+
diff --git a/source/rpc_client/cli_login.c b/source/rpc_client/cli_login.c
index 5fe392f2148..ae6aff300e3 100644
--- a/source/rpc_client/cli_login.c
+++ b/source/rpc_client/cli_login.c
@@ -2,9 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1994-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Jeremy Allison 1999.
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,132 +21,210 @@
*/
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
-extern fstring global_myworkgroup;
-extern pstring global_myname;
/****************************************************************************
Initialize domain session credentials.
****************************************************************************/
-BOOL cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
+uint32 cli_nt_setup_creds(const char *srv_name,
+ const char *domain,
+ const char *myhostname,
+ const char *trust_acct,
+ const uchar trust_pwd[16], uint16 sec_chan)
{
- DOM_CHAL clnt_chal;
- DOM_CHAL srv_chal;
-
- UTIME zerotime;
-
- /******************* Request Challenge ********************/
-
- generate_random_buffer( clnt_chal.data, 8, False);
-
- /* send a client challenge; receive a server challenge */
- if (!cli_net_req_chal(cli, &clnt_chal, &srv_chal))
- {
- DEBUG(0,("cli_nt_setup_creds: request challenge failed\n"));
- return False;
- }
-
- /**************** Long-term Session key **************/
-
- /* calculate the session key */
- cred_session_key(&clnt_chal, &srv_chal, (char *)mach_pwd, cli->sess_key);
- memset((char *)cli->sess_key+8, '\0', 8);
-
- /******************* Authenticate 2 ********************/
-
- /* calculate auth-2 credentials */
- zerotime.time = 0;
- cred_create(cli->sess_key, &clnt_chal, zerotime, &(cli->clnt_cred.challenge));
-
- /*
- * Send client auth-2 challenge.
- * Receive an auth-2 challenge response and check it.
- */
-
- if (!cli_net_auth2(cli, SEC_CHAN_WKSTA, 0x000001ff, &srv_chal))
- {
- DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed\n"));
- return False;
- }
-
- return True;
+ DOM_CHAL clnt_chal;
+ DOM_CHAL srv_chal;
+ uint32 ret;
+ UTIME zerotime;
+ uint8 sess_key[16];
+ DOM_CRED clnt_cred;
+ uint32 neg_flags = !lp_client_schannel()? 0x000001ff : 0x400001ff;
+
+ /******************* Request Challenge ********************/
+
+ generate_random_buffer(clnt_chal.data, 8, False);
+
+ /* send a client challenge; receive a server challenge */
+ ret = cli_net_req_chal(srv_name, myhostname, &clnt_chal, &srv_chal);
+ if (ret != 0)
+ {
+ DEBUG(1, ("cli_nt_setup_creds: request challenge failed\n"));
+ return ret;
+ }
+
+ /**************** Long-term Session key **************/
+
+ /* calculate the session key */
+ cred_session_key(&clnt_chal, &srv_chal, trust_pwd, sess_key);
+ bzero(sess_key + 8, 8);
+
+ /******************* Authenticate 2 ********************/
+
+ /* calculate auth-2 credentials */
+ zerotime.time = 0;
+ cred_create(sess_key, &clnt_chal, zerotime, &clnt_cred.challenge);
+
+ if (!cli_con_set_creds(srv_name, sess_key, &clnt_cred))
+ {
+ return NT_STATUS_ACCESS_DENIED | 0xC0000000;
+ }
+
+ /*
+ * Send client auth-2 challenge.
+ * Receive an auth-2 challenge response and check it.
+ */
+ ret = cli_net_auth2(srv_name, trust_acct, myhostname,
+ sec_chan, &neg_flags, &srv_chal);
+ if (ret != 0x0)
+ {
+ DEBUG(1,
+ ("cli_nt_setup_creds: auth2 challenge failed. status: %x\n",
+ ret));
+ }
+
+ /* check the client secure channel status */
+ if (ret == 0x0 &&
+ lp_client_schannel() == True &&
+ IS_BITS_CLR_ALL(neg_flags, 0x40000000))
+ {
+ /* netlogon secure channel was required, and not negotiated */
+ return NT_STATUS_ACCESS_DENIED | 0xC0000000;
+ }
+
+ if (ret == 0x0 && IS_BITS_SET_ALL(neg_flags, 0x40000000))
+ {
+ extern cli_auth_fns cli_netsec_fns;
+ struct cli_connection *con = NULL;
+ struct netsec_creds creds;
+
+ safe_strcpy(creds.domain, domain, sizeof(creds.myname) - 1);
+ safe_strcpy(creds.myname, myhostname,
+ sizeof(creds.myname) - 1);
+ memcpy(creds.sess_key, sess_key, sizeof(creds.sess_key));
+
+ if (!cli_connection_init_auth(srv_name, PIPE_NETLOGON, &con,
+ &cli_netsec_fns,
+ (void *)&creds))
+ {
+ return NT_STATUS_ACCESS_DENIED | 0xC0000000;
+ }
+ if (!cli_con_set_creds(srv_name, sess_key, &clnt_cred))
+ {
+ cli_connection_free(con);
+ return NT_STATUS_ACCESS_DENIED | 0xC0000000;
+ }
+ }
+ return ret;
}
/****************************************************************************
Set machine password.
****************************************************************************/
-BOOL cli_nt_srv_pwset(struct cli_state *cli, unsigned char *new_hashof_mach_pwd)
+BOOL cli_nt_srv_pwset(const char *srv_name, const char *myhostname,
+ const char *trust_acct,
+ const uchar * new_hashof_trust_pwd, uint16 sec_chan)
{
- unsigned char processed_new_pwd[16];
-
- DEBUG(5,("cli_nt_srv_pwset: %d\n", __LINE__));
+ DEBUG(5, ("cli_nt_srv_pwset: %d\n", __LINE__));
#ifdef DEBUG_PASSWORD
- dump_data(6, (char *)new_hashof_mach_pwd, 16);
+ dump_data(6, new_hashof_trust_pwd, 16);
#endif
- /* Process the new password. */
- cred_hash3( processed_new_pwd, new_hashof_mach_pwd, cli->sess_key, 1);
-
- /* send client srv_pwset challenge */
- return cli_net_srv_pwset(cli, processed_new_pwd);
+ /* send client srv_pwset challenge */
+ return cli_net_srv_pwset(srv_name, myhostname, trust_acct,
+ new_hashof_trust_pwd, sec_chan);
}
/****************************************************************************
-NT login - interactive.
+NT login - general.
*NEVER* use this code. This method of doing a logon (sending the cleartext
password equivalents, protected by the session key) is inherently insecure
given the current design of the NT Domain system. JRA.
****************************************************************************/
-BOOL cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username,
- uint32 smb_userid_low, char *password,
- NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
+BOOL cli_nt_login_general(const char *srv_name, const char *myhostname,
+ const char *domain, const char *username,
+ uint32 luid_low,
+ const char *general,
+ NET_ID_INFO_CTR * ctr, NET_USER_INFO_3 * user_info3)
{
- uchar lm_owf_user_pwd[16];
- uchar nt_owf_user_pwd[16];
- BOOL ret;
+ uint8 sess_key[16];
- DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
-
- nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
+ DEBUG(5, ("cli_nt_login_general: %d\n", __LINE__));
#ifdef DEBUG_PASSWORD
- DEBUG(100,("nt owf of user password: "));
- dump_data(100, (char *)lm_owf_user_pwd, 16);
+ DEBUG(100, ("\"general\" user password: "));
+ dump_data(100, general, strlen(general));
+#endif
- DEBUG(100,("nt owf of user password: "));
- dump_data(100, (char *)nt_owf_user_pwd, 16);
+ if (!cli_get_sesskey_srv(srv_name, sess_key))
+ {
+ DEBUG(1, ("could not obtain session key for %s\n", srv_name));
+ return False;
+ }
-#endif
+ /* indicate an "general" login */
+ ctr->switch_value = GENERAL_LOGON_TYPE;
- DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
+ /* Create the structure needed for SAM logon. */
+ make_id_info4(&ctr->auth.id4, domain, 0,
+ luid_low, 0, username, myhostname, general);
- /* indicate an "interactive" login */
- ctr->switch_value = INTERACTIVE_LOGON_TYPE;
+ /* Send client sam-logon request - update credentials on success. */
+ return cli_net_sam_logon(srv_name, myhostname, ctr, user_info3);
+}
+
+/****************************************************************************
+NT login - interactive.
+*NEVER* use this code. This method of doing a logon (sending the cleartext
+password equivalents, protected by the session key) is inherently insecure
+given the current design of the NT Domain system. JRA.
+ ****************************************************************************/
+BOOL cli_nt_login_interactive(const char *srv_name, const char *myhostname,
+ const char *domain, const char *username,
+ uint32 luid_low,
+ const uchar * lm_owf_user_pwd,
+ const uchar * nt_owf_user_pwd,
+ NET_ID_INFO_CTR * ctr,
+ NET_USER_INFO_3 * user_info3)
+{
+ BOOL ret;
+ uint8 sess_key[16];
- /* Create the structure needed for SAM logon. */
- init_id_info1(&ctr->auth.id1, domain, 0,
- smb_userid_low, 0,
- username, cli->clnt_name_slash,
- (char *)cli->sess_key, lm_owf_user_pwd, nt_owf_user_pwd);
+ DEBUG(5, ("cli_nt_login_interactive: %d\n", __LINE__));
- /* Ensure we overwrite all the plaintext password
- equivalents. */
- memset(lm_owf_user_pwd, '\0', sizeof(lm_owf_user_pwd));
- memset(nt_owf_user_pwd, '\0', sizeof(nt_owf_user_pwd));
+ dump_data_pw("nt owf of user password:\n", lm_owf_user_pwd, 16);
+ dump_data_pw("nt owf of user password:\n", nt_owf_user_pwd, 16);
- /* Send client sam-logon request - update credentials on success. */
- ret = cli_net_sam_logon(cli, ctr, user_info3);
+ if (!cli_get_sesskey_srv(srv_name, sess_key))
+ {
+ DEBUG(1, ("could not obtain session key for %s\n", srv_name));
+ return False;
+ }
- memset(ctr->auth.id1.lm_owf.data, '\0', sizeof(lm_owf_user_pwd));
- memset(ctr->auth.id1.nt_owf.data, '\0', sizeof(nt_owf_user_pwd));
+ /* indicate an "interactive" login */
+ ctr->switch_value = INTERACTIVE_LOGON_TYPE;
- return ret;
+ /* Create the structure needed for SAM logon. */
+ make_id_info1(&ctr->auth.id1, domain, 0,
+ luid_low, 0,
+ username, myhostname,
+ (char *)sess_key, lm_owf_user_pwd, nt_owf_user_pwd);
+
+ /* Send client sam-logon request - update credentials on success. */
+ ret = cli_net_sam_logon(srv_name, myhostname, ctr, user_info3);
+
+ memset(ctr->auth.id1.lm_owf.data, '\0',
+ sizeof(ctr->auth.id1.lm_owf.data));
+ memset(ctr->auth.id1.nt_owf.data, '\0',
+ sizeof(ctr->auth.id1.nt_owf.data));
+
+ return ret;
}
/****************************************************************************
@@ -156,33 +233,106 @@ NT login - network.
password equivalents over the network. JRA.
****************************************************************************/
-BOOL cli_nt_login_network(struct cli_state *cli, char *domain, char *username,
- uint32 smb_userid_low, char lm_chal[8], char lm_chal_resp[24],
- char nt_chal_resp[24],
- NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
+BOOL cli_nt_login_network(const char *srv_name, const char *myhostname,
+ const char *domain, const char *username,
+ uint32 luid_low, const char lm_chal[8],
+ const char *lm_chal_resp,
+ int lm_chal_len,
+ const char *nt_chal_resp,
+ int nt_chal_len,
+ NET_ID_INFO_CTR * ctr, NET_USER_INFO_3 * user_info3)
{
- DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
+ uint8 sess_key[16];
+ BOOL ret;
+ DEBUG(5, ("cli_nt_login_network: %d\n", __LINE__));
+
+ if (!cli_get_sesskey_srv(srv_name, sess_key))
+ {
+ DEBUG(1, ("could not obtain session key for %s\n", srv_name));
+ return False;
+ }
+
+ /* indicate a "network" login */
+ ctr->switch_value = NETWORK_LOGON_TYPE;
+
+ /* Create the structure needed for SAM logon. */
+ make_id_info2(&ctr->auth.id2, domain, 0,
+ luid_low, 0,
+ username, myhostname,
+ lm_chal,
+ lm_chal_resp, lm_chal_len, nt_chal_resp, nt_chal_len);
- /* indicate a "network" login */
- ctr->switch_value = NET_LOGON_TYPE;
+ /* Send client sam-logon request - update credentials on success. */
+ ret = cli_net_sam_logon(srv_name, myhostname, ctr, user_info3);
- /* Create the structure needed for SAM logon. */
- init_id_info2(&ctr->auth.id2, domain, 0,
- smb_userid_low, 0,
- username, cli->clnt_name_slash,
- (uchar *)lm_chal, (uchar *)lm_chal_resp, (uchar *)nt_chal_resp);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("cli sess key:"));
+ dump_data(100, sess_key, 8);
+ DEBUG(100, ("enc padding:"));
+ dump_data(100, user_info3->padding, 8);
+ DEBUG(100, ("enc user sess key:"));
+ dump_data(100, user_info3->user_sess_key, 16);
+#endif
+
+ SamOEMhash(user_info3->user_sess_key, sess_key, 0);
+ SamOEMhash(user_info3->padding, sess_key, 3);
- /* Send client sam-logon request - update credentials on success. */
- return cli_net_sam_logon(cli, ctr, user_info3);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("dec paddin:"));
+ dump_data(100, user_info3->padding, 8);
+ DEBUG(100, ("dec user sess key:"));
+ dump_data(100, user_info3->user_sess_key, 16);
+#endif
+ return ret;
}
/****************************************************************************
NT Logoff.
****************************************************************************/
-BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
+BOOL cli_nt_logoff(const char *srv_name, const char *myhostname,
+ NET_ID_INFO_CTR * ctr)
+{
+ DEBUG(5, ("cli_nt_logoff: %d\n", __LINE__));
+
+ /* Send client sam-logoff request - update credentials on success. */
+ return cli_net_sam_logoff(srv_name, myhostname, ctr);
+}
+
+/****************************************************************************
+NT SAM database sync
+****************************************************************************/
+BOOL net_sam_sync(const char *srv_name,
+ const char *domain,
+ const char *myhostname,
+ const char *trust_acct,
+ uchar trust_passwd[16],
+ SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS],
+ SAM_DELTA_CTR deltas[MAX_SAM_DELTAS], uint32 * num_deltas)
{
- DEBUG(5,("cli_nt_logoff: %d\n", __LINE__));
+ BOOL res = True;
+
+ *num_deltas = 0;
+
+ DEBUG(5, ("Attempting SAM sync with PDC: %s\n", srv_name));
+
+ res = res ? cli_nt_setup_creds(srv_name, domain, myhostname,
+ trust_acct,
+ trust_passwd,
+ SEC_CHAN_BDC) == 0x0 : False;
+
+ memset(trust_passwd, 0, 16);
+
+ res = res ? cli_net_sam_sync(srv_name, myhostname,
+ 0, num_deltas, hdr_deltas,
+ deltas) : False;
+
+ if (!res)
+ {
+ DEBUG(5, ("SAM synchronisation FAILED\n"));
+ return False;
+ }
+
+ DEBUG(5, ("SAM synchronisation returned %d entries\n", *num_deltas));
- /* Send client sam-logoff request - update credentials on success. */
- return cli_net_sam_logoff(cli, ctr);
+ return True;
}
diff --git a/source/rpc_client/cli_lsarpc.c b/source/rpc_client/cli_lsarpc.c
index 34201ebc16f..f350e7ede58 100644
--- a/source/rpc_client/cli_lsarpc.c
+++ b/source/rpc_client/cli_lsarpc.c
@@ -6,7 +6,6 @@
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jeremy Allison 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,183 +28,960 @@
#endif
#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
extern int DEBUGLEVEL;
+/****************************************************************************
+ obtain the sid from the PDC. do some verification along the way...
+****************************************************************************/
+BOOL get_domain_sids(const char *domain, DOM_SID * sid3, DOM_SID * sid5)
+{
+ POLICY_HND pol;
+ fstring srv_name;
+ BOOL res = True;
+ BOOL res1 = True;
+ fstring dom3;
+ fstring dom5;
+
+ if (sid3 == NULL && sid5 == NULL)
+ {
+ /* don't waste my time... */
+ return False;
+ }
+
+ if (!get_any_dc_name(domain, srv_name))
+ {
+ return False;
+ }
+
+ /*
+ * Ok - we have an anonymous connection to the IPC$ share.
+ * Now start the NT Domain stuff :-).
+ */
+
+ fstrcpy(dom3, "");
+ fstrcpy(dom5, "");
+ if (sid3 != NULL)
+ {
+ ZERO_STRUCTP(sid3);
+ }
+ if (sid5 != NULL)
+ {
+ ZERO_STRUCTP(sid5);
+ }
+
+ /* lookup domain controller; receive a policy handle */
+ res =
+ res ? lsa_open_policy(srv_name, &pol, False,
+ 0x02000000) : False;
+
+ if (sid3 != NULL)
+ {
+ /* send client info query, level 3. receive domain name and sid */
+ res1 = res ? lsa_query_info_pol(&pol, 3, dom3, sid3) : False;
+ }
+
+ if (sid5 != NULL)
+ {
+ /* send client info query, level 5. receive domain name and sid */
+ res1 = res1 ? lsa_query_info_pol(&pol, 5, dom5, sid5) : False;
+ }
+
+ /* close policy handle */
+ res = res ? lsa_close(&pol) : False;
+
+ if (res1)
+ {
+ pstring sid;
+ DEBUG(2, ("LSA Query Info Policy\n"));
+ if (sid3 != NULL)
+ {
+ sid_to_string(sid, sid3);
+ DEBUG(2,
+ ("Domain Member - Domain: %s SID: %s\n",
+ dom3, sid));
+ }
+ if (sid5 != NULL)
+ {
+ sid_to_string(sid, sid5);
+ DEBUG(2,
+ ("Domain Controller - Domain: %s SID: %s\n",
+ dom5, sid));
+ }
+ }
+ else
+ {
+ DEBUG(1, ("lsa query info failed\n"));
+ }
+ return res;
+}
+
+#if 0
/****************************************************************************
-do a LSA Open Policy
+ obtain a sid and domain name from a Domain Controller.
****************************************************************************/
+BOOL get_trust_sid_and_domain(const char *myname, char *server,
+ DOM_SID * sid, char *domain, size_t len)
+{
+ POLICY_HND pol;
+ fstring srv_name;
+ struct cli_connection *con = NULL;
+ BOOL res = True;
+ BOOL res1 = True;
+ DOM_SID sid3;
+ DOM_SID sid5;
+ fstring dom3;
+ fstring dom5;
+
+ if (!cli_connection_init_list(server, PIPE_LSARPC, &con))
+ {
+ DEBUG(0,
+ ("get_trust_sid: unable to initialise client connection.\n"));
+ return False;
+ }
+
+ fstrcpy(dom3, "");
+ fstrcpy(dom5, "");
+ ZERO_STRUCT(sid3);
+ ZERO_STRUCT(sid5);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, myname);
+ strupper(srv_name);
+
+ /* lookup domain controller; receive a policy handle */
+ res =
+ res ? lsa_open_policy(srv_name, &pol, False,
+ 0x02000000) : False;
+
+ /* send client info query, level 3. receive domain name and sid */
+ res1 = res ? lsa_query_info_pol(&pol, 3, dom3, &sid3) : False;
+
+ /* send client info query, level 5. receive domain name and sid */
+ res1 = res1 ? lsa_query_info_pol(&pol, 5, dom5, &sid5) : False;
+
+ /* close policy handle */
+ res = res ? lsa_close(&pol) : False;
+
+ if (res1)
+ {
+ pstring sid_str;
+ DEBUG(2, ("LSA Query Info Policy\n"));
+ sid_to_string(sid_str, &sid3);
+ DEBUG(2, ("Domain Member - Domain: %s SID: %s\n",
+ dom3, sid_str));
+ sid_to_string(sid_str, &sid5);
+ DEBUG(2, ("Domain Controller - Domain: %s SID: %s\n",
+ dom5, sid_str));
+
+ if (dom5[0] != 0 && sid_equal(&sid3, &sid5))
+ {
+ safe_strcpy(domain, dom5, len);
+ sid_copy(sid, &sid5);
+ }
+ else
+ {
+ DEBUG(2, ("Server %s is not a PDC\n", server));
+ return False;
+ }
-BOOL do_lsa_open_policy(struct cli_state *cli,
- char *system_name, POLICY_HND *hnd,
- BOOL sec_qos)
+ }
+ else
+ {
+ DEBUG(1, ("lsa query info failed\n"));
+ }
+
+ return res1;
+}
+#endif
+
+/****************************************************************************
+do a LSA Open Policy
+****************************************************************************/
+BOOL lsa_open_policy(const char *system_name, POLICY_HND *hnd,
+ BOOL sec_qos, uint32 des_access)
{
prs_struct rbuf;
- prs_struct buf;
+ prs_struct buf;
LSA_Q_OPEN_POL q_o;
LSA_SEC_QOS qos;
- LSA_R_OPEN_POL r_o;
+ BOOL valid_pol = False;
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(system_name, PIPE_LSARPC, &con))
+ {
+ return False;
+ }
if (hnd == NULL)
return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL );
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
/* create and send a MSRPC command with api LSA_OPENPOLICY */
- DEBUG(4,("LSA Open Policy\n"));
+ DEBUG(4, ("LSA Open Policy\n"));
/* store the parameters */
- if (sec_qos) {
- init_lsa_sec_qos(&qos, 2, 1, 0, 0x20000000);
- init_q_open_pol(&q_o, 0x5c, 0, 0, &qos);
- } else {
- init_q_open_pol(&q_o, 0x5c, 0, 0x1, NULL);
+ if (sec_qos)
+ {
+ make_lsa_sec_qos(&qos, 2, 1, 0, des_access);
+ make_q_open_pol(&q_o, 0x5c, 0, des_access, &qos);
+ }
+ else
+ {
+ make_q_open_pol(&q_o, 0x5c, 0, des_access, NULL);
}
/* turn parameters into data stream */
- if(!lsa_io_q_open_pol("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
+ if (lsa_io_q_open_pol("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, LSA_OPENPOLICY, &buf, &rbuf))
+ {
+ LSA_R_OPEN_POL r_o;
+ BOOL p;
+
+ lsa_io_r_open_pol("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,
+ ("LSA_OPENPOLICY: %s\n",
+ get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.pol;
+
+ valid_pol =
+ register_policy_hnd(get_global_hnd_cache(),
+ cli_con_sec_ctx(con), hnd,
+ des_access)
+ && set_policy_con(get_global_hnd_cache(), hnd,
+ con, cli_connection_unlink);
+ if (valid_pol)
+ {
+ policy_hnd_set_name(get_global_hnd_cache(),
+ hnd, "LSA_OPENPOL");
+ }
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a LSA Open Policy2
+****************************************************************************/
+BOOL lsa_open_policy2(const char *system_name, POLICY_HND *hnd,
+ BOOL sec_qos, uint32 des_access)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_OPEN_POL2 q_o;
+ LSA_SEC_QOS qos;
+ BOOL valid_pol = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(system_name, PIPE_LSARPC, &con))
+ {
return False;
}
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, LSA_OPENPOLICY, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
+ if (hnd == NULL)
return False;
+
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
+
+ /* create and send a MSRPC command with api LSA_OPENPOLICY2 */
+
+ DEBUG(4, ("LSA Open Policy2\n"));
+
+ /* store the parameters */
+ if (sec_qos)
+ {
+ make_lsa_sec_qos(&qos, 2, 1, 0, des_access);
+ make_q_open_pol2(&q_o, system_name, 0, des_access, &qos);
+ }
+ else
+ {
+ make_q_open_pol2(&q_o, system_name, 0, des_access, NULL);
}
- prs_mem_free(&buf);
+ /* turn parameters into data stream */
+ if (lsa_io_q_open_pol2("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, LSA_OPENPOLICY2, &buf, &rbuf))
+ {
+ LSA_R_OPEN_POL2 r_o;
+ BOOL p;
+
+ lsa_io_r_open_pol2("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,
+ ("LSA_OPENPOLICY2: %s\n",
+ get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if(!lsa_io_r_open_pol("", &r_o, &rbuf, 0)) {
- DEBUG(0,("do_lsa_open_policy: Failed to unmarshall LSA_R_OPEN_POL\n"));
- prs_mem_free(&rbuf);
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.pol;
+
+ valid_pol =
+ register_policy_hnd(get_global_hnd_cache(),
+ cli_con_sec_ctx(con), hnd,
+ des_access)
+ && set_policy_con(get_global_hnd_cache(), hnd,
+ con, cli_connection_unlink);
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a LSA Create Secret
+****************************************************************************/
+BOOL lsa_create_secret(const POLICY_HND *hnd,
+ const char *secret_name,
+ uint32 des_access, POLICY_HND *hnd_secret)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_CREATE_SECRET q_o;
+ BOOL valid_pol = False;
+
+ if (hnd == NULL)
return False;
+
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
+
+ /* create and send a MSRPC command with api LSA_CREATE_SECRET */
+
+ DEBUG(4, ("LSA Create Secret\n"));
+
+ make_q_create_secret(&q_o, hnd, secret_name, des_access);
+
+ /* turn parameters into data stream */
+ if (lsa_io_q_create_secret("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, LSA_CREATESECRET, &buf, &rbuf))
+ {
+ LSA_R_CREATE_SECRET r_o;
+ BOOL p;
+
+ lsa_io_r_create_secret("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,
+ ("LSA_OPENSECRET: %s\n",
+ get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd_secret = r_o.pol;
+ valid_pol = cli_pol_link(hnd_secret, hnd);
+ }
}
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("LSA_OPENPOLICY: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a LSA Open Secret
+****************************************************************************/
+BOOL lsa_open_secret(const POLICY_HND *hnd,
+ const char *secret_name,
+ uint32 des_access, POLICY_HND *hnd_secret)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_OPEN_SECRET q_o;
+ BOOL valid_pol = False;
+
+ if (hnd == NULL)
return False;
- } else {
- /* ok, at last: we're happy. return the policy handle */
- memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
+
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
+
+ /* create and send a MSRPC command with api LSA_OPENSECRET */
+
+ DEBUG(4, ("LSA Open Secret\n"));
+
+ make_q_open_secret(&q_o, hnd, secret_name, des_access);
+
+ /* turn parameters into data stream */
+ if (lsa_io_q_open_secret("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, LSA_OPENSECRET, &buf, &rbuf))
+ {
+ LSA_R_OPEN_SECRET r_o;
+ BOOL p;
+
+ lsa_io_r_open_secret("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,
+ ("LSA_OPENSECRET: %s\n",
+ get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd_secret = r_o.pol;
+ valid_pol = cli_pol_link(hnd_secret, hnd);
+ }
}
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
- return True;
+ return valid_pol;
}
/****************************************************************************
-do a LSA Lookup SIDs
+do a LSA Set Secret
****************************************************************************/
+uint32 lsa_set_secret(POLICY_HND *hnd, const STRING2 * secret)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_SET_SECRET q_q;
+
+ uchar sess_key[16];
+#if 0
+ char data[12] =
+ {
+ 0x1a, 0x32, 0xb6, 0x63, 0xd7, 0x08, 0x79, 0x64,
+ 0x9c, 0x36, 0x94, 0x8b
+ };
+#endif
+ uint32 status = NT_STATUS_NOPROBLEMO;
+
+ if (hnd == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
+
+ /* create and send a MSRPC command with api LSA_SETSECRET */
+
+ DEBUG(4, ("LSA Set Secret\n"));
+
+ q_q.pol = *hnd;
+ q_q.unknown = 0x0;
+ q_q.value.ptr_secret = 0x1;
+ make_strhdr2(&q_q.value.hdr_secret, secret->str_str_len,
+ secret->str_max_len, 1);
+
+ if (!cli_get_usr_sesskey(hnd, sess_key))
+ {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ dump_data_pw("sess_key:", sess_key, 16);
+
+#if 0
+ memcpy(&q_q.value.enc_secret.buffer, data, sizeof(data));
+ q_q.value.enc_secret.str_str_len = sizeof(data);
+ q_q.value.enc_secret.str_max_len = sizeof(data);
+ if (!nt_decrypt_string2(&q_q.value.enc_secret, secret, sess_key))
+ {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+#endif
+
+ if (!nt_encrypt_string2(&q_q.value.enc_secret, secret, sess_key))
+ {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
-BOOL do_lsa_lookup_sids(struct cli_state *cli,
- POLICY_HND *hnd,
- int num_sids,
- DOM_SID **sids,
- char ***names,
- int *num_names)
+ /* turn parameters into data stream */
+ if (lsa_io_q_set_secret("", &q_q, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, LSA_SETSECRET, &buf, &rbuf))
+ {
+ LSA_R_SET_SECRET r_q;
+ BOOL p;
+
+ lsa_io_r_set_secret("", &r_q, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_q.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,
+ ("LSA_SETSECRET: %s\n",
+ get_nt_error_msg(r_q.status)));
+ status = NT_STATUS_INVALID_PARAMETER;
+ }
+ else
+ {
+ status = r_q.status;
+ }
+ }
+ else
+ {
+
+ status = NT_STATUS_INVALID_PARAMETER;
+ }
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
+
+ return status;
+}
+
+/****************************************************************************
+do a LSA Query Secret
+****************************************************************************/
+BOOL lsa_query_secret(POLICY_HND *hnd, STRING2 * secret, NTTIME * last_update)
{
prs_struct rbuf;
- prs_struct buf;
- LSA_Q_LOOKUP_SIDS q_l;
- LSA_R_LOOKUP_SIDS r_l;
- DOM_R_REF ref;
- LSA_TRANS_NAME_ENUM t_names;
- int i;
+ prs_struct buf;
+ LSA_Q_QUERY_SECRET q_q;
+ BOOL valid_info = False;
+
+ if (hnd == NULL)
+ return False;
+
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
+
+ /* create and send a MSRPC command with api LSA_QUERYSECRET */
+
+ DEBUG(4, ("LSA Query Secret\n"));
+
+ make_q_query_secret(&q_q, hnd, secret, last_update);
+
+ /* turn parameters into data stream */
+ if (lsa_io_q_query_secret("", &q_q, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, LSA_QUERYSECRET, &buf, &rbuf))
+ {
+ LSA_R_QUERY_SECRET r_q;
+ BOOL p;
+
+ lsa_io_r_query_secret("", &r_q, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_q.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,
+ ("LSA_QUERYSECRET: %s\n",
+ get_nt_error_msg(r_q.status)));
+ p = False;
+ }
+
+ if (p && (r_q.sec.curinfo.ptr_value != 0) &&
+ (r_q.sec.curinfo.value.ptr_secret != 0))
+ {
+ uchar sess_key[16];
+ STRING2 enc_secret;
+ memcpy(&enc_secret,
+ &(r_q.sec.curinfo.value.enc_secret),
+ sizeof(STRING2));
+ if (!cli_get_usr_sesskey(hnd, sess_key))
+ {
+ return False;
+ }
+ dump_data_pw("sess key:", sess_key, 16);
+ valid_info = nt_decrypt_string2(secret, &enc_secret,
+ sess_key);
+ }
+ if (p && last_update != NULL &&
+ (r_q.sec.curinfo.ptr_value != 0) &&
+ (r_q.sec.curinfo.ptr_update != 0))
+ {
+ memcpy(last_update, &(r_q.sec.curinfo.last_update),
+ sizeof(NTTIME));
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
+
+ return valid_info;
+}
+
+
+/****************************************************************************
+do a LSA Lookup Names
+****************************************************************************/
+BOOL lsa_lookup_names(POLICY_HND *hnd,
+ int num_names,
+ char **names,
+ DOM_SID ** sids, uint32 ** types, int *num_sids)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_LOOKUP_NAMES q_l;
BOOL valid_response = False;
if (hnd == NULL || num_sids == 0 || sids == NULL)
return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL );
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
- /* create and send a MSRPC command with api LSA_LOOKUP_SIDS */
+ /* create and send a MSRPC command with api LSA_LOOKUP_NAMES */
- DEBUG(4,("LSA Lookup SIDs\n"));
+ DEBUG(4, ("LSA Lookup NAMEs\n"));
/* store the parameters */
- init_q_lookup_sids(&q_l, hnd, num_sids, sids, 1);
+ make_q_lookup_names(&q_l, hnd, num_names, names);
/* turn parameters into data stream */
- if(!lsa_io_q_lookup_sids("", &q_l, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ if (lsa_io_q_lookup_names("", &q_l, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, LSA_LOOKUPNAMES, &buf, &rbuf))
+ {
+ LSA_R_LOOKUP_NAMES r_l;
+ DOM_R_REF ref;
+ DOM_RID2 t_rids[MAX_LOOKUP_SIDS];
+ BOOL p;
+
+ ZERO_STRUCT(ref);
+ ZERO_STRUCT(t_rids);
+
+ r_l.dom_ref = &ref;
+ r_l.dom_rid = t_rids;
+
+ lsa_io_r_lookup_names("", &r_l, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_l.status != 0)
+ {
+ /* report error code */
+ DEBUG(1,
+ ("LSA_LOOKUP_NAMES: %s\n",
+ get_nt_error_msg(r_l.status)));
+ p = False;
+ }
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ if (p)
+ {
+ if (r_l.ptr_dom_ref != 0 && r_l.ptr_entries != 0)
+ {
+ valid_response = True;
+ }
+ }
+
+ if (num_sids != NULL && valid_response)
+ {
+ (*num_sids) = r_l.num_entries;
+ }
+ if (valid_response)
+ {
+ uint32 i;
+ for (i = 0; i < r_l.num_entries; i++)
+ {
+ if (t_rids[i].rid_idx >= ref.num_ref_doms_1 &&
+ t_rids[i].rid_idx != 0xffffffff)
+ {
+ DEBUG(0,
+ ("LSA_LOOKUP_NAMES: domain index %d out of bounds\n",
+ t_rids[i].rid_idx));
+ valid_response = False;
+ break;
+ }
+ }
+ }
- prs_mem_free(&buf);
+ if (types != NULL && valid_response && r_l.num_entries != 0)
+ {
+ (*types) = (uint32 *) malloc((*num_sids) * sizeof(uint32));
+ }
- r_l.dom_ref = &ref;
- r_l.names = &t_names;
+ if (sids != NULL && valid_response && r_l.num_entries != 0)
+ {
+ (*sids) = (DOM_SID *) malloc((*num_sids) * sizeof(DOM_SID));
+ }
- if(!lsa_io_r_lookup_sids("", &r_l, &rbuf, 0)) {
- DEBUG(0,("do_lsa_lookup_sids: Failed to unmarshall LSA_R_LOOKUP_SIDS\n"));
- prs_mem_free(&rbuf);
- return False;
+ if (sids != NULL && (*sids) != NULL)
+ {
+ int i;
+ /* take each name, construct a SID */
+ for (i = 0; i < (*num_sids); i++)
+ {
+ uint32 dom_idx = t_rids[i].rid_idx;
+ uint32 dom_rid = t_rids[i].rid;
+ DOM_SID *sid = &(*sids)[i];
+ if (dom_idx != 0xffffffff)
+ {
+ sid_copy(sid,
+ &ref.ref_dom[dom_idx].
+ ref_dom.sid);
+ if (dom_rid != 0xffffffff)
+ {
+ sid_append_rid(sid, dom_rid);
+ }
+ if (types != NULL && (*types) != NULL)
+ {
+ (*types)[i] = t_rids[i].type;
+ }
+ }
+ else
+ {
+ ZERO_STRUCTP(sid);
+ if (types != NULL && (*types) != NULL)
+ {
+ (*types)[i] = SID_NAME_UNKNOWN;
+ }
+ }
+ }
+ }
}
-
- if (r_l.status != 0) {
- /* report error code */
- DEBUG(0,("LSA_LOOKUP_SIDS: %s\n", get_nt_error_msg(r_l.status)));
- } else {
- if (t_names.ptr_trans_names != 0)
- valid_response = True;
- }
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
- if(!valid_response) {
- prs_mem_free(&rbuf);
+ return valid_response;
+}
+
+/****************************************************************************
+do a LSA Lookup SIDs
+****************************************************************************/
+BOOL lsa_lookup_sids(POLICY_HND *hnd,
+ int num_sids,
+ DOM_SID ** sids,
+ char ***names, uint32 ** types, int *num_names)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_LOOKUP_SIDS q_l;
+ BOOL valid_response = False;
+
+ ZERO_STRUCT(q_l);
+
+ if (hnd == NULL || num_sids == 0 || sids == NULL)
return False;
- }
if (num_names != NULL)
- (*num_names) = t_names.num_entries;
+ {
+ *num_names = 0;
+ }
+ if (types != NULL)
+ {
+ *types = NULL;
+ }
+ if (names != NULL)
+ {
+ *names = NULL;
+ }
- for (i = 0; i < t_names.num_entries; i++) {
- if (t_names.name[i].domain_idx >= ref.num_ref_doms_1) {
- DEBUG(0,("LSA_LOOKUP_SIDS: domain index out of bounds\n"));
- prs_mem_free(&rbuf);
- return False;
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
+
+ /* create and send a MSRPC command with api LSA_LOOKUP_SIDS */
+
+ DEBUG(4, ("LSA Lookup SIDs\n"));
+
+ /* store the parameters */
+ make_q_lookup_sids(&q_l, hnd, num_sids, sids, 1);
+
+ /* turn parameters into data stream */
+ if (lsa_io_q_lookup_sids("", &q_l, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, LSA_LOOKUPSIDS, &buf, &rbuf))
+ {
+ LSA_R_LOOKUP_SIDS r_l;
+ DOM_R_REF ref;
+ LSA_TRANS_NAME_ENUM t_names;
+ BOOL p;
+
+ r_l.dom_ref = &ref;
+ r_l.names = &t_names;
+
+ lsa_io_r_lookup_sids("", &r_l, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_l.status != 0 &&
+ r_l.status != 0x107 &&
+ r_l.status != (0xC0000000 | NT_STATUS_NONE_MAPPED))
+ {
+ /* report error code */
+ DEBUG(1,
+ ("LSA_LOOKUP_SIDS: %s\n",
+ get_nt_error_msg(r_l.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ if (t_names.ptr_trans_names != 0
+ && r_l.ptr_dom_ref != 0)
+ {
+ valid_response = True;
+ }
+ }
+
+ if (num_names != NULL && valid_response)
+ {
+ (*num_names) = t_names.num_entries;
+ }
+ if (valid_response)
+ {
+ uint32 i;
+ for (i = 0; i < t_names.num_entries; i++)
+ {
+ if (t_names.name[i].domain_idx >=
+ ref.num_ref_doms_1)
+ {
+ DEBUG(0,
+ ("LSA_LOOKUP_SIDS: domain index out of bounds\n"));
+ valid_response = False;
+ break;
+ }
+ }
+ }
+
+ if (types != NULL && valid_response && (*num_names) != 0)
+ {
+ (*types) = (uint32 *) malloc((*num_names) * sizeof(uint32));
+ }
+
+ if (names != NULL && valid_response && (*num_names) != 0)
+ {
+ (*names) = (char **)malloc((*num_names) * sizeof(char *));
+ }
+
+ if (names != NULL && (*names) != NULL)
+ {
+ int i;
+ /* take each name, construct a \DOMAIN\name string */
+ for (i = 0; i < (*num_names); i++)
+ {
+ fstring name;
+ fstring dom_name;
+ fstring full_name;
+ uint32 dom_idx = t_names.name[i].domain_idx;
+
+ if (dom_idx != 0xffffffff)
+ {
+ unistr2_to_ascii(dom_name,
+ &ref.
+ ref_dom[dom_idx].
+ uni_dom_name,
+ sizeof(dom_name) -
+ 1);
+ unistr2_to_ascii(name,
+ &t_names.uni_name[i],
+ sizeof(name) - 1);
+
+ memset(full_name, 0,
+ sizeof(full_name));
+
+ slprintf(full_name,
+ sizeof(full_name) - 1,
+ "%s\\%s", dom_name, name);
+
+ (*names)[i] = strdup(full_name);
+ if (types != NULL && (*types) != NULL)
+ {
+ (*types)[i] = t_names.name[i].sid_name_use;
+ }
+ }
+ else
+ {
+ (*names)[i] = NULL;
+ if (types != NULL && (*types) != NULL)
+ {
+ (*types)[i] = SID_NAME_UNKNOWN;
+ }
+ }
+ }
}
}
- if (names != NULL && t_names.num_entries != 0)
- (*names) = (char**)malloc((*num_names) * sizeof(char*));
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
- if (names != NULL && (*names) != NULL) {
- /* take each name, construct a \DOMAIN\name string */
- for (i = 0; i < (*num_names); i++) {
- fstring name;
- fstring dom_name;
- fstring full_name;
- uint32 dom_idx = t_names.name[i].domain_idx;
- fstrcpy(dom_name, dos_unistr2(ref.ref_dom[dom_idx].uni_dom_name.buffer));
- fstrcpy(name, dos_unistr2(t_names.uni_name[i].buffer));
-
- slprintf(full_name, sizeof(full_name)-1, "\\%s\\%s",
- dom_name, name);
+ return valid_response;
+}
+
+/****************************************************************************
+do a LSA Query Info Policy
+****************************************************************************/
+BOOL lsa_query_sec_obj(const POLICY_HND *hnd, uint32 sec_info,
+ SEC_DESC_BUF *sec_buf)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_QUERY_SEC_OBJ q_q;
+ BOOL valid_response = False;
+
+ if (hnd == NULL || sec_buf == NULL)
+ return False;
+
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
+
+ /* create and send a MSRPC command with api LSA_QUERY_SECOBJ */
- (*names)[i] = strdup(full_name);
+ DEBUG(4, ("LSA Query Info Policy\n"));
+
+ /* store the parameters */
+ make_q_query_sec_obj(&q_q, hnd, sec_info);
+
+ /* turn parameters into data stream */
+ if (lsa_io_q_query_sec_obj("", &q_q, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, LSA_QUERYSECOBJECT, &buf, &rbuf))
+ {
+ LSA_R_QUERY_SEC_OBJ r_q;
+ BOOL p = False;
+
+ lsa_io_r_query_sec_obj("", &r_q, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_q.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,
+ ("LSA_QUERY_SECOBJ: %s\n",
+ get_nt_error_msg(r_q.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_response = True;
+ sec_buf->sec = r_q.buf.sec;
}
}
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
return valid_response;
}
@@ -213,15 +989,13 @@ BOOL do_lsa_lookup_sids(struct cli_state *cli,
/****************************************************************************
do a LSA Query Info Policy
****************************************************************************/
-BOOL do_lsa_query_info_pol(struct cli_state *cli,
- POLICY_HND *hnd, uint16 info_class,
- fstring domain_name, DOM_SID *domain_sid)
+BOOL lsa_query_info_pol(POLICY_HND *hnd, uint16 info_class,
+ fstring domain_name, DOM_SID * domain_sid)
{
prs_struct rbuf;
- prs_struct buf;
+ prs_struct buf;
LSA_Q_QUERY_INFO q_q;
- LSA_R_QUERY_INFO r_q;
- fstring sid_str;
+ BOOL valid_response = False;
ZERO_STRUCTP(domain_sid);
domain_name[0] = 0;
@@ -229,153 +1003,261 @@ BOOL do_lsa_query_info_pol(struct cli_state *cli,
if (hnd == NULL || domain_name == NULL || domain_sid == NULL)
return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL );
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
/* create and send a MSRPC command with api LSA_QUERYINFOPOLICY */
- DEBUG(4,("LSA Query Info Policy\n"));
+ DEBUG(4, ("LSA Query Info Policy\n"));
/* store the parameters */
- init_q_query(&q_q, hnd, info_class);
+ make_q_query(&q_q, hnd, info_class);
/* turn parameters into data stream */
- if(!lsa_io_q_query("", &q_q, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ if (lsa_io_q_query("", &q_q, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, LSA_QUERYINFOPOLICY, &buf, &rbuf))
+ {
+ LSA_R_QUERY_INFO r_q;
+ BOOL p;
+
+ lsa_io_r_query("", &r_q, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_q.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,
+ ("LSA_QUERYINFOPOLICY: %s\n",
+ get_nt_error_msg(r_q.status)));
+ p = False;
+ }
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
+ if (p && r_q.info_class != q_q.info_class)
+ {
+ /* report different info classes */
+ DEBUG(0,
+ ("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n",
+ q_q.info_class, r_q.info_class));
+ p = False;
+ }
+
+ if (p)
+ {
+ fstring sid_str;
+ /* ok, at last: we're happy. */
+ switch (r_q.info_class)
+ {
+ case 3:
+ {
+ if (r_q.dom.id3.buffer_dom_name != 0)
+ {
+ unistr2_to_ascii(domain_name,
+ &r_q.dom.id3.
+ uni_domain_name,
+ sizeof
+ (fstring) -
+ 1);
+ }
+ if (r_q.dom.id3.buffer_dom_sid != 0)
+ {
+ *domain_sid =
+ r_q.dom.id3.dom_sid.
+ sid;
+ }
+
+ valid_response = True;
+ break;
+ }
+ case 5:
+ {
+ if (r_q.dom.id5.buffer_dom_name != 0)
+ {
+ unistr2_to_ascii(domain_name,
+ &r_q.dom.id5.
+ uni_domain_name,
+ sizeof
+ (fstring) -
+ 1);
+ }
+ if (r_q.dom.id5.buffer_dom_sid != 0)
+ {
+ *domain_sid =
+ r_q.dom.id5.dom_sid.
+ sid;
+ }
+
+ valid_response = True;
+ break;
+ }
+ default:
+ {
+ DEBUG(3,
+ ("LSA_QUERYINFOPOLICY: unknown info class\n"));
+ domain_name[0] = 0;
+
+ break;
+ }
+ }
+
+ sid_to_string(sid_str, domain_sid);
+ DEBUG(3,
+ ("LSA_QUERYINFOPOLICY (level %x): domain:%s domain sid:%s\n",
+ r_q.info_class, domain_name, sid_str));
+ }
}
- prs_mem_free(&buf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
- if(!lsa_io_r_query("", &r_q, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ return valid_response;
+}
- if (r_q.status != 0) {
- /* report error code */
- DEBUG(0,("LSA_QUERYINFOPOLICY: %s\n", get_nt_error_msg(r_q.status)));
- prs_mem_free(&rbuf);
- return False;
- }
+/****************************************************************************
+do a LSA Enumerate Trusted Domain
+****************************************************************************/
+BOOL lsa_enum_trust_dom(POLICY_HND *hnd, uint32 * enum_ctx,
+ uint32 * num_doms, char ***names, DOM_SID *** sids)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ LSA_Q_ENUM_TRUST_DOM q_q;
+ BOOL valid_response = False;
- if (r_q.info_class != q_q.info_class) {
- /* report different info classes */
- DEBUG(0,("LSA_QUERYINFOPOLICY: error info_class (q,r) differ - (%x,%x)\n",
- q_q.info_class, r_q.info_class));
- prs_mem_free(&rbuf);
+ if (hnd == NULL || num_doms == NULL || names == NULL)
return False;
- }
- /* ok, at last: we're happy. */
- switch (r_q.info_class) {
- case 3:
- if (r_q.dom.id3.buffer_dom_name != 0) {
- char *dom_name = dos_unistrn2(r_q.dom.id3.uni_domain_name.buffer,
- r_q.dom.id3.uni_domain_name.uni_str_len);
- fstrcpy(domain_name, dom_name);
- }
- if (r_q.dom.id3.buffer_dom_sid != 0)
- *domain_sid = r_q.dom.id3.dom_sid.sid;
- break;
- case 5:
- if (r_q.dom.id5.buffer_dom_name != 0) {
- char *dom_name = dos_unistrn2(r_q.dom.id5.uni_domain_name.buffer,
- r_q.dom.id5.uni_domain_name.uni_str_len);
- fstrcpy(domain_name, dom_name);
- }
- if (r_q.dom.id5.buffer_dom_sid != 0)
- *domain_sid = r_q.dom.id5.dom_sid.sid;
- break;
- default:
- DEBUG(3,("LSA_QUERYINFOPOLICY: unknown info class\n"));
- domain_name[0] = 0;
-
- prs_mem_free(&rbuf);
- return False;
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
+
+ /* create and send a MSRPC command with api LSA_ENUMTRUSTDOM */
+
+ DEBUG(4, ("LSA Enum Trusted Domains\n"));
+
+ /* store the parameters */
+ make_q_enum_trust_dom(&q_q, hnd, *enum_ctx, 0xffffffff);
+
+ /* turn parameters into data stream */
+ if (lsa_io_q_enum_trust_dom("", &q_q, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, LSA_ENUMTRUSTDOM, &buf, &rbuf))
+ {
+ LSA_R_ENUM_TRUST_DOM r_q;
+ BOOL p;
+
+ lsa_io_r_enum_trust_dom("", &r_q, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_q.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,
+ ("LSA_ENUMTRUSTDOM: %s\n",
+ get_nt_error_msg(r_q.status)));
+ p = r_q.status == 0x8000001a;
+ }
+
+ if (p)
+ {
+ uint32 i;
+ uint32 num_sids = 0;
+ valid_response = True;
+
+ for (i = 0; i < r_q.num_domains; i++)
+ {
+ fstring tmp;
+ unistr2_to_ascii(tmp, &r_q.uni_domain_name[i],
+ sizeof(tmp) - 1);
+ add_chars_to_array(num_doms, names, tmp);
+ add_sid_to_array(&num_sids, sids,
+ &r_q.domain_sid[i].sid);
+ }
+
+ if (r_q.status == NT_STATUS_NOPROBLEMO)
+ {
+ *enum_ctx = r_q.enum_context;
+ }
+ else
+ {
+ *enum_ctx = 0;
+ }
+ }
+
+ lsa_free_r_enum_trust_dom(&r_q);
}
-
- sid_to_string(sid_str, domain_sid);
- DEBUG(3,("LSA_QUERYINFOPOLICY (level %x): domain:%s domain sid:%s\n",
- r_q.info_class, domain_name, sid_str));
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
- return True;
+ return valid_response;
}
/****************************************************************************
do a LSA Close
****************************************************************************/
-
-BOOL do_lsa_close(struct cli_state *cli, POLICY_HND *hnd)
+BOOL lsa_close(POLICY_HND *hnd)
{
prs_struct rbuf;
- prs_struct buf;
+ prs_struct buf;
LSA_Q_CLOSE q_c;
- LSA_R_CLOSE r_c;
- int i;
+ BOOL valid_close = False;
if (hnd == NULL)
return False;
/* create and send a MSRPC command with api LSA_OPENPOLICY */
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL );
+ prs_init(&buf, 0, 4, False);
+ prs_init(&rbuf, 0, 4, True);
- DEBUG(4,("LSA Close\n"));
+ DEBUG(4, ("LSA Close\n"));
/* store the parameters */
- init_lsa_q_close(&q_c, hnd);
+ make_lsa_q_close(&q_c, hnd);
/* turn parameters into data stream */
- if(!lsa_io_q_close("", &q_c, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, LSA_CLOSE, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- if(!lsa_io_r_close("", &r_c, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
-
- if (r_c.status != 0) {
- /* report error code */
- DEBUG(0,("LSA_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* check that the returned policy handle is all zeros */
+ if (lsa_io_q_close("", &q_c, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, LSA_CLOSE, &buf, &rbuf))
+ {
+ LSA_R_CLOSE r_c;
+ BOOL p;
+
+ lsa_io_r_close("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,
+ ("LSA_CLOSE: %s\n",
+ get_nt_error_msg(r_c.status)));
+ p = False;
+ }
- for (i = 0; i < sizeof(r_c.pol.data); i++) {
- if (r_c.pol.data[i] != 0) {
- DEBUG(0,("LSA_CLOSE: non-zero handle returned\n"));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ /* check that the returned policy handle is all zeros */
+ uint32 i;
+ valid_close = True;
+
+ for (i = 0; i < sizeof(r_c.pol.data); i++)
+ {
+ if (r_c.pol.data[i] != 0)
+ {
+ valid_close = False;
+ break;
+ }
+ }
+ if (!valid_close)
+ {
+ DEBUG(0,
+ ("LSA_CLOSE: non-zero handle returned\n"));
+ }
}
}
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf);
+
+ close_policy_hnd(get_global_hnd_cache(), hnd);
- return True;
+ return valid_close;
}
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index dab4aa7ad58..47afd228acc 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -28,86 +28,81 @@
#endif
#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
extern int DEBUGLEVEL;
-extern pstring global_myname;
-extern fstring global_myworkgroup;
/****************************************************************************
Generate the next creds to use.
****************************************************************************/
-static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred)
+void gen_next_creds( struct ntdom_info *nt, DOM_CRED *new_clnt_cred)
{
/*
* Create the new client credentials.
*/
- cli->clnt_cred.timestamp.time = time(NULL);
+ nt->clnt_cred.timestamp.time = time(NULL);
- memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred));
+ memcpy(new_clnt_cred, &nt->clnt_cred, sizeof(*new_clnt_cred));
/* Calculate the new credentials. */
- cred_create(cli->sess_key, &(cli->clnt_cred.challenge),
+ cred_create(nt->sess_key, &(nt->clnt_cred.challenge),
new_clnt_cred->timestamp, &(new_clnt_cred->challenge));
}
-#if UNUSED_CODE
/****************************************************************************
do a LSA Logon Control2
****************************************************************************/
-BOOL cli_net_logon_ctrl2(struct cli_state *cli, uint32 status_level)
+BOOL cli_net_logon_ctrl2(const char* srv_name, uint32 status_level)
{
- prs_struct rbuf;
- prs_struct buf;
- NET_Q_LOGON_CTRL2 q_l;
- BOOL ok = False;
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_LOGON_CTRL2 q_l;
+ BOOL ok = False;
- prs_init(&buf , 1024, 4, False);
- prs_init(&rbuf, 0, 4, True );
+ struct cli_connection *con = NULL;
- /* create and send a MSRPC command with api NET_LOGON_CTRL2 */
+ if (!cli_connection_init(srv_name, PIPE_NETLOGON, &con))
+ {
+ return False;
+ }
- DEBUG(4,("do_net_logon_ctrl2 from %s status level:%x\n",
- global_myname, status_level));
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
- /* store the parameters */
- init_q_logon_ctrl2(&q_l, cli->srv_name_slash, status_level);
+ /* create and send a MSRPC command with api NET_LOGON_CTRL2 */
- /* turn parameters into data stream */
- if(!net_io_q_logon_ctrl2("", &q_l, &buf, 0)) {
- DEBUG(0,("cli_net_logon_ctrl2: Error : failed to marshall NET_Q_LOGON_CTRL2 struct.\n"));
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ DEBUG(4,("net_logon_ctrl2 status level:%x\n", status_level));
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &buf, &rbuf))
- {
- NET_R_LOGON_CTRL2 r_l;
+ /* store the parameters */
+ make_q_logon_ctrl2(&q_l, srv_name, 0, 0, status_level);
- /*
- * Unmarshall the return buffer.
- */
- ok = net_io_r_logon_ctrl2("", &r_l, &rbuf, 0);
-
- if (ok && r_l.status != 0)
- {
- /* report error code */
- DEBUG(0,("do_net_logon_ctrl2: Error %s\n", get_nt_error_msg(r_l.status)));
- cli->nt_error = r_l.status;
- ok = False;
- }
- }
+ /* turn parameters into data stream */
+ if (net_io_q_logon_ctrl2("", &q_l, &buf, 0) &&
+ rpc_con_pipe_req(con, NET_LOGON_CTRL2, &buf, &rbuf))
+ {
+ NET_R_LOGON_CTRL2 r_l;
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
+ net_io_r_logon_ctrl2("", &r_l, &rbuf, 0);
+ ok = (rbuf.offset != 0);
- return ok;
+ if (ok && r_l.status != 0)
+ {
+ /* report error code */
+ DEBUG(5,("net_logon_ctrl2: Error %s\n", get_nt_error_msg(r_l.status)));
+ ok = False;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ cli_connection_unlink(con);
+ return ok;
}
-#endif
/****************************************************************************
LSA Authenticate 2
@@ -117,90 +112,117 @@ Ensure that the server credential returned matches the session key
encrypt of the server challenge originally received. JRA.
****************************************************************************/
-BOOL cli_net_auth2(struct cli_state *cli, uint16 sec_chan,
- uint32 neg_flags, DOM_CHAL *srv_chal)
+uint32 cli_net_auth2(const char *srv_name,
+ const char *trust_acct,
+ const char *acct_name,
+ uint16 sec_chan,
+ uint32 *neg_flags, DOM_CHAL *srv_chal)
{
- prs_struct rbuf;
- prs_struct buf;
- NET_Q_AUTH_2 q_a;
- BOOL ok = False;
-
- prs_init(&buf , 1024, 4, False);
- prs_init(&rbuf, 0, 4, True );
-
- /* create and send a MSRPC command with api NET_AUTH2 */
-
- DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n",
- cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname,
- credstr(cli->clnt_cred.challenge.data), neg_flags));
-
- /* store the parameters */
- init_q_auth_2(&q_a, cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname,
- &cli->clnt_cred.challenge, neg_flags);
-
- /* turn parameters into data stream */
- if(!net_io_q_auth_2("", &q_a, &buf, 0)) {
- DEBUG(0,("cli_net_auth2: Error : failed to marshall NET_Q_AUTH_2 struct.\n"));
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, NET_AUTH2, &buf, &rbuf))
- {
- NET_R_AUTH_2 r_a;
-
- ok = net_io_r_auth_2("", &r_a, &rbuf, 0);
-
- if (ok && r_a.status != 0)
- {
- /* report error code */
- DEBUG(0,("cli_net_auth2: Error %s\n", get_nt_error_msg(r_a.status)));
- cli->nt_error = r_a.status;
- ok = False;
- }
-
- if (ok)
- {
- /*
- * Check the returned value using the initial
- * server received challenge.
- */
- UTIME zerotime;
-
- zerotime.time = 0;
- if(cred_assert( &r_a.srv_chal, cli->sess_key, srv_chal, zerotime) == 0) {
- /*
- * Server replied with bad credential. Fail.
- */
- DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \
-password ?).\n", cli->desthost ));
- ok = False;
- }
- }
-
+ prs_struct rbuf;
+ prs_struct buf;
+ NET_Q_AUTH_2 q_a;
+ uint32 status = 0x0;
+ uint8 sess_key[16];
+ DOM_CRED clnt_cred;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
+ {
+ return 0xC0000000 | NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (!cli_get_con_sesskey(con, sess_key))
+ {
+ return 0xC0000000 | NT_STATUS_INVALID_PARAMETER;
+ }
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api NET_AUTH2 */
+
+ DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s neg: %x\n",
+ srv_name, trust_acct, sec_chan, acct_name,
+ *neg_flags));
+
+ cli_con_get_cli_cred(con, &clnt_cred);
+
+ /* store the parameters */
+ make_q_auth_2(&q_a, srv_name, trust_acct, sec_chan, acct_name,
+ &clnt_cred.challenge, *neg_flags);
+
+ /* turn parameters into data stream */
+ if (net_io_q_auth_2("", &q_a, &buf, 0) &&
+ rpc_con_pipe_req(con, NET_AUTH2, &buf, &rbuf))
+ {
+ NET_R_AUTH_2 r_a;
+
+ net_io_r_auth_2("", &r_a, &rbuf, 0);
+ status = (rbuf.offset == 0) ? 0xC0000000 | NT_STATUS_INVALID_PARAMETER : 0;
+
+ if (status == 0x0 && r_a.status != 0)
+ {
+ /* report error code */
+ DEBUG(5,("cli_net_auth2: Error %s\n",
+ get_nt_error_msg(r_a.status)));
+ status = r_a.status;
+ }
+
+ if (status == 0x0)
+ {
+ /*
+ * Check the returned value using the initial
+ * server received challenge.
+ */
+ UTIME zerotime;
+
+ zerotime.time = 0;
+ if(cred_assert( &r_a.srv_chal, sess_key,
+ srv_chal, zerotime) == 0)
+ {
+ /*
+ * Server replied with bad credential. Fail.
+ */
+ DEBUG(5,("cli_net_auth2: server %s replied \
+with bad credential (bad trust account password ?).\n", srv_name));
+ status = NT_STATUS_NETWORK_CREDENTIAL_CONFLICT | 0xC0000000;
+ }
+ }
+
+ if (status == 0x0)
+ {
+ (*neg_flags) = r_a.srv_flgs.neg_flags;
+ }
#if 0
- /*
- * Try commenting this out to see if this makes the connect
- * work for a NT 3.51 PDC. JRA.
- */
-
- if (ok && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
- {
- /* report different neg_flags */
- DEBUG(0,("cli_net_auth2: error neg_flags (q,r) differ - (%x,%x)\n",
- q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
- ok = False;
- }
+ /*
+ * Try commenting this out to see if this makes the connect
+ * work for a NT 3.51 PDC. JRA.
+ */
+
+ if (ok && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags)
+ {
+ /* report different neg_flags */
+ DEBUG(5,("cli_net_auth2: error neg_flags (q,r) differ - (%x,%x)\n",
+ q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags));
+ ok = False;
+ }
#endif
- }
+ }
+ else
+ {
+ DEBUG(5,("rpc_con_pipe_req FAILED\n"));
+ status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+ }
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
+ DEBUG(5,("cli_net_auth2 neg_flags: %x status: %x\n",
+ (*neg_flags), status));
- return ok;
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return status;
}
/****************************************************************************
@@ -208,137 +230,159 @@ LSA Request Challenge. Sends our challenge to server, then gets
server response. These are used to generate the credentials.
****************************************************************************/
-BOOL cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
+uint32 cli_net_req_chal( const char *srv_name, const char* myhostname,
+ DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal)
{
prs_struct rbuf;
prs_struct buf;
NET_Q_REQ_CHAL q_c;
- BOOL valid_chal = False;
+ uint32 status = 0x0;
- prs_init(&buf , 1024, 4, False);
- prs_init(&rbuf, 0, 4, True );
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_NETLOGON, &con))
+ {
+ return 0xC0000000 | NT_STATUS_INVALID_PARAMETER;
+ }
+
+ if (srv_chal == NULL || clnt_chal == NULL)
+ return 0xC0000000 | NT_STATUS_INVALID_PARAMETER;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api NET_REQCHAL */
DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n",
- cli->desthost, global_myname, credstr(clnt_chal->data)));
+ srv_name, myhostname, credstr(clnt_chal->data)));
/* store the parameters */
- init_q_req_chal(&q_c, cli->srv_name_slash, global_myname, clnt_chal);
+ make_q_req_chal(&q_c, srv_name, myhostname, clnt_chal);
/* turn parameters into data stream */
- if(!net_io_q_req_chal("", &q_c, &buf, 0)) {
- DEBUG(0,("cli_net_req_chal: Error : failed to marshall NET_Q_REQ_CHAL struct.\n"));
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, NET_REQCHAL, &buf, &rbuf))
+ if (net_io_q_req_chal("", &q_c, &buf, 0) &&
+ rpc_con_pipe_req(con, NET_REQCHAL, &buf, &rbuf))
{
NET_R_REQ_CHAL r_c;
- BOOL ok;
- ok = net_io_r_req_chal("", &r_c, &rbuf, 0);
+ net_io_r_req_chal("", &r_c, &rbuf, 0);
+ status = (rbuf.offset == 0) ? 0xC0000000 | NT_STATUS_INVALID_PARAMETER : 0;
- if (ok && r_c.status != 0)
+ if (status == 0x0 && r_c.status != 0)
{
/* report error code */
- DEBUG(0,("cli_net_req_chal: Error %s\n", get_nt_error_msg(r_c.status)));
- cli->nt_error = r_c.status;
- ok = False;
+ DEBUG(5,("cli_net_req_chal: Error %s\n", get_nt_error_msg(r_c.status)));
+ status = r_c.status;
}
- if (ok)
+ if (status == 0x0)
{
/* ok, at last: we're happy. return the challenge */
memcpy(srv_chal, r_c.srv_chal.data, sizeof(srv_chal->data));
- valid_chal = True;
}
}
+ else
+ {
+ DEBUG(5,("rpc_con_pipe_req FAILED\n"));
+ status = 0xC0000000 | NT_STATUS_ACCESS_DENIED;
+ }
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return valid_chal;
+ return status;
}
/***************************************************************************
LSA Server Password Set.
****************************************************************************/
-BOOL cli_net_srv_pwset(struct cli_state *cli, uint8 hashed_mach_pwd[16])
+BOOL cli_net_srv_pwset(const char* srv_name,
+ const char* myhostname,
+ const char* trust_acct,
+ const uint8 hashed_trust_pwd[16],
+ uint16 sec_chan_type)
{
prs_struct rbuf;
prs_struct buf;
DOM_CRED new_clnt_cred;
NET_Q_SRV_PWSET q_s;
BOOL ok = False;
- uint16 sec_chan_type = 2;
+ unsigned char processed_new_pwd[16];
+ /* Process the new password. */
+
+ uint8 sess_key[16];
+
+ struct cli_connection *con = NULL;
- gen_next_creds( cli, &new_clnt_cred);
+ if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
+ {
+ return False;
+ }
- prs_init(&buf , 1024, 4, False);
- prs_init(&rbuf, 0, 4, True );
+ if (!cli_get_con_sesskey(con, sess_key))
+ {
+ return False;
+ }
+
+ cred_hash3( processed_new_pwd, hashed_trust_pwd, sess_key, 1);
+
+ cli_con_gen_next_creds( con, &new_clnt_cred);
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api NET_SRV_PWSET */
DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n",
- cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname,
+ srv_name, trust_acct, sec_chan_type, myhostname,
credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time));
/* store the parameters */
- init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->mach_acct, sec_chan_type,
- global_myname, &new_clnt_cred, (char *)hashed_mach_pwd);
+ make_q_srv_pwset(&q_s, srv_name, trust_acct, sec_chan_type,
+ myhostname, &new_clnt_cred, (char *)processed_new_pwd);
/* turn parameters into data stream */
- if(!net_io_q_srv_pwset("", &q_s, &buf, 0)) {
- DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n"));
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf))
+ if (net_io_q_srv_pwset("", &q_s, &buf, 0) &&
+ rpc_con_pipe_req(con, NET_SRVPWSET, &buf, &rbuf))
{
NET_R_SRV_PWSET r_s;
- ok = net_io_r_srv_pwset("", &r_s, &rbuf, 0);
+ net_io_r_srv_pwset("", &r_s, &rbuf, 0);
+ ok = (rbuf.offset != 0);
if (ok && r_s.status != 0)
{
/* report error code */
- DEBUG(0,("cli_net_srv_pwset: %s\n", get_nt_error_msg(r_s.status)));
- cli->nt_error = r_s.status;
+ DEBUG(5,("cli_net_srv_pwset: %s\n", get_nt_error_msg(r_s.status)));
ok = False;
}
/* Update the credentials. */
- if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred)))
+ if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_cred)))
{
/*
* Server replied with bad credential. Fail.
*/
- DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \
-password ?).\n", cli->desthost ));
+ DEBUG(5,("cli_net_srv_pwset: server %s replied with bad credential \
+(bad trust account password ?).\n", srv_name));
ok = False;
}
}
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
return ok;
}
/***************************************************************************
-LSA SAM Logon - interactive or network.
+LSA SAM Logon.
****************************************************************************/
-BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
- NET_USER_INFO_3 *user_info3)
+uint32 cli_net_sam_logon(const char* srv_name, const char* myhostname,
+ NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3)
{
DOM_CRED new_clnt_cred;
DOM_CRED dummy_rtn_creds;
@@ -346,77 +390,87 @@ BOOL cli_net_sam_logon(struct cli_state *cli, NET_ID_INFO_CTR *ctr,
prs_struct buf;
uint16 validation_level = 3;
NET_Q_SAM_LOGON q_s;
- BOOL ok = False;
+ uint32 status = 0x0;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
+ {
+ return 0xC0000000 | NT_STATUS_INVALID_PARAMETER;
+ }
- gen_next_creds( cli, &new_clnt_cred);
+ cli_con_gen_next_creds( con, &new_clnt_cred);
- prs_init(&buf , 1024, 4, False);
- prs_init(&rbuf, 0, 4, True );
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api NET_SAMLOGON */
- DEBUG(4,("cli_net_sam_logon: srv:%s mc:%s clnt %s %x ll: %d\n",
- cli->srv_name_slash, global_myname,
- credstr(new_clnt_cred.challenge.data), cli->clnt_cred.timestamp.time,
+ DEBUG(4,("cli_net_sam_logon: srv:%s mc:%s ll: %d\n",
+ srv_name, myhostname,
ctr->switch_value));
memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
dummy_rtn_creds.timestamp.time = time(NULL);
/* store the parameters */
- q_s.validation_level = validation_level;
- init_sam_info(&q_s.sam_id, cli->srv_name_slash, global_myname,
+ make_sam_info(&(q_s.sam_id), srv_name, myhostname,
&new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr);
- /* turn parameters into data stream */
- if(!net_io_q_sam_logon("", &q_s, &buf, 0)) {
- DEBUG(0,("cli_net_sam_logon: Error : failed to marshall NET_Q_SAM_LOGON struct.\n"));
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ q_s.validation_level = validation_level;
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, NET_SAMLOGON, &buf, &rbuf))
+ /* turn parameters into data stream */
+ if (net_io_q_sam_logon("", &q_s, &buf, 0) &&
+ rpc_con_pipe_req(con, NET_SAMLOGON, &buf, &rbuf))
{
NET_R_SAM_LOGON r_s;
r_s.user = user_info3;
- ok = net_io_r_sam_logon("", &r_s, &rbuf, 0);
+ net_io_r_sam_logon("", &r_s, &rbuf, 0);
+ status = (rbuf.offset == 0) ? 0xC0000000 | NT_STATUS_INVALID_PARAMETER : 0;
- if (ok && r_s.status != 0)
+ if (status != 0x0)
{
/* report error code */
- DEBUG(0,("cli_net_sam_logon: %s\n", get_nt_error_msg(r_s.status)));
- cli->nt_error = r_s.status;
- ok = False;
+ DEBUG(5,("cli_net_sam_logon: %s\n", get_nt_error_msg(r_s.status)));
+ }
+
+ if (status == 0x0)
+ {
+ /* report error code */
+ DEBUG(5,("cli_net_sam_logon: %s\n", get_nt_error_msg(r_s.status)));
+ status = r_s.status;
}
/* Update the credentials. */
- if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds)))
+ if (status == 0x0 && !cli_con_deal_with_creds(con, &(r_s.srv_creds)))
{
/*
* Server replied with bad credential. Fail.
*/
- DEBUG(0,("cli_net_sam_logon: server %s replied with bad credential (bad machine \
-password ?).\n", cli->desthost ));
- ok = False;
+ DEBUG(5,("cli_net_sam_logon: server %s replied with bad credential \
+(bad trust account password ?).\n", srv_name));
+ status = 0xC0000000 | NT_STATUS_LOGON_FAILURE;
}
- if (ok && r_s.switch_value != 3)
+ if (status == 0x0 && r_s.switch_value != 3)
{
/* report different switch_value */
- DEBUG(0,("cli_net_sam_logon: switch_value of 3 expected %x\n",
+ DEBUG(5,("cli_net_sam_logon: switch_value of 3 expected %x\n",
r_s.switch_value));
- ok = False;
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
}
}
+ else
+ {
+ status = 0xC0000000 | NT_STATUS_INVALID_PARAMETER;
+ }
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return ok;
+ return status;
}
/***************************************************************************
@@ -428,7 +482,8 @@ send a different info level. Right now though, I'm not sure
what that needs to be (I need to see one on the wire before
I can be sure). JRA.
****************************************************************************/
-BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
+BOOL cli_net_sam_logoff(const char* srv_name, const char* myhostname,
+ NET_ID_INFO_CTR *ctr)
{
DOM_CRED new_clnt_cred;
DOM_CRED dummy_rtn_creds;
@@ -437,266 +492,143 @@ BOOL cli_net_sam_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
NET_Q_SAM_LOGOFF q_s;
BOOL ok = False;
- gen_next_creds( cli, &new_clnt_cred);
+ struct cli_connection *con = NULL;
- prs_init(&buf , 1024, 4, False);
- prs_init(&rbuf, 0, 4, True );
+ if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
+ {
+ return False;
+ }
+
+ cli_con_gen_next_creds( con, &new_clnt_cred);
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api NET_SAMLOGOFF */
DEBUG(4,("cli_net_sam_logoff: srv:%s mc:%s clnt %s %x ll: %d\n",
- cli->srv_name_slash, global_myname,
+ srv_name, myhostname,
credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time,
ctr->switch_value));
memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds));
- init_sam_info(&q_s.sam_id, cli->srv_name_slash, global_myname,
+ /* store the parameters */
+ make_sam_info(&(q_s.sam_id), srv_name, myhostname,
&new_clnt_cred, &dummy_rtn_creds, ctr->switch_value, ctr);
/* turn parameters into data stream */
- if(!net_io_q_sam_logoff("", &q_s, &buf, 0)) {
- DEBUG(0,("cli_net_sam_logoff: Error : failed to marshall NET_Q_SAM_LOGOFF struct.\n"));
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, NET_SAMLOGOFF, &buf, &rbuf))
+ if (net_io_q_sam_logoff("", &q_s, &buf, 0) &&
+ rpc_con_pipe_req(con, NET_SAMLOGOFF, &buf, &rbuf))
{
NET_R_SAM_LOGOFF r_s;
- ok = net_io_r_sam_logoff("", &r_s, &rbuf, 0);
+ net_io_r_sam_logoff("", &r_s, &rbuf, 0);
+ ok = (rbuf.offset != 0);
if (ok && r_s.status != 0)
{
/* report error code */
- DEBUG(0,("cli_net_sam_logoff: %s\n", get_nt_error_msg(r_s.status)));
- cli->nt_error = r_s.status;
+ DEBUG(5,("cli_net_sam_logoff: %s\n", get_nt_error_msg(r_s.status)));
ok = False;
}
/* Update the credentials. */
- if (ok && !clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_creds)))
+ if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_creds)))
{
/*
* Server replied with bad credential. Fail.
*/
- DEBUG(0,("cli_net_sam_logoff: server %s replied with bad credential (bad machine \
-password ?).\n", cli->desthost ));
+ DEBUG(5,("cli_net_sam_logoff: server %s replied with bad credential \
+(bad trust account password ?).\n", srv_name ));
ok = False;
}
}
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
return ok;
}
-/*********************************************************
- Change the domain password on the PDC.
-**********************************************************/
-
-static BOOL modify_trust_password( char *domain, char *remote_machine,
- unsigned char orig_trust_passwd_hash[16],
- unsigned char new_trust_passwd_hash[16])
-{
- struct cli_state cli;
-
- ZERO_STRUCT(cli);
- if(cli_initialise(&cli) == False) {
- DEBUG(0,("modify_trust_password: unable to initialize client connection.\n"));
- return False;
- }
-
- if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) {
- DEBUG(0,("modify_trust_password: Can't resolve address for %s\n", remote_machine));
- return False;
- }
-
- if (ismyip(cli.dest_ip)) {
- DEBUG(0,("modify_trust_password: Machine %s is one of our addresses. Cannot add \
-to ourselves.\n", remote_machine));
- return False;
- }
-
- if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) {
- DEBUG(0,("modify_trust_password: unable to connect to SMB server on \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- return False;
- }
-
- if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) {
- DEBUG(0,("modify_trust_password: machine %s rejected the NetBIOS \
-session request. Error was %s\n", remote_machine, cli_errstr(&cli) ));
- return False;
- }
-
- cli.protocol = PROTOCOL_NT1;
-
- if (!cli_negprot(&cli)) {
- DEBUG(0,("modify_trust_password: machine %s rejected the negotiate protocol. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
- if (cli.protocol != PROTOCOL_NT1) {
- DEBUG(0,("modify_trust_password: machine %s didn't negotiate NT protocol.\n",
- remote_machine));
- cli_shutdown(&cli);
- return False;
- }
-
- /*
- * Do an anonymous session setup.
- */
-
- if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
- DEBUG(0,("modify_trust_password: machine %s rejected the session setup. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
- if (!(cli.sec_mode & 1)) {
- DEBUG(0,("modify_trust_password: machine %s isn't in user level security mode\n",
- remote_machine));
- cli_shutdown(&cli);
- return False;
- }
-
- if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) {
- DEBUG(0,("modify_trust_password: machine %s rejected the tconX on the IPC$ share. \
-Error was : %s.\n", remote_machine, cli_errstr(&cli) ));
- cli_shutdown(&cli);
- return False;
- }
-
- /*
- * Ok - we have an anonymous connection to the IPC$ share.
- * Now start the NT Domain stuff :-).
- */
-
- if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) {
- DEBUG(0,("modify_trust_password: unable to open the domain client session to \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
-
- if(cli_nt_setup_creds(&cli, orig_trust_passwd_hash) == False) {
- DEBUG(0,("modify_trust_password: unable to setup the PDC credentials to machine \
-%s. Error was : %s.\n", remote_machine, cli_errstr(&cli)));
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
-
- if( cli_nt_srv_pwset( &cli,new_trust_passwd_hash ) == False) {
- DEBUG(0,("modify_trust_password: unable to change password for machine %s in domain \
-%s to Domain controller %s. Error was %s.\n", global_myname, domain, remote_machine,
- cli_errstr(&cli)));
- cli_close(&cli, cli.nt_pipe_fnum);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
-
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
-
- return True;
-}
-
-/************************************************************************
- Change the trust account password for a domain.
- The user of this function must have locked the trust password file for
- update.
-************************************************************************/
-
-BOOL change_trust_account_password( char *domain, char *remote_machine_list)
+/***************************************************************************
+Synchronise SAM Database (requires SEC_CHAN_BDC).
+****************************************************************************/
+BOOL cli_net_sam_sync( const char* srv_name, const char* myhostname,
+ uint32 database_id,
+ uint32 *num_deltas,
+ SAM_DELTA_HDR *hdr_deltas,
+ SAM_DELTA_CTR *deltas)
{
- fstring remote_machine;
- unsigned char old_trust_passwd_hash[16];
- unsigned char new_trust_passwd_hash[16];
- time_t lct;
- BOOL res = False;
-
- if(!get_trust_account_password( old_trust_passwd_hash, &lct)) {
- DEBUG(0,("change_trust_account_password: unable to read the machine \
-account password for domain %s.\n", domain));
- return False;
- }
-
- /*
- * Create the new (random) password.
- */
- generate_random_buffer( new_trust_passwd_hash, 16, True);
-
- while(remote_machine_list &&
- next_token(&remote_machine_list, remote_machine,
- LIST_SEP, sizeof(remote_machine))) {
- strupper(remote_machine);
- if(strequal(remote_machine, "*")) {
-
- /*
- * We have been asked to dynamcially determine the IP addresses of the PDC.
- */
-
- struct in_addr *ip_list = NULL;
- int count = 0;
- int i;
-
- if(!get_dc_list(domain, &ip_list, &count))
- continue;
-
- /*
- * Try and connect to the PDC/BDC list in turn as an IP
- * address used as a string.
- */
-
- for(i = 0; i < count; i++) {
- fstring dc_name;
- if(!lookup_pdc_name(global_myname, domain, &ip_list[i], dc_name))
- continue;
- if((res = modify_trust_password( domain, dc_name,
- old_trust_passwd_hash, new_trust_passwd_hash)))
- break;
- }
-
- if(ip_list != NULL)
- free((char *)ip_list);
-
- } else {
- res = modify_trust_password( domain, remote_machine,
- old_trust_passwd_hash, new_trust_passwd_hash);
- }
-
- if(res) {
- DEBUG(0,("%s : change_trust_account_password: Changed password for \
-domain %s.\n", timestring(False), domain));
- /*
- * Return the result of trying to write the new password
- * back into the trust account file.
- */
- res = set_trust_account_password(new_trust_passwd_hash);
- memset(new_trust_passwd_hash, 0, 16);
- memset(old_trust_passwd_hash, 0, 16);
- return res;
- }
- }
-
- memset(new_trust_passwd_hash, 0, 16);
- memset(old_trust_passwd_hash, 0, 16);
-
- DEBUG(0,("%s : change_trust_account_password: Failed to change password for \
-domain %s.\n", timestring(False), domain));
- return False;
+ NET_Q_SAM_SYNC q_s;
+ prs_struct rbuf;
+ prs_struct buf;
+ DOM_CRED new_clnt_cred;
+ BOOL ok = False;
+ uint8 sess_key[16];
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_getsrv(srv_name, PIPE_NETLOGON, &con))
+ {
+ return False;
+ }
+
+ if (!cli_get_con_sesskey(con, sess_key))
+ {
+ return False;
+ }
+
+ cli_con_gen_next_creds(con, &new_clnt_cred);
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api NET_SAM_SYNC */
+
+ make_q_sam_sync(&q_s, srv_name, myhostname,
+ &new_clnt_cred, database_id);
+
+ /* turn parameters into data stream */
+ if (net_io_q_sam_sync("", &q_s, &buf, 0) &&
+ rpc_con_pipe_req(con, NET_SAM_SYNC, &buf, &rbuf))
+ {
+ NET_R_SAM_SYNC r_s;
+
+ r_s.hdr_deltas = hdr_deltas;
+ r_s.deltas = deltas;
+
+ net_io_r_sam_sync("", sess_key, &r_s, &rbuf, 0);
+ ok = (rbuf.offset != 0);
+
+ if (ok && r_s.status != 0 && r_s.status != STATUS_MORE_ENTRIES)
+ {
+ /* report error code */
+ DEBUG(5,("cli_net_sam_sync: %s\n", get_nt_error_msg(r_s.status)));
+ ok = False;
+ }
+
+ /* Update the credentials. */
+ if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_creds)))
+ {
+ DEBUG(5,("cli_net_sam_sync: server %s replied with bad \
+credential (bad trust account password ?).\n", srv_name));
+ ok = False;
+ }
+
+ if (ok)
+ {
+ *num_deltas = r_s.num_deltas2;
+
+ if (r_s.status == STATUS_MORE_ENTRIES)
+ {
+ DEBUG(5, ("(More entries)\n"));
+ }
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return ok;
}
diff --git a/source/rpc_client/cli_netlogon_sync.c b/source/rpc_client/cli_netlogon_sync.c
new file mode 100644
index 00000000000..440d9ed34d3
--- /dev/null
+++ b/source/rpc_client/cli_netlogon_sync.c
@@ -0,0 +1,110 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Matthew Chapman 1999-2000,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+extern pstring global_myname;
+
+BOOL synchronise_passdb(void)
+{
+ SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS];
+ SAM_DELTA_CTR deltas[MAX_SAM_DELTAS];
+ uint32 num;
+
+ SAM_ACCOUNT_INFO *acc;
+ struct smb_passwd pwd;
+ fstring nt_name;
+ unsigned char smb_passwd[16];
+ unsigned char smb_nt_passwd[16];
+ uchar trust_passwd[16];
+ fstring trust_acct;
+
+ char *mode;
+ BOOL success;
+ BOOL ret;
+ int i;
+
+ fstrcpy(trust_acct, global_myname);
+ fstrcat(trust_acct, "$");
+
+ if (!msrpc_lsa_query_trust_passwd("\\\\.", "$MACHINE.ACC",
+ trust_passwd, NULL))
+ {
+ return False;
+ }
+
+ ret = net_sam_sync(lp_passwordserver(), lp_workgroup(),
+ global_myname, trust_acct,
+ trust_passwd, hdr_deltas, deltas, &num);
+
+ if (ret)
+ {
+ for (i = 0; i < num; i++)
+ {
+ /* Currently only interested in accounts */
+ if (hdr_deltas[i].type != 5)
+ {
+ continue;
+ }
+
+ acc = &deltas[i].account_info;
+ pwdb_init_smb(&pwd);
+
+ pwd.user_rid = acc->user_rid;
+ unistr2_to_ascii(nt_name, &(acc->uni_acct_name),
+ sizeof(fstring) - 1);
+ pwd.nt_name = nt_name;
+ pwd.acct_ctrl = acc->acb_info;
+ pwd.pass_last_set_time =
+ nt_time_to_unix(&(acc->pwd_last_set_time));
+
+ sam_pwd_hash(acc->user_rid, smb_passwd,
+ acc->pass.buf_lm_pwd, 0);
+ sam_pwd_hash(acc->user_rid, smb_nt_passwd,
+ acc->pass.buf_nt_pwd, 0);
+ pwd.smb_passwd = smb_passwd;
+ pwd.smb_nt_passwd = smb_nt_passwd;
+
+ mode = "modify";
+ success = mod_smbpwd_entry(&pwd, True);
+
+ if (!success)
+ {
+ mode = "add";
+ success = add_smbpwd_entry(&pwd);
+ }
+
+ DEBUG(0,
+ ("Attempted to %s account for %s: %s\n", mode,
+ nt_name, success ? "OK" : "FAILED"));
+ }
+ }
+
+ return ret;
+}
diff --git a/source/rpc_client/cli_pipe.c b/source/rpc_client/cli_pipe.c
index 8711ab116ee..c1fedbdf149 100644
--- a/source/rpc_client/cli_pipe.c
+++ b/source/rpc_client/cli_pipe.c
@@ -3,10 +3,9 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1998.
- * Copyright (C) Jeremy Allison 1999.
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Elrond 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,16 +28,15 @@
#endif
#include "includes.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
extern struct pipe_id_info pipe_names[];
-extern fstring global_myworkgroup;
extern pstring global_myname;
/********************************************************************
- Rpc pipe call id.
+ rpc pipe call id
********************************************************************/
-
static uint32 get_rpc_call_id(void)
{
static uint32 call_id = 0;
@@ -46,831 +44,747 @@ static uint32 get_rpc_call_id(void)
}
/*******************************************************************
- Use SMBreadX to get rest of one fragment's worth of rpc data.
+ uses SMBreadX to get rest of rpc data
********************************************************************/
-static BOOL rpc_read(struct cli_state *cli, prs_struct *rdata, uint32 data_to_read, uint32 *rdata_offset)
+static BOOL rpc_read(struct cli_state *cli, uint16 fnum,
+ prs_struct * rdata, uint32 data_to_read,
+ uint32 rdata_offset, BOOL one_only)
{
- size_t size = (size_t)cli->max_recv_frag;
- int stream_offset = 0;
+ size_t size = cli->nt.max_recv_frag;
+ int file_offset = 0;
int num_read;
- char *pdata;
- uint32 err;
- int extra_data_size = ((int)*rdata_offset) + ((int)data_to_read) - (int)prs_data_size(rdata);
-
- DEBUG(5,("rpc_read: data_to_read: %u rdata offset: %u extra_data_size: %d\n",
- (int)data_to_read, (unsigned int)*rdata_offset, extra_data_size));
+ char *data;
+ uint32 new_data_size = rdata_offset + data_to_read;
+ uint8 cls;
+ uint32 type;
- /*
- * Grow the buffer if needed to accommodate the data to be read.
- */
+ DEBUG(5,
+ ("rpc_read: data_to_read: %d data offset: %d file offset: %d\n",
+ data_to_read, rdata_offset, file_offset));
- if (extra_data_size > 0) {
- if(!prs_force_grow(rdata, (uint32)extra_data_size)) {
- DEBUG(0,("rpc_read: Failed to grow parse struct by %d bytes.\n", extra_data_size ));
- return False;
- }
- DEBUG(5,("rpc_read: grew buffer by %d bytes to %u\n", extra_data_size, prs_data_size(rdata) ));
+ if (new_data_size > rdata->data_size)
+ {
+ prs_grow_data(rdata, True, new_data_size, True);
+ DEBUG(5, ("rpc_read: grow buffer to %d\n", rdata->data_size));
}
- pdata = prs_data_p(rdata) + *rdata_offset;
+ data = rdata->data + rdata_offset;
- do /* read data using SMBreadX */
+ do /* read data using SMBreadX */
{
- if (size > (size_t)data_to_read)
- size = (size_t)data_to_read;
+ if (size > data_to_read)
+ {
+ size = data_to_read;
+ }
- num_read = (int)cli_read(cli, cli->nt_pipe_fnum, pdata, (off_t)stream_offset, size);
+ num_read = cli_read_one(cli, fnum, data, file_offset, size);
- DEBUG(5,("rpc_read: num_read = %d, read offset: %d, to read: %d\n",
- num_read, stream_offset, data_to_read));
+ DEBUG(5, ("rpc_read: read offset: %d read: %d to read: %d\n",
+ file_offset, num_read, data_to_read));
- if (cli_error(cli, NULL, &err, NULL)) {
- DEBUG(0,("rpc_read: Error %u in cli_read\n", (unsigned int)err ));
- return False;
+ data_to_read -= num_read;
+ file_offset += num_read;
+ data += num_read;
+
+ if (cli_error(cli, &cls, &type))
+ {
+ if (cls != ERRDOS || type != ERRmoredata)
+ {
+ return False;
+ }
}
- data_to_read -= num_read;
- stream_offset += num_read;
- pdata += num_read;
+ }
+ while (!one_only && num_read > 0 && data_to_read > 0);
- } while (num_read > 0 && data_to_read > 0);
- /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
+ rdata->end = new_data_size;
- /*
- * Update the current offset into rdata by the amount read.
- */
- *rdata_offset += stream_offset;
+ DEBUG(5, ("rpc_read: offset end: 0x%x. data left to read:0x%x\n",
+ rdata->end, data_to_read));
return True;
}
/****************************************************************************
- Checks the header.
+ checks the header
****************************************************************************/
-
-static BOOL rpc_check_hdr(prs_struct *rdata, RPC_HDR *rhdr,
- BOOL *first, BOOL *last, uint32 *len)
+static BOOL rpc_check_hdr(prs_struct * rdata, RPC_HDR * rhdr,
+ BOOL *first, BOOL *last, int *len)
{
- DEBUG(5,("rpc_check_hdr: rdata->data_size = %u\n", (uint32)prs_data_size(rdata) ));
+ DEBUG(5, ("rpc_check_hdr: rdata->data_size: %d\n", rdata->data_size));
- if(!smb_io_rpc_hdr("rpc_hdr ", rhdr, rdata, 0)) {
- DEBUG(0,("rpc_check_hdr: Failed to unmarshall RPC_HDR.\n"));
- return False;
- }
+ smb_io_rpc_hdr("rpc_hdr ", rhdr, rdata, 0);
- if (prs_offset(rdata) != RPC_HEADER_LEN) {
- DEBUG(0,("rpc_check_hdr: offset was %x, should be %x.\n", prs_offset(rdata), RPC_HEADER_LEN));
+ if (!rdata->offset || rdata->offset != 0x10)
+ {
+ DEBUG(0, ("rpc_check_hdr: error in rpc header\n"));
return False;
}
+ DEBUG(5,
+ ("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data_size: %d\n",
+ rdata->data_size));
+
(*first) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_FIRST);
- (*last) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST );
- (*len) = (uint32)rhdr->frag_len - prs_data_size(rdata);
+ (*last) = IS_BITS_SET_ALL(rhdr->flags, RPC_FLG_LAST);
+ (*len) = rhdr->frag_len - rdata->data_size;
- return (rhdr->pkt_type != RPC_FAULT);
+ return rhdr->pkt_type != RPC_FAULT;
}
-static void NTLMSSPcalc_ap( struct cli_state *cli, unsigned char *data, uint32 len)
-{
- unsigned char *hash = cli->ntlmssp_hash;
- unsigned char index_i = hash[256];
- unsigned char index_j = hash[257];
- int ind;
-
- for( ind = 0; ind < len; ind++) {
- unsigned char tc;
- unsigned char t;
+/*******************************************************************
+ creates a DCE/RPC bind request
- index_i++;
- index_j += hash[index_i];
+ - initialises the parse structure.
+ - dynamically allocates the header data structure
+ - caller is expected to free the header data structure once used.
- tc = hash[index_i];
- hash[index_i] = hash[index_j];
- hash[index_j] = tc;
+ ********************************************************************/
+BOOL create_rpc_request(prs_struct * rhdr, uint16 vuid,
+ uint8 op_num, uint8 flags, int data_len, int auth_len)
+{
+ uint32 alloc_hint;
+ RPC_HDR_REQ hdr_req;
+ RPC_HDR hdr;
- t = hash[index_i] + hash[index_j];
- data[ind] = data[ind] ^ hash[t];
- }
+ DEBUG(5, ("create_rpc_request: opnum: 0x%x data_len: 0x%x\n",
+ op_num, data_len));
- hash[256] = index_i;
- hash[257] = index_j;
-}
+ /* create the rpc header RPC_HDR */
+ make_rpc_hdr(&hdr, RPC_REQUEST, flags,
+ get_rpc_call_id(), data_len, auth_len);
-/****************************************************************************
- Verify data on an rpc pipe.
- The VERIFY & SEAL code is only executed on packets that look like this :
+ if (auth_len != 0)
+ {
+ alloc_hint = data_len - 0x18 - auth_len - 16;
+ }
+ else
+ {
+ alloc_hint = data_len - 0x18;
+ }
- Request/Response PDU's look like the following...
+ DEBUG(10,
+ ("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n",
+ data_len, auth_len, alloc_hint));
- |<------------------PDU len----------------------------------------------->|
- |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
+ /* create the rpc request RPC_HDR_REQ */
+ make_rpc_hdr_req(&hdr_req, alloc_hint, vuid, op_num);
- +------------+-----------------+-------------+---------------+-------------+
- | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
- +------------+-----------------+-------------+---------------+-------------+
+ /* stream-time... */
+ smb_io_rpc_hdr("hdr ", &hdr, rhdr, 0);
+ smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0);
- Never on bind requests/responses.
- ****************************************************************************/
+ if (rhdr->data == NULL || rhdr->offset != 0x18)
+ return False;
-static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, int len, int auth_len)
-{
- /*
- * The following is that length of the data we must sign or seal.
- * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
- * preceeding the auth_data.
- */
+ rhdr->start = 0;
+ rhdr->end = rhdr->offset;
- int data_len = len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
+ return True;
+}
- /*
- * The start of the data to sign/seal is just after the RPC headers.
- */
- char *reply_data = prs_data_p(rdata) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;
+/****************************************************************************
+ send data on an rpc pipe, which *must* be in one fragment.
+ receive response data from an rpc pipe, which may be large...
- BOOL auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
- BOOL auth_seal = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
+ read the first fragment: unfortunately have to use SMBtrans for the first
+ bit, then SMBreadX for subsequent bits.
- DEBUG(5,("rpc_auth_pipe: len: %d auth_len: %d verify %s seal %s\n",
- len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal)));
+ if first fragment received also wasn't the last fragment, continue
+ getting fragments until we _do_ receive the last fragment.
- /*
- * Unseal any sealed data in the PDU, not including the
- * 8 byte auth_header or the auth_data.
- */
+ ****************************************************************************/
+static BOOL rpc_api_pipe_bind(struct cli_connection *con, prs_struct * data,
+ prs_struct * rdata)
+{
+ int len;
- if (auth_seal) {
- DEBUG(10,("rpc_auth_pipe: unseal\n"));
- dump_data(100, reply_data, data_len);
- NTLMSSPcalc_ap(cli, (uchar*)reply_data, data_len);
- dump_data(100, reply_data, data_len);
- }
+ BOOL first = True;
+ BOOL last = True;
+ RPC_HDR rhdr;
+ prs_struct rpdu;
- if (auth_verify || auth_seal) {
- RPC_HDR_AUTH rhdr_auth;
- prs_struct auth_req;
- char data[RPC_HDR_AUTH_LEN];
- /*
- * We set dp to be the end of the packet, minus the auth_len
- * and the length of the header that preceeds the auth_data.
- */
- char *dp = prs_data_p(rdata) + len - auth_len - RPC_HDR_AUTH_LEN;
-
- if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
- DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
- return False;
- }
+ prs_init(&rpdu, 0, 4, True);
- memcpy(data, dp, sizeof(data));
-
- prs_init(&auth_req , 0, 4, UNMARSHALL);
- prs_give_memory(&auth_req, data, RPC_HDR_AUTH_LEN, False);
+ rpc_api_send_rcv_pdu(con, data, &rpdu);
- /*
- * Unmarshall the 8 byte auth_header that comes before the
- * auth data.
- */
+ /**** parse the header: check it's a response record */
- if(!smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0)) {
- DEBUG(0,("rpc_auth_pipe: unmarshalling RPC_HDR_AUTH failed.\n"));
- return False;
- }
+ rpdu.start = 0;
+ rpdu.end = rpdu.data_size;
+ rpdu.offset = 0;
- if (!rpc_hdr_auth_chk(&rhdr_auth)) {
- DEBUG(0,("rpc_auth_pipe: rpc_hdr_auth_chk failed.\n"));
- return False;
- }
+ if (!rpc_check_hdr(&rpdu, &rhdr, &first, &last, &len))
+ {
+ return False;
}
- /*
- * Now unseal and check the auth verifier in the auth_data at
- * then end of the packet. The 4 bytes skipped in the unseal
- * seem to be a buffer pointer preceeding the sealed data.
- */
+ prs_set_packtype(rdata, rhdr.pack_type);
- if (auth_verify) {
- RPC_AUTH_NTLMSSP_CHK chk;
- uint32 crc32;
- prs_struct auth_verf;
- char data[RPC_AUTH_NTLMSSP_CHK_LEN];
- char *dp = prs_data_p(rdata) + len - auth_len;
-
- if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
- DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
- return False;
- }
-
- DEBUG(10,("rpc_auth_pipe: verify\n"));
- dump_data(100, dp, auth_len);
- NTLMSSPcalc_ap(cli, (uchar*)(dp+4), auth_len - 4);
-
- memcpy(data, dp, RPC_AUTH_NTLMSSP_CHK_LEN);
- dump_data(100, data, auth_len);
+ if (rhdr.pkt_type != RPC_BINDACK)
+ {
+ return False;
+ }
+ if (!last && !first)
+ {
+ DEBUG(5,
+ ("cli_pipe: bug in AS/U, setting fragment first/last ON\n"));
+ first = True;
+ last = True;
+ }
- prs_init(&auth_verf, 0, 4, UNMARSHALL);
- prs_give_memory(&auth_verf, data, RPC_AUTH_NTLMSSP_CHK_LEN, False);
+ prs_append_data(rdata, prs_data(&rpdu, rpdu.offset),
+ rhdr.frag_len - rpdu.offset);
+ prs_free_data(&rpdu);
- if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0)) {
- DEBUG(0,("rpc_auth_pipe: unmarshalling RPC_AUTH_NTLMSSP_CHK failed.\n"));
- return False;
- }
+ /* only one rpc fragment, and it has been read */
+ if (!first || !last)
+ {
+ return False;
+ }
- crc32 = crc32_calc_buffer(reply_data, data_len);
+ DEBUG(6, ("cli_pipe: fragment first and last both set\n"));
- if (!rpc_auth_ntlmssp_chk(&chk, crc32 , cli->ntlmssp_seq_num)) {
- DEBUG(0,("rpc_auth_pipe: rpc_auth_ntlmssp_chk failed.\n"));
- return False;
- }
- cli->ntlmssp_seq_num++;
- }
return True;
}
-
/****************************************************************************
- Send data on an rpc pipe, which *must* be in one fragment.
receive response data from an rpc pipe, which may be large...
- Read the first fragment: unfortunately have to use SMBtrans for the first
+ read the first fragment: unfortunately have to use SMBtrans for the first
bit, then SMBreadX for subsequent bits.
- If first fragment received also wasn't the last fragment, continue
+ if first fragment received also wasn't the last fragment, continue
getting fragments until we _do_ receive the last fragment.
- Request/Response PDU's look like the following...
-
- |<------------------PDU len----------------------------------------------->|
- |<-HDR_LEN-->|<--REQ LEN------>|.............|<-AUTH_HDRLEN->|<-AUTH_LEN-->|
-
- +------------+-----------------+-------------+---------------+-------------+
- | RPC HEADER | REQ/RESP HEADER | DATA ...... | AUTH_HDR | AUTH DATA |
- +------------+-----------------+-------------+---------------+-------------+
-
- Where the presence of the AUTH_HDR and AUTH are dependent on the
- signing & sealing being neogitated.
-
****************************************************************************/
-
-static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, prs_struct *rdata)
+BOOL rpc_api_pipe_req(struct cli_connection *con, uint8 opnum,
+ prs_struct * data, prs_struct * rdata)
{
- uint32 len;
- char *rparam = NULL;
- uint32 rparam_len = 0;
- uint16 setup[2];
- uint32 err;
+ int len;
+
BOOL first = True;
- BOOL last = True;
+ BOOL last = True;
RPC_HDR rhdr;
- char *pdata = data ? prs_data_p(data) : NULL;
- uint32 data_len = data ? prs_offset(data) : 0;
- char *prdata = NULL;
- uint32 rdata_len = 0;
- uint32 current_offset = 0;
+ prs_struct rpdu;
+ cli_auth_fns *auth = cli_conn_get_authfns(con);
+ uint8 flags;
- /*
- * Create setup parameters - must be in native byte order.
- */
- setup[0] = cmd;
- setup[1] = cli->nt_pipe_fnum; /* Pipe file handle. */
+ int data_start = 0;
+ int data_end = 0;
- DEBUG(5,("rpc_api_pipe: cmd:%x fnum:%x\n", (int)cmd, (int)cli->nt_pipe_fnum));
+ prs_init(&rpdu, 0, 4, True);
- /* send the data: receive a response. */
- if (!cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
- setup, 2, 0, /* Setup, length, max */
- NULL, 0, 0, /* Params, length, max */
- pdata, data_len, data_len, /* data, length, max */
- &rparam, &rparam_len, /* return params, len */
- &prdata, &rdata_len)) /* return data, len */
+ do
{
- DEBUG(0, ("cli_pipe: return critical error. Error was %s\n", cli_errstr(cli)));
- return False;
- }
+ prs_struct data_t;
- /*
- * Throw away returned params - we know we won't use them.
- */
+ DEBUG(10, ("rpc_api_pipe_req: start: %d off: %d\n",
+ data_start, data->offset));
+
+ if (!auth->cli_create_pdu(con, opnum, data, data_start,
+ &data_end, &data_t, &flags))
+ {
+ return False;
+ }
+
+ DEBUG(10, ("rpc_api_pipe_req: end: %d\n", data_end));
+ dbgflush();
+
+ if (IS_BITS_CLR_ALL(flags, RPC_FLG_LAST))
+ {
+ if (!rpc_api_write(con, &data_t))
+ {
+ prs_free_data(&data_t);
+ return False;
+ }
+ }
+ else
+ {
+ if (!rpc_api_send_rcv_pdu(con, &data_t, &rpdu))
+ {
+ prs_free_data(&data_t);
+ return False;
+ }
+
+ if (data_end != data->offset)
+ {
+ prs_free_data(&rpdu);
+ prs_init(&rpdu, 0, 4, True);
+ }
+ }
+
+ prs_free_data(&data_t);
+ data_start = data_end;
- if(rparam) {
- free(rparam);
- rparam = NULL;
}
+ while (data_end < data->offset);
- if (prdata == NULL) {
- DEBUG(0,("rpc_api_pipe: cmd %x on pipe %x failed to return data.\n",
- (int)cmd, (int)cli->nt_pipe_fnum));
+ if (data_end != data->offset)
+ {
+ DEBUG(2,
+ ("rpc_api_pipe_req: data_end: %d and offset %d wrong\n",
+ data_end, data->offset));
+ prs_free_data(&rpdu);
return False;
}
- /*
- * Give this memory as dynamically allocated to the return parse struct.
- */
+ /**** parse the header: check it's a response record */
- prs_give_memory(rdata, prdata, rdata_len, True);
- current_offset = rdata_len;
+ rpdu.start = 0;
+ rpdu.end = rpdu.data_size;
+ rpdu.offset = 0;
- if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len)) {
- prs_mem_free(rdata);
+ if (!rpc_check_hdr(&rpdu, &rhdr, &first, &last, &len))
+ {
return False;
}
- if (rhdr.pkt_type == RPC_BINDACK) {
- if (!last && !first) {
- DEBUG(5,("rpc_api_pipe: bug in server (AS/U?), setting fragment first/last ON.\n"));
+ prs_set_packtype(rdata, rhdr.pack_type);
+
+ if (rhdr.pkt_type == RPC_BINDACK)
+ {
+ if (!last && !first)
+ {
+ DEBUG(5,
+ ("cli_pipe: bug in AS/U, setting fragment first/last ON\n"));
first = True;
last = True;
}
}
- if (rhdr.pkt_type == RPC_RESPONSE) {
+ if (rhdr.pkt_type == RPC_RESPONSE)
+ {
RPC_HDR_RESP rhdr_resp;
- if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0)) {
- DEBUG(5,("rpc_api_pipe: failed to unmarshal RPC_HDR_RESP.\n"));
- prs_mem_free(rdata);
- return False;
- }
+ smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &rpdu, 0);
}
- DEBUG(5,("rpc_api_pipe: len left: %u smbtrans read: %u\n",
- (unsigned int)len, (unsigned int)rdata_len ));
-
- /* check if data to be sent back was too large for one SMB. */
- /* err status is only informational: the _real_ check is on the length */
- if (len > 0) {
- /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
- /*
- * Read the rest of the first response PDU.
- */
- if (!rpc_read(cli, rdata, len, &current_offset)) {
- prs_mem_free(rdata);
- return False;
- }
+ if (rhdr.auth_len != 0
+ && !auth->cli_decode_pdu(con, &rpdu, rhdr.frag_len,
+ rhdr.auth_len))
+ {
+ DEBUG(10, ("auth->cli_decode_pdu: failed\n"));
+ return False;
}
- /*
- * Now we have a complete PDU, check the auth struct if any was sent.
- */
-
- if (rhdr.auth_len != 0) {
- if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
- return False;
- /*
- * Drop the auth footers from the current offset.
- * We need this if there are more fragments.
- * The auth footers consist of the auth_data and the
- * preceeding 8 byte auth_header.
- */
- current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN);
+ {
+ prs_append_data(rdata,
+ prs_data(&rpdu, rpdu.offset),
+ rhdr.frag_len - rpdu.offset);
+ prs_free_data(&rpdu);
}
-
- /*
- * Only one rpc fragment, and it has been read.
- */
- if (first && last) {
- DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
+ /* only one rpc fragment, and it has been read */
+ if (first && last)
+ {
+ DEBUG(6, ("cli_pipe: fragment first and last both set\n"));
return True;
}
- /*
- * Read more fragments until we get the last one.
- */
+ DEBUG(100, ("first frag: %s", BOOLSTR(first)));
+ DEBUG(100, ("last frag: %s\n", BOOLSTR(last)));
- while (!last) {
+ while (!last) /* read more fragments until we get the last one */
+ {
RPC_HDR_RESP rhdr_resp;
int num_read;
- char hdr_data[RPC_HEADER_LEN+RPC_HDR_RESP_LEN];
- prs_struct hps;
- /*
- * First read the header of the next PDU.
- */
+ DEBUG(10, ("rpc_api_pipe: another fragment expected\n"));
- prs_init(&hps, 0, 4, UNMARSHALL);
- prs_give_memory(&hps, hdr_data, sizeof(hdr_data), False);
+ prs_init(&rpdu, 0, 4, True);
- num_read = cli_read(cli, cli->nt_pipe_fnum, hdr_data, 0, RPC_HEADER_LEN+RPC_HDR_RESP_LEN);
- if (cli_error(cli, NULL, &err, NULL)) {
- DEBUG(0,("rpc_api_pipe: cli_read error : %d\n", err ));
- return False;
- }
+ rpc_api_rcv_pdu(con, &rpdu);
+
+ rpdu.start = 0;
+ rpdu.end = rpdu.data_size;
+ rpdu.offset = 0;
+ num_read = rpdu.data_size;
- DEBUG(5,("rpc_api_pipe: read header (size:%d)\n", num_read));
+ DEBUG(5, ("cli_pipe: read header (size:%d)\n", num_read));
- if (num_read != RPC_HEADER_LEN+RPC_HDR_RESP_LEN) {
- DEBUG(0,("rpc_api_pipe: Error : requested %d bytes, got %d.\n",
- RPC_HEADER_LEN+RPC_HDR_RESP_LEN, num_read ));
+ if (!rpc_check_hdr(&rpdu, &rhdr, &first, &last, &len))
+ {
+ prs_free_data(&rpdu);
return False;
}
- if (!rpc_check_hdr(&hps, &rhdr, &first, &last, &len))
- return False;
+ smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &rpdu, 0);
- if(!smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0)) {
- DEBUG(0,("rpc_api_pipe: Error in unmarshalling RPC_HDR_RESP.\n"));
+ if (first)
+ {
+ DEBUG(0, ("cli_pipe: wierd rpc header received\n"));
+ prs_free_data(&rpdu);
return False;
}
- if (first) {
- DEBUG(0,("rpc_api_pipe: secondary PDU rpc header has 'first' set !\n"));
+ if (rhdr.auth_len != 0 &&
+ !auth->cli_decode_pdu(con, &rpdu, rhdr.frag_len,
+ rhdr.auth_len))
+ {
+ prs_free_data(&rpdu);
return False;
}
- /*
- * Now read the rest of the PDU.
- */
-
- if (!rpc_read(cli, rdata, len, &current_offset))
- return False;
-
- /*
- * Verify any authentication footer.
- */
-
- if (rhdr.auth_len != 0 ) {
- if(!rpc_auth_pipe(cli, rdata, rhdr.frag_len, rhdr.auth_len))
- return False;
- /*
- * Drop the auth footers from the current offset.
- * The auth footers consist of the auth_data and the
- * preceeding 8 byte auth_header.
- * We need this if there are more fragments.
- */
- current_offset -= (rhdr.auth_len + RPC_HDR_AUTH_LEN);
+ {
+ prs_append_data(rdata,
+ prs_data(&rpdu, rpdu.offset),
+ rhdr.frag_len - rpdu.offset);
+ prs_free_data(&rpdu);
}
}
return True;
}
-/*******************************************************************
- creates a DCE/RPC bind request
-
- - initialises the parse structure.
- - dynamically allocates the header data structure
- - caller is expected to free the header data structure once used.
-
- ********************************************************************/
-
-static BOOL create_rpc_bind_req(prs_struct *rpc_out, BOOL do_auth, uint32 rpc_call_id,
- RPC_IFACE *abstract, RPC_IFACE *transfer,
- char *my_name, char *domain, uint32 neg_flags)
-{
- RPC_HDR hdr;
- RPC_HDR_RB hdr_rb;
- char buffer[4096];
- prs_struct auth_info;
- int auth_len = 0;
-
- prs_init(&auth_info, 0, 4, MARSHALL);
-
- if (do_auth) {
- RPC_HDR_AUTH hdr_auth;
- RPC_AUTH_VERIFIER auth_verifier;
- RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
-
- /*
- * Create the auth structs we will marshall.
- */
-
- init_rpc_hdr_auth(&hdr_auth, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, 0x00, 1);
- init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_NEGOTIATE);
- init_rpc_auth_ntlmssp_neg(&ntlmssp_neg, neg_flags, my_name, domain);
+/****************************************************************************
+ send data on an rpc pipe, which *must* be in one fragment.
+ receive response data from an rpc pipe, which may be large...
- /*
- * Use the 4k buffer to store the auth info.
- */
+ read the first fragment: unfortunately have to use SMBtrans for the first
+ bit, then SMBreadX for subsequent bits.
- prs_give_memory( &auth_info, buffer, sizeof(buffer), False);
+ if first fragment received also wasn't the last fragment, continue
+ getting fragments until we _do_ receive the last fragment.
- /*
- * Now marshall the data into the temporary parse_struct.
- */
+ [note: from a data abstraction viewpoint, this function is marginally
+ complicated by the return side of cli_api_pipe getting in the way
+ (i.e, the SMB header stuff). the proper way to do this is to split
+ cli_api_pipe down into receive / transmit. oh, and split cli_readx
+ down. in other words, state-based (kernel) techniques...]
- if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &auth_info, 0)) {
- DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_AUTH.\n"));
- return False;
- }
+ ****************************************************************************/
- if(!smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_info, 0)) {
- DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_AUTH_VERIFIER.\n"));
- return False;
- }
+static BOOL cli_send_trans_data(struct cli_state *cli, uint16 fnum,
+ prs_struct * data,
+ int max_data_len, prs_struct * rdata)
+{
+ uint16 cmd = 0x0026;
+ uint16 setup[2]; /* only need 2 uint16 setup parameters */
- if(!smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, &auth_info, 0)) {
- DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_AUTH_NTLMSSP_NEG.\n"));
- return False;
- }
+ char *rparam = NULL;
+ uint32 rparam_len = 0;
- /* Auth len in the rpc header doesn't include auth_header. */
- auth_len = prs_offset(&auth_info) - RPC_HDR_AUTH_LEN;
- }
+ /*
+ * Setup the pointers to the outgoing.
+ */
+ char *rdata_t = NULL;
+ uint32 rdata_len = 0;
+ char *pipe_name = "\\PIPE\\\0\0\0";
+ int pipe_len = 8;
+ int setup_len = 2;
- /* create the request RPC_HDR */
- init_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id,
- RPC_HEADER_LEN + RPC_HDR_RB_LEN + prs_offset(&auth_info),
- auth_len);
+ /*
+ * Setup the pointers from the incoming.
+ */
+ char *pdata = prs_data(data, 0);
+ int data_len = data ? (data->data_size) : 0;
+ data_len = MIN(max_data_len, data_len);
- if(!smb_io_rpc_hdr("hdr" , &hdr, rpc_out, 0)) {
- DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR.\n"));
- return False;
- }
+ /* create setup parameters. */
+ setup[0] = cmd;
+ setup[1] = fnum; /* pipe file handle. got this from an SMBOpenX. */
- /* create the bind request RPC_HDR_RB */
- init_rpc_hdr_rb(&hdr_rb, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, 0x0,
- 0x1, 0x0, 0x1, abstract, transfer);
+ DEBUG(5, ("cli_send_trans_data: data_len: %d cmd:%x fnum:%x\n",
+ data_len, cmd, fnum));
- /* Marshall the bind request data */
- if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_out, 0)) {
- DEBUG(0,("create_rpc_bind_req: failed to marshall RPC_HDR_RB.\n"));
+ /* send the data: receive a response. */
+ if (!cli_api_pipe(cli, pipe_name, pipe_len, setup, setup_len, 0, /* Setup, length, max */
+ NULL, 0, 0, /* Params, length, max */
+ pdata, data_len, max_data_len, /* data, length, max */
+ &rparam, &rparam_len, /* return param, length */
+ &rdata_t, &rdata_len)) /* return data, len */
+ {
+ fstring errstr;
+ cli_safe_errstr(cli, errstr, sizeof(errstr) - 1);
+ DEBUG(0,
+ ("cli_pipe: return critical error. Error was %s\n",
+ errstr));
return False;
}
- /*
- * Grow the outgoing buffer to store any auth info.
- */
+ if (rparam)
+ free(rparam);
- if(hdr.auth_len != 0) {
- if(!prs_append_prs_data( rpc_out, &auth_info)) {
- DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
- return False;
- }
+ if (rdata_len != 0)
+ {
+ BOOL ret = prs_append_data(rdata, rdata_t, rdata_len);
+ safe_free(rdata_t);
+ return ret;
}
return True;
}
-/*******************************************************************
- Creates a DCE/RPC bind authentication response.
- This is the packet that is sent back to the server once we
- have received a BIND-ACK, to finish the third leg of
- the authentication handshake.
- ********************************************************************/
-
-static BOOL create_rpc_bind_resp(struct pwd_info *pwd,
- char *domain, char *user_name, char *my_name,
- uint32 ntlmssp_cli_flgs,
- uint32 rpc_call_id,
- prs_struct *rpc_out)
+/****************************************************************************
+ send data on an rpc pipe, which *must* be in one fragment.
+ receive response data from an rpc pipe, which may be large...
+ ****************************************************************************/
+BOOL cli_send_and_rcv_pdu_trans(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu)
{
- unsigned char lm_owf[24];
- unsigned char nt_owf[24];
- RPC_HDR hdr;
- RPC_HDR_AUTHA hdr_autha;
- RPC_AUTH_VERIFIER auth_verifier;
- RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
- char buffer[4096];
- prs_struct auth_info;
+ int len;
+ uint16 cmd = 0x0026;
+ cli_auth_fns *auth = cli_conn_get_authfns(con);
- /*
- * Marshall the variable length data into a temporary parse
- * struct, pointing into a 4k local buffer.
- */
- prs_init(&auth_info, 0, 4, MARSHALL);
-
- /*
- * Use the 4k buffer to store the auth info.
- */
-
- prs_give_memory( &auth_info, buffer, sizeof(buffer), False);
-
- /*
- * Create the variable length auth_data.
- */
-
- init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH);
+ BOOL first = True;
+ BOOL last = True;
+ RPC_HDR rhdr;
+ size_t data_len = data->data_size;
+ int max_data_len = MAX(data_len, 2048);
+ DEBUG(5, ("cli_send_and_rcv_pdu_trans: cmd:%x fnum:%x\n", cmd, fnum));
- pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf);
-
- init_rpc_auth_ntlmssp_resp(&ntlmssp_resp,
- lm_owf, nt_owf,
- domain, user_name, my_name,
- ntlmssp_cli_flgs);
+ DEBUG(10, ("cli_send_and_rcv_pdu_trans: len: %d\n", data_len));
- /*
- * Marshall the variable length auth_data into a temp parse_struct.
- */
-
- if(!smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_info, 0)) {
- DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_AUTH_VERIFIER.\n"));
+ if (!cli_send_trans_data(cli, fnum, data, max_data_len, rdata))
+ {
return False;
}
- if(!smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, &auth_info, 0)) {
- DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_AUTH_NTLMSSP_RESP.\n"));
+ if (rdata->data == NULL)
return False;
- }
- /* Create the request RPC_HDR */
- init_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id,
- RPC_HEADER_LEN + RPC_HDR_AUTHA_LEN + prs_offset(&auth_info),
- prs_offset(&auth_info) );
+ /**** parse the header: check it's a response record */
+
+ rdata->start = 0;
+ rdata->end = rdata->data_size;
+ rdata->offset = 0;
- /* Marshall it. */
- if(!smb_io_rpc_hdr("hdr", &hdr, rpc_out, 0)) {
- DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR.\n"));
+ if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len))
+ {
return False;
}
- /* Create the request RPC_HDR_AUTHA */
- init_rpc_hdr_autha(&hdr_autha, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN,
- NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, 0x00);
+ prs_set_packtype(rdata, rhdr.pack_type);
- if(!smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rpc_out, 0)) {
- DEBUG(0,("create_rpc_bind_resp: failed to marshall RPC_HDR_AUTHA.\n"));
- return False;
+ if (rhdr.pkt_type == RPC_BINDACK)
+ {
+ if (!last && !first)
+ {
+ DEBUG(5,
+ ("cli_pipe: bug in AS/U, setting fragment first/last ON\n"));
+ first = True;
+ last = True;
+ }
}
- /*
- * Append the auth data to the outgoing buffer.
- */
- if(!prs_append_prs_data(rpc_out, &auth_info)) {
- DEBUG(0,("create_rpc_bind_req: failed to grow parse struct to add auth.\n"));
- return False;
+ DEBUG(5, ("cli_pipe: len left: %d smbtrans read: %d\n",
+ len, rdata->data_size));
+
+ /* check if data to be sent back was too large for one SMB. */
+ /* err status is only informational: the _real_ check is on the length */
+ if (len > 0) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
+ {
+ if (!rpc_read(cli, fnum, rdata, len, rdata->data_size, False))
+ {
+ return False;
+ }
+ if (rhdr.auth_len != 0 &&
+ !auth->cli_decode_pdu(con, rdata, rhdr.frag_len,
+ rhdr.auth_len))
+ {
+ return False;
+ }
+
}
return True;
}
+/****************************************************************************
+ send data on an rpc pipe, which *must* be in one fragment.
+ receive response data from an rpc pipe, which may be large...
+ ****************************************************************************/
-/*******************************************************************
- Creates a DCE/RPC request.
- ********************************************************************/
-
-static BOOL create_rpc_request(prs_struct *rpc_out, uint8 op_num, int data_len, int auth_len)
+BOOL cli_send_and_rcv_pdu_rw(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu)
{
- uint32 alloc_hint;
- RPC_HDR hdr;
- RPC_HDR_REQ hdr_req;
-
- DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n", op_num, data_len));
-
- /* create the rpc header RPC_HDR */
- init_rpc_hdr(&hdr, RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
- get_rpc_call_id(), data_len, auth_len);
-
- /*
- * The alloc hint should be the amount of data, not including
- * RPC headers & footers.
- */
+ int len;
+ int data_offset = 0;
+ uint16 cmd = 0x0026;
+ cli_auth_fns *auth = cli_conn_get_authfns(con);
- if (auth_len != 0)
- alloc_hint = data_len - RPC_HEADER_LEN - RPC_HDR_AUTH_LEN - auth_len;
- else
- alloc_hint = data_len - RPC_HEADER_LEN;
-
- DEBUG(10,("create_rpc_request: data_len: %x auth_len: %x alloc_hint: %x\n",
- data_len, auth_len, alloc_hint));
-
- /* Create the rpc request RPC_HDR_REQ */
- init_rpc_hdr_req(&hdr_req, alloc_hint, op_num);
+ BOOL first = True;
+ BOOL last = True;
+ RPC_HDR rhdr;
+ int max_data_len = 2048;
+ int write_mode = 0x000c;
+ char *d = NULL;
+ size_t data_left = data->data_size;
+ size_t data_len = data->data_size;
+ DEBUG(5, ("cli_send_and_rcv_pdu_rw: cmd:%x fnum:%x\n", cmd, fnum));
+
+ while (data_offset < data_len)
+ {
+ DEBUG(10,
+ ("cli_send_and_rcv_pdu_rw: off: %d len: %d left: %d\n",
+ data_offset, data_len, data_left));
- /* stream-time... */
- if(!smb_io_rpc_hdr("hdr ", &hdr, rpc_out, 0))
- return False;
+ if (d == NULL)
+ {
+ d = (char *)malloc(data_left + 2);
- if(!smb_io_rpc_hdr_req("hdr_req", &hdr_req, rpc_out, 0))
+ if (d == NULL)
+ {
+ return False;
+ }
+ SSVAL(d, 0, data_len);
+ memcpy(d + 2, data->data, data_len);
+ data_len += 2;
+ }
+ max_data_len = MIN(max_data_len, data_len - data_offset);
+ if (cli_write(cli, fnum, write_mode,
+ d, data_offset,
+ max_data_len, data_left) != max_data_len)
+ {
+ return False;
+ }
+ write_mode = 0x0004;
+ d += max_data_len;
+ data_offset += max_data_len;
+ data_left -= max_data_len;
+ }
+ if (!rpc_read(cli, fnum, rdata, max_send_pdu, 0, True))
+ {
return False;
+ }
- if (prs_offset(rpc_out) != RPC_HEADER_LEN + RPC_HDR_REQ_LEN)
+ if (rdata->data == NULL)
return False;
- return True;
-}
+ /**** parse the header: check it's a response record */
+ rdata->start = 0;
+ rdata->end = rdata->data_size;
+ rdata->offset = 0;
-/****************************************************************************
- Send a request on an rpc pipe.
- ****************************************************************************/
-
-BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num,
- prs_struct *data, prs_struct *rdata)
-{
- prs_struct outgoing_packet;
- uint32 data_len;
- uint32 auth_len;
- BOOL ret;
- BOOL auth_verify;
- BOOL auth_seal;
- uint32 crc32 = 0;
- char *pdata_out = NULL;
-
- auth_verify = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SIGN);
- auth_seal = IS_BITS_SET_ALL(cli->ntlmssp_srv_flgs, NTLMSSP_NEGOTIATE_SEAL);
-
- /*
- * The auth_len doesn't include the RPC_HDR_AUTH_LEN.
- */
+ if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len))
+ {
+ return False;
+ }
- auth_len = (auth_verify ? RPC_AUTH_NTLMSSP_CHK_LEN : 0);
+ prs_set_packtype(rdata, rhdr.pack_type);
- /*
- * PDU len is header, plus request header, plus data, plus
- * auth_header_len (if present), plus auth_len (if present).
- * NB. The auth stuff should be aligned on an 8 byte boundary
- * to be totally DCE/RPC spec complient. For now we cheat and
- * hope that the data structs defined are a multiple of 8 bytes.
- */
+ if (rhdr.pkt_type == RPC_BINDACK)
+ {
+ if (!last && !first)
+ {
+ DEBUG(5,
+ ("cli_pipe: bug in AS/U, setting fragment first/last ON\n"));
+ first = True;
+ last = True;
+ }
+ }
- if((prs_offset(data) % 8) != 0) {
- DEBUG(5,("rpc_api_pipe_req: Outgoing data not a multiple of 8 bytes....\n"));
+ if (rhdr.pkt_type == RPC_RESPONSE)
+ {
+ RPC_HDR_RESP rhdr_resp;
+ smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0);
}
- data_len = RPC_HEADER_LEN + RPC_HDR_REQ_LEN + prs_offset(data) +
- (auth_verify ? RPC_HDR_AUTH_LEN : 0) + auth_len;
+ DEBUG(5, ("cli_pipe: len left: %d smbtrans read: %d\n",
+ len, rdata->data_size));
- /*
- * Malloc a parse struct to hold it (and enough for alignments).
- */
+ /* check if data to be sent back was too large for one SMB. */
+ /* err status is only informational: the _real_ check is on the length */
+ if (len > 0)
+ {
+ if (!rpc_read(cli, fnum, rdata, len, rdata->data_size, False))
+ {
+ return False;
+ }
+ }
- if(!prs_init(&outgoing_packet, data_len + 8, 4, MARSHALL)) {
- DEBUG(0,("rpc_api_pipe_req: Failed to malloc %u bytes.\n", (unsigned int)data_len ));
+ if (rhdr.auth_len != 0
+ && !auth->cli_decode_pdu(con, rdata, rhdr.frag_len,
+ rhdr.auth_len))
+ {
return False;
}
- pdata_out = prs_data_p(&outgoing_packet);
-
- /*
- * Write out the RPC header and the request header.
- */
+ return True;
+}
- if(!create_rpc_request(&outgoing_packet, op_num, data_len, auth_len)) {
- DEBUG(0,("rpc_api_pipe_req: Failed to create RPC request.\n"));
- prs_mem_free(&outgoing_packet);
- return False;
+/****************************************************************************
+ send data on an rpc pipe, which *must* be in one fragment.
+ receive response data from an rpc pipe, which may be large...
+ ****************************************************************************/
+BOOL cli_send_and_rcv_pdu(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum,
+ prs_struct * data, prs_struct * rdata,
+ int max_send_pdu)
+{
+ if (True)
+ {
+ return cli_send_and_rcv_pdu_trans(con, cli, fnum, data, rdata,
+ max_send_pdu);
+ }
+ else
+ {
+ return cli_send_and_rcv_pdu_rw(con, cli, fnum, data, rdata,
+ max_send_pdu);
}
+}
- /*
- * Seal the outgoing data if requested.
- */
+BOOL cli_rcv_pdu(struct cli_connection *con,
+ struct cli_state *cli, uint16 fnum, prs_struct *rdata)
+{
+ RPC_HDR_RESP rhdr_resp;
+ RPC_HDR rhdr;
+ char readbuf[0x19];
+ int num_read;
+ BOOL first = True;
+ BOOL last = True;
+ int len;
+ cli_auth_fns *auth = cli_conn_get_authfns(con);
- if (auth_seal) {
- crc32 = crc32_calc_buffer(prs_data_p(data), prs_offset(data));
- NTLMSSPcalc_ap(cli, (unsigned char*)prs_data_p(data), prs_offset(data));
- }
+ /* with a little help by Scummer */
+ num_read = cli_read_one(cli, fnum, readbuf, 0, 0x18);
+ DEBUG(5, ("cli_pipe: read header (size:%d)\n", num_read));
+ prs_append_data(rdata, readbuf, num_read);
- /*
- * Now copy the data into the outgoing packet.
- */
+ if (num_read != 0x18)
+ return False;
- if(!prs_append_prs_data( &outgoing_packet, data)) {
- DEBUG(0,("rpc_api_pipe_req: Failed to append data to outgoing packet.\n"));
- prs_mem_free(&outgoing_packet);
+ if (!rpc_check_hdr(rdata, &rhdr, &first, &last, &len))
+ {
return False;
}
- /*
- * Add a trailing auth_verifier if needed.
- */
+ prs_set_packtype(rdata, rhdr.pack_type);
- if (auth_seal || auth_verify) {
- RPC_HDR_AUTH hdr_auth;
+ smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0);
- init_rpc_hdr_auth(&hdr_auth, NTLMSSP_AUTH_TYPE,
- NTLMSSP_AUTH_LEVEL, 0x08, (auth_verify ? 1 : 0));
- if(!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &outgoing_packet, 0)) {
- DEBUG(0,("rpc_api_pipe_req: Failed to marshal RPC_HDR_AUTH.\n"));
- prs_mem_free(&outgoing_packet);
- return False;
- }
+ if (!rpc_read(cli, fnum, rdata, len, rdata->data_size, False))
+ {
+ return False;
}
- /*
- * Finally the auth data itself.
- */
-
- if (auth_verify) {
- RPC_AUTH_NTLMSSP_CHK chk;
- uint32 current_offset = prs_offset(&outgoing_packet);
-
- init_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, cli->ntlmssp_seq_num++);
- if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &outgoing_packet, 0)) {
- DEBUG(0,("rpc_api_pipe_req: Failed to marshal RPC_AUTH_NTLMSSP_CHK.\n"));
- prs_mem_free(&outgoing_packet);
- return False;
- }
- NTLMSSPcalc_ap(cli, (unsigned char*)&pdata_out[current_offset+4], RPC_AUTH_NTLMSSP_CHK_LEN - 4);
+ if (rhdr.auth_len != 0 &&
+ !auth->cli_decode_pdu(con, rdata, rhdr.frag_len, rhdr.auth_len))
+ {
+ return False;
}
- DEBUG(100,("data_len: %x data_calc_len: %x\n", data_len, prs_offset(&outgoing_packet)));
-
- ret = rpc_api_pipe(cli, 0x0026, &outgoing_packet, rdata);
-
- prs_mem_free(&outgoing_packet);
-
- return ret;
+ return True;
}
+
/****************************************************************************
- Set the handle state.
+do an rpc bind
****************************************************************************/
-static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint16 device_state)
+static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, uint16 fnum,
+ const char *pipe_name, uint16 device_state)
{
BOOL state_set = False;
char param[2];
- uint16 setup[2]; /* only need 2 uint16 setup parameters */
+ uint16 setup[2]; /* only need 2 uint16 setup parameters */
char *rparam = NULL;
char *rdata = NULL;
uint32 rparam_len, rdata_len;
@@ -878,23 +792,22 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1
if (pipe_name == NULL)
return False;
- DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n",
- cli->nt_pipe_fnum, pipe_name, device_state));
+ DEBUG(5, ("Set Handle state Pipe[%x]: %s - device state:%x\n",
+ fnum, pipe_name, device_state));
/* create parameters: device state */
SSVAL(param, 0, device_state);
/* create setup parameters. */
- setup[0] = 0x0001;
- setup[1] = cli->nt_pipe_fnum; /* pipe file handle. got this from an SMBOpenX. */
+ setup[0] = 0x0001;
+ setup[1] = fnum; /* pipe file handle. got this from an SMBOpenX. */
/* send the data on \PIPE\ */
- if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8,
- setup, 2, 0, /* setup, length, max */
- param, 2, 0, /* param, length, max */
- NULL, 0, 1024, /* data, length, max */
- &rparam, &rparam_len, /* return param, length */
- &rdata, &rdata_len)) /* return data, length */
+ if (cli_api_pipe(cli, "\\PIPE\\\0\0\0", 8, setup, 2, 0, /* setup, length, max */
+ param, 2, 0, /* param, length, max */
+ NULL, 0, 1024, /* data, length, max */
+ &rparam, &rparam_len, /* return param, length */
+ &rdata, &rdata_len)) /* return data, length */
{
DEBUG(5, ("Set Handle state: return OK\n"));
state_set = True;
@@ -903,7 +816,7 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1
if (rparam)
free(rparam);
if (rdata)
- free(rdata );
+ free(rdata);
return state_set;
}
@@ -912,29 +825,38 @@ static BOOL rpc_pipe_set_hnd_state(struct cli_state *cli, char *pipe_name, uint1
check the rpc bind acknowledge response
****************************************************************************/
-static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *transfer)
+static BOOL valid_pipe_name(const char *pipe_name,
+ RPC_IFACE * abstract, RPC_IFACE * transfer)
{
int pipe_idx = 0;
- while (pipe_names[pipe_idx].client_pipe != NULL) {
- if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe )) {
- DEBUG(5,("Bind Abstract Syntax: "));
- dump_data(5, (char*)&(pipe_names[pipe_idx].abstr_syntax),
- sizeof(pipe_names[pipe_idx].abstr_syntax));
- DEBUG(5,("Bind Transfer Syntax: "));
- dump_data(5, (char*)&(pipe_names[pipe_idx].trans_syntax),
- sizeof(pipe_names[pipe_idx].trans_syntax));
+ while (pipe_names[pipe_idx].client_pipe != NULL)
+ {
+ if (strequal(pipe_name, pipe_names[pipe_idx].client_pipe))
+ {
+ DEBUG(5, ("Bind Abstract Syntax:\n"));
+ dump_data(5,
+ (char *)
+ &(pipe_names[pipe_idx].abstr_syntax),
+ sizeof(pipe_names[pipe_idx].abstr_syntax));
+ DEBUG(5, ("Bind Transfer Syntax:\n"));
+ dump_data(5,
+ (char *)
+ &(pipe_names[pipe_idx].trans_syntax),
+ sizeof(pipe_names[pipe_idx].trans_syntax));
/* copy the required syntaxes out so we can do the right bind */
- *transfer = pipe_names[pipe_idx].trans_syntax;
- *abstract = pipe_names[pipe_idx].abstr_syntax;
+ memcpy(transfer, &(pipe_names[pipe_idx].trans_syntax),
+ sizeof(pipe_names[pipe_idx].trans_syntax));
+ memcpy(abstract, &(pipe_names[pipe_idx].abstr_syntax),
+ sizeof(pipe_names[pipe_idx].abstr_syntax));
return True;
}
pipe_idx++;
};
- DEBUG(5,("Bind RPC Pipe[%s] unsupported\n", pipe_name));
+ DEBUG(5, ("Bind RPC Pipe[%s] unsupported\n", pipe_name));
return False;
}
@@ -942,283 +864,227 @@ static BOOL valid_pipe_name(char *pipe_name, RPC_IFACE *abstract, RPC_IFACE *tra
check the rpc bind acknowledge response
****************************************************************************/
-static BOOL check_bind_response(RPC_HDR_BA *hdr_ba, char *pipe_name, RPC_IFACE *transfer)
+static BOOL check_bind_response(RPC_HDR_BA * hdr_ba, const char *pipe_name,
+ RPC_IFACE * transfer)
{
int i = 0;
- while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0) {
- DEBUG(6,("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
- pipe_names[i].client_pipe , pipe_names[i].server_pipe ));
-
- if ((strequal(pipe_name, pipe_names[i].client_pipe ))) {
- if (strequal(hdr_ba->addr.str, pipe_names[i].server_pipe )) {
- DEBUG(5,("bind_rpc_pipe: server pipe_name found: %s\n",
- pipe_names[i].server_pipe ));
+ while ((pipe_names[i].client_pipe != NULL) && hdr_ba->addr.len > 0)
+ {
+ DEBUG(6,
+ ("bind_rpc_pipe: searching pipe name: client:%s server:%s\n",
+ pipe_names[i].client_pipe, pipe_names[i].server_pipe));
+
+ if ((strequal(pipe_name, pipe_names[i].client_pipe)))
+ {
+ if (strequal
+ (hdr_ba->addr.str, pipe_names[i].server_pipe))
+ {
+ DEBUG(5,
+ ("bind_rpc_pipe: server pipe_name found: %s\n",
+ pipe_names[i].server_pipe));
break;
- } else {
- DEBUG(4,("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n",
- pipe_names[i].server_pipe ,
- hdr_ba->addr.str));
+ }
+ else
+ {
+ DEBUG(4,
+ ("bind_rpc_pipe: pipe_name %s != expected pipe %s. oh well!\n",
+ pipe_names[i].server_pipe,
+ hdr_ba->addr.str));
break;
}
- } else {
+ }
+ else
+ {
i++;
}
}
- if (pipe_names[i].server_pipe == NULL) {
- DEBUG(2,("bind_rpc_pipe: pipe name %s unsupported\n", hdr_ba->addr.str));
+ if (pipe_names[i].server_pipe == NULL)
+ {
+ DEBUG(2,
+ ("bind_rpc_pipe: pipe name %s unsupported\n",
+ hdr_ba->addr.str));
return False;
}
/* check the transfer syntax */
- if ((hdr_ba->transfer.version != transfer->version) ||
- (memcmp(&hdr_ba->transfer.uuid, &transfer->uuid, sizeof(transfer->uuid)) !=0)) {
- DEBUG(0,("bind_rpc_pipe: transfer syntax differs\n"));
+ if (!((hdr_ba->transfer.version == transfer->version) &&
+ (memcmp(hdr_ba->transfer.data, transfer->data,
+ sizeof(transfer->version)) == 0)))
+ {
+ DEBUG(0, ("bind_rpc_pipe: transfer syntax differs\n"));
return False;
}
/* lkclXXXX only accept one result: check the result(s) */
- if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0) {
- DEBUG(2,("bind_rpc_pipe: bind denied results: %d reason: %x\n",
- hdr_ba->res.num_results, hdr_ba->res.reason));
+ if (hdr_ba->res.num_results != 0x1 || hdr_ba->res.result != 0)
+ {
+ DEBUG(2,
+ ("bind_rpc_pipe: bind denied results: %d reason: %x\n",
+ hdr_ba->res.num_results, hdr_ba->res.reason));
}
- DEBUG(5,("bind_rpc_pipe: accepted!\n"));
+ DEBUG(5, ("bind_rpc_pipe: accepted!\n"));
return True;
}
/****************************************************************************
- Create and send the third packet in an RPC auth.
+do an rpc bind
****************************************************************************/
-static BOOL rpc_send_auth_reply(struct cli_state *cli, prs_struct *rdata, uint32 rpc_call_id)
+BOOL rpc_pipe_bind(struct cli_connection *con,
+ const char *pipe_name,
+ RPC_IFACE * abstract, RPC_IFACE * transfer)
{
- RPC_HDR_AUTH rhdr_auth;
- RPC_AUTH_VERIFIER rhdr_verf;
- RPC_AUTH_NTLMSSP_CHAL rhdr_chal;
- char buffer[MAX_PDU_FRAG_LEN];
- prs_struct rpc_out;
- ssize_t ret;
-
- unsigned char p24[24];
- unsigned char lm_owf[24];
- unsigned char lm_hash[16];
-
- if(!smb_io_rpc_hdr_auth("", &rhdr_auth, rdata, 0)) {
- DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_HDR_AUTH.\n"));
- return False;
- }
- if(!smb_io_rpc_auth_verifier("", &rhdr_verf, rdata, 0)) {
- DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_AUTH_VERIFIER.\n"));
- return False;
- }
- if(!smb_io_rpc_auth_ntlmssp_chal("", &rhdr_chal, rdata, 0)) {
- DEBUG(0,("rpc_send_auth_reply: Failed to unmarshall RPC_AUTH_NTLMSSP_CHAL.\n"));
- return False;
- }
-
- cli->ntlmssp_cli_flgs = rhdr_chal.neg_flags;
-
- pwd_make_lm_nt_owf(&cli->pwd, rhdr_chal.challenge);
-
- prs_init(&rpc_out, 0, 4, MARSHALL);
-
- prs_give_memory( &rpc_out, buffer, sizeof(buffer), False);
-
- create_rpc_bind_resp(&cli->pwd, cli->domain,
- cli->user_name, global_myname,
- cli->ntlmssp_cli_flgs, rpc_call_id,
- &rpc_out);
-
- pwd_get_lm_nt_owf(&cli->pwd, lm_owf, NULL);
- pwd_get_lm_nt_16(&cli->pwd, lm_hash, NULL);
+ prs_struct data;
+ prs_struct rdata;
- NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
+ BOOL valid_ack = False;
+ uint32 rpc_call_id;
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+ cli_auth_fns *auth = cli_conn_get_authfns(con);
+ if (con == NULL || auth == NULL)
{
- unsigned char j = 0;
- int ind;
- unsigned char k2[8];
-
- memcpy(k2, p24, 5);
- k2[5] = 0xe5;
- k2[6] = 0x38;
- k2[7] = 0xb0;
-
- for (ind = 0; ind < 256; ind++)
- cli->ntlmssp_hash[ind] = (unsigned char)ind;
-
- for( ind = 0; ind < 256; ind++) {
- unsigned char tc;
-
- j += (cli->ntlmssp_hash[ind] + k2[ind%8]);
-
- tc = cli->ntlmssp_hash[ind];
- cli->ntlmssp_hash[ind] = cli->ntlmssp_hash[j];
- cli->ntlmssp_hash[j] = tc;
- }
-
- cli->ntlmssp_hash[256] = 0;
- cli->ntlmssp_hash[257] = 0;
+ DEBUG(0, ("rpc_pipe_bind: invalid connection\n"));
+ return False;
}
- memset((char *)lm_hash, '\0', sizeof(lm_hash));
-
- if ((ret = cli_write(cli, cli->nt_pipe_fnum, 0x8, prs_data_p(&rpc_out),
- 0, (size_t)prs_offset(&rpc_out))) != (ssize_t)prs_offset(&rpc_out)) {
- DEBUG(0,("rpc_send_auth_reply: cli_write failed. Return was %d\n", (int)ret));
+ if (pipe_name == NULL || abstract == NULL || transfer == NULL)
+ {
return False;
}
- cli->ntlmssp_srv_flgs = rhdr_chal.neg_flags;
- return True;
-}
-
-/****************************************************************************
- Do an rpc bind.
-****************************************************************************/
+ DEBUG(5, ("Bind RPC Pipe: %s\n", pipe_name));
-static BOOL rpc_pipe_bind(struct cli_state *cli, char *pipe_name, char *my_name)
-{
- RPC_IFACE abstract;
- RPC_IFACE transfer;
- prs_struct rpc_out;
- prs_struct rdata;
- BOOL do_auth = (cli->ntlmssp_cli_flgs != 0);
- uint32 rpc_call_id;
- char buffer[MAX_PDU_FRAG_LEN];
-
- DEBUG(5,("Bind RPC Pipe[%x]: %s\n", cli->nt_pipe_fnum, pipe_name));
-
- if (!valid_pipe_name(pipe_name, &abstract, &transfer))
+ if (!valid_pipe_name(pipe_name, abstract, transfer))
return False;
- prs_init(&rpc_out, 0, 4, MARSHALL);
-
- /*
- * Use the MAX_PDU_FRAG_LEN buffer to store the bind request.
- */
-
- prs_give_memory( &rpc_out, buffer, sizeof(buffer), False);
+ prs_init(&rdata, 0, 4, True);
rpc_call_id = get_rpc_call_id();
- /* Marshall the outgoing data. */
- create_rpc_bind_req(&rpc_out, do_auth, rpc_call_id,
- &abstract, &transfer,
- global_myname, cli->domain, cli->ntlmssp_cli_flgs);
+ if (!auth->create_bind_req(con, &data,
+ rpc_call_id, abstract, transfer))
+ {
+ return False;
+ }
- /* Initialize the incoming data struct. */
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ nt->max_recv_frag = 0x1000;
+ nt->max_xmit_frag = 0x1000;
/* send data on \PIPE\. receive a response */
- if (rpc_api_pipe(cli, 0x0026, &rpc_out, &rdata)) {
- RPC_HDR_BA hdr_ba;
+ if (rpc_api_pipe_bind(con, &data, &rdata))
+ {
+ RPC_HDR_BA hdr_ba;
- DEBUG(5, ("rpc_pipe_bind: rpc_api_pipe returned OK.\n"));
+ DEBUG(5, ("rpc_api_pipe: return OK\n"));
- if(!smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0)) {
- DEBUG(0,("rpc_pipe_bind: Failed to unmarshall RPC_HDR_BA.\n"));
- prs_mem_free(&rdata);
- return False;
- }
+ smb_io_rpc_hdr_ba("", &hdr_ba, &rdata, 0);
- if(!check_bind_response(&hdr_ba, pipe_name, &transfer)) {
- DEBUG(0,("rpc_pipe_bind: check_bind_response failed.\n"));
- prs_mem_free(&rdata);
- return False;
+ if (rdata.offset != 0)
+ {
+ valid_ack =
+ check_bind_response(&hdr_ba, pipe_name,
+ transfer);
}
- cli->max_xmit_frag = hdr_ba.bba.max_tsize;
- cli->max_recv_frag = hdr_ba.bba.max_rsize;
-
- /*
- * If we're doing NTLMSSP auth we need to send a reply to
- * the bind-ack to complete the 3-way challenge response
- * handshake.
- */
+ if (valid_ack)
+ {
+ nt->max_xmit_frag = hdr_ba.bba.max_tsize;
+ nt->max_recv_frag = hdr_ba.bba.max_rsize;
+ }
- if (do_auth && !rpc_send_auth_reply(cli, &rdata, rpc_call_id)) {
- DEBUG(0,("rpc_pipe_bind: rpc_send_auth_reply failed.\n"));
- prs_mem_free(&rdata);
- return False;
+ if (valid_ack && auth->decode_bind_resp != NULL)
+ {
+ valid_ack = auth->decode_bind_resp(con, &rdata);
+ if (valid_ack && auth->create_bind_cont != NULL)
+ {
+ prs_struct dataa;
+ prs_init(&dataa, 0, 4, False);
+
+ valid_ack = auth->create_bind_cont(con,
+ &dataa,
+ rpc_call_id);
+ if (valid_ack)
+ {
+ valid_ack =
+ rpc_api_write(con, &dataa);
+ }
+ prs_free_data(&dataa);
+ }
}
}
- prs_mem_free(&rdata);
- return True;
+ prs_free_data(&data);
+ prs_free_data(&rdata);
+
+ return valid_ack;
}
/****************************************************************************
- Set ntlmssp negotiation flags.
+ set ntlmssp negotiation flags
****************************************************************************/
void cli_nt_set_ntlmssp_flgs(struct cli_state *cli, uint32 ntlmssp_flgs)
{
- cli->ntlmssp_cli_flgs = ntlmssp_flgs;
+ cli->nt.ntlmssp_cli_flgs = ntlmssp_flgs;
}
/****************************************************************************
- Open a session.
+ open a session
****************************************************************************/
-BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name)
+BOOL cli_nt_session_open(struct cli_state *cli, const char *pipe_name,
+ uint16 * fnum)
{
- int fnum;
-
- if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS)) {
- if ((fnum = cli_nt_create(cli, &(pipe_name[5]))) == -1) {
- DEBUG(0,("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n",
- &(pipe_name[5]), cli->desthost, cli_errstr(cli)));
+ /******************* open the pipe *****************/
+ if (IS_BITS_SET_ALL(cli->capabilities, CAP_NT_SMBS))
+ {
+ int f;
+ f = cli_nt_create(cli, &(pipe_name[5]));
+ if (f == -1)
+ {
+ fstring errstr;
+ cli_safe_errstr(cli, errstr, sizeof(errstr) - 1);
+ DEBUG(0,
+ ("cli_nt_session_open: cli_nt_create failed on pipe %s to machine %s. Error was %s\n",
+ &(pipe_name[5]), cli->desthost, errstr));
return False;
}
-
- cli->nt_pipe_fnum = (uint16)fnum;
- } else {
- if ((fnum = cli_open(cli, pipe_name, O_CREAT|O_RDWR, DENY_NONE)) == -1) {
- DEBUG(0,("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n",
- pipe_name, cli->desthost, cli_errstr(cli)));
+ *fnum = (uint16) f;
+ }
+ else
+ {
+ int f;
+ f = cli_open(cli, pipe_name, O_CREAT | O_RDWR, DENY_NONE);
+ if (f == -1)
+ {
+ fstring errstr;
+ cli_safe_errstr(cli, errstr, sizeof(errstr) - 1);
+ DEBUG(0,
+ ("cli_nt_session_open: cli_open failed on pipe %s to machine %s. Error was %s\n",
+ pipe_name, cli->desthost, errstr));
return False;
}
-
- cli->nt_pipe_fnum = (uint16)fnum;
+ *fnum = (uint16) f;
/**************** Set Named Pipe State ***************/
- if (!rpc_pipe_set_hnd_state(cli, pipe_name, 0x4300)) {
- DEBUG(0,("cli_nt_session_open: pipe hnd state failed. Error was %s\n",
- cli_errstr(cli)));
- cli_close(cli, cli->nt_pipe_fnum);
+ if (!rpc_pipe_set_hnd_state(cli, *fnum, pipe_name, 0x4300))
+ {
+ fstring errstr;
+ cli_safe_errstr(cli, errstr, sizeof(errstr) - 1);
+ DEBUG(0,
+ ("cli_nt_session_open: pipe hnd state failed. Error was %s\n",
+ errstr));
+ cli_close(cli, *fnum);
return False;
}
- }
- /******************* bind request on pipe *****************/
-
- if (!rpc_pipe_bind(cli, pipe_name, global_myname)) {
- DEBUG(0,("cli_nt_session_open: rpc bind failed. Error was %s\n",
- cli_errstr(cli)));
- cli_close(cli, cli->nt_pipe_fnum);
- return False;
}
- /*
- * Setup the remote server name prefixed by \ and the machine account name.
- */
-
- fstrcpy(cli->srv_name_slash, "\\\\");
- fstrcat(cli->srv_name_slash, cli->desthost);
- strupper(cli->srv_name_slash);
-
- fstrcpy(cli->clnt_name_slash, "\\\\");
- fstrcat(cli->clnt_name_slash, global_myname);
- strupper(cli->clnt_name_slash);
-
- fstrcpy(cli->mach_acct, global_myname);
- fstrcat(cli->mach_acct, "$");
- strupper(cli->mach_acct);
-
return True;
}
@@ -1226,7 +1092,10 @@ BOOL cli_nt_session_open(struct cli_state *cli, char *pipe_name)
close the session
****************************************************************************/
-void cli_nt_session_close(struct cli_state *cli)
+void cli_nt_session_close(struct cli_state *cli, uint16 fnum)
{
- cli_close(cli, cli->nt_pipe_fnum);
+ if (fnum != 0xffff)
+ {
+ cli_close(cli, fnum);
+ }
}
diff --git a/source/rpc_client/cli_pipe_netsec.c b/source/rpc_client/cli_pipe_netsec.c
new file mode 100644
index 00000000000..755c07b3e72
--- /dev/null
+++ b/source/rpc_client/cli_pipe_netsec.c
@@ -0,0 +1,338 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+ decrypt data on an rpc pipe
+ ****************************************************************************/
+static BOOL decode_netsec_pdu(struct cli_connection *con,
+ prs_struct *rdata,
+ int len, int auth_len)
+{
+ RPC_AUTH_NETSEC_CHK chk;
+ RPC_HDR_AUTH auth_info;
+ int data_len = len - 0x18 - auth_len - 8;
+ char *reply_data = prs_data(rdata, 0x18);
+ uint32 old_offset;
+
+ netsec_auth_struct *a;
+ a = (netsec_auth_struct *)cli_conn_get_auth_info(con);
+
+ if (a == NULL)
+ {
+ return False;
+ }
+
+ DEBUG(5,("decode_netsec_pdu: len: %d auth_len: %d\n",
+ len, auth_len));
+
+ if (reply_data == NULL) return False;
+
+ if (auth_len != 0x20 )
+ {
+ return False;
+ }
+
+ /*** skip the data, record the offset so we can restore it again */
+ old_offset = rdata->offset;
+
+ rdata->offset = data_len + 0x18;
+ smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rdata, 0);
+ if (!rpc_hdr_netsec_auth_chk(&(auth_info)))
+ {
+ return False;
+ }
+
+ smb_io_rpc_auth_netsec_chk("auth_sign", &chk, rdata, 0);
+
+ if (!netsec_decode(a, &chk, reply_data, data_len))
+ {
+ return False;
+ }
+
+ a->seq_num++;
+
+ /* restore the [data, now decoded] offset */
+ rdata->offset = old_offset;
+
+ return True;
+}
+
+/****************************************************************************
+ send a request on an rpc pipe.
+ ****************************************************************************/
+static BOOL create_netsec_pdu(struct cli_connection *con,
+ uint8 op_num,
+ prs_struct *data, int data_start, int *data_end,
+ prs_struct *dataa,
+ uint8 *flags)
+{
+ prs_struct data_t;
+ prs_struct hdr;
+ prs_struct hdr_auth;
+ prs_struct auth_verf;
+ int data_len;
+ int frag_len;
+ int auth_len;
+ char *d = prs_data(data, data_start);
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+ netsec_auth_struct *a = NULL;
+ BOOL ret;
+ RPC_HDR_AUTH auth_info;
+ RPC_AUTH_NETSEC_CHK verf;
+ uchar sign[8];
+ static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
+
+ a = (netsec_auth_struct *)cli_conn_get_auth_info(con);
+ if (a == NULL)
+ {
+ return False;
+ }
+
+ *flags = 0;
+
+ auth_len = 0x20;
+ data_len = data->offset - data_start;
+
+ if (data_start == 0)
+ {
+ (*flags) |= RPC_FLG_FIRST;
+ }
+
+ if (data_len > nt->max_recv_frag)
+ {
+ data_len = nt->max_recv_frag - auth_len - 8 - 0x18;
+ }
+ else
+ {
+ (*flags) |= RPC_FLG_LAST;
+ }
+
+ (*data_end) += data_len;
+
+ /* happen to know that NETSEC authentication verifier is 16 bytes */
+ frag_len = data_len + auth_len + 8 + 0x18;
+
+ prs_init(&data_t , 0 , 4, False);
+ prs_init(&hdr , frag_len, 4, False);
+ prs_init(&hdr_auth , 0 , 4, False);
+ prs_init(&auth_verf, auth_len, 4, False);
+
+ prs_append_data(&data_t, d, data_len);
+ data_t.end = data_t.data_size;
+ data_t.offset = data_t.data_size;
+
+ create_rpc_request(&hdr, nt->key.vuid, op_num, (*flags),
+ frag_len, auth_len);
+
+ DEBUG(5,("create_netsec_reply: data %d auth %d\n",
+ data_len, auth_len));
+
+ make_rpc_hdr_auth(&auth_info, 0x44, 0x06, 0x0, 1);
+ smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &hdr_auth, 0);
+
+ memset(sign, 0, sizeof(sign));
+ sign[4] = 0x80;
+
+ make_rpc_auth_netsec_chk(&verf, netsec_sig, NULL, sign, NULL);
+
+ ret = netsec_encode(a, &verf, prs_data(&data_t, 0),
+ prs_buf_len(&data_t));
+
+ if (ret)
+ {
+ smb_io_rpc_auth_netsec_chk("auth_sign", &verf, &auth_verf, 0);
+ }
+
+ if (ret)
+ {
+ prs_link(NULL , &hdr , &data_t );
+ prs_link(&hdr , &data_t , &hdr_auth );
+ prs_link(&data_t , &hdr_auth , &auth_verf);
+ prs_link(&hdr_auth, &auth_verf, NULL );
+
+ prs_init(dataa, 0, 4, False);
+ ret = prs_copy(dataa, &hdr);
+ }
+
+ prs_free_data(&hdr_auth );
+ prs_free_data(&data_t );
+ prs_free_data(&auth_verf);
+ prs_free_data(&hdr );
+
+ return True;
+}
+
+/*******************************************************************
+ creates a DCE/RPC bind request
+
+ - initialises the parse structure.
+ - dynamically allocates the header data structure
+ - caller is expected to free the header data structure once used.
+
+ ********************************************************************/
+static BOOL create_netsec_bind_req(struct cli_connection *con,
+ prs_struct *data,
+ uint32 rpc_call_id,
+ RPC_IFACE *abstract, RPC_IFACE *transfer)
+{
+ prs_struct rhdr;
+ prs_struct rhdr_rb;
+ prs_struct rhdr_auth;
+ prs_struct auth_req;
+
+ RPC_HDR_RB hdr_rb;
+ RPC_HDR hdr;
+ RPC_HDR_AUTH hdr_auth;
+ RPC_AUTH_VERIFIER auth_verifier;
+ RPC_AUTH_NETSEC_NEG netsec_neg;
+
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+ netsec_auth_struct *a;
+ struct netsec_creds *usr;
+ usr = (struct netsec_creds*)cli_conn_get_auth_creds(con);
+
+ prs_init(&rhdr , 0x0, 4, False);
+ prs_init(&rhdr_rb , 0x0, 4, False);
+ prs_init(&rhdr_auth, 0x0, 4, False);
+ prs_init(&auth_req , 0x0, 4, False);
+
+ /* create the bind request RPC_HDR_RB */
+ make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, nt->key.pid,
+ 0x1, nt->key.vuid, 0x1, abstract, transfer);
+
+ /* stream the bind request data */
+ smb_io_rpc_hdr_rb("", &hdr_rb, &rhdr_rb, 0);
+
+ make_rpc_hdr_auth(&hdr_auth, 0x44, 0x06, 0x00, 1);
+ smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &rhdr_auth, 0);
+
+ make_rpc_auth_verifier(&auth_verifier, "", 0x3);
+
+ smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_req, 0);
+
+ make_rpc_auth_netsec_neg(&netsec_neg, usr->domain, usr->myname);
+
+ smb_io_rpc_auth_netsec_neg("netsec_neg", &netsec_neg, &auth_req, 0);
+
+ /* create the request RPC_HDR */
+ make_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id,
+ auth_req .offset + rhdr_auth.offset +
+ rhdr_rb.offset + 0x10,
+ auth_req .offset);
+
+ smb_io_rpc_hdr("hdr" , &hdr , &rhdr, 0);
+
+ if (rhdr.data == NULL || rhdr_rb.data == NULL) return False;
+
+ /***/
+ /*** link rpc header, bind ack and auth responses ***/
+ /***/
+
+ prs_link(NULL , &rhdr , &rhdr_rb );
+ prs_link(&rhdr , &rhdr_rb , &rhdr_auth);
+ prs_link(&rhdr_rb , &rhdr_auth , &auth_req );
+ prs_link(&rhdr_auth, &auth_req , NULL );
+
+ prs_init(data, prs_buf_len(&rhdr), 4, False);
+ prs_buf_copy(data->data, &rhdr, 0, prs_buf_len(&rhdr));
+
+ prs_free_data(&rhdr );
+ prs_free_data(&rhdr_rb );
+ prs_free_data(&rhdr_auth);
+ prs_free_data(&auth_req );
+
+ a = malloc(sizeof(struct netsec_auth_struct));
+ if (a == NULL)
+ {
+ return False;
+ }
+
+ memcpy(a->sess_key, usr->sess_key, sizeof(a->sess_key));
+
+ if (!cli_conn_set_auth_info(con, (void*)a))
+ {
+ free(a);
+ return False;
+ }
+ return True;
+}
+
+static BOOL decode_netsec_bind_resp(struct cli_connection *con,
+ prs_struct *rdata)
+{
+ BOOL valid_ack = True;
+ netsec_auth_struct *a;
+ a = (netsec_auth_struct *)cli_conn_get_auth_info(con);
+
+ if (a == NULL)
+ {
+ return False;
+ }
+
+ if (valid_ack)
+ {
+ RPC_HDR_AUTH rhdr_auth;
+ smb_io_rpc_hdr_auth("", &rhdr_auth, rdata, 0);
+ if (rdata->offset == 0 ||
+ !rpc_hdr_netsec_auth_chk(&rhdr_auth))
+ {
+ valid_ack = False;
+ }
+ }
+ if (valid_ack)
+ {
+ RPC_AUTH_VERIFIER rhdr_verf;
+ smb_io_rpc_auth_verifier("", &rhdr_verf, rdata, 0);
+ if (rdata->offset == 0 ||
+ !rpc_auth_verifier_chk(&rhdr_verf, "\001", 0))
+ {
+ valid_ack = False;
+ }
+ }
+ if (valid_ack)
+ {
+ RPC_AUTH_NETSEC_RESP rresp;
+ smb_io_rpc_auth_netsec_resp("", &rresp, rdata, 0);
+ if (rdata->offset == 0) valid_ack = False;
+ }
+ return valid_ack;
+}
+
+cli_auth_fns cli_netsec_fns =
+{
+ create_netsec_bind_req,
+ decode_netsec_bind_resp,
+ NULL,
+ create_netsec_pdu,
+ decode_netsec_pdu
+};
diff --git a/source/rpc_client/cli_pipe_noauth.c b/source/rpc_client/cli_pipe_noauth.c
new file mode 100644
index 00000000000..c403e8bf101
--- /dev/null
+++ b/source/rpc_client/cli_pipe_noauth.c
@@ -0,0 +1,180 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+extern struct pipe_id_info pipe_names[];
+extern pstring global_myname;
+
+/****************************************************************************
+ send a request on an rpc pipe.
+ ****************************************************************************/
+static BOOL create_noauth_pdu(struct cli_connection *con,
+ uint8 op_num,
+ prs_struct *data, int data_start, int *data_end,
+ prs_struct *dataa,
+ uint8 *flags)
+{
+ /* fudge this, at the moment: create the header; memcpy the data. oops. */
+ prs_struct data_t;
+ prs_struct hdr;
+ int data_len;
+ int frag_len;
+ char *d = prs_data(data, data_start);
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+
+ *flags = 0;
+
+ data_len = data->offset - data_start;
+
+ if (data_start == 0)
+ {
+ (*flags) |= RPC_FLG_FIRST;
+ }
+
+ if (data_len > nt->max_recv_frag)
+ {
+ data_len = nt->max_recv_frag + 0x18;
+ }
+ else
+ {
+ (*flags) |= RPC_FLG_LAST;
+ }
+
+ (*data_end) += data_len;
+
+ /* happen to know that NTLMSSP authentication verifier is 16 bytes */
+ frag_len = data_len + 0x18;
+
+ prs_init(&data_t , 0 , 4, False);
+ prs_init(&hdr , frag_len, 4, False);
+
+ prs_append_data(&data_t, d, data_len);
+ data_t.end = data_t.data_size;
+ data_t.offset = data_t.data_size;
+
+ create_rpc_request(&hdr, nt->key.vuid, op_num, (*flags), frag_len, 0);
+
+ prs_link(NULL, &hdr , &data_t);
+ prs_link(&hdr, &data_t, NULL );
+
+ DEBUG(100,("frag_len: 0x%x data_len: 0x%x data_calc_len: 0x%x\n",
+ frag_len, data_len, prs_buf_len(&data_t)));
+
+ if (frag_len != prs_buf_len(&hdr))
+ {
+ DEBUG(0,("expected fragment length does not match\n"));
+
+ prs_free_data(&hdr );
+ prs_free_data(&data_t );
+
+ return False;
+ }
+
+ DEBUG(100,("create_noauth_pdu: %d\n", __LINE__));
+
+ /* this is all a hack */
+ prs_init(dataa, prs_buf_len(&hdr), 4, False);
+ prs_debug_out(dataa, "create_noauth_pdu", 200);
+ prs_buf_copy(dataa->data, &hdr, 0, frag_len);
+
+ DEBUG(100,("create_noauth_pdu: %d\n", __LINE__));
+
+ prs_free_data(&hdr );
+ prs_free_data(&data_t );
+
+ return True;
+}
+
+/*******************************************************************
+ creates a DCE/RPC bind request
+
+ - initialises the parse structure.
+ - dynamically allocates the header data structure
+ - caller is expected to free the header data structure once used.
+
+ ********************************************************************/
+static BOOL create_rpc_noauth_bind_req(struct cli_connection *con,
+ prs_struct *data,
+ uint32 rpc_call_id,
+ RPC_IFACE *abstract, RPC_IFACE *transfer)
+{
+ prs_struct rhdr;
+ prs_struct rhdr_rb;
+
+ RPC_HDR_RB hdr_rb;
+ RPC_HDR hdr;
+
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+
+ DEBUG(10,("create_rpc_noauth_bind_req\n"));
+
+ prs_init(&rhdr , 0x0, 4, False);
+ prs_init(&rhdr_rb , 0x0, 4, False);
+
+ /* create the bind request RPC_HDR_RB */
+ make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, nt->key.pid,
+ 0x1, nt->key.vuid, 0x1, abstract, transfer);
+
+ /* stream the bind request data */
+ smb_io_rpc_hdr_rb("", &hdr_rb, &rhdr_rb, 0);
+
+ /* create the request RPC_HDR */
+ make_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id,
+ rhdr_rb.offset + 0x10, 0);
+
+ smb_io_rpc_hdr("hdr" , &hdr , &rhdr, 0);
+
+ if (rhdr.data == NULL || rhdr_rb.data == NULL) return False;
+
+ /***/
+ /*** link rpc header and bind acknowledgment ***/
+ /***/
+
+ prs_link(NULL , &rhdr , &rhdr_rb);
+ prs_link(&rhdr, &rhdr_rb, NULL );
+
+ prs_init(data, prs_buf_len(&rhdr), 4, False);
+ prs_buf_copy(data->data, &rhdr, 0, prs_buf_len(&rhdr));
+
+ prs_free_data(&rhdr );
+ prs_free_data(&rhdr_rb );
+
+ return True;
+}
+
+cli_auth_fns cli_noauth_fns =
+{
+ create_rpc_noauth_bind_req,
+ NULL,
+ NULL,
+ create_noauth_pdu,
+ NULL
+};
diff --git a/source/rpc_client/cli_pipe_ntlmssp.c b/source/rpc_client/cli_pipe_ntlmssp.c
new file mode 100644
index 00000000000..fbbccc72796
--- /dev/null
+++ b/source/rpc_client/cli_pipe_ntlmssp.c
@@ -0,0 +1,576 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+extern struct pipe_id_info pipe_names[];
+extern pstring global_myname;
+
+static void NTLMSSPcalc_ap( struct ntlmssp_auth_struct *a, unsigned char *data, int len)
+{
+ unsigned char *hash = a->ntlmssp_hash;
+ unsigned char index_i = hash[256];
+ unsigned char index_j = hash[257];
+ int ind;
+
+ for (ind = 0; ind < len; ind++)
+ {
+ unsigned char tc;
+ unsigned char t;
+
+ index_i++;
+ index_j += hash[index_i];
+
+ tc = hash[index_i];
+ hash[index_i] = hash[index_j];
+ hash[index_j] = tc;
+
+ t = hash[index_i] + hash[index_j];
+ data[ind] = data[ind] ^ hash[t];
+ }
+
+ hash[256] = index_i;
+ hash[257] = index_j;
+}
+
+/****************************************************************************
+ decrypt data on an rpc pipe
+ ****************************************************************************/
+static BOOL decode_ntlmssp_pdu(struct cli_connection *con,
+ prs_struct *rdata,
+ int len, int auth_len)
+{
+ RPC_AUTH_NTLMSSP_CHK chk;
+ uint32 crc32;
+
+ int data_len = len - 0x18 - auth_len - 8;
+ char *reply_data = prs_data(rdata, 0x18);
+
+ BOOL auth_verify;
+ BOOL auth_seal ;
+
+ ntlmssp_auth_struct *a;
+ a = (ntlmssp_auth_struct *)cli_conn_get_auth_info(con);
+
+ if (a == NULL)
+ {
+ return False;
+ }
+
+ auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SIGN);
+ auth_seal = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SEAL);
+
+ DEBUG(5,("decode_ntlmssp_pdu: len: %d auth_len: %d verify %s seal %s\n",
+ len, auth_len, BOOLSTR(auth_verify), BOOLSTR(auth_seal)));
+
+ if (reply_data == NULL) return False;
+
+ if (auth_seal)
+ {
+ DEBUG(10,("decode_ntlmssp_pdu: seal\n"));
+ dump_data(100, reply_data, data_len);
+ NTLMSSPcalc_ap(a, (uchar*)reply_data, data_len);
+ dump_data(100, reply_data, data_len);
+ }
+
+ if (auth_verify || auth_seal)
+ {
+ RPC_HDR_AUTH rhdr_auth;
+ prs_struct auth_req;
+ prs_init(&auth_req , 0x0, 4, True);
+ prs_append_data(&auth_req,
+ prs_data(rdata, len - auth_len - 8),
+ 8);
+ smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &auth_req, 0);
+ prs_free_data(&auth_req);
+
+ if (!rpc_hdr_ntlmssp_auth_chk(&rhdr_auth))
+ {
+ return False;
+ }
+ }
+
+ if (auth_verify)
+ {
+ prs_struct auth_verf;
+ char *data = prs_data(rdata, len - auth_len);
+ if (data == NULL) return False;
+
+ DEBUG(10,("decode_ntlmssp_pdu: verify\n"));
+ dump_data(100, data, auth_len);
+ NTLMSSPcalc_ap(a, (uchar*)(data+4), auth_len - 4);
+ prs_init(&auth_verf, 0x0, 4, True);
+ prs_append_data(&auth_verf, data, 16);
+ smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
+ dump_data(100, data, auth_len);
+ prs_free_data(&auth_verf);
+ }
+
+ if (auth_verify)
+ {
+ crc32 = crc32_calc_buffer(data_len, prs_data(rdata, 0x18));
+ if (!rpc_auth_ntlmssp_chk(&chk, crc32 , a->ntlmssp_seq_num))
+ {
+ return False;
+ }
+ a->ntlmssp_seq_num++;
+ }
+ return True;
+}
+
+/****************************************************************************
+ send a request on an rpc pipe.
+ ****************************************************************************/
+static BOOL create_ntlmssp_pdu(struct cli_connection *con,
+ uint8 op_num,
+ prs_struct *data, int data_start, int *data_end,
+ prs_struct *dataa,
+ uint8 *flags)
+{
+ prs_struct data_t;
+ prs_struct hdr;
+ prs_struct hdr_auth;
+ prs_struct auth_verf;
+ int data_len;
+ int frag_len;
+ int auth_len;
+ BOOL auth_verify;
+ BOOL auth_seal;
+ uint32 crc32 = 0;
+
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+ ntlmssp_auth_struct *a;
+ a = (ntlmssp_auth_struct *)cli_conn_get_auth_info(con);
+
+ if (a == NULL)
+ {
+ return False;
+ }
+
+ (*flags) = 0;
+
+ auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SIGN);
+ auth_seal = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SEAL);
+
+ auth_len = (auth_verify ? 16 : 0);
+ data_len = data->offset - data_start;
+
+ if (data_start == 0)
+ {
+ (*flags) |= RPC_FLG_FIRST;
+ }
+
+ if (data_len > nt->max_recv_frag)
+ {
+ data_len = nt->max_recv_frag - (auth_len + (auth_verify ? 8 : 0) + 0x18);
+ }
+ else
+ {
+ (*flags) |= RPC_FLG_LAST;
+ }
+
+ (*data_end) += data_len;
+
+ /* happen to know that NTLMSSP authentication verifier is 16 bytes */
+ frag_len = data_len + auth_len + (auth_verify ? 8 : 0) + 0x18;
+
+ prs_init(&data_t , 0 , 4, False);
+ prs_init(&hdr , frag_len, 4, False);
+ prs_init(&hdr_auth , 0 , 4, False);
+ prs_init(&auth_verf, auth_len, 4, False);
+
+ prs_append_data(&data_t, prs_data(data, data_start), data_len);
+ data_t.end = data_t.data_size;
+ data_t.offset = data_t.data_size;
+
+ create_rpc_request(&hdr, nt->key.vuid, op_num, (*flags),
+ frag_len, auth_len);
+
+ if (auth_seal)
+ {
+ char *buf = prs_data(&data_t, 0);
+ size_t len = prs_buf_len(&data_t);
+ crc32 = crc32_calc_buffer(len, buf);
+ NTLMSSPcalc_ap(a, (uchar*)buf, len);
+ }
+
+ if (auth_seal || auth_verify)
+ {
+ RPC_HDR_AUTH rhdr_auth;
+
+ make_rpc_hdr_auth(&rhdr_auth, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
+ smb_io_rpc_hdr_auth("hdr_auth", &rhdr_auth, &hdr_auth, 0);
+ }
+
+ if (auth_verify)
+ {
+ RPC_AUTH_NTLMSSP_CHK chk;
+
+ make_rpc_auth_ntlmssp_chk(&chk, NTLMSSP_SIGN_VERSION, crc32, a->ntlmssp_seq_num++);
+ smb_io_rpc_auth_ntlmssp_chk("auth_sign", &chk, &auth_verf, 0);
+ NTLMSSPcalc_ap(a, (uchar*)prs_data(&auth_verf, 4), 12);
+ }
+
+ if (auth_seal || auth_verify)
+ {
+ prs_link(NULL , &hdr , &data_t );
+ prs_link(&hdr , &data_t , &hdr_auth );
+ prs_link(&data_t , &hdr_auth , &auth_verf);
+ prs_link(&hdr_auth, &auth_verf, NULL );
+ }
+ else
+ {
+ prs_link(NULL, &hdr , &data_t);
+ prs_link(&hdr, &data_t, NULL );
+ }
+
+ DEBUG(100,("frag_len: 0x%x data_len: 0x%x data_calc_len: 0x%x\n",
+ frag_len, data_len, prs_buf_len(&data_t)));
+
+ if (frag_len != prs_buf_len(&hdr))
+ {
+ DEBUG(0,("expected fragment length does not match\n"));
+
+ prs_free_data(&hdr_auth );
+ prs_free_data(&auth_verf);
+ prs_free_data(&hdr );
+ prs_free_data(&data_t );
+
+ return False;
+ }
+
+ DEBUG(100,("create_ntlmssp_pdu: %d\n", __LINE__));
+
+ /* this is all a hack */
+ prs_init(dataa, prs_buf_len(&hdr), 4, False);
+ prs_debug_out(dataa, "create_ntlmssp_pdu", 200);
+ prs_buf_copy(dataa->data, &hdr, 0, frag_len);
+
+ DEBUG(100,("create_ntlmssp_pdu: %d\n", __LINE__));
+
+ prs_free_data(&hdr_auth );
+ prs_free_data(&auth_verf);
+ prs_free_data(&hdr );
+ prs_free_data(&data_t );
+
+ return True;
+}
+
+/*******************************************************************
+ creates a DCE/RPC bind request
+
+ - initialises the parse structure.
+ - dynamically allocates the header data structure
+ - caller is expected to free the header data structure once used.
+
+ ********************************************************************/
+static BOOL create_ntlmssp_bind_req(struct cli_connection *con,
+ prs_struct *data,
+ uint32 rpc_call_id,
+ RPC_IFACE *abstract, RPC_IFACE *transfer)
+{
+ prs_struct rhdr;
+ prs_struct rhdr_rb;
+ prs_struct rhdr_auth;
+ prs_struct auth_req;
+
+ RPC_HDR_RB hdr_rb;
+ RPC_HDR hdr;
+ RPC_HDR_AUTH hdr_auth;
+ RPC_AUTH_VERIFIER auth_verifier;
+ RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
+
+ struct ntdom_info *nt = cli_conn_get_ntinfo(con);
+ struct ntuser_creds *usr;
+ usr = (struct ntuser_creds*)cli_conn_get_auth_creds(con);
+
+ if (usr == NULL)
+ {
+ DEBUG(10,("create_ntlmssp_bind_req: NULL user creds\n"));
+ return False;
+ }
+
+ prs_init(&rhdr , 0x0, 4, False);
+ prs_init(&rhdr_rb , 0x0, 4, False);
+ prs_init(&rhdr_auth, 0x0, 4, False);
+ prs_init(&auth_req , 0x0, 4, False);
+
+ /* create the bind request RPC_HDR_RB */
+ make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, nt->key.pid,
+ 0x1, nt->key.vuid, 0x1, abstract, transfer);
+
+ /* stream the bind request data */
+ smb_io_rpc_hdr_rb("", &hdr_rb, &rhdr_rb, 0);
+
+ make_rpc_hdr_auth(&hdr_auth, 0x0a, 0x06, 0x00, 1);
+ smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &rhdr_auth, 0);
+
+ make_rpc_auth_verifier(&auth_verifier,
+ "NTLMSSP", NTLMSSP_NEGOTIATE);
+
+ smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, &auth_req, 0);
+
+ make_rpc_auth_ntlmssp_neg(&ntlmssp_neg,
+ usr->ntlmssp_flags, global_myname, usr->domain);
+
+ smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, &auth_req, 0);
+
+ /* create the request RPC_HDR */
+ make_rpc_hdr(&hdr, RPC_BIND, 0x0, rpc_call_id,
+ auth_req .offset + rhdr_auth.offset +
+ rhdr_rb.offset + 0x10,
+ auth_req .offset);
+
+ smb_io_rpc_hdr("hdr" , &hdr , &rhdr, 0);
+
+ if (rhdr.data == NULL || rhdr_rb.data == NULL) return False;
+
+ /***/
+ /*** link rpc header, bind ack and auth responses ***/
+ /***/
+
+ prs_link(NULL , &rhdr , &rhdr_rb );
+ prs_link(&rhdr , &rhdr_rb , &rhdr_auth);
+ prs_link(&rhdr_rb , &rhdr_auth , &auth_req );
+ prs_link(&rhdr_auth, &auth_req , NULL );
+
+ prs_init(data, prs_buf_len(&rhdr), 4, False);
+ prs_buf_copy(data->data, &rhdr, 0, prs_buf_len(&rhdr));
+
+ prs_free_data(&rhdr );
+ prs_free_data(&rhdr_rb );
+ prs_free_data(&rhdr_auth);
+ prs_free_data(&auth_req );
+
+ return cli_conn_set_auth_info(con,
+ (void*)malloc(sizeof(struct ntlmssp_auth_struct)));
+}
+
+static BOOL decode_ntlmssp_bind_resp(struct cli_connection *con,
+ prs_struct *rdata)
+{
+ BOOL valid_ack = True;
+
+ ntlmssp_auth_struct *a;
+ a = (ntlmssp_auth_struct *)cli_conn_get_auth_info(con);
+
+ if (a == NULL)
+ {
+ return False;
+ }
+
+ if (valid_ack)
+ {
+ RPC_HDR_AUTH rhdr_auth;
+ smb_io_rpc_hdr_auth("", &rhdr_auth, rdata, 0);
+ if (rdata->offset == 0 ||
+ !rpc_hdr_ntlmssp_auth_chk(&rhdr_auth))
+ {
+ valid_ack = False;
+ }
+ }
+ if (valid_ack)
+ {
+ RPC_AUTH_VERIFIER rhdr_verf;
+ smb_io_rpc_auth_verifier("", &rhdr_verf, rdata, 0);
+ if (rdata->offset == 0 ||
+ !rpc_auth_verifier_chk(&rhdr_verf,
+ "NTLMSSP",
+ NTLMSSP_CHALLENGE))
+ {
+ valid_ack = False;
+ }
+ }
+ if (valid_ack)
+ {
+ smb_io_rpc_auth_ntlmssp_chal("", &a->ntlmssp_chal, rdata, 0);
+ if (rdata->offset == 0) valid_ack = False;
+ }
+ return valid_ack;
+}
+
+/*******************************************************************
+ creates a DCE/RPC bind authentication response
+
+ - initialises the parse structure.
+ - dynamically allocates the header data structure
+ - caller is expected to free the header data structure once used.
+
+ ********************************************************************/
+static BOOL create_ntlmssp_rpc_bind_resp(struct pwd_info *pwd,
+ char *domain, char *user_name, char *my_name,
+ uint32 ntlmssp_cli_flgs,
+ uint32 rpc_call_id,
+ prs_struct *rhdr,
+ prs_struct *rhdr_autha,
+ prs_struct *auth_resp)
+{
+ RPC_HDR hdr;
+ RPC_HDR_AUTHA hdr_autha;
+ RPC_AUTH_VERIFIER auth_verifier;
+
+ make_rpc_hdr_autha(&hdr_autha, 0x1630, 0x1630, 0x0a, 0x06, 0x00);
+ smb_io_rpc_hdr_autha("hdr_autha", &hdr_autha, rhdr_autha, 0);
+ prs_realloc_data(rhdr_autha, rhdr_autha->offset);
+
+ make_rpc_auth_verifier(&auth_verifier,
+ "NTLMSSP", NTLMSSP_AUTH);
+
+ smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_resp, 0);
+ prs_realloc_data(auth_resp, auth_resp->offset);
+
+ create_ntlmssp_resp(pwd, domain, user_name, my_name, ntlmssp_cli_flgs,
+ auth_resp);
+
+ /* create the request RPC_HDR */
+ make_rpc_hdr(&hdr, RPC_BINDRESP, 0x0, rpc_call_id,
+ auth_resp->offset + rhdr_autha->offset + 0x10,
+ auth_resp->offset);
+
+ smb_io_rpc_hdr("hdr" , &hdr , rhdr, 0);
+ prs_realloc_data(rhdr, rhdr->offset);
+
+ if (rhdr->data == NULL || rhdr_autha->data == NULL) return False;
+
+ /***/
+ /*** link rpc header and authentication responses ***/
+ /***/
+
+ prs_link(NULL , rhdr , rhdr_autha);
+ prs_link(rhdr , rhdr_autha , auth_resp );
+ prs_link(rhdr_autha, auth_resp , NULL );
+
+ return True;
+}
+
+/*******************************************************************
+ creates a DCE/RPC bind continue request
+
+ - initialises the parse structure.
+ - dynamically allocates the header data structure
+ - caller is expected to free the header data structure once used.
+
+ ********************************************************************/
+static BOOL create_ntlmssp_bind_cont(struct cli_connection *con,
+ prs_struct *dataa,
+ uint32 rpc_call_id)
+{
+ BOOL ret = False;
+
+ unsigned char p24[24];
+ unsigned char lm_owf[24];
+ unsigned char lm_hash[16];
+ unsigned char usr_sess_key[16];
+
+ prs_struct hdra;
+ prs_struct hdr_autha;
+ prs_struct auth_resp;
+
+ struct ntuser_creds *usr;
+ ntlmssp_auth_struct *a;
+ a = (ntlmssp_auth_struct *)cli_conn_get_auth_info(con);
+ usr = (struct ntuser_creds*)cli_conn_get_auth_creds(con);
+
+ DEBUG(5,("Bind RPC Cont\n"));
+
+ if (a == NULL)
+ {
+ return False;
+ }
+
+ prs_init(&hdra , 0x0, 4, False);
+ prs_init(&hdr_autha, 0x0, 4, False);
+ prs_init(&auth_resp, 0x0, 4, False);
+
+ pwd_make_lm_nt_owf(&usr->pwd, a->ntlmssp_chal.challenge, usr_sess_key);
+
+ create_ntlmssp_rpc_bind_resp(&usr->pwd, usr->domain,
+ usr->user_name, global_myname,
+ a->ntlmssp_chal.neg_flags,
+ rpc_call_id,
+ &hdra, &hdr_autha, &auth_resp);
+
+ cli_set_con_usr_sesskey(con, usr_sess_key);
+ pwd_get_lm_nt_owf(&usr->pwd, lm_owf, NULL, NULL);
+ pwd_get_lm_nt_16(&usr->pwd, lm_hash, NULL);
+ NTLMSSPOWFencrypt(lm_hash, lm_owf, p24);
+ {
+ unsigned char j = 0;
+ int ind;
+ unsigned char k2[8];
+
+ memcpy(k2, p24, 5);
+ k2[5] = 0xe5;
+ k2[6] = 0x38;
+ k2[7] = 0xb0;
+
+ for (ind = 0; ind < 256; ind++)
+ {
+ a->ntlmssp_hash[ind] = (unsigned char)ind;
+ }
+
+ for (ind = 0; ind < 256; ind++)
+ {
+ unsigned char tc;
+
+ j += (a->ntlmssp_hash[ind] + k2[ind%8]);
+
+ tc = a->ntlmssp_hash[ind];
+ a->ntlmssp_hash[ind] = a->ntlmssp_hash[j];
+ a->ntlmssp_hash[j] = tc;
+ }
+
+ a->ntlmssp_hash[256] = 0;
+ a->ntlmssp_hash[257] = 0;
+ }
+ bzero(lm_hash, sizeof(lm_hash));
+
+ prs_init(dataa, 0, 4, False);
+ ret = prs_copy(dataa, &hdra);
+
+ prs_free_data(&hdra);
+ prs_free_data(&hdr_autha);
+ prs_free_data(&auth_resp);
+
+ return ret;
+}
+
+cli_auth_fns cli_ntlmssp_fns =
+{
+ create_ntlmssp_bind_req,
+ decode_ntlmssp_bind_resp,
+ create_ntlmssp_bind_cont,
+ create_ntlmssp_pdu,
+ decode_ntlmssp_pdu
+};
diff --git a/source/rpc_client/cli_reg.c b/source/rpc_client/cli_reg.c
index b5e9cbb2ac2..94f526b4d87 100644
--- a/source/rpc_client/cli_reg.c
+++ b/source/rpc_client/cli_reg.c
@@ -3,10 +3,9 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998.
- * Copyright (C) Jeremy Allison 1999.
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Paul Ashton 1997-2000.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,44 +28,89 @@
#endif
#include "includes.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
/****************************************************************************
do a REG Open Policy
****************************************************************************/
-BOOL do_reg_connect(struct cli_state *cli, char *full_keyname, char *key_name,
+BOOL reg_connect( const char* srv_name,
+ const char *full_keyname,
+ char *key_name,
+ uint32 access_mask,
POLICY_HND *reg_hnd)
{
BOOL res = True;
uint32 reg_type = 0;
- if (full_keyname == NULL)
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_WINREG, &con))
+ {
return False;
+ }
ZERO_STRUCTP(reg_hnd);
+ if (full_keyname == NULL)
+ {
+ return False;
+ }
+
/*
* open registry receive a policy handle
*/
- if (!reg_split_key(full_keyname, &reg_type, key_name)) {
- DEBUG(0,("do_reg_connect: unrecognised key name %s\n", full_keyname));
+ if (!reg_split_key(full_keyname, &reg_type, key_name))
+ {
+ DEBUG(0,("reg_connect: unrecognised key name %s\n",
+ full_keyname));
return False;
}
- switch (reg_type) {
- case HKEY_LOCAL_MACHINE:
- res = res ? do_reg_open_hklm(cli, 0x84E0, 0x02000000, reg_hnd) : False;
- break;
+ switch (reg_type)
+ {
+ case HKEY_CLASSES_ROOT:
+ {
+ res = res ? reg_open_hkcr(con,
+ 0x5428, access_mask,
+ reg_hnd) : False;
+ break;
+ }
+
+ case HKEY_LOCAL_MACHINE:
+ {
+ res = res ? reg_open_hklm(con,
+ 0x84E0, access_mask,
+ reg_hnd) : False;
+ break;
+ }
- case HKEY_USERS:
- res = res ? do_reg_open_hku(cli, 0x84E0, 0x02000000, reg_hnd) : False;
- break;
+ case HKEY_USERS:
+ {
+ res = res ? reg_open_hku(con,
+ 0x84E0, access_mask,
+ reg_hnd) : False;
+ break;
+ }
+ default:
+ {
+ DEBUG(0,("reg_connect: unrecognised hive key\n"));
+ return False;
+ }
+ }
- default:
- DEBUG(0,("do_reg_connect: unrecognised hive key\n"));
- return False;
+ if (res)
+ {
+ if (!register_policy_hnd(get_global_hnd_cache(), cli_con_sec_ctx(con),
+ reg_hnd, access_mask) ||
+ !set_policy_con(get_global_hnd_cache(), reg_hnd, con,
+ cli_connection_unlink))
+ {
+ cli_connection_unlink(con);
+ return False;
+ }
}
return res;
@@ -75,123 +119,169 @@ BOOL do_reg_connect(struct cli_state *cli, char *full_keyname, char *key_name,
/****************************************************************************
do a REG Open Policy
****************************************************************************/
-BOOL do_reg_open_hklm(struct cli_state *cli, uint16 unknown_0, uint32 level,
+BOOL reg_open_hkcr( struct cli_connection *con,
+ uint16 unknown_0, uint32 level,
POLICY_HND *hnd)
{
prs_struct rbuf;
prs_struct buf;
- REG_Q_OPEN_HKLM q_o;
- REG_R_OPEN_HKLM r_o;
+ REG_Q_OPEN_HKCR q_o;
+ BOOL valid_pol = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
- /* create and send a MSRPC command with api REG_OPEN_HKLM */
+ /* create and send a MSRPC command with api REG_OPEN_HKCR */
- DEBUG(4,("REG Open HKLM\n"));
+ DEBUG(4,("REG Open HKCR\n"));
- init_reg_q_open_hklm(&q_o, unknown_0, level);
+ make_reg_q_open_hkcr(&q_o, unknown_0, level);
/* turn parameters into data stream */
- if(!reg_io_q_open_hklm("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_open_hkcr("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, REG_OPEN_HKCR, &buf, &rbuf))
+ {
+ REG_R_OPEN_HKCR r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_open_hkcr("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_OPEN_HKCR: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_OPEN_HKLM, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.pol;
+ valid_pol = True;
+ }
}
- prs_mem_free(&buf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- ZERO_STRUCT(r_o);
+ return valid_pol;
+}
- if(!reg_io_r_open_hklm("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+/****************************************************************************
+do a REG Open Policy
+****************************************************************************/
+BOOL reg_open_hklm( struct cli_connection *con,
+ uint16 unknown_0, uint32 level,
+ POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_OPEN_HKLM q_o;
+ BOOL valid_pol = False;
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_OPEN_HKLM: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
- }
+ if (hnd == NULL) return False;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api REG_OPEN_HKLM */
+
+ DEBUG(4,("REG Open HKLM\n"));
+
+ make_reg_q_open_hklm(&q_o, unknown_0, level);
- /* ok, at last: we're happy. return the policy handle */
- memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
+ /* turn parameters into data stream */
+ if (reg_io_q_open_hklm("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, REG_OPEN_HKLM, &buf, &rbuf))
+ {
+ REG_R_OPEN_HKLM r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_open_hklm("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_OPEN_HKLM: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.pol;
+ valid_pol = True;
+ }
+ }
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_pol;
}
/****************************************************************************
do a REG Open HKU
****************************************************************************/
-BOOL do_reg_open_hku(struct cli_state *cli, uint16 unknown_0, uint32 level,
+BOOL reg_open_hku( struct cli_connection *con,
+ uint16 unknown_0, uint32 level,
POLICY_HND *hnd)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_OPEN_HKU q_o;
- REG_R_OPEN_HKU r_o;
+ BOOL valid_pol = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_OPEN_HKU */
DEBUG(4,("REG Open HKU\n"));
- init_reg_q_open_hku(&q_o, unknown_0, level);
+ make_reg_q_open_hku(&q_o, unknown_0, level);
/* turn parameters into data stream */
- if(!reg_io_q_open_hku("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, REG_OPEN_HKU, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
-
- if(!reg_io_r_open_hku("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_open_hku("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, REG_OPEN_HKU, &buf, &rbuf))
+ {
+ REG_R_OPEN_HKU r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_open_hku("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_OPEN_HKU: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_OPEN_HKU: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.pol;
+ valid_pol = True;
+ }
}
- /* ok, at last: we're happy. return the policy handle */
- memcpy(hnd, r_o.pol.data, sizeof(hnd->data));
-
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_pol;
}
/****************************************************************************
@@ -199,65 +289,60 @@ do a REG Unknown 0xB command. sent after a create key or create value.
this might be some sort of "sync" or "refresh" command, sent after
modification of the registry...
****************************************************************************/
-BOOL do_reg_flush_key(struct cli_state *cli, POLICY_HND *hnd)
+BOOL reg_flush_key( POLICY_HND *hnd)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_FLUSH_KEY q_o;
- REG_R_FLUSH_KEY r_o;
+ BOOL valid_query = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_FLUSH_KEY */
DEBUG(4,("REG Unknown 0xB\n"));
- init_reg_q_flush_key(&q_o, hnd);
+ make_reg_q_flush_key(&q_o, hnd);
/* turn parameters into data stream */
- if(!reg_io_q_flush_key("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_FLUSH_KEY, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
-
- if(!reg_io_r_flush_key("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_flush_key("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_FLUSH_KEY, &buf, &rbuf))
+ {
+ REG_R_FLUSH_KEY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_flush_key("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_FLUSH_KEY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_FLUSH_KEY: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ valid_query = True;
+ }
}
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_query;
}
/****************************************************************************
do a REG Query Key
****************************************************************************/
-BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd,
- char *class, uint32 *class_len,
+BOOL reg_query_key( POLICY_HND *hnd,
+ char *key_class, uint32 *class_len,
uint32 *num_subkeys, uint32 *max_subkeylen,
uint32 *max_subkeysize, uint32 *num_values,
uint32 *max_valnamelen, uint32 *max_valbufsize,
@@ -266,427 +351,395 @@ BOOL do_reg_query_key(struct cli_state *cli, POLICY_HND *hnd,
prs_struct rbuf;
prs_struct buf;
REG_Q_QUERY_KEY q_o;
- REG_R_QUERY_KEY r_o;
+ BOOL valid_query = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_QUERY_KEY */
DEBUG(4,("REG Query Key\n"));
- init_reg_q_query_key(&q_o, hnd, *class_len);
+ make_reg_q_query_key(&q_o, hnd, *class_len);
/* turn parameters into data stream */
- if(!reg_io_q_query_key("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_QUERY_KEY, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
-
- if(!reg_io_r_query_key("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_query_key("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_QUERY_KEY, &buf, &rbuf))
+ {
+ REG_R_QUERY_KEY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_query_key("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_QUERY_KEY: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ valid_query = True;
+
+ *class_len = r_o.hdr_class.uni_max_len;
+ unistr2_to_ascii(key_class, &r_o.uni_class, sizeof(fstring)-1);
+ *num_subkeys = r_o.num_subkeys ;
+ *max_subkeylen = r_o.max_subkeylen ;
+ *max_subkeysize = r_o.max_subkeysize;
+ *num_values = r_o.num_values ;
+ *max_valnamelen = r_o.max_valnamelen;
+ *max_valbufsize = r_o.max_valbufsize;
+ *sec_desc = r_o.sec_desc ;
+ *mod_time = r_o.mod_time ;
+ }
}
- *class_len = r_o.hdr_class.uni_max_len;
- fstrcpy(class, dos_unistr2_to_str(&r_o.uni_class));
- *num_subkeys = r_o.num_subkeys ;
- *max_subkeylen = r_o.max_subkeylen ;
- *max_subkeysize = r_o.max_subkeysize;
- *num_values = r_o.num_values ;
- *max_valnamelen = r_o.max_valnamelen;
- *max_valbufsize = r_o.max_valbufsize;
- *sec_desc = r_o.sec_desc ;
- *mod_time = r_o.mod_time ;
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- prs_mem_free(&rbuf);
-
- return True;
+ return valid_query;
}
/****************************************************************************
do a REG Unknown 1A
****************************************************************************/
-BOOL do_reg_unknown_1a(struct cli_state *cli, POLICY_HND *hnd, uint32 *unk)
+BOOL reg_unknown_1a( POLICY_HND *hnd, uint32 *unk)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_UNK_1A q_o;
- REG_R_UNK_1A r_o;
+ BOOL valid_query = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_UNKNOWN_1A */
DEBUG(4,("REG Unknown 1a\n"));
- init_reg_q_unk_1a(&q_o, hnd);
+ make_reg_q_unk_1a(&q_o, hnd);
/* turn parameters into data stream */
- if(!reg_io_q_unk_1a("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, REG_UNK_1A, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
-
- if(!reg_io_r_unk_1a("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_unk_1a("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_UNK_1A, &buf, &rbuf))
+ {
+ REG_R_UNK_1A r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_unk_1a("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_UNK_1A: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ valid_query = True;
+ (*unk) = r_o.unknown;
+ }
}
- (*unk) = r_o.unknown;
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- prs_mem_free(&rbuf);
-
- return True;
+ return valid_query;
}
/****************************************************************************
do a REG Query Info
****************************************************************************/
-BOOL do_reg_query_info(struct cli_state *cli, POLICY_HND *hnd,
- char *type, uint32 *unk_0, uint32 *unk_1)
+BOOL reg_query_info( POLICY_HND *hnd,
+ const char* val_name,
+ uint32 *type, BUFFER2 *buffer)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_INFO q_o;
- REG_R_INFO r_o;
+ BOOL valid_query = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_INFO */
DEBUG(4,("REG Query Info\n"));
- init_reg_q_info(&q_o, hnd, "ProductType", time(NULL), 4, 1);
+ make_reg_q_info(&q_o, hnd, val_name, 4, 0);
/* turn parameters into data stream */
- if(!reg_io_q_info("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_info("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_INFO, &buf, &rbuf))
+ {
+ REG_R_INFO r_o;
+ BOOL p;
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_INFO, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ ZERO_STRUCT(r_o);
- prs_mem_free(&buf);
+ r_o.type = type;
+ r_o.uni_type = buffer;
- ZERO_STRUCT(r_o);
+ reg_io_r_info("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
- if(!reg_io_r_info("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if ( r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_INFO: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ valid_query = True;
+ }
}
- fstrcpy(type, dos_buffer2_to_str(&r_o.uni_type));
- (*unk_0) = r_o.unknown_0;
- (*unk_1) = r_o.unknown_1;
-
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_query;
}
/****************************************************************************
do a REG Set Key Security
****************************************************************************/
-BOOL do_reg_set_key_sec(struct cli_state *cli, POLICY_HND *hnd, SEC_DESC_BUF *sec_desc_buf)
+BOOL reg_set_key_sec( POLICY_HND *hnd,
+ uint32 sec_info,
+ uint32 sec_buf_size, SEC_DESC *sec_buf)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_SET_KEY_SEC q_o;
- REG_R_SET_KEY_SEC r_o;
+ BOOL valid_query = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_SET_KEY_SEC */
DEBUG(4,("REG Set Key security.\n"));
- init_reg_q_set_key_sec(&q_o, hnd, sec_desc_buf);
+ make_reg_q_set_key_sec(&q_o, hnd, sec_info, sec_buf_size, sec_buf);
/* turn parameters into data stream */
- if(!reg_io_q_set_key_sec("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_SET_KEY_SEC, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_set_key_sec("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_SET_KEY_SEC, &buf, &rbuf))
+ {
+ REG_R_SET_KEY_SEC r_o;
+ BOOL p;
- prs_mem_free(&buf);
+ ZERO_STRUCT(r_o);
- ZERO_STRUCT(r_o);
+ reg_io_r_set_key_sec("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
- if(!reg_io_r_set_key_sec("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
-
- if (r_o.status != 0) {
- prs_mem_free(&rbuf);
- return False;
+ if (p && r_o.status != 0)
+ {
+ valid_query = True;
+ }
}
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_query;
}
+
/****************************************************************************
do a REG Query Key Security
****************************************************************************/
-
-BOOL do_reg_get_key_sec(struct cli_state *cli, POLICY_HND *hnd, uint32 *sec_buf_size, SEC_DESC_BUF **ppsec_desc_buf)
+BOOL reg_get_key_sec( POLICY_HND *hnd,
+ uint32 sec_info,
+ uint32 *sec_buf_size, SEC_DESC_BUF *sec_buf)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_GET_KEY_SEC q_o;
- REG_R_GET_KEY_SEC r_o;
+ BOOL valid_query = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_GET_KEY_SEC */
DEBUG(4,("REG query key security. buf_size: %d\n", *sec_buf_size));
- init_reg_q_get_key_sec(&q_o, hnd, *sec_buf_size, NULL);
+ make_reg_q_get_key_sec(&q_o, hnd, sec_info, *sec_buf_size, sec_buf);
/* turn parameters into data stream */
- if(!reg_io_q_get_key_sec("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_GET_KEY_SEC, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
-
- if(!reg_io_r_get_key_sec("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
-
- if (r_o.status == 0x0000007a) {
- /*
- * get the maximum buffer size: it was too small
- */
- (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
- DEBUG(5,("sec_buf_size too small. use %d\n", *sec_buf_size));
- } else if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
- } else {
- (*sec_buf_size) = r_o.data->len;
- *ppsec_desc_buf = r_o.data;
+ if (reg_io_q_get_key_sec("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_GET_KEY_SEC, &buf, &rbuf))
+ {
+ REG_R_GET_KEY_SEC r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ r_o.data = sec_buf;
+ if (*sec_buf_size != 0)
+ {
+ sec_buf->sec = (SEC_DESC*)malloc(*sec_buf_size);
+ }
+ reg_io_r_get_key_sec("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status == 0x0000007a)
+ {
+ /*
+ * get the maximum buffer size: it was too small
+ */
+ (*sec_buf_size) = r_o.hdr_sec.buf_max_len;
+ DEBUG(5,("sec_buf_size too small. use %d\n", *sec_buf_size));
+ valid_query = True;
+ }
+ else if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_GET_KEY_SEC: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+ else
+ {
+ valid_query = True;
+ (*sec_buf_size) = r_o.data->len;
+ }
}
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_query;
}
/****************************************************************************
do a REG Delete Value
****************************************************************************/
-BOOL do_reg_delete_val(struct cli_state *cli, POLICY_HND *hnd, char *val_name)
+BOOL reg_delete_val( POLICY_HND *hnd, char *val_name)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_DELETE_VALUE q_o;
- REG_R_DELETE_VALUE r_o;
+ BOOL valid_delete = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_DELETE_VALUE */
DEBUG(4,("REG Delete Value: %s\n", val_name));
- init_reg_q_delete_val(&q_o, hnd, val_name);
+ make_reg_q_delete_val(&q_o, hnd, val_name);
/* turn parameters into data stream */
- if(!reg_io_q_delete_val("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, REG_DELETE_VALUE, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
-
- if(!reg_io_r_delete_val("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_delete_val("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_DELETE_VALUE, &buf, &rbuf))
+ {
+ REG_R_DELETE_VALUE r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_delete_val("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_DELETE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_DELETE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ valid_delete = True;
+ }
}
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_delete;
}
/****************************************************************************
do a REG Delete Key
****************************************************************************/
-BOOL do_reg_delete_key(struct cli_state *cli, POLICY_HND *hnd, char *key_name)
+BOOL reg_delete_key( POLICY_HND *hnd, char *key_name)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_DELETE_KEY q_o;
- REG_R_DELETE_KEY r_o;
+ BOOL valid_delete = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_DELETE_KEY */
DEBUG(4,("REG Delete Key: %s\n", key_name));
- init_reg_q_delete_key(&q_o, hnd, key_name);
+ make_reg_q_delete_key(&q_o, hnd, key_name);
/* turn parameters into data stream */
- if(!reg_io_q_delete_key("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_DELETE_KEY, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
-
- if(!reg_io_r_delete_key("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_delete_key("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_DELETE_KEY, &buf, &rbuf))
+ {
+ REG_R_DELETE_KEY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_delete_key("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_DELETE_KEY: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ valid_delete = True;
+ }
}
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_delete;
}
/****************************************************************************
do a REG Create Key
****************************************************************************/
-BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
+BOOL reg_create_key( POLICY_HND *hnd,
char *key_name, char *key_class,
SEC_ACCESS *sam_access,
POLICY_HND *key)
@@ -694,84 +747,71 @@ BOOL do_reg_create_key(struct cli_state *cli, POLICY_HND *hnd,
prs_struct rbuf;
prs_struct buf;
REG_Q_CREATE_KEY q_o;
- REG_R_CREATE_KEY r_o;
- SEC_DESC *sec = NULL;
- SEC_DESC_BUF *sec_buf = NULL;
- size_t sec_len;
+ BOOL valid_create = False;
+ SEC_DESC sec;
+ SEC_DESC_BUF sec_buf;
+ int sec_len;
+ ZERO_STRUCT(sec);
+ ZERO_STRUCT(sec_buf);
ZERO_STRUCT(q_o);
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_CREATE_KEY */
DEBUG(4,("REG Create Key: %s %s 0x%08x\n", key_name, key_class,
sam_access != NULL ? sam_access->mask : 0));
- if((sec = make_sec_desc( 1, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, NULL, &sec_len)) == NULL) {
- DEBUG(0,("make_sec_desc : malloc fail.\n"));
- return False;
- }
+ sec_len = make_sec_desc(&sec, 1, SEC_DESC_SELF_RELATIVE,
+ NULL, NULL, NULL, NULL);
- DEBUG(10,("make_sec_desc: len = %d\n", (int)sec_len));
+ DEBUG(10,("make_sec_desc: len = %d\n", sec_len));
- if((sec_buf = make_sec_desc_buf( (int)sec_len, sec)) == NULL) {
- DEBUG(0,("make_sec_desc : malloc fail (1)\n"));
- free_sec_desc(&sec);
- return False;
- }
- free_sec_desc(&sec);
-
- prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
-
- init_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access, sec_buf);
+ make_reg_q_create_key(&q_o, hnd, key_name, key_class, sam_access,
+ &sec_buf, sec_len, &sec);
/* turn parameters into data stream */
- if(!reg_io_q_create_key("", &q_o, &buf, 0)) {
- free_sec_desc_buf(&sec_buf);
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (rpc_api_pipe_req(cli, REG_CREATE_KEY, &buf, &rbuf)) {
- free_sec_desc_buf(&sec_buf);
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- free_sec_desc_buf(&sec_buf);
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
-
- if(!reg_io_r_create_key("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_create_key("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_CREATE_KEY, &buf, &rbuf))
+ {
+ REG_R_CREATE_KEY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_create_key("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_CREATE_KEY: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ valid_create = True;
+ *key = r_o.key_pol;
+ }
}
- memcpy(key, r_o.key_pol.data, sizeof(key->data));
+ free_sec_desc(&sec);
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_create;
}
/****************************************************************************
do a REG Enum Key
****************************************************************************/
-BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd,
+BOOL reg_enum_key( POLICY_HND *hnd,
int key_index, char *key_name,
uint32 *unk_1, uint32 *unk_2,
time_t *mod_time)
@@ -779,122 +819,112 @@ BOOL do_reg_enum_key(struct cli_state *cli, POLICY_HND *hnd,
prs_struct rbuf;
prs_struct buf;
REG_Q_ENUM_KEY q_o;
- REG_R_ENUM_KEY r_o;
+ BOOL valid_query = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_ENUM_KEY */
DEBUG(4,("REG Enum Key\n"));
- init_reg_q_enum_key(&q_o, hnd, key_index);
+ make_reg_q_enum_key(&q_o, hnd, key_index);
/* turn parameters into data stream */
- if(!reg_io_q_enum_key("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_ENUM_KEY, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
-
- if(!reg_io_r_enum_key("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_enum_key("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_ENUM_KEY, &buf, &rbuf))
+ {
+ REG_R_ENUM_KEY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_enum_key("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_ENUM_KEY: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ valid_query = True;
+ (*unk_1) = r_o.unknown_1;
+ (*unk_2) = r_o.unknown_2;
+ unistr_to_ascii(key_name, r_o.key_name.str.buffer,
+ sizeof(fstring)-1);
+ (*mod_time) = nt_time_to_unix(&r_o.time);
+ }
}
- (*unk_1) = r_o.unknown_1;
- (*unk_2) = r_o.unknown_2;
- fstrcpy(key_name, dos_unistr2(r_o.key_name.str.buffer));
- (*mod_time) = nt_time_to_unix(&r_o.time);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- prs_mem_free(&rbuf);
-
- return True;
+ return valid_query;
}
/****************************************************************************
do a REG Create Value
****************************************************************************/
-BOOL do_reg_create_val(struct cli_state *cli, POLICY_HND *hnd,
+BOOL reg_create_val( POLICY_HND *hnd,
char *val_name, uint32 type, BUFFER3 *data)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_CREATE_VALUE q_o;
- REG_R_CREATE_VALUE r_o;
+ BOOL valid_create = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_CREATE_VALUE */
DEBUG(4,("REG Create Value: %s\n", val_name));
- init_reg_q_create_val(&q_o, hnd, val_name, type, data);
+ make_reg_q_create_val(&q_o, hnd, val_name, type, data);
/* turn parameters into data stream */
- if(!reg_io_q_create_val("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_CREATE_VALUE, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
-
- if(!reg_io_r_create_val("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_create_val("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_CREATE_VALUE, &buf, &rbuf))
+ {
+ REG_R_CREATE_VALUE r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_create_val("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_CREATE_VALUE: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ valid_create = True;
+ }
}
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_create;
}
/****************************************************************************
do a REG Enum Value
****************************************************************************/
-BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd,
+BOOL reg_enum_val( POLICY_HND *hnd,
int val_index, int max_valnamelen, int max_valbufsize,
fstring val_name,
uint32 *val_type, BUFFER2 *value)
@@ -902,185 +932,245 @@ BOOL do_reg_enum_val(struct cli_state *cli, POLICY_HND *hnd,
prs_struct rbuf;
prs_struct buf;
REG_Q_ENUM_VALUE q_o;
- REG_R_ENUM_VALUE r_o;
+ BOOL valid_query = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_ENUM_VALUE */
DEBUG(4,("REG Enum Value\n"));
- init_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize);
+ make_reg_q_enum_val(&q_o, hnd, val_index, max_valnamelen, max_valbufsize);
/* turn parameters into data stream */
- if(!reg_io_q_enum_val("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_ENUM_VALUE, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- ZERO_STRUCT(r_o);
- r_o.buf_value = value;
-
- if(!reg_io_r_enum_val("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_enum_val("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_ENUM_VALUE, &buf, &rbuf))
+ {
+ REG_R_ENUM_VALUE r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+ r_o.buf_value = value;
+
+ reg_io_r_enum_val("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_ENUM_VALUE: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ valid_query = True;
+ (*val_type) = r_o.type;
+ unistr2_to_ascii(val_name, &r_o.uni_name, sizeof(fstring)-1);
+ }
}
- (*val_type) = r_o.type;
- fstrcpy(val_name, dos_unistr2_to_str(&r_o.uni_name));
-
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_query;
}
/****************************************************************************
do a REG Open Key
****************************************************************************/
-BOOL do_reg_open_entry(struct cli_state *cli, POLICY_HND *hnd,
+BOOL reg_open_entry( POLICY_HND *hnd,
char *key_name, uint32 unk_0,
POLICY_HND *key_hnd)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_OPEN_ENTRY q_o;
- REG_R_OPEN_ENTRY r_o;
+ BOOL valid_pol = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
- prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api REG_OPEN_ENTRY */
DEBUG(4,("REG Open Entry\n"));
- init_reg_q_open_entry(&q_o, hnd, key_name, unk_0);
+ make_reg_q_open_entry(&q_o, hnd, key_name, unk_0);
/* turn parameters into data stream */
- if(!reg_io_q_open_entry("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_OPEN_ENTRY, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_open_entry("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_OPEN_ENTRY, &buf, &rbuf))
+ {
+ REG_R_OPEN_ENTRY r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_open_entry("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- prs_mem_free(&buf);
+ if (p)
+ {
+ struct cli_connection *con = NULL;
- ZERO_STRUCT(r_o);
+ if (!cli_connection_get(hnd, &con))
+ {
+ return False;
+ }
- if(!reg_io_r_open_entry("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
-
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("REG_OPEN_ENTRY: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
+ *key_hnd = r_o.pol;
+ valid_pol = cli_pol_link(key_hnd, hnd);
+ }
}
- memcpy(key_hnd, r_o.pol.data, sizeof(key_hnd->data));
-
- prs_mem_free(&rbuf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- return True;
+ return valid_pol;
}
/****************************************************************************
do a REG Close
****************************************************************************/
-BOOL do_reg_close(struct cli_state *cli, POLICY_HND *hnd)
+BOOL reg_close( POLICY_HND *hnd)
{
prs_struct rbuf;
prs_struct buf;
REG_Q_CLOSE q_c;
- REG_R_CLOSE r_c;
- int i;
+ BOOL valid_close = False;
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
/* create and send a MSRPC command with api REG_CLOSE */
- prs_init(&buf, MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
DEBUG(4,("REG Close\n"));
/* store the parameters */
- init_reg_q_close(&q_c, hnd);
+ make_reg_q_close(&q_c, hnd);
/* turn parameters into data stream */
- if(!reg_io_q_close("", &q_c, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
+ if (reg_io_q_close("", &q_c, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, REG_CLOSE, &buf, &rbuf))
+ {
+ REG_R_CLOSE r_c;
+ BOOL p;
+
+ ZERO_STRUCT(r_c);
+
+ reg_io_r_close("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, REG_CLOSE, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
+ if (p)
+ {
+ /* check that the returned policy handle is all zeros */
+ uint32 i;
+ valid_close = True;
+
+ for (i = 0; i < sizeof(r_c.pol.data); i++)
+ {
+ if (r_c.pol.data[i] != 0)
+ {
+ valid_close = False;
+ break;
+ }
+ }
+ if (!valid_close)
+ {
+ DEBUG(0,("REG_CLOSE: non-zero handle returned\n"));
+ }
+ }
}
- prs_mem_free(&buf);
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- ZERO_STRUCT(r_c);
+ close_policy_hnd(get_global_hnd_cache(), hnd);
- if(!reg_io_r_close("", &r_c, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
- }
+ return valid_close;
+}
- if (r_c.status != 0) {
- /* report error code */
- DEBUG(0,("REG_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
- prs_mem_free(&rbuf);
+/****************************************************************************
+do a REG Shutdown Server
+****************************************************************************/
+BOOL reg_shutdown(const char *srv_name,
+ const char *msg, uint32 timeout, uint16 flags)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ REG_Q_SHUTDOWN q_o;
+ BOOL valid_shutdown = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_LSARPC, &con))
+ {
return False;
}
- /* check that the returned policy handle is all zeros */
+ if (msg == NULL) return False;
- for (i = 0; i < sizeof(r_c.pol.data); i++) {
- if (r_c.pol.data[i] != 0) {
- prs_mem_free(&rbuf);
- DEBUG(0,("REG_CLOSE: non-zero handle returned\n"));
- return False;
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api REG_SHUTDOWN */
+
+ DEBUG(4,("REG Shutdown: (timeout: %d secs) %s\n", timeout, msg));
+
+ make_reg_q_shutdown(&q_o, msg, timeout, flags);
+
+ /* turn parameters into data stream */
+ if (reg_io_q_shutdown("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, REG_SHUTDOWN, &buf, &rbuf))
+ {
+ REG_R_SHUTDOWN r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ reg_io_r_shutdown("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("REG_SHUTDOWN: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_shutdown = True;
}
- }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- prs_mem_free(&rbuf);
+ cli_connection_unlink(con);
- return True;
+ return valid_shutdown;
}
+
+
diff --git a/source/rpc_client/cli_samr.c b/source/rpc_client/cli_samr.c
index 8fccf6c7962..64659327fa6 100644
--- a/source/rpc_client/cli_samr.c
+++ b/source/rpc_client/cli_samr.c
@@ -2,9 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1994-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Jeremy Allison 1999.
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -28,797 +27,2533 @@
#endif
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
/****************************************************************************
-do a SAMR query user groups
+do a SAMR change user password command
****************************************************************************/
-BOOL get_samr_query_usergroups(struct cli_state *cli,
- POLICY_HND *pol_open_domain, uint32 user_rid,
- uint32 *num_groups, DOM_GID *gid)
+BOOL samr_chgpasswd_user( struct cli_connection *con,
+ const char *srv_name, const char *user_name,
+ const char nt_newpass[516], const uchar nt_oldhash[16],
+ const char lm_newpass[516], const uchar lm_oldhash[16])
{
- POLICY_HND pol_open_user;
- if (pol_open_domain == NULL || num_groups == NULL || gid == NULL)
- return False;
+ prs_struct data;
+ prs_struct rdata;
- /* send open domain (on user sid) */
- if (!do_samr_open_user(cli,
- pol_open_domain,
- 0x02011b, user_rid,
- &pol_open_user))
- {
- return False;
- }
+ SAMR_Q_CHGPASSWD_USER q_e;
+ BOOL valid_pwc = False;
- /* send user groups query */
- if (!do_samr_query_usergroups(cli,
- &pol_open_user,
- num_groups, gid))
+ /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
+ srv_name, user_name));
+
+ make_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
+ nt_newpass, nt_oldhash,
+ lm_newpass, lm_oldhash);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_chgpasswd_user("", &q_e, &data, 0) &&
+ rpc_con_pipe_req(con, SAMR_CHGPASSWD_USER, &data, &rdata))
{
- DEBUG(5,("do_samr_query_usergroups: error in query user groups\n"));
+ SAMR_R_CHGPASSWD_USER r_e;
+ BOOL p;
+
+ samr_io_r_chgpasswd_user("", &r_e, &rdata, 0);
+
+ p = rdata.offset != 0;
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pwc = True;
+ }
}
- return do_samr_close(cli, &pol_open_user);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pwc;
}
+
/****************************************************************************
-do a SAMR query user info
+do a SAMR unknown 0x38 command
****************************************************************************/
-BOOL get_samr_query_userinfo(struct cli_state *cli,
- POLICY_HND *pol_open_domain,
- uint32 info_level,
- uint32 user_rid, SAM_USER_INFO_21 *usr)
+BOOL samr_get_dom_pwinfo(struct cli_connection *con, const char *srv_name)
{
- POLICY_HND pol_open_user;
- if (pol_open_domain == NULL || usr == NULL)
- return False;
+ prs_struct data;
+ prs_struct rdata;
- memset((char *)usr, '\0', sizeof(*usr));
+ SAMR_Q_GET_DOM_PWINFO q_e;
+ BOOL valid_un8 = False;
- /* send open domain (on user sid) */
- if (!do_samr_open_user(cli,
- pol_open_domain,
- 0x02011b, user_rid,
- &pol_open_user))
+ /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Query Domain Password Info server:%s\n", srv_name));
+
+ make_samr_q_get_dom_pwinfo(&q_e, srv_name);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_get_dom_pwinfo("", &q_e, &data, 0) &&
+ rpc_con_pipe_req(con, SAMR_GET_DOM_PWINFO, &data, &rdata))
{
- return False;
+ SAMR_R_GET_DOM_PWINFO r_e;
+ BOOL p;
+
+ samr_io_r_get_dom_pwinfo("", &r_e, &rdata, 0);
+
+ p = rdata.offset != 0;
+#if 0
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_GET_DOM_PWINFO: %s\n", get_nt_error_msg(r_e.status)));
+ p = False;
+ }
+#endif
+ if (p)
+ {
+ valid_un8 = True;
+ }
}
-
- /* send user info query */
- if (!do_samr_query_userinfo(cli,
- &pol_open_user,
- info_level, (void*)usr))
+ else
{
- DEBUG(5,("do_samr_query_userinfo: error in query user info, level 0x%x\n",
- info_level));
+ DEBUG(4,("samr_unknown38: rpc_con_pipe_req failed\n"));
}
- return do_samr_close(cli, &pol_open_user);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_un8;
}
/****************************************************************************
-do a SAMR change user password command
+do a SAMR unknown 0x8 command
****************************************************************************/
-BOOL do_samr_chgpasswd_user(struct cli_state *cli,
- char *srv_name, char *user_name,
- char nt_newpass[516], uchar nt_oldhash[16],
- char lm_newpass[516], uchar lm_oldhash[16])
+BOOL samr_query_dom_info( POLICY_HND *domain_pol, uint16 switch_value,
+ SAM_UNK_CTR *ctr)
{
prs_struct data;
prs_struct rdata;
- SAMR_Q_CHGPASSWD_USER q_e;
- SAMR_R_CHGPASSWD_USER r_e;
- /* create and send a MSRPC command with api SAMR_CHGPASSWD_USER */
+ SAMR_Q_QUERY_DOMAIN_INFO q_e;
+ BOOL valid_un8 = False;
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
- DEBUG(4,("SAMR Change User Password. server:%s username:%s\n",
- srv_name, user_name));
+ if (domain_pol == NULL) return False;
- init_samr_q_chgpasswd_user(&q_e, srv_name, user_name,
- nt_newpass, nt_oldhash,
- lm_newpass, lm_oldhash);
+ /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
/* turn parameters into data stream */
- if(!samr_io_q_chgpasswd_user("", &q_e, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ if (samr_io_q_query_dom_info("", &q_e, &data, 0) &&
+ rpc_hnd_pipe_req(domain_pol, SAMR_QUERY_DOMAIN_INFO, &data, &rdata))
+ {
+ SAMR_R_QUERY_DOMAIN_INFO r_e;
+ BOOL p;
+
+ r_e.ctr = ctr;
+ samr_io_r_query_dom_info("", &r_e, &rdata, 0);
+
+ p = rdata.offset != 0;
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status)));
+ p = False;
+ }
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ if (p)
+ {
+ valid_un8 = True;
+ }
}
- prs_mem_free(&data);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- if(!samr_io_r_chgpasswd_user("", &r_e, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
+ return valid_un8;
+}
+
+/****************************************************************************
+do a SAMR enumerate Domains
+****************************************************************************/
+uint32 samr_enum_domains( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_domains)
+{
+ uint32 status = 0x0;
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_ENUM_DOMAINS q_e;
+
+ DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
+
+ if (pol == NULL || num_sam_domains == NULL || sam == NULL)
+ {
+ return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
}
- if (r_e.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_R_CHGPASSWD_USER: %s\n", get_nt_error_msg(r_e.status)));
- prs_mem_free(&rdata);
- return False;
+ /* create and send a MSRPC command with api SAMR_ENUM_DOMAINS */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_enum_domains(&q_e, pol, *start_idx, size);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_enum_domains("", &q_e, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_ENUM_DOMAINS, &data, &rdata))
+ {
+ SAMR_R_ENUM_DOMAINS r_e;
+ BOOL p;
+
+ samr_io_r_enum_domains("", &r_e, &rdata, 0);
+
+ status = r_e.status;
+ p = rdata.offset != 0;
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_ENUM_DOMAINS: %s\n", get_nt_error_msg(r_e.status)));
+ p = (r_e.status == STATUS_MORE_ENTRIES);
+ }
+
+ if (p)
+ {
+ uint32 i = (*num_sam_domains);
+ uint32 j = 0;
+ uint32 name_idx = 0;
+
+ (*num_sam_domains) += r_e.num_entries2;
+ (*sam) = (struct acct_info*) Realloc((*sam),
+ sizeof(struct acct_info) * (*num_sam_domains));
+
+ if ((*sam) == NULL)
+ {
+ (*num_sam_domains) = 0;
+ i = 0;
+ }
+
+ for (j = 0; i < (*num_sam_domains) && j < r_e.num_entries2; j++, i++)
+ {
+ (*sam)[i].rid = r_e.sam[j].rid;
+ (*sam)[i].acct_name[0] = 0;
+ (*sam)[i].acct_desc[0] = 0;
+ if (r_e.sam[j].hdr_name.buffer)
+ {
+ unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_dom_name[name_idx], sizeof((*sam)[i].acct_name)-1);
+ name_idx++;
+ }
+ DEBUG(5,("samr_enum_domains: idx: %4d rid: %8x acct: %s\n",
+ i, (*sam)[i].rid, (*sam)[i].acct_name));
+ }
+ (*start_idx) = r_e.next_idx;
+ }
+ else if (status == 0x0)
+ {
+ status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
+ }
+
+ if (r_e.sam != NULL)
+ {
+ free(r_e.sam);
+ }
+ if (r_e.uni_dom_name != NULL)
+ {
+ free(r_e.uni_dom_name);
+ }
}
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ return status;
}
/****************************************************************************
-do a SAMR unknown 0x38 command
+do a SAMR enumerate groups
****************************************************************************/
-BOOL do_samr_unknown_38(struct cli_state *cli, char *srv_name)
+uint32 samr_enum_dom_groups( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_groups)
{
+ uint32 status = 0x0;
prs_struct data;
prs_struct rdata;
- SAMR_Q_UNKNOWN_38 q_e;
- SAMR_R_UNKNOWN_38 r_e;
+ SAMR_Q_ENUM_DOM_GROUPS q_e;
- /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
+ DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ if (pol == NULL || num_sam_groups == NULL)
+ {
+ return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
+ }
- DEBUG(4,("SAMR Unknown 38 server:%s\n", srv_name));
+ /* create and send a MSRPC command with api SAMR_ENUM_DOM_GROUPS */
- init_samr_q_unknown_38(&q_e, srv_name);
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
- /* turn parameters into data stream */
- if(!samr_io_q_unknown_38("", &q_e, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ /* store the parameters */
+ make_samr_q_enum_dom_groups(&q_e, pol, *start_idx, size);
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_UNKNOWN_38, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ /* turn parameters into data stream */
+ if (samr_io_q_enum_dom_groups("", &q_e, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_GROUPS, &data, &rdata))
+ {
+ SAMR_R_ENUM_DOM_GROUPS r_e;
+ BOOL p;
+
+ samr_io_r_enum_dom_groups("", &r_e, &rdata, 0);
+
+ status = r_e.status;
+ p = rdata.offset != 0;
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_ENUM_DOM_GROUPS: %s\n", get_nt_error_msg(r_e.status)));
+ p = (r_e.status == STATUS_MORE_ENTRIES);
+ }
- prs_mem_free(&data);
+ if (p)
+ {
+ uint32 i = (*num_sam_groups);
+ uint32 j = 0;
+ uint32 name_idx = 0;
- if(!samr_io_r_unknown_38("", &r_e, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
- }
+ (*num_sam_groups) += r_e.num_entries2;
+ (*sam) = (struct acct_info*) Realloc((*sam),
+ sizeof(struct acct_info) * (*num_sam_groups));
+
+ if ((*sam) == NULL)
+ {
+ (*num_sam_groups) = 0;
+ i = 0;
+ }
+
+ for (j = 0; i < (*num_sam_groups) && j < r_e.num_entries2; j++, i++)
+ {
+ (*sam)[i].rid = r_e.sam[j].rid;
+ (*sam)[i].acct_name[0] = 0;
+ (*sam)[i].acct_desc[0] = 0;
+ if (r_e.sam[j].hdr_name.buffer)
+ {
+ unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_grp_name[name_idx], sizeof((*sam)[i].acct_name)-1);
+ name_idx++;
+ }
+ DEBUG(5,("samr_enum_dom_groups: idx: %4d rid: %8x acct: %s\n",
+ i, (*sam)[i].rid, (*sam)[i].acct_name));
+ }
+ (*start_idx) = r_e.next_idx;
+ }
+ else if (status == 0x0)
+ {
+ status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
+ }
- if (r_e.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_R_UNKNOWN_38: %s\n", get_nt_error_msg(r_e.status)));
- prs_mem_free(&rdata);
- return False;
+ if (r_e.sam != NULL)
+ {
+ free(r_e.sam);
+ }
+ if (r_e.uni_grp_name != NULL)
+ {
+ free(r_e.uni_grp_name);
+ }
}
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ return status;
}
/****************************************************************************
-do a SAMR unknown 0x8 command
+do a SAMR enumerate aliases
****************************************************************************/
-BOOL do_samr_query_dom_info(struct cli_state *cli,
- POLICY_HND *domain_pol, uint16 switch_value)
+uint32 samr_enum_dom_aliases( POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ struct acct_info **sam,
+ uint32 *num_sam_aliases)
{
+ uint32 status = 0x0;
prs_struct data;
prs_struct rdata;
- SAMR_Q_QUERY_DOMAIN_INFO q_e;
- SAMR_R_QUERY_DOMAIN_INFO r_e;
- if (domain_pol == NULL)
- return False;
+ SAMR_Q_ENUM_DOM_ALIASES q_e;
- /* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
+ DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ if (pol == NULL || num_sam_aliases == NULL)
+ {
+ return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
+ }
- DEBUG(4,("SAMR Unknown 8 switch:%d\n", switch_value));
+ /* create and send a MSRPC command with api SAMR_ENUM_DOM_ALIASES */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
/* store the parameters */
- init_samr_q_query_dom_info(&q_e, domain_pol, switch_value);
+ make_samr_q_enum_dom_aliases(&q_e, pol, *start_idx, size);
/* turn parameters into data stream */
- if(!samr_io_q_query_dom_info("", &q_e, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ if (samr_io_q_enum_dom_aliases("", &q_e, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_ALIASES, &data, &rdata))
+ {
+ SAMR_R_ENUM_DOM_ALIASES r_e;
+ BOOL p;
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ ZERO_STRUCT(r_e);
- prs_mem_free(&data);
+ samr_io_r_enum_dom_aliases("", &r_e, &rdata, 0);
- if(!samr_io_r_query_dom_info("", &r_e, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
- }
+ p = rdata.offset != 0;
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_ENUM_DOM_ALIASES: %s\n", get_nt_error_msg(r_e.status)));
+ p = (r_e.status == STATUS_MORE_ENTRIES);
+ }
- if (r_e.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_R_QUERY_DOMAIN_INFO: %s\n", get_nt_error_msg(r_e.status)));
- prs_mem_free(&rdata);
- return False;
+ if (p)
+ {
+ uint32 i = (*num_sam_aliases);
+ uint32 j = 0;
+ uint32 name_idx = 0;
+
+ (*num_sam_aliases) += r_e.num_entries2;
+ (*sam) = (struct acct_info*) Realloc((*sam),
+ sizeof(struct acct_info) * (*num_sam_aliases));
+
+ if ((*sam) == NULL)
+ {
+ (*num_sam_aliases) = 0;
+ i = 0;
+ }
+
+ for (j = 0; i < (*num_sam_aliases) && j < r_e.num_entries2; j++, i++)
+ {
+ (*sam)[i].rid = r_e.sam[j].rid;
+ (*sam)[i].acct_name[0] = 0;
+ (*sam)[i].acct_desc[0] = 0;
+ if (r_e.sam[j].hdr_name.buffer)
+ {
+ unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_grp_name[name_idx], sizeof((*sam)[i].acct_name)-1);
+ name_idx++;
+ }
+ DEBUG(5,("samr_enum_dom_aliases: idx: %4d rid: %8x acct: %s\n",
+ i, (*sam)[i].rid, (*sam)[i].acct_name));
+ }
+ (*start_idx) = r_e.next_idx;
+ }
+ else if (status == 0x0)
+ {
+ status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
+ }
+
+ if (r_e.sam != NULL)
+ {
+ free(r_e.sam);
+ }
+ if (r_e.uni_grp_name != NULL)
+ {
+ free(r_e.uni_grp_name);
+ }
}
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ return status;
}
/****************************************************************************
do a SAMR enumerate users
****************************************************************************/
-BOOL do_samr_enum_dom_users(struct cli_state *cli,
- POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
+uint32 samr_enum_dom_users( POLICY_HND *pol, uint32 *start_idx,
uint16 acb_mask, uint16 unk_1, uint32 size,
struct acct_info **sam,
- int *num_sam_users)
+ uint32 *num_sam_users)
{
+ uint32 status = 0x0;
prs_struct data;
prs_struct rdata;
+
SAMR_Q_ENUM_DOM_USERS q_e;
- SAMR_R_ENUM_DOM_USERS r_e;
- int i;
- int name_idx = 0;
+
+ DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
if (pol == NULL || num_sam_users == NULL)
- return False;
+ {
+ return NT_STATUS_INVALID_PARAMETER | 0xC0000000;
+ }
/* create and send a MSRPC command with api SAMR_ENUM_DOM_USERS */
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
-
- DEBUG(4,("SAMR Enum SAM DB max size:%x\n", size));
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
/* store the parameters */
- init_samr_q_enum_dom_users(&q_e, pol,
- num_entries, unk_0,
+ make_samr_q_enum_dom_users(&q_e, pol, *start_idx,
acb_mask, unk_1, size);
/* turn parameters into data stream */
- if(!samr_io_q_enum_dom_users("", &q_e, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ if (samr_io_q_enum_dom_users("", &q_e, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_ENUM_DOM_USERS, &data, &rdata))
+ {
+ SAMR_R_ENUM_DOM_USERS r_e;
+ BOOL p;
- prs_mem_free(&data);
+ ZERO_STRUCT(r_e);
- if(!samr_io_r_enum_dom_users("", &r_e, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
- }
+ samr_io_r_enum_dom_users("", &r_e, &rdata, 0);
- if (r_e.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
- prs_mem_free(&rdata);
- return False;
- }
+ status = r_e.status;
+ p = rdata.offset != 0;
- *num_sam_users = r_e.num_entries2;
- if (*num_sam_users > MAX_SAM_ENTRIES) {
- *num_sam_users = MAX_SAM_ENTRIES;
- DEBUG(2,("do_samr_enum_dom_users: sam user entries limited to %d\n",
- *num_sam_users));
- }
+ if (p && r_e.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_ENUM_DOM_USERS: %s\n", get_nt_error_msg(r_e.status)));
+ p = (r_e.status == STATUS_MORE_ENTRIES);
+ }
- *sam = (struct acct_info*) malloc(sizeof(struct acct_info) * (*num_sam_users));
+ if (p)
+ {
+ uint32 i = (*num_sam_users);
+ uint32 j = 0;
+ uint32 name_idx = 0;
+
+ (*num_sam_users) += r_e.num_entries2;
+ if ((*num_sam_users) != 0)
+ {
+ (*sam) = g_renew(struct acct_info, (*sam),
+ (*num_sam_users));
+ }
- if ((*sam) == NULL)
- *num_sam_users = 0;
-
- for (i = 0; i < *num_sam_users; i++) {
- (*sam)[i].smb_userid = r_e.sam[i].rid;
- if (r_e.sam[i].hdr_name.buffer) {
- char *acct_name = dos_unistrn2(r_e.uni_acct_name[name_idx].buffer,
- r_e.uni_acct_name[name_idx].uni_str_len);
- fstrcpy((*sam)[i].acct_name, acct_name);
- name_idx++;
- } else {
- memset((char *)(*sam)[i].acct_name, '\0', sizeof((*sam)[i].acct_name));
+ if ((*sam) == NULL)
+ {
+ (*num_sam_users) = 0;
+ i = 0;
+ }
+
+ for (j = 0; i < (*num_sam_users) && j < r_e.num_entries2; j++, i++)
+ {
+ (*sam)[i].rid = r_e.sam[j].rid;
+ (*sam)[i].acct_name[0] = 0;
+ (*sam)[i].acct_desc[0] = 0;
+ if (r_e.sam[j].hdr_name.buffer)
+ {
+ unistr2_to_ascii((*sam)[i].acct_name, &r_e.uni_acct_name[name_idx], sizeof((*sam)[i].acct_name)-1);
+ name_idx++;
+ }
+ DEBUG(5,("samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
+ i, (*sam)[i].rid, (*sam)[i].acct_name));
+ }
+ (*start_idx) = r_e.next_idx;
+ }
+ else if (status == 0x0)
+ {
+ status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
}
- DEBUG(5,("do_samr_enum_dom_users: idx: %4d rid: %8x acct: %s\n",
- i, (*sam)[i].smb_userid, (*sam)[i].acct_name));
+ safe_free(r_e.sam);
+ safe_free(r_e.uni_acct_name);
+ }
+ else
+ {
+ status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
}
- prs_mem_free(&rdata );
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ return status;
}
/****************************************************************************
do a SAMR Connect
****************************************************************************/
-BOOL do_samr_connect(struct cli_state *cli,
- char *srv_name, uint32 unknown_0,
+BOOL samr_connect( const char *srv_name, uint32 access_mask,
POLICY_HND *connect_pol)
{
prs_struct data;
prs_struct rdata;
+
SAMR_Q_CONNECT q_o;
- SAMR_R_CONNECT r_o;
+ BOOL valid_pol = False;
- if (srv_name == NULL || connect_pol == NULL)
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_SAMR, &con))
+ {
return False;
+ }
- /* create and send a MSRPC command with api SAMR_CONNECT */
+ DEBUG(4,("SAMR Open Policy server:%s access_mask:%x\n",
+ srv_name, access_mask));
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ if (srv_name == NULL || connect_pol == NULL) return False;
- DEBUG(4,("SAMR Open Policy server:%s undoc value:%x\n",
- srv_name, unknown_0));
+ /* create and send a MSRPC command with api SAMR_CONNECT */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
/* store the parameters */
- init_samr_q_connect(&q_o, srv_name, unknown_0);
+ make_samr_q_connect(&q_o, srv_name, access_mask);
/* turn parameters into data stream */
- if(!samr_io_q_connect("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ if (samr_io_q_connect("", &q_o, &data, 0) &&
+ rpc_con_pipe_req(con, SAMR_CONNECT, &data, &rdata))
+ {
+ SAMR_R_CONNECT r_o;
+ BOOL p;
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_CONNECT, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ samr_io_r_connect("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
+ valid_pol = register_policy_hnd(get_global_hnd_cache(),
+ cli_con_sec_ctx(con),
+ connect_pol,
+ access_mask) &&
+ set_policy_con(get_global_hnd_cache(),
+ connect_pol, con,
+ cli_connection_unlink);
+ }
}
- prs_mem_free(&data);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- if(!samr_io_r_connect("", &r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
- }
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Query Security Object
+****************************************************************************/
+BOOL samr_query_sec_obj( const POLICY_HND *pol,
+ uint32 type,
+ SEC_DESC_BUF *buf)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_SEC_OBJ q_o;
+ BOOL valid_pol = False;
+
+ DEBUG(4,("SAMR Query Sec Object: type %x\n", type));
+
+ if (pol == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_QUERY_SEC_OBJ */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_query_sec_obj(&q_o, pol, type);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_query_sec_obj("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_QUERY_SEC_OBJECT, &data, &rdata))
+ {
+ SAMR_R_QUERY_SEC_OBJ r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ samr_io_r_query_sec_obj("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_R_CONNECT: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rdata);
- return False;
- }
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_SEC_OBJ: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
- memcpy(connect_pol, &r_o.connect_pol, sizeof(r_o.connect_pol));
+ if (p)
+ {
+ valid_pol = True;
+ buf->sec = r_o.buf.sec;
+ }
+ }
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ return valid_pol;
}
/****************************************************************************
do a SAMR Open User
****************************************************************************/
-BOOL do_samr_open_user(struct cli_state *cli,
- POLICY_HND *pol, uint32 unk_0, uint32 rid,
+BOOL samr_open_user( const POLICY_HND *pol,
+ uint32 unk_0, uint32 rid,
POLICY_HND *user_pol)
{
prs_struct data;
prs_struct rdata;
+
SAMR_Q_OPEN_USER q_o;
- SAMR_R_OPEN_USER r_o;
+ BOOL valid_pol = False;
- if (pol == NULL || user_pol == NULL)
- return False;
+ DEBUG(4,("SAMR Open User. unk_0: %08x RID:%x\n",
+ unk_0, rid));
+
+ if (pol == NULL || user_pol == NULL) return False;
/* create and send a MSRPC command with api SAMR_OPEN_USER */
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
- DEBUG(4,("SAMR Open User. unk_0: %08x RID:%x\n",
- unk_0, rid));
+ /* store the parameters */
+ make_samr_q_open_user(&q_o, pol, unk_0, rid);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_open_user("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_OPEN_USER, &data, &rdata))
+ {
+ SAMR_R_OPEN_USER r_o;
+ BOOL p;
+
+ samr_io_r_open_user("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
+ valid_pol = cli_pol_link(user_pol, pol);
+ }
+ }
+
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Open Alias
+****************************************************************************/
+BOOL samr_open_alias( const POLICY_HND *domain_pol,
+ uint32 flags, uint32 rid,
+ POLICY_HND *alias_pol)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_OPEN_ALIAS q_o;
+ BOOL valid_pol = False;
+
+ DEBUG(4,("SAMR Open Alias. RID:%x\n", rid));
+
+ if (alias_pol == NULL || domain_pol == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_OPEN_ALIAS */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
/* store the parameters */
- init_samr_q_open_user(&q_o, pol, unk_0, rid);
+ make_samr_q_open_alias(&q_o, domain_pol, flags, rid);
/* turn parameters into data stream */
- if(!samr_io_q_open_user("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ if (samr_io_q_open_alias("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(domain_pol, SAMR_OPEN_ALIAS, &data, &rdata))
+ {
+ SAMR_R_OPEN_ALIAS r_o;
+ BOOL p;
+
+ samr_io_r_open_alias("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_OPEN_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(alias_pol, &r_o.pol, sizeof(r_o.pol));
+ valid_pol = cli_pol_link(alias_pol, domain_pol);
+ }
}
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_OPEN_USER, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Delete Alias Member
+****************************************************************************/
+BOOL samr_del_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_DEL_ALIASMEM q_o;
+ BOOL valid_pol = False;
+
+ if (alias_pol == NULL || sid == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_DEL_ALIASMEM */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Delete Alias Member.\n"));
+
+ /* store the parameters */
+ make_samr_q_del_aliasmem(&q_o, alias_pol, sid);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_del_aliasmem("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(alias_pol, SAMR_DEL_ALIASMEM, &data, &rdata))
+ {
+ SAMR_R_DEL_ALIASMEM r_o;
+ BOOL p;
+
+ samr_io_r_del_aliasmem("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_DEL_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ }
}
- prs_mem_free(&data);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- if(!samr_io_r_open_user("", &r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Add Alias Member
+****************************************************************************/
+BOOL samr_add_aliasmem( POLICY_HND *alias_pol, DOM_SID *sid)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_ADD_ALIASMEM q_o;
+ BOOL valid_pol = False;
+
+ if (alias_pol == NULL || sid == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_ADD_ALIASMEM */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Add Alias Member.\n"));
+
+ /* store the parameters */
+ make_samr_q_add_aliasmem(&q_o, alias_pol, sid);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_add_aliasmem("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(alias_pol, SAMR_ADD_ALIASMEM, &data, &rdata))
+ {
+ SAMR_R_ADD_ALIASMEM r_o;
+ BOOL p;
+
+ samr_io_r_add_aliasmem("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_ADD_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ }
}
-
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_R_OPEN_USER: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rdata);
- return False;
+
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Delete Domain Alias
+****************************************************************************/
+BOOL samr_delete_dom_alias( POLICY_HND *alias_pol)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_DELETE_DOM_ALIAS q_o;
+ BOOL valid_pol = False;
+
+ if (alias_pol == NULL) return False;
+
+ /* delete and send a MSRPC command with api SAMR_DELETE_DOM_ALIAS */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Delete Domain Alias.\n"));
+
+ /* store the parameters */
+ make_samr_q_delete_dom_alias(&q_o, alias_pol);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_delete_dom_alias("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(alias_pol, SAMR_DELETE_DOM_ALIAS, &data, &rdata))
+ {
+ SAMR_R_DELETE_DOM_ALIAS r_o;
+ BOOL p;
+
+ samr_io_r_delete_dom_alias("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_DELETE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ }
}
- memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- prs_mem_free(&rdata);
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Create Domain User
+****************************************************************************/
+uint32 samr_create_dom_user( POLICY_HND *domain_pol, const char *acct_name,
+ uint32 unk_0, uint32 unk_1,
+ POLICY_HND *user_pol, uint32 *rid)
+{
+ prs_struct data;
+ prs_struct rdata;
+ uint32 status = NT_STATUS_INVALID_PARAMETER | 0xC0000000;
+
+ SAMR_Q_CREATE_USER q_o;
+
+ if (user_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_CREATE_USER */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Create Domain User. Name:%s\n", acct_name));
+
+ /* store the parameters */
+ make_samr_q_create_user(&q_o, domain_pol, acct_name, unk_0, unk_1);
- return True;
+ /* turn parameters into data stream */
+ if (samr_io_q_create_user("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_USER, &data, &rdata))
+ {
+ SAMR_R_CREATE_USER r_o;
+ BOOL p;
+
+ samr_io_r_create_user("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+ status = r_o.status;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_CREATE_USER: %s\n", get_nt_error_msg(r_o.status)));
+ p = r_o.status != NT_STATUS_USER_EXISTS;
+ }
+
+ if (p)
+ {
+ memcpy(user_pol, &r_o.user_pol, sizeof(r_o.user_pol));
+ *rid = r_o.user_rid;
+ if (!cli_pol_link(user_pol, domain_pol))
+ {
+ status = NT_STATUS_INVALID_HANDLE | 0xC0000000;
+ }
+ }
+ }
+
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return status;
}
/****************************************************************************
-do a SAMR Open Domain
+do a SAMR Create Domain Alias
****************************************************************************/
-BOOL do_samr_open_domain(struct cli_state *cli,
- POLICY_HND *connect_pol, uint32 rid, DOM_SID *sid,
- POLICY_HND *domain_pol)
+BOOL samr_create_dom_alias( POLICY_HND *domain_pol, const char *acct_name,
+ POLICY_HND *alias_pol, uint32 *rid)
{
prs_struct data;
prs_struct rdata;
- pstring sid_str;
- SAMR_Q_OPEN_DOMAIN q_o;
- SAMR_R_OPEN_DOMAIN r_o;
- if (connect_pol == NULL || sid == NULL || domain_pol == NULL)
- return False;
+ SAMR_Q_CREATE_DOM_ALIAS q_o;
+ BOOL valid_pol = False;
- /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
+ if (alias_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ /* create and send a MSRPC command with api SAMR_CREATE_DOM_ALIAS */
- sid_to_string(sid_str, sid);
- DEBUG(4,("SAMR Open Domain. SID:%s RID:%x\n", sid_str, rid));
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Create Domain Alias. Name:%s\n", acct_name));
/* store the parameters */
- init_samr_q_open_domain(&q_o, connect_pol, rid, sid);
+ make_samr_q_create_dom_alias(&q_o, domain_pol, acct_name);
/* turn parameters into data stream */
- if(!samr_io_q_open_domain("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ if (samr_io_q_create_dom_alias("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_DOM_ALIAS, &data, &rdata))
+ {
+ SAMR_R_CREATE_DOM_ALIAS r_o;
+ BOOL p;
+
+ samr_io_r_create_dom_alias("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_CREATE_DOM_ALIAS: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(alias_pol, &r_o.alias_pol, sizeof(r_o.alias_pol));
+ *rid = r_o.rid;
+ valid_pol = cli_pol_link(alias_pol, domain_pol);
+ }
}
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Get Alias Info
+****************************************************************************/
+BOOL samr_query_aliasinfo( POLICY_HND *alias_pol, uint16 switch_value,
+ ALIAS_INFO_CTR *ctr)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_ALIASINFO q_o;
+ BOOL valid_pol = False;
+
+ if (alias_pol == NULL || ctr == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_GET_ALIASINFO */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Get Alias Info\n"));
+
+ /* store the parameters */
+ make_samr_q_query_aliasinfo(&q_o, alias_pol, switch_value);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_query_aliasinfo("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(alias_pol, SAMR_QUERY_ALIASINFO, &data, &rdata))
+ {
+ SAMR_R_QUERY_ALIASINFO r_o;
+ BOOL p;
+
+ /* get alias info */
+ r_o.ctr = ctr;
+
+ samr_io_r_query_aliasinfo("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_ALIASINFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ }
}
- prs_mem_free(&data);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- if(!samr_io_r_open_domain("", &r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Set Alias Info
+****************************************************************************/
+BOOL samr_set_aliasinfo( POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_SET_ALIASINFO q_o;
+ BOOL valid_pol = False;
+
+ if (alias_pol == NULL || ctr == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_SET_ALIASINFO */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Set Alias Info\n"));
+
+ /* store the parameters */
+ make_samr_q_set_aliasinfo(&q_o, alias_pol, ctr);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_set_aliasinfo("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(alias_pol, SAMR_SET_ALIASINFO, &data, &rdata))
+ {
+ SAMR_R_SET_ALIASINFO r_o;
+ BOOL p;
+
+ samr_io_r_set_aliasinfo("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_SET_ALIASINFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ }
}
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rdata);
- return False;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Open Group
+****************************************************************************/
+BOOL samr_open_group( const POLICY_HND *domain_pol,
+ uint32 flags, uint32 rid,
+ POLICY_HND *group_pol)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_OPEN_GROUP q_o;
+ BOOL valid_pol = False;
+
+ DEBUG(4,("SAMR Open Group. RID:%x\n", rid));
+
+ if (group_pol == NULL || domain_pol == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_OPEN_GROUP */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_open_group(&q_o, domain_pol, flags, rid);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_open_group("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(domain_pol, SAMR_OPEN_GROUP, &data, &rdata))
+ {
+ SAMR_R_OPEN_GROUP r_o;
+ BOOL p;
+
+ samr_io_r_open_group("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_OPEN_GROUP: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
+ valid_pol = cli_pol_link(group_pol, domain_pol);
+ }
}
- memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- prs_mem_free(&rdata);
+ return valid_pol;
+}
- return True;
+/****************************************************************************
+do a SAMR Delete Group Member
+****************************************************************************/
+BOOL samr_del_groupmem( POLICY_HND *group_pol, uint32 rid)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_DEL_GROUPMEM q_o;
+ BOOL valid_pol = False;
+
+ if (group_pol == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_DEL_GROUPMEM */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Delete Group Member.\n"));
+
+ /* store the parameters */
+ make_samr_q_del_groupmem(&q_o, group_pol, rid);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_del_groupmem("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(group_pol, SAMR_DEL_GROUPMEM, &data, &rdata))
+ {
+ SAMR_R_DEL_GROUPMEM r_o;
+ BOOL p;
+
+ samr_io_r_del_groupmem("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_DEL_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ }
+ }
+
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pol;
}
/****************************************************************************
-do a SAMR Query Unknown 12
+do a SAMR Add Group Member
****************************************************************************/
-BOOL do_samr_query_unknown_12(struct cli_state *cli,
- POLICY_HND *pol, uint32 rid, uint32 num_gids, uint32 *gids,
- uint32 *num_aliases,
- fstring als_names [MAX_LOOKUP_SIDS],
- uint32 num_als_users[MAX_LOOKUP_SIDS])
+BOOL samr_add_groupmem( POLICY_HND *group_pol, uint32 rid)
{
prs_struct data;
prs_struct rdata;
- SAMR_Q_UNKNOWN_12 q_o;
- SAMR_R_UNKNOWN_12 r_o;
- if (pol == NULL || rid == 0 || num_gids == 0 || gids == NULL ||
- num_aliases == NULL || als_names == NULL || num_als_users == NULL )
- return False;
+ SAMR_Q_ADD_GROUPMEM q_o;
+ BOOL valid_pol = False;
- /* create and send a MSRPC command with api SAMR_UNKNOWN_12 */
+ if (group_pol == NULL) return False;
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ /* create and send a MSRPC command with api SAMR_ADD_GROUPMEM */
- DEBUG(4,("SAMR Query Unknown 12.\n"));
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Add Group Member.\n"));
/* store the parameters */
- init_samr_q_unknown_12(&q_o, pol, rid, num_gids, gids);
+ make_samr_q_add_groupmem(&q_o, group_pol, rid);
/* turn parameters into data stream */
- if(!samr_io_q_unknown_12("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ if (samr_io_q_add_groupmem("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(group_pol, SAMR_ADD_GROUPMEM, &data, &rdata))
+ {
+ SAMR_R_ADD_GROUPMEM r_o;
+ BOOL p;
+
+ samr_io_r_add_groupmem("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_ADD_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ }
}
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_UNKNOWN_12, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Delete Domain User
+****************************************************************************/
+BOOL samr_delete_dom_user( POLICY_HND *user_pol)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_DELETE_DOM_USER q_o;
+ BOOL valid_pol = False;
+
+ if (user_pol == NULL) return False;
+
+ /* delete and send a MSRPC command with api SAMR_DELETE_DOM_USER */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Delete Domain User.\n"));
+
+ /* store the parameters */
+ make_samr_q_delete_dom_user(&q_o, user_pol);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_delete_dom_user("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(user_pol, SAMR_DELETE_DOM_USER, &data, &rdata))
+ {
+ SAMR_R_DELETE_DOM_USER r_o;
+ BOOL p;
+
+ samr_io_r_delete_dom_user("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_DELETE_DOM_USER: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ }
}
- prs_mem_free(&data);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- if(!samr_io_r_unknown_12("", &r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Delete Domain Group
+****************************************************************************/
+BOOL samr_delete_dom_group( POLICY_HND *group_pol)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_DELETE_DOM_GROUP q_o;
+ BOOL valid_pol = False;
+
+ if (group_pol == NULL) return False;
+
+ /* delete and send a MSRPC command with api SAMR_DELETE_DOM_GROUP */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Delete Domain Group.\n"));
+
+ /* store the parameters */
+ make_samr_q_delete_dom_group(&q_o, group_pol);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_delete_dom_group("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(group_pol, SAMR_DELETE_DOM_GROUP, &data, &rdata))
+ {
+ SAMR_R_DELETE_DOM_GROUP r_o;
+ BOOL p;
+
+ samr_io_r_delete_dom_group("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_DELETE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ }
}
-
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_R_UNKNOWN_12: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rdata);
- return False;
+
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Create Domain Group
+****************************************************************************/
+BOOL samr_create_dom_group( POLICY_HND *domain_pol, const char *acct_name,
+ POLICY_HND *group_pol, uint32 *rid)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_CREATE_DOM_GROUP q_o;
+ BOOL valid_pol = False;
+
+ if (group_pol == NULL || domain_pol == NULL || acct_name == NULL || rid == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_CREATE_DOM_GROUP */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Create Domain Group. Name:%s\n", acct_name));
+
+ /* store the parameters */
+ make_samr_q_create_dom_group(&q_o, domain_pol, acct_name);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_create_dom_group("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(domain_pol, SAMR_CREATE_DOM_GROUP, &data, &rdata))
+ {
+ SAMR_R_CREATE_DOM_GROUP r_o;
+ BOOL p;
+
+ samr_io_r_create_dom_group("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_CREATE_DOM_GROUP: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(group_pol, &r_o.pol, sizeof(r_o.pol));
+ *rid = r_o.rid;
+ valid_pol = cli_pol_link(group_pol, domain_pol);
+ }
}
- if (r_o.ptr_aliases != 0 && r_o.ptr_als_usrs != 0 &&
- r_o.num_als_usrs1 == r_o.num_aliases1) {
- int i;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- *num_aliases = r_o.num_aliases1;
+ return valid_pol;
+}
- for (i = 0; i < r_o.num_aliases1; i++) {
- fstrcpy(als_names[i], dos_unistrn2(r_o.uni_als_name[i].buffer,
- r_o.uni_als_name[i].uni_str_len));
+/****************************************************************************
+do a SAMR Set Group Info
+****************************************************************************/
+BOOL samr_set_groupinfo( POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_SET_GROUPINFO q_o;
+ BOOL valid_pol = False;
+
+ if (group_pol == NULL || ctr == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_SET_GROUPINFO */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Set Group Info\n"));
+
+ /* store the parameters */
+ make_samr_q_set_groupinfo(&q_o, group_pol, ctr);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_set_groupinfo("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(group_pol, SAMR_SET_GROUPINFO, &data, &rdata))
+ {
+ SAMR_R_SET_GROUPINFO r_o;
+ BOOL p;
+
+ samr_io_r_set_groupinfo("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_SET_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
}
- for (i = 0; i < r_o.num_als_usrs1; i++) {
- num_als_users[i] = r_o.num_als_usrs[i];
+
+ if (p)
+ {
+ valid_pol = True;
}
- } else if (r_o.ptr_aliases == 0 && r_o.ptr_als_usrs == 0) {
- *num_aliases = 0;
- } else {
- prs_mem_free(&rdata);
- return False;
}
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ return valid_pol;
}
/****************************************************************************
-do a SAMR Query User Groups
+do a SAMR Unknown 2d
****************************************************************************/
-BOOL do_samr_query_usergroups(struct cli_state *cli,
- POLICY_HND *pol, uint32 *num_groups, DOM_GID *gid)
+BOOL samr_unknown_2d( const POLICY_HND *domain_pol,
+ const DOM_SID *sid)
{
+ pstring sid_str;
prs_struct data;
prs_struct rdata;
- SAMR_Q_QUERY_USERGROUPS q_o;
- SAMR_R_QUERY_USERGROUPS r_o;
- if (pol == NULL || gid == NULL || num_groups == 0)
- return False;
+ SAMR_Q_UNKNOWN_2D q_o;
+ BOOL valid_pol = False;
- /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
+ if (DEBUGLEVEL >= 4)
+ {
+ sid_to_string(sid_str, sid);
+ DEBUG(4,("SAMR Unknown 0x2d. SID:%s\n", sid_str));
+ }
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ if (sid == NULL || domain_pol == NULL) return False;
- DEBUG(4,("SAMR Query User Groups.\n"));
+ /* create and send a MSRPC command with api SAMR_UNKNOWN_2D */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
/* store the parameters */
- init_samr_q_query_usergroups(&q_o, pol);
+ make_samr_q_unknown_2d(&q_o, domain_pol, sid);
/* turn parameters into data stream */
- if(!samr_io_q_query_usergroups("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ if (samr_io_q_unknown_2d("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(domain_pol, SAMR_UNKNOWN_2D, &data, &rdata))
+ {
+ SAMR_R_UNKNOWN_2D r_o;
+ BOOL p;
+
+ samr_io_r_unknown_2d("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_UNKNOWN_2D: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_pol = True;
+ }
}
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Open Domain
+****************************************************************************/
+BOOL samr_open_domain( const POLICY_HND *connect_pol,
+ uint32 ace_perms,
+ const DOM_SID *sid,
+ POLICY_HND *domain_pol)
+{
+ pstring sid_str;
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_OPEN_DOMAIN q_o;
+ BOOL valid_pol = False;
+
+ if (DEBUGLEVEL >= 4)
+ {
+ sid_to_string(sid_str, sid);
+ DEBUG(4,("SAMR Open Domain. SID:%s Permissions:%x\n",
+ sid_str, ace_perms));
}
- prs_mem_free(&data);
+ if (connect_pol == NULL || sid == NULL || domain_pol == NULL) return False;
- /* get user info */
- r_o.gid = gid;
+ /* create and send a MSRPC command with api SAMR_OPEN_DOMAIN */
- if(!samr_io_r_query_usergroups("", &r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_open_domain(&q_o, connect_pol, ace_perms, sid);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_open_domain("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(connect_pol, SAMR_OPEN_DOMAIN, &data, &rdata))
+ {
+ SAMR_R_OPEN_DOMAIN r_o;
+ BOOL p;
+
+ samr_io_r_open_domain("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_OPEN_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ memcpy(domain_pol, &r_o.domain_pol, sizeof(r_o.domain_pol));
+ valid_pol = cli_pol_link(domain_pol, connect_pol);
+ }
}
+
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SAMR Query Lookup Domain
+****************************************************************************/
+BOOL samr_query_lookup_domain( POLICY_HND *pol, const char *dom_name,
+ DOM_SID *dom_sid)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_LOOKUP_DOMAIN q_o;
+ BOOL valid_query = False;
+
+ if (pol == NULL || dom_name == NULL || dom_sid == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_LOOKUP_DOMAIN */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Query Lookup Domain.\n"));
+
+ /* store the parameters */
+ make_samr_q_lookup_domain(&q_o, pol, dom_name);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_lookup_domain("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_LOOKUP_DOMAIN, &data, &rdata))
+ {
+ SAMR_R_LOOKUP_DOMAIN r_o;
+ BOOL p;
+
+ samr_io_r_lookup_domain("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rdata);
- return False;
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_LOOKUP_DOMAIN: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p && r_o.ptr_sid != 0)
+ {
+ sid_copy(dom_sid, &r_o.dom_sid.sid);
+ valid_query = True;
+ }
}
- *num_groups = r_o.num_entries;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Query Lookup Names
+****************************************************************************/
+BOOL samr_query_lookup_names(const POLICY_HND *pol, uint32 flags,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids, uint32 **types)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_LOOKUP_NAMES q_o;
+ BOOL valid_query = False;
+
+ if (pol == NULL || flags == 0 || num_names == 0 || names == NULL ||
+ num_rids == NULL || rids == NULL || types == NULL ) return False;
+
+ *num_rids = 0;
+ *types = NULL;
+ *rids = NULL;
+
+ /* create and send a MSRPC command with api SAMR_LOOKUP_NAMES */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
- prs_mem_free(&rdata);
+ DEBUG(4,("SAMR Query Lookup NAMES.\n"));
- return True;
+ /* store the parameters */
+ make_samr_q_lookup_names(&q_o, pol, flags, num_names, names);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_lookup_names("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_LOOKUP_NAMES, &data, &rdata))
+ {
+ SAMR_R_LOOKUP_NAMES r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+ samr_io_r_lookup_names("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_LOOKUP_NAMES: %s\n", get_nt_error_msg(r_o.status)));
+ p = r_o.status == 0x107;
+ }
+
+ if (p)
+ {
+ if (r_o.ptr_rids != 0 && r_o.ptr_types != 0 &&
+ r_o.num_types1 == r_o.num_rids1)
+ {
+ uint32 i;
+
+ valid_query = True;
+ *num_rids = r_o.num_rids1;
+ *types = g_new(uint32, *num_rids);
+ *rids = g_new(uint32, *num_rids);
+
+ for (i = 0; i < r_o.num_rids1; i++)
+ {
+ (*rids)[i] = r_o.rids[i];
+ }
+ for (i = 0; i < r_o.num_types1; i++)
+ {
+ (*types)[i] = r_o.types[i];
+ }
+ }
+ else if (r_o.ptr_rids == 0 && r_o.ptr_types == 0)
+ {
+ valid_query = True;
+ *num_rids = 0;
+ }
+ else
+ {
+ p = False;
+ }
+ }
+
+ samr_free_r_lookup_names(&r_o);
+ }
+
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_query;
}
/****************************************************************************
-do a SAMR Query User Info
+do a SAMR Query Lookup RIDS
****************************************************************************/
-BOOL do_samr_query_userinfo(struct cli_state *cli,
- POLICY_HND *pol, uint16 switch_value, void* usr)
+BOOL samr_query_lookup_rids( const POLICY_HND *pol, uint32 flags,
+ uint32 num_rids, const uint32 *rids,
+ uint32 *num_names,
+ char ***names,
+ uint32 **type)
{
prs_struct data;
prs_struct rdata;
- SAMR_Q_QUERY_USERINFO q_o;
- SAMR_R_QUERY_USERINFO r_o;
- if (pol == NULL || usr == NULL || switch_value == 0)
- return False;
+ SAMR_Q_LOOKUP_RIDS q_o;
+ BOOL valid_query = False;
- /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
+ if (pol == NULL || flags == 0 || num_rids == 0 || rids == NULL ||
+ num_names == NULL || names == NULL || type == NULL ) return False;
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ /* create and send a MSRPC command with api SAMR_LOOKUP_RIDS */
- DEBUG(4,("SAMR Query User Info. level: %d\n", switch_value));
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4,("SAMR Query Lookup RIDs.\n"));
/* store the parameters */
- init_samr_q_query_userinfo(&q_o, pol, switch_value);
+ make_samr_q_lookup_rids(&q_o, pol, flags, num_rids, rids);
/* turn parameters into data stream */
- if(!samr_io_q_query_userinfo("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ if (samr_io_q_lookup_rids("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_LOOKUP_RIDS, &data, &rdata))
+ {
+ SAMR_R_LOOKUP_RIDS r_o;
+ BOOL p;
+ ZERO_STRUCT(r_o);
+
+ samr_io_r_lookup_rids("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_LOOKUP_RIDS: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ if (r_o.ptr_names != 0 && r_o.ptr_types != 0 &&
+ r_o.num_types1 == r_o.num_names1)
+ {
+ uint32 i;
+ valid_query = True;
+
+ (*num_names) = 0;
+ (*names) = NULL;
+
+ for (i = 0; i < r_o.num_names1; i++)
+ {
+ fstring tmp;
+ unistr2_to_ascii(tmp, &r_o.uni_name[i], sizeof(tmp)-1);
+ add_chars_to_array(num_names, names, tmp);
+ }
+
+ if ((*num_names) != 0)
+ {
+ (*type) = (uint32*)malloc((*num_names) * sizeof(**type));
+ }
+
+ for (i = 0; (*type) != NULL && i < r_o.num_types1; i++)
+ {
+ (*type)[i] = r_o.type[i];
+ }
+ }
+ else if (r_o.ptr_names == 0 && r_o.ptr_types == 0)
+ {
+ valid_query = True;
+ *num_names = 0;
+ *names = NULL;
+ *type = NULL;
+ }
+ else
+ {
+ p = False;
+ }
+ }
+
+ samr_free_r_lookup_rids(&r_o);
}
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Query Alias Members
+****************************************************************************/
+BOOL samr_query_aliasmem( const POLICY_HND *alias_pol,
+ uint32 *num_mem, DOM_SID2 *sid)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_ALIASMEM q_o;
+ BOOL valid_query = False;
+
+ DEBUG(4,("SAMR Query Alias Members.\n"));
+
+ if (alias_pol == NULL || sid == NULL || num_mem == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_QUERY_ALIASMEM */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_query_aliasmem(&q_o, alias_pol);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_query_aliasmem("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(alias_pol, SAMR_QUERY_ALIASMEM, &data, &rdata))
+ {
+ SAMR_R_QUERY_ALIASMEM r_o;
+ BOOL p;
+
+ /* get user info */
+ r_o.sid = sid;
+
+ samr_io_r_query_aliasmem("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_ALIASMEM: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p && r_o.ptr != 0)
+ {
+ valid_query = True;
+ *num_mem = r_o.num_sids;
+ }
+
}
- prs_mem_free(&data);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- /* get user info */
- r_o.info.id = usr;
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Query User Aliases
+****************************************************************************/
+BOOL samr_query_useraliases( const POLICY_HND *pol,
+ uint32 *ptr_sid, DOM_SID2 *sid,
+ uint32 *num_aliases, uint32 **rid)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_USERALIASES q_o;
+ BOOL valid_query = False;
+ ZERO_STRUCT(q_o);
+
+ DEBUG(4,("SAMR Query User Aliases.\n"));
+
+ if (pol == NULL || sid == NULL || rid == NULL || num_aliases == 0) return False;
+
+ /* create and send a MSRPC command with api SAMR_QUERY_USERALIASES */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_query_useraliases(&q_o, pol, ptr_sid, sid);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_query_useraliases("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_QUERY_USERALIASES, &data, &rdata))
+ {
+ SAMR_R_QUERY_USERALIASES r_o;
+ BOOL p;
+
+ r_o.rid = NULL;
+
+ samr_io_r_query_useraliases("", &r_o, &rdata, 0);
+ *rid = r_o.rid;
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_USERALIASES: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p && r_o.ptr != 0)
+ {
+ valid_query = True;
+ *num_aliases = r_o.num_entries;
+ }
- if(!samr_io_r_query_userinfo("", &r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
}
+
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Query Group Members
+****************************************************************************/
+BOOL samr_query_groupmem( POLICY_HND *group_pol,
+ uint32 *num_mem, uint32 **rid, uint32 **attr)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_GROUPMEM q_o;
+ BOOL valid_query = False;
+
+ DEBUG(4,("SAMR Query Group Members.\n"));
+
+ if (group_pol == NULL || rid == NULL || attr == NULL || num_mem == NULL) return False;
+
+ /* create and send a MSRPC command with api SAMR_QUERY_GROUPMEM */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_query_groupmem(&q_o, group_pol);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_query_groupmem("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(group_pol, SAMR_QUERY_GROUPMEM, &data, &rdata))
+ {
+ SAMR_R_QUERY_GROUPMEM r_o;
+ BOOL p;
+
+ r_o.rid = NULL;
+ r_o.attr = NULL;
+
+ samr_io_r_query_groupmem("", &r_o, &rdata, 0);
+ *rid = r_o.rid ;
+ *attr = r_o.attr;
+ p = rdata.offset != 0;
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rdata);
- return False;
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_GROUPMEM: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p && r_o.ptr != 0 &&
+ r_o.ptr_rids != 0 && r_o.ptr_attrs != 0 &&
+ r_o.num_rids == r_o.num_attrs)
+ {
+ valid_query = True;
+ *num_mem = r_o.num_rids;
+ }
+
}
- if (r_o.switch_value != switch_value) {
- DEBUG(0,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
- r_o.switch_value));
- prs_mem_free(&rdata);
- return False;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Query User Groups
+****************************************************************************/
+BOOL samr_query_usergroups( POLICY_HND *pol, uint32 *num_groups,
+ DOM_GID **gid)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_USERGROUPS q_o;
+ BOOL valid_query = False;
+
+ DEBUG(4,("SAMR Query User Groups.\n"));
+
+ if (pol == NULL || gid == NULL || num_groups == 0) return False;
+
+ /* create and send a MSRPC command with api SAMR_QUERY_USERGROUPS */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_query_usergroups(&q_o, pol);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_query_usergroups("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_QUERY_USERGROUPS, &data, &rdata))
+ {
+ SAMR_R_QUERY_USERGROUPS r_o;
+ BOOL p;
+
+ /* get user info */
+ r_o.gid = NULL;
+
+ samr_io_r_query_usergroups("", &r_o, &rdata, 0);
+ *gid = r_o.gid;
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_USERGROUPS: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p && r_o.ptr_0 != 0)
+ {
+ valid_query = True;
+ *num_groups = r_o.num_entries;
+ }
}
- if (r_o.ptr == 0) {
- prs_mem_free(&rdata);
- return False;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Query Group Info
+****************************************************************************/
+BOOL samr_query_groupinfo( POLICY_HND *pol,
+ uint16 switch_value, GROUP_INFO_CTR* ctr)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_GROUPINFO q_o;
+ BOOL valid_query = False;
+
+ DEBUG(4,("SAMR Query Group Info. level: %d\n", switch_value));
+
+ if (pol == NULL || ctr == NULL || switch_value == 0) return False;
+
+ /* create and send a MSRPC command with api SAMR_QUERY_GROUPINFO */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_query_groupinfo(&q_o, pol, switch_value);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_query_groupinfo("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_QUERY_GROUPINFO, &data, &rdata))
+ {
+ SAMR_R_QUERY_GROUPINFO r_o;
+ BOOL p;
+
+ /* get group info */
+ r_o.ctr = ctr;
+
+ samr_io_r_query_groupinfo("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_GROUPINFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p && r_o.ctr->switch_value1 != switch_value)
+ {
+ DEBUG(4,("SAMR_R_QUERY_GROUPINFO: received incorrect level %d\n",
+ r_o.ctr->switch_value1));
+ }
+
+ if (p && r_o.ptr != 0)
+ {
+ valid_query = True;
+ }
}
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ return valid_query;
}
/****************************************************************************
-do a SAMR Close
+do a SAMR Set User Info
****************************************************************************/
-BOOL do_samr_close(struct cli_state *cli, POLICY_HND *hnd)
+BOOL samr_set_userinfo2( POLICY_HND *pol, uint16 switch_value,
+ void* usr)
{
prs_struct data;
prs_struct rdata;
- SAMR_Q_CLOSE_HND q_c;
- SAMR_R_CLOSE_HND r_c;
- int i;
- if (hnd == NULL)
- return False;
+ SAMR_Q_SET_USERINFO2 q_o;
+ SAM_USERINFO_CTR ctr;
+ BOOL valid_query = False;
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ ctr.info.id = usr;
- /* create and send a MSRPC command with api SAMR_CLOSE_HND */
+ DEBUG(4,("SAMR Set User Info 2. level: %d\n", switch_value));
- DEBUG(4,("SAMR Close\n"));
+ if (pol == NULL || usr == NULL || switch_value == 0) return False;
+
+ /* create and send a MSRPC command with api SAMR_SET_USERINFO2 */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
/* store the parameters */
- init_samr_q_close_hnd(&q_c, hnd);
+ make_samr_q_set_userinfo2(&q_o, pol, switch_value, &ctr);
/* turn parameters into data stream */
- if(!samr_io_q_close_hnd("", &q_c, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ if (samr_io_q_set_userinfo2("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_SET_USERINFO2, &data, &rdata))
+ {
+ SAMR_R_SET_USERINFO2 r_o;
+ BOOL p;
+
+ samr_io_r_set_userinfo2("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_USERINFO2: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_query = True;
+ }
}
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Set User Info
+****************************************************************************/
+BOOL samr_set_userinfo( POLICY_HND *pol, uint16 switch_value, void* usr)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_SET_USERINFO q_o;
+ SAM_USERINFO_CTR ctr;
+ BOOL valid_query = False;
+
+ DEBUG(4,("SAMR Set User Info. level: %d\n", switch_value));
+
+ if (pol == NULL || usr == NULL || switch_value == 0) return False;
+
+ /* create and send a MSRPC command with api SAMR_SET_USERINFO */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ q_o.ctr = &ctr;
+
+ /* store the parameters */
+ make_samr_q_set_userinfo(&q_o, pol, switch_value, usr);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_set_userinfo("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_SET_USERINFO, &data, &rdata))
+ {
+ SAMR_R_SET_USERINFO r_o;
+ BOOL p;
+
+ samr_io_r_set_userinfo("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_query = True;
+ }
}
- prs_mem_free(&data);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- if(!samr_io_r_close_hnd("", &r_c, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Query User Info
+****************************************************************************/
+BOOL samr_query_userinfo( POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_USERINFO q_o;
+ BOOL valid_query = False;
+
+ DEBUG(4,("SAMR Query User Info. level: %d\n", switch_value));
+
+ if (pol == NULL || ctr == NULL || switch_value == 0) return False;
+
+ /* create and send a MSRPC command with api SAMR_QUERY_USERINFO */
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_query_userinfo(&q_o, pol, switch_value);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_query_userinfo("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol, SAMR_QUERY_USERINFO, &data, &rdata))
+ {
+ SAMR_R_QUERY_USERINFO r_o;
+ BOOL p;
+ ZERO_STRUCT(r_o);
+
+ r_o.ctr = ctr;
+
+ samr_io_r_query_userinfo("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_USERINFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p && r_o.ptr == 0)
+ {
+ p = False;
+ }
+
+ if (p && r_o.ctr->switch_value != switch_value)
+ {
+ DEBUG(4,("SAMR_R_QUERY_USERINFO: received incorrect level %d\n",
+ r_o.ctr->switch_value));
+ }
+
+ if (p && r_o.ptr != 0)
+ {
+ valid_query = True;
+ }
}
- if (r_c.status != 0) {
- /* report error code */
- DEBUG(0,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_query;
+}
+
+/****************************************************************************
+do a SAMR Close
+****************************************************************************/
+BOOL samr_close( POLICY_HND *hnd)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_CLOSE_HND q_c;
+ BOOL valid_close = False;
+
+ DEBUG(4,("SAMR Close\n"));
+
+ if (hnd == NULL) return False;
+
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* create and send a MSRPC command with api SAMR_CLOSE_HND */
+
+ /* store the parameters */
+ make_samr_q_close_hnd(&q_c, hnd);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_close_hnd("", &q_c, &data, 0) &&
+ rpc_hnd_pipe_req(hnd, SAMR_CLOSE_HND, &data, &rdata))
+ {
+ SAMR_R_CLOSE_HND r_c;
+ BOOL p;
+
+ samr_io_r_close_hnd("", &r_c, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_CLOSE_HND: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* check that the returned policy handle is all zeros */
+ uint32 i;
+ valid_close = True;
+
+ for (i = 0; i < sizeof(r_c.pol.data); i++)
+ {
+ if (r_c.pol.data[i] != 0)
+ {
+ valid_close = False;
+ break;
+ }
+ }
+ if (!valid_close)
+ {
+ DEBUG(4,("SAMR_CLOSE_HND: non-zero handle returned\n"));
+ }
+ }
+ }
+
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ close_policy_hnd(get_global_hnd_cache(), hnd);
+
+ return valid_close;
+}
+
+/****************************************************************************
+do a SAMR query display info
+****************************************************************************/
+BOOL samr_query_dispinfo( POLICY_HND *pol_domain, uint16 level,
+ uint32 *num_entries,
+ SAM_DISPINFO_CTR *ctr)
+{
+ prs_struct data;
+ prs_struct rdata;
+
+ SAMR_Q_QUERY_DISPINFO q_o;
+ BOOL valid_query = False;
+
+ DEBUG(4,("SAMR Query Display Info. level: %d\n", level));
+
+ if (pol_domain == NULL || num_entries == NULL || ctr == NULL ||
+ level == 0)
+ {
return False;
}
- /* check that the returned policy handle is all zeros */
+ /* create and send a MSRPC command with api SAMR_QUERY_DISPINFO */
- for (i = 0; i < sizeof(r_c.pol.data); i++) {
- if (r_c.pol.data[i] != 0) {
- DEBUG(0,("SAMR_CLOSE_HND: non-zero handle returned\n"));
- prs_mem_free(&rdata);
- return False;
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* store the parameters */
+ make_samr_q_query_dispinfo(&q_o, pol_domain, level, 0, 0xffffffff);
+
+ /* turn parameters into data stream */
+ if (samr_io_q_query_dispinfo("", &q_o, &data, 0) &&
+ rpc_hnd_pipe_req(pol_domain, SAMR_QUERY_DISPINFO, &data, &rdata))
+ {
+ SAMR_R_QUERY_DISPINFO r_o;
+ BOOL p;
+
+ /* get user info */
+ r_o.ctr = ctr;
+
+ samr_io_r_query_dispinfo("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(4,("SAMR_R_QUERY_DISPINFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
}
- }
- prs_mem_free(&rdata);
+ if (p && r_o.switch_level != level)
+ {
+ DEBUG(4,("SAMR_R_QUERY_DISPINFO: received incorrect level %d\n",
+ r_o.switch_level));
+ }
- return True;
+ if (p && r_o.ptr_entries != 0)
+ {
+ valid_query = True;
+ (*num_entries) = r_o.num_entries;
+ }
+ }
+
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ return valid_query;
}
+
diff --git a/source/rpc_client/cli_spoolss.c b/source/rpc_client/cli_spoolss.c
new file mode 100644
index 00000000000..66b479094c4
--- /dev/null
+++ b/source/rpc_client/cli_spoolss.c
@@ -0,0 +1,326 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+/****************************************************************************
+do a SPOOLSS Enum Printers
+****************************************************************************/
+BOOL spoolss_enum_printers(uint32 flags, const char *srv_name,
+ uint32 level,
+ uint32 *count,
+ void ***printers)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_ENUMPRINTERS q_o;
+ BOOL valid_pol = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+ {
+ return False;
+ }
+
+ if (count == NULL || printers == NULL) return False;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api SPOOLSS_ENUM_PRINTERS */
+
+ DEBUG(5,("SPOOLSS Enum Printers (Server: %s level: %d)\n",
+ srv_name, level));
+
+ make_spoolss_q_enumprinters(&q_o, flags, srv_name, level, 0x2000);
+
+ /* turn parameters into data stream */
+ if (spoolss_io_q_enumprinters("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SPOOLSS_ENUMPRINTERS, &buf, &rbuf))
+ {
+ SPOOL_R_ENUMPRINTERS r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ r_o.level = level; /* i can't believe you have to this */
+
+ spoolss_io_r_enumprinters("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(5,("SPOOLSS_ENUM_PRINTERS: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ (*count) = r_o.returned;
+ (*printers) = r_o.ctr.printer.info;
+ valid_pol = True;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ cli_connection_unlink(con);
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SPOOLSS Enum Jobs
+****************************************************************************/
+uint32 spoolss_enum_jobs( const POLICY_HND *hnd,
+ uint32 firstjob,
+ uint32 numofjobs,
+ uint32 level,
+ uint32 *buf_size,
+ uint32 *count,
+ void ***jobs)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_ENUMJOBS q_o;
+ uint32 status = NT_STATUS_INTERNAL_ERROR;
+
+ if (hnd == NULL || count == NULL || jobs == NULL)
+ {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api SPOOLSS_ENUMJOBS */
+
+ DEBUG(5,("SPOOLSS Enum Jobs level: %d)\n", level));
+
+ make_spoolss_q_enumjobs(&q_o, hnd,
+ firstjob, numofjobs,
+ level, *buf_size);
+
+ /* turn parameters into data stream */
+ if (spoolss_io_q_enumjobs("", &q_o, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, SPOOLSS_ENUMJOBS, &buf, &rbuf))
+ {
+ SPOOL_R_ENUMJOBS r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ r_o.level = level; /* i can't believe you have to this */
+
+ spoolss_io_r_enumjobs("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ status = r_o.status;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(5,("SPOOLSS_ENUM_JOBS: %s\n", get_nt_error_msg(r_o.status)));
+ p = status = ERROR_INSUFFICIENT_BUFFER;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ (*count) = r_o.numofjobs;
+ (*jobs) = r_o.ctr.job.info;
+ (*buf_size) = r_o.offered;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return status;
+}
+
+/****************************************************************************
+do a SPOOLSS Open Printer Ex
+****************************************************************************/
+BOOL spoolss_open_printer_ex( const char *printername,
+ uint32 cbbuf, uint32 devmod, uint32 des_access,
+ const char *station, const char *username,
+ POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_OPEN_PRINTER_EX q_o;
+ BOOL valid_pol = False;
+ fstring srv_name;
+ char *s;
+
+ struct cli_connection *con = NULL;
+
+ memset(srv_name, 0, sizeof(srv_name));
+ fstrcpy(srv_name, printername);
+
+ s = strchr(&srv_name[2], '\\');
+
+ if (s != NULL)
+ {
+ *s = 0;
+ }
+
+ if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
+ {
+ return False;
+ }
+
+ if (hnd == NULL) return False;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api SPOOLSS_OPENPRINTEREX */
+
+ DEBUG(5,("SPOOLSS Open Printer Ex\n"));
+
+ make_spoolss_q_open_printer_ex(&q_o, printername,
+ cbbuf, devmod, des_access,
+ station, username);
+
+ /* turn parameters into data stream */
+ if (spoolss_io_q_open_printer_ex("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SPOOLSS_OPENPRINTEREX, &buf, &rbuf))
+ {
+ SPOOL_R_OPEN_PRINTER_EX r_o;
+ BOOL p;
+
+ spoolss_io_r_open_printer_ex("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(5,("SPOOLSS_OPENPRINTEREX: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.handle;
+
+ valid_pol = register_policy_hnd(get_global_hnd_cache(),
+ cli_con_sec_ctx(con),
+ hnd, des_access) &&
+ set_policy_con(get_global_hnd_cache(),
+ hnd, con,
+ cli_connection_unlink);
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return valid_pol;
+}
+
+/****************************************************************************
+do a SPOOL Close
+****************************************************************************/
+BOOL spoolss_closeprinter(POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SPOOL_Q_CLOSEPRINTER q_c;
+ BOOL valid_close = False;
+
+ if (hnd == NULL) return False;
+
+ /* create and send a MSRPC command with api SPOOLSS_CLOSEPRINTER */
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ DEBUG(4,("SPOOL Close Printer\n"));
+
+ /* store the parameters */
+ make_spoolss_q_closeprinter(&q_c, hnd);
+
+ /* turn parameters into data stream */
+ if (spoolss_io_q_closeprinter("", &q_c, &buf, 0) &&
+ rpc_hnd_pipe_req(hnd, SPOOLSS_CLOSEPRINTER, &buf, &rbuf))
+ {
+ SPOOL_R_CLOSEPRINTER r_c;
+ BOOL p;
+
+ spoolss_io_r_closeprinter("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SPOOL_CLOSEPRINTER: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* check that the returned policy handle is all zeros */
+ uint32 i;
+ valid_close = True;
+
+ for (i = 0; i < sizeof(r_c.handle.data); i++)
+ {
+ if (r_c.handle.data[i] != 0)
+ {
+ valid_close = False;
+ break;
+ }
+ }
+ if (!valid_close)
+ {
+ DEBUG(0,("SPOOL_CLOSEPRINTER: non-zero handle returned\n"));
+ }
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ close_policy_hnd(get_global_hnd_cache(), hnd);
+
+ return valid_close;
+}
+
diff --git a/source/rpc_client/cli_srvsvc.c b/source/rpc_client/cli_srvsvc.c
index b883cc19425..327db0086f4 100644
--- a/source/rpc_client/cli_srvsvc.c
+++ b/source/rpc_client/cli_srvsvc.c
@@ -6,7 +6,6 @@
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jeremy Allison 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,94 +28,179 @@
#endif
#include "includes.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
/****************************************************************************
-do a server net conn enum
+do a server net tprt enum
****************************************************************************/
-BOOL do_srv_net_srv_conn_enum(struct cli_state *cli,
- char *server_name, char *qual_name,
- uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
+BOOL srv_net_srv_tprt_enum(
+ const char *srv_name,
+ uint32 switch_value, SRV_TPRT_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd)
{
prs_struct data;
prs_struct rdata;
- SRV_Q_NET_CONN_ENUM q_o;
- SRV_R_NET_CONN_ENUM r_o;
+ SRV_Q_NET_TPRT_ENUM q_o;
+ BOOL valid_enum = False;
+ struct cli_connection *con = NULL;
- if (server_name == NULL || ctr == NULL || preferred_len == 0)
+ if (ctr == NULL || preferred_len == 0) return False;
+
+ if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
+ {
return False;
+ }
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
- /* create and send a MSRPC command with api SRV_NETCONNENUM */
+ /* create and send a MSRPC command with api SRV_NETTPRTENUM */
- DEBUG(4,("SRV Net Server Connection Enum(%s, %s), level %d, enum:%8x\n",
- server_name, qual_name, switch_value, get_enum_hnd(hnd)));
+ DEBUG(4,("SRV Net Server Transport Enum, level %d, enum:%8x\n",
+ switch_value, get_enum_hnd(hnd)));
ctr->switch_value = switch_value;
- ctr->ptr_conn_ctr = 1;
- ctr->conn.info0.num_entries_read = 0;
- ctr->conn.info0.ptr_conn_info = 1;
+ ctr->ptr_tprt_ctr = 1;
+ ctr->tprt.info0.num_entries_read = 0;
+ ctr->tprt.info0.ptr_tprt_info = 1;
/* store the parameters */
- init_srv_q_net_conn_enum(&q_o, server_name, qual_name,
+ make_srv_q_net_tprt_enum(&q_o, srv_name,
switch_value, ctr,
preferred_len,
hnd);
/* turn parameters into data stream */
- if(!srv_io_q_net_conn_enum("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ if (srv_io_q_net_tprt_enum("", &q_o, &data, 0) &&
+ rpc_con_pipe_req(con, SRV_NETTRANSPORTENUM, &data, &rdata))
+ {
+ SRV_R_NET_TPRT_ENUM r_o;
+ BOOL p;
- /* send the data on \PIPE\ */
- if(!rpc_api_pipe_req(cli, SRV_NETCONNENUM, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ r_o.ctr = ctr;
+
+ srv_io_r_net_tprt_enum("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_TPRT_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_enum = True;
+ }
}
- prs_mem_free(&data);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ cli_connection_unlink(con);
- r_o.ctr = ctr;
+ return valid_enum;
+}
- if(!srv_io_r_net_conn_enum("", &r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
- }
+/****************************************************************************
+do a server net conn enum
+****************************************************************************/
+BOOL srv_net_srv_conn_enum( char *srv_name, char *qual_name,
+ uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
+{
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_CONN_ENUM q_o;
+ BOOL valid_enum = False;
+ struct cli_connection *con = NULL;
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rdata);
+ if (ctr == NULL || preferred_len == 0) return False;
+
+ if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
+ {
return False;
}
- if (r_o.ctr->switch_value != switch_value) {
- /* different switch levels. oops. */
- DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: info class %d does not match request %d\n",
- r_o.ctr->switch_value, switch_value));
- prs_mem_free(&rdata);
- return False;
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* create and send a MSRPC command with api SRV_NETCONNENUM */
+
+ DEBUG(4,("SRV Net Server Connection Enum %s), level %d, enum:%8x\n",
+ qual_name, switch_value, get_enum_hnd(hnd)));
+
+ ctr->switch_value = switch_value;
+ ctr->ptr_conn_ctr = 1;
+ ctr->conn.info0.num_entries_read = 0;
+ ctr->conn.info0.ptr_conn_info = 1;
+
+ /* store the parameters */
+ make_srv_q_net_conn_enum(&q_o, srv_name, qual_name,
+ switch_value, ctr,
+ preferred_len,
+ hnd);
+
+ /* turn parameters into data stream */
+ if (srv_io_q_net_conn_enum("", &q_o, &data, 0) &&
+ rpc_con_pipe_req(con, SRV_NETCONNENUM, &data, &rdata))
+ {
+ SRV_R_NET_CONN_ENUM r_o;
+ BOOL p;
+
+ r_o.ctr = ctr;
+
+ srv_io_r_net_conn_enum("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_CONN_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_enum = True;
+ }
}
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ cli_connection_unlink(con);
+
+ return valid_enum;
}
/****************************************************************************
do a server net sess enum
****************************************************************************/
-
-BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
- char *server_name, char *qual_name,
+BOOL srv_net_srv_sess_enum( char *srv_name, char *qual_name, char *user_name,
uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd)
@@ -124,18 +208,23 @@ BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
prs_struct data;
prs_struct rdata;
SRV_Q_NET_SESS_ENUM q_o;
- SRV_R_NET_SESS_ENUM r_o;
+ BOOL valid_enum = False;
+ struct cli_connection *con = NULL;
- if (server_name == NULL || ctr == NULL || preferred_len == 0)
+ if (ctr == NULL || preferred_len == 0) return False;
+
+ if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
+ {
return False;
+ }
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
/* create and send a MSRPC command with api SRV_NETSESSENUM */
- DEBUG(4,("SRV Net Session Enum (%s), level %d, enum:%8x\n",
- server_name, switch_value, get_enum_hnd(hnd)));
+ DEBUG(4,("SRV Net Session Enum, level %d, enum:%8x\n",
+ switch_value, get_enum_hnd(hnd)));
ctr->switch_value = switch_value;
ctr->ptr_sess_ctr = 1;
@@ -143,130 +232,195 @@ BOOL do_srv_net_srv_sess_enum(struct cli_state *cli,
ctr->sess.info0.ptr_sess_info = 1;
/* store the parameters */
- init_srv_q_net_sess_enum(&q_o, server_name, qual_name,
+ make_srv_q_net_sess_enum(&q_o, srv_name, qual_name, user_name,
switch_value, ctr,
preferred_len,
hnd);
/* turn parameters into data stream */
- if(!srv_io_q_net_sess_enum("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ if (srv_io_q_net_sess_enum("", &q_o, &data, 0) &&
+ rpc_con_pipe_req(con, SRV_NETSESSENUM, &data, &rdata))
+ {
+ SRV_R_NET_SESS_ENUM r_o;
+ BOOL p;
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SRV_NETSESSENUM, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ r_o.ctr = ctr;
- prs_mem_free(&data);
-
- r_o.ctr = ctr;
-
- if(!srv_io_r_net_sess_enum("", &r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
- }
+ srv_io_r_net_sess_enum("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rdata);
- return False;
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_enum = True;
+ }
}
- if (r_o.ctr->switch_value != switch_value) {
- /* different switch levels. oops. */
- DEBUG(0,("SRV_R_NET_SRV_SESS_ENUM: info class %d does not match request %d\n",
- r_o.ctr->switch_value, switch_value));
- prs_mem_free(&rdata);
- return False;
- }
-
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ cli_connection_unlink(con);
+
+ return valid_enum;
}
/****************************************************************************
do a server net share enum
****************************************************************************/
-BOOL do_srv_net_srv_share_enum(struct cli_state *cli,
- char *server_name,
- uint32 switch_value, SRV_R_NET_SHARE_ENUM *r_o,
- uint32 preferred_len, ENUM_HND *hnd)
+BOOL srv_net_srv_share_enum( char *srv_name,
+ uint32 switch_value, SRV_SHARE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
{
prs_struct data;
prs_struct rdata;
SRV_Q_NET_SHARE_ENUM q_o;
+ BOOL valid_enum = False;
+ struct cli_connection *con = NULL;
+
+ if (ctr == NULL || preferred_len == 0) return False;
- if (server_name == NULL || preferred_len == 0)
+ if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
+ {
return False;
+ }
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
/* create and send a MSRPC command with api SRV_NETSHAREENUM */
- DEBUG(4,("SRV Get Share Info (%s), level %d, enum:%8x\n",
- server_name, switch_value, get_enum_hnd(hnd)));
+ DEBUG(4,("SRV Get Share Info, level %d, enum:%8x\n",
+ switch_value, get_enum_hnd(hnd)));
+ q_o.share_level = switch_value;
+
+ ctr->switch_value = switch_value;
+ ctr->ptr_share_ctr = 1;
+ ctr->share.info1.num_entries_read = 0;
+ ctr->share.info1.ptr_share_info = 1;
+
/* store the parameters */
- init_srv_q_net_share_enum(&q_o, server_name, switch_value,
- preferred_len, hnd);
+ make_srv_q_net_share_enum(&q_o, srv_name,
+ switch_value, ctr,
+ preferred_len,
+ hnd);
/* turn parameters into data stream */
- if(!srv_io_q_net_share_enum("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ if (srv_io_q_net_share_enum("", &q_o, &data, 0) &&
+ rpc_con_pipe_req(con, SRV_NETSHAREENUM, &data, &rdata))
+ {
+ SRV_R_NET_SHARE_ENUM r_o;
+ BOOL p;
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SRV_NETSHAREENUM, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ r_o.ctr = ctr;
+
+ srv_io_r_net_share_enum("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_SHARE_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_enum = True;
+ }
}
- prs_mem_free(&data);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ cli_connection_unlink(con);
- if(!srv_io_r_net_share_enum("", r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
- }
-
- if (r_o->status != 0) {
- /* report error code */
- DEBUG(0,("SRV_R_NET_SHARE_ENUM: %s\n", get_nt_error_msg(r_o->status)));
- prs_mem_free(&rdata);
- free_srv_r_net_share_enum(r_o);
+ return valid_enum;
+}
+
+/****************************************************************************
+do a share get info
+****************************************************************************/
+BOOL srv_net_srv_share_get_info(const char *srv_name,
+ const char *share_name,
+ uint32 info_level)
+{
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_SHARE_GET_INFO q_o;
+ struct cli_connection *con = NULL;
+ UNISTR2 uni_srv_name;
+ UNISTR2 uni_share_name;
+ BOOL valid_result = False;
+
+ if (srv_name == NULL || share_name == NULL) return False;
+
+ if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
+ {
return False;
}
- if (r_o->ctr.switch_value != switch_value) {
- /* different switch levels. oops. */
- DEBUG(0,("SRV_R_NET_SHARE_ENUM: info class %d does not match request %d\n",
- r_o->ctr.switch_value, switch_value));
- prs_mem_free(&rdata);
- free_srv_r_net_share_enum(r_o);
- return False;
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ DEBUG(4, ("SRV Get Share Info, share:%s, level %d\n",
+ share_name, info_level));
+
+ make_unistr2(&uni_srv_name, srv_name, strlen(srv_name) + 1);
+ make_unistr2(&uni_share_name, share_name, strlen(share_name) + 1);
+
+ /* store the parameters */
+ make_srv_q_net_share_get_info(&q_o, &uni_srv_name, &uni_share_name,
+ info_level);
+
+ /* turn parameters into data stream */
+ if (srv_io_q_net_share_get_info("", &q_o, &data, 0) &&
+ rpc_con_pipe_req(con, SRV_NETSHAREGETINFO, &data, &rdata))
+ {
+ SRV_R_NET_SHARE_GET_INFO r_o;
+
+ srv_io_r_net_share_get_info("", &r_o, &rdata, 0);
+
+ valid_result = False;
}
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ cli_connection_unlink(con);
+
+ return valid_result;
}
/****************************************************************************
do a server net file enum
****************************************************************************/
-
-BOOL do_srv_net_srv_file_enum(struct cli_state *cli,
- char *server_name, char *qual_name,
+BOOL srv_net_srv_file_enum( char *srv_name, char *qual_name, uint32 file_id,
uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd)
@@ -274,18 +428,23 @@ BOOL do_srv_net_srv_file_enum(struct cli_state *cli,
prs_struct data;
prs_struct rdata;
SRV_Q_NET_FILE_ENUM q_o;
- SRV_R_NET_FILE_ENUM r_o;
+ BOOL valid_enum = False;
+ struct cli_connection *con = NULL;
+
+ if (ctr == NULL || preferred_len == 0) return False;
- if (server_name == NULL || ctr == NULL || preferred_len == 0)
+ if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
+ {
return False;
+ }
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
/* create and send a MSRPC command with api SRV_NETFILEENUM */
- DEBUG(4,("SRV Get File Info (%s), level %d, enum:%8x\n",
- server_name, switch_value, get_enum_hnd(hnd)));
+ DEBUG(4,("SRV Get File Info level %d, enum:%8x\n",
+ switch_value, get_enum_hnd(hnd)));
q_o.file_level = switch_value;
@@ -295,117 +454,183 @@ BOOL do_srv_net_srv_file_enum(struct cli_state *cli,
ctr->file.info3.ptr_file_info = 1;
/* store the parameters */
- init_srv_q_net_file_enum(&q_o, server_name, qual_name,
+ make_srv_q_net_file_enum(&q_o, srv_name, qual_name, file_id,
switch_value, ctr,
preferred_len,
hnd);
/* turn parameters into data stream */
- if(!srv_io_q_net_file_enum("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SRV_NETFILEENUM, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ if (srv_io_q_net_file_enum("", &q_o, &data, 0) &&
+ rpc_con_pipe_req(con, SRV_NETFILEENUM, &data, &rdata))
+ {
+ SRV_R_NET_FILE_ENUM r_o;
+ BOOL p;
- prs_mem_free(&data);
+ r_o.ctr = ctr;
- r_o.ctr = ctr;
-
- if(!srv_io_r_net_file_enum("", &r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
- }
+ srv_io_r_net_file_enum("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("SRV_R_NET_FILE_ENUM: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rdata);
- return False;
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_FILE_ENUM: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_enum = True;
+ }
}
- if (r_o.ctr->switch_value != switch_value) {
- /* different switch levels. oops. */
- DEBUG(0,("SRV_R_NET_FILE_ENUM: info class %d does not match request %d\n",
- r_o.ctr->switch_value, switch_value));
- prs_mem_free(&rdata);
- return False;
- }
-
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ cli_connection_unlink(con);
+
+ return valid_enum;
}
/****************************************************************************
do a server get info
****************************************************************************/
-BOOL do_srv_net_srv_get_info(struct cli_state *cli,
- char *server_name, uint32 switch_value, SRV_INFO_CTR *ctr)
+BOOL srv_net_srv_get_info( char *srv_name, uint32 switch_value,
+ SRV_INFO_CTR *ctr)
{
prs_struct data;
prs_struct rdata;
SRV_Q_NET_SRV_GET_INFO q_o;
- SRV_R_NET_SRV_GET_INFO r_o;
+ BOOL valid_info = False;
+ struct cli_connection *con = NULL;
+
+ if (switch_value == 0 || ctr == NULL) return False;
- if (server_name == NULL || switch_value == 0 || ctr == NULL)
+ if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
+ {
return False;
+ }
- prs_init(&data , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rdata, 0, 4, UNMARSHALL);
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
/* create and send a MSRPC command with api SRV_NET_SRV_GET_INFO */
- DEBUG(4,("SRV Get Server Info (%s), level %d\n", server_name, switch_value));
+ DEBUG(4,("SRV Get Server Info level %d\n", switch_value));
/* store the parameters */
- init_srv_q_net_srv_get_info(&q_o, server_name, switch_value);
+ make_srv_q_net_srv_get_info(&q_o, srv_name, switch_value);
/* turn parameters into data stream */
- if(!srv_io_q_net_srv_get_info("", &q_o, &data, 0)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
- }
+ if (srv_io_q_net_srv_get_info("", &q_o, &data, 0) &&
+ rpc_con_pipe_req(con, SRV_NET_SRV_GET_INFO, &data, &rdata))
+ {
+ SRV_R_NET_SRV_GET_INFO r_o;
+ BOOL p;
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &data, &rdata)) {
- prs_mem_free(&data);
- prs_mem_free(&rdata);
- return False;
+ r_o.ctr = ctr;
+
+ srv_io_r_net_srv_get_info("", &r_o, &rdata, 0);
+ p = rdata.offset != 0;
+ p = rdata.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = 0;
+ }
+
+ if (p && r_o.ctr->switch_value != q_o.switch_value)
+ {
+ /* different switch levels. oops. */
+ DEBUG(0,("SRV_R_NET_SRV_GET_INFO: info class %d does not match request %d\n",
+ r_o.ctr->switch_value, q_o.switch_value));
+ p = 0;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. */
+ valid_info = True;
+ }
}
- prs_mem_free(&data);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
+
+ cli_connection_unlink(con);
- r_o.ctr = ctr;
+ return valid_info;
+}
- if(!srv_io_r_net_srv_get_info("", &r_o, &rdata, 0)) {
- prs_mem_free(&rdata);
- return False;
- }
+/****************************************************************************
+get server time
+****************************************************************************/
+BOOL srv_net_remote_tod( char *srv_name, TIME_OF_DAY_INFO *tod)
+{
+ prs_struct data;
+ prs_struct rdata;
+ SRV_Q_NET_REMOTE_TOD q_t;
+ BOOL valid_info = False;
+ struct cli_connection *con = NULL;
+
+ if (tod == NULL) return False;
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("SRV_R_NET_SRV_GET_INFO: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rdata);
+ if (!cli_connection_init(srv_name, PIPE_SRVSVC, &con))
+ {
return False;
}
- if (r_o.ctr->switch_value != q_o.switch_value) {
- /* different switch levels. oops. */
- DEBUG(0,("SRV_R_NET_SRV_GET_INFO: info class %d does not match request %d\n",
- r_o.ctr->switch_value, q_o.switch_value));
- prs_mem_free(&rdata);
- return False;
+ prs_init(&data , 0, 4, False);
+ prs_init(&rdata, 0, 4, True );
+
+ /* create and send a MSRPC command with api SRV_NET_REMOTE_TOD */
+
+ DEBUG(4,("SRV Remote TOD (%s)\n", srv_name));
+
+ /* store the parameters */
+ make_srv_q_net_remote_tod(&q_t, srv_name);
+
+ /* turn parameters into data stream */
+ if (srv_io_q_net_remote_tod("", &q_t, &data, 0) &&
+ rpc_con_pipe_req(con, SRV_NET_REMOTE_TOD, &data, &rdata))
+ {
+ SRV_R_NET_REMOTE_TOD r_t;
+ BOOL p;
+
+ r_t.tod = tod;
+
+ srv_io_r_net_remote_tod("", &r_t, &rdata, 0);
+ p = rdata.offset != 0;
+ p = rdata.offset != 0;
+
+ if (p && r_t.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("SRV_R_NET_REMOTE_TOD: %s\n", get_nt_error_msg(r_t.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_info = True;
+ }
}
- prs_mem_free(&rdata);
+ prs_free_data(&data );
+ prs_free_data(&rdata );
- return True;
+ cli_connection_unlink(con);
+
+ return valid_info;
}
diff --git a/source/rpc_client/cli_svcctl.c b/source/rpc_client/cli_svcctl.c
new file mode 100644
index 00000000000..533656c620e
--- /dev/null
+++ b/source/rpc_client/cli_svcctl.c
@@ -0,0 +1,593 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1998,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ * Copyright (C) Paul Ashton 1997-1998.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+do a SVC Open Policy
+****************************************************************************/
+BOOL svc_open_sc_man( const char *srv_name, char *db_name,
+ uint32 des_access,
+ POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SVC_Q_OPEN_SC_MAN q_o;
+ BOOL valid_pol = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_init(srv_name, PIPE_SVCCTL, &con))
+ {
+ return False;
+ }
+
+ if (hnd == NULL) return False;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api SVC_OPEN_SC_MAN */
+
+ DEBUG(4,("SVC Open SC_MAN\n"));
+
+ make_svc_q_open_sc_man(&q_o, srv_name, db_name, des_access);
+
+ /* turn parameters into data stream */
+ if (svc_io_q_open_sc_man("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SVC_OPEN_SC_MAN, &buf, &rbuf))
+ {
+ SVC_R_OPEN_SC_MAN r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ svc_io_r_open_sc_man("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(1,("SVC_OPEN_SC_MAN: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.pol;
+ valid_pol = True;
+ valid_pol = register_policy_hnd(get_global_hnd_cache(),
+ cli_con_sec_ctx(con),
+ hnd, des_access) &&
+ set_policy_con(get_global_hnd_cache(), hnd, con,
+ cli_connection_unlink);
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return valid_pol;
+}
+
+
+/****************************************************************************
+do a SVC Open Service
+****************************************************************************/
+BOOL svc_open_service( POLICY_HND *scm_hnd,
+ const char *srv_name,
+ uint32 des_access,
+ POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SVC_Q_OPEN_SERVICE q_o;
+ BOOL valid_pol = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(scm_hnd, &con))
+ {
+ return False;
+ }
+
+ if (hnd == NULL || scm_hnd == NULL) return False;
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api SVC_OPEN_SERVICE */
+
+ DEBUG(4,("SVC Open Service\n"));
+
+ make_svc_q_open_service(&q_o, scm_hnd, srv_name, des_access);
+
+ /* turn parameters into data stream */
+ if (svc_io_q_open_service("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SVC_OPEN_SERVICE, &buf, &rbuf))
+ {
+ SVC_R_OPEN_SERVICE r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ svc_io_r_open_service("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(1,("SVC_OPEN_SC_MAN: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* ok, at last: we're happy. return the policy handle */
+ *hnd = r_o.pol;
+ valid_pol = register_policy_hnd(get_global_hnd_cache(),
+ cli_con_sec_ctx(con),
+ hnd, des_access) &&
+ set_policy_con(get_global_hnd_cache(), hnd, con, NULL);
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return valid_pol;
+}
+
+
+/****************************************************************************
+do a SVC Enumerate Services
+****************************************************************************/
+BOOL svc_enum_svcs( POLICY_HND *hnd,
+ uint32 services_type, uint32 services_state,
+ uint32 *buf_size, uint32 *resume_hnd,
+ uint32 *dos_error,
+ ENUM_SRVC_STATUS **svcs, uint32 *num_svcs)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SVC_Q_ENUM_SVCS_STATUS q_o;
+ BOOL valid_pol = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(hnd, &con))
+ {
+ return False;
+ }
+
+ if (hnd == NULL || buf_size == NULL || dos_error == NULL || num_svcs == NULL)
+ {
+ return False;
+ }
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ /* create and send a MSRPC command with api SVC_ENUM_SVCS_STATUS */
+
+ DEBUG(4,("SVC Enum Services Status\n"));
+
+ make_svc_q_enum_svcs_status(&q_o, hnd,
+ services_type, services_state,
+ *buf_size, *resume_hnd);
+
+ /* turn parameters into data stream */
+ if (svc_io_q_enum_svcs_status("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, SVC_ENUM_SVCS_STATUS, &buf, &rbuf))
+ {
+ SVC_R_ENUM_SVCS_STATUS r_o;
+ BOOL p;
+
+ ZERO_STRUCT(r_o);
+
+ svc_io_r_enum_svcs_status("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.dos_status != 0)
+ {
+ fstring errmsg;
+
+ if (r_o.dos_status != ERRmoredata)
+ {
+ smb_safe_err_msg(ERRDOS, r_o.dos_status,
+ errmsg, sizeof(errmsg));
+ /* report error code */
+ DEBUG(1,("SVC_ENUM_SVCS_STATUS: %s\n", errmsg));
+ }
+ p = r_o.dos_status == ERRmoredata;
+ }
+
+ if (p)
+ {
+ (*svcs) = r_o.svcs;
+ (*num_svcs) = r_o.num_svcs;
+ (*resume_hnd) = get_enum_hnd(&r_o.resume_hnd);
+ (*buf_size) = r_o.more_buf_size;
+ (*dos_error) = r_o.dos_status;
+ valid_pol = True;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return valid_pol;
+}
+
+
+/****************************************************************************
+do a SVC Stop Service
+****************************************************************************/
+BOOL svc_stop_service( POLICY_HND *hnd,
+ uint32 unknown)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SVC_Q_STOP_SERVICE q_c;
+ BOOL valid_cfg = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(hnd, &con))
+ {
+ return False;
+ }
+
+ if (hnd == NULL) return False;
+
+ /* create and send a MSRPC command with api SVC_STOP_SERVICE */
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ DEBUG(4,("SVC Stop Service\n"));
+
+ /* store the parameters */
+ make_svc_q_stop_service(&q_c, hnd, unknown);
+
+ /* turn parameters into data stream */
+ if (svc_io_q_stop_service("", &q_c, &buf, 0) &&
+ rpc_con_pipe_req(con, SVC_STOP_SERVICE, &buf, &rbuf))
+ {
+ SVC_R_STOP_SERVICE r_c;
+ BOOL p;
+
+ ZERO_STRUCT (r_c);
+
+ svc_io_r_stop_service("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(1,("SVC_START_SERVICE: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_cfg = True;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return valid_cfg;
+}
+
+
+/****************************************************************************
+do a SVC Start Service
+****************************************************************************/
+BOOL svc_start_service( POLICY_HND *hnd,
+ uint32 argc,
+ char **argv)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SVC_Q_START_SERVICE q_c;
+ BOOL valid_cfg = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(hnd, &con))
+ {
+ return False;
+ }
+
+ if (hnd == NULL) return False;
+
+ /* create and send a MSRPC command with api SVC_START_SERVICE */
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ DEBUG(4,("SVC Start Service\n"));
+
+ /* store the parameters */
+ make_svc_q_start_service(&q_c, hnd, argc, argv);
+
+ /* turn parameters into data stream */
+ if (svc_io_q_start_service("", &q_c, &buf, 0) &&
+ rpc_con_pipe_req(con, SVC_START_SERVICE, &buf, &rbuf))
+ {
+ SVC_R_START_SERVICE r_c;
+ BOOL p;
+
+ ZERO_STRUCT (r_c);
+
+ svc_io_r_start_service("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(1,("SVC_START_SERVICE: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_cfg = True;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return valid_cfg;
+}
+
+
+/****************************************************************************
+do a SVC Query Service Config
+****************************************************************************/
+BOOL svc_query_svc_cfg( POLICY_HND *hnd,
+ QUERY_SERVICE_CONFIG *cfg,
+ uint32 *buf_size)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SVC_Q_QUERY_SVC_CONFIG q_c;
+ BOOL valid_cfg = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(hnd, &con))
+ {
+ return False;
+ }
+
+ if (hnd == NULL || buf_size == NULL) return False;
+
+ /* create and send a MSRPC command with api SVC_QUERY_SVC_CONFIG */
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ DEBUG(4,("SVC Query Service Config\n"));
+
+ /* store the parameters */
+ make_svc_q_query_svc_config(&q_c, hnd, *buf_size);
+
+ /* turn parameters into data stream */
+ if (svc_io_q_query_svc_config("", &q_c, &buf, 0) &&
+ rpc_con_pipe_req(con, SVC_QUERY_SVC_CONFIG, &buf, &rbuf))
+ {
+ SVC_R_QUERY_SVC_CONFIG r_c;
+ BOOL p;
+
+ ZERO_STRUCT (r_c);
+ ZERO_STRUCTP(cfg);
+
+ r_c.cfg = cfg;
+
+ svc_io_r_query_svc_config("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(1,("SVC_QUERY_SVC_CONFIG: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_cfg = r_c.buf_size != 0;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return valid_cfg;
+}
+
+
+/****************************************************************************
+do a SVC Close
+****************************************************************************/
+BOOL svc_close(POLICY_HND *hnd)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SVC_Q_CLOSE q_c;
+ BOOL valid_close = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(hnd, &con))
+ {
+ return False;
+ }
+
+ if (hnd == NULL) return False;
+
+ /* create and send a MSRPC command with api SVC_CLOSE */
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ DEBUG(4,("SVC Close\n"));
+
+ /* store the parameters */
+ make_svc_q_close(&q_c, hnd);
+
+ /* turn parameters into data stream */
+ if (svc_io_q_close("", &q_c, &buf, 0) &&
+ rpc_con_pipe_req(con, SVC_CLOSE, &buf, &rbuf))
+ {
+ SVC_R_CLOSE r_c;
+ BOOL p;
+
+ ZERO_STRUCT(r_c);
+
+ svc_io_r_close("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(1,("SVC_CLOSE: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ /* check that the returned policy handle is all zeros */
+ uint32 i;
+ valid_close = True;
+
+ for (i = 0; i < sizeof(r_c.pol.data); i++)
+ {
+ if (r_c.pol.data[i] != 0)
+ {
+ valid_close = False;
+ break;
+ }
+ }
+ if (!valid_close)
+ {
+ DEBUG(1,("SVC_CLOSE: non-zero handle returned\n"));
+ }
+ }
+ }
+
+ close_policy_hnd(get_global_hnd_cache(), hnd);
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return valid_close;
+}
+
+/****************************************************************************
+do a SVC Change Service Config
+****************************************************************************/
+BOOL svc_change_svc_cfg( POLICY_HND *hnd,
+ uint32 service_type, uint32 start_type,
+ uint32 unknown_0,
+ uint32 error_control,
+ char* bin_path_name, char* load_order_grp,
+ uint32 tag_id,
+ char* dependencies, char* service_start_name,
+ char* password,
+ char* disp_name)
+{
+ prs_struct rbuf;
+ prs_struct buf;
+ SVC_Q_CHANGE_SVC_CONFIG q_c;
+ BOOL valid_cfg = False;
+
+ struct cli_connection *con = NULL;
+
+ if (!cli_connection_get(hnd, &con))
+ {
+ return False;
+ }
+
+ if (hnd == NULL) return False;
+
+ /* create and send a MSRPC command with api SVC_CHANGE_SVC_CONFIG */
+
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
+
+ DEBUG(4,("SVC Change Service Config\n"));
+
+ /* store the parameters */
+ make_svc_q_change_svc_config(&q_c, hnd,
+ service_type, start_type,
+ unknown_0, error_control,
+ bin_path_name, load_order_grp,
+ tag_id,
+ dependencies, service_start_name,
+ password, disp_name);
+
+ /* turn parameters into data stream */
+ if (svc_io_q_change_svc_config("", &q_c, &buf, 0) &&
+ rpc_con_pipe_req(con, SVC_CHANGE_SVC_CONFIG, &buf, &rbuf))
+ {
+ SVC_R_CHANGE_SVC_CONFIG r_c;
+ BOOL p;
+
+ ZERO_STRUCT (r_c);
+
+ svc_io_r_change_svc_config("", &r_c, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_c.status != 0)
+ {
+ /* report error code */
+ DEBUG(1,("SVC_CHANGE_SVC_CONFIG: %s\n", get_nt_error_msg(r_c.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_cfg = True;
+ }
+ }
+
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
+
+ return valid_cfg;
+}
diff --git a/source/rpc_client/cli_use.c b/source/rpc_client/cli_use.c
new file mode 100644
index 00000000000..89e64e56702
--- /dev/null
+++ b/source/rpc_client/cli_use.c
@@ -0,0 +1,446 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client generic functions
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define NO_SYSLOG
+
+#include "includes.h"
+#include "trans2.h"
+
+extern int DEBUGLEVEL;
+extern pstring scope;
+extern pstring global_myname;
+
+struct cli_use
+{
+ struct cli_state *cli;
+ uint32 num_users;
+};
+
+static struct cli_use **clis = NULL;
+static uint32 num_clis = 0;
+
+/****************************************************************************
+terminate client connection
+****************************************************************************/
+static void cli_use_free(struct cli_use *cli)
+{
+ if (cli->cli != NULL)
+ {
+ if (cli->cli->initialised)
+ {
+ cli_ulogoff(cli->cli);
+ cli_shutdown(cli->cli);
+ }
+ free(cli->cli);
+ }
+
+ free(cli);
+}
+
+/****************************************************************************
+free a client array
+****************************************************************************/
+static void free_cli_array(uint32 num_entries, struct cli_use **entries)
+{
+ void (*fn) (void *) = (void (*)(void *))&cli_use_free;
+ free_void_array(num_entries, (void **)entries, *fn);
+}
+
+/****************************************************************************
+add a client state to the array
+****************************************************************************/
+static struct cli_use *add_cli_to_array(uint32 * len,
+ struct cli_use ***array,
+ struct cli_use *cli)
+{
+ int i;
+ for (i = 0; i < num_clis; i++)
+ {
+ if (clis[i] == NULL)
+ {
+ clis[i] = cli;
+ return cli;
+ }
+ }
+
+ return (struct cli_use *)add_item_to_array(len,
+ (void ***)array,
+ (void *)cli);
+
+}
+
+/****************************************************************************
+initiate client array
+****************************************************************************/
+void init_cli_use(void)
+{
+ clis = NULL;
+ num_clis = 0;
+}
+
+/****************************************************************************
+terminate client array
+****************************************************************************/
+void free_cli_use(void)
+{
+ free_cli_array(num_clis, clis);
+ init_cli_use();
+}
+
+/****************************************************************************
+find client state. server name, user name, domain name and password must all
+match.
+****************************************************************************/
+static struct cli_use *cli_find(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL reuse)
+{
+ int i;
+ const char *sv_name = srv_name;
+ struct ntuser_creds null_usr;
+
+ if (usr_creds == NULL)
+ {
+ copy_nt_creds(&null_usr, usr_creds);
+ usr_creds = &null_usr;
+ }
+
+ if (strnequal("\\\\", sv_name, 2))
+ {
+ sv_name = &sv_name[2];
+ }
+
+ DEBUG(10, ("cli_find: %s %s %s reuse: %s\n",
+ srv_name, usr_creds->user_name, usr_creds->domain,
+ BOOLSTR(reuse)));
+
+
+ for (i = 0; i < num_clis; i++)
+ {
+ char *cli_name = NULL;
+ struct cli_use *c = clis[i];
+
+ if (c == NULL || !c->cli->initialised)
+ {
+ continue;
+ }
+
+ cli_name = c->cli->desthost;
+
+ DEBUG(10, ("cli_find[%d]: %s %s %s\n",
+ i, cli_name,
+ c->cli->usr.user_name, c->cli->usr.domain));
+
+ if (strnequal("\\\\", cli_name, 2))
+ {
+ cli_name = &cli_name[2];
+ }
+
+ if (!strequal(cli_name, sv_name))
+ {
+ continue;
+ }
+ if (strequal(usr_creds->user_name, "") &&
+ strequal(usr_creds->domain, "") &&
+ pwd_is_nullpwd(&usr_creds->pwd))
+ {
+ return c;
+ }
+ if (!strequal(usr_creds->user_name, c->cli->usr.user_name))
+ {
+ continue;
+ }
+ if (!reuse && !pwd_compare(&usr_creds->pwd, &c->cli->usr.pwd))
+ {
+ DEBUG(100, ("password doesn't match\n"));
+ continue;
+ }
+ if (usr_creds->domain[0] == 0)
+ {
+ return c;
+ }
+ if (strequal(usr_creds->domain, c->cli->usr.domain))
+ {
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+create a new client state from user credentials
+****************************************************************************/
+static struct cli_use *cli_use_get(const char *srv_name,
+ const struct ntuser_creds *usr_creds)
+{
+ struct cli_use *cli = (struct cli_use *)malloc(sizeof(*cli));
+
+ if (cli == NULL)
+ {
+ return NULL;
+ }
+
+ memset(cli, 0, sizeof(*cli));
+
+ cli->cli = cli_initialise(NULL);
+
+ if (cli->cli == NULL)
+ {
+ return NULL;
+ }
+
+ cli_init_creds(cli->cli, usr_creds);
+
+ return cli;
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+struct cli_state *cli_net_use_add(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL redir, BOOL reuse, BOOL *is_new)
+{
+ struct nmb_name calling;
+ struct nmb_name called;
+ struct in_addr *dest_ip = NULL;
+ fstring dest_host;
+ struct in_addr ip;
+
+ struct cli_use *cli;
+
+ DEBUG(10, ("cli_net_use_add\n"));
+
+ cli = cli_find(srv_name, usr_creds, reuse);
+
+ if (cli != NULL)
+ {
+ cli->num_users++;
+ DEBUG(10,
+ ("cli_net_use_add: num_users: %d\n", cli->num_users));
+ (*is_new) = False;
+ return cli->cli;
+ }
+
+ /* reuse an existing connection requested, and one was not found */
+ if (usr_creds != NULL && reuse && !redir)
+ {
+ return False;
+ }
+
+ /*
+ * allocate
+ */
+
+ cli = cli_use_get(srv_name, usr_creds);
+ cli->cli->redirect = redir;
+
+ if (resolve_srv_name(srv_name, dest_host, &ip))
+ {
+ dest_ip = &ip;
+ }
+ else
+ {
+ cli_use_free(cli);
+ return NULL;
+ }
+
+ make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20, scope);
+ make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0, scope);
+
+ /*
+ * connect
+ */
+
+ if (!cli_establish_connection(cli->cli,
+ dest_host, dest_ip,
+ &calling, &called,
+ "IPC$", "IPC", False, True))
+ {
+ DEBUG(0, ("cli_net_use_add: connection failed\n"));
+ cli->cli = NULL;
+ cli_use_free(cli);
+ return NULL;
+ }
+
+ add_cli_to_array(&num_clis, &clis, cli);
+ cli->num_users++;
+
+ DEBUG(10, ("cli_net_use_add: num_users: %d\n", cli->num_users));
+
+ (*is_new) = True;
+
+ return cli->cli;
+}
+
+/****************************************************************************
+delete a client state
+****************************************************************************/
+BOOL cli_net_use_del(const char *srv_name,
+ const struct ntuser_creds *usr_creds,
+ BOOL force_close, BOOL *connection_closed)
+{
+ int i;
+ const char *sv_name = srv_name;
+
+ DEBUG(10, ("cli_net_use_del: %s. %s. %s. force close: %s\n",
+ srv_name,
+ usr_creds->user_name, usr_creds->domain,
+ BOOLSTR(force_close)));
+
+ if (strnequal("\\\\", sv_name, 2))
+ {
+ sv_name = &sv_name[2];
+ }
+
+ if (connection_closed != NULL)
+ {
+ *connection_closed = False;
+ }
+
+ for (i = 0; i < num_clis; i++)
+ {
+ char *cli_name = NULL;
+
+ if (clis[i] == NULL)
+ continue;
+ if (clis[i]->cli == NULL)
+ continue;
+
+ cli_name = clis[i]->cli->desthost;
+
+ DEBUG(10, ("connection: %s %s %s\n", cli_name,
+ clis[i]->cli->usr.user_name,
+ clis[i]->cli->usr.domain));
+
+ if (strnequal("\\\\", cli_name, 2))
+ {
+ cli_name = &cli_name[2];
+ }
+
+ if (!strequal(cli_name, sv_name))
+ continue;
+
+ if (strequal(usr_creds->user_name,
+ clis[i]->cli->usr.user_name) &&
+ strequal(usr_creds->domain, clis[i]->cli->usr.domain))
+ {
+ /* decrement number of users */
+ clis[i]->num_users--;
+
+ DEBUG(10, ("idx: %i num_users now: %d\n",
+ i, clis[i]->num_users));
+
+ if (force_close || clis[i]->num_users == 0)
+ {
+ cli_use_free(clis[i]);
+ clis[i] = NULL;
+ if (connection_closed != NULL)
+ {
+ *connection_closed = True;
+ }
+ }
+ return True;
+ }
+ }
+
+ return False;
+}
+
+/****************************************************************************
+enumerate client states
+****************************************************************************/
+void cli_net_use_enum(uint32 * num_cons, struct use_info ***use)
+{
+ int i;
+
+ *num_cons = 0;
+ *use = NULL;
+
+ for (i = 0; i < num_clis; i++)
+ {
+ struct use_info item;
+
+ ZERO_STRUCT(item);
+
+ if (clis[i] == NULL)
+ continue;
+
+ item.connected = clis[i]->cli != NULL ? True : False;
+
+ if (item.connected)
+ {
+ item.srv_name = clis[i]->cli->desthost;
+ item.user_name = clis[i]->cli->usr.user_name;
+ item.key = clis[i]->cli->nt.key;
+ item.domain = clis[i]->cli->usr.domain;
+ }
+
+ add_use_info_to_array(num_cons, use, &item);
+ }
+}
+
+
+/****************************************************************************
+wait for keyboard activity, swallowing network packets on all client states.
+****************************************************************************/
+void cli_use_wait_keyboard(void)
+{
+ fd_set fds;
+ struct timeval timeout;
+
+ while (1)
+ {
+ int i;
+ int maxfd = fileno(stdin);
+ FD_ZERO(&fds);
+ FD_SET(fileno(stdin), &fds);
+ for (i = 0; i < num_clis; i++)
+ {
+ if (clis[i] != NULL && clis[i]->cli != NULL)
+ {
+ int fd = clis[i]->cli->fd;
+ FD_SET(fd, &fds);
+ maxfd = MAX(fd, maxfd);
+ }
+ }
+
+ timeout.tv_sec = 20;
+ timeout.tv_usec = 0;
+ sys_select(maxfd + 1, NULL, &fds, &timeout);
+
+ if (FD_ISSET(fileno(stdin), &fds))
+ return;
+
+ /* We deliberately use receive_smb instead of
+ client_receive_smb as we want to receive
+ session keepalives and then drop them here.
+ */
+ for (i = 0; i < num_clis; i++)
+ {
+ int fd = clis[i]->cli->fd;
+ if (FD_ISSET(fd, &fds))
+ receive_smb(fd, clis[i]->cli->inbuf, 0);
+ }
+ }
+}
diff --git a/source/rpc_client/cli_wkssvc.c b/source/rpc_client/cli_wkssvc.c
index ae0d5d8231a..400ca56aba4 100644
--- a/source/rpc_client/cli_wkssvc.c
+++ b/source/rpc_client/cli_wkssvc.c
@@ -6,7 +6,6 @@
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jeremy Allison 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,65 +28,69 @@
#endif
#include "includes.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
/****************************************************************************
do a WKS Open Policy
****************************************************************************/
-BOOL do_wks_query_info(struct cli_state *cli,
- char *server_name, uint32 switch_value,
+BOOL wks_query_info( char *srv_name, uint32 switch_value,
WKS_INFO_100 *wks100)
{
prs_struct rbuf;
prs_struct buf;
WKS_Q_QUERY_INFO q_o;
- WKS_R_QUERY_INFO r_o;
+ BOOL valid_info = False;
+ struct cli_connection *con = NULL;
- if (server_name == 0 || wks100 == NULL)
+ if (wks100 == NULL) return False;
+
+ if (!cli_connection_init(srv_name, PIPE_WKSSVC, &con))
+ {
return False;
+ }
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL );
+ prs_init(&buf , 0, 4, False);
+ prs_init(&rbuf, 0, 4, True );
/* create and send a MSRPC command with api WKS_QUERY_INFO */
DEBUG(4,("WKS Query Info\n"));
/* store the parameters */
- init_wks_q_query_info(&q_o, server_name, switch_value);
+ make_wks_q_query_info(&q_o, srv_name, switch_value);
/* turn parameters into data stream */
- if(!wks_io_q_query_info("", &q_o, &buf, 0)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- /* send the data on \PIPE\ */
- if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) {
- prs_mem_free(&buf);
- prs_mem_free(&rbuf);
- return False;
- }
-
- prs_mem_free(&buf);
-
- r_o.wks100 = wks100;
-
- if(!wks_io_r_query_info("", &r_o, &rbuf, 0)) {
- prs_mem_free(&rbuf);
- return False;
+ if (wks_io_q_query_info("", &q_o, &buf, 0) &&
+ rpc_con_pipe_req(con, WKS_QUERY_INFO, &buf, &rbuf))
+ {
+ WKS_R_QUERY_INFO r_o;
+ BOOL p;
+
+ r_o.wks100 = wks100;
+
+ wks_io_r_query_info("", &r_o, &rbuf, 0);
+ p = rbuf.offset != 0;
+
+ if (p && r_o.status != 0)
+ {
+ /* report error code */
+ DEBUG(0,("WKS_R_QUERY_INFO: %s\n", get_nt_error_msg(r_o.status)));
+ p = False;
+ }
+
+ if (p)
+ {
+ valid_info = True;
+ }
}
- if (r_o.status != 0) {
- /* report error code */
- DEBUG(0,("WKS_R_QUERY_INFO: %s\n", get_nt_error_msg(r_o.status)));
- prs_mem_free(&rbuf);
- return False;
- }
+ prs_free_data(&rbuf);
+ prs_free_data(&buf );
- prs_mem_free(&rbuf);
+ cli_connection_unlink(con);
- return True;
+ return valid_info;
}
+
diff --git a/source/rpc_client/msrpc_lsarpc.c b/source/rpc_client/msrpc_lsarpc.c
new file mode 100644
index 00000000000..0fbc3a513dd
--- /dev/null
+++ b/source/rpc_client/msrpc_lsarpc.c
@@ -0,0 +1,365 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+uint32 lookup_lsa_names(const char *srv_name,
+ uint32 num_names, char **names,
+ uint32 * num_sids, DOM_SID ** sids, uint32 ** types)
+{
+ BOOL res1 = True;
+ BOOL res2 = True;
+ POLICY_HND lsa_pol;
+
+ if (srv_name == NULL)
+ {
+ srv_name = "\\\\.";
+ }
+
+ if (num_sids)
+ {
+ *num_sids = 0;
+ }
+ if (sids)
+ {
+ *sids = NULL;
+ }
+ if (types)
+ {
+ *types = NULL;
+ }
+
+ if (!num_sids || (!types && !sids))
+ {
+ /* Not sure, wether that's a good error-code */
+ return NT_STATUS_NONE_MAPPED | 0xC0000000;
+ }
+
+ res1 =
+ res1 ? lsa_open_policy(srv_name, &lsa_pol, True,
+ 0x02000000) : False;
+
+ res2 = res1 ? lsa_lookup_names(&lsa_pol,
+ num_names, names,
+ sids, types, num_sids) : False;
+
+ res1 = res1 ? lsa_close(&lsa_pol) : False;
+
+ if (!res2)
+ {
+ return NT_STATUS_NONE_MAPPED | 0xC0000000;
+ }
+
+ return 0x0;
+}
+
+
+uint32 lookup_lsa_name(const char *domain,
+ char *name, DOM_SID * sid, uint32 * type)
+{
+ fstring srv_name;
+ BOOL res3 = True;
+ BOOL res4 = True;
+ char **names = NULL;
+ uint32 *types = NULL;
+ int num_names = 0;
+ DOM_SID *sids = NULL;
+ int num_sids = 0;
+ POLICY_HND lsa_pol;
+
+ if (!get_any_dc_name(domain, srv_name))
+ {
+ return NT_STATUS_NONE_MAPPED | 0xC0000000;
+ }
+
+ num_names = 1;
+ names = &name;
+
+ /* lookup domain controller; receive a policy handle */
+ res3 =
+ res3 ? lsa_open_policy(srv_name, &lsa_pol, True,
+ 0x02000000) : False;
+
+ /* send lsa lookup sids call */
+ res4 = res3 ? lsa_lookup_names(&lsa_pol,
+ num_names, names,
+ &sids, &types, &num_sids) : False;
+
+ res3 = res3 ? lsa_close(&lsa_pol) : False;
+
+ res4 = num_sids != 1 ? False : res4;
+
+ if (!res4)
+ {
+ return NT_STATUS_NONE_MAPPED | 0xC0000000;
+ }
+ sid_copy(sid, &sids[0]);
+ *type = types[0];
+
+ if (types != NULL)
+ {
+ free(types);
+ }
+
+ if (sids != NULL)
+ {
+ free(sids);
+ }
+
+ return 0x0;
+}
+
+/****************************************************************************
+lookup sids
+****************************************************************************/
+uint32 lookup_lsa_sid(const char *domain,
+ DOM_SID * sid, char *name, uint32 * type)
+{
+ POLICY_HND lsa_pol;
+ fstring srv_name;
+ DOM_SID **sids = NULL;
+ uint32 num_sids = 0;
+ char **names = NULL;
+ int num_names = 0;
+ uint32 *types = NULL;
+
+ BOOL res = True;
+ BOOL res1 = True;
+
+ if (!get_any_dc_name(domain, srv_name))
+ {
+ return NT_STATUS_NONE_MAPPED | 0xC0000000;
+ }
+
+ add_sid_to_array(&num_sids, &sids, sid);
+
+ /* lookup domain controller; receive a policy handle */
+ res =
+ res ? lsa_open_policy(srv_name, &lsa_pol, True,
+ 0x02000000) : False;
+
+ /* send lsa lookup sids call */
+ res1 = res ? lsa_lookup_sids(&lsa_pol,
+ num_sids, sids,
+ &names, &types, &num_names) : False;
+
+ res = res ? lsa_close(&lsa_pol) : False;
+
+ if (!res1 || names == NULL || types == NULL)
+ {
+ return NT_STATUS_NONE_MAPPED | 0xC0000000;
+ }
+
+ fstrcpy(name, names[0]);
+ *type = types[0];
+
+ free_sid_array(num_sids, sids);
+ free_char_array(num_names, names);
+
+ if (types != NULL)
+ {
+ free(types);
+ }
+
+ return 0x0;
+}
+
+/****************************************************************************
+nt lsa create secret
+****************************************************************************/
+BOOL msrpc_lsa_create_secret(const char *srv_name, const char *secret_name,
+ uint32 access_rights)
+{
+ BOOL res = True;
+ BOOL res1;
+
+ POLICY_HND pol_sec;
+ POLICY_HND lsa_pol;
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? lsa_open_policy(srv_name,
+ &lsa_pol, True, 0x02000000) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res1 = res ? lsa_create_secret(&lsa_pol,
+ secret_name, access_rights,
+ &pol_sec) : False;
+
+ res1 = res1 ? lsa_close(&pol_sec) : False;
+
+ res = res ? lsa_close(&lsa_pol) : False;
+
+ return res1;
+}
+
+/****************************************************************************
+put data into secret buffer.
+****************************************************************************/
+void secret_store_data(STRING2 * secret, const char* data, int len)
+{
+ ZERO_STRUCTP(secret);
+
+ secret->str_max_len = len + 8;
+ secret->undoc = 0;
+ secret->str_str_len = len + 8;
+
+ SIVAL(secret->buffer, 0, len);
+ SIVAL(secret->buffer, 4, 0x01);
+ memcpy(secret->buffer + 8, data, len);
+}
+
+/****************************************************************************
+put data into secret buffer.
+****************************************************************************/
+void secret_store_data2(STRING2 * secret, const char* data, int len)
+{
+ ZERO_STRUCTP(secret);
+
+ secret->str_max_len = len;
+ secret->undoc = 0;
+ secret->str_str_len = len;
+
+ memcpy(secret->buffer, data, len);
+}
+
+/****************************************************************************
+nt lsa query secret
+****************************************************************************/
+BOOL msrpc_lsa_set_secret(const char *srv_name,
+ const char *secret_name, const char *data, int len)
+{
+ BOOL res = True;
+ BOOL res1;
+ BOOL res2;
+
+ POLICY_HND pol_sec;
+ POLICY_HND lsa_pol;
+ STRING2 secret;
+
+ secret_store_data(&secret, data, len);
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? lsa_open_policy(srv_name,
+ &lsa_pol, True, 0x02000000) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res1 = res ? lsa_open_secret(&lsa_pol,
+ secret_name, 0x02000000, &pol_sec) : False;
+
+ res2 =
+ res1 ? (lsa_set_secret(&pol_sec, &secret) ==
+ NT_STATUS_NOPROBLEMO) : False;
+
+ res1 = res1 ? lsa_close(&pol_sec) : False;
+
+ res = res ? lsa_close(&lsa_pol) : False;
+
+ return res2;
+}
+
+/****************************************************************************
+nt lsa query secret
+****************************************************************************/
+BOOL msrpc_lsa_query_secret(const char *srv_name,
+ const char *secret_name,
+ STRING2 * secret, NTTIME * last_update)
+{
+ BOOL res = True;
+ BOOL res1;
+ BOOL res2;
+
+ POLICY_HND pol_sec;
+ POLICY_HND lsa_pol;
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? lsa_open_policy2(srv_name,
+ &lsa_pol, False, 0x02000000) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res1 = res ? lsa_open_secret(&lsa_pol,
+ secret_name, 0x02000000,
+ &pol_sec) : False;
+
+ res2 = res1 ? lsa_query_secret(&pol_sec, secret, last_update) : False;
+
+ res1 = res1 ? lsa_close(&pol_sec) : False;
+
+ res = res ? lsa_close(&lsa_pol) : False;
+
+ return res2;
+}
+
+/****************************************************************************
+obtains a trust account password
+****************************************************************************/
+BOOL secret_get_data(const STRING2 *secret, uchar *data, uint32 *len)
+{
+ (*len) = IVAL(secret->buffer, 0);
+ if (secret->str_str_len != (*len) + 8)
+ {
+ return False;
+ }
+ if (IVAL(secret->buffer, 4) != 0x1)
+ {
+ return False;
+ }
+ memcpy(data, secret->buffer + 8, *len);
+ return True;
+}
+
+/****************************************************************************
+obtains a trust account password
+****************************************************************************/
+BOOL msrpc_lsa_query_trust_passwd(const char *srv_name,
+ const char *secret_name,
+ uchar trust_passwd[16],
+ NTTIME * last_update)
+{
+ STRING2 secret;
+ UNISTR2 uni_pwd;
+ uint32 len;
+ if (!msrpc_lsa_query_secret(srv_name, secret_name, &secret,
+ last_update))
+ {
+ return False;
+ }
+ if (!secret_get_data(&secret, (uchar*)&uni_pwd.buffer, &len))
+ {
+ return False;
+ }
+
+ uni_pwd.uni_str_len = len / 2;
+ uni_pwd.uni_max_len = len / 2;
+ nt_owf_genW(&uni_pwd, trust_passwd);
+
+ return True;
+}
diff --git a/source/rpc_client/msrpc_netlogon.c b/source/rpc_client/msrpc_netlogon.c
new file mode 100644
index 00000000000..1f72202f2a1
--- /dev/null
+++ b/source/rpc_client/msrpc_netlogon.c
@@ -0,0 +1,259 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Jeremy Allison 1998-2000.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+extern pstring global_myname;
+extern pstring global_myworkgroup;
+
+/*********************************************************
+ Change the domain password on the PDC.
+**********************************************************/
+
+BOOL modify_trust_password(const char *domain, const char *srv_name,
+ const uchar orig_trust_passwd_hash[16],
+ const uchar new_trust_passwd_hash[16],
+ uint16 sec_chan)
+{
+ fstring trust_acct;
+
+ fstrcpy(trust_acct, global_myname);
+ fstrcat(trust_acct, "$");
+
+ if (cli_nt_setup_creds(srv_name, domain, global_myname, trust_acct,
+ orig_trust_passwd_hash, sec_chan) != 0x0)
+ {
+ return False;
+ }
+
+ if (!cli_nt_srv_pwset(srv_name, global_myname, trust_acct,
+ new_trust_passwd_hash, sec_chan))
+ {
+ return False;
+ }
+
+ return True;
+}
+
+/***********************************************************************
+ Do the same as security=server, but using NT Domain calls and a session
+ key from the workstation trust account password.
+************************************************************************/
+static uint32 domain_client_validate(const char *user, const char *domain,
+ const char *acct_name, uint16 acct_type,
+ const char *challenge,
+ const char *smb_apasswd,
+ int smb_apasslen,
+ const char *smb_ntpasswd,
+ int smb_ntpasslen,
+ NET_USER_INFO_3 * info3)
+{
+ unsigned char trust_passwd[16];
+ NET_ID_INFO_CTR ctr;
+ uint32 smb_uid_low;
+ uint32 status;
+ fstring trust_acct;
+ fstring srv_name;
+ BOOL cleartext = smb_apasslen != 0 && smb_apasslen != 24 &&
+ smb_ntpasslen == 0;
+
+ DEBUG(100, ("domain_client_validate: %s %s\n", user, domain));
+#ifdef DEBUG_PASSWORD
+ dump_data_pw("lmpw:", smb_apasswd, smb_apasslen);
+ dump_data_pw("ntpw:", smb_ntpasswd, smb_ntpasslen);
+#endif
+
+ fstrcpy(trust_acct, acct_name);
+ fstrcat(trust_acct, "$");
+
+ /*
+ * Check that the requested domain is not our own machine name.
+ * If it is, we should never check the PDC here, we use our own local
+ * password file.
+ */
+
+ if (!get_any_dc_name(domain, srv_name))
+ {
+ DEBUG(3,
+ ("domain_client_validate: could not find domain %s\n",
+ domain));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!msrpc_lsa_query_trust_passwd("\\\\.", "$MACHINE.ACC",
+ trust_passwd, NULL))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /*
+ * At this point, smb_apasswd points to the lanman response to
+ * the challenge in local_challenge, and smb_ntpasswd points to
+ * the NT response to the challenge in local_challenge. Ship
+ * these over the secure channel to a domain controller and
+ * see if they were valid.
+ */
+
+ /*
+ * Ok - we have an anonymous connection to the IPC$ share.
+ * Now start the NT Domain stuff :-).
+ */
+
+ status =
+ cli_nt_setup_creds(srv_name, domain, global_myname,
+ trust_acct, trust_passwd, acct_type);
+ if (status != 0x0)
+ {
+ DEBUG(0, ("domain_client_validate: credentials failed (%s)\n",
+ srv_name));
+ return status;
+ }
+
+ /* We really don't care what LUID we give the user. */
+ generate_random_buffer((unsigned char *)&smb_uid_low, 4, False);
+
+ if (challenge == NULL && !cleartext)
+ {
+ status = cli_nt_login_interactive(srv_name,
+ global_myname,
+ domain, user,
+ smb_uid_low,
+ smb_apasswd, smb_ntpasswd,
+ &ctr, info3);
+ }
+ else if (challenge == NULL)
+ {
+ status = cli_nt_login_general(srv_name,
+ global_myname,
+ domain, user,
+ smb_uid_low,
+ smb_apasswd, &ctr, info3);
+ }
+ else
+ {
+ status = cli_nt_login_network(srv_name,
+ global_myname,
+ domain, user,
+ smb_uid_low,
+ (const char *)challenge,
+ (const uchar *)smb_apasswd,
+ smb_apasslen,
+ (const uchar *)smb_ntpasswd,
+ smb_ntpasslen, &ctr, info3);
+ }
+
+ if (status ==
+ (NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT | 0xc0000000))
+ {
+ DEBUG(10, ("domain_client_validate: wks trust valid:%s\n",
+ user));
+ return status;
+ }
+
+ if (status == (NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT | 0xc0000000))
+ {
+ DEBUG(10, ("domain_client_validate: srv trust valid:%s\n",
+ user));
+ return status;
+ }
+
+ if (status ==
+ (NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT | 0xc0000000))
+ {
+ DEBUG(10,
+ ("domain_client_validate: interdom trust valid:%s\n",
+ user));
+ return status;
+ }
+
+ if (status != 0x0)
+ {
+ DEBUG(0,
+ ("domain_client_validate: unable to validate password for user %s in domain \
+ %s to Domain controller %s.\n",
+ user, domain, srv_name));
+ return status;
+ }
+
+ /*
+ * Here, if we really want it, we have lots of info about the user in info3.
+ * LKCLXXXX - really important to check things like "is this user acct
+ * locked out / disabled" etc!!!!
+ */
+
+ DEBUG(10, ("domain_client_validate: user %s\%s OK\n", domain, user));
+ DEBUG(3, ("domain_client_validate: check lockout / pwd expired!\n"));
+
+ return 0x0;
+}
+
+/****************************************************************************
+ Check for a valid username and password in security=domain mode.
+****************************************************************************/
+uint32 check_domain_security(const char *orig_user, const char *domain,
+ const uchar * challenge,
+ const char *smb_apasswd, int smb_apasslen,
+ const char *smb_ntpasswd, int smb_ntpasslen,
+ NET_USER_INFO_3 * info3)
+{
+ fstring acct_name;
+ uint16 acct_type = 0;
+
+ if (lp_security() == SEC_SHARE || lp_security() == SEC_SERVER)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (domain == NULL || strequal(domain, ""))
+ {
+ domain = global_myworkgroup;
+ }
+
+ if (lp_security() == SEC_USER ||
+ (lp_security() == SEC_DOMAIN &&
+ strequal(domain, global_myworkgroup)))
+ {
+ fstrcpy(acct_name, global_myname);
+ acct_type = SEC_CHAN_WKSTA;
+ }
+ else
+ {
+ fstrcpy(acct_name, global_myworkgroup);
+ acct_type = SEC_CHAN_DOMAIN;
+ }
+
+ DEBUG(10, ("check_domain_security: %s(%d)\n", acct_name, acct_type));
+
+ return domain_client_validate(orig_user, domain,
+ acct_name, acct_type,
+ challenge,
+ smb_apasswd, smb_apasslen,
+ smb_ntpasswd, smb_ntpasslen, info3);
+}
diff --git a/source/rpc_client/msrpc_samr.c b/source/rpc_client/msrpc_samr.c
new file mode 100644
index 00000000000..7815e173a94
--- /dev/null
+++ b/source/rpc_client/msrpc_samr.c
@@ -0,0 +1,2027 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+/****************************************************************************
+lookup SID for a domain in a sam database
+****************************************************************************/
+uint32 lookup_sam_domainname(const char *srv_name,
+ const char *domain, DOM_SID *sid)
+{
+ POLICY_HND sam_pol;
+ BOOL res = True;
+ BOOL res1 = True;
+
+ if (srv_name == NULL)
+ {
+ srv_name = "\\\\.";
+ }
+
+ /* establish a connection. */
+ res = res ? samr_connect(srv_name, 0x02000000, &sam_pol) : False;
+
+ res1 = res ? samr_query_lookup_domain(&sam_pol, domain, sid) : False;
+
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (! res1)
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+ return 0x0;
+}
+
+
+/****************************************************************************
+lookup in a sam database
+****************************************************************************/
+uint32 lookup_sam_names(const char *domain, const DOM_SID *sid,
+ uint32 num_names, char **names,
+ uint32 *num_rids, uint32 **rids, uint32 **types)
+{
+ fstring srv_name;
+ BOOL res = True;
+ BOOL res1 = True;
+ uint32 *my_types = NULL;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ if (domain == NULL)
+ {
+ fstrcpy(srv_name, "\\\\.");
+ }
+ else if (!get_any_dc_name(domain, srv_name))
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ if (num_rids)
+ {
+ *num_rids = 0;
+ }
+ if (rids)
+ {
+ *rids = NULL;
+ }
+ if (types)
+ {
+ *types = NULL;
+ }
+
+ if (!num_names || !names || !num_rids || (!types && !rids))
+ {
+ /* Not sure, wether that's a good error-code */
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ /* establish a connection. */
+ res = res ? samr_connect(srv_name, 0x02000000, &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain(&sam_pol, ace_perms, sid, &pol_dom) : False;
+
+ res1 = res ? samr_query_lookup_names(&pol_dom, 0x000003e8,
+ num_names, names,
+ num_rids, rids, &my_types) : False;
+
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (! res1)
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+ if (types)
+ {
+ uint32 i, num;
+ num = *num_rids;
+ *types = g_new(uint32, num);
+ if (*types == NULL)
+ {
+ safe_free(my_types);
+ return NT_STATUS_NONE_MAPPED;
+ }
+ for(i = 0; i < num; i++)
+ {
+ (*types)[i] = my_types[i];
+ }
+ }
+ safe_free(my_types);
+
+ return 0x0;
+}
+
+/****************************************************************************
+lookup in a sam database
+****************************************************************************/
+uint32 lookup_sam_name(const char *domain, DOM_SID *sid,
+ char *name, uint32 *rid, uint32 *type)
+{
+ fstring srv_name;
+ BOOL res = True;
+ BOOL res1 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ char *names[1];
+ uint32 *rids = NULL;
+ uint32 *types = NULL;
+ uint32 num_rids;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ if (domain == NULL)
+ {
+ fstrcpy(srv_name, "\\\\.");
+ }
+ else if (!get_any_dc_name(domain, srv_name))
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000, &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, sid, &pol_dom) : False;
+
+ names[0] = name;
+
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x000003e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (!res1 || num_rids != 1)
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ *rid = rids[0];
+ *type = (uint32)(types[0]);
+
+ free(rids);
+ free(types);
+
+ return 0x0;
+}
+
+/****************************************************************************
+lookup in a sam database
+****************************************************************************/
+uint32 lookup_sam_rid(const char *domain, DOM_SID *sid,
+ uint32 rid, char *name, uint32 *type)
+{
+ fstring srv_name;
+ int i;
+ BOOL res = True;
+ BOOL res1 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ char **names = NULL;
+ uint32 *rid_mem;
+ uint32 *types = NULL;
+ uint32 num_names;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ if (!get_any_dc_name(domain, srv_name))
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000, &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, sid, &pol_dom) : False;
+
+ rid_mem = (uint32*)malloc(1 * sizeof(rid_mem[0]));
+
+ if (rid_mem == NULL)
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ for (i = 0; i < 1; i++)
+ {
+ rid_mem[i] = rid;
+ }
+
+ res1 = res ? samr_query_lookup_rids( &pol_dom, 0x3e8,
+ 1, rid_mem,
+ &num_names, &names, &types) : False;
+
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ free(rid_mem);
+
+ if (!res1 || num_names != 1)
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ fstrcpy(name, names[0]);
+ *type = types[0];
+
+ free_char_array(num_names, names);
+
+ if (types != NULL)
+ {
+ free(types);
+ }
+
+ return 0x0;
+}
+
+BOOL req_user_info( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid, uint16 info_level,
+ USER_INFO_FN(usr_inf))
+{
+ SAM_USERINFO_CTR ctr;
+ /* send user info query, level 0x15 */
+ if (get_samr_query_userinfo( pol_dom,
+ info_level, user_rid, &ctr))
+ {
+ if (usr_inf != NULL)
+ {
+ usr_inf(domain, sid, user_rid, &ctr);
+ }
+ return True;
+ }
+ return False;
+}
+
+/****************************************************************************
+SAM Query User Groups.
+****************************************************************************/
+uint32 sam_query_usergroups( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 user_rid,
+ const char *user_name,
+ uint32 *num_groups,
+ DOM_GID **gid,
+ char ***name,
+ uint32 **type,
+ USER_MEM_FN(usr_mem))
+{
+ uint32 num_names = 0;
+ (*gid) = NULL;
+ /* send user group query */
+ if (get_samr_query_usergroups( pol_dom,
+ user_rid, num_groups, gid) &&
+ gid != NULL)
+ {
+ uint32 i;
+ uint32 *rid_mem;
+
+ rid_mem = (uint32*)malloc((*num_groups) * sizeof(rid_mem[0]));
+
+ if (rid_mem == NULL)
+ {
+ free(*gid);
+ (*gid) = NULL;
+ return 0;
+ }
+
+ for (i = 0; i < (*num_groups); i++)
+ {
+ rid_mem[i] = (*gid)[i].g_rid;
+ }
+
+ if (samr_query_lookup_rids( pol_dom, 0x3e8,
+ (*num_groups), rid_mem,
+ &num_names, name, type))
+ {
+ usr_mem(domain, sid,
+ user_rid, user_name,
+ num_names, rid_mem, *name, *type);
+ }
+
+ free(rid_mem);
+ }
+
+ return num_names;
+}
+
+static uint32 req_group_info( const POLICY_HND *pol_dom,
+ const char *domain, const DOM_SID *sid,
+ uint32 user_rid, const char *user_name,
+ USER_MEM_FN(usr_mem))
+{
+ uint32 num_groups;
+ uint32 num_names;
+ DOM_GID *gid = NULL;
+ char **name = NULL;
+ uint32 *type = NULL;
+
+ num_names = sam_query_usergroups( pol_dom,
+ domain, sid,
+ user_rid, user_name,
+ &num_groups, &gid,
+ &name, &type, usr_mem);
+
+ free_char_array(num_names, name);
+ if (type != NULL)
+ {
+ free(type);
+ }
+
+ if (gid != NULL)
+ {
+ free(gid);
+ }
+
+ return num_names;
+}
+
+static void req_alias_info( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid1, uint32 user_rid,
+ const char *user_name,
+ USER_MEM_FN(usr_mem))
+{
+ uint32 num_aliases;
+ uint32 *rid_mem = NULL;
+ uint32 *ptr_sid;
+ DOM_SID2 *als_sid;
+
+ if (pol_dom == NULL)
+ {
+ return;
+ }
+
+ ptr_sid = (uint32*) malloc(sizeof(ptr_sid[0]) * 1);
+ als_sid = (DOM_SID2*)malloc(sizeof(als_sid[0]) * 1);
+
+ sid_copy(&als_sid[0].sid, sid1);
+ sid_append_rid(&als_sid[0].sid, user_rid);
+ als_sid[0].num_auths = als_sid[0].sid.num_auths;
+
+ ptr_sid[0] = 1;
+
+ /* send user alias query */
+ if (samr_query_useraliases( pol_dom,
+ ptr_sid, als_sid, &num_aliases, &rid_mem))
+ {
+ uint32 num_names;
+ char **name = NULL;
+ uint32 *type = NULL;
+
+ uint32 *rid_copy = (uint32*)malloc(num_aliases * sizeof(*rid_copy));
+
+ if (rid_copy != NULL)
+ {
+ uint32 i;
+ for (i = 0; i < num_aliases; i++)
+ {
+ rid_copy[i] = rid_mem[i];
+ }
+ if (samr_query_lookup_rids(
+ pol_dom, 0x3e8,
+ num_aliases, rid_copy,
+ &num_names, &name, &type))
+ {
+ usr_mem(domain, sid1,
+ user_rid, user_name,
+ num_names, rid_mem, name, type);
+ }
+
+ free(rid_copy);
+ }
+
+ free_char_array(num_names, name);
+ if (type != NULL)
+ {
+ free(type);
+ }
+ }
+
+ if (rid_mem != NULL)
+ {
+ free(rid_mem);
+ rid_mem = NULL;
+ }
+}
+
+/****************************************************************************
+experimental SAM user display info.
+****************************************************************************/
+void msrpc_sam_user( const POLICY_HND *pol_dom, const POLICY_HND *pol_blt,
+ const char* domain,
+ const DOM_SID *sid1,
+ const DOM_SID *blt_sid1,
+ uint32 user_rid, uint16 info_level,
+ char *user_name,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn))
+{
+ if (usr_fn != NULL)
+ {
+ usr_fn(domain, sid1, user_rid, user_name);
+ }
+
+ if (usr_inf_fn != NULL)
+ {
+ req_user_info(pol_dom,
+ domain, sid1,
+ user_rid, info_level,
+ usr_inf_fn);
+ }
+
+ if (usr_grp_fn != NULL)
+ {
+ req_group_info(pol_dom,
+ domain, sid1,
+ user_rid, user_name,
+ usr_grp_fn);
+ }
+
+ if (usr_als_fn != NULL)
+ {
+ req_alias_info(pol_dom,
+ domain, sid1,
+ user_rid, user_name,
+ usr_als_fn);
+ req_alias_info(pol_blt,
+ domain, blt_sid1,
+ user_rid, user_name,
+ usr_als_fn);
+ }
+}
+
+/****************************************************************************
+experimental SAM user query.
+****************************************************************************/
+BOOL msrpc_sam_query_user( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid,
+ char *user_name,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn))
+{
+ BOOL res = True;
+ BOOL res1 = True;
+
+ char *names[1];
+ uint32 num_rids;
+ uint32 *rid = NULL;
+ uint32 *type = NULL;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000, &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, 0x304, sid, &pol_dom) : False;
+
+ /* look up user rid */
+ names[0] = user_name;
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rid, &type) : False;
+
+ /* send user info query */
+ if (res1 && num_rids == 1)
+ {
+ msrpc_sam_user( &pol_dom, NULL,
+ domain,
+ sid, NULL,
+ rid[0], 0x15,
+ user_name,
+ usr_fn, usr_inf_fn,
+ usr_grp_fn, usr_als_fn);
+ }
+ else
+ {
+ res1 = False;
+ }
+
+ if (rid)
+ free(rid);
+ if (type)
+ free(type);
+
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ return res1;
+}
+
+/****************************************************************************
+experimental SAM users enum.
+****************************************************************************/
+int msrpc_sam_enum_users( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ USER_FN(usr_fn),
+ USER_INFO_FN(usr_inf_fn),
+ USER_MEM_FN(usr_grp_fn),
+ USER_MEM_FN(usr_als_fn))
+{
+ DOM_SID sid_1_5_20;
+ uint32 user_idx;
+ BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ uint32 start_idx = 0x0;
+ uint16 unk_0 = 0x0;
+ uint16 acb_mask = 0;
+ uint16 unk_1 = 0x0;
+ uint32 ace_perms = 0x304; /* access control permissions */
+ uint32 status;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ POLICY_HND pol_blt;
+
+ (*sam) = NULL;
+ (*num_sam_entries) = 0;
+
+ string_to_sid(&sid_1_5_20, "S-1-5-32");
+
+ DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
+ start_idx, unk_0, acb_mask, unk_1));
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res1 = res ? samr_open_domain( &sam_pol, ace_perms, sid1,
+ &pol_dom) : False;
+
+ /* connect to the S-1-5-20 domain */
+ res2 = res ? samr_open_domain( &sam_pol, ace_perms, &sid_1_5_20,
+ &pol_blt) : False;
+
+ if (res1)
+ {
+ /* read some users */
+ do
+ {
+ status = samr_enum_dom_users( &pol_dom,
+ &start_idx, acb_mask, unk_1, 0x10000,
+ sam, num_sam_entries);
+
+ } while (status == STATUS_MORE_ENTRIES);
+
+#if 0
+ if ((*num_sam_entries) == 0)
+ {
+ report(out_hnd, "No users\n");
+ }
+#endif
+
+ /* query all the users */
+ for (user_idx = 0; res && user_idx <
+ (*num_sam_entries); user_idx++)
+ {
+ uint32 user_rid = (*sam)[user_idx].rid;
+ char *user_name = (*sam)[user_idx].acct_name;
+
+ msrpc_sam_user( &pol_dom, &pol_blt,
+ domain,
+ sid1, &sid_1_5_20,
+ user_rid, 0x15, user_name,
+ usr_fn, usr_inf_fn,
+ usr_grp_fn, usr_als_fn);
+ }
+ }
+
+ res2 = res2 ? samr_close( &pol_blt) : False;
+ res1 = res1 ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ if (res)
+ {
+ DEBUG(5,("msrpc_sam_enum_users: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("msrpc_sam_enum_users: failed\n"));
+ }
+
+ return (*num_sam_entries);
+}
+
+
+/****************************************************************************
+experimental SAM domain info query.
+****************************************************************************/
+BOOL sam_query_dominfo(const char* srv_name,
+ const DOM_SID *sid1,
+ uint32 switch_value, SAM_UNK_CTR *ctr)
+{
+ BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ /* establish a connection. */
+ res = res ? samr_connect(
+ srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res1 = res ? samr_open_domain( &sam_pol, ace_perms, sid1,
+ &pol_dom) : False;
+
+ /* send a samr 0x8 command */
+ res2 = res ? samr_query_dom_info( &pol_dom, switch_value, ctr) : False;
+
+ res1 = res1 ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ if (res2)
+ {
+ DEBUG(5,("sam_query_dominfo: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("sam_query_dominfo: failed\n"));
+ }
+
+ return res2;
+}
+
+
+BOOL query_aliasinfo( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ ALIAS_INFO_FN(grp_inf))
+{
+ ALIAS_INFO_CTR ctr;
+
+ /* send alias info query */
+ if (get_samr_query_aliasinfo( pol_dom,
+ 3, /* info level */
+ alias_rid, &ctr))
+ {
+ if (grp_inf != NULL)
+ {
+ grp_inf(domain, sid, alias_rid, &ctr);
+ }
+ return True;
+ }
+ return False;
+}
+
+BOOL sam_query_aliasmem(const char *srv_name,
+ const POLICY_HND *pol_dom,
+ uint32 alias_rid,
+ uint32 *num_names,
+ DOM_SID ***sids,
+ char ***name,
+ uint32 **type)
+{
+ BOOL res3 = True;
+ BOOL res4 = True;
+ DOM_SID2 sid_mem[MAX_LOOKUP_SIDS];
+ uint32 num_aliases = 0;
+
+ *sids = NULL;
+ *num_names = 0;
+ *name = NULL;
+ *type = NULL;
+
+ /* get alias members */
+ res3 = get_samr_query_aliasmem(
+ pol_dom,
+ alias_rid, &num_aliases, sid_mem);
+
+ if (res3 && num_aliases != 0)
+ {
+ POLICY_HND lsa_pol;
+
+ uint32 i;
+ uint32 numsids = 0;
+
+ for (i = 0; i < num_aliases; i++)
+ {
+ add_sid_to_array(&numsids, sids, &sid_mem[i].sid);
+ }
+
+ /* lookup domain controller; receive a policy handle */
+ res3 = res3 ? lsa_open_policy( srv_name,
+ &lsa_pol, True, 0x02000000) : False;
+
+ /* send lsa lookup sids call */
+ res4 = res3 ? lsa_lookup_sids( &lsa_pol,
+ num_aliases, *sids,
+ name, type, num_names) : False;
+
+ res3 = res3 ? lsa_close(&lsa_pol) : False;
+ }
+
+ if (!res4)
+ {
+ free_char_array(*num_names, *name);
+ if ((*type) != NULL)
+ {
+ free(*type);
+ }
+ if ((*sids) != NULL)
+ {
+ free_sid_array(num_aliases, *sids);
+ }
+ *num_names = 0;
+ *name = NULL;
+ *type = NULL;
+ *sids = NULL;
+ }
+
+ return res4;
+}
+
+BOOL req_aliasmem_info(const char* srv_name,
+ const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 alias_rid,
+ const char *alias_name,
+ ALIAS_MEM_FN(als_mem))
+{
+ uint32 num_names = 0;
+ char **name = NULL;
+ uint32 *type = NULL;
+ DOM_SID **sids = NULL;
+
+ if (sam_query_aliasmem( srv_name, pol_dom, alias_rid,
+ &num_names, &sids,
+ &name, &type))
+ {
+ als_mem(domain, sid,
+ alias_rid, alias_name,
+ num_names, sids, name, type);
+
+ free_char_array(num_names, name);
+ if (type != NULL)
+ {
+ free(type);
+ }
+ if (sids != NULL)
+ {
+ free_sid_array(num_names, sids);
+ }
+ return True;
+ }
+ return False;
+}
+
+BOOL sam_query_groupmem( const POLICY_HND *pol_dom,
+ uint32 group_rid,
+ uint32 *num_names,
+ uint32 **rid_mem,
+ char ***name,
+ uint32 **type)
+{
+ uint32 num_mem;
+ uint32 *attr_mem = NULL;
+ BOOL res3;
+
+ *rid_mem = NULL;
+ *num_names = 0;
+ *name = NULL;
+ *type = NULL;
+
+ /* get group members */
+ res3 = get_samr_query_groupmem(
+ pol_dom,
+ group_rid, &num_mem, rid_mem, &attr_mem);
+
+ if (res3 && num_mem != 0)
+ {
+ uint32 *rid_copy = (uint32*)malloc(num_mem *
+ sizeof(rid_copy[0]));
+
+ if (rid_copy != NULL)
+ {
+ uint32 i;
+ for (i = 0; i < num_mem; i++)
+ {
+ rid_copy[i] = (*rid_mem)[i];
+ }
+ /* resolve names */
+ res3 = samr_query_lookup_rids( pol_dom, 1000,
+ num_mem, rid_copy, num_names, name, type);
+
+ free(rid_copy);
+ }
+ }
+ else
+ {
+ if (attr_mem != NULL)
+ {
+ free(attr_mem);
+ }
+ if ((*rid_mem) != NULL)
+ {
+ free(*rid_mem);
+ }
+ attr_mem = NULL;
+ *rid_mem = NULL;
+ }
+
+ if (!res3)
+ {
+ free_char_array(*num_names, *name);
+ if ((*type) != NULL)
+ {
+ free(*type);
+ }
+ *num_names = 0;
+ *name = NULL;
+ *type = NULL;
+ }
+
+ if (attr_mem != NULL)
+ {
+ free(attr_mem);
+ }
+
+ return res3;
+}
+
+BOOL query_groupinfo( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ GROUP_INFO_FN(grp_inf))
+{
+ GROUP_INFO_CTR ctr;
+
+ /* send group info query */
+ if (get_samr_query_groupinfo( pol_dom,
+ 1, /* info level */
+ group_rid, &ctr))
+ {
+ if (grp_inf != NULL)
+ {
+ grp_inf(domain, sid, group_rid, &ctr);
+ }
+ return True;
+ }
+ return False;
+}
+
+BOOL req_groupmem_info( const POLICY_HND *pol_dom,
+ const char *domain,
+ const DOM_SID *sid,
+ uint32 group_rid,
+ const char *group_name,
+ GROUP_MEM_FN(grp_mem))
+{
+ uint32 num_names = 0;
+ char **name = NULL;
+ uint32 *type = NULL;
+ uint32 *rid_mem = NULL;
+
+ if (sam_query_groupmem(pol_dom, group_rid,
+ &num_names, &rid_mem, &name, &type))
+ {
+ grp_mem(domain, sid,
+ group_rid, group_name,
+ num_names, rid_mem, name, type);
+
+ free_char_array(num_names, name);
+ if (type != NULL)
+ {
+ free(type);
+ }
+ if (rid_mem != NULL)
+ {
+ free(rid_mem);
+ }
+ return True;
+ }
+ return False;
+}
+
+/****************************************************************************
+SAM Domains query.
+ DOMAIN_INFO_FN(dom_inf_fn),
+ DOMAIN_MEM_FN(dom_mem_fn))
+****************************************************************************/
+uint32 msrpc_sam_get_first_domain( const char* srv_name,
+ char *dom_name,
+ DOM_SID *dom_sid)
+{
+ BOOL res = True;
+ uint32 ace_perms = 0x02000000; /* access control permissions. */
+ POLICY_HND sam_pol;
+ uint32 status;
+ struct acct_info *sam = NULL;
+ uint32 num_sam_entries = 0;
+ uint32 domain_idx;
+ uint32 start_idx = 0;
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, ace_perms, &sam_pol) : False;
+
+ if (!res)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* read some domains */
+ do
+ {
+ status = samr_enum_domains( &sam_pol,
+ &start_idx, 0x10000,
+ &sam, &num_sam_entries);
+
+ } while (status == STATUS_MORE_ENTRIES);
+
+ for (domain_idx = 0; status == 0x0 &&
+ domain_idx < num_sam_entries; domain_idx++)
+ {
+ fstrcpy(dom_name, sam[domain_idx].acct_name);
+
+ if (strequal("BUILTIN", dom_name))
+ {
+ dom_name[0] = 0;
+ continue;
+ }
+ /* connect to the domain */
+ if (samr_query_lookup_domain( &sam_pol, dom_name, dom_sid))
+ {
+ status = 0x0;
+ break;
+ }
+ else
+ {
+ status = NT_STATUS_NO_SUCH_DOMAIN;
+ }
+ }
+
+ res = res ? samr_close(&sam_pol) : False;
+
+ safe_free(sam);
+
+ return status;
+}
+
+/****************************************************************************
+SAM Domains query.
+ DOMAIN_INFO_FN(dom_inf_fn),
+ DOMAIN_MEM_FN(dom_mem_fn))
+****************************************************************************/
+uint32 msrpc_sam_enum_domains( const char* srv_name,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ DOMAIN_FN(dom_fn),
+ DOMAIN_INFO_FN(dom_inf_fn))
+{
+ BOOL res = True;
+ uint32 ace_perms = 0x02000000; /* access control permissions. */
+ POLICY_HND sam_pol;
+ uint32 status;
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, ace_perms,
+ &sam_pol) : False;
+
+ (*sam) = NULL;
+ (*num_sam_entries) = 0;
+
+ if (res)
+ {
+ uint32 domain_idx;
+ uint32 start_idx = 0;
+ /* read some domains */
+ do
+ {
+ status = samr_enum_domains( &sam_pol,
+ &start_idx, 0x10000,
+ sam, num_sam_entries);
+
+ } while (status == STATUS_MORE_ENTRIES);
+
+#if 0
+ if ((*num_sam_entries) == 0)
+ {
+ report(out_hnd, "No domains\n");
+ }
+#endif
+
+ for (domain_idx = 0; domain_idx < (*num_sam_entries); domain_idx++)
+ {
+ char *domain_name = (*sam)[domain_idx].acct_name;
+
+ if (dom_fn != NULL)
+ {
+ dom_fn(domain_name);
+ }
+
+ if (dom_inf_fn != NULL)
+ {
+ uint32 switch_value = 2;
+ SAM_UNK_CTR ctr;
+ DOM_SID dom_sid;
+ /* connect to the domain */
+ if (samr_query_lookup_domain( &sam_pol,
+ domain_name,
+ &dom_sid) &&
+ sam_query_dominfo(srv_name, &dom_sid,
+ switch_value, &ctr))
+ {
+ dom_inf_fn(domain_name, &dom_sid,
+ switch_value, &ctr);
+ }
+ }
+ }
+ }
+
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (res)
+ {
+ DEBUG(5,("msrpc_sam_enum_domains: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("msrpc_sam_enum_domains: failed\n"));
+ }
+ return (*num_sam_entries);
+}
+
+/****************************************************************************
+SAM groups query.
+****************************************************************************/
+uint32 msrpc_sam_enum_groups( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ GROUP_FN(grp_fn),
+ GROUP_INFO_FN(grp_inf_fn),
+ GROUP_MEM_FN(grp_mem_fn))
+{
+ BOOL res = True;
+ uint32 ace_perms = 0x02000000; /* access control permissions. */
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ uint32 status;
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, sid1,
+ &pol_dom) : False;
+
+ (*sam) = NULL;
+ (*num_sam_entries) = 0;
+
+ if (res)
+ {
+ uint32 group_idx;
+ uint32 start_idx = 0;
+ /* read some groups */
+ do
+ {
+ status = samr_enum_dom_groups( &pol_dom,
+ &start_idx, 0x100000,
+ sam, num_sam_entries);
+
+ } while (status == STATUS_MORE_ENTRIES);
+
+#if 0
+ if ((*num_sam_entries) == 0)
+ {
+ report(out_hnd, "No groups\n");
+ }
+#endif
+
+ for (group_idx = 0; group_idx < (*num_sam_entries); group_idx++)
+ {
+ uint32 group_rid = (*sam)[group_idx].rid;
+ char *group_name = (*sam)[group_idx].acct_name;
+
+ if (grp_fn != NULL)
+ {
+ grp_fn(domain, sid1, group_rid, group_name);
+ }
+
+ if (grp_inf_fn != NULL)
+ {
+ query_groupinfo(&pol_dom,
+ domain, sid1,
+ group_rid,
+ grp_inf_fn);
+ }
+ if (grp_mem_fn != NULL)
+ {
+ req_groupmem_info(&pol_dom,
+ domain, sid1,
+ group_rid, group_name,
+ grp_mem_fn);
+ }
+ }
+ }
+
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (res)
+ {
+ DEBUG(5,("msrpc_sam_enum_groups: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("msrpc_sam_enum_groups: failed\n"));
+ }
+ return (*num_sam_entries);
+}
+
+/****************************************************************************
+SAM aliases query.
+****************************************************************************/
+uint32 msrpc_sam_enum_aliases( const char* srv_name,
+ const char* domain,
+ const DOM_SID *sid1,
+ struct acct_info **sam,
+ uint32 *num_sam_entries,
+ ALIAS_FN(als_fn),
+ ALIAS_INFO_FN(als_inf_fn),
+ ALIAS_MEM_FN(als_mem_fn))
+{
+ BOOL res = True;
+ uint32 ace_perms = 0x02000000; /* access control permissions */
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ uint32 status = 0x0;
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, sid1,
+ &pol_dom) : False;
+
+ (*sam) = NULL;
+ (*num_sam_entries) = 0;
+
+ if (res)
+ {
+ uint32 alias_idx;
+ uint32 start_idx = 0;
+ /* read some groups */
+ do
+ {
+ status = samr_enum_dom_aliases( &pol_dom,
+ &start_idx, 0x100000,
+ sam, num_sam_entries);
+
+ } while (status == STATUS_MORE_ENTRIES);
+
+#if 0
+ if ((*num_sam_entries) == 0)
+ {
+ report(out_hnd, "No aliases\n");
+ }
+#endif
+
+ for (alias_idx = 0; alias_idx < (*num_sam_entries); alias_idx++)
+ {
+ uint32 alias_rid = (*sam)[alias_idx].rid;
+ char *alias_name = (*sam)[alias_idx].acct_name;
+
+ if (als_fn != NULL)
+ {
+ als_fn(domain, sid1, alias_rid, alias_name);
+ }
+
+ if (als_inf_fn != NULL)
+ {
+ query_aliasinfo(&pol_dom,
+ domain, sid1,
+ alias_rid,
+ als_inf_fn);
+ }
+ if (als_mem_fn != NULL)
+ {
+ req_aliasmem_info(srv_name, &pol_dom,
+ domain, sid1,
+ alias_rid, alias_name,
+ als_mem_fn);
+ }
+ }
+ }
+
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (res)
+ {
+ DEBUG(5,("msrpc_sam_enum_aliases: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("msrpc_sam_enum_aliases: failed\n"));
+ }
+
+ return (*num_sam_entries);
+}
+
+/****************************************************************************
+do a SAMR create domain user
+****************************************************************************/
+BOOL create_samr_domain_user( POLICY_HND *pol_dom,
+ char *acct_name, uint16 acb_info,
+ const char* password, int plen,
+ uint32 *rid)
+{
+ POLICY_HND pol_open_user;
+ BOOL ret = True;
+ BOOL res1 = True;
+ char pwbuf[516];
+ SAM_USER_INFO_24 *p24;
+ SAM_USER_INFO_10 *p10;
+ SAM_USERINFO_CTR ctr;
+
+ if (pol_dom == NULL || acct_name == NULL) return False;
+
+ /* send create user */
+ ret = samr_create_dom_user( pol_dom,
+ acct_name, acb_info, 0xe005000b,
+ &pol_open_user, rid);
+
+ if (ret == 0x0)
+ {
+ samr_close(&pol_open_user);
+ }
+
+ if (ret != 0 && ret != (NT_STATUS_USER_EXISTS))
+ {
+ return False;
+ }
+
+ if (ret == (NT_STATUS_USER_EXISTS))
+ {
+ uint32 num_rids;
+ char *names[1];
+ uint32 *types = NULL;
+ uint32 *rids = NULL;
+
+ names[0] = acct_name;
+ res1 = samr_query_lookup_names( pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rids, &types);
+ if (res1 == False || types[0] != SID_NAME_USER)
+ {
+ if(rids)
+ free(rids);
+ if(types)
+ free(types);
+ return False;
+ }
+
+ *rid = rids[0];
+
+ safe_free(rids);
+ safe_free(types);
+ }
+
+ DEBUG(5,("create_samr_domain_user: name: %s rid 0x%x\n",
+ acct_name, *rid));
+
+ if (IS_BITS_SET_SOME(acb_info, ACB_NORMAL | ACB_DOMTRUST) &&
+ password == NULL)
+ {
+ DEBUG(10,("create_samr_dom_user: null password\n"));
+ return True;
+ }
+
+ encode_pw_buffer(pwbuf, password, plen, False);
+
+ p24 = (SAM_USER_INFO_24*)malloc(sizeof(SAM_USER_INFO_24));
+ if (p24 == NULL)
+ {
+ return False;
+ }
+
+ make_sam_user_info24(p24, pwbuf, plen);
+
+ res1 = set_samr_set_userinfo( pol_dom, 0x18, *rid, (void*)p24);
+
+ if (!res1)
+ {
+ DEBUG(10,("sam_set_userinfo: failed\n"));
+ return False;
+ }
+
+ DEBUG(10,("create_samr_dom_user: succeeded\n"));
+
+ ZERO_STRUCT(ctr);
+
+ /* send set user info */
+ res1 = get_samr_query_userinfo( pol_dom, 0x10, *rid, &ctr);
+
+ if (res1 == False)
+ {
+ return False;
+ }
+
+ p10 = ctr.info.id10;
+
+ if (p10 != NULL && p10->acb_info != acb_info)
+ {
+ p10->acb_info = acb_info;
+
+ res1 = set_samr_set_userinfo2( pol_dom, 0x10, *rid, (void*)p10);
+ }
+ else
+ {
+ free_samr_userinfo_ctr(&ctr);
+ }
+ return res1;
+}
+
+/****************************************************************************
+do a SAMR create domain alias
+****************************************************************************/
+BOOL create_samr_domain_alias( POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid)
+{
+ POLICY_HND pol_open_alias;
+ ALIAS_INFO_CTR ctr;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
+
+ /* send create alias */
+ if (!samr_create_dom_alias( pol_open_domain,
+ acct_name,
+ &pol_open_alias, rid))
+ {
+ return False;
+ }
+
+ DEBUG(5,("create_samr_domain_alias: name: %s rid 0x%x\n",
+ acct_name, *rid));
+
+ ctr.switch_value1 = 3;
+ make_samr_alias_info3(&ctr.alias.info3, acct_desc);
+
+ /* send set alias info */
+ if (!samr_set_aliasinfo( &pol_open_alias,
+ &ctr))
+ {
+ DEBUG(5,("create_samr_domain_alias: error in samr_set_aliasinfo\n"));
+ ret = False;
+ }
+
+ return samr_close(&pol_open_alias) && ret;
+}
+
+/****************************************************************************
+do a SAMR create domain group
+****************************************************************************/
+BOOL create_samr_domain_group( POLICY_HND *pol_open_domain,
+ const char *acct_name, const char *acct_desc,
+ uint32 *rid)
+{
+ POLICY_HND pol_open_group;
+ GROUP_INFO_CTR ctr;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || acct_name == NULL || acct_desc == NULL) return False;
+
+ /* send create group*/
+ if (!samr_create_dom_group( pol_open_domain,
+ acct_name,
+ &pol_open_group, rid))
+ {
+ return False;
+ }
+
+ DEBUG(5,("create_samr_domain_group: name: %s rid 0x%x\n",
+ acct_name, *rid));
+
+ ctr.switch_value1 = 4;
+ ctr.switch_value2 = 4;
+ make_samr_group_info4(&ctr.group.info4, acct_desc);
+
+ /* send user groups query */
+ if (!samr_set_groupinfo( &pol_open_group,
+ &ctr))
+ {
+ DEBUG(5,("create_samr_domain_group: error in samr_set_groupinfo\n"));
+ ret = False;
+ }
+
+ return samr_close(&pol_open_group) && ret;
+}
+
+/****************************************************************************
+do a SAMR query user groups
+****************************************************************************/
+BOOL get_samr_query_usergroups( const POLICY_HND *pol_open_domain,
+ uint32 user_rid,
+ uint32 *num_groups, DOM_GID **gid)
+{
+ POLICY_HND pol_open_user;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || num_groups == NULL || gid == NULL) return False;
+
+ /* send open domain (on user sid) */
+ if (!samr_open_user( pol_open_domain,
+ 0x02011b, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user groups query */
+ if (!samr_query_usergroups( &pol_open_user, num_groups, gid))
+ {
+ DEBUG(5,("samr_query_usergroups: error in query user groups\n"));
+ ret = False;
+ }
+
+ return samr_close(&pol_open_user) && ret;
+}
+
+/****************************************************************************
+do a SAMR delete group
+****************************************************************************/
+BOOL delete_samr_dom_group( POLICY_HND *pol_open_domain,
+ uint32 group_rid)
+{
+ POLICY_HND pol_open_group;
+
+ if (pol_open_domain == NULL) return False;
+
+ /* send open domain (on group rid) */
+ if (!samr_open_group(pol_open_domain,
+ 0x00000010, group_rid,
+ &pol_open_group))
+ {
+ return False;
+ }
+
+ /* send group delete */
+ if (!samr_delete_dom_group(&pol_open_group))
+
+ {
+ DEBUG(5,("delete_samr_dom_group: error in delete domain group\n"));
+ samr_close(&pol_open_group);
+ return False;
+ }
+
+ return True;
+}
+
+
+/****************************************************************************
+do a SAMR query group members
+****************************************************************************/
+BOOL get_samr_query_groupmem(
+ const POLICY_HND *pol_open_domain,
+ uint32 group_rid, uint32 *num_mem,
+ uint32 **rid, uint32 **attr)
+{
+ POLICY_HND pol_open_group;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || num_mem == NULL || rid == NULL || attr == NULL) return False;
+
+ /* send open domain (on group sid) */
+ if (!samr_open_group( pol_open_domain,
+ 0x00000010, group_rid,
+ &pol_open_group))
+ {
+ return False;
+ }
+
+ /* send group info query */
+ if (!samr_query_groupmem(&pol_open_group, num_mem, rid, attr))
+
+ {
+ DEBUG(5,("samr_query_group: error in query group members\n"));
+ ret = False;
+ }
+
+ return samr_close(&pol_open_group) && ret;
+}
+
+/****************************************************************************
+do a SAMR delete alias
+****************************************************************************/
+BOOL delete_samr_dom_alias(
+ POLICY_HND *pol_open_domain,
+ uint32 alias_rid)
+{
+ POLICY_HND pol_open_alias;
+
+ if (pol_open_domain == NULL) return False;
+
+ /* send open domain (on alias rid) */
+ if (!samr_open_alias(pol_open_domain,
+ 0x000f001f, alias_rid, &pol_open_alias))
+ {
+ return False;
+ }
+
+ /* send alias delete */
+ if (!samr_delete_dom_alias(&pol_open_alias))
+
+ {
+ DEBUG(5,("delete_samr_dom_alias: error in delete domain alias\n"));
+ samr_close(&pol_open_alias);
+ return False;
+ }
+
+ return True;
+}
+
+
+/****************************************************************************
+do a SAMR query alias members
+****************************************************************************/
+BOOL get_samr_query_aliasmem(
+ const POLICY_HND *pol_open_domain,
+ uint32 alias_rid, uint32 *num_mem, DOM_SID2 *sid)
+{
+ POLICY_HND pol_open_alias;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || num_mem == NULL || sid == NULL) return False;
+
+ /* send open domain (on alias sid) */
+ if (!samr_open_alias( pol_open_domain,
+ 0x000f001f, alias_rid,
+ &pol_open_alias))
+ {
+ return False;
+ }
+
+ /* send alias info query */
+ if (!samr_query_aliasmem( &pol_open_alias, num_mem, sid))
+
+ {
+ DEBUG(5,("samr_query_alias: error in query alias members\n"));
+ ret = False;
+ }
+
+ return samr_close(&pol_open_alias) && ret;
+}
+
+/****************************************************************************
+do a SAMR set user info
+****************************************************************************/
+BOOL set_samr_set_userinfo2(
+ POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, void *usr)
+{
+ POLICY_HND pol_open_user;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || usr == NULL) return False;
+
+ /* send open domain (on user sid) */
+ if (!samr_open_user( pol_open_domain,
+ 0x000601b4, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user info query */
+ if (!samr_set_userinfo2( &pol_open_user, info_level, usr))
+ {
+ DEBUG(5,("samr_set_userinfo2: error in query user info, level 0x%x\n",
+ info_level));
+ ret = False;
+ }
+
+ return samr_close(&pol_open_user) && ret;
+}
+
+/****************************************************************************
+do a SAMR set user info
+****************************************************************************/
+BOOL set_samr_set_userinfo( const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, void *usr)
+{
+ POLICY_HND pol_open_user;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || usr == NULL) return False;
+
+ /* send open domain (on user sid) */
+ if (!samr_open_user( pol_open_domain,
+ 0x000601b4, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user info query */
+ if (!samr_set_userinfo( &pol_open_user, info_level, usr))
+ {
+ DEBUG(5,("samr_set_userinfo: error in query user info, level 0x%x\n",
+ info_level));
+ ret = False;
+ }
+
+ return samr_close(&pol_open_user) && ret;
+}
+
+/****************************************************************************
+do a SAMR query user info
+****************************************************************************/
+BOOL get_samr_query_userinfo( const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 user_rid, SAM_USERINFO_CTR *ctr)
+{
+ POLICY_HND pol_open_user;
+ BOOL ret = True;
+
+ DEBUG(10,("get_samr_query_userinfo: info_level: %d rid: %x\n",
+ info_level, user_rid));
+
+ if (pol_open_domain == NULL || ctr == NULL) return False;
+
+ /* send open domain (on user sid) */
+ if (!samr_open_user( pol_open_domain,
+ 0x02011b, user_rid,
+ &pol_open_user))
+ {
+ return False;
+ }
+
+ /* send user info query */
+ if (!samr_query_userinfo( &pol_open_user, info_level, ctr))
+ {
+ DEBUG(5,("samr_query_userinfo: error in query user info, level 0x%x\n",
+ info_level));
+ ret = False;
+ }
+
+ return samr_close(&pol_open_user) && ret;
+}
+
+/****************************************************************************
+do a SAMR query group info
+****************************************************************************/
+BOOL get_samr_query_groupinfo(
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 group_rid, GROUP_INFO_CTR *ctr)
+{
+ POLICY_HND pol_open_group;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || ctr == NULL) return False;
+
+ bzero(ctr, sizeof(*ctr));
+
+ /* send open domain (on group sid) */
+ if (!samr_open_group( pol_open_domain,
+ 0x02000000, group_rid, &pol_open_group))
+ {
+ return False;
+ }
+
+ /* send group info query */
+ if (!samr_query_groupinfo( &pol_open_group, info_level, ctr))
+ {
+ DEBUG(5,("samr_query_groupinfo: error in query group info, level 0x%x\n",
+ info_level));
+ ret = False;
+ }
+
+ return samr_close(&pol_open_group) && ret;
+}
+
+/****************************************************************************
+do a SAMR query alias info
+****************************************************************************/
+BOOL get_samr_query_aliasinfo(
+ const POLICY_HND *pol_open_domain,
+ uint32 info_level,
+ uint32 alias_rid, ALIAS_INFO_CTR *ctr)
+{
+ POLICY_HND pol_open_alias;
+ BOOL ret = True;
+
+ if (pol_open_domain == NULL || ctr == NULL) return False;
+
+ bzero(ctr, sizeof(*ctr));
+
+ /* send open domain (on alias sid) */
+ if (!samr_open_alias( pol_open_domain,
+ 0x02000000, alias_rid, &pol_open_alias))
+ {
+ return False;
+ }
+
+ /* send alias info query */
+ if (!samr_query_aliasinfo( &pol_open_alias, info_level, ctr))
+ {
+ DEBUG(5,("samr_query_aliasinfo: error in query alias info, level 0x%x\n",
+ info_level));
+ ret = False;
+ }
+
+ return samr_close(&pol_open_alias) && ret;
+}
+
+/****************************************************************************
+SAM create domain user.
+****************************************************************************/
+BOOL msrpc_sam_create_dom_user(const char* srv_name, DOM_SID *sid1,
+ char *acct_name, uint16 acb_info,
+ const char *password, int plen,
+ uint32 *rid)
+{
+ BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ uint32 user_rid;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ /* establish a connection. */
+ res = res ? samr_connect(
+ srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res1 = res ? samr_open_domain( &sam_pol, ace_perms, sid1,
+ &pol_dom) : False;
+
+ /* create a domain user */
+ res2 = res1 ? create_samr_domain_user( &pol_dom,
+ acct_name,
+ acb_info, password, plen, &user_rid) : False;
+
+ res1 = res1 ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ if (res2)
+ {
+ DEBUG(5,("msrpc_sam_create_dom_user: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("msrpc_sam_create_dom_user: failed\n"));
+ }
+
+ return res2;
+}
+
+/****************************************************************************
+experimental SAM query display info.
+****************************************************************************/
+BOOL msrpc_sam_query_dispinfo(const char* srv_name, const char* domain,
+ DOM_SID *sid1,
+ uint16 switch_value,
+ uint32 *num_entries, SAM_DISPINFO_CTR *ctr,
+ DISP_FN(disp_fn))
+{
+ BOOL res = True;
+ BOOL res1 = True;
+ uint32 ace_perms = 0x304; /* absolutely no idea. */
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000, &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, sid1,
+ &pol_dom) : False;
+
+ /* send a samr query_disp_info command */
+ res1 = res ? samr_query_dispinfo( &pol_dom, switch_value,
+ num_entries, ctr) : False;
+
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (res1 && disp_fn != NULL)
+ {
+ disp_fn(domain, sid1, switch_value, *num_entries, ctr);
+ }
+
+ return res1;
+}
+
+/****************************************************************************
+SAM password change
+****************************************************************************/
+BOOL msrpc_sam_ntchange_pwd(const char* srv_name,
+ const char* domain,
+ const char *ntuser,
+ const uchar lm_oldhash[16],
+ const uchar nt_oldhash[16],
+ const char* new_passwd)
+{
+ BOOL ret;
+
+ char nt_newpass[516];
+ uchar nt_hshhash[16];
+ uchar nt_newhash[16];
+
+ char lm_newpass[516];
+ uchar lm_newhash[16];
+ uchar lm_hshhash[16];
+
+ extern struct user_creds *usr_creds;
+ struct ntuser_creds samr_creds;
+
+ copy_nt_creds(&samr_creds, usr_creds != NULL ? &usr_creds->ntc : NULL);
+
+ if (ntuser != NULL)
+ {
+ safe_strcpy(samr_creds.user_name, ntuser,
+ sizeof(samr_creds.user_name)-1);
+ }
+
+ if (domain != NULL)
+ {
+ safe_strcpy(samr_creds.domain, ntuser,
+ sizeof(samr_creds.domain)-1);
+ }
+
+ if (lm_oldhash != NULL || nt_oldhash != NULL)
+ {
+ pwd_set_lm_nt_16(&samr_creds.pwd, lm_oldhash, nt_oldhash);
+ }
+
+ samr_creds.ntlmssp_flags = NTLMSSP_NEGOTIATE_UNICODE |
+ NTLMSSP_NEGOTIATE_OEM |
+ NTLMSSP_NEGOTIATE_SIGN |
+ NTLMSSP_NEGOTIATE_SEAL |
+ NTLMSSP_NEGOTIATE_LM_KEY |
+ NTLMSSP_NEGOTIATE_NTLM |
+ NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
+ NTLMSSP_NEGOTIATE_00001000 |
+ NTLMSSP_NEGOTIATE_00002000;
+
+ nt_lm_owf_gen(new_passwd, nt_newhash, lm_newhash);
+ make_oem_passwd_hash(nt_newpass, new_passwd, 0, nt_oldhash, True);
+ make_oem_passwd_hash(lm_newpass, new_passwd, 0, lm_oldhash, True);
+ E_old_pw_hash(nt_newhash, lm_oldhash, lm_hshhash);
+ E_old_pw_hash(nt_newhash, nt_oldhash, nt_hshhash);
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, nt_newhash, 16);
+ dump_data(100, lm_oldhash, 16);
+ dump_data(100, lm_hshhash, 16);
+#endif
+
+ ret = msrpc_sam_ntpasswd_set(srv_name, ntuser, &samr_creds,
+ lm_newpass, lm_hshhash,
+ nt_newpass, nt_hshhash);
+ return ret;
+}
+
+/****************************************************************************
+SAM password change
+****************************************************************************/
+BOOL msrpc_sam_ntpasswd_set(const char* srv_name, const char *user,
+ struct ntuser_creds *samr_creds,
+ const uchar lm_newpass[516],
+ const uchar lm_hshhash[16],
+ const uchar nt_newpass[516],
+ const uchar nt_hshhash[16])
+{
+ BOOL res = True;
+ BOOL res1 = True;
+
+ struct cli_connection *con = NULL;
+ extern cli_auth_fns cli_ntlmssp_fns;
+
+ DEBUG(10,("msrpc_sam_ntpasswd_set: user: %s\n", user));
+
+ /* open SAMR session. */
+ res = res ? cli_connection_init_auth(srv_name, PIPE_SAMR, &con,
+ samr_creds != NULL ? &cli_ntlmssp_fns : NULL,
+ (void*)samr_creds) : False;
+
+ res1 = res ? samr_get_dom_pwinfo(con, srv_name) : False;
+ res1 = res1 ? samr_chgpasswd_user(con, srv_name, user,
+ nt_newpass, nt_hshhash,
+ lm_newpass, lm_hshhash) : False;
+ /* close the session */
+ if (res)
+ {
+ cli_connection_unlink(con);
+ }
+
+ return res1;
+}
+
+/****************************************************************************
+experimental SAM user query.
+****************************************************************************/
+BOOL msrpc_sam_query_userinfo(const char* srv_name, const DOM_SID *sid,
+ const char *user_name, uint16 info_level,
+ SAM_USERINFO_CTR *ctr)
+{
+ BOOL res = True;
+ BOOL res1 = True;
+
+ char *names[1];
+ uint32 num_rids;
+ uint32 *rids = NULL;
+ uint32 *types = NULL;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ /* establish a connection to a domain */
+ res = res ? samr_connect( srv_name, 0x02000000, &sam_pol) : False;
+ res = res ? samr_open_domain( &sam_pol, 0x304, sid, &pol_dom) : False;
+
+ /* look up user rid */
+ names[0] = strdup(user_name);
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+ safe_free(names[0]);
+
+ /* send user info query */
+ if (res1 && num_rids == 1)
+ {
+ res1 = get_samr_query_userinfo( &pol_dom,
+ info_level, rids[0], ctr);
+ }
+ else
+ {
+ res1 = False;
+ }
+
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ if (res1)
+ {
+ DEBUG(5,("msrpc_sam_query_userinfo: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("msrpc_sam_query_userinfo: failed\n"));
+ }
+
+ safe_free(rids);
+ safe_free(types);
+
+ return res1;
+}
diff --git a/source/rpc_client/ncacn_np_use.c b/source/rpc_client/ncacn_np_use.c
new file mode 100644
index 00000000000..df0a6026fad
--- /dev/null
+++ b/source/rpc_client/ncacn_np_use.c
@@ -0,0 +1,487 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client generic functions
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define NO_SYSLOG
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "trans2.h"
+
+extern int DEBUGLEVEL;
+extern pstring global_myname;
+
+struct ncacn_np_use
+{
+ struct ncacn_np *cli;
+ uint32 num_users;
+};
+
+static struct ncacn_np_use **msrpcs = NULL;
+uint32 num_msrpcs = 0;
+
+/****************************************************************************
+terminate client connection
+****************************************************************************/
+static void ncacn_np_shutdown(struct ncacn_np *cli)
+{
+ if (cli != NULL)
+ {
+ if (cli->smb != NULL)
+ {
+ if (cli->smb->initialised)
+ {
+ cli_nt_session_close(cli->smb, cli->fnum);
+ }
+ cli_net_use_del(cli->smb->desthost,
+ &cli->smb->usr, False, False);
+ }
+ }
+}
+
+BOOL ncacn_np_establish_connection(struct ncacn_np *cli,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ const char *pipe_name, BOOL redir,
+ BOOL reuse)
+{
+ BOOL new_smb_conn;
+ cli->smb = cli_net_use_add(srv_name, ntc, redir, reuse,
+ &new_smb_conn);
+ if (cli->smb == NULL)
+ {
+ return False;
+ }
+ if (!cli_nt_session_open(cli->smb, pipe_name, &cli->fnum))
+ {
+ cli_net_use_del(srv_name, ntc, False, NULL);
+ return False;
+ }
+ fstrcpy(cli->pipe_name, pipe_name);
+ dump_data_pw("sess key:", cli->smb->nt.usr_sess_key, 16);
+ return True;
+}
+
+/****************************************************************************
+terminate client connection
+****************************************************************************/
+static void ncacn_np_use_free(struct ncacn_np_use *cli)
+{
+ if (cli->cli != NULL)
+ {
+ if (cli->cli->initialised)
+ {
+ ncacn_np_shutdown(cli->cli);
+ }
+ ZERO_STRUCTP(cli->cli);
+ free(cli->cli);
+ }
+ ZERO_STRUCTP(cli);
+ free(cli);
+}
+
+/****************************************************************************
+free a client array
+****************************************************************************/
+static void free_ncacn_np_array(uint32 num_entries,
+ struct ncacn_np_use **entries)
+{
+ void (*fn) (void *) = (void (*)(void *))&ncacn_np_use_free;
+ free_void_array(num_entries, (void **)entries, *fn);
+}
+
+/****************************************************************************
+add a client state to the array
+****************************************************************************/
+static struct ncacn_np_use *add_ncacn_np_to_array(uint32 * len,
+ struct ncacn_np_use
+ ***array,
+ struct ncacn_np_use *cli)
+{
+ int i;
+ for (i = 0; i < num_msrpcs; i++)
+ {
+ if (msrpcs[i] == NULL)
+ {
+ msrpcs[i] = cli;
+ return cli;
+ }
+ }
+
+ return (struct ncacn_np_use *)add_item_to_array(len,
+ (void ***)array,
+ (void *)cli);
+
+}
+
+/****************************************************************************
+initiate client array
+****************************************************************************/
+void init_ncacn_np_use(void)
+{
+ msrpcs = NULL;
+ num_msrpcs = 0;
+}
+
+/****************************************************************************
+terminate client array
+****************************************************************************/
+void free_ncacn_np_use(void)
+{
+ free_ncacn_np_array(num_msrpcs, msrpcs);
+ init_ncacn_np_use();
+}
+
+/****************************************************************************
+find client state. server name, user name, domain name and password must all
+match.
+****************************************************************************/
+static struct ncacn_np_use *ncacn_np_find(const char *srv_name,
+ const char *pipe_name,
+ const vuser_key * key,
+ const struct ntuser_creds
+ *usr_creds, BOOL reuse)
+{
+ int i;
+ const char *sv_name = srv_name;
+ struct ntuser_creds null_usr;
+
+ copy_nt_creds(&null_usr, usr_creds);
+ usr_creds = &null_usr;
+
+ if (strnequal("\\PIPE\\", pipe_name, 6))
+ {
+ pipe_name = &pipe_name[6];
+ }
+
+ if (strnequal("\\\\", sv_name, 2))
+ {
+ sv_name = &sv_name[2];
+ }
+
+ DEBUG(10, ("cli_find: %s %s %s",
+ srv_name, usr_creds->user_name, usr_creds->domain));
+
+ if (key != NULL)
+ {
+ DEBUG(10, ("[%d,%x]", key->pid, key->vuid));
+ }
+ DEBUG(10, ("\n"));
+
+ for (i = 0; i < num_msrpcs; i++)
+ {
+ char *cli_name = NULL;
+ struct ncacn_np_use *c = msrpcs[i];
+ vuser_key k;
+
+ char *ncacn_np_name = NULL;
+
+ if (c == NULL || c->cli == NULL || c->cli->smb == NULL ||
+ !c->cli->initialised)
+ {
+ continue;
+ }
+
+ ncacn_np_name = c->cli->pipe_name;
+ cli_name = c->cli->smb->desthost;
+
+ k = c->cli->smb->nt.key;
+
+ DEBUG(10, ("ncacn_np_find[%d]: %s %s %s %s [%d,%x]\n",
+ i, ncacn_np_name, cli_name,
+ c->cli->smb->usr.user_name,
+ c->cli->smb->usr.domain, k.pid, k.vuid));
+
+ if (strnequal("\\\\", cli_name, 2))
+ {
+ cli_name = &cli_name[2];
+ }
+
+ if (strnequal("\\PIPE\\", ncacn_np_name, 6))
+ {
+ ncacn_np_name = &ncacn_np_name[6];
+ }
+
+ if (!strequal(ncacn_np_name, pipe_name))
+ {
+ continue;
+ }
+ if (!strequal(cli_name, sv_name))
+ {
+ continue;
+ }
+ if (!strequal
+ (usr_creds->user_name, c->cli->smb->usr.user_name))
+ {
+ continue;
+ }
+ if (key != NULL && (k.pid != key->pid || k.vuid != key->vuid))
+ {
+ continue;
+ }
+ if (!reuse
+ && !pwd_compare(&usr_creds->pwd, &c->cli->smb->usr.pwd))
+ {
+ DEBUG(100, ("password doesn't match\n"));
+ continue;
+ }
+ if (usr_creds->domain[0] == 0)
+ {
+ return c;
+ }
+ if (strequal(usr_creds->domain, c->cli->smb->usr.domain))
+ {
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+initialise a msrpcent structure
+****************************************************************************/
+struct ncacn_np *ncacn_np_initialise(struct ncacn_np *msrpc,
+ const vuser_key * key)
+{
+ if (!msrpc)
+ {
+ msrpc = (struct ncacn_np *)malloc(sizeof(*msrpc));
+ if (!msrpc)
+ return NULL;
+ ZERO_STRUCTP(msrpc);
+ }
+
+ if (msrpc->initialised)
+ {
+ ncacn_np_shutdown(msrpc);
+ }
+
+ ZERO_STRUCTP(msrpc);
+
+ msrpc->fnum = -1;
+ msrpc->initialised = 1;
+
+ return msrpc;
+}
+
+/****************************************************************************
+create a new client state from user credentials
+****************************************************************************/
+static struct ncacn_np_use *ncacn_np_use_get(const char *pipe_name,
+ const vuser_key * key)
+{
+ struct ncacn_np_use *cli =
+ (struct ncacn_np_use *)malloc(sizeof(*cli));
+
+ if (cli == NULL)
+ {
+ return NULL;
+ }
+
+ memset(cli, 0, sizeof(*cli));
+
+ cli->cli = ncacn_np_initialise(NULL, key);
+
+ if (cli->cli == NULL)
+ {
+ return NULL;
+ }
+
+ return cli;
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+struct ncacn_np *ncacn_np_use_add(const char *pipe_name,
+ const vuser_key * key,
+ const char *srv_name,
+ const struct ntuser_creds *ntc,
+ BOOL redir,
+ BOOL reuse, BOOL *is_new_connection)
+{
+ struct ncacn_np_use *cli;
+ DEBUG(10, ("ncacn_np_use_add: %s redir: %s\n", pipe_name,
+ BOOLSTR(redir)));
+
+ (*is_new_connection) = False;
+ cli = ncacn_np_find(srv_name, pipe_name, key, ntc, reuse);
+
+ if (cli != NULL)
+ {
+ cli->num_users++;
+ return cli->cli;
+ }
+
+ /* reuse an existing connection requested, and one was not found */
+ if (reuse)
+ {
+ DEBUG(0,
+ ("ncacn_np_use_add: reuse requested, but one not found\n"));
+ return False;
+ }
+
+ /*
+ * allocate
+ */
+
+ (*is_new_connection) = True;
+
+ cli = ncacn_np_use_get(pipe_name, key);
+ cli->cli->redirect = redir;
+
+ if (!ncacn_np_establish_connection
+ (cli->cli, srv_name, ntc, pipe_name, redir, True))
+ {
+ DEBUG(0, ("ncacn_np_use_add: connection failed\n"));
+ cli->cli = NULL;
+ ncacn_np_use_free(cli);
+ return NULL;
+ }
+
+ if (key != NULL)
+ {
+ cli->cli->smb->nt.key = *key;
+ }
+ else
+ {
+ cli->cli->smb->nt.key.pid = getpid();
+ cli->cli->smb->nt.key.vuid = UID_FIELD_INVALID;
+#if 0
+ NET_USER_INFO_3 usr;
+ uid_t uid = getuid();
+ gid_t gid = getgid();
+ char *name = uidtoname(uid);
+
+ ZERO_STRUCT(usr);
+
+ cli->cli->smb->nt.key.pid = getpid();
+ cli->cli->smb->nt.key.vuid =
+ register_vuid(cli->cli->smb->nt.key.pid, uid, gid,
+ name, name, False, &usr);
+#endif
+ }
+
+ add_ncacn_np_to_array(&num_msrpcs, &msrpcs, cli);
+ cli->num_users++;
+ return cli->cli;
+}
+
+/****************************************************************************
+delete a client state
+****************************************************************************/
+BOOL ncacn_np_use_del(const char *pipe_name,
+ const vuser_key * key,
+ BOOL force_close, BOOL *connection_closed)
+{
+ int i;
+ DEBUG(10, ("ncacn_np_net_use_del: %s. force close: %s ",
+ pipe_name, BOOLSTR(force_close)));
+ if (key != NULL)
+ {
+ DEBUG(10, ("[%d,%x]", key->pid, key->vuid));
+ }
+ DEBUG(10, ("\n"));
+
+ if (connection_closed != NULL)
+ {
+ *connection_closed = False;
+ }
+
+ if (strnequal("\\PIPE\\", pipe_name, 6))
+ {
+ pipe_name = &pipe_name[6];
+ }
+
+ for (i = 0; i < num_msrpcs; i++)
+ {
+ char *ncacn_np_name = NULL;
+ struct ncacn_np_use *c = msrpcs[i];
+ vuser_key k;
+
+ if (c == NULL || c->cli == NULL)
+ continue;
+
+ ncacn_np_name = c->cli->pipe_name;
+
+ k = c->cli->smb->nt.key;
+
+ DEBUG(10, ("use_del[%d]: %s %s %s [%d,%x]\n",
+ i, ncacn_np_name,
+ c->cli->smb->usr.user_name,
+ c->cli->smb->usr.domain, k.pid, k.vuid));
+
+ if (strnequal("\\PIPE\\", ncacn_np_name, 6))
+ {
+ ncacn_np_name = &ncacn_np_name[6];
+ }
+ if (!strequal(ncacn_np_name, pipe_name))
+ {
+ continue;
+ }
+ if (key->pid != k.pid || key->vuid != k.vuid)
+ {
+ continue;
+ }
+ /* decrement number of users */
+ c->num_users--;
+ DEBUG(10, ("idx: %i num_users now: %d\n",
+ i, c->num_users));
+ if (force_close || c->num_users == 0)
+ {
+ ncacn_np_use_free(c);
+ msrpcs[i] = NULL;
+ if (connection_closed != NULL)
+ {
+ *connection_closed = True;
+ }
+ }
+ return True;
+ }
+
+ return False;
+}
+
+/****************************************************************************
+enumerate client states
+****************************************************************************/
+void ncacn_np_use_enum(uint32 * num_cons, struct use_info ***use)
+{
+ int i;
+ *num_cons = 0;
+ *use = NULL;
+ for (i = 0; i < num_msrpcs; i++)
+ {
+ struct use_info item;
+ ZERO_STRUCT(item);
+ if (msrpcs[i] == NULL)
+ continue;
+ item.connected = msrpcs[i]->cli != NULL ? True : False;
+ if (item.connected)
+ {
+ item.srv_name = msrpcs[i]->cli->pipe_name;
+ item.key = msrpcs[i]->cli->smb->nt.key;
+ }
+
+ add_use_info_to_array(num_cons, use, &item);
+ }
+}
diff --git a/source/rpc_client/ncalrpc_l_use.c b/source/rpc_client/ncalrpc_l_use.c
new file mode 100644
index 00000000000..d479645b61d
--- /dev/null
+++ b/source/rpc_client/ncalrpc_l_use.c
@@ -0,0 +1,393 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client generic functions
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define NO_SYSLOG
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+struct ncalrpc_use
+{
+ struct msrpc_local *cli;
+ uint32 num_users;
+};
+
+static struct ncalrpc_use **clis = NULL;
+static uint32 num_clis = 0;
+
+/****************************************************************************
+terminate client connection
+****************************************************************************/
+static void ncalrpc_use_free(struct ncalrpc_use *cli)
+{
+ if (cli->cli != NULL)
+ {
+ if (cli->cli->initialised)
+ {
+ ncalrpc_l_shutdown(cli->cli);
+ }
+ free(cli->cli);
+ }
+
+ free(cli);
+}
+
+/****************************************************************************
+free a client array
+****************************************************************************/
+static void free_cli_array(uint32 num_entries, struct ncalrpc_use **entries)
+{
+ void (*fn) (void *) = (void (*)(void *))&ncalrpc_use_free;
+ free_void_array(num_entries, (void **)entries, *fn);
+}
+
+/****************************************************************************
+add a client state to the array
+****************************************************************************/
+static struct ncalrpc_use *add_cli_to_array(uint32 * len,
+ struct ncalrpc_use ***array,
+ struct ncalrpc_use *cli)
+{
+ int i;
+ for (i = 0; i < num_clis; i++)
+ {
+ if (clis[i] == NULL)
+ {
+ clis[i] = cli;
+ return cli;
+ }
+ }
+
+ return (struct ncalrpc_use *)add_item_to_array(len,
+ (void ***)array,
+ (void *)cli);
+
+}
+
+/****************************************************************************
+initiate client array
+****************************************************************************/
+void init_ncalrpc_use(void)
+{
+ clis = NULL;
+ num_clis = 0;
+}
+
+/****************************************************************************
+terminate client array
+****************************************************************************/
+void free_ncalrpc_use(void)
+{
+ free_cli_array(num_clis, clis);
+ init_ncalrpc_use();
+}
+
+/****************************************************************************
+find client state. server name, user name, vuid name and password must all
+match.
+****************************************************************************/
+static struct ncalrpc_use *ncalrpc_l_find(const char *pipe_name,
+ const vuser_key * key, BOOL reuse)
+{
+ int i;
+ vuser_key null_usr;
+
+ if (key == NULL)
+ {
+ key = &null_usr;
+ null_usr.pid = getpid();
+ null_usr.vuid = UID_FIELD_INVALID;
+ }
+
+ DEBUG(10, ("ncalrpc_l_find: %s [%d,%x]\n",
+ pipe_name, key->pid, key->vuid));
+
+ for (i = 0; i < num_clis; i++)
+ {
+ char *cli_name = NULL;
+ struct ncalrpc_use *c = clis[i];
+
+ if (c == NULL || !c->cli->initialised)
+ {
+ continue;
+ }
+
+ cli_name = c->cli->pipe_name;
+
+ DEBUG(10, ("ncalrpc_l_find[%d]: %s [%d,%x]\n",
+ i, cli_name,
+ c->cli->nt.key.pid, c->cli->nt.key.vuid));
+
+ if (!strequal(cli_name, pipe_name))
+ {
+ continue;
+ }
+ if (reuse)
+ {
+ return c;
+ }
+ if (key->vuid == c->cli->nt.key.vuid &&
+ key->pid == c->cli->nt.key.pid)
+ {
+ return c;
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+create a new client state from user credentials
+****************************************************************************/
+static struct ncalrpc_use *ncalrpc_use_get(const char *pipe_name,
+ const vuser_key * key)
+{
+ struct ncalrpc_use *cli = (struct ncalrpc_use *)malloc(sizeof(*cli));
+
+ if (cli == NULL)
+ {
+ return NULL;
+ }
+
+ memset(cli, 0, sizeof(*cli));
+
+ cli->cli = ncalrpc_l_initialise(NULL, key);
+
+ if (cli->cli == NULL)
+ {
+ return NULL;
+ }
+
+ return cli;
+}
+
+/****************************************************************************
+init client state
+****************************************************************************/
+struct msrpc_local *ncalrpc_l_use_add(const char *pipe_name,
+ const vuser_key * key,
+ BOOL redir, BOOL reuse, BOOL *is_new)
+{
+ struct ncalrpc_use *cli;
+
+ DEBUG(10, ("ncalrpc_l_use_add\n"));
+
+ if (strnequal("\\PIPE\\", pipe_name, 6))
+ {
+ pipe_name = &pipe_name[6];
+ }
+
+ cli = ncalrpc_l_find(pipe_name, key, reuse);
+
+ if (cli != NULL)
+ {
+ cli->num_users++;
+ DEBUG(10,
+ ("ncalrpc_l_use_add: num_users: %d\n", cli->num_users));
+ (*is_new) = False;
+ return cli->cli;
+ }
+
+ /* reuse an existing connection requested, and one was not found */
+ if (key != NULL && reuse && !redir)
+ {
+ return False;
+ }
+
+ /*
+ * allocate
+ */
+
+ cli = ncalrpc_use_get(pipe_name, key);
+ cli->cli->redirect = redir;
+
+ /*
+ * connect
+ */
+
+ if (!ncalrpc_l_establish_connection(cli->cli, pipe_name))
+ {
+ DEBUG(0, ("ncalrpc_l_use_add: connection failed\n"));
+ cli->cli = NULL;
+ ncalrpc_use_free(cli);
+ return NULL;
+ }
+
+ add_cli_to_array(&num_clis, &clis, cli);
+ cli->num_users++;
+
+ DEBUG(10, ("ncalrpc_l_use_add: num_users: %d\n", cli->num_users));
+
+ (*is_new) = True;
+
+ return cli->cli;
+}
+
+/****************************************************************************
+delete a client state
+****************************************************************************/
+BOOL ncalrpc_l_use_del(const char *pipe_name,
+ const vuser_key * key,
+ BOOL force_close, BOOL *connection_closed)
+{
+ int i;
+
+ if (strnequal("\\PIPE\\", pipe_name, 6))
+ {
+ pipe_name = &pipe_name[6];
+ }
+
+ DEBUG(10, ("ncalrpc_l_use_del: %s. [%d,%x] force close: %s\n",
+ pipe_name, key->pid, key->vuid, BOOLSTR(force_close)));
+
+ if (connection_closed != NULL)
+ {
+ *connection_closed = False;
+ }
+
+ for (i = 0; i < num_clis; i++)
+ {
+ char *ncalrpc_name = NULL;
+
+ if (clis[i] == NULL)
+ continue;
+ if (clis[i]->cli == NULL)
+ continue;
+
+ ncalrpc_name = clis[i]->cli->pipe_name;
+
+ if (strnequal("\\PIPE\\", pipe_name, 6))
+ {
+ ncalrpc_name = &ncalrpc_name[6];
+ }
+
+ DEBUG(10, ("connection: %s [%d,%x]", ncalrpc_name,
+ clis[i]->cli->nt.key.pid,
+ clis[i]->cli->nt.key.vuid));
+
+ if (!strequal(ncalrpc_name, pipe_name))
+ continue;
+
+ if (key->pid != clis[i]->cli->nt.key.pid ||
+ key->vuid != clis[i]->cli->nt.key.vuid)
+ {
+ continue;
+ }
+ /* decrement number of users */
+ clis[i]->num_users--;
+
+ DEBUG(10, ("idx: %i num_users now: %d\n",
+ i, clis[i]->num_users));
+
+ if (force_close || clis[i]->num_users == 0)
+ {
+ ncalrpc_use_free(clis[i]);
+ clis[i] = NULL;
+ if (connection_closed != NULL)
+ {
+ *connection_closed = True;
+ }
+ }
+ return True;
+ }
+
+ return False;
+}
+
+/****************************************************************************
+enumerate client states
+****************************************************************************/
+void ncalrpc_l_use_enum(uint32 * num_cons, struct use_info ***use)
+{
+ int i;
+
+ *num_cons = 0;
+ *use = NULL;
+
+ for (i = 0; i < num_clis; i++)
+ {
+ struct use_info item;
+
+ ZERO_STRUCT(item);
+
+ if (clis[i] == NULL)
+ continue;
+
+ item.connected = clis[i]->cli != NULL ? True : False;
+
+ if (item.connected)
+ {
+ item.srv_name = clis[i]->cli->pipe_name;
+ item.user_name = NULL;
+ item.key = clis[i]->cli->nt.key;
+ item.domain = NULL;
+ }
+
+ add_use_info_to_array(num_cons, use, &item);
+ }
+}
+
+
+/****************************************************************************
+wait for keyboard activity, swallowing network packets on all client states.
+****************************************************************************/
+void ncalrpc_use_wait_keyboard(void)
+{
+ fd_set fds;
+ struct timeval timeout;
+
+ while (1)
+ {
+ int i;
+ int maxfd = fileno(stdin);
+ FD_ZERO(&fds);
+ FD_SET(fileno(stdin), &fds);
+ for (i = 0; i < num_clis; i++)
+ {
+ if (clis[i] != NULL && clis[i]->cli != NULL)
+ {
+ int fd = clis[i]->cli->fd;
+ FD_SET(fd, &fds);
+ maxfd = MAX(fd, maxfd);
+ }
+ }
+
+ timeout.tv_sec = 20;
+ timeout.tv_usec = 0;
+ sys_select(maxfd + 1, NULL, &fds, &timeout);
+
+ if (FD_ISSET(fileno(stdin), &fds))
+ return;
+
+ /* We deliberately use receive_smb instead of
+ client_receive_smb as we want to receive
+ session keepalives and then drop them here.
+ */
+ for (i = 0; i < num_clis; i++)
+ {
+ int fd = clis[i]->cli->fd;
+ if (FD_ISSET(fd, &fds))
+ receive_smb(fd, clis[i]->cli->inbuf, 0);
+ }
+ }
+}
diff --git a/source/rpc_client/ntclienttrust.c b/source/rpc_client/ntclienttrust.c
index 8ef193fa893..04860171817 100644
--- a/source/rpc_client/ntclienttrust.c
+++ b/source/rpc_client/ntclienttrust.c
@@ -34,7 +34,7 @@ extern int DEBUGLEVEL;
check workstation trust account status
************************************************************************/
BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
- char *hostname, char *domain, fstring mach_acct,
+ char *myhostname, char *domain, fstring mach_acct,
fstring new_mach_pwd)
{
pstring tmp;
@@ -53,7 +53,7 @@ BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
char *change_mach_pwd;
/* initial machine password */
- fstrcpy(mach_pwd, hostname);
+ fstrcpy(mach_pwd, myhostname);
strlower(mach_pwd);
slprintf(tmp, sizeof(tmp) - 1,"Enter Workstation Trust Account password for [%s].\nDefault is [%s].\nPassword:",
@@ -91,9 +91,9 @@ BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
DEBUG(1,("server connect for cli_trust\n"));
- if (!server_connect_init(&cli_trust, hostname, dest_ip, dest_host))
+ if (!server_connect_init(&cli_trust, myhostname, dest_ip, dest_host))
{
- cli_error(&cli_trust, &err_cls, &err_num, NULL);
+ cli_error(&cli_trust, &err_cls, &err_num);
DEBUG(1,("server_connect_init failed (%s)\n", cli_errstr(&cli_trust)));
cli_shutdown(&cli_trust);
@@ -141,7 +141,7 @@ BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
return False;
}
- cli_error(&cli_trust, &err_cls, &err_num, NULL);
+ cli_error(&cli_trust, &err_cls, &err_num);
if (err_num == (0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT))
{
diff --git a/source/rpc_parse/.cvsignore b/source/rpc_parse/.cvsignore
index e69de29bb2d..af9d6be961b 100644
--- a/source/rpc_parse/.cvsignore
+++ b/source/rpc_parse/.cvsignore
@@ -0,0 +1 @@
+*.lo \ No newline at end of file
diff --git a/source/rpc_parse/parse_at.c b/source/rpc_parse/parse_at.c
new file mode 100644
index 00000000000..b07ca87af2c
--- /dev/null
+++ b/source/rpc_parse/parse_at.c
@@ -0,0 +1,300 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 2.1.
+ * RPC parsing routines: scheduler service
+ * Copyright (C) Matthew Chapman 1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Andrew Tridgell 1992-1999.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ make_at_q_add_job
+ ********************************************************************/
+BOOL make_at_q_add_job(AT_Q_ADD_JOB *q_a, char *server,
+ AT_JOB_INFO *info, char *command)
+{
+ DEBUG(5,("make_at_q_add_job\n"));
+
+ make_buf_unistr2(&(q_a->uni_srv_name), &(q_a->ptr_srv_name), server);
+ memcpy(&(q_a->info), info, sizeof(q_a->info));
+ make_unistr2(&(q_a->command), command, strlen(command)+1);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a AT_JOB_INFO structure.
+********************************************************************/
+BOOL at_io_job_info(char *desc, AT_JOB_INFO *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return False;
+
+ prs_debug(ps, depth, desc, "at_io_job_info");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("time", ps, depth, &(info->time));
+ prs_uint32("monthdays", ps, depth, &(info->monthdays));
+ prs_uint8("weekdays", ps, depth, &(info->weekdays));
+ prs_uint8("flags", ps, depth, &(info->flags));
+ prs_align(ps);
+
+ prs_uint32("ptr_command", ps, depth, &(info->ptr_command));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a AT_Q_ADD_JOB structure.
+********************************************************************/
+BOOL at_io_q_add_job(char *desc, AT_Q_ADD_JOB *q_a, prs_struct *ps, int depth)
+{
+ if (q_a == NULL) return False;
+
+ prs_debug(ps, depth, desc, "at_q_add_job");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("ptr_srv_name", ps, depth, &(q_a->ptr_srv_name));
+ smb_io_unistr2("", &(q_a->uni_srv_name), q_a->ptr_srv_name, ps, depth);
+ at_io_job_info("", &(q_a->info), ps, depth);
+ smb_io_unistr2("", &(q_a->command), q_a->info.ptr_command, ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a AT_R_ADD_JOB structure.
+********************************************************************/
+BOOL at_io_r_add_job(char *desc, AT_R_ADD_JOB *r_a, prs_struct *ps, int depth)
+{
+ if (r_a == NULL) return False;
+
+ prs_debug(ps, depth, desc, "at_r_add_job");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("jobid", ps, depth, &(r_a->jobid));
+ prs_uint32("status", ps, depth, &(r_a->status));
+
+ return True;
+}
+
+/*******************************************************************
+ make_at_q_del_job
+ ********************************************************************/
+BOOL make_at_q_del_job(AT_Q_DEL_JOB *q_a, char *server, uint32 min_jobid,
+ uint32 max_jobid)
+{
+ DEBUG(5,("make_at_q_del_job\n"));
+
+ make_buf_unistr2(&(q_a->uni_srv_name), &(q_a->ptr_srv_name), server);
+ q_a->min_jobid = min_jobid;
+ q_a->max_jobid = max_jobid;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a AT_Q_DEL_JOB structure.
+********************************************************************/
+BOOL at_io_q_del_job(char *desc, AT_Q_DEL_JOB *q_d, prs_struct *ps, int depth)
+{
+ if (q_d == NULL) return False;
+
+ prs_debug(ps, depth, desc, "at_q_del_job");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_srv_name", ps, depth, &(q_d->ptr_srv_name));
+ smb_io_unistr2("", &(q_d->uni_srv_name), q_d->ptr_srv_name, ps, depth);
+ prs_align(ps);
+ prs_uint32("min_jobid", ps, depth, &(q_d->min_jobid));
+ prs_uint32("max_jobid", ps, depth, &(q_d->max_jobid));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a AT_R_DEL_JOB structure.
+********************************************************************/
+BOOL at_io_r_del_job(char *desc, AT_R_DEL_JOB *r_d, prs_struct *ps, int depth)
+{
+ if (r_d == NULL) return False;
+
+ prs_debug(ps, depth, desc, "at_r_del_job");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_d->status));
+
+ return True;
+}
+
+/*******************************************************************
+ make_at_q_enum_jobs
+ ********************************************************************/
+BOOL make_at_q_enum_jobs(AT_Q_ENUM_JOBS *q_e, char *server)
+{
+ DEBUG(5,("make_at_q_enum_jobs\n"));
+
+ make_buf_unistr2(&(q_e->uni_srv_name), &(q_e->ptr_srv_name), server);
+ q_e->unknown0 = 0;
+ q_e->unknown1 = 0;
+ q_e->max_len = 0xffff;
+ q_e->ptr_resume = 1;
+ q_e->hnd_resume = 0;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a AT_Q_ENUM_JOBS structure.
+********************************************************************/
+BOOL at_io_q_enum_jobs(char *desc, AT_Q_ENUM_JOBS *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return False;
+
+ prs_debug(ps, depth, desc, "at_q_enum_jobs");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("ptr_srv_name", ps, depth, &(q_e->ptr_srv_name));
+ smb_io_unistr2("", &(q_e->uni_srv_name), q_e->ptr_srv_name, ps, depth);
+ prs_align(ps);
+ prs_uint32("unknown0", ps, depth, &(q_e->unknown0));
+ prs_uint32("unknown1", ps, depth, &(q_e->unknown1));
+ prs_uint32("max_len" , ps, depth, &(q_e->max_len ));
+
+ prs_uint32("ptr_resume", ps, depth, &(q_e->ptr_resume));
+ prs_uint32("hnd_resume", ps, depth, &(q_e->hnd_resume));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a AT_R_ENUM_JOBS structure.
+********************************************************************/
+BOOL at_io_r_enum_jobs(char *desc, AT_R_ENUM_JOBS *r_e, prs_struct *ps, int depth)
+{
+ if (r_e == NULL) return False;
+
+ prs_debug(ps, depth, desc, "at_r_enum_jobs");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("num_entries", ps, depth, &(r_e->num_entries));
+ prs_uint32("ptr_entries", ps, depth, &(r_e->ptr_entries));
+
+ if (r_e->ptr_entries != 0)
+ {
+ int i;
+
+ prs_uint32("num_entries2", ps, depth, &(r_e->num_entries2));
+ if (r_e->num_entries2 != r_e->num_entries)
+ {
+ /* RPC fault */
+ return False;
+ }
+
+ SMB_ASSERT_ARRAY(r_e->info, r_e->num_entries2);
+
+ for (i = 0; i < r_e->num_entries2; i++)
+ {
+ prs_uint32("jobid", ps, depth, &(r_e->info[i].jobid));
+ at_io_job_info("", &(r_e->info[i].info), ps, depth);
+ }
+
+ for (i = 0; i < r_e->num_entries2; i++)
+ {
+ smb_io_unistr2("", &(r_e->command[i]),
+ r_e->info[i].info.ptr_command, ps, depth);
+ }
+ }
+
+ prs_align(ps);
+ prs_uint32("total_entries", ps, depth, &(r_e->total_entries));
+ prs_uint32("ptr_resume" , ps, depth, &(r_e->ptr_resume ));
+ prs_uint32("hnd_resume" , ps, depth, &(r_e->hnd_resume ));
+
+ prs_uint32("status", ps, depth, &(r_e->status));
+
+ return True;
+}
+
+/*******************************************************************
+ make_at_q_query_job
+ ********************************************************************/
+BOOL make_at_q_query_job(AT_Q_QUERY_JOB *q_q, char *server, uint32 jobid)
+{
+ DEBUG(5,("make_at_q_query_job\n"));
+
+ make_buf_unistr2(&(q_q->uni_srv_name), &(q_q->ptr_srv_name), server);
+ q_q->jobid = jobid;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a AT_Q_QUERY_JOB structure.
+********************************************************************/
+BOOL at_io_q_query_job(char *desc, AT_Q_QUERY_JOB *q_q, prs_struct *ps, int depth)
+{
+ if (q_q == NULL) return False;
+
+ prs_debug(ps, depth, desc, "at_q_query_job");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("ptr_srv_name", ps, depth, &(q_q->ptr_srv_name));
+ smb_io_unistr2("", &(q_q->uni_srv_name), q_q->ptr_srv_name, ps, depth);
+ prs_align(ps);
+ prs_uint32("jobid", ps, depth, &(q_q->jobid));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a AT_R_QUERY_JOB structure.
+********************************************************************/
+BOOL at_io_r_query_job(char *desc, AT_R_QUERY_JOB *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return False;
+
+ prs_debug(ps, depth, desc, "at_r_query_job");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("ptr_info", ps, depth, &(r_q->ptr_info));
+ if (r_q->ptr_info != 0)
+ {
+ at_io_job_info("", &(r_q->info), ps, depth);
+ smb_io_unistr2("", &(r_q->command), r_q->info.ptr_command, ps, depth);
+ }
+
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_q->status));
+
+ return True;
+}
diff --git a/source/rpc_parse/parse_brs.c b/source/rpc_parse/parse_brs.c
new file mode 100644
index 00000000000..0bd1183cf5b
--- /dev/null
+++ b/source/rpc_parse/parse_brs.c
@@ -0,0 +1,181 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Paul Ashton 1997-1999.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+ make_brs_q_query_info
+ ********************************************************************/
+BOOL make_brs_q_query_info(BRS_Q_QUERY_INFO *q_u,
+ const char *server, uint16 switch_value)
+{
+ DEBUG(5,("make_brs_q_query_info\n"));
+
+ make_buf_unistr2(&(q_u->uni_srv_name), &(q_u->ptr_srv_name), server);
+ q_u->switch_value1 = switch_value;
+ q_u->switch_value2 = switch_value;
+
+ q_u->ptr = 1;
+ q_u->pad1 = 0x0;
+ q_u->pad2 = 0x0;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a BRS_Q_QUERY_INFO structure.
+********************************************************************/
+BOOL brs_io_q_query_info(char *desc, BRS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "brs_io_q_query_info");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_srv_name", ps, depth, &(q_u->ptr_srv_name));
+ smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps, depth);
+ prs_align(ps);
+
+ prs_uint16("switch_value1", ps, depth, &(q_u->switch_value1));
+ prs_align(ps);
+
+ prs_uint16("switch_value2", ps, depth, &(q_u->switch_value2));
+ prs_align(ps);
+
+ prs_uint32("ptr", ps, depth, &(q_u->ptr));
+ if (q_u->ptr)
+ {
+ prs_uint32("pad1", ps, depth, &(q_u->pad1));
+ }
+
+ prs_uint32("pad2", ps, depth, &(q_u->pad2));
+
+ return True;
+}
+
+/*******************************************************************
+ brs_info_100
+ ********************************************************************/
+BOOL make_brs_info_100(BRS_INFO_100 *inf)
+{
+ DEBUG(5,("BRS_INFO_100: %d\n", __LINE__));
+
+ inf->pad1 = 0x0;
+ inf->ptr2 = 0x1;
+ inf->pad2 = 0x0;
+ inf->pad3 = 0x0;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a BRS_INFO_100 structure.
+********************************************************************/
+static BOOL brs_io_brs_info_100(char *desc, BRS_INFO_100 *inf, prs_struct *ps, int depth)
+{
+ if (inf == NULL) return False;
+
+ prs_debug(ps, depth, desc, "brs_io_brs_info_100");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("pad1", ps, depth, &(inf->pad1));
+ prs_uint32("ptr2", ps, depth, &(inf->ptr2));
+ prs_uint32("pad2", ps, depth, &(inf->pad2));
+ prs_uint32("pad3", ps, depth, &(inf->pad3));
+
+ return True;
+}
+
+/*******************************************************************
+ make_brs_r_query_info
+
+ only supports info level 100 at the moment.
+
+ ********************************************************************/
+BOOL make_brs_r_query_info(BRS_R_QUERY_INFO *r_u,
+ uint32 switch_value, void *inf,
+ int status)
+{
+ DEBUG(5,("make_brs_r_unknown_0: %d\n", __LINE__));
+
+ r_u->switch_value1 = switch_value; /* same as in request */
+ r_u->switch_value2 = switch_value; /* same as in request */
+
+ r_u->ptr_1 = inf != NULL ? 1 : 0; /* pointer 1 */
+ r_u->info.id = inf;
+
+ r_u->status = status;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL brs_io_r_query_info(char *desc, BRS_R_QUERY_INFO *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "brs_io_r_query_info");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint16("switch_value1", ps, depth, &(r_u->switch_value1));
+ prs_align(ps);
+
+ prs_uint16("switch_value2", ps, depth, &(r_u->switch_value2));
+ prs_align(ps);
+
+ prs_uint32("ptr_1 ", ps, depth, &(r_u->ptr_1));
+ if (r_u->ptr_1 != 0x0)
+ {
+ switch (r_u->switch_value1)
+ {
+ case 100:
+ {
+ brs_io_brs_info_100("inf", r_u->info.brs100, ps, depth);
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ }
+
+ prs_uint32("status ", ps, depth, &(r_u->status));
+
+ return True;
+}
+
diff --git a/source/rpc_parse/parse_creds.c b/source/rpc_parse/parse_creds.c
index ba45fa163af..29a5bb12f0a 100644
--- a/source/rpc_parse/parse_creds.c
+++ b/source/rpc_parse/parse_creds.c
@@ -23,6 +23,7 @@
#include "includes.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
@@ -153,82 +154,6 @@ void creds_free_unix_sec(CREDS_UNIX_SEC *r_u)
}
/*******************************************************************
-makes a CREDS_NT_SEC structure.
-********************************************************************/
-BOOL make_creds_nt_sec(CREDS_NT_SEC *r_u,
- DOM_SID *sid, uint32 num_grps, uint32 *grps)
-{
- int i;
- if (r_u == NULL) return False;
-
- DEBUG(5,("make_creds_unix_sec\n"));
-
- sid_copy(&r_u->sid, sid);
- r_u->num_grps = num_grps;
- r_u->grp_rids = (uint32*)Realloc(NULL, sizeof(r_u->grp_rids[0]) *
- r_u->num_grps);
-
- if (r_u->grp_rids == NULL && num_grps != 0)
- {
- return False;
- }
- for (i = 0; i < num_grps; i++)
- {
- r_u->grp_rids[i] = grps[i];
- }
-
- return True;
-}
-
-/*******************************************************************
-reads or writes a structure.
-********************************************************************/
-BOOL creds_io_nt_sec(char *desc, CREDS_NT_SEC *r_u, prs_struct *ps, int depth)
-{
- int i;
- if (r_u == NULL) return False;
-
- prs_debug(ps, depth, desc, "creds_io_nt");
- depth++;
-
- prs_align(ps);
-
- smb_io_dom_sid ("sid", &r_u->sid, ps, depth);
- prs_align(ps);
-
- prs_uint32("num_grps", ps, depth, &(r_u->num_grps));
- if (r_u->num_grps != 0)
- {
- r_u->grp_rids = (uint32*)Realloc(r_u->grp_rids,
- sizeof(r_u->grp_rids[0]) *
- r_u->num_grps);
- if (r_u->grp_rids == NULL)
- {
- creds_free_nt_sec(r_u);
- return False;
- }
- }
- for (i = 0; i < r_u->num_grps; i++)
- {
- prs_uint32("", ps, depth, &(r_u->grp_rids[i]));
- }
-
- return True;
-}
-
-/*******************************************************************
-frees a structure.
-********************************************************************/
-void creds_free_nt_sec(CREDS_NT_SEC *r_u)
-{
- if (r_u->grp_rids != NULL)
- {
- free(r_u->grp_rids);
- r_u->grp_rids = NULL;
- }
-}
-
-/*******************************************************************
reads or writes a structure.
********************************************************************/
BOOL creds_io_pwd_info(char *desc, struct pwd_info *pwd, prs_struct *ps, int depth)
@@ -335,7 +260,6 @@ BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth)
prs_uint32("ptr_uxc", ps, depth, &(r_u->ptr_uxc));
prs_uint32("ptr_nts", ps, depth, &(r_u->ptr_nts));
prs_uint32("ptr_uxs", ps, depth, &(r_u->ptr_uxs));
- prs_uint32("ptr_ssk", ps, depth, &(r_u->ptr_ssk));
if (r_u->ptr_ntc != 0)
{
if (!creds_io_nt ("ntc", &r_u->ntc, ps, depth)) return False;
@@ -346,20 +270,12 @@ BOOL creds_io_hybrid(char *desc, CREDS_HYBRID *r_u, prs_struct *ps, int depth)
}
if (r_u->ptr_nts != 0)
{
- if (!creds_io_nt_sec ("nts", &r_u->nts, ps, depth)) return False;
+ if (!net_io_user_info3("nts", &r_u->nts, ps, depth)) return False;
}
if (r_u->ptr_uxs != 0)
{
if (!creds_io_unix_sec("uxs", &r_u->uxs, ps, depth)) return False;
}
- if (r_u->ptr_ssk != 0)
- {
- prs_uint8s(False, "usr_sess_key", ps, depth, (char*)&r_u->usr_sess_key, sizeof(r_u->usr_sess_key));
- }
- else
- {
- memset(r_u->usr_sess_key, 0, sizeof(r_u->usr_sess_key));
- }
return True;
}
@@ -373,30 +289,6 @@ void copy_unix_creds(CREDS_UNIX *to, const CREDS_UNIX *from)
fstrcpy(to->user_name, from->user_name);
};
-void copy_nt_sec_creds(CREDS_NT_SEC *to, const CREDS_NT_SEC *from)
-{
- if (from == NULL)
- {
- ZERO_STRUCTP(to);
- return;
- }
- sid_copy(&to->sid, &from->sid);
- to->num_grps = 0;
- to->grp_rids = NULL;
-
- if (from->num_grps != 0)
- {
- size_t size = from->num_grps * sizeof(from->grp_rids[0]);
- to->grp_rids = (uint32*)malloc(size);
- if (to->grp_rids == NULL)
- {
- return;
- }
- to->num_grps = from->num_grps;
- memcpy(to->grp_rids, from->grp_rids, size);
- }
-};
-
void copy_unix_sec_creds(CREDS_UNIX_SEC *to, const CREDS_UNIX_SEC *from)
{
if (from == NULL)
@@ -442,8 +334,8 @@ void copy_nt_creds(struct ntuser_creds *to,
safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1);
memcpy(&to->pwd, &from->pwd, sizeof(from->pwd));
to->ntlmssp_flags = from->ntlmssp_flags;
- DEBUG(10,("copy_nt_creds: user %s domain %s flgs: %x\n",
- to->user_name, to->domain,
+ DEBUG(10,("copy_nt_creds: user %s domain %s nopw %s flgs: %x\n",
+ to->user_name, to->domain, BOOLSTR(pwd_is_nullpwd(&to->pwd)),
to->ntlmssp_flags));
};
@@ -457,10 +349,12 @@ void copy_user_creds(struct user_creds *to,
to->ptr_uxc = 0;
to->ptr_nts = 0;
to->ptr_uxs = 0;
- to->ptr_ssk = 0;
copy_nt_creds(&to->ntc, NULL);
copy_unix_creds(&to->uxc, NULL);
+ memset(&to->nts, 0, sizeof(to->nts));
+#if 0
copy_nt_sec_creds(&to->nts, NULL);
+#endif
copy_unix_sec_creds(&to->uxs, NULL);
to->reuse = False;
return;
@@ -472,7 +366,6 @@ void copy_user_creds(struct user_creds *to,
to->ptr_uxs = from->ptr_uxs;
to->ptr_ntc = from->ptr_ntc;
to->ptr_uxc = from->ptr_uxc;
- to->ptr_ssk = from->ptr_ssk;
if (to->ptr_ntc != 0)
{
@@ -484,17 +377,15 @@ void copy_user_creds(struct user_creds *to,
}
if (to->ptr_nts != 0)
{
+ memcpy(&to->nts, &from->nts, sizeof(to->nts));
+#if 0
copy_nt_sec_creds(&to->nts, &from->nts);
+#endif
}
if (to->ptr_uxs != 0)
{
copy_unix_sec_creds(&to->uxs, &from->uxs);
}
- if (to->ptr_ssk != 0)
- {
- memcpy(to->usr_sess_key, from->usr_sess_key,
- sizeof(to->usr_sess_key));
- }
};
void free_user_creds(struct user_creds *creds)
@@ -502,7 +393,9 @@ void free_user_creds(struct user_creds *creds)
creds_free_unix(&creds->uxc);
creds_free_nt (&creds->ntc);
creds_free_unix_sec(&creds->uxs);
+#if 0
creds_free_nt_sec (&creds->nts);
+#endif
}
/*******************************************************************
@@ -519,7 +412,8 @@ BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth)
prs_uint16("version", ps, depth, &(r_u->version));
prs_uint16("command", ps, depth, &(r_u->command));
- prs_uint32("pid ", ps, depth, &(r_u->pid ));
+
+ vuid_io_key("key", &r_u->key, ps, 0);
prs_string("name ", ps, depth, r_u->name, strlen(r_u->name), sizeof(r_u->name));
prs_align(ps);
@@ -541,7 +435,7 @@ BOOL creds_io_cmd(char *desc, CREDS_CMD *r_u, prs_struct *ps, int depth)
BOOL create_ntuser_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
- uint32 pid,
+ const vuser_key *key,
const struct ntuser_creds *ntu,
BOOL reuse)
{
@@ -559,7 +453,7 @@ BOOL create_ntuser_creds( prs_struct *ps,
fstrcpy(cmd.name, name);
cmd.version = version;
cmd.command = command;
- cmd.pid = pid ;
+ cmd.key = *key ;
cmd.ptr_creds = ntu != NULL ? 1 : 0;
cmd.cred = &usr;
@@ -573,16 +467,16 @@ BOOL create_ntuser_creds( prs_struct *ps,
usr.ptr_ntc = 0;
}
- prs_init(ps, 1024, 4, False);
+ prs_init(ps, 0, 4, False);
- ps->data_offset = 4;
+ ps->offset = 4;
return creds_io_cmd("creds", &cmd, ps, 0);
}
BOOL create_user_creds( prs_struct *ps,
const char* name,
uint16 version, uint16 command,
- uint32 pid,
+ const vuser_key *key,
const struct user_creds *usr)
{
CREDS_CMD cmd;
@@ -595,12 +489,12 @@ BOOL create_user_creds( prs_struct *ps,
fstrcpy(cmd.name, name);
cmd.version = version;
cmd.command = command;
- cmd.pid = pid ;
+ cmd.key = *key;
cmd.ptr_creds = usr != NULL ? 1 : 0;
cmd.cred = usr;
- prs_init(ps, 1024, 4, False);
+ prs_init(ps, 0, 4, False);
- ps->data_offset = 4;
+ ps->offset = 4;
return creds_io_cmd("creds", &cmd, ps, 0);
}
diff --git a/source/rpc_parse/parse_eventlog.c b/source/rpc_parse/parse_eventlog.c
new file mode 100644
index 00000000000..81870f19e41
--- /dev/null
+++ b/source/rpc_parse/parse_eventlog.c
@@ -0,0 +1,275 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Jean François Micouleau 1998-1999.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+********************************************************************/
+BOOL make_eventlog_q_open(EVENTLOG_Q_OPEN *q_u, const char *journal, char *unk)
+{
+ int len_journal = journal != NULL ? strlen(journal) : 0;
+ int len_unk = unk != NULL ? strlen(unk) : 0;
+
+ q_u->ptr0=0x1;
+ q_u->unk0=0x5c;
+ q_u->unk1=0x01;
+
+ make_uni_hdr(&(q_u->hdr_source), len_journal);
+ make_unistr2(&(q_u->uni_source), journal, len_journal);
+
+ make_uni_hdr(&(q_u->hdr_unk), len_unk);
+ make_unistr2(&(q_u->uni_unk), unk, len_unk);
+
+ q_u->unk6=0x01; /* one of these is an access mask! */
+ q_u->unk7=0x01; /* one of these is an access mask! */
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL eventlog_io_q_open(char *desc, EVENTLOG_Q_OPEN *q_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "eventlog_io_q_open");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr0", ps, depth, &(q_u->ptr0));
+
+ prs_uint16("unk0", ps, depth, &(q_u->unk0));
+ prs_uint16("unk1", ps, depth, &(q_u->unk1));
+
+ smb_io_unihdr("hdr_source", &(q_u->hdr_source), ps, depth);
+ smb_io_unistr2("uni_source", &(q_u->uni_source),
+ q_u->hdr_source.buffer, ps, depth);
+ prs_align(ps);
+
+ smb_io_unihdr("hdr_unk", &(q_u->hdr_unk), ps, depth);
+ smb_io_unistr2("uni_unk", &(q_u->uni_unk),
+ q_u->hdr_unk.buffer, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("unk6", ps, depth, &(q_u->unk6));
+ prs_uint32("unk7", ps, depth, &(q_u->unk7));
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL eventlog_io_r_open(char *desc, EVENTLOG_R_OPEN *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "eventlog_io_r_open");
+ depth++;
+
+ prs_align(ps);
+ smb_io_pol_hnd("", &(r_u->pol), ps, depth);
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL make_eventlog_q_close(EVENTLOG_Q_CLOSE *q_u, POLICY_HND *pol)
+{
+ if ((q_u == NULL) || (pol == NULL))
+ {
+ return False;
+ }
+
+ q_u->pol = *pol;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL eventlog_io_q_close(char *desc, EVENTLOG_Q_CLOSE *q_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "eventlog_io_q_close");
+ depth++;
+
+ prs_align(ps);
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL eventlog_io_r_close(char *desc, EVENTLOG_R_CLOSE *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "eventlog_io_r_close");
+ depth++;
+
+ prs_align(ps);
+ smb_io_pol_hnd("", &(r_u->pol), ps, depth);
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL make_eventlog_q_numofeventlogrec(EVENTLOG_Q_NUMOFEVENTLOGREC *q_u, POLICY_HND *pol)
+{
+ if ((q_u == NULL) || (pol == NULL))
+ {
+ return False;
+ }
+
+ q_u->pol = *pol;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL eventlog_io_q_numofeventlogrec(char *desc,EVENTLOG_Q_NUMOFEVENTLOGREC *q_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "eventlog_io_q_numofeventlogrec");
+ depth++;
+
+ prs_align(ps);
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL eventlog_io_r_numofeventlogrec(char *desc, EVENTLOG_R_NUMOFEVENTLOGREC *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "eventlog_io_r_numofeventlogrec");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("number", ps, depth, &(r_u->number));
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL make_eventlog_q_readeventlog(EVENTLOG_Q_READEVENTLOG *q_u, POLICY_HND *pol,
+ uint32 flags, uint32 offset, uint32 number_of_bytes)
+{
+ if ((q_u == NULL) || (pol == NULL))
+ {
+ return False;
+ }
+
+ q_u->pol = *pol;
+ q_u->flags = flags;
+ q_u->offset = offset;
+ q_u->number_of_bytes = number_of_bytes;
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL eventlog_io_q_readeventlog(char *desc, EVENTLOG_Q_READEVENTLOG *q_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "eventlog_io_q_readeventlog");
+ depth++;
+
+ prs_align(ps);
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ prs_uint32("flags", ps, depth, &(q_u->flags));
+ prs_uint32("offset", ps, depth, &(q_u->offset));
+ prs_uint32("number_of_bytes", ps, depth, &(q_u->number_of_bytes));
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+static BOOL eventlog_io_eventlog(char *desc, EVENTLOGRECORD *ev, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "eventlog_io_eventlog");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("size", ps, depth, &(ev->size));
+ prs_uint32("reserved", ps, depth, &(ev->reserved));
+ prs_uint32("recordnumber", ps, depth, &(ev->recordnumber));
+ prs_uint32("creationtime", ps, depth, &(ev->creationtime));
+ prs_uint32("writetime", ps, depth, &(ev->writetime));
+ prs_uint32("eventnumber", ps, depth, &(ev->eventnumber));
+
+ prs_uint16("eventtype", ps, depth, &(ev->eventtype));
+ prs_uint16("num_of_strings", ps, depth, &(ev->num_of_strings));
+ prs_uint16("category", ps, depth, &(ev->category));
+ prs_uint16("reserved_flag", ps, depth, &(ev->reserved_flag));
+
+ prs_uint32("closingrecord", ps, depth, &(ev->closingrecord));
+ prs_uint32("stringoffset", ps, depth, &(ev->stringoffset));
+ prs_uint32("sid_length", ps, depth, &(ev->sid_length));
+ prs_uint32("sid_offset", ps, depth, &(ev->sid_offset));
+ prs_uint32("data_length", ps, depth, &(ev->data_length));
+ prs_uint32("data_offset", ps, depth, &(ev->data_offset));
+
+ smb_io_unistr("", &(ev->sourcename), ps, depth);
+ smb_io_unistr("", &(ev->computername), ps, depth);
+
+ if (ev->sid_length!=0)
+ smb_io_unistr("", &(ev->sid), ps, depth);
+
+ if (ev->num_of_strings!=0)
+ smb_io_unistr("", &(ev->strings),ps, depth);
+
+ if (ev->data_length)
+ smb_io_unistr("", &(ev->data), ps, depth);
+
+ prs_uint32("size2", ps, depth, &(ev->size2));
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL eventlog_io_r_readeventlog(char *desc, EVENTLOG_R_READEVENTLOG *r_u, prs_struct *ps, int depth)
+{
+ prs_debug(ps, depth, desc, "eventlog_io_r_readeventlog");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("number_of_bytes", ps, depth, &(r_u->number_of_bytes));
+
+ if (r_u->number_of_bytes!= 0)
+ eventlog_io_eventlog("", r_u->event, ps, depth);
+
+ prs_uint32("sent_size", ps, depth, &(r_u->sent_size));
+ prs_uint32("real_size", ps, depth, &(r_u->real_size));
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
diff --git a/source/rpc_parse/parse_lsa.c b/source/rpc_parse/parse_lsa.c
index 771e7c31d45..871b06682f9 100644
--- a/source/rpc_parse/parse_lsa.c
+++ b/source/rpc_parse/parse_lsa.c
@@ -2,9 +2,9 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Paul Ashton 1997-1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,35 +22,32 @@
*/
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
-static BOOL lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM *trn, prs_struct *ps, int depth);
-
/*******************************************************************
- Inits a LSA_TRANS_NAME structure.
+creates a LSA_TRANS_NAME structure.
********************************************************************/
-
-void init_lsa_trans_name(LSA_TRANS_NAME *trn, UNISTR2 *uni_name,
- uint32 sid_name_use, char *name, uint32 idx)
+BOOL make_lsa_trans_name(LSA_TRANS_NAME * trn, UNISTR2 * uni_name,
+ uint32 sid_name_use, char *name, uint32 idx)
{
int len_name = strlen(name);
- if(len_name == 0)
- len_name = 1;
-
trn->sid_name_use = sid_name_use;
- init_uni_hdr(&trn->hdr_name, len_name);
- init_unistr2(uni_name, name, len_name);
+ make_uni_hdr(&(trn->hdr_name), len_name);
+ make_unistr2(uni_name, name, len_name);
trn->domain_idx = idx;
+
+ return True;
}
/*******************************************************************
- Reads or writes a LSA_TRANS_NAME structure.
+reads or writes a LSA_TRANS_NAME structure.
********************************************************************/
-
-static BOOL lsa_io_trans_name(char *desc, LSA_TRANS_NAME *trn, prs_struct *ps, int depth)
+static BOOL lsa_io_trans_name(char *desc, LSA_TRANS_NAME * trn,
+ prs_struct * ps, int depth)
{
if (trn == NULL)
return False;
@@ -58,77 +55,137 @@ static BOOL lsa_io_trans_name(char *desc, LSA_TRANS_NAME *trn, prs_struct *ps, i
prs_debug(ps, depth, desc, "lsa_io_trans_name");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("sid_name_use", ps, depth, &trn->sid_name_use))
- return False;
- if(!smb_io_unihdr ("hdr_name", &trn->hdr_name, ps, depth))
- return False;
- if(!prs_uint32("domain_idx ", ps, depth, &trn->domain_idx))
- return False;
+ prs_align(ps);
+
+ prs_uint32("sid_name_use", ps, depth, &(trn->sid_name_use));
+ smb_io_unihdr("hdr_name", &(trn->hdr_name), ps, depth);
+ prs_uint32("domain_idx ", ps, depth, &(trn->domain_idx));
return True;
}
+/***************************************************************************
+make_dom_ref - adds a domain if it's not already in, returns the index
+ ***************************************************************************/
+int make_dom_ref_uni(DOM_R_REF * ref, const UNISTR2 * uni_domname,
+ const DOM_SID * dom_sid)
+{
+ int num = 0;
+ UNISTR2 uni_tmp;
+
+ if (ref == NULL)
+ {
+ return -1;
+ }
+
+ if (uni_domname == NULL)
+ {
+ uni_domname = &uni_tmp;
+ make_unistr2(&uni_tmp, NULL, 0);
+ }
+
+ for (num = 0; num < ref->num_ref_doms_1; num++)
+ {
+ if (unistr2equal(uni_domname,
+ &ref->ref_dom[num].uni_dom_name))
+ {
+ return num;
+ }
+ }
+
+ if (num >= MAX_REF_DOMAINS)
+ {
+ /* index not found, already at maximum domain limit */
+ return -1;
+ }
+
+ ref->num_ref_doms_1 = num + 1;
+ ref->ptr_ref_dom = 1;
+ ref->max_entries = MAX_REF_DOMAINS;
+ ref->num_ref_doms_2 = num + 1;
+
+ make_unihdr_from_unistr2(&(ref->hdr_ref_dom[num].hdr_dom_name),
+ uni_domname);
+ copy_unistr2(&(ref->ref_dom[num].uni_dom_name), uni_domname);
+
+ ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
+ make_dom_sid2(&(ref->ref_dom[num].ref_dom), dom_sid);
+
+ return num;
+}
+
+int make_dom_ref(DOM_R_REF * ref, const char *domname,
+ const DOM_SID * dom_sid)
+{
+ UNISTR2 *uni_domname;
+ int ret;
+
+ uni_domname = unistr2_new(domname);
+ ret = make_dom_ref_uni(ref, uni_domname, dom_sid);
+ unistr2_free(uni_domname);
+ return ret;
+}
+
/*******************************************************************
- Reads or writes a DOM_R_REF structure.
+reads or writes a DOM_R_REF structure.
********************************************************************/
-
-static BOOL lsa_io_dom_r_ref(char *desc, DOM_R_REF *r_r, prs_struct *ps, int depth)
+static BOOL lsa_io_dom_r_ref(char *desc, DOM_R_REF * r_r, prs_struct * ps,
+ int depth)
{
- int i, s, n;
+ uint32 i, s, n;
- prs_debug(ps, depth, desc, "lsa_io_dom_r_ref");
+ prs_debug(ps, depth, desc, "smb_io_dom_r_ref");
depth++;
if (r_r == NULL)
return False;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("num_ref_doms_1", ps, depth, &r_r->num_ref_doms_1)) /* num referenced domains? */
- return False;
- if(!prs_uint32("ptr_ref_dom ", ps, depth, &r_r->ptr_ref_dom)) /* undocumented buffer pointer. */
- return False;
- if(!prs_uint32("max_entries ", ps, depth, &r_r->max_entries)) /* 32 - max number of entries */
- return False;
+ prs_align(ps);
- SMB_ASSERT_ARRAY(r_r->hdr_ref_dom, r_r->num_ref_doms_1);
+ prs_uint32("num_ref_doms_1", ps, depth, &(r_r->num_ref_doms_1)); /* num referenced domains? */
+ prs_uint32("ptr_ref_dom ", ps, depth, &(r_r->ptr_ref_dom)); /* undocumented buffer pointer. */
+ prs_uint32("max_entries ", ps, depth, &(r_r->max_entries)); /* 32 - max number of entries */
- if (r_r->ptr_ref_dom != 0) {
- if(!prs_uint32("num_ref_doms_2", ps, depth, &r_r->num_ref_doms_2)) /* 4 - num referenced domains? */
- return False;
+ SMB_ASSERT_ARRAY(r_r->hdr_ref_dom, r_r->num_ref_doms_1);
+ if (r_r->ptr_ref_dom != 0)
+ {
+ prs_uint32("num_ref_doms_2", ps, depth, &(r_r->num_ref_doms_2)); /* 4 - num referenced domains? */
SMB_ASSERT_ARRAY(r_r->ref_dom, r_r->num_ref_doms_2);
- for (i = 0; i < r_r->num_ref_doms_1; i++) {
+ for (i = 0; i < r_r->num_ref_doms_1; i++)
+ {
fstring t;
slprintf(t, sizeof(t) - 1, "dom_ref[%d] ", i);
- if(!smb_io_unihdr(t, &r_r->hdr_ref_dom[i].hdr_dom_name, ps, depth))
- return False;
+ smb_io_unihdr(t, &(r_r->hdr_ref_dom[i].hdr_dom_name),
+ ps, depth);
slprintf(t, sizeof(t) - 1, "sid_ptr[%d] ", i);
- if(!prs_uint32(t, ps, depth, &r_r->hdr_ref_dom[i].ptr_dom_sid))
- return False;
+ prs_uint32(t, ps, depth,
+ &(r_r->hdr_ref_dom[i].ptr_dom_sid));
}
- for (i = 0, n = 0, s = 0; i < r_r->num_ref_doms_2; i++) {
+ for (i = 0, n = 0, s = 0; i < r_r->num_ref_doms_2; i++)
+ {
fstring t;
- if (r_r->hdr_ref_dom[i].hdr_dom_name.buffer != 0) {
+ if (r_r->hdr_ref_dom[i].hdr_dom_name.buffer != 0)
+ {
slprintf(t, sizeof(t) - 1, "dom_ref[%d] ", i);
- if(!smb_io_unistr2(t, &r_r->ref_dom[n].uni_dom_name, True, ps, depth)) /* domain name unicode string */
- return False;
+ smb_io_unistr2(t,
+ &(r_r->ref_dom[n].
+ uni_dom_name), True, ps, depth); /* domain name unicode string */
+ prs_align(ps);
n++;
}
- if (r_r->hdr_ref_dom[i].ptr_dom_sid != 0) {
+ if (r_r->hdr_ref_dom[i].ptr_dom_sid != 0)
+ {
slprintf(t, sizeof(t) - 1, "sid_ptr[%d] ", i);
- if(!smb_io_dom_sid2("", &r_r->ref_dom[s].ref_dom, ps, depth)) /* referenced domain SIDs */
- return False;
+ smb_io_dom_sid2("",
+ &(r_r->ref_dom[s].ref_dom),
+ ps, depth); /* referenced domain SIDs */
s++;
}
}
@@ -137,29 +194,34 @@ static BOOL lsa_io_dom_r_ref(char *desc, DOM_R_REF *r_r, prs_struct *ps, int dep
return True;
}
+
/*******************************************************************
- Inits an LSA_SEC_QOS structure.
+makes an LSA_SEC_QOS structure.
********************************************************************/
-
-void init_lsa_sec_qos(LSA_SEC_QOS *qos, uint16 imp_lev, uint8 ctxt, uint8 eff,
- uint32 unknown)
+BOOL make_lsa_sec_qos(LSA_SEC_QOS * qos, uint16 imp_lev, uint8 ctxt,
+ uint8 eff, uint32 unknown)
{
- DEBUG(5,("init_lsa_sec_qos\n"));
+ if (qos == NULL)
+ return False;
+
+ DEBUG(5, ("make_lsa_sec_qos\n"));
- qos->len = 0x0c; /* length of quality of service block, in bytes */
+ qos->len = 0x0c; /* length of quality of service block, in bytes */
qos->sec_imp_level = imp_lev;
qos->sec_ctxt_mode = ctxt;
qos->effective_only = eff;
qos->unknown = unknown;
+
+ return True;
}
/*******************************************************************
- Reads or writes an LSA_SEC_QOS structure.
+reads or writes an LSA_SEC_QOS structure.
********************************************************************/
-
-static BOOL lsa_io_sec_qos(char *desc, LSA_SEC_QOS *qos, prs_struct *ps, int depth)
+static BOOL lsa_io_sec_qos(char *desc, LSA_SEC_QOS * qos, prs_struct * ps,
+ int depth)
{
- uint32 start;
+ int start;
if (qos == NULL)
return False;
@@ -167,28 +229,24 @@ static BOOL lsa_io_sec_qos(char *desc, LSA_SEC_QOS *qos, prs_struct *ps, int de
prs_debug(ps, depth, desc, "lsa_io_obj_qos");
depth++;
- if(!prs_align(ps))
- return False;
-
- start = prs_offset(ps);
+ prs_align(ps);
+
+ start = ps->offset;
/* these pointers had _better_ be zero, because we don't know
what they point to!
*/
- if(!prs_uint32("len ", ps, depth, &qos->len)) /* 0x18 - length (in bytes) inc. the length field. */
- return False;
- if(!prs_uint16("sec_imp_level ", ps, depth, &qos->sec_imp_level ))
- return False;
- if(!prs_uint8 ("sec_ctxt_mode ", ps, depth, &qos->sec_ctxt_mode ))
- return False;
- if(!prs_uint8 ("effective_only", ps, depth, &qos->effective_only))
- return False;
- if(!prs_uint32("unknown ", ps, depth, &qos->unknown))
- return False;
-
- if (qos->len != prs_offset(ps) - start) {
- DEBUG(3,("lsa_io_sec_qos: length %x does not match size %x\n",
- qos->len, prs_offset(ps) - start));
+ prs_uint32("len ", ps, depth, &(qos->len)); /* 0x18 - length (in bytes) inc. the length field. */
+ prs_uint16("sec_imp_level ", ps, depth, &(qos->sec_imp_level));
+ prs_uint8("sec_ctxt_mode ", ps, depth, &(qos->sec_ctxt_mode));
+ prs_uint8("effective_only", ps, depth, &(qos->effective_only));
+ prs_uint32("unknown ", ps, depth, &(qos->unknown));
+
+ if (qos->len != ps->offset - start)
+ {
+ DEBUG(3,
+ ("lsa_io_sec_qos: length %x does not match size %x\n",
+ qos->len, ps->offset - start));
}
return True;
@@ -196,35 +254,43 @@ static BOOL lsa_io_sec_qos(char *desc, LSA_SEC_QOS *qos, prs_struct *ps, int de
/*******************************************************************
- Inits an LSA_OBJ_ATTR structure.
+makes an LSA_OBJ_ATTR structure.
********************************************************************/
-
-void init_lsa_obj_attr(LSA_OBJ_ATTR *attr, uint32 attributes, LSA_SEC_QOS *qos)
+BOOL make_lsa_obj_attr(LSA_OBJ_ATTR * attr, uint32 attributes,
+ LSA_SEC_QOS * qos)
{
- DEBUG(5,("make_lsa_obj_attr\n"));
+ if (attr == NULL)
+ return False;
- attr->len = 0x18; /* length of object attribute block, in bytes */
+ DEBUG(5, ("make_lsa_obj_attr\n"));
+
+ attr->len = 0x18; /* length of object attribute block, in bytes */
attr->ptr_root_dir = 0;
attr->ptr_obj_name = 0;
attr->attributes = attributes;
attr->ptr_sec_desc = 0;
-
- if (qos != NULL) {
+
+ if (qos != NULL)
+ {
attr->ptr_sec_qos = 1;
attr->sec_qos = qos;
- } else {
+ }
+ else
+ {
attr->ptr_sec_qos = 0;
attr->sec_qos = NULL;
}
+
+ return True;
}
/*******************************************************************
- Reads or writes an LSA_OBJ_ATTR structure.
+reads or writes an LSA_OBJ_ATTR structure.
********************************************************************/
-
-static BOOL lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR *attr, prs_struct *ps, int depth)
+static BOOL lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR * attr, prs_struct * ps,
+ int depth)
{
- uint32 start;
+ int start;
if (attr == NULL)
return False;
@@ -232,35 +298,30 @@ static BOOL lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR *attr, prs_struct *ps, int
prs_debug(ps, depth, desc, "lsa_io_obj_attr");
depth++;
- if(!prs_align(ps))
- return False;
-
- start = prs_offset(ps);
+ prs_align(ps);
+
+ start = ps->offset;
/* these pointers had _better_ be zero, because we don't know
what they point to!
*/
- if(!prs_uint32("len ", ps, depth, &attr->len)) /* 0x18 - length (in bytes) inc. the length field. */
- return False;
- if(!prs_uint32("ptr_root_dir", ps, depth, &attr->ptr_root_dir)) /* 0 - root directory (pointer) */
- return False;
- if(!prs_uint32("ptr_obj_name", ps, depth, &attr->ptr_obj_name)) /* 0 - object name (pointer) */
- return False;
- if(!prs_uint32("attributes ", ps, depth, &attr->attributes)) /* 0 - attributes (undocumented) */
- return False;
- if(!prs_uint32("ptr_sec_desc", ps, depth, &attr->ptr_sec_desc)) /* 0 - security descriptior (pointer) */
- return False;
- if(!prs_uint32("ptr_sec_qos ", ps, depth, &attr->ptr_sec_qos )) /* security quality of service (pointer) */
- return False;
-
- if (attr->len != prs_offset(ps) - start) {
- DEBUG(3,("lsa_io_obj_attr: length %x does not match size %x\n",
- attr->len, prs_offset(ps) - start));
+ prs_uint32("len ", ps, depth, &(attr->len)); /* 0x18 - length (in bytes) inc. the length field. */
+ prs_uint32("ptr_root_dir", ps, depth, &(attr->ptr_root_dir)); /* 0 - root directory (pointer) */
+ prs_uint32("ptr_obj_name", ps, depth, &(attr->ptr_obj_name)); /* 0 - object name (pointer) */
+ prs_uint32("attributes ", ps, depth, &(attr->attributes)); /* 0 - attributes (undocumented) */
+ prs_uint32("ptr_sec_desc", ps, depth, &(attr->ptr_sec_desc)); /* 0 - security descriptior (pointer) */
+ prs_uint32("ptr_sec_qos ", ps, depth, &(attr->ptr_sec_qos)); /* security quality of service (pointer) */
+
+ if (attr->len != ps->offset - start)
+ {
+ DEBUG(3,
+ ("lsa_io_obj_attr: length %x does not match size %x\n",
+ attr->len, ps->offset - start));
}
- if (attr->ptr_sec_qos != 0 && attr->sec_qos != NULL) {
- if(!lsa_io_sec_qos("sec_qos", attr->sec_qos, ps, depth))
- return False;
+ if (attr->ptr_sec_qos != 0 && attr->sec_qos != NULL)
+ {
+ lsa_io_sec_qos("sec_qos", attr->sec_qos, ps, depth);
}
return True;
@@ -268,30 +329,36 @@ static BOOL lsa_io_obj_attr(char *desc, LSA_OBJ_ATTR *attr, prs_struct *ps, int
/*******************************************************************
- Inits an LSA_Q_OPEN_POL structure.
+makes an LSA_Q_OPEN_POL structure.
********************************************************************/
-
-void init_q_open_pol(LSA_Q_OPEN_POL *r_q, uint16 system_name,
- uint32 attributes,
- uint32 desired_access,
- LSA_SEC_QOS *qos)
+BOOL make_q_open_pol(LSA_Q_OPEN_POL * r_q, uint16 system_name,
+ uint32 attributes,
+ uint32 desired_access, LSA_SEC_QOS * qos)
{
- DEBUG(5,("make_open_pol: attr:%d da:%d\n", attributes, desired_access));
+ if (r_q == NULL)
+ return False;
- r_q->ptr = 1; /* undocumented pointer */
+ DEBUG(5,
+ ("make_open_pol: attr:%d da:%d\n", attributes, desired_access));
+
+ r_q->ptr = 1; /* undocumented pointer */
if (qos == NULL)
+ {
r_q->des_access = desired_access;
+ }
r_q->system_name = system_name;
- init_lsa_obj_attr(&r_q->attr, attributes, qos);
+ make_lsa_obj_attr(&(r_q->attr), attributes, qos);
+
+ return True;
}
/*******************************************************************
- Reads or writes an LSA_Q_OPEN_POL structure.
+reads or writes an LSA_Q_OPEN_POL structure.
********************************************************************/
-
-BOOL lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int depth)
+BOOL lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL * r_q, prs_struct * ps,
+ int depth)
{
if (r_q == NULL)
return False;
@@ -299,29 +366,25 @@ BOOL lsa_io_q_open_pol(char *desc, LSA_Q_OPEN_POL *r_q, prs_struct *ps, int dept
prs_debug(ps, depth, desc, "lsa_io_q_open_pol");
depth++;
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
- return False;
- if(!prs_uint16("system_name", ps, depth, &r_q->system_name))
- return False;
- if(!prs_align( ps ))
- return False;
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr));
+ prs_uint16("system_name", ps, depth, &(r_q->system_name));
+ prs_align(ps);
- if(!lsa_io_obj_attr("", &r_q->attr, ps, depth))
- return False;
+ lsa_io_obj_attr("", &(r_q->attr), ps, depth);
- if (r_q->attr.ptr_sec_qos == 0) {
- if(!prs_uint32("des_access", ps, depth, &r_q->des_access))
- return False;
+ if (r_q->attr.ptr_sec_qos == 0)
+ {
+ prs_uint32("des_access", ps, depth, &(r_q->des_access));
}
return True;
}
/*******************************************************************
- Reads or writes an LSA_R_OPEN_POL structure.
+reads or writes an LSA_R_OPEN_POL structure.
********************************************************************/
-
-BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int depth)
+BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL * r_p, prs_struct * ps,
+ int depth)
{
if (r_p == NULL)
return False;
@@ -329,40 +392,46 @@ BOOL lsa_io_r_open_pol(char *desc, LSA_R_OPEN_POL *r_p, prs_struct *ps, int dept
prs_debug(ps, depth, desc, "lsa_io_r_open_pol");
depth++;
- if(!smb_io_pol_hnd("", &r_p->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_p->pol), ps, depth);
- if(!prs_uint32("status", ps, depth, &r_p->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_p->status));
return True;
}
/*******************************************************************
- Inits an LSA_Q_OPEN_POL2 structure.
+makes an LSA_Q_OPEN_POL2 structure.
********************************************************************/
-
-void init_q_open_pol2(LSA_Q_OPEN_POL2 *r_q, char *server_name,
- uint32 attributes,
- uint32 desired_access,
- LSA_SEC_QOS *qos)
+BOOL make_q_open_pol2(LSA_Q_OPEN_POL2 * r_q, const char *server_name,
+ uint32 attributes,
+ uint32 desired_access, LSA_SEC_QOS * qos)
{
- DEBUG(5,("make_open_pol2: attr:%d da:%d\n", attributes, desired_access));
+ if (r_q == NULL)
+ return False;
- r_q->ptr = 1; /* undocumented pointer */
+ DEBUG(5,
+ ("make_open_pol2: attr:%d da:%d\n", attributes,
+ desired_access));
+
+ r_q->ptr = 1; /* undocumented pointer */
if (qos == NULL)
+ {
r_q->des_access = desired_access;
+ }
- init_unistr2(&r_q->uni_server_name, server_name, strlen(server_name));
- init_lsa_obj_attr(&r_q->attr, attributes, qos);
+ make_unistr2(&(r_q->uni_server_name), server_name,
+ strlen(server_name));
+ make_lsa_obj_attr(&(r_q->attr), attributes, qos);
+
+ return True;
}
/*******************************************************************
- Reads or writes an LSA_Q_OPEN_POL2 structure.
+reads or writes an LSA_Q_OPEN_POL2 structure.
********************************************************************/
-
-BOOL lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, int depth)
+BOOL lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 * r_q, prs_struct * ps,
+ int depth)
{
if (r_q == NULL)
return False;
@@ -370,27 +439,26 @@ BOOL lsa_io_q_open_pol2(char *desc, LSA_Q_OPEN_POL2 *r_q, prs_struct *ps, int de
prs_debug(ps, depth, desc, "lsa_io_q_open_pol2");
depth++;
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
- return False;
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr));
- if(!smb_io_unistr2 ("", &r_q->uni_server_name, r_q->ptr, ps, depth))
- return False;
- if(!lsa_io_obj_attr("", &r_q->attr, ps, depth))
- return False;
+ smb_io_unistr2("", &(r_q->uni_server_name), r_q->ptr, ps, depth);
+ prs_align(ps);
- if (r_q->attr.ptr_sec_qos == 0) {
- if(!prs_uint32("des_access", ps, depth, &r_q->des_access))
- return False;
+ lsa_io_obj_attr("", &(r_q->attr), ps, depth);
+
+ if (r_q->attr.ptr_sec_qos == 0)
+ {
+ prs_uint32("des_access", ps, depth, &(r_q->des_access));
}
return True;
}
/*******************************************************************
- Reads or writes an LSA_R_OPEN_POL2 structure.
+reads or writes an LSA_R_OPEN_POL2 structure.
********************************************************************/
-
-BOOL lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 *r_p, prs_struct *ps, int depth)
+BOOL lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 * r_p, prs_struct * ps,
+ int depth)
{
if (r_p == NULL)
return False;
@@ -398,33 +466,93 @@ BOOL lsa_io_r_open_pol2(char *desc, LSA_R_OPEN_POL2 *r_p, prs_struct *ps, int de
prs_debug(ps, depth, desc, "lsa_io_r_open_pol2");
depth++;
- if(!smb_io_pol_hnd("", &r_p->pol, ps, depth))
+ smb_io_pol_hnd("", &(r_p->pol), ps, depth);
+
+ prs_uint32("status", ps, depth, &(r_p->status));
+
+ return True;
+
+ return True;
+}
+
+/*******************************************************************
+makes an LSA_Q_QUERY_SEC_OBJ structure.
+********************************************************************/
+BOOL make_q_query_sec_obj(LSA_Q_QUERY_SEC_OBJ * q_q, const POLICY_HND *hnd,
+ uint32 sec_info)
+{
+ if (q_q == NULL || hnd == NULL)
return False;
- if(!prs_uint32("status", ps, depth, &r_p->status))
+ DEBUG(5, ("make_q_query_sec_obj\n"));
+
+ q_q->pol = *hnd;
+ q_q->sec_info = sec_info;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_QUERY_SEC_OBJ structure.
+********************************************************************/
+BOOL lsa_io_q_query_sec_obj(char *desc, LSA_Q_QUERY_SEC_OBJ * q_q, prs_struct * ps,
+ int depth)
+{
+ if (q_q == NULL)
return False;
+ prs_debug(ps, depth, desc, "lsa_io_q_query_sec_obj");
+ depth++;
+
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+ prs_uint32("sec_info", ps, depth, &(q_q->sec_info));
+
return True;
}
/*******************************************************************
- Inits an LSA_Q_QUERY_INFO structure.
+reads or writes a LSA_R_QUERY_SEC_OBJ structure.
********************************************************************/
+BOOL lsa_io_r_query_sec_obj(char *desc, LSA_R_QUERY_SEC_OBJ *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_query_sec_obj");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr", ps, depth, &(r_u->ptr));
+ if (r_u->ptr != 0x0)
+ {
+ sec_io_desc_buf("sec", &r_u->buf, ps, depth);
+ }
+ prs_uint32("status", ps, depth, &(r_u->status));
-void init_q_query(LSA_Q_QUERY_INFO *q_q, POLICY_HND *hnd, uint16 info_class)
+ return True;
+}
+/*******************************************************************
+makes an LSA_Q_QUERY_INFO structure.
+********************************************************************/
+BOOL make_q_query(LSA_Q_QUERY_INFO * q_q, POLICY_HND *hnd, uint16 info_class)
{
- DEBUG(5,("make_q_query\n"));
+ if (q_q == NULL || hnd == NULL)
+ return False;
+
+ DEBUG(5, ("make_q_query\n"));
- memcpy(&q_q->pol, hnd, sizeof(q_q->pol));
+ memcpy(&(q_q->pol), hnd, sizeof(q_q->pol));
q_q->info_class = info_class;
+
+ return True;
}
/*******************************************************************
- Reads or writes an LSA_Q_QUERY_INFO structure.
+reads or writes an LSA_Q_QUERY_INFO structure.
********************************************************************/
-
-BOOL lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth)
+BOOL lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO * q_q, prs_struct * ps,
+ int depth)
{
if (q_q == NULL)
return False;
@@ -432,74 +560,431 @@ BOOL lsa_io_q_query(char *desc, LSA_Q_QUERY_INFO *q_q, prs_struct *ps, int depth
prs_debug(ps, depth, desc, "lsa_io_q_query");
depth++;
- if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+
+ prs_uint16("info_class", ps, depth, &(q_q->info_class));
+
+ return True;
+}
+
+/*******************************************************************
+makes an LSA_Q_CREATE_SECRET structure.
+********************************************************************/
+BOOL make_q_create_secret(LSA_Q_CREATE_SECRET * q_o,
+ const POLICY_HND *pol_hnd, const char *secret_name,
+ uint32 desired_access)
+{
+ int len = strlen(secret_name);
+
+ if (q_o == NULL)
return False;
- if(!prs_uint16("info_class", ps, depth, &q_q->info_class))
+ DEBUG(5, ("make_q_create_secret"));
+
+ memcpy(&(q_o->pol), pol_hnd, sizeof(q_o->pol));
+
+ make_uni_hdr(&(q_o->hdr_secret), len);
+ make_unistr2(&(q_o->uni_secret), secret_name, len);
+
+ q_o->des_access = desired_access;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_CREATE_SECRET structure.
+********************************************************************/
+BOOL lsa_io_q_create_secret(char *desc, LSA_Q_CREATE_SECRET * q_o,
+ prs_struct * ps, int depth)
+{
+ if (q_o == NULL)
return False;
+ prs_debug(ps, depth, desc, "lsa_io_q_create_secret");
+ depth++;
+
+ smb_io_pol_hnd("", &(q_o->pol), ps, depth);
+
+ prs_align(ps);
+ smb_io_unihdr("", &(q_o->hdr_secret), ps, depth);
+ smb_io_unistr2("", &(q_o->uni_secret), 1, ps, depth);
+
+ prs_align(ps);
+ prs_uint32("des_access", ps, depth, &(q_o->des_access));
+
return True;
}
/*******************************************************************
- Reads or writes an LSA_Q_ENUM_TRUST_DOM structure.
+reads or writes an LSA_R_CREATE_SECRET structure.
********************************************************************/
+BOOL lsa_io_r_create_secret(char *desc, LSA_R_CREATE_SECRET * r_o,
+ prs_struct * ps, int depth)
+{
+ if (r_o == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_create_secret");
+ depth++;
+
+ smb_io_pol_hnd("", &(r_o->pol), ps, depth);
-BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM *q_e, prs_struct *ps, int depth)
+ prs_uint32("status", ps, depth, &(r_o->status));
+
+ return True;
+}
+
+/*******************************************************************
+makes an LSA_Q_OPEN_SECRET structure.
+********************************************************************/
+BOOL make_q_open_secret(LSA_Q_OPEN_SECRET * q_o, const POLICY_HND *pol_hnd,
+ const char *secret_name, uint32 desired_access)
{
- if (q_e == NULL)
+ int len = strlen(secret_name);
+
+ if (q_o == NULL)
return False;
- prs_debug(ps, depth, desc, "lsa_io_q_enum_trust_dom");
+ DEBUG(5, ("make_q_open_secret"));
+
+ memcpy(&(q_o->pol), pol_hnd, sizeof(q_o->pol));
+
+ make_uni_hdr(&(q_o->hdr_secret), len);
+ make_unistr2(&(q_o->uni_secret), secret_name, len);
+
+ q_o->des_access = desired_access;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_OPEN_SECRET structure.
+********************************************************************/
+BOOL lsa_io_q_open_secret(char *desc, LSA_Q_OPEN_SECRET * q_o,
+ prs_struct * ps, int depth)
+{
+ if (q_o == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_open_secret");
+ depth++;
+
+ smb_io_pol_hnd("", &(q_o->pol), ps, depth);
+
+ prs_align(ps);
+ smb_io_unihdr("", &(q_o->hdr_secret), ps, depth);
+ smb_io_unistr2("", &(q_o->uni_secret), 1, ps, depth);
+
+ prs_align(ps);
+ prs_uint32("des_access", ps, depth, &(q_o->des_access));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_R_OPEN_SECRET structure.
+********************************************************************/
+BOOL lsa_io_r_open_secret(char *desc, LSA_R_OPEN_SECRET * r_o,
+ prs_struct * ps, int depth)
+{
+ if (r_o == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_open_secret");
+ depth++;
+
+ smb_io_pol_hnd("", &(r_o->pol), ps, depth);
+
+ prs_uint32("status", ps, depth, &(r_o->status));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_SECRET_VALUE structure.
+********************************************************************/
+BOOL lsa_io_secret_value(char *desc, LSA_SECRET_VALUE * value,
+ prs_struct * ps, int depth)
+{
+ if (value == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_secret_value");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("ptr_secret", ps, depth, &(value->ptr_secret));
+
+ if (value->ptr_secret != 0)
+ {
+ smb_io_strhdr2("hdr_secret", &(value->hdr_secret), ps, depth);
+ smb_io_string2("secret", &(value->enc_secret),
+ value->hdr_secret.buffer, ps, depth);
+ }
+
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_SECRET_INFO structure.
+********************************************************************/
+BOOL lsa_io_secret_info(char *desc, LSA_SECRET_INFO * info, prs_struct * ps,
+ int depth)
+{
+ if (info == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_secret_info");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("ptr_value ", ps, depth, &(info->ptr_value));
+
+ if (info->ptr_value != 0)
+ {
+ lsa_io_secret_value("", &(info->value), ps, depth);
+ }
+
+ prs_align(ps);
+ prs_uint32("ptr_update", ps, depth, &(info->ptr_update));
+
+ if (info->ptr_update != 0)
+ {
+ ps->align = 8;
+ prs_align(ps);
+ ps->align = 4;
+
+ smb_io_time("last_update", &(info->last_update), ps, depth);
+ }
+
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_SECRET structure.
+********************************************************************/
+BOOL lsa_io_secret(char *desc, LSA_SECRET * q_q, prs_struct * ps, int depth)
+{
+ if (q_q == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_secret");
depth++;
+ lsa_io_secret_info("", &(q_q->curinfo), ps, depth);
+ lsa_io_secret_info("", &(q_q->oldinfo), ps, depth);
- if(!smb_io_pol_hnd("", &q_e->pol, ps, depth))
+ return True;
+}
+
+/*******************************************************************
+makes an LSA_Q_QUERY_SECRET structure.
+********************************************************************/
+BOOL make_q_query_secret(LSA_Q_QUERY_SECRET * q_q, POLICY_HND *pol,
+ const STRING2 *secret, const NTTIME * update)
+{
+ if (q_q == NULL)
+ return False;
+
+ DEBUG(5, ("make_q_query_secret\n"));
+
+ memcpy(&(q_q->pol), pol, sizeof(q_q->pol));
+
+ /* Want secret */
+ q_q->sec.curinfo.ptr_value = secret != NULL ? 1 : 0;
+ q_q->sec.curinfo.value.ptr_secret = 0;
+
+ /* Want last change time */
+ q_q->sec.curinfo.ptr_update = update != NULL ? 1 : 0;
+
+ /* Don't care about old info */
+ q_q->sec.oldinfo.ptr_value = 0;
+ q_q->sec.oldinfo.ptr_update = 0;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_QUERY_SECRET structure.
+********************************************************************/
+BOOL lsa_io_q_query_secret(char *desc, LSA_Q_QUERY_SECRET * q_q,
+ prs_struct * ps, int depth)
+{
+ if (q_q == NULL)
return False;
- if(!prs_uint32("enum_context ", ps, depth, &q_e->enum_context))
+ prs_debug(ps, depth, desc, "lsa_io_q_query_secret");
+ depth++;
+
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+ lsa_io_secret("", &(q_q->sec), ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_QUERY_SECRET structure.
+********************************************************************/
+BOOL lsa_io_r_query_secret(char *desc, LSA_R_QUERY_SECRET * r_q,
+ prs_struct * ps, int depth)
+{
+ if (r_q == NULL)
return False;
- if(!prs_uint32("preferred_len", ps, depth, &q_e->preferred_len))
+
+ prs_debug(ps, depth, desc, "lsa_io_r_query_secret");
+ depth++;
+
+ lsa_io_secret("", &(r_q->sec), ps, depth);
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_q->status));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_SET_SECRET structure.
+********************************************************************/
+BOOL lsa_io_q_set_secret(char *desc, LSA_Q_SET_SECRET * q_q, prs_struct * ps,
+ int depth)
+{
+ if (q_q == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_set_secret");
+ depth++;
+
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
+
+ lsa_io_secret_value("", &(q_q->value), ps, depth);
+ prs_uint32("unknown", ps, depth, &(q_q->unknown));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an LSA_Q_SET_SECRET structure.
+********************************************************************/
+BOOL lsa_io_r_set_secret(char *desc, LSA_R_SET_SECRET * r_q, prs_struct * ps,
+ int depth)
+{
+ if (r_q == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_r_set_secret");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_q->status));
+
+ return True;
+}
+
+/*******************************************************************
+makes an LSA_Q_ENUM_TRUST_DOM structure.
+********************************************************************/
+BOOL make_q_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM * q_e,
+ POLICY_HND *pol,
+ uint32 enum_context, uint32 preferred_len)
+{
+ if (q_e == NULL)
return False;
+ DEBUG(5, ("make_q_enum_trust_dom\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(q_e->pol));
+ q_e->enum_context = enum_context;
+ q_e->preferred_len = preferred_len;
+
return True;
}
/*******************************************************************
- Inits an LSA_R_ENUM_TRUST_DOM structure.
+reads or writes an LSA_Q_ENUM_TRUST_DOM structure.
********************************************************************/
+BOOL lsa_io_q_enum_trust_dom(char *desc, LSA_Q_ENUM_TRUST_DOM * q_e,
+ prs_struct * ps, int depth)
+{
+ if (q_e == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_q_enum_trust_dom");
+ depth++;
+
+
+ smb_io_pol_hnd("", &(q_e->pol), ps, depth);
+
+ prs_uint32("enum_context ", ps, depth, &(q_e->enum_context));
+ prs_uint32("preferred_len", ps, depth, &(q_e->preferred_len));
+
+ return True;
+}
-void init_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM *r_e,
- uint32 enum_context, char *domain_name, DOM_SID *domain_sid,
- uint32 status)
+/*******************************************************************
+makes an LSA_R_ENUM_TRUST_DOM structure.
+********************************************************************/
+BOOL make_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM * r_e, int32 enum_context,
+ uint32 num_domains,
+ UNISTR2 * domain_names, DOM_SID ** domain_sids,
+ uint32 status)
{
- DEBUG(5,("make_r_enum_trust_dom\n"));
+ if (r_e == NULL)
+ return False;
+
+ DEBUG(5, ("make_r_enum_trust_dom\n"));
r_e->enum_context = enum_context;
- if (status == 0) {
- int len_domain_name = strlen(domain_name);
+ if ((domain_names == NULL) || (domain_sids == NULL))
+ {
+ num_domains = 0;
+ }
+
+ if ((status == 0) && (num_domains != 0))
+ {
+ uint32 i;
- r_e->num_domains = 1;
+ r_e->num_domains = num_domains;
r_e->ptr_enum_domains = 1;
- r_e->num_domains2 = 1;
-
- init_uni_hdr2(&r_e->hdr_domain_name, len_domain_name);
- init_unistr2 (&r_e->uni_domain_name, domain_name, len_domain_name);
- init_dom_sid2(&r_e->other_domain_sid, domain_sid);
- } else {
+ r_e->num_domains2 = num_domains;
+
+ r_e->hdr_domain_name = g_new(UNIHDR2, num_domains);
+ r_e->domain_sid = g_new(DOM_SID2, num_domains);
+ if ((r_e->hdr_domain_name == NULL)
+ || (r_e->domain_sid == NULL))
+ {
+ r_e->uni_domain_name = NULL;
+ lsa_free_r_enum_trust_dom(r_e);
+ r_e->status = status;
+ return False;
+ }
+ r_e->uni_domain_name = domain_names;
+ for (i = 0; i < num_domains; i++)
+ {
+ make_unihdr2_from_unistr2(&(r_e->hdr_domain_name[i]),
+ &(domain_names[i]));
+ make_dom_sid2(&(r_e->domain_sid[i]), domain_sids[i]);
+ }
+ }
+ else
+ {
r_e->num_domains = 0;
r_e->ptr_enum_domains = 0;
}
r_e->status = status;
+
+ return True;
}
/*******************************************************************
- Reads or writes an LSA_R_ENUM_TRUST_DOM structure.
+reads or writes an LSA_R_ENUM_TRUST_DOM structure.
********************************************************************/
-
-BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct *ps, int depth)
+BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM * r_e,
+ prs_struct * ps, int depth)
{
if (r_e == NULL)
return False;
@@ -507,35 +992,79 @@ BOOL lsa_io_r_enum_trust_dom(char *desc, LSA_R_ENUM_TRUST_DOM *r_e, prs_struct
prs_debug(ps, depth, desc, "lsa_io_r_enum_trust_dom");
depth++;
- if(!prs_uint32("enum_context ", ps, depth, &r_e->enum_context))
- return False;
- if(!prs_uint32("num_domains ", ps, depth, &r_e->num_domains))
- return False;
- if(!prs_uint32("ptr_enum_domains", ps, depth, &r_e->ptr_enum_domains))
- return False;
+ prs_uint32("enum_context ", ps, depth, &(r_e->enum_context));
+ prs_uint32("num_domains ", ps, depth, &(r_e->num_domains));
+ prs_uint32("ptr_enum_domains", ps, depth, &(r_e->ptr_enum_domains));
+
+ if (r_e->ptr_enum_domains != 0)
+ {
+ uint32 i, num_domains;
+ prs_uint32("num_domains2", ps, depth, &(r_e->num_domains2));
+ num_domains = r_e->num_domains2;
+
+ if (ps->io)
+ {
+ r_e->uni_domain_name = g_new(UNISTR2, num_domains);
+ r_e->hdr_domain_name = g_new(UNIHDR2, num_domains);
+ r_e->domain_sid = g_new(DOM_SID2, num_domains);
+ if ((r_e->uni_domain_name == NULL)
+ || (r_e->hdr_domain_name == NULL)
+ || (r_e->domain_sid == NULL))
+ {
+ lsa_free_r_enum_trust_dom(r_e);
+ return False;
+ }
+ }
- if (r_e->ptr_enum_domains != 0) {
- if(!prs_uint32("num_domains2", ps, depth, &r_e->num_domains2))
- return False;
- if(!smb_io_unihdr2 ("", &r_e->hdr_domain_name, ps, depth))
- return False;
- if(!smb_io_unistr2 ("", &r_e->uni_domain_name, r_e->hdr_domain_name.buffer, ps, depth))
- return False;
- if(!smb_io_dom_sid2("", &r_e->other_domain_sid, ps, depth))
- return False;
+ for (i = 0; i < num_domains; i++)
+ {
+ smb_io_unihdr2("", &(r_e->hdr_domain_name[i]), ps,
+ depth);
+ }
+
+ for (i = 0; i < num_domains; i++)
+ {
+ smb_io_unistr2("", &(r_e->uni_domain_name[i]),
+ r_e->hdr_domain_name[i].buffer, ps,
+ depth);
+ prs_align(ps);
+ smb_io_dom_sid2("", &(r_e->domain_sid[i]), ps, depth);
+ }
}
- if(!prs_uint32("status", ps, depth, &r_e->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_e->status));
+
+ if (!ps->io)
+ {
+ r_e->uni_domain_name = NULL;
+ lsa_free_r_enum_trust_dom(r_e);
+ }
return True;
}
+void lsa_free_r_enum_trust_dom(LSA_R_ENUM_TRUST_DOM * r_e)
+{
+ if (r_e == NULL)
+ {
+ return;
+ }
+ safe_free(r_e->uni_domain_name);
+ safe_free(r_e->hdr_domain_name);
+ safe_free(r_e->domain_sid);
+ r_e->uni_domain_name = NULL;
+ r_e->hdr_domain_name = NULL;
+ r_e->domain_sid = NULL;
+
+ r_e->num_domains = 0;
+ r_e->ptr_enum_domains = 0;
+}
+
/*******************************************************************
- Reads or writes an LSA_Q_QUERY_INFO structure.
+reads or writes an LSA_R_QUERY_INFO structure.
********************************************************************/
-
-BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth)
+BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO * r_q, prs_struct * ps,
+ int depth)
{
if (r_q == NULL)
return False;
@@ -543,69 +1072,82 @@ BOOL lsa_io_r_query(char *desc, LSA_R_QUERY_INFO *r_q, prs_struct *ps, int depth
prs_debug(ps, depth, desc, "lsa_io_r_query");
depth++;
- if(!prs_uint32("undoc_buffer", ps, depth, &r_q->undoc_buffer))
- return False;
+ prs_uint32("undoc_buffer", ps, depth, &(r_q->undoc_buffer));
- if (r_q->undoc_buffer != 0) {
- if(!prs_uint16("info_class", ps, depth, &r_q->info_class))
- return False;
+ if (r_q->undoc_buffer != 0)
+ {
+ prs_uint16("info_class", ps, depth, &(r_q->info_class));
+ prs_align(ps);
- switch (r_q->info_class) {
- case 3:
- if(!smb_io_dom_query_3("", &r_q->dom.id3, ps, depth))
- return False;
- break;
- case 5:
- if(!smb_io_dom_query_5("", &r_q->dom.id3, ps, depth))
- return False;
- break;
- default:
- /* PANIC! */
- break;
+ switch (r_q->info_class)
+ {
+ case 3:
+ {
+ smb_io_dom_query_3("", &(r_q->dom.id3), ps,
+ depth);
+ break;
+ }
+ case 5:
+ {
+ smb_io_dom_query_5("", &(r_q->dom.id3), ps,
+ depth);
+ break;
+ }
+ default:
+ {
+ /* PANIC! */
+ break;
+ }
}
}
- if(!prs_uint32("status", ps, depth, &r_q->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_q->status));
return True;
}
/*******************************************************************
- Inits a LSA_SID_ENUM structure.
+makes a LSA_SID_ENUM structure.
********************************************************************/
-
-void init_lsa_sid_enum(LSA_SID_ENUM *sen, int num_entries, DOM_SID **sids)
+BOOL make_lsa_sid_enum(LSA_SID_ENUM * sen, uint32 num_entries,
+ DOM_SID ** sids)
{
- int i, i2;
+ uint32 i, i2;
+ if (sen == NULL || sids == NULL)
+ return False;
- DEBUG(5,("make_lsa_sid_enum\n"));
+ DEBUG(5, ("make_lsa_sid_enum\n"));
- sen->num_entries = num_entries;
- sen->ptr_sid_enum = (num_entries != 0) ? 1 : 0;
+ sen->num_entries = num_entries;
+ sen->ptr_sid_enum = num_entries != 0 ? 1 : 0;
sen->num_entries2 = num_entries;
SMB_ASSERT_ARRAY(sen->sid, sen->num_entries);
- for (i = 0, i2 = 0; i < num_entries; i++) {
- if (sids[i] != NULL) {
+ for (i = 0, i2 = 0; i < num_entries; i++)
+ {
+ if (sids[i] != NULL)
+ {
sen->ptr_sid[i] = 1;
- init_dom_sid2(&sen->sid[i2], sids[i]);
+ make_dom_sid2(&(sen->sid[i2]), sids[i]);
i2++;
- } else {
+ }
+ else
+ {
sen->ptr_sid[i] = 0;
}
}
+
+ return True;
}
/*******************************************************************
- Reads or writes a LSA_SID_ENUM structure.
+reads or writes a LSA_SID_ENUM structure.
********************************************************************/
-
-static BOOL lsa_io_sid_enum(char *desc, LSA_SID_ENUM *sen,
- prs_struct *ps, int depth)
+static BOOL lsa_io_sid_enum(char *desc, LSA_SID_ENUM * sen,
+ prs_struct * ps, int depth)
{
- int i;
+ uint32 i;
if (sen == NULL)
return False;
@@ -613,142 +1155,132 @@ static BOOL lsa_io_sid_enum(char *desc, LSA_SID_ENUM *sen,
prs_debug(ps, depth, desc, "lsa_io_sid_enum");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("num_entries ", ps, depth, &sen->num_entries))
- return False;
- if(!prs_uint32("ptr_sid_enum", ps, depth, &sen->ptr_sid_enum))
- return False;
- if(!prs_uint32("num_entries2", ps, depth, &sen->num_entries2))
- return False;
+ prs_align(ps);
+
+ prs_uint32("num_entries ", ps, depth, &(sen->num_entries));
+ prs_uint32("ptr_sid_enum", ps, depth, &(sen->ptr_sid_enum));
+ prs_uint32("num_entries2", ps, depth, &(sen->num_entries2));
SMB_ASSERT_ARRAY(sen->ptr_sid, sen->num_entries);
- for (i = 0; i < sen->num_entries; i++) {
+ for (i = 0; i < sen->num_entries; i++)
+ {
fstring temp;
slprintf(temp, sizeof(temp) - 1, "ptr_sid[%d]", i);
- if(!prs_uint32(temp, ps, depth, &sen->ptr_sid[i])) /* domain SID pointers to be looked up. */
- return False;
+ prs_uint32(temp, ps, depth, &(sen->ptr_sid[i])); /* domain SID pointers to be looked up. */
}
SMB_ASSERT_ARRAY(sen->sid, sen->num_entries);
- for (i = 0; i < sen->num_entries; i++) {
+ for (i = 0; i < sen->num_entries; i++)
+ {
fstring temp;
slprintf(temp, sizeof(temp) - 1, "sid[%d]", i);
- if(!smb_io_dom_sid2(temp, &sen->sid[i], ps, depth)) /* domain SIDs to be looked up. */
- return False;
+ smb_io_dom_sid2(temp, &(sen->sid[i]), ps, depth); /* domain SIDs to be looked up. */
}
return True;
}
/*******************************************************************
- Inits an LSA_R_ENUM_TRUST_DOM structure.
+reads or writes a structure.
********************************************************************/
-
-void init_q_lookup_sids(LSA_Q_LOOKUP_SIDS *q_l, POLICY_HND *hnd,
- int num_sids, DOM_SID **sids,
- uint16 level)
+static BOOL lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM * trn,
+ prs_struct * ps, int depth)
{
- DEBUG(5,("make_r_enum_trust_dom\n"));
+ uint32 i;
+
+ if (trn == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "lsa_io_trans_names");
+ depth++;
- memcpy(&q_l->pol, hnd, sizeof(q_l->pol));
- init_lsa_sid_enum(&q_l->sids, num_sids, sids);
+ prs_align(ps);
- q_l->names.num_entries = 0;
- q_l->names.ptr_trans_names = 0;
- q_l->names.num_entries2 = 0;
+ prs_uint32("num_entries ", ps, depth, &(trn->num_entries));
+ prs_uint32("ptr_trans_names", ps, depth, &(trn->ptr_trans_names));
- q_l->level.value = level;
+ if (trn->ptr_trans_names != 0)
+ {
+ prs_uint32("num_entries2 ", ps, depth,
+ &(trn->num_entries2));
+ SMB_ASSERT_ARRAY(trn->name, trn->num_entries);
+
+ for (i = 0; i < trn->num_entries2; i++)
+ {
+ fstring t;
+ slprintf(t, sizeof(t) - 1, "name[%d] ", i);
+
+ lsa_io_trans_name(t, &(trn->name[i]), ps, depth); /* translated name */
+
+ }
+ for (i = 0; i < trn->num_entries2; i++)
+ {
+ fstring t;
+ slprintf(t, sizeof(t) - 1, "name[%d] ", i);
+
+ smb_io_unistr2(t, &(trn->uni_name[i]),
+ trn->name[i].hdr_name.buffer, ps,
+ depth);
+ prs_align(ps);
+ }
+ }
+
+ return True;
}
/*******************************************************************
- Reads or writes a LSA_Q_LOOKUP_SIDS structure.
+makes a structure.
********************************************************************/
-
-BOOL lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS *q_s, prs_struct *ps, int depth)
+BOOL make_q_lookup_sids(LSA_Q_LOOKUP_SIDS * q_l, POLICY_HND *hnd,
+ int num_sids, DOM_SID ** sids, uint16 level)
{
- if (q_s == NULL)
+ if (q_l == NULL)
return False;
- prs_debug(ps, depth, desc, "lsa_io_q_lookup_sids");
- depth++;
+ DEBUG(5, ("make_q_lookup_sids\n"));
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("pol_hnd", &q_s->pol, ps, depth)) /* policy handle */
- return False;
- if(!lsa_io_sid_enum("sids ", &q_s->sids, ps, depth)) /* sids to be looked up */
- return False;
- if(!lsa_io_trans_names("names ", &q_s->names, ps, depth)) /* translated names */
- return False;
- if(!smb_io_lookup_level("switch ", &q_s->level, ps, depth)) /* lookup level */
- return False;
+ memcpy(&(q_l->pol), hnd, sizeof(q_l->pol));
+ make_lsa_sid_enum(&(q_l->sids), num_sids, sids);
- if(!prs_uint32("mapped_count", ps, depth, &q_s->mapped_count))
- return False;
+ q_l->names.ptr_trans_names = 0;
+ q_l->names.num_entries = 0;
+
+ q_l->level.value = level;
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a LSA_Q_LOOKUP_SIDS structure.
********************************************************************/
-
-static BOOL lsa_io_trans_names(char *desc, LSA_TRANS_NAME_ENUM *trn,
- prs_struct *ps, int depth)
+BOOL lsa_io_q_lookup_sids(char *desc, LSA_Q_LOOKUP_SIDS * q_s,
+ prs_struct * ps, int depth)
{
- int i;
-
- if (trn == NULL)
+ if (q_s == NULL)
return False;
- prs_debug(ps, depth, desc, "lsa_io_trans_names");
+ prs_debug(ps, depth, desc, "lsa_io_q_lookup_sids");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("num_entries ", ps, depth, &trn->num_entries))
- return False;
- if(!prs_uint32("ptr_trans_names", ps, depth, &trn->ptr_trans_names))
- return False;
+ prs_align(ps);
- if (trn->ptr_trans_names != 0) {
- if(!prs_uint32("num_entries2 ", ps, depth, &trn->num_entries2))
- return False;
- SMB_ASSERT_ARRAY(trn->name, trn->num_entries);
+ smb_io_pol_hnd("pol_hnd", &(q_s->pol), ps, depth); /* policy handle */
+ lsa_io_sid_enum("sids ", &(q_s->sids), ps, depth); /* sids to be looked up */
+ lsa_io_trans_names("names ", &(q_s->names), ps, depth); /* translated names */
+ smb_io_lookup_level("switch ", &(q_s->level), ps, depth); /* lookup level */
- for (i = 0; i < trn->num_entries2; i++) {
- fstring t;
- slprintf(t, sizeof(t) - 1, "name[%d] ", i);
-
- if(!lsa_io_trans_name(t, &trn->name[i], ps, depth)) /* translated name */
- return False;
- }
-
- for (i = 0; i < trn->num_entries2; i++) {
- fstring t;
- slprintf(t, sizeof(t) - 1, "name[%d] ", i);
-
- if(!smb_io_unistr2(t, &trn->uni_name[i], trn->name[i].hdr_name.buffer, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- }
- }
+ prs_uint32("mapped_count", ps, depth, &(q_s->mapped_count));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, int depth)
+BOOL lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS * r_s,
+ prs_struct * ps, int depth)
{
if (r_s == NULL)
return False;
@@ -756,27 +1288,20 @@ BOOL lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, in
prs_debug(ps, depth, desc, "lsa_io_r_lookup_sids");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_dom_ref", ps, depth, &r_s->ptr_dom_ref))
- return False;
+ prs_align(ps);
+ prs_uint32("ptr_dom_ref", ps, depth, &(r_s->ptr_dom_ref));
if (r_s->ptr_dom_ref != 0)
- if(!lsa_io_dom_r_ref ("dom_ref", r_s->dom_ref, ps, depth)) /* domain reference info */
- return False;
-
- if(!lsa_io_trans_names("names ", r_s->names, ps, depth)) /* translated names */
- return False;
+ {
+ lsa_io_dom_r_ref("dom_ref", r_s->dom_ref, ps, depth); /* domain reference info */
+ }
+ lsa_io_trans_names("names ", r_s->names, ps, depth); /* translated names */
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("mapped_count", ps, depth, &r_s->mapped_count))
- return False;
+ prs_uint32("mapped_count", ps, depth, &(r_s->mapped_count));
- if(!prs_uint32("status ", ps, depth, &r_s->status))
- return False;
+ prs_uint32("status ", ps, depth, &(r_s->status));
return True;
}
@@ -784,41 +1309,45 @@ BOOL lsa_io_r_lookup_sids(char *desc, LSA_R_LOOKUP_SIDS *r_s, prs_struct *ps, in
/*******************************************************************
makes a structure.
********************************************************************/
-
-void init_q_lookup_names(LSA_Q_LOOKUP_NAMES *q_l, POLICY_HND *hnd,
- int num_names, char **names)
+BOOL make_q_lookup_names(LSA_Q_LOOKUP_NAMES * q_l, POLICY_HND *hnd,
+ uint32 num_names, char **names)
{
- int i;
+ uint32 i;
+ if (q_l == NULL)
+ return False;
- DEBUG(5,("init_q_lookup_names\n"));
+ DEBUG(5, ("make_q_lookup_names\n"));
- memcpy(&q_l->pol, hnd, sizeof(q_l->pol));
+ memcpy(&(q_l->pol), hnd, sizeof(q_l->pol));
q_l->num_entries = num_names;
q_l->num_entries2 = num_names;
SMB_ASSERT_ARRAY(q_l->uni_name, q_l->num_entries);
- for (i = 0; i < num_names; i++) {
- char* name = names[i];
+ for (i = 0; i < num_names; i++)
+ {
+ const char *name = names[i];
int len = strlen(name);
- init_uni_hdr(&q_l->hdr_name[i], len);
- init_unistr2(&q_l->uni_name[i], name, len);
+ make_uni_hdr(&q_l->hdr_name[i], len);
+ make_unistr2(&q_l->uni_name[i], name, len);
}
- q_l->num_trans_entries = 0;
- q_l->ptr_trans_sids = 0;
+ q_l->num_trans_entries = 0;
+ q_l->ptr_trans_sids = 0;
q_l->lookup_level = 1;
q_l->mapped_count = 0;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
-BOOL lsa_io_q_lookup_names(char *desc, LSA_Q_LOOKUP_NAMES *q_r, prs_struct *ps, int depth)
+BOOL lsa_io_q_lookup_names(char *desc, LSA_Q_LOOKUP_NAMES * q_r,
+ prs_struct * ps, int depth)
{
- int i;
+ uint32 i;
if (q_r == NULL)
return False;
@@ -826,39 +1355,32 @@ BOOL lsa_io_q_lookup_names(char *desc, LSA_Q_LOOKUP_NAMES *q_r, prs_struct *ps,
prs_debug(ps, depth, desc, "lsa_io_q_lookup_names");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &q_r->pol, ps, depth)) /* policy handle */
- return False;
+ smb_io_pol_hnd("", &(q_r->pol), ps, depth); /* policy handle */
- if(!prs_uint32("num_entries ", ps, depth, &q_r->num_entries))
- return False;
- if(!prs_uint32("num_entries2 ", ps, depth, &q_r->num_entries2))
- return False;
+ prs_uint32("num_entries ", ps, depth, &(q_r->num_entries));
+ prs_uint32("num_entries2 ", ps, depth, &(q_r->num_entries2));
SMB_ASSERT_ARRAY(q_r->uni_name, q_r->num_entries);
- for (i = 0; i < q_r->num_entries; i++) {
- if(!smb_io_unihdr("hdr_name", &q_r->hdr_name[i], ps, depth)) /* pointer names */
- return False;
+ for (i = 0; i < q_r->num_entries; i++)
+ {
+ smb_io_unihdr("hdr_name", &(q_r->hdr_name[i]), ps, depth); /* pointer names */
}
- for (i = 0; i < q_r->num_entries; i++) {
- if(!smb_io_unistr2("dom_name", &q_r->uni_name[i], q_r->hdr_name[i].buffer, ps, depth)) /* names to be looked up */
- return False;
- if(!prs_align(ps))
- return False;
+ for (i = 0; i < q_r->num_entries; i++)
+ {
+ smb_io_unistr2("dom_name", &(q_r->uni_name[i]),
+ q_r->hdr_name[i].buffer, ps, depth); /* names to be looked up */
+ prs_align(ps);
}
- if(!prs_uint32("num_trans_entries ", ps, depth, &q_r->num_trans_entries))
- return False;
- if(!prs_uint32("ptr_trans_sids ", ps, depth, &q_r->ptr_trans_sids))
- return False;
- if(!prs_uint32("lookup_level ", ps, depth, &q_r->lookup_level))
- return False;
- if(!prs_uint32("mapped_count ", ps, depth, &q_r->mapped_count))
- return False;
+ prs_uint32("num_trans_entries ", ps, depth,
+ &(q_r->num_trans_entries));
+ prs_uint32("ptr_trans_sids ", ps, depth, &(q_r->ptr_trans_sids));
+ prs_uint32("lookup_level ", ps, depth, &(q_r->lookup_level));
+ prs_uint32("mapped_count ", ps, depth, &(q_r->mapped_count));
return True;
}
@@ -866,10 +1388,10 @@ BOOL lsa_io_q_lookup_names(char *desc, LSA_Q_LOOKUP_NAMES *q_r, prs_struct *ps,
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
-BOOL lsa_io_r_lookup_names(char *desc, LSA_R_LOOKUP_NAMES *r_r, prs_struct *ps, int depth)
+BOOL lsa_io_r_lookup_names(char *desc, LSA_R_LOOKUP_NAMES * r_r,
+ prs_struct * ps, int depth)
{
- int i;
+ uint32 i;
if (r_r == NULL)
return False;
@@ -877,61 +1399,60 @@ BOOL lsa_io_r_lookup_names(char *desc, LSA_R_LOOKUP_NAMES *r_r, prs_struct *ps,
prs_debug(ps, depth, desc, "lsa_io_r_lookup_names");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_dom_ref", ps, depth, &r_r->ptr_dom_ref))
- return False;
+ prs_align(ps);
+ prs_uint32("ptr_dom_ref", ps, depth, &(r_r->ptr_dom_ref));
if (r_r->ptr_dom_ref != 0)
- if(!lsa_io_dom_r_ref("", r_r->dom_ref, ps, depth))
- return False;
+ {
+ lsa_io_dom_r_ref("", r_r->dom_ref, ps, depth);
+ }
- if(!prs_uint32("num_entries", ps, depth, &r_r->num_entries))
- return False;
- if(!prs_uint32("ptr_entries", ps, depth, &r_r->ptr_entries))
- return False;
+ prs_uint32("num_entries", ps, depth, &(r_r->num_entries));
+ prs_uint32("ptr_entries", ps, depth, &(r_r->ptr_entries));
- if (r_r->ptr_entries != 0) {
- if(!prs_uint32("num_entries2", ps, depth, &r_r->num_entries2))
- return False;
+ if (r_r->ptr_entries != 0)
+ {
+ prs_uint32("num_entries2", ps, depth, &(r_r->num_entries2));
- if (r_r->num_entries2 != r_r->num_entries) {
+ if (r_r->num_entries2 != r_r->num_entries)
+ {
/* RPC fault */
return False;
}
for (i = 0; i < r_r->num_entries2; i++)
- if(!smb_io_dom_rid2("", &r_r->dom_rid[i], ps, depth)) /* domain RIDs being looked up */
- return False;
+ {
+ smb_io_dom_rid2("", &(r_r->dom_rid[i]), ps, depth); /* domain RIDs being looked up */
+ }
}
- if(!prs_uint32("mapped_count", ps, depth, &r_r->mapped_count))
- return False;
+ prs_uint32("mapped_count", ps, depth, &(r_r->mapped_count));
- if(!prs_uint32("status ", ps, depth, &r_r->status))
- return False;
+ prs_uint32("status ", ps, depth, &(r_r->status));
return True;
}
/*******************************************************************
- Inits an LSA_Q_CLOSE structure.
+makes an LSA_Q_CLOSE structure.
********************************************************************/
-
-void init_lsa_q_close(LSA_Q_CLOSE *q_c, POLICY_HND *hnd)
+BOOL make_lsa_q_close(LSA_Q_CLOSE * q_c, POLICY_HND *hnd)
{
- DEBUG(5,("make_lsa_q_close\n"));
+ if (q_c == NULL || hnd == NULL)
+ return False;
+
+ DEBUG(5, ("make_lsa_q_close\n"));
- memcpy(&q_c->pol, hnd, sizeof(q_c->pol));
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+
+ return True;
}
/*******************************************************************
- Reads or writes an LSA_Q_CLOSE structure.
+reads or writes an LSA_Q_CLOSE structure.
********************************************************************/
-
-BOOL lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth)
+BOOL lsa_io_q_close(char *desc, LSA_Q_CLOSE * q_c, prs_struct * ps, int depth)
{
if (q_c == NULL)
return False;
@@ -939,17 +1460,15 @@ BOOL lsa_io_q_close(char *desc, LSA_Q_CLOSE *q_c, prs_struct *ps, int depth)
prs_debug(ps, depth, desc, "lsa_io_q_close");
depth++;
- if(!smb_io_pol_hnd("", &q_c->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(q_c->pol), ps, depth);
return True;
}
/*******************************************************************
- Reads or writes an LSA_R_CLOSE structure.
+reads or writes an LSA_R_CLOSE structure.
********************************************************************/
-
-BOOL lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth)
+BOOL lsa_io_r_close(char *desc, LSA_R_CLOSE * r_c, prs_struct * ps, int depth)
{
if (r_c == NULL)
return False;
@@ -957,11 +1476,9 @@ BOOL lsa_io_r_close(char *desc, LSA_R_CLOSE *r_c, prs_struct *ps, int depth)
prs_debug(ps, depth, desc, "lsa_io_r_close");
depth++;
- if(!smb_io_pol_hnd("", &r_c->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_c->pol), ps, depth);
- if(!prs_uint32("status", ps, depth, &r_c->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_c->status));
return True;
}
diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c
index 21d97b444c3..5ec0496f76d 100644
--- a/source/rpc_parse/parse_misc.c
+++ b/source/rpc_parse/parse_misc.c
@@ -1,3 +1,4 @@
+
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
@@ -26,487 +27,485 @@
extern int DEBUGLEVEL;
+
/*******************************************************************
- Reads or writes a UTIME type.
+reads or writes a BIGINT structure.
********************************************************************/
+BOOL smb_io_bigint(char *desc, BIGINT *bigint, prs_struct *ps, int depth)
+{
+ if (bigint == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_bigint");
+ depth++;
-static BOOL smb_io_utime(char *desc, UTIME *t, prs_struct *ps, int depth)
+ prs_align(ps);
+
+ prs_uint32("low ", ps, depth, &(bigint->low ));
+ prs_uint32("high", ps, depth, &(bigint->high));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a UTIME type.
+********************************************************************/
+static BOOL smb_io_utime(char *desc, UTIME *t, prs_struct *ps, int depth)
{
- if (t == NULL)
- return False;
+ if (t == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_utime");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32 ("time", ps, depth, &t->time))
- return False;
+ prs_uint32 ("time", ps, depth, &(t->time));
return True;
}
/*******************************************************************
- Reads or writes an NTTIME structure.
+reads or writes an NTTIME structure.
********************************************************************/
-
-BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth)
+BOOL smb_io_time(char *desc, NTTIME *nttime, prs_struct *ps, int depth)
{
- if (nttime == NULL)
- return False;
+ if (nttime == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_time");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("low ", ps, depth, &nttime->low)) /* low part */
- return False;
- if(!prs_uint32("high", ps, depth, &nttime->high)) /* high part */
- return False;
+ prs_uint32("low ", ps, depth, &(nttime->low )); /* low part */
+ prs_uint32("high", ps, depth, &(nttime->high)); /* high part */
return True;
}
/*******************************************************************
- Reads or writes a LOOKUP_LEVEL structure.
+reads or writes a LOOKUP_LEVEL structure.
********************************************************************/
-
BOOL smb_io_lookup_level(char *desc, LOOKUP_LEVEL *level, prs_struct *ps, int depth)
{
- if (level == NULL)
- return False;
+ if (level == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_lookup_level");
depth++;
- if(!prs_align(ps))
- return False;
- if(!prs_uint16("value", ps, depth, &level->value))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+ prs_uint16("value", ps, depth, &(level->value));
+ prs_align(ps);
return True;
}
/*******************************************************************
- Gets an enumeration handle from an ENUM_HND structure.
+gets an enumeration handle from an ENUM_HND structure.
********************************************************************/
-
uint32 get_enum_hnd(ENUM_HND *enh)
{
return (enh && enh->ptr_hnd != 0) ? enh->handle : 0;
+
+ return True;
}
/*******************************************************************
- Inits an ENUM_HND structure.
+makes an ENUM_HND structure.
********************************************************************/
-
-void init_enum_hnd(ENUM_HND *enh, uint32 hnd)
+BOOL make_enum_hnd(ENUM_HND *enh, uint32 hnd)
{
+ if (enh == NULL) return False;
+
DEBUG(5,("smb_io_enum_hnd\n"));
enh->ptr_hnd = (hnd != 0) ? 1 : 0;
enh->handle = hnd;
+
+ return True;
}
/*******************************************************************
- Reads or writes an ENUM_HND structure.
+reads or writes an ENUM_HND structure.
********************************************************************/
-
-BOOL smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth)
+BOOL smb_io_enum_hnd(char *desc, ENUM_HND *hnd, prs_struct *ps, int depth)
{
- if (hnd == NULL)
- return False;
+ if (hnd == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_enum_hnd");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_hnd", ps, depth, &hnd->ptr_hnd)) /* pointer */
- return False;
-
- if (hnd->ptr_hnd != 0) {
- if(!prs_uint32("handle ", ps, depth, &hnd->handle )) /* enum handle */
- return False;
+ prs_uint32("ptr_hnd", ps, depth, &(hnd->ptr_hnd)); /* pointer */
+ if (hnd->ptr_hnd != 0)
+ {
+ prs_uint32("handle ", ps, depth, &(hnd->handle )); /* enum handle */
}
return True;
}
/*******************************************************************
- Reads or writes a DOM_SID structure.
+reads or writes a DOM_SID structure.
********************************************************************/
-
-BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth)
+BOOL smb_io_dom_sid(char *desc, DOM_SID *sid, prs_struct *ps, int depth)
{
int i;
- if (sid == NULL)
- return False;
+ if (sid == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_dom_sid");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num))
- return False;
- if(!prs_uint8 ("num_auths ", ps, depth, &sid->num_auths))
- return False;
+ prs_uint8 ("sid_rev_num", ps, depth, &(sid->sid_rev_num));
+ prs_uint8 ("num_auths ", ps, depth, &(sid->num_auths));
for (i = 0; i < 6; i++)
{
fstring tmp;
slprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i);
- if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i]))
- return False;
+ prs_uint8 (tmp, ps, depth, &(sid->id_auth[i]));
}
/* oops! XXXX should really issue a warning here... */
- if (sid->num_auths > MAXSUBAUTHS)
- sid->num_auths = MAXSUBAUTHS;
+ if (sid->num_auths > MAXSUBAUTHS) sid->num_auths = MAXSUBAUTHS;
- if(!prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths))
- return False;
+ prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths);
return True;
}
/*******************************************************************
- Inits a DOM_SID structure.
-
- BIG NOTE: this function only does SIDS where the identauth is not >= 2^32
- identauth >= 2^32 can be detected because it will be specified in hex
+creates a DOM_SID2 structure.
********************************************************************/
-
-void init_dom_sid(DOM_SID *sid, char *str_sid)
+BOOL make_dom_sid2(DOM_SID2 *sid2, const DOM_SID *sid)
{
- pstring domsid;
- int identauth;
- char *p;
-
- if (str_sid == NULL)
- {
- DEBUG(4,("netlogon domain SID: none\n"));
- sid->sid_rev_num = 0;
- sid->num_auths = 0;
- return;
- }
-
- pstrcpy(domsid, str_sid);
-
- DEBUG(4,("init_dom_sid %d SID: %s\n", __LINE__, domsid));
-
- /* assume, but should check, that domsid starts "S-" */
- p = strtok(domsid+2,"-");
- sid->sid_rev_num = atoi(p);
+ sid_copy(&sid2->sid, sid);
+ sid2->num_auths = sid2->sid.num_auths;
- /* identauth in decimal should be < 2^32 */
- /* identauth in hex should be >= 2^32 */
- identauth = atoi(strtok(0,"-"));
+ return True;
+}
- DEBUG(4,("netlogon rev %d\n", sid->sid_rev_num));
- DEBUG(4,("netlogon %s ia %d\n", p, identauth));
+/*******************************************************************
+reads or writes a DOM_SID2 structure.
+********************************************************************/
+BOOL smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
+{
+ if (sid == NULL) return False;
- sid->id_auth[0] = 0;
- sid->id_auth[1] = 0;
- sid->id_auth[2] = (identauth & 0xff000000) >> 24;
- sid->id_auth[3] = (identauth & 0x00ff0000) >> 16;
- sid->id_auth[4] = (identauth & 0x0000ff00) >> 8;
- sid->id_auth[5] = (identauth & 0x000000ff);
+ prs_debug(ps, depth, desc, "smb_io_dom_sid2");
+ depth++;
- sid->num_auths = 0;
+ prs_align(ps);
+
+ prs_uint32("num_auths", ps, depth, &(sid->num_auths));
- while ((p = strtok(0, "-")) != NULL && sid->num_auths < MAXSUBAUTHS)
- sid->sub_auths[sid->num_auths++] = atoi(p);
+ smb_io_dom_sid("sid", &(sid->sid), ps, depth);
- DEBUG(4,("init_dom_sid: %d SID: %s\n", __LINE__, domsid));
+ return True;
}
/*******************************************************************
- Inits a DOM_SID2 structure.
+creates a STRHDR structure.
********************************************************************/
-
-void init_dom_sid2(DOM_SID2 *sid2, DOM_SID *sid)
+BOOL make_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
{
- sid2->sid = *sid;
- sid2->num_auths = sid2->sid.num_auths;
+ hdr->str_max_len = max_len;
+ hdr->str_str_len = len;
+ hdr->buffer = buffer;
+
+ return True;
}
/*******************************************************************
- Reads or writes a DOM_SID2 structure.
+reads or writes a STRHDR structure.
********************************************************************/
-
-BOOL smb_io_dom_sid2(char *desc, DOM_SID2 *sid, prs_struct *ps, int depth)
+BOOL smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth)
{
- if (sid == NULL)
- return False;
+ if (hdr == NULL) return False;
- prs_debug(ps, depth, desc, "smb_io_dom_sid2");
+ prs_debug(ps, depth, desc, "smb_io_strhdr");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("num_auths", ps, depth, &sid->num_auths))
- return False;
+ prs_uint16("str_str_len", ps, depth, &(hdr->str_str_len));
+ prs_uint16("str_max_len", ps, depth, &(hdr->str_max_len));
+ prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
- if(!smb_io_dom_sid("sid", &sid->sid, ps, depth))
- return False;
+ /* oops! XXXX maybe issue a warning that this is happening... */
+ if (hdr->str_max_len > MAX_STRINGLEN) hdr->str_max_len = MAX_STRINGLEN;
+ if (hdr->str_str_len > MAX_STRINGLEN) hdr->str_str_len = MAX_STRINGLEN;
return True;
}
/*******************************************************************
-creates a STRHDR structure.
+creates a STRHDR2 structure.
********************************************************************/
-
-void init_str_hdr(STRHDR *hdr, int max_len, int len, uint32 buffer)
+BOOL make_strhdr2(STRHDR2 *hdr, uint32 max_len, uint32 len, uint32 buffer)
{
hdr->str_max_len = max_len;
hdr->str_str_len = len;
hdr->buffer = buffer;
+
+ return True;
}
/*******************************************************************
- Reads or writes a STRHDR structure.
+reads or writes a STRHDR2 structure.
********************************************************************/
-
-BOOL smb_io_strhdr(char *desc, STRHDR *hdr, prs_struct *ps, int depth)
+BOOL smb_io_strhdr2(char *desc, STRHDR2 *hdr, prs_struct *ps, int depth)
{
- if (hdr == NULL)
- return False;
+ if (hdr == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_strhdr");
depth++;
prs_align(ps);
- if(!prs_uint16("str_str_len", ps, depth, &hdr->str_str_len))
- return False;
- if(!prs_uint16("str_max_len", ps, depth, &hdr->str_max_len))
- return False;
- if(!prs_uint32("buffer ", ps, depth, &hdr->buffer))
- return False;
+ prs_uint32("str_str_len", ps, depth, &(hdr->str_str_len));
+ prs_uint32("str_max_len", ps, depth, &(hdr->str_max_len));
+ prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
/* oops! XXXX maybe issue a warning that this is happening... */
- if (hdr->str_max_len > MAX_STRINGLEN)
- hdr->str_max_len = MAX_STRINGLEN;
- if (hdr->str_str_len > MAX_STRINGLEN)
- hdr->str_str_len = MAX_STRINGLEN;
+ if (hdr->str_max_len > MAX_STRINGLEN) hdr->str_max_len = MAX_STRINGLEN;
+ if (hdr->str_str_len > MAX_STRINGLEN) hdr->str_str_len = MAX_STRINGLEN;
return True;
}
/*******************************************************************
- Inits a UNIHDR structure.
+creates a UNIHDR structure.
********************************************************************/
-
-void init_uni_hdr(UNIHDR *hdr, int len)
+BOOL make_uni_hdr(UNIHDR *hdr, int len)
{
+ if (hdr == NULL)
+ {
+ return False;
+ }
hdr->uni_str_len = 2 * len;
hdr->uni_max_len = 2 * len;
hdr->buffer = len != 0 ? 1 : 0;
+
+ return True;
}
/*******************************************************************
- Reads or writes a UNIHDR structure.
+creates a UNIHDR structure from a UNISTR2.
********************************************************************/
+BOOL make_unihdr_from_unistr2(UNIHDR *hdr, const UNISTR2 *str)
+{
+ int len;
-BOOL smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth)
+ len = (str ? str->uni_str_len : 0);
+
+ return make_uni_hdr(hdr, len);
+}
+
+/*******************************************************************
+reads or writes a UNIHDR structure.
+********************************************************************/
+BOOL smb_io_unihdr(char *desc, UNIHDR *hdr, prs_struct *ps, int depth)
{
- if (hdr == NULL)
- return False;
+ if (hdr == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_unihdr");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint16("uni_str_len", ps, depth, &hdr->uni_str_len))
- return False;
- if(!prs_uint16("uni_max_len", ps, depth, &hdr->uni_max_len))
- return False;
- if(!prs_uint32("buffer ", ps, depth, &hdr->buffer))
- return False;
+ prs_uint16("uni_str_len", ps, depth, &(hdr->uni_str_len));
+ prs_uint16("uni_max_len", ps, depth, &(hdr->uni_max_len));
+ prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
/* oops! XXXX maybe issue a warning that this is happening... */
- if (hdr->uni_max_len > MAX_UNISTRLEN)
- hdr->uni_max_len = MAX_UNISTRLEN;
- if (hdr->uni_str_len > MAX_UNISTRLEN)
- hdr->uni_str_len = MAX_UNISTRLEN;
+ if (hdr->uni_max_len > MAX_UNISTRLEN) hdr->uni_max_len = MAX_UNISTRLEN;
+ if (hdr->uni_str_len > MAX_UNISTRLEN) hdr->uni_str_len = MAX_UNISTRLEN;
return True;
}
/*******************************************************************
- Inits a BUFHDR structure.
+creates a BUFHDR structure.
********************************************************************/
-
-void init_buf_hdr(BUFHDR *hdr, int max_len, int len)
+BOOL make_buf_hdr(BUFHDR *hdr, int max_len, int len)
{
hdr->buf_max_len = max_len;
hdr->buf_len = len;
+
+ return True;
}
/*******************************************************************
- prs_uint16 wrapper. Call this and it sets up a pointer to where the
- uint16 should be stored, or gets the size if reading.
+ prs_uint16 wrapper. call this and it sets up a pointer to where the
+ uint16 should be stored, or gets the size if reading
********************************************************************/
-
-BOOL smb_io_hdrbuf_pre(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset)
+BOOL smb_io_hdrbuf_pre(char *desc, BUFHDR *hdr, prs_struct *ps, int depth, uint32 *offset)
{
- (*offset) = prs_offset(ps);
- if (ps->io) {
-
+ (*offset) = ps->offset;
+ if (ps->io)
+ {
/* reading. */
-
- if(!smb_io_hdrbuf(desc, hdr, ps, depth))
- return False;
-
- } else {
-
- /* writing. */
-
- if(!prs_set_offset(ps, prs_offset(ps) + (sizeof(uint32) * 2)))
- return False;
+ smb_io_hdrbuf(desc, hdr, ps, depth);
+ }
+ else
+ {
+ ps->offset += sizeof(uint32) * 2;
}
return True;
}
/*******************************************************************
- smb_io_hdrbuf wrapper. Call this and it retrospectively stores the size.
- Does nothing on reading, as that is already handled by ...._pre()
+ smb_io_hdrbuf wrapper. call this and it retrospectively stores the size.
+ does nothing on reading, as that is already handled by ...._pre()
********************************************************************/
-
-BOOL smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
+BOOL smb_io_hdrbuf_post(char *desc, BUFHDR *hdr, prs_struct *ps, int depth,
uint32 ptr_hdrbuf, uint32 max_len, uint32 len)
{
- if (!ps->io) {
- /* writing: go back and do a retrospective job. i hate this */
-
- uint32 old_offset = prs_offset(ps);
-
- init_buf_hdr(hdr, max_len, len);
- if(!prs_set_offset(ps, ptr_hdrbuf))
- return False;
- if(!smb_io_hdrbuf(desc, hdr, ps, depth))
- return False;
+ if (!ps->io)
+ {
+ /* storing: go back and do a retrospective job. i hate this */
+ uint32 old_offset = ps->offset;
- if(!prs_set_offset(ps, old_offset))
- return False;
+ make_buf_hdr(hdr, max_len, len);
+ ps->offset = ptr_hdrbuf;
+ smb_io_hdrbuf(desc, hdr, ps, depth);
+ ps->offset = old_offset;
}
return True;
}
/*******************************************************************
- Reads or writes a BUFHDR structure.
+reads or writes a BUFHDR structure.
********************************************************************/
-
-BOOL smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
+BOOL smb_io_hdrbuf(char *desc, BUFHDR *hdr, prs_struct *ps, int depth)
{
- if (hdr == NULL)
- return False;
+ if (hdr == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_hdrbuf");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("buf_max_len", ps, depth, &hdr->buf_max_len))
- return False;
- if(!prs_uint32("buf_len ", ps, depth, &hdr->buf_len))
- return False;
+ prs_uint32("buf_max_len", ps, depth, &(hdr->buf_max_len));
+ prs_uint32("buf_len ", ps, depth, &(hdr->buf_len ));
/* oops! XXXX maybe issue a warning that this is happening... */
- if (hdr->buf_max_len > MAX_BUFFERLEN)
- hdr->buf_max_len = MAX_BUFFERLEN;
- if (hdr->buf_len > MAX_BUFFERLEN)
- hdr->buf_len = MAX_BUFFERLEN;
+ if (hdr->buf_max_len > MAX_BUFFERLEN) hdr->buf_max_len = MAX_BUFFERLEN;
+ if (hdr->buf_len > MAX_BUFFERLEN) hdr->buf_len = MAX_BUFFERLEN;
return True;
}
/*******************************************************************
-creates a UNIHDR2 structure.
+creates a BUFHDR2 structure.
********************************************************************/
-
-void init_uni_hdr2(UNIHDR2 *hdr, int len)
+BOOL make_bufhdr2(BUFHDR2 *hdr, uint32 info_level, uint32 length, uint32 buffer)
{
- init_uni_hdr(&hdr->unihdr, len);
- hdr->buffer = (len > 0) ? 1 : 0;
+ hdr->info_level = info_level;
+ hdr->length = length;
+ hdr->buffer = buffer;
+
+ return True;
}
/*******************************************************************
- Reads or writes a UNIHDR2 structure.
+reads or writes a BUFHDR2 structure.
********************************************************************/
+BOOL smb_io_bufhdr2(char *desc, BUFHDR2 *hdr, prs_struct *ps, int depth)
+{
+ if (hdr == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_bufhdr2");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("info_level", ps, depth, &(hdr->info_level));
+ prs_uint32("length ", ps, depth, &(hdr->length ));
+ prs_uint32("buffer ", ps, depth, &(hdr->buffer ));
-BOOL smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth)
+ return True;
+}
+
+/*******************************************************************
+creates a UNIHDR2 structure.
+********************************************************************/
+BOOL make_uni_hdr2(UNIHDR2 *hdr, int len)
{
- if (hdr2 == NULL)
+ if (hdr == NULL)
+ {
return False;
+ }
+ make_uni_hdr(&(hdr->unihdr), len);
+ hdr->buffer = len > 0 ? 1 : 0;
+
+ return True;
+}
+
+/*******************************************************************
+creates a UNIHDR2 structure from a UNISTR2.
+********************************************************************/
+BOOL make_unihdr2_from_unistr2(UNIHDR2 *hdr, const UNISTR2 *str)
+{
+ int len;
+
+ len = (str ? str->uni_str_len : 0);
+
+ return make_uni_hdr2(hdr, len);
+}
+
+/*******************************************************************
+reads or writes a UNIHDR2 structure.
+********************************************************************/
+BOOL smb_io_unihdr2(char *desc, UNIHDR2 *hdr2, prs_struct *ps, int depth)
+{
+ if (hdr2 == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_unihdr2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unihdr("hdr", &hdr2->unihdr, ps, depth))
- return False;
- if(!prs_uint32("buffer", ps, depth, &hdr2->buffer))
- return False;
+ smb_io_unihdr("hdr", &(hdr2->unihdr), ps, depth);
+ prs_uint32("buffer", ps, depth, &(hdr2->buffer));
return True;
}
/*******************************************************************
- Inits a UNISTR structure.
+creates a UNISTR structure.
********************************************************************/
-
-void init_unistr(UNISTR *str, char *buf)
+BOOL make_unistr(UNISTR *str, char *buf)
{
- /* store the string (null-terminated copy) */
- dos_struni2((char *)str->buffer, buf, sizeof(str->buffer));
+ ascii_to_unistr(str->buffer, buf, sizeof(str->buffer)-1);
+
+ return True;
}
/*******************************************************************
reads or writes a UNISTR structure.
XXXX NOTE: UNISTR structures NEED to be null-terminated.
********************************************************************/
-
-BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
+BOOL smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
{
- if (uni == NULL)
- return False;
+ if (uni == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_unistr");
depth++;
- if(!prs_align(ps))
- return False;
- if(!prs_unistr("unistr", ps, depth, uni))
- return False;
+ prs_unistr("unistr", ps, depth, uni);
return True;
}
/*******************************************************************
- Inits a BUFFER3 structure from a uint32
+creates a BUFFER3 structure from a uint32
********************************************************************/
-
-void init_buffer3_uint32(BUFFER3 *str, uint32 val)
+BOOL make_buffer3_uint32(BUFFER3 *str, uint32 val)
{
ZERO_STRUCTP(str);
@@ -515,13 +514,14 @@ void init_buffer3_uint32(BUFFER3 *str, uint32 val)
str->buf_len = sizeof(uint32);
SIVAL(str->buffer, 0, val);
+
+ return True;
}
/*******************************************************************
- Inits a BUFFER3 structure.
+creates a BUFFER3 structure.
********************************************************************/
-
-void init_buffer3_str(BUFFER3 *str, char *buf, int len)
+BOOL make_buffer3_str(BUFFER3 *str, const char *buf, int len)
{
ZERO_STRUCTP(str);
@@ -529,65 +529,149 @@ void init_buffer3_str(BUFFER3 *str, char *buf, int len)
str->buf_max_len = len * 2;
str->buf_len = len * 2;
- /* store the string (null-terminated 8 bit chars into 16 bit chars) */
- dos_struni2((char *)str->buffer, buf, sizeof(str->buffer));
+ /* store the string (little endian buffer) */
+ ascii_to_unibuf((char*)str->buffer, buf, str->buf_len);
+
+ return True;
}
/*******************************************************************
- Inits a BUFFER3 structure from a hex string.
+creates a BUFFER3 structure from a hex string.
********************************************************************/
-
-void init_buffer3_hex(BUFFER3 *str, char *buf)
+BOOL make_buffer3_hex(BUFFER3 *str, char *buf)
{
ZERO_STRUCTP(str);
str->buf_max_len = str->buf_len = strhex_to_str((char *)str->buffer, sizeof(str->buffer), buf);
+
+ return True;
}
/*******************************************************************
- Inits a BUFFER3 structure.
+creates a BUFFER3 structure.
********************************************************************/
-
-void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len)
+BOOL make_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len)
{
ZERO_STRUCTP(str);
/* max buffer size (allocated size) */
str->buf_max_len = len;
if (buf != NULL)
+ {
memcpy(str->buffer, buf, MIN(str->buf_len, sizeof(str->buffer)));
+ }
str->buf_len = buf != NULL ? len : 0;
+
+ return True;
}
/*******************************************************************
- Reads or writes a BUFFER3 structure.
- the uni_max_len member tells you how large the buffer is.
- the uni_str_len member tells you how much of the buffer is really used.
+reads or writes a BUFFER3 structure.
+ the uni_max_len member tells you how large the buffer is.
+ the uni_str_len member tells you how much of the buffer is really used.
********************************************************************/
-
-BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth)
+BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth)
{
- if (buf3 == NULL)
- return False;
+ if (buf3 == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_buffer3");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("uni_max_len", ps, depth, &buf3->buf_max_len))
- return False;
+ prs_uint32("uni_max_len", ps, depth, &(buf3->buf_max_len));
+ if (buf3->buf_max_len > MAX_UNISTRLEN) buf3->buf_max_len = MAX_UNISTRLEN;
- if (buf3->buf_max_len > MAX_UNISTRLEN)
- buf3->buf_max_len = MAX_UNISTRLEN;
+ prs_uint8s(True, "buffer ", ps, depth, buf3->buffer, buf3->buf_max_len);
- if(!prs_uint8s(True, "buffer ", ps, depth, buf3->buffer, buf3->buf_max_len))
- return False;
+ prs_uint32("buf_len ", ps, depth, &(buf3->buf_len));
+ if (buf3->buf_len > MAX_UNISTRLEN) buf3->buf_len = MAX_UNISTRLEN;
- if(!prs_uint32("buf_len ", ps, depth, &buf3->buf_len))
- return False;
- if (buf3->buf_len > MAX_UNISTRLEN)
- buf3->buf_len = MAX_UNISTRLEN;
+ return True;
+}
+
+/*******************************************************************
+creates a BUFFER4 structure.
+********************************************************************/
+BOOL make_buffer4_str(BUFFER4 *str, const char *buf, int len)
+{
+ ZERO_STRUCTP(str);
+
+ /* set up string lengths. */
+ str->buf_len = len * 2;
+
+ /* store the string (little endian buffer) */
+ ascii_to_unibuf((char*)str->buffer, buf, str->buf_len);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a BUFFER4 structure.
+********************************************************************/
+BOOL smb_io_buffer4(char *desc, BUFFER4 *buf4, uint32 buffer, prs_struct *ps, int depth)
+{
+ if ((buf4 == NULL) || (buffer == 0)) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_buffer4");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("buf_len", ps, depth, &(buf4->buf_len));
+
+ if (buf4->buf_len > MAX_BUFFERLEN)
+ {
+ buf4->buf_len = MAX_BUFFERLEN;
+ }
+
+ prs_uint8s(True, "buffer", ps, depth, buf4->buffer, buf4->buf_len);
+
+ return True;
+}
+
+/*******************************************************************
+initialise a BUFFER5 structure.
+********************************************************************/
+BOOL init_buffer5(BUFFER5 **str)
+{
+ BUFFER5 *buf5;
+
+ buf5=(BUFFER5 *)malloc( sizeof(BUFFER5) );
+
+ buf5->buf_len=0;
+ buf5->buffer=NULL;
+ *str=buf5;
+
+ return True;
+}
+
+/*******************************************************************
+clear a BUFFER5 structure.
+********************************************************************/
+BOOL clear_buffer5(BUFFER5 **str)
+{
+ BUFFER5 *buf5;
+
+ buf5=*str;
+ if (buf5->buffer != NULL )
+ {
+ free(buf5->buffer);
+ }
+ free(buf5);
+ *str=NULL;
+
+ return True;
+}
+
+/*******************************************************************
+creates a BUFFER5 structure.
+********************************************************************/
+BOOL make_buffer5(BUFFER5 *str, char *buf, int len)
+{
+
+ /* max buffer size (allocated size) */
+ str->buf_len = len;
+ str->buffer = (uint16 *)malloc( sizeof(uint16) * len );
+ ascii_to_unistr(str->buffer, buf, len);
return True;
}
@@ -612,275 +696,272 @@ BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth)
buf5->buffer=(uint16 *)malloc( sizeof(uint16)*buf5->buf_len );
}
- prs_uint16s(True, "buffer", ps, depth, buf5->buffer, buf5->buf_len);
+ prs_uint16s(True, "buffer ", ps, depth, buf5->buffer, buf5->buf_len);
return True;
}
/*******************************************************************
- Inits a BUFFER2 structure.
+creates a BUFFER2 structure.
********************************************************************/
-
-void init_buffer2(BUFFER2 *str, uint8 *buf, int len)
+BOOL make_buffer2_multi(BUFFER2 *str, char *const* const buf, uint32 num)
{
+ int i;
+ char *dest = (char*)str->buffer;
+ size_t max_len = sizeof(str->buffer)-1;
+
ZERO_STRUCTP(str);
- /* max buffer size (allocated size) */
- str->buf_max_len = len;
+ str->buf_max_len = 0;
str->undoc = 0;
- str->buf_len = buf != NULL ? len : 0;
- if (buf != NULL)
- memcpy(str->buffer, buf, MIN(str->buf_len, sizeof(str->buffer)));
+ for (i = 0; i < num && max_len > 0; i++)
+ {
+ size_t len = buf[i] != NULL ? strlen(buf[i]) : 0;
+
+ str->buf_max_len += len * 2;
+ str->buf_len += len * 2;
+
+ ascii_to_unibuf(dest, buf[i], max_len);
+
+ dest += len * 2 + 2;
+ max_len -= len * 2 + 2;
+ }
+
+ return True;
}
/*******************************************************************
- Reads or writes a BUFFER2 structure.
- the uni_max_len member tells you how large the buffer is.
- the uni_str_len member tells you how much of the buffer is really used.
+creates a BUFFER2 structure.
********************************************************************/
-
-BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth)
+BOOL make_buffer2(BUFFER2 *str, const char *buf, int len)
{
- if (buf2 == NULL)
- return False;
+ ZERO_STRUCTP(str);
+
+ /* set up string lengths. */
+ str->buf_max_len = str->buf_len = len * 2;
+ str->undoc = 0;
+
+ /* store the string */
+ ascii_to_unibuf((char*)str->buffer, buf,
+ MIN(str->buf_len, sizeof(str->buffer)-1));
+
+ return True;
+}
- if (buffer) {
+/*******************************************************************
+reads or writes a BUFFER2 structure.
+ the uni_max_len member tells you how large the buffer is.
+ the uni_str_len member tells you how much of the buffer is really used.
+********************************************************************/
+BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth)
+{
+ if (buf2 == NULL) return False;
+ if (buffer)
+ {
prs_debug(ps, depth, desc, "smb_io_buffer2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("uni_max_len", ps, depth, &buf2->buf_max_len))
- return False;
- if(!prs_uint32("undoc ", ps, depth, &buf2->undoc))
- return False;
- if(!prs_uint32("buf_len ", ps, depth, &buf2->buf_len))
- return False;
+ prs_uint32("buf_max_len", ps, depth, &(buf2->buf_max_len));
+ prs_uint32("undoc ", ps, depth, &(buf2->undoc ));
+ prs_uint32("buf_len ", ps, depth, &(buf2->buf_len));
/* oops! XXXX maybe issue a warning that this is happening... */
- if (buf2->buf_max_len > MAX_UNISTRLEN)
- buf2->buf_max_len = MAX_UNISTRLEN;
- if (buf2->buf_len > MAX_UNISTRLEN)
- buf2->buf_len = MAX_UNISTRLEN;
+ if (buf2->buf_max_len > MAX_UNISTRLEN) buf2->buf_max_len = MAX_UNISTRLEN;
+ if (buf2->buf_len > MAX_UNISTRLEN) buf2->buf_len = MAX_UNISTRLEN;
/* buffer advanced by indicated length of string
NOT by searching for null-termination */
-
- if(!prs_buffer2(True, "buffer ", ps, depth, buf2))
- return False;
-
- } else {
-
+ prs_buffer2(True, "buffer ", ps, depth, buf2);
+ }
+ else
+ {
prs_debug(ps, depth, desc, "smb_io_buffer2 - NULL");
depth++;
- memset((char *)buf2, '\0', sizeof(*buf2));
-
+ bzero(buf2, sizeof(*buf2));
}
+
return True;
}
/*******************************************************************
creates a UNISTR2 structure: sets up the buffer, too
********************************************************************/
-
-void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf)
+BOOL make_buf_unistr2(UNISTR2 *str, uint32 *ptr, const char *buf)
{
- if (buf != NULL) {
-
+ if (buf != NULL)
+ {
*ptr = 1;
- init_unistr2(str, buf, strlen(buf)+1);
-
- } else {
-
+ make_unistr2(str, buf, strlen(buf)+1);
+ }
+ else
+ {
*ptr = 0;
- init_unistr2(str, "", 0);
-
+ make_unistr2(str, "", 0);
}
+
+ return True;
}
/*******************************************************************
- Copies a UNISTR2 structure.
+creates a STRING2 structure.
********************************************************************/
-
-void copy_unistr2(UNISTR2 *str, UNISTR2 *from)
+BOOL make_string2(STRING2 *str, const char *buf, int len)
{
- /* set up string lengths. add one if string is not null-terminated */
- str->uni_max_len = from->uni_max_len;
- str->undoc = from->undoc;
- str->uni_str_len = from->uni_str_len;
+ ZERO_STRUCTP(str);
- /* copy the string */
- memcpy(str->buffer, from->buffer, sizeof(from->buffer));
+ /* set up string lengths. */
+ str->str_max_len = len;
+ str->undoc = 0;
+ str->str_str_len = len;
+
+ /* store the string */
+ if(len != 0)
+ {
+ memcpy(str->buffer, buf, len);
+ }
+
+ return True;
}
/*******************************************************************
- Creates a STRING2 structure.
+creates a STRING2 structure: sets up the buffer, too
********************************************************************/
-
-void init_string2(STRING2 *str, char *buf, int len)
+BOOL make_buf_string2(STRING2 *str, uint32 *ptr, const char *buf)
{
- /* set up string lengths. */
- str->str_max_len = len;
- str->undoc = 0;
- str->str_str_len = len;
+ if (buf != NULL)
+ {
+ *ptr = 1;
+ make_string2(str, buf, strlen(buf)+1);
+ }
+ else
+ {
+ *ptr = 0;
+ make_string2(str, "", 0);
+ }
- /* store the string */
- if(len != 0)
- memcpy(str->buffer, buf, len);
+ return True;
}
/*******************************************************************
- Reads or writes a STRING2 structure.
- XXXX NOTE: STRING2 structures need NOT be null-terminated.
- the str_str_len member tells you how long the string is;
- the str_max_len member tells you how large the buffer is.
+reads or writes a STRING2 structure.
+XXXX NOTE: STRING2 structures need NOT be null-terminated.
+ the str_str_len member tells you how long the string is;
+ the str_max_len member tells you how large the buffer is.
********************************************************************/
-
-BOOL smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
+BOOL smb_io_string2(char *desc, STRING2 *str2, uint32 buffer, prs_struct *ps, int depth)
{
- if (str2 == NULL)
- return False;
-
- if (buffer) {
+ if (str2 == NULL) return False;
+ if (buffer)
+ {
prs_debug(ps, depth, desc, "smb_io_string2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("str_max_len", ps, depth, &str2->str_max_len))
- return False;
- if(!prs_uint32("undoc ", ps, depth, &str2->undoc))
- return False;
- if(!prs_uint32("str_str_len", ps, depth, &str2->str_str_len))
- return False;
+ prs_uint32("str_max_len", ps, depth, &(str2->str_max_len));
+ prs_uint32("undoc ", ps, depth, &(str2->undoc ));
+ prs_uint32("str_str_len", ps, depth, &(str2->str_str_len));
/* oops! XXXX maybe issue a warning that this is happening... */
- if (str2->str_max_len > MAX_STRINGLEN)
- str2->str_max_len = MAX_STRINGLEN;
- if (str2->str_str_len > MAX_STRINGLEN)
- str2->str_str_len = MAX_STRINGLEN;
+ if (str2->str_max_len > MAX_STRINGLEN) str2->str_max_len = MAX_STRINGLEN;
+ if (str2->str_str_len > MAX_STRINGLEN) str2->str_str_len = MAX_STRINGLEN;
/* buffer advanced by indicated length of string
NOT by searching for null-termination */
- if(!prs_string2(True, "buffer ", ps, depth, str2))
- return False;
-
- } else {
-
+ prs_string2(True, "buffer ", ps, depth, str2);
+ }
+ else
+ {
prs_debug(ps, depth, desc, "smb_io_string2 - NULL");
depth++;
- memset((char *)str2, '\0', sizeof(*str2));
-
+ bzero(str2, sizeof(*str2));
}
return True;
}
/*******************************************************************
- Inits a UNISTR2 structure.
+creates a UNISTR2 structure.
********************************************************************/
-
-void init_unistr2(UNISTR2 *str, char *buf, int len)
+BOOL make_unistr2(UNISTR2 *str, const char *buf, int len)
{
- ZERO_STRUCTP(str);
+ unistr2_assign_ascii(str, buf, len);
- /* set up string lengths. */
- str->uni_max_len = len;
- str->undoc = 0;
- str->uni_str_len = len;
-
- /* store the string (null-terminated 8 bit chars into 16 bit chars) */
- dos_struni2((char *)str->buffer, buf, sizeof(str->buffer));
+ return True;
}
/*******************************************************************
- Reads or writes a UNISTR2 structure.
- XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
- the uni_str_len member tells you how long the string is;
- the uni_max_len member tells you how large the buffer is.
+reads or writes a UNISTR2 structure.
+XXXX NOTE: UNISTR2 structures need NOT be null-terminated.
+ the uni_str_len member tells you how long the string is;
+ the uni_max_len member tells you how large the buffer is.
********************************************************************/
-
-BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
+BOOL smb_io_unistr2(char *desc, UNISTR2 *uni2, uint32 buffer, prs_struct *ps, int depth)
{
- if (uni2 == NULL)
- return False;
-
- if (buffer) {
+ if (uni2 == NULL) return False;
+ if (buffer)
+ {
prs_debug(ps, depth, desc, "smb_io_unistr2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("uni_max_len", ps, depth, &uni2->uni_max_len))
- return False;
- if(!prs_uint32("undoc ", ps, depth, &uni2->undoc))
- return False;
- if(!prs_uint32("uni_str_len", ps, depth, &uni2->uni_str_len))
- return False;
+ prs_uint32("uni_max_len", ps, depth, &(uni2->uni_max_len));
+ prs_uint32("undoc ", ps, depth, &(uni2->undoc ));
+ prs_uint32("uni_str_len", ps, depth, &(uni2->uni_str_len));
/* oops! XXXX maybe issue a warning that this is happening... */
- if (uni2->uni_max_len > MAX_UNISTRLEN)
- uni2->uni_max_len = MAX_UNISTRLEN;
- if (uni2->uni_str_len > MAX_UNISTRLEN)
- uni2->uni_str_len = MAX_UNISTRLEN;
+ if (uni2->uni_max_len > MAX_UNISTRLEN) uni2->uni_max_len = MAX_UNISTRLEN;
+ if (uni2->uni_str_len > MAX_UNISTRLEN) uni2->uni_str_len = MAX_UNISTRLEN;
/* buffer advanced by indicated length of string
NOT by searching for null-termination */
- if(!prs_unistr2(True, "buffer ", ps, depth, uni2))
- return False;
-
- } else {
-
+ prs_unistr2(True, "buffer ", ps, depth, uni2);
+ }
+ else
+ {
prs_debug(ps, depth, desc, "smb_io_unistr2 - NULL");
depth++;
- memset((char *)uni2, '\0', sizeof(*uni2));
-
+ bzero(uni2, sizeof(*uni2));
}
return True;
}
/*******************************************************************
- Inits a DOM_RID2 structure.
+creates a DOM_RID2 structure.
********************************************************************/
-
-void init_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
+BOOL make_dom_rid2(DOM_RID2 *rid2, uint32 rid, uint8 type, uint32 idx)
{
rid2->type = type;
rid2->rid = rid;
rid2->rid_idx = idx;
+
+ return True;
}
/*******************************************************************
- Reads or writes a DOM_RID2 structure.
+reads or writes a DOM_RID2 structure.
********************************************************************/
-
-BOOL smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
+BOOL smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
{
- if (rid2 == NULL)
- return False;
+ if (rid2 == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_dom_rid2");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint8("type ", ps, depth, &rid2->type))
- return False;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("rid ", ps, depth, &rid2->rid))
- return False;
- if(!prs_uint32("rid_idx", ps, depth, &rid2->rid_idx))
- return False;
+ prs_align(ps);
+
+ prs_uint8("type ", ps, depth, &(rid2->type));
+ prs_align(ps);
+ prs_uint32("rid ", ps, depth, &(rid2->rid ));
+ prs_uint32("rid_idx", ps, depth, &(rid2->rid_idx ));
return True;
}
@@ -888,495 +969,414 @@ BOOL smb_io_dom_rid2(char *desc, DOM_RID2 *rid2, prs_struct *ps, int depth)
/*******************************************************************
creates a DOM_RID3 structure.
********************************************************************/
-
-void init_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
+BOOL make_dom_rid3(DOM_RID3 *rid3, uint32 rid, uint8 type)
{
- rid3->rid = rid;
- rid3->type1 = type;
- rid3->ptr_type = 0x1; /* non-zero, basically. */
- rid3->type2 = 0x1;
- rid3->unk = type;
+ rid3->rid = rid;
+ rid3->type1 = type;
+ rid3->ptr_type = 0x1; /* non-zero, basically. */
+ rid3->type2 = 0x1;
+ rid3->unk = type;
+
+ return True;
}
/*******************************************************************
reads or writes a DOM_RID3 structure.
********************************************************************/
-
-BOOL smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
+BOOL smb_io_dom_rid3(char *desc, DOM_RID3 *rid3, prs_struct *ps, int depth)
{
- if (rid3 == NULL)
- return False;
+ if (rid3 == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_dom_rid3");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("rid ", ps, depth, &rid3->rid))
- return False;
- if(!prs_uint32("type1 ", ps, depth, &rid3->type1))
- return False;
- if(!prs_uint32("ptr_type", ps, depth, &rid3->ptr_type))
- return False;
- if(!prs_uint32("type2 ", ps, depth, &rid3->type2))
- return False;
- if(!prs_uint32("unk ", ps, depth, &rid3->unk))
- return False;
+ prs_align(ps);
+
+ prs_uint32("rid ", ps, depth, &(rid3->rid ));
+ prs_uint32("type1 ", ps, depth, &(rid3->type1 ));
+ prs_uint32("ptr_type", ps, depth, &(rid3->ptr_type));
+ prs_uint32("type2 ", ps, depth, &(rid3->type2 ));
+ prs_uint32("unk ", ps, depth, &(rid3->unk ));
return True;
}
/*******************************************************************
- Inits a DOM_RID4 structure.
+makes a DOM_CLNT_SRV structure.
********************************************************************/
-
-void init_dom_rid4(DOM_RID4 *rid4, uint16 unknown, uint16 attr, uint32 rid)
+static BOOL make_clnt_srv(DOM_CLNT_SRV *log,
+ const char *logon_srv,
+ const char *comp_name)
{
- rid4->unknown = unknown;
- rid4->attr = attr;
- rid4->rid = rid;
-}
+ if (log == NULL) return False;
-/*******************************************************************
- Inits a DOM_CLNT_SRV structure.
-********************************************************************/
-
-static void init_clnt_srv(DOM_CLNT_SRV *log, char *logon_srv, char *comp_name)
-{
- DEBUG(5,("init_clnt_srv: %d\n", __LINE__));
+ DEBUG(5,("make_clnt_srv: %d\n", __LINE__));
- if (logon_srv != NULL) {
+ if (logon_srv != NULL)
+ {
log->undoc_buffer = 1;
- init_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)+1);
- } else {
+ make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)+1);
+ }
+ else
+ {
log->undoc_buffer = 0;
}
- if (comp_name != NULL) {
+ if (comp_name != NULL)
+ {
log->undoc_buffer2 = 1;
- init_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
- } else {
+ make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
+ }
+ else
+ {
log->undoc_buffer2 = 0;
}
+
+ return True;
}
/*******************************************************************
- Inits or writes a DOM_CLNT_SRV structure.
+reads or writes a DOM_CLNT_SRV structure.
********************************************************************/
-
-static BOOL smb_io_clnt_srv(char *desc, DOM_CLNT_SRV *log, prs_struct *ps, int depth)
+static BOOL smb_io_clnt_srv(char *desc, DOM_CLNT_SRV *log, prs_struct *ps, int depth)
{
- if (log == NULL)
- return False;
+ if (log == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_clnt_srv");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("undoc_buffer ", ps, depth, &log->undoc_buffer))
- return False;
-
- if (log->undoc_buffer != 0) {
- if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, log->undoc_buffer, ps, depth))
- return False;
+ prs_uint32("undoc_buffer ", ps, depth, &(log->undoc_buffer ));
+ if (log->undoc_buffer != 0)
+ {
+ smb_io_unistr2("unistr2", &(log->uni_logon_srv), log->undoc_buffer, ps, depth);
}
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("undoc_buffer2", ps, depth, &log->undoc_buffer2))
- return False;
+ prs_align(ps);
- if (log->undoc_buffer2 != 0) {
- if(!smb_io_unistr2("unistr2", &log->uni_comp_name, log->undoc_buffer2, ps, depth))
- return False;
+ prs_uint32("undoc_buffer2", ps, depth, &(log->undoc_buffer2));
+ if (log->undoc_buffer2 != 0)
+ {
+ smb_io_unistr2("unistr2", &(log->uni_comp_name), log->undoc_buffer2, ps, depth);
}
return True;
}
/*******************************************************************
- Inits a DOM_LOG_INFO structure.
+makes a DOM_LOG_INFO structure.
********************************************************************/
-
-void init_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name,
- uint16 sec_chan, char *comp_name)
+BOOL make_log_info(DOM_LOG_INFO *log,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name)
{
+ if (log == NULL) return False;
+
DEBUG(5,("make_log_info %d\n", __LINE__));
log->undoc_buffer = 1;
- init_unistr2(&log->uni_logon_srv, logon_srv, strlen(logon_srv)+1);
- init_unistr2(&log->uni_acct_name, acct_name, strlen(acct_name)+1);
+ make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)+1);
+ make_unistr2(&(log->uni_acct_name), acct_name, strlen(acct_name)+1);
log->sec_chan = sec_chan;
- init_unistr2(&log->uni_comp_name, comp_name, strlen(comp_name)+1);
+ make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)+1);
+
+ return True;
}
/*******************************************************************
- Reads or writes a DOM_LOG_INFO structure.
+reads or writes a DOM_LOG_INFO structure.
********************************************************************/
-
-BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth)
+BOOL smb_io_log_info(char *desc, DOM_LOG_INFO *log, prs_struct *ps, int depth)
{
- if (log == NULL)
- return False;
+ if (log == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_log_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("undoc_buffer", ps, depth, &log->undoc_buffer))
- return False;
+ prs_uint32("undoc_buffer", ps, depth, &(log->undoc_buffer));
- if(!smb_io_unistr2("unistr2", &log->uni_logon_srv, True, ps, depth))
- return False;
- if(!smb_io_unistr2("unistr2", &log->uni_acct_name, True, ps, depth))
- return False;
+ smb_io_unistr2("unistr2", &(log->uni_logon_srv), True, ps, depth);
+ smb_io_unistr2("unistr2", &(log->uni_acct_name), True, ps, depth);
- if(!prs_uint16("sec_chan", ps, depth, &log->sec_chan))
- return False;
+ prs_uint16("sec_chan", ps, depth, &(log->sec_chan));
- if(!smb_io_unistr2("unistr2", &log->uni_comp_name, True, ps, depth))
- return False;
+ smb_io_unistr2("unistr2", &(log->uni_comp_name), True, ps, depth);
return True;
}
/*******************************************************************
- Reads or writes a DOM_CHAL structure.
+reads or writes a DOM_CHAL structure.
********************************************************************/
-
-BOOL smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
+BOOL smb_io_chal(char *desc, DOM_CHAL *chal, prs_struct *ps, int depth)
{
- if (chal == NULL)
- return False;
+ if (chal == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_chal");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint8s (False, "data", ps, depth, chal->data, 8))
- return False;
+ prs_uint8s (False, "data", ps, depth, chal->data, 8);
return True;
}
/*******************************************************************
- Reads or writes a DOM_CRED structure.
+reads or writes a DOM_CRED structure.
********************************************************************/
-
BOOL smb_io_cred(char *desc, DOM_CRED *cred, prs_struct *ps, int depth)
{
- if (cred == NULL)
- return False;
+ if (cred == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_cred");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_chal ("", &cred->challenge, ps, depth))
- return False;
- if(!smb_io_utime("", &cred->timestamp, ps, depth))
- return False;
+ prs_align(ps);
+
+ smb_io_chal ("", &(cred->challenge), ps, depth);
+ smb_io_utime("", &(cred->timestamp), ps, depth);
return True;
}
/*******************************************************************
- Inits a DOM_CLNT_INFO2 structure.
+makes a DOM_CLNT_INFO2 structure.
********************************************************************/
-
-void init_clnt_info2(DOM_CLNT_INFO2 *clnt,
- char *logon_srv, char *comp_name,
+BOOL make_clnt_info2(DOM_CLNT_INFO2 *clnt,
+ const char *logon_srv, const char *comp_name,
DOM_CRED *clnt_cred)
{
+ if (clnt == NULL) return False;
+
DEBUG(5,("make_clnt_info: %d\n", __LINE__));
- init_clnt_srv(&(clnt->login), logon_srv, comp_name);
+ make_clnt_srv(&(clnt->login), logon_srv, comp_name);
- if (clnt_cred != NULL) {
+ if (clnt_cred != NULL)
+ {
clnt->ptr_cred = 1;
memcpy(&(clnt->cred), clnt_cred, sizeof(clnt->cred));
- } else {
+ }
+ else
+ {
clnt->ptr_cred = 0;
}
+
+ return True;
}
/*******************************************************************
- Reads or writes a DOM_CLNT_INFO2 structure.
+reads or writes a DOM_CLNT_INFO2 structure.
********************************************************************/
-
-BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
+BOOL smb_io_clnt_info2(char *desc, DOM_CLNT_INFO2 *clnt, prs_struct *ps, int depth)
{
- if (clnt == NULL)
- return False;
+ if (clnt == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_clnt_info2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_clnt_srv("", &clnt->login, ps, depth))
- return False;
+ smb_io_clnt_srv("", &(clnt->login), ps, depth);
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_cred", ps, depth, &clnt->ptr_cred))
- return False;
- if(!smb_io_cred("", &clnt->cred, ps, depth))
- return False;
+ prs_uint32("ptr_cred", ps, depth, &(clnt->ptr_cred));
+ smb_io_cred ("", &(clnt->cred ), ps, depth);
return True;
}
/*******************************************************************
- Inits a DOM_CLNT_INFO structure.
+makes a DOM_CLNT_INFO structure.
********************************************************************/
-
-void init_clnt_info(DOM_CLNT_INFO *clnt,
- char *logon_srv, char *acct_name,
- uint16 sec_chan, char *comp_name,
+BOOL make_clnt_info(DOM_CLNT_INFO *clnt,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
DOM_CRED *cred)
{
+ if (clnt == NULL || cred == NULL) return False;
+
DEBUG(5,("make_clnt_info\n"));
- init_log_info(&clnt->login, logon_srv, acct_name, sec_chan, comp_name);
- memcpy(&clnt->cred, cred, sizeof(clnt->cred));
+ make_log_info(&(clnt->login), logon_srv, acct_name, sec_chan, comp_name);
+ memcpy(&(clnt->cred), cred, sizeof(clnt->cred));
+
+ return True;
}
/*******************************************************************
- Reads or writes a DOM_CLNT_INFO structure.
+reads or writes a DOM_CLNT_INFO structure.
********************************************************************/
-
BOOL smb_io_clnt_info(char *desc, DOM_CLNT_INFO *clnt, prs_struct *ps, int depth)
{
- if (clnt == NULL)
- return False;
+ if (clnt == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_clnt_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_log_info("", &clnt->login, ps, depth))
- return False;
- if(!smb_io_cred("", &clnt->cred, ps, depth))
- return False;
+ smb_io_log_info("", &(clnt->login), ps, depth);
+ smb_io_cred ("", &(clnt->cred ), ps, depth);
return True;
}
/*******************************************************************
- Inits a DOM_LOGON_ID structure.
+makes an OWF_INFO structure.
********************************************************************/
-
-void init_logon_id(DOM_LOGON_ID *log, uint32 log_id_low, uint32 log_id_high)
-{
- DEBUG(5,("make_logon_id: %d\n", __LINE__));
-
- log->low = log_id_low;
- log->high = log_id_high;
-}
-
-/*******************************************************************
- Reads or writes a DOM_LOGON_ID structure.
-********************************************************************/
-
-BOOL smb_io_logon_id(char *desc, DOM_LOGON_ID *log, prs_struct *ps, int depth)
+BOOL make_owf_info(OWF_INFO *hash, const uint8 data[16])
{
- if (log == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_logon_id");
- depth++;
+ if (hash == NULL) return False;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("low ", ps, depth, &log->low ))
- return False;
- if(!prs_uint32("high", ps, depth, &log->high))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits an OWF_INFO structure.
-********************************************************************/
-
-void init_owf_info(OWF_INFO *hash, uint8 data[16])
-{
- DEBUG(5,("init_owf_info: %d\n", __LINE__));
+ DEBUG(5,("make_owf_info: %d\n", __LINE__));
if (data != NULL)
+ {
memcpy(hash->data, data, sizeof(hash->data));
+ }
else
- memset((char *)hash->data, '\0', sizeof(hash->data));
+ {
+ bzero(hash->data, sizeof(hash->data));
+ }
+
+ return True;
}
/*******************************************************************
- Reads or writes an OWF_INFO structure.
+reads or writes an OWF_INFO structure.
********************************************************************/
-
BOOL smb_io_owf_info(char *desc, OWF_INFO *hash, prs_struct *ps, int depth)
{
- if (hash == NULL)
- return False;
+ if (hash == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_owf_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint8s (False, "data", ps, depth, hash->data, 16))
- return False;
+ prs_uint8s (False, "data", ps, depth, hash->data, 16);
return True;
}
/*******************************************************************
- Reads or writes a DOM_GID structure.
+reads or writes a DOM_GID structure.
********************************************************************/
-
BOOL smb_io_gid(char *desc, DOM_GID *gid, prs_struct *ps, int depth)
{
- if (gid == NULL)
- return False;
+ if (gid == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_gid");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("g_rid", ps, depth, &gid->g_rid))
- return False;
- if(!prs_uint32("attr ", ps, depth, &gid->attr))
- return False;
+ prs_uint32("g_rid", ps, depth, &(gid->g_rid));
+ prs_uint32("attr ", ps, depth, &(gid->attr ));
return True;
}
/*******************************************************************
- Reads or writes an POLICY_HND structure.
+reads or writes an POLICY_HND structure.
********************************************************************/
-
-BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
+BOOL smb_io_pol_hnd(char *desc, POLICY_HND *pol, prs_struct *ps, int depth)
{
- if (pol == NULL)
- return False;
+ if (pol == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_pol_hnd");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint8s (False, "data", ps, depth, pol->data, POL_HND_SIZE))
- return False;
+ prs_uint8s (False, "data", ps, depth, pol->data, POL_HND_SIZE);
return True;
}
/*******************************************************************
- Reads or writes a dom query structure.
+reads or writes a dom query structure.
********************************************************************/
-
-static BOOL smb_io_dom_query(char *desc, DOM_QUERY *d_q, prs_struct *ps, int depth)
+static BOOL smb_io_dom_query(char *desc, DOM_QUERY *d_q, prs_struct *ps, int depth)
{
- if (d_q == NULL)
- return False;
+ if (d_q == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_dom_query");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint16("uni_dom_max_len", ps, depth, &d_q->uni_dom_max_len)) /* domain name string length * 2 */
- return False;
- if(!prs_uint16("uni_dom_str_len", ps, depth, &d_q->uni_dom_str_len)) /* domain name string length * 2 */
- return False;
+ prs_uint16("uni_dom_max_len", ps, depth, &(d_q->uni_dom_max_len)); /* domain name string length * 2 */
+ prs_uint16("uni_dom_str_len", ps, depth, &(d_q->uni_dom_str_len)); /* domain name string length * 2 */
- if(!prs_uint32("buffer_dom_name", ps, depth, &d_q->buffer_dom_name)) /* undocumented domain name string buffer pointer */
- return False;
- if(!prs_uint32("buffer_dom_sid ", ps, depth, &d_q->buffer_dom_sid)) /* undocumented domain SID string buffer pointer */
- return False;
+ prs_uint32("buffer_dom_name", ps, depth, &(d_q->buffer_dom_name)); /* undocumented domain name string buffer pointer */
+ prs_uint32("buffer_dom_sid ", ps, depth, &(d_q->buffer_dom_sid )); /* undocumented domain SID string buffer pointer */
- if(!smb_io_unistr2("unistr2", &d_q->uni_domain_name, d_q->buffer_dom_name, ps, depth)) /* domain name (unicode string) */
- return False;
+ smb_io_unistr2("unistr2", &(d_q->uni_domain_name), d_q->buffer_dom_name, ps, depth); /* domain name (unicode string) */
- if(!prs_align(ps))
- return False;
-
- if (d_q->buffer_dom_sid != 0) {
- if(!smb_io_dom_sid2("", &d_q->dom_sid, ps, depth)) /* domain SID */
- return False;
- } else {
- memset((char *)&d_q->dom_sid, '\0', sizeof(d_q->dom_sid));
+ prs_align(ps);
+
+ if (d_q->buffer_dom_sid != 0)
+ {
+ smb_io_dom_sid2("", &(d_q->dom_sid), ps, depth); /* domain SID */
+ }
+ else
+ {
+ bzero(&(d_q->dom_sid), sizeof(d_q->dom_sid));
}
return True;
}
/*******************************************************************
- Reads or writes a dom query structure.
+reads or writes a dom query structure.
********************************************************************/
-
-BOOL smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
+BOOL smb_io_dom_query_3(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
{
- return smb_io_dom_query("", d_q, ps, depth);
+ smb_io_dom_query("", d_q, ps, depth);
+
+ return True;
}
/*******************************************************************
- Reads or writes a dom query structure.
+reads or writes a dom query structure.
********************************************************************/
-
-BOOL smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
+BOOL smb_io_dom_query_5(char *desc, DOM_QUERY_3 *d_q, prs_struct *ps, int depth)
{
- return smb_io_dom_query("", d_q, ps, depth);
+ smb_io_dom_query("", d_q, ps, depth);
+
+ return True;
}
/*******************************************************************
- Reads or writes a UNISTR3 structure.
+reads or writes a UNISTR3 structure.
********************************************************************/
-
-BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth)
+BOOL smb_io_unistr3(char *desc, UNISTR3 *name, prs_struct *ps, int depth)
{
- if (name == NULL)
- return False;
+ if (name == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_unistr3");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("uni_str_len", ps, depth, &name->uni_str_len))
- return False;
+ prs_uint32("uni_str_len", ps, depth, &(name->uni_str_len));
/* don't know if len is specified by uni_str_len member... */
/* assume unicode string is unicode-null-terminated, instead */
- if(!prs_unistr3(True, "unistr", name, ps, depth))
- return False;
+ prs_unistr3(True, "unistr", name, ps, depth);
return True;
}
+
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index 9588d1c53b3..fec96372bc7 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -4,7 +4,8 @@
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Paul Ashton 1997,
+ * Copyright (C) Sander Striker 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,733 +23,659 @@
*/
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL net_io_neg_flags(char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth)
+static BOOL net_io_neg_flags(char *desc, NEG_FLAGS *neg, prs_struct *ps, int depth)
{
- if (neg == NULL)
- return False;
+ if (neg == NULL) return False;
prs_debug(ps, depth, desc, "net_io_neg_flags");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("neg_flags", ps, depth, &neg->neg_flags))
- return False;
+ prs_uint32("neg_flags", ps, depth, &(neg->neg_flags));
return True;
}
/*******************************************************************
- Inits a NETLOGON_INFO_3 structure.
-********************************************************************/
-
-static void init_netinfo_3(NETLOGON_INFO_3 *info, uint32 flags, uint32 logon_attempts)
-{
- info->flags = flags;
- info->logon_attempts = logon_attempts;
- info->reserved_1 = 0x0;
- info->reserved_2 = 0x0;
- info->reserved_3 = 0x0;
- info->reserved_4 = 0x0;
- info->reserved_5 = 0x0;
-}
-
-/*******************************************************************
- Reads or writes a NETLOGON_INFO_3 structure.
+reads or writes a NETLOGON_INFO_3 structure.
********************************************************************/
-
static BOOL net_io_netinfo_3(char *desc, NETLOGON_INFO_3 *info, prs_struct *ps, int depth)
{
- if (info == NULL)
- return False;
+ if (info == NULL) return False;
prs_debug(ps, depth, desc, "net_io_netinfo_3");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("flags ", ps, depth, &info->flags))
- return False;
- if(!prs_uint32("logon_attempts", ps, depth, &info->logon_attempts))
- return False;
- if(!prs_uint32("reserved_1 ", ps, depth, &info->reserved_1))
- return False;
- if(!prs_uint32("reserved_2 ", ps, depth, &info->reserved_2))
- return False;
- if(!prs_uint32("reserved_3 ", ps, depth, &info->reserved_3))
- return False;
- if(!prs_uint32("reserved_4 ", ps, depth, &info->reserved_4))
- return False;
- if(!prs_uint32("reserved_5 ", ps, depth, &info->reserved_5))
- return False;
+ prs_align(ps);
+
+ prs_uint32("flags ", ps, depth, &(info->flags ));
+ prs_uint32("logon_attempts", ps, depth, &(info->logon_attempts));
+ prs_uint32("reserved_1 ", ps, depth, &(info->reserved_1 ));
+ prs_uint32("reserved_2 ", ps, depth, &(info->reserved_2 ));
+ prs_uint32("reserved_3 ", ps, depth, &(info->reserved_3 ));
+ prs_uint32("reserved_4 ", ps, depth, &(info->reserved_4 ));
+ prs_uint32("reserved_5 ", ps, depth, &(info->reserved_5 ));
return True;
}
/*******************************************************************
- Inits a NETLOGON_INFO_1 structure.
+reads or writes a NETLOGON_INFO_1 structure.
********************************************************************/
-
-static void init_netinfo_1(NETLOGON_INFO_1 *info, uint32 flags, uint32 pdc_status)
+static BOOL net_io_netinfo_1(char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
{
- info->flags = flags;
- info->pdc_status = pdc_status;
-}
-
-/*******************************************************************
- Reads or writes a NETLOGON_INFO_1 structure.
-********************************************************************/
-
-static BOOL net_io_netinfo_1(char *desc, NETLOGON_INFO_1 *info, prs_struct *ps, int depth)
-{
- if (info == NULL)
- return False;
+ if (info == NULL) return False;
prs_debug(ps, depth, desc, "net_io_netinfo_1");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("flags ", ps, depth, &info->flags))
- return False;
- if(!prs_uint32("pdc_status", ps, depth, &info->pdc_status))
- return False;
+ prs_uint32("flags ", ps, depth, &(info->flags ));
+ prs_uint32("pdc_status", ps, depth, &(info->pdc_status));
return True;
}
/*******************************************************************
- Inits a NETLOGON_INFO_2 structure.
+reads or writes a NETLOGON_INFO_2 structure.
********************************************************************/
-
-static void init_netinfo_2(NETLOGON_INFO_2 *info, uint32 flags, uint32 pdc_status,
- uint32 tc_status, char *trusted_dc_name)
+static BOOL net_io_netinfo_2(char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
{
- int len_dc_name = strlen(trusted_dc_name);
- info->flags = flags;
- info->pdc_status = pdc_status;
- info->ptr_trusted_dc_name = 1;
- info->tc_status = tc_status;
-
- if (trusted_dc_name != NULL)
- init_unistr2(&(info->uni_trusted_dc_name), trusted_dc_name, len_dc_name+1);
- else
- init_unistr2(&(info->uni_trusted_dc_name), "", 1);
-}
-
-/*******************************************************************
- Reads or writes a NETLOGON_INFO_2 structure.
-********************************************************************/
-
-static BOOL net_io_netinfo_2(char *desc, NETLOGON_INFO_2 *info, prs_struct *ps, int depth)
-{
- if (info == NULL)
- return False;
+ if (info == NULL) return False;
prs_debug(ps, depth, desc, "net_io_netinfo_2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("flags ", ps, depth, &info->flags))
- return False;
- if(!prs_uint32("pdc_status ", ps, depth, &info->pdc_status))
- return False;
- if(!prs_uint32("ptr_trusted_dc_name", ps, depth, &info->ptr_trusted_dc_name))
- return False;
- if(!prs_uint32("tc_status ", ps, depth, &info->tc_status))
- return False;
-
- if (info->ptr_trusted_dc_name != 0) {
- if(!smb_io_unistr2("unistr2", &info->uni_trusted_dc_name, info->ptr_trusted_dc_name, ps, depth))
- return False;
+ prs_uint32("flags ", ps, depth, &(info->flags ));
+ prs_uint32("pdc_status ", ps, depth, &(info->pdc_status ));
+ prs_uint32("ptr_trusted_dc_name", ps, depth, &(info->ptr_trusted_dc_name));
+ prs_uint32("tc_status ", ps, depth, &(info->tc_status ));
+
+ if (info->ptr_trusted_dc_name != 0)
+ {
+ smb_io_unistr2("unistr2", &(info->uni_trusted_dc_name), info->ptr_trusted_dc_name, ps, depth);
}
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
return True;
}
/*******************************************************************
- Reads or writes an NET_Q_LOGON_CTRL2 structure.
+makes an NET_Q_LOGON_CTRL2 structure.
********************************************************************/
+BOOL make_q_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l,
+ const char* srv_name,
+ uint32 function_code,
+ uint32 query_level,
+ uint32 switch_value)
+{
+ if (q_l == NULL) return False;
+
+ DEBUG(5,("make_q_logon_ctrl2\n"));
+
+ q_l->ptr = 1;
-BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
+ make_unistr2(&(q_l->uni_server_name ), srv_name , strlen(srv_name )+1);
+
+ q_l->function_code = function_code;
+ q_l->query_level = query_level;
+ q_l->switch_value = switch_value;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an NET_Q_LOGON_CTRL2 structure.
+********************************************************************/
+BOOL net_io_q_logon_ctrl2(char *desc, NET_Q_LOGON_CTRL2 *q_l, prs_struct *ps, int depth)
{
- if (q_l == NULL)
- return False;
+ if (q_l == NULL) return False;
prs_debug(ps, depth, desc, "net_io_q_logon_ctrl2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr ", ps, depth, &q_l->ptr))
- return False;
+ prs_uint32("ptr ", ps, depth, &(q_l->ptr ));
- if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
- return False;
+ smb_io_unistr2 ("", &(q_l->uni_server_name), q_l->ptr, ps, depth);
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
- return False;
- if(!prs_uint32("query_level ", ps, depth, &q_l->query_level))
- return False;
- if(!prs_uint32("switch_value ", ps, depth, &q_l->switch_value))
- return False;
+ prs_uint32("function_code", ps, depth, &(q_l->function_code));
+ prs_uint32("query_level ", ps, depth, &(q_l->query_level ));
+ prs_uint32("switch_value ", ps, depth, &(q_l->switch_value ));
return True;
}
/*******************************************************************
- Inits an NET_R_LOGON_CTRL2 structure.
+makes an NET_R_LOGON_CTRL2 structure.
********************************************************************/
-
-void init_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l, uint32 query_level,
- uint32 flags, uint32 pdc_status, uint32 logon_attempts,
- uint32 tc_status, char *trusted_domain_name)
+BOOL make_r_logon_ctrl2(NET_R_LOGON_CTRL2 *r_l,
+ uint32 switch_value,
+ NETLOGON_INFO *logon_info,
+ uint32 status)
{
- DEBUG(5,("make_r_logon_ctrl2\n"));
-
- r_l->switch_value = query_level; /* should only be 0x1 */
-
- switch (query_level) {
- case 1:
- r_l->ptr = 1; /* undocumented pointer */
- init_netinfo_1(&r_l->logon.info1, flags, pdc_status);
- r_l->status = 0;
- break;
- case 2:
- r_l->ptr = 1; /* undocumented pointer */
- init_netinfo_2(&r_l->logon.info2, flags, pdc_status,
- tc_status, trusted_domain_name);
- r_l->status = 0;
- break;
- case 3:
- r_l->ptr = 1; /* undocumented pointer */
- init_netinfo_3(&(r_l->logon.info3), flags, logon_attempts);
- r_l->status = 0;
- break;
- default:
- DEBUG(2,("init_r_logon_ctrl2: unsupported switch value %d\n",
- r_l->switch_value));
- r_l->ptr = 0; /* undocumented pointer */
-
- /* take a guess at an error code... */
- r_l->status = NT_STATUS_INVALID_INFO_CLASS;
- break;
+ if (r_l == NULL) return False;
+
+ r_l->switch_value = switch_value; /* should only be 0x1 */
+ r_l->status = status;
+ memcpy(&(r_l->logon), logon_info, sizeof(NETLOGON_INFO));
+
+ if (status == NT_STATUS_NOPROBLEMO)
+ {
+ r_l->ptr = 1;
+ }
+ else
+ {
+ r_l->ptr = 0;
}
+
+ return True;
}
/*******************************************************************
- Reads or writes an NET_R_LOGON_CTRL2 structure.
+reads or writes an NET_R_LOGON_CTRL2 structure.
********************************************************************/
-
-BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
+BOOL net_io_r_logon_ctrl2(char *desc, NET_R_LOGON_CTRL2 *r_l, prs_struct *ps, int depth)
{
- if (r_l == NULL)
- return False;
+ if (r_l == NULL) return False;
prs_debug(ps, depth, desc, "net_io_r_logon_ctrl2");
depth++;
- if(!prs_uint32("switch_value ", ps, depth, &r_l->switch_value))
- return False;
- if(!prs_uint32("ptr ", ps, depth, &r_l->ptr))
- return False;
-
- if (r_l->ptr != 0) {
- switch (r_l->switch_value) {
- case 1:
- if(!net_io_netinfo_1("", &r_l->logon.info1, ps, depth))
- return False;
- break;
- case 2:
- if(!net_io_netinfo_2("", &r_l->logon.info2, ps, depth))
- return False;
- break;
- case 3:
- if(!net_io_netinfo_3("", &r_l->logon.info3, ps, depth))
- return False;
- break;
- default:
- DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
- r_l->switch_value));
- break;
+ prs_uint32("switch_value ", ps, depth, &(r_l->switch_value ));
+ prs_uint32("ptr ", ps, depth, &(r_l->ptr ));
+
+ if (r_l->ptr != 0)
+ {
+ switch (r_l->switch_value)
+ {
+ case 1:
+ {
+ net_io_netinfo_1("", &(r_l->logon.info1), ps, depth);
+ break;
+ }
+ case 2:
+ {
+ net_io_netinfo_2("", &(r_l->logon.info2), ps, depth);
+ break;
+ }
+ case 3:
+ {
+ net_io_netinfo_3("", &(r_l->logon.info3), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(2,("net_io_r_logon_ctrl2: unsupported switch value %d\n",
+ r_l->switch_value));
+ break;
+ }
}
}
- if(!prs_uint32("status ", ps, depth, &r_l->status))
- return False;
+ prs_uint32("status ", ps, depth, &(r_l->status ));
return True;
}
/*******************************************************************
- Inits an NET_R_TRUST_DOM_LIST structure.
-********************************************************************/
-
-void init_r_trust_dom(NET_R_TRUST_DOM_LIST *r_t,
- uint32 num_doms, char *dom_name)
-{
- int i = 0;
-
- DEBUG(5,("make_r_trust_dom\n"));
-
- for (i = 0; i < MAX_TRUST_DOMS; i++) {
- r_t->uni_trust_dom_name[i].uni_str_len = 0;
- r_t->uni_trust_dom_name[i].uni_max_len = 0;
- }
- if (num_doms > MAX_TRUST_DOMS)
- num_doms = MAX_TRUST_DOMS;
-
- for (i = 0; i < num_doms; i++) {
- fstring domain_name;
- fstrcpy(domain_name, dom_name);
- strupper(domain_name);
- init_unistr2(&r_t->uni_trust_dom_name[i], domain_name, strlen(domain_name)+1);
- /* the use of UNISTR2 here is non-standard. */
- r_t->uni_trust_dom_name[i].undoc = 0x1;
- }
-
- r_t->status = 0;
-}
-
-/*******************************************************************
- Reads or writes an NET_R_TRUST_DOM_LIST structure.
+reads or writes an NET_R_TRUST_DOM_LIST structure.
********************************************************************/
-
-BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
+BOOL net_io_r_trust_dom(char *desc, NET_R_TRUST_DOM_LIST *r_t, prs_struct *ps, int depth)
{
- int i;
- if (r_t == NULL)
- return False;
+ if (r_t == NULL) return False;
prs_debug(ps, depth, desc, "net_io_r_trust_dom");
depth++;
- for (i = 0; i < MAX_TRUST_DOMS; i++) {
- if (r_t->uni_trust_dom_name[i].uni_str_len == 0)
- break;
- if(!smb_io_unistr2("", &r_t->uni_trust_dom_name[i], True, ps, depth))
- return False;
- }
+ smb_io_buffer2("", &r_t->uni_trust_dom_name, True, ps, depth);
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_t->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_t->status));
return True;
}
/*******************************************************************
- Reads or writes an NET_Q_TRUST_DOM_LIST structure.
+reads or writes an NET_Q_TRUST_DOM_LIST structure.
********************************************************************/
-
-BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
+BOOL net_io_q_trust_dom(char *desc, NET_Q_TRUST_DOM_LIST *q_l, prs_struct *ps, int depth)
{
- if (q_l == NULL)
- return False;
+ if (q_l == NULL) return False;
prs_debug(ps, depth, desc, "net_io_q_trust_dom");
depth++;
- if(!prs_uint32("ptr ", ps, depth, &q_l->ptr))
- return False;
- if(!smb_io_unistr2 ("", &q_l->uni_server_name, q_l->ptr, ps, depth))
- return False;
+ prs_uint32("ptr", ps, depth, &(q_l->ptr));
+ smb_io_unistr2 ("name", &(q_l->uni_server_name), q_l->ptr, ps, depth);
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("function_code", ps, depth, &q_l->function_code))
- return False;
+ prs_uint32("function_code", ps, depth, &(q_l->function_code));
return True;
}
/*******************************************************************
- Inits an NET_Q_REQ_CHAL structure.
+makes an NET_Q_REQ_CHAL structure.
********************************************************************/
-
-void init_q_req_chal(NET_Q_REQ_CHAL *q_c,
- char *logon_srv, char *logon_clnt,
+BOOL make_q_req_chal(NET_Q_REQ_CHAL *q_c,
+ const char *logon_srv, const char *logon_clnt,
DOM_CHAL *clnt_chal)
{
+ if (q_c == NULL) return False;
+
DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
q_c->undoc_buffer = 1; /* don't know what this buffer is */
- init_unistr2(&q_c->uni_logon_srv, logon_srv , strlen(logon_srv )+1);
- init_unistr2(&q_c->uni_logon_clnt, logon_clnt, strlen(logon_clnt)+1);
+ make_unistr2(&(q_c->uni_logon_srv ), logon_srv , strlen(logon_srv )+1);
+ make_unistr2(&(q_c->uni_logon_clnt), logon_clnt, strlen(logon_clnt)+1);
memcpy(q_c->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
DEBUG(5,("make_q_req_chal: %d\n", __LINE__));
+
+ return True;
}
/*******************************************************************
- Reads or writes an NET_Q_REQ_CHAL structure.
+reads or writes an NET_Q_REQ_CHAL structure.
********************************************************************/
-
BOOL net_io_q_req_chal(char *desc, NET_Q_REQ_CHAL *q_c, prs_struct *ps, int depth)
{
int old_align;
-
- if (q_c == NULL)
- return False;
+ if (q_c == NULL) return False;
prs_debug(ps, depth, desc, "net_io_q_req_chal");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("undoc_buffer", ps, depth, &q_c->undoc_buffer))
- return False;
+ prs_uint32("undoc_buffer", ps, depth, &(q_c->undoc_buffer));
- if(!smb_io_unistr2("", &q_c->uni_logon_srv, True, ps, depth)) /* logon server unicode string */
- return False;
- if(!smb_io_unistr2("", &q_c->uni_logon_clnt, True, ps, depth)) /* logon client unicode string */
- return False;
+ smb_io_unistr2("", &(q_c->uni_logon_srv ), True, ps, depth); /* logon server unicode string */
+ smb_io_unistr2("", &(q_c->uni_logon_clnt), True, ps, depth); /* logon client unicode string */
old_align = ps->align;
ps->align = 0;
/* client challenge is _not_ aligned after the unicode strings */
- if(!smb_io_chal("", &q_c->clnt_chal, ps, depth)) {
- /* client challenge */
- ps->align = old_align;
- return False;
- }
+ smb_io_chal("", &(q_c->clnt_chal), ps, depth); /* client challenge */
ps->align = old_align;
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
+BOOL net_io_r_req_chal(char *desc, NET_R_REQ_CHAL *r_c, prs_struct *ps, int depth)
{
- if (r_c == NULL)
- return False;
+ if (r_c == NULL) return False;
prs_debug(ps, depth, desc, "net_io_r_req_chal");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_chal("", &r_c->srv_chal, ps, depth)) /* server challenge */
- return False;
+ smb_io_chal("", &(r_c->srv_chal), ps, depth); /* server challenge */
- if(!prs_uint32("status", ps, depth, &r_c->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_c->status));
return True;
}
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL make_q_auth(NET_Q_AUTH *q_a,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CHAL *clnt_chal)
+{
+ if (q_a == NULL) return False;
+
+ DEBUG(5,("make_q_auth: %d\n", __LINE__));
+
+ make_log_info(&(q_a->clnt_id), logon_srv, acct_name, sec_chan, comp_name);
+ memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
+
+ DEBUG(5,("make_q_auth: %d\n", __LINE__));
+
+ return True;
+}
/*******************************************************************
- Inits a NET_Q_AUTH_2 struct.
+reads or writes a structure.
********************************************************************/
+BOOL net_io_q_auth(char *desc, NET_Q_AUTH *q_a, prs_struct *ps, int depth)
+{
+ int old_align;
+ if (q_a == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_q_auth");
+ depth++;
-void init_q_auth_2(NET_Q_AUTH_2 *q_a,
- char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name,
+ prs_align(ps);
+
+ smb_io_log_info ("", &(q_a->clnt_id), ps, depth); /* client identification info */
+ /* client challenge is _not_ aligned */
+ old_align = ps->align;
+ ps->align = 0;
+ smb_io_chal ("", &(q_a->clnt_chal), ps, depth); /* client-calculated credentials */
+ ps->align = old_align;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL net_io_r_auth(char *desc, NET_R_AUTH *r_a, prs_struct *ps, int depth)
+{
+ if (r_a == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_r_auth");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_chal ("", &(r_a->srv_chal), ps, depth); /* server challenge */
+ prs_uint32("status", ps, depth, &(r_a->status));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL make_q_auth_2(NET_Q_AUTH_2 *q_a,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
DOM_CHAL *clnt_chal, uint32 clnt_flgs)
{
- DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
+ if (q_a == NULL) return False;
- init_log_info(&q_a->clnt_id, logon_srv, acct_name, sec_chan, comp_name);
+ DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
+
+ make_log_info(&(q_a->clnt_id), logon_srv, acct_name, sec_chan, comp_name);
memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data));
q_a->clnt_flgs.neg_flags = clnt_flgs;
- DEBUG(5,("init_q_auth_2: %d\n", __LINE__));
+ DEBUG(5,("make_q_auth_2: %d\n", __LINE__));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
+BOOL net_io_q_auth_2(char *desc, NET_Q_AUTH_2 *q_a, prs_struct *ps, int depth)
{
int old_align;
- if (q_a == NULL)
- return False;
+ if (q_a == NULL) return False;
prs_debug(ps, depth, desc, "net_io_q_auth_2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_log_info ("", &q_a->clnt_id, ps, depth)) /* client identification info */
- return False;
+ smb_io_log_info ("", &(q_a->clnt_id), ps, depth); /* client identification info */
/* client challenge is _not_ aligned */
old_align = ps->align;
ps->align = 0;
- if(!smb_io_chal("", &q_a->clnt_chal, ps, depth)) {
- /* client-calculated credentials */
- ps->align = old_align;
- return False;
- }
+ smb_io_chal ("", &(q_a->clnt_chal), ps, depth); /* client-calculated credentials */
ps->align = old_align;
- if(!net_io_neg_flags("", &q_a->clnt_flgs, ps, depth))
- return False;
+ net_io_neg_flags("", &(q_a->clnt_flgs), ps, depth);
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
+BOOL net_io_r_auth_2(char *desc, NET_R_AUTH_2 *r_a, prs_struct *ps, int depth)
{
- if (r_a == NULL)
- return False;
+ if (r_a == NULL) return False;
prs_debug(ps, depth, desc, "net_io_r_auth_2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_chal("", &r_a->srv_chal, ps, depth)) /* server challenge */
- return False;
- if(!net_io_neg_flags("", &r_a->srv_flgs, ps, depth))
- return False;
+ smb_io_chal ("", &(r_a->srv_chal), ps, depth); /* server challenge */
+ net_io_neg_flags("", &(r_a->srv_flgs), ps, depth);
- if(!prs_uint32("status", ps, depth, &r_a->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_a->status));
return True;
}
/*******************************************************************
- Inits a NET_Q_SRV_PWSET.
+reads or writes a structure.
********************************************************************/
-
-void init_q_srv_pwset(NET_Q_SRV_PWSET *q_s, char *logon_srv, char *acct_name,
- uint16 sec_chan, char *comp_name, DOM_CRED *cred, char nt_cypher[16])
+BOOL make_q_srv_pwset(NET_Q_SRV_PWSET *q_s,
+ const char *logon_srv, const char *acct_name,
+ uint16 sec_chan, const char *comp_name,
+ DOM_CRED *cred, char nt_cypher[16])
{
+ if (q_s == NULL || cred == NULL) return False;
+
DEBUG(5,("make_q_srv_pwset\n"));
- init_clnt_info(&q_s->clnt_id, logon_srv, acct_name, sec_chan, comp_name, cred);
+ make_clnt_info(&(q_s->clnt_id), logon_srv, acct_name, sec_chan, comp_name, cred);
memcpy(q_s->pwd, nt_cypher, sizeof(q_s->pwd));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
+BOOL net_io_q_srv_pwset(char *desc, NET_Q_SRV_PWSET *q_s, prs_struct *ps, int depth)
{
- if (q_s == NULL)
- return False;
+ if (q_s == NULL) return False;
prs_debug(ps, depth, desc, "net_io_q_srv_pwset");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_clnt_info("", &q_s->clnt_id, ps, depth)) /* client identification/authentication info */
- return False;
- if(!prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16)) /* new password - undocumented */
- return False;
+ smb_io_clnt_info("", &(q_s->clnt_id), ps, depth); /* client identification/authentication info */
+ prs_uint8s (False, "pwd", ps, depth, q_s->pwd, 16); /* new password - undocumented */
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
+BOOL net_io_r_srv_pwset(char *desc, NET_R_SRV_PWSET *r_s, prs_struct *ps, int depth)
{
- if (r_s == NULL)
- return False;
+ if (r_s == NULL) return False;
prs_debug(ps, depth, desc, "net_io_r_srv_pwset");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_cred("", &r_s->srv_cred, ps, depth)) /* server challenge */
- return False;
+ smb_io_cred("", &(r_s->srv_cred), ps, depth); /* server challenge */
- if(!prs_uint32("status", ps, depth, &r_s->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_s->status));
return True;
}
+
/*************************************************************************
- Init DOM_SID2 array from a string containing multiple sids
+ make DOM_SID2 array from a string containing multiple sids
*************************************************************************/
-
-static int init_dom_sid2s(char *sids_str, DOM_SID2 *sids, int max_sids)
+static int make_dom_sid2s(const char *sids_str, DOM_SID2 *sids, int max_sids)
{
char *ptr;
pstring s2;
- int count = 0;
+ int count;
- DEBUG(4,("init_dom_sid2s: %s\n", sids_str ? sids_str:""));
+ DEBUG(4,("make_dom_sid2s: %s\n", sids_str ? sids_str:""));
- if(sids_str) {
- for (count = 0, ptr = sids_str;
- next_token(&ptr, s2, NULL, sizeof(s2)) && count < max_sids; count++) {
- DOM_SID tmpsid;
- string_to_sid(&tmpsid, s2);
- init_dom_sid2(&sids[count], &tmpsid);
- }
+ if (sids_str == NULL || *sids_str == 0) return 0;
+
+ for (count = 0, ptr = sids_str;
+ next_token(&ptr, s2, NULL, sizeof(s2)) && count < max_sids;
+ count++)
+ {
+ DOM_SID tmpsid;
+ string_to_sid(&tmpsid, s2);
+ make_dom_sid2(&sids[count], &tmpsid);
}
return count;
+
+ return True;
}
/*******************************************************************
- Inits a NET_ID_INFO_1 structure.
+makes a NET_ID_INFO_1 structure.
********************************************************************/
-
-void init_id_info1(NET_ID_INFO_1 *id, char *domain_name,
- uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
- char *user_name, char *wksta_name,
- char sess_key[16],
- unsigned char lm_cypher[16], unsigned char nt_cypher[16])
+BOOL make_id_info1(NET_ID_INFO_1 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low,
+ uint32 log_id_high,
+ const char *user_name,
+ const char *wksta_name,
+ const char sess_key[16],
+ const uchar lm_cypher[16],
+ const uchar nt_cypher[16])
{
int len_domain_name = strlen(domain_name);
int len_user_name = strlen(user_name );
int len_wksta_name = strlen(wksta_name );
- unsigned char lm_owf[16];
- unsigned char nt_owf[16];
+ uchar lm_owf[16];
+ uchar nt_owf[16];
+ uchar key[16];
+
+ if (id == NULL) return False;
DEBUG(5,("make_id_info1: %d\n", __LINE__));
id->ptr_id_info1 = 1;
- init_uni_hdr(&id->hdr_domain_name, len_domain_name);
+ make_uni_hdr(&(id->hdr_domain_name), len_domain_name);
id->param_ctrl = param_ctrl;
- init_logon_id(&id->logon_id, log_id_low, log_id_high);
+ id->logon_id.low = log_id_low;
+ id->logon_id.high = log_id_high;
- init_uni_hdr(&id->hdr_user_name, len_user_name);
- init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
+ make_uni_hdr(&(id->hdr_user_name ), len_user_name );
+ make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name );
- if (lm_cypher && nt_cypher) {
- unsigned char key[16];
+ memset(key, 0, 16);
+ memcpy(key, sess_key, 8);
+
+ if (lm_cypher != NULL)
+ {
#ifdef DEBUG_PASSWORD
DEBUG(100,("lm cypher:"));
- dump_data(100, (char *)lm_cypher, 16);
-
- DEBUG(100,("nt cypher:"));
- dump_data(100, (char *)nt_cypher, 16);
+ dump_data(100, lm_cypher, 16);
#endif
- memset(key, 0, 16);
- memcpy(key, sess_key, 8);
-
memcpy(lm_owf, lm_cypher, 16);
SamOEMhash(lm_owf, key, False);
- memcpy(nt_owf, nt_cypher, 16);
- SamOEMhash(nt_owf, key, False);
#ifdef DEBUG_PASSWORD
DEBUG(100,("encrypt of lm owf password:"));
- dump_data(100, (char *)lm_owf, 16);
+ dump_data(100, lm_owf, 16);
+#endif
+ /* set up pointers to cypher blocks */
+ lm_cypher = lm_owf;
+ }
+ if (nt_cypher != NULL)
+ {
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt cypher:"));
+ dump_data(100, nt_cypher, 16);
+#endif
+
+ memcpy(nt_owf, nt_cypher, 16);
+ SamOEMhash(nt_owf, key, False);
+
+#ifdef DEBUG_PASSWORD
DEBUG(100,("encrypt of nt owf password:"));
- dump_data(100, (char *)nt_owf, 16);
+ dump_data(100, nt_owf, 16);
#endif
/* set up pointers to cypher blocks */
- lm_cypher = lm_owf;
nt_cypher = nt_owf;
}
- init_owf_info(&id->lm_owf, lm_cypher);
- init_owf_info(&id->nt_owf, nt_cypher);
+ make_owf_info(&(id->lm_owf), lm_cypher);
+ make_owf_info(&(id->nt_owf), nt_cypher);
+
+ make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
+ make_unistr2(&(id->uni_user_name ), user_name , len_user_name );
+ make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
- init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
- init_unistr2(&id->uni_user_name, user_name, len_user_name);
- init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
+ return True;
}
/*******************************************************************
- Reads or writes an NET_ID_INFO_1 structure.
+reads or writes an NET_ID_INFO_1 structure.
********************************************************************/
-
static BOOL net_io_id_info1(char *desc, NET_ID_INFO_1 *id, prs_struct *ps, int depth)
{
- if (id == NULL)
- return False;
+ if (id == NULL) return False;
prs_debug(ps, depth, desc, "net_io_id_info1");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_id_info1", ps, depth, &id->ptr_id_info1))
- return False;
+ prs_uint32("ptr_id_info1", ps, depth, &(id->ptr_id_info1));
- if (id->ptr_id_info1 != 0) {
- if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
- return False;
+ if (id->ptr_id_info1 != 0)
+ {
+ smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
- if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
- return False;
- if(!smb_io_logon_id("", &id->logon_id, ps, depth))
- return False;
+ prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
+ smb_io_bigint("", &(id->logon_id), ps, depth);
- if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
- return False;
- if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
- return False;
+ smb_io_unihdr("unihdr", &(id->hdr_user_name ), ps, depth);
+ smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
- if(!smb_io_owf_info("", &id->lm_owf, ps, depth))
- return False;
- if(!smb_io_owf_info("", &id->nt_owf, ps, depth))
- return False;
+ smb_io_owf_info("", &(id->lm_owf), ps, depth);
+ smb_io_owf_info("", &(id->nt_owf), ps, depth);
- if(!smb_io_unistr2("unistr2", &id->uni_domain_name,
- id->hdr_domain_name.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("unistr2", &id->uni_user_name,
- id->hdr_user_name.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("unistr2", &id->uni_wksta_name,
- id->hdr_wksta_name.buffer, ps, depth))
- return False;
+ smb_io_unistr2("unistr2", &(id->uni_domain_name), id->hdr_domain_name.buffer, ps, depth);
+ smb_io_unistr2("unistr2", &(id->uni_user_name ), id->hdr_user_name.buffer, ps, depth);
+ smb_io_unistr2("unistr2", &(id->uni_wksta_name ), id->hdr_wksta_name.buffer, ps, depth);
}
return True;
}
/*******************************************************************
-Inits a NET_ID_INFO_2 structure.
+makes a NET_ID_INFO_4 structure.
This is a network logon packet. The log_id parameters
are what an NT server would generate for LUID once the
@@ -762,111 +689,182 @@ checking for a logon as it doesn't export the password
hashes to anyone who has compromised the secure channel. JRA.
********************************************************************/
-void init_id_info2(NET_ID_INFO_2 *id, char *domain_name,
- uint32 param_ctrl, uint32 log_id_low, uint32 log_id_high,
- char *user_name, char *wksta_name,
- unsigned char lm_challenge[8],
- unsigned char lm_chal_resp[24],
- unsigned char nt_chal_resp[24])
+BOOL make_id_info4(NET_ID_INFO_4 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const char *general)
{
int len_domain_name = strlen(domain_name);
int len_user_name = strlen(user_name );
int len_wksta_name = strlen(wksta_name );
- int nt_chal_resp_len = ((nt_chal_resp != NULL) ? 24 : 0);
- int lm_chal_resp_len = ((lm_chal_resp != NULL) ? 24 : 0);
- unsigned char lm_owf[24];
- unsigned char nt_owf[24];
+ int len_general = strlen(general);
- DEBUG(5,("init_id_info2: %d\n", __LINE__));
+ if (id == NULL) return False;
+
+ DEBUG(5,("make_id_info4: %d\n", __LINE__));
+
+ id->ptr_id_info4 = 1;
+
+ make_uni_hdr(&(id->hdr_domain_name), len_domain_name);
+
+ id->param_ctrl = param_ctrl;
+ id->logon_id.low = log_id_low;
+ id->logon_id.high = log_id_high;
+
+ make_uni_hdr(&(id->hdr_user_name ), len_user_name );
+ make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name );
+ make_str_hdr(&(id->hdr_general ), len_general, len_general, 1);
+
+ make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
+ make_unistr2(&(id->uni_user_name ), user_name , len_user_name );
+ make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
+ make_string2(&(id->str_general ), general , len_general );
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an NET_ID_INFO_4 structure.
+********************************************************************/
+static BOOL net_io_id_info4(char *desc, NET_ID_INFO_4 *id, prs_struct *ps, int depth)
+{
+ if (id == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_id_info4");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_id_info4", ps, depth, &(id->ptr_id_info4));
+
+ if (id->ptr_id_info4 != 0)
+ {
+ smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
+
+ prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
+ smb_io_bigint("", &(id->logon_id), ps, depth);
+
+ smb_io_unihdr("hdr_user ", &(id->hdr_user_name ), ps, depth);
+ smb_io_unihdr("hdr_wksta ", &(id->hdr_wksta_name), ps, depth);
+ smb_io_strhdr("hdr_general", &(id->hdr_general ), ps, depth);
+
+ smb_io_unistr2("uni_domain_name", &(id->uni_domain_name), id->hdr_domain_name .buffer, ps, depth);
+ smb_io_unistr2("uni_user_name ", &(id->uni_user_name ), id->hdr_user_name .buffer, ps, depth);
+ smb_io_unistr2("uni_wksta_name ", &(id->uni_wksta_name ), id->hdr_wksta_name .buffer, ps, depth);
+ smb_io_string2("str_general ", &(id->str_general ), id->hdr_general .buffer, ps, depth);
+ }
+
+ return True;
+}
+
+/*******************************************************************
+makes a NET_ID_INFO_2 structure.
+
+This is a network logon packet. The log_id parameters
+are what an NT server would generate for LUID once the
+user is logged on. I don't think we care about them.
+
+Note that this has no access to the NT and LM hashed passwords,
+so it forwards the challenge, and the NT and LM responses (24
+bytes each) over the secure channel to the Domain controller
+for it to say yea or nay. This is the preferred method of
+checking for a logon as it doesn't export the password
+hashes to anyone who has compromised the secure channel. JRA.
+********************************************************************/
+
+BOOL make_id_info2(NET_ID_INFO_2 *id, const char *domain_name,
+ uint32 param_ctrl,
+ uint32 log_id_low, uint32 log_id_high,
+ const char *user_name, const char *wksta_name,
+ const uchar lm_challenge[8],
+ const uchar *lm_chal_resp,
+ int lm_chal_len,
+ const uchar *nt_chal_resp,
+ int nt_chal_len)
+{
+ int len_domain_name = strlen(domain_name);
+ int len_user_name = strlen(user_name );
+ int len_wksta_name = strlen(wksta_name );
+ uchar lm_owf[24];
+ uchar nt_owf[128];
+
+ if (id == NULL) return False;
+
+ DEBUG(5,("make_id_info2: %d\n", __LINE__));
id->ptr_id_info2 = 1;
- init_uni_hdr(&id->hdr_domain_name, len_domain_name);
+ make_uni_hdr(&(id->hdr_domain_name), len_domain_name);
id->param_ctrl = param_ctrl;
- init_logon_id(&id->logon_id, log_id_low, log_id_high);
+ id->logon_id.low = log_id_low;
+ id->logon_id.high = log_id_high;
- init_uni_hdr(&id->hdr_user_name, len_user_name);
- init_uni_hdr(&id->hdr_wksta_name, len_wksta_name);
+ make_uni_hdr(&(id->hdr_user_name ), len_user_name );
+ make_uni_hdr(&(id->hdr_wksta_name ), len_wksta_name );
- if (nt_chal_resp) {
+ if (nt_chal_resp != NULL)
+ {
/* oops. can only send what-ever-it-is direct */
- memcpy(nt_owf, nt_chal_resp, 24);
+ memcpy(nt_owf, nt_chal_resp, MIN(nt_chal_len, sizeof(nt_owf)));
nt_chal_resp = nt_owf;
}
- if (lm_chal_resp) {
+ if (lm_chal_resp != NULL)
+ {
/* oops. can only send what-ever-it-is direct */
- memcpy(lm_owf, lm_chal_resp, 24);
+ memcpy(lm_owf, lm_chal_resp, MIN(lm_chal_len, sizeof(lm_owf)));
lm_chal_resp = lm_owf;
}
memcpy(id->lm_chal, lm_challenge, sizeof(id->lm_chal));
- init_str_hdr(&id->hdr_nt_chal_resp, 24, nt_chal_resp_len, (nt_chal_resp != NULL) ? 1 : 0);
- init_str_hdr(&id->hdr_lm_chal_resp, 24, lm_chal_resp_len, (lm_chal_resp != NULL) ? 1 : 0);
+ make_str_hdr(&(id->hdr_nt_chal_resp), sizeof(nt_owf), nt_chal_len, nt_chal_resp != NULL ? 1 : 0);
+ make_str_hdr(&(id->hdr_lm_chal_resp), sizeof(lm_owf), lm_chal_len, lm_chal_resp != NULL ? 1 : 0);
+
+ make_unistr2(&(id->uni_domain_name), domain_name, len_domain_name);
+ make_unistr2(&(id->uni_user_name ), user_name , len_user_name );
+ make_unistr2(&(id->uni_wksta_name ), wksta_name , len_wksta_name );
- init_unistr2(&id->uni_domain_name, domain_name, len_domain_name);
- init_unistr2(&id->uni_user_name, user_name, len_user_name);
- init_unistr2(&id->uni_wksta_name, wksta_name, len_wksta_name);
+ make_string2(&(id->nt_chal_resp ), nt_chal_resp , nt_chal_len);
+ make_string2(&(id->lm_chal_resp ), lm_chal_resp , lm_chal_len);
- init_string2(&id->nt_chal_resp, (char *)nt_chal_resp, nt_chal_resp_len);
- init_string2(&id->lm_chal_resp, (char *)lm_chal_resp, lm_chal_resp_len);
+ return True;
}
/*******************************************************************
- Reads or writes an NET_ID_INFO_2 structure.
+reads or writes an NET_ID_INFO_2 structure.
********************************************************************/
-
static BOOL net_io_id_info2(char *desc, NET_ID_INFO_2 *id, prs_struct *ps, int depth)
{
- if (id == NULL)
- return False;
+ if (id == NULL) return False;
prs_debug(ps, depth, desc, "net_io_id_info2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_id_info2", ps, depth, &id->ptr_id_info2))
- return False;
+ prs_uint32("ptr_id_info2", ps, depth, &(id->ptr_id_info2));
- if (id->ptr_id_info2 != 0) {
- if(!smb_io_unihdr("unihdr", &id->hdr_domain_name, ps, depth))
- return False;
+ if (id->ptr_id_info2 != 0)
+ {
+ smb_io_unihdr("unihdr", &(id->hdr_domain_name), ps, depth);
- if(!prs_uint32("param_ctrl", ps, depth, &id->param_ctrl))
- return False;
- if(!smb_io_logon_id("", &id->logon_id, ps, depth))
- return False;
+ prs_uint32("param_ctrl", ps, depth, &(id->param_ctrl));
+ smb_io_bigint("", &(id->logon_id), ps, depth);
- if(!smb_io_unihdr("unihdr", &id->hdr_user_name, ps, depth))
- return False;
- if(!smb_io_unihdr("unihdr", &id->hdr_wksta_name, ps, depth))
- return False;
+ smb_io_unihdr("unihdr", &(id->hdr_user_name ), ps, depth);
+ smb_io_unihdr("unihdr", &(id->hdr_wksta_name ), ps, depth);
- if(!prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8)) /* lm 8 byte challenge */
- return False;
+ prs_uint8s (False, "lm_chal", ps, depth, id->lm_chal, 8); /* lm 8 byte challenge */
- if(!smb_io_strhdr("hdr_nt_chal_resp", &id->hdr_nt_chal_resp, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_lm_chal_resp", &id->hdr_lm_chal_resp, ps, depth))
- return False;
+ smb_io_strhdr("hdr_nt_chal_resp", &(id->hdr_nt_chal_resp ), ps, depth);
+ smb_io_strhdr("hdr_lm_chal_resp", &(id->hdr_lm_chal_resp ), ps, depth);
- if(!smb_io_unistr2("uni_domain_name", &id->uni_domain_name,
- id->hdr_domain_name.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_user_name ", &id->uni_user_name,
- id->hdr_user_name.buffer, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_wksta_name ", &id->uni_wksta_name,
- id->hdr_wksta_name.buffer, ps, depth))
- return False;
- if(!smb_io_string2("nt_chal_resp", &id->nt_chal_resp,
- id->hdr_nt_chal_resp.buffer, ps, depth))
- return False;
- if(!smb_io_string2("lm_chal_resp", &id->lm_chal_resp,
- id->hdr_lm_chal_resp.buffer, ps, depth))
- return False;
+ smb_io_unistr2("uni_domain_name", &(id->uni_domain_name), id->hdr_domain_name .buffer, ps, depth);
+ smb_io_unistr2("uni_user_name ", &(id->uni_user_name ), id->hdr_user_name .buffer, ps, depth);
+ smb_io_unistr2("uni_wksta_name ", &(id->uni_wksta_name ), id->hdr_wksta_name .buffer, ps, depth);
+ smb_io_string2("nt_chal_resp" , &(id->nt_chal_resp) , id->hdr_nt_chal_resp.buffer, ps, depth);
+ smb_io_string2("lm_chal_resp" , &(id->lm_chal_resp) , id->hdr_lm_chal_resp.buffer, ps, depth);
}
return True;
@@ -874,103 +872,237 @@ static BOOL net_io_id_info2(char *desc, NET_ID_INFO_2 *id, prs_struct *ps, int
/*******************************************************************
- Inits a DOM_SAM_INFO structure.
+makes a DOM_SAM_INFO structure.
********************************************************************/
-
-void init_sam_info(DOM_SAM_INFO *sam,
- char *logon_srv, char *comp_name, DOM_CRED *clnt_cred,
+BOOL make_sam_info(DOM_SAM_INFO *sam,
+ const char *logon_srv, const char *comp_name,
+ DOM_CRED *clnt_cred,
DOM_CRED *rtn_cred, uint16 logon_level,
NET_ID_INFO_CTR *ctr)
{
- DEBUG(5,("init_sam_info: %d\n", __LINE__));
+ if (sam == NULL) return False;
+
+ DEBUG(5,("make_sam_info: %d\n", __LINE__));
- init_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
+ make_clnt_info2(&(sam->client), logon_srv, comp_name, clnt_cred);
- if (rtn_cred != NULL) {
+ if (rtn_cred != NULL)
+ {
sam->ptr_rtn_cred = 1;
- memcpy(&sam->rtn_cred, rtn_cred, sizeof(sam->rtn_cred));
- } else {
+ memcpy(&(sam->rtn_cred), rtn_cred, sizeof(sam->rtn_cred));
+ }
+ else
+ {
sam->ptr_rtn_cred = 0;
}
sam->logon_level = logon_level;
sam->ctr = ctr;
+
+ return True;
}
/*******************************************************************
- Reads or writes a DOM_SAM_INFO structure.
+reads or writes a DOM_SAM_INFO structure.
********************************************************************/
-
-static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth)
+static BOOL net_io_id_info_ctr(char *desc, NET_ID_INFO_CTR *ctr, prs_struct *ps, int depth)
{
- if (ctr == NULL)
- return False;
+ if (ctr == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_sam_info");
depth++;
/* don't 4-byte align here! */
- if(!prs_uint16("switch_value ", ps, depth, &ctr->switch_value))
- return False;
+ prs_uint16("switch_value ", ps, depth, &(ctr->switch_value));
- switch (ctr->switch_value) {
- case 1:
- if(!net_io_id_info1("", &ctr->auth.id1, ps, depth))
- return False;
- break;
- case 2:
- if(!net_io_id_info2("", &ctr->auth.id2, ps, depth))
- return False;
- break;
- default:
- /* PANIC! */
- DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
- break;
+ switch (ctr->switch_value)
+ {
+ case INTERACTIVE_LOGON_TYPE:
+ {
+ net_io_id_info1("", &(ctr->auth.id1), ps, depth);
+ break;
+ }
+ case NETWORK_LOGON_TYPE:
+ {
+ net_io_id_info2("", &(ctr->auth.id2), ps, depth);
+ break;
+ }
+ case GENERAL_LOGON_TYPE:
+ {
+ net_io_id_info4("", &(ctr->auth.id4), ps, depth);
+ break;
+ }
+ default:
+ {
+ /* PANIC! */
+ DEBUG(4,("smb_io_sam_info: unknown switch_value!\n"));
+ break;
+ }
}
return True;
}
/*******************************************************************
- Reads or writes a DOM_SAM_INFO structure.
- ********************************************************************/
-
-static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
+reads or writes a DOM_SAM_INFO structure.
+********************************************************************/
+static BOOL smb_io_sam_info(char *desc, DOM_SAM_INFO *sam, prs_struct *ps, int depth)
{
- if (sam == NULL)
- return False;
+ if (sam == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_sam_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_clnt_info2("", &sam->client, ps, depth))
- return False;
+ smb_io_clnt_info2("", &(sam->client ), ps, depth);
- if(!prs_uint32("ptr_rtn_cred ", ps, depth, &sam->ptr_rtn_cred))
- return False;
- if(!smb_io_cred("", &sam->rtn_cred, ps, depth))
- return False;
+ prs_uint32("ptr_rtn_cred ", ps, depth, &(sam->ptr_rtn_cred));
+ smb_io_cred ("", &(sam->rtn_cred), ps, depth);
- if(!prs_uint16("logon_level ", ps, depth, &sam->logon_level))
- return False;
+ prs_uint16("logon_level ", ps, depth, &(sam->logon_level ));
- if (sam->logon_level != 0 && sam->ctr != NULL) {
- if(!net_io_id_info_ctr("logon_info", sam->ctr, ps, depth))
- return False;
+ if (sam->logon_level != 0 && sam->ctr != NULL)
+ {
+ net_io_id_info_ctr("logon_info", sam->ctr, ps, depth);
}
return True;
}
/*************************************************************************
- Init
+ make_net_user_info3
*************************************************************************/
+BOOL make_net_user_info3W(NET_USER_INFO_3 *usr,
+
+ const NTTIME *logon_time,
+ const NTTIME *logoff_time,
+ const NTTIME *kickoff_time,
+ const NTTIME *pass_last_set_time,
+ const NTTIME *pass_can_change_time,
+ const NTTIME *pass_must_change_time,
+
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+
+ uint16 logon_count,
+ uint16 bad_pw_count,
+
+ uint32 user_id,
+ uint32 group_id,
+ uint32 num_groups,
+ const DOM_GID *gids,
+ uint32 user_flgs,
+
+ const char sess_key[16],
+
+ const UNISTR2 *logon_srv,
+ const UNISTR2 *logon_dom,
+
+ const char *padding,
+
+ const DOM_SID *dom_sid,
+ const char *other_sids)
+{
+ /* only cope with one "other" sid, right now. */
+ /* need to count the number of space-delimited sids */
+ uint32 i;
+ int num_other_sids = 0;
+
+ int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
+ int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
+ int len_logon_script = log_scr != NULL ? log_scr ->uni_str_len : 0;
+ int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
+ int len_home_dir = home_dir != NULL ? home_dir ->uni_str_len : 0;
+ int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
+
+ int len_logon_srv = logon_srv != NULL ? logon_srv ->uni_str_len : 0;
+ int len_logon_dom = logon_dom != NULL ? logon_dom ->uni_str_len : 0;
+
+ usr->logon_time = *logon_time;
+ usr->logoff_time = *logoff_time;
+ usr->kickoff_time = *kickoff_time;
+ usr->pass_last_set_time = *pass_last_set_time;
+ usr->pass_can_change_time = *pass_can_change_time;
+ usr->pass_must_change_time = *pass_must_change_time;
+
+ make_uni_hdr(&(usr->hdr_user_name ), len_user_name );
+ make_uni_hdr(&(usr->hdr_full_name ), len_full_name );
+ make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
+ make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
+ make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir );
+ make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive );
+
+ usr->logon_count = logon_count;
+ usr->bad_pw_count = bad_pw_count;
+
+ usr->user_id = user_id;
+ usr->group_id = group_id;
+ usr->num_groups = num_groups;
+ usr->buffer_groups = 1; /* indicates fill in groups, below, even if there are none */
+ usr->user_flgs = user_flgs;
+
+ if (sess_key != NULL)
+ {
+ memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
+ }
+ else
+ {
+ bzero(usr->user_sess_key, sizeof(usr->user_sess_key));
+ }
+
+ make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
+ make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
-void init_net_user_info3(NET_USER_INFO_3 *usr,
+ usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, put a domain SID in */
+
+ bzero(usr->padding, sizeof(usr->padding));
+ if (padding != NULL)
+ {
+ memcpy(usr->padding, padding, 8);
+ }
+
+ num_other_sids = make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
+
+ usr->num_other_sids = num_other_sids;
+ usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0;
+
+ copy_unistr2(&(usr->uni_user_name ), user_name);
+ copy_unistr2(&(usr->uni_full_name ), full_name);
+ copy_unistr2(&(usr->uni_logon_script), log_scr );
+ copy_unistr2(&(usr->uni_profile_path), prof_path);
+ copy_unistr2(&(usr->uni_home_dir ), home_dir );
+ copy_unistr2(&(usr->uni_dir_drive ), dir_drive);
+
+ usr->num_groups2 = num_groups;
+
+ SMB_ASSERT_ARRAY(usr->gids, num_groups);
+
+ for (i = 0; i < num_groups; i++)
+ {
+ usr->gids[i] = gids[i];
+ }
+
+ copy_unistr2(&(usr->uni_logon_srv ), logon_srv);
+ copy_unistr2(&(usr->uni_logon_dom ), logon_dom);
+
+ make_dom_sid2(&(usr->dom_sid), dom_sid);
+ /* "other" sids are set up above */
+
+ usr->auth_resp = 1;
+
+ return True;
+}
+
+/*************************************************************************
+ make_net_user_info3
+ *************************************************************************/
+BOOL make_net_user_info3(NET_USER_INFO_3 *usr,
NTTIME *logon_time,
NTTIME *logoff_time,
@@ -1000,12 +1132,14 @@ void init_net_user_info3(NET_USER_INFO_3 *usr,
char *logon_srv,
char *logon_dom,
+ char *padding,
+
DOM_SID *dom_sid,
char *other_sids)
{
/* only cope with one "other" sid, right now. */
/* need to count the number of space-delimited sids */
- int i;
+ uint32 i;
int num_other_sids = 0;
int len_user_name = strlen(user_name );
@@ -1018,10 +1152,6 @@ void init_net_user_info3(NET_USER_INFO_3 *usr,
int len_logon_srv = strlen(logon_srv);
int len_logon_dom = strlen(logon_dom);
- memset(usr, '\0', sizeof(*usr));
-
- usr->ptr_user_info = 1; /* yes, we're bothering to put USER_INFO data here */
-
usr->logon_time = *logon_time;
usr->logoff_time = *logoff_time;
usr->kickoff_time = *kickoff_time;
@@ -1029,12 +1159,12 @@ void init_net_user_info3(NET_USER_INFO_3 *usr,
usr->pass_can_change_time = *pass_can_change_time;
usr->pass_must_change_time = *pass_must_change_time;
- init_uni_hdr(&usr->hdr_user_name, len_user_name);
- init_uni_hdr(&usr->hdr_full_name, len_full_name);
- init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
- init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
- init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
- init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
+ make_uni_hdr(&(usr->hdr_user_name ), len_user_name );
+ make_uni_hdr(&(usr->hdr_full_name ), len_full_name );
+ make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
+ make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
+ make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir );
+ make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive );
usr->logon_count = logon_count;
usr->bad_pw_count = bad_pw_count;
@@ -1046,274 +1176,955 @@ void init_net_user_info3(NET_USER_INFO_3 *usr,
usr->user_flgs = user_flgs;
if (sess_key != NULL)
+ {
memcpy(usr->user_sess_key, sess_key, sizeof(usr->user_sess_key));
+ }
else
- memset((char *)usr->user_sess_key, '\0', sizeof(usr->user_sess_key));
+ {
+ bzero(usr->user_sess_key, sizeof(usr->user_sess_key));
+ }
- init_uni_hdr(&usr->hdr_logon_srv, len_logon_srv);
- init_uni_hdr(&usr->hdr_logon_dom, len_logon_dom);
+ make_uni_hdr(&(usr->hdr_logon_srv), len_logon_srv);
+ make_uni_hdr(&(usr->hdr_logon_dom), len_logon_dom);
usr->buffer_dom_id = dom_sid ? 1 : 0; /* yes, we're bothering to put a domain SID in */
- memset((char *)usr->padding, '\0', sizeof(usr->padding));
+ bzero(usr->padding, sizeof(usr->padding));
+ if (padding != NULL)
+ {
+ memcpy(usr->padding, padding, 8);
+ }
- num_other_sids = init_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
+ num_other_sids = make_dom_sid2s(other_sids, usr->other_sids, LSA_MAX_SIDS);
usr->num_other_sids = num_other_sids;
- usr->buffer_other_sids = (num_other_sids != 0) ? 1 : 0;
+ usr->buffer_other_sids = num_other_sids != 0 ? 1 : 0;
- init_unistr2(&usr->uni_user_name, user_name, len_user_name);
- init_unistr2(&usr->uni_full_name, full_name, len_full_name);
- init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
- init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
- init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
- init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
+ make_unistr2(&(usr->uni_user_name ), user_name , len_user_name );
+ make_unistr2(&(usr->uni_full_name ), full_name , len_full_name );
+ make_unistr2(&(usr->uni_logon_script), logon_script, len_logon_script);
+ make_unistr2(&(usr->uni_profile_path), profile_path, len_profile_path);
+ make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir );
+ make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive );
usr->num_groups2 = num_groups;
SMB_ASSERT_ARRAY(usr->gids, num_groups);
for (i = 0; i < num_groups; i++)
+ {
usr->gids[i] = gids[i];
+ }
- init_unistr2(&usr->uni_logon_srv, logon_srv, len_logon_srv);
- init_unistr2(&usr->uni_logon_dom, logon_dom, len_logon_dom);
+ make_unistr2(&(usr->uni_logon_srv), logon_srv, len_logon_srv);
+ make_unistr2(&(usr->uni_logon_dom), logon_dom, len_logon_dom);
- init_dom_sid2(&usr->dom_sid, dom_sid);
+ make_dom_sid2(&(usr->dom_sid), dom_sid);
/* "other" sids are set up above */
+
+ usr->auth_resp = 1;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth)
+BOOL net_io_user_info3(char *desc, NET_USER_INFO_3 *usr, prs_struct *ps, int depth)
{
- int i;
+ uint32 i;
- if (usr == NULL)
- return False;
+ if (usr == NULL) return False;
prs_debug(ps, depth, desc, "lsa_io_lsa_user_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_user_info ", ps, depth, &usr->ptr_user_info))
- return False;
-
- if (usr->ptr_user_info == 0)
- return True;
-
- if(!smb_io_time("time", &usr->logon_time, ps, depth)) /* logon time */
- return False;
- if(!smb_io_time("time", &usr->logoff_time, ps, depth)) /* logoff time */
- return False;
- if(!smb_io_time("time", &usr->kickoff_time, ps, depth)) /* kickoff time */
- return False;
- if(!smb_io_time("time", &usr->pass_last_set_time, ps, depth)) /* password last set time */
- return False;
- if(!smb_io_time("time", &usr->pass_can_change_time , ps, depth)) /* password can change time */
- return False;
- if(!smb_io_time("time", &usr->pass_must_change_time, ps, depth)) /* password must change time */
- return False;
-
- if(!smb_io_unihdr("unihdr", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
- return False;
- if(!smb_io_unihdr("unihdr", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
- return False;
- if(!smb_io_unihdr("unihdr", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
- return False;
- if(!smb_io_unihdr("unihdr", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
- return False;
- if(!smb_io_unihdr("unihdr", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
- return False;
- if(!smb_io_unihdr("unihdr", &usr->hdr_dir_drive, ps, depth)) /* home directory drive unicode string header */
- return False;
-
- if(!prs_uint16("logon_count ", ps, depth, &usr->logon_count)) /* logon count */
- return False;
- if(!prs_uint16("bad_pw_count ", ps, depth, &usr->bad_pw_count)) /* bad password count */
- return False;
-
- if(!prs_uint32("user_id ", ps, depth, &usr->user_id)) /* User ID */
- return False;
- if(!prs_uint32("group_id ", ps, depth, &usr->group_id)) /* Group ID */
- return False;
- if(!prs_uint32("num_groups ", ps, depth, &usr->num_groups)) /* num groups */
- return False;
- if(!prs_uint32("buffer_groups ", ps, depth, &usr->buffer_groups)) /* undocumented buffer pointer to groups. */
- return False;
- if(!prs_uint32("user_flgs ", ps, depth, &usr->user_flgs)) /* user flags */
- return False;
-
- if(!prs_uint8s(False, "user_sess_key", ps, depth, usr->user_sess_key, 16)) /* unused user session key */
- return False;
-
- if(!smb_io_unihdr("unihdr", &usr->hdr_logon_srv, ps, depth)) /* logon server unicode string header */
- return False;
- if(!smb_io_unihdr("unihdr", &usr->hdr_logon_dom, ps, depth)) /* logon domain unicode string header */
- return False;
-
- if(!prs_uint32("buffer_dom_id ", ps, depth, &usr->buffer_dom_id)) /* undocumented logon domain id pointer */
- return False;
- if(!prs_uint8s (False, "padding ", ps, depth, usr->padding, 40)) /* unused padding bytes? */
- return False;
-
- if(!prs_uint32("num_other_sids", ps, depth, &usr->num_other_sids)) /* 0 - num_sids */
- return False;
- if(!prs_uint32("buffer_other_sids", ps, depth, &usr->buffer_other_sids)) /* NULL - undocumented pointer to SIDs. */
- return False;
-
- if(!smb_io_unistr2("unistr2", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
- return False;
- if(!smb_io_unistr2("unistr2", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
- return False;
- if(!smb_io_unistr2("unistr2", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
- return False;
- if(!smb_io_unistr2("unistr2", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
- return False;
- if(!smb_io_unistr2("unistr2", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
- return False;
- if(!smb_io_unistr2("unistr2", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
- return False;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("num_groups2 ", ps, depth, &usr->num_groups2)) /* num groups */
- return False;
+ smb_io_time("time", &(usr->logon_time) , ps, depth); /* logon time */
+ smb_io_time("time", &(usr->logoff_time) , ps, depth); /* logoff time */
+ smb_io_time("time", &(usr->kickoff_time) , ps, depth); /* kickoff time */
+ smb_io_time("time", &(usr->pass_last_set_time) , ps, depth); /* password last set time */
+ smb_io_time("time", &(usr->pass_can_change_time) , ps, depth); /* password can change time */
+ smb_io_time("time", &(usr->pass_must_change_time), ps, depth); /* password must change time */
+
+ smb_io_unihdr("unihdr", &(usr->hdr_user_name) , ps, depth); /* username unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_full_name) , ps, depth); /* user's full name unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_home_dir) , ps, depth); /* home directory unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_dir_drive) , ps, depth); /* home directory drive unicode string header */
+
+ prs_uint16("logon_count ", ps, depth, &(usr->logon_count )); /* logon count */
+ prs_uint16("bad_pw_count ", ps, depth, &(usr->bad_pw_count)); /* bad password count */
+
+ prs_uint32("user_id ", ps, depth, &(usr->user_id )); /* User ID */
+ prs_uint32("group_id ", ps, depth, &(usr->group_id )); /* Group ID */
+ prs_uint32("num_groups ", ps, depth, &(usr->num_groups )); /* num groups */
+ prs_uint32("buffer_groups ", ps, depth, &(usr->buffer_groups)); /* undocumented buffer pointer to groups. */
+ prs_uint32("user_flgs ", ps, depth, &(usr->user_flgs )); /* user flags */
+
+ prs_uint8s (False, "user_sess_key", ps, depth, usr->user_sess_key, 16); /* unused user session key */
+
+ smb_io_unihdr("unihdr", &(usr->hdr_logon_srv), ps, depth); /* logon server unicode string header */
+ smb_io_unihdr("unihdr", &(usr->hdr_logon_dom), ps, depth); /* logon domain unicode string header */
+
+ prs_uint32("buffer_dom_id ", ps, depth, &(usr->buffer_dom_id)); /* undocumented logon domain id pointer */
+ prs_uint8s (False, "padding ", ps, depth, usr->padding, 40); /* unused padding bytes? */
+
+ prs_uint32("num_other_sids", ps, depth, &(usr->num_other_sids)); /* 0 - num_sids */
+ prs_uint32("buffer_other_sids", ps, depth, &(usr->buffer_other_sids)); /* NULL - undocumented pointer to SIDs. */
+
+ smb_io_unistr2("unistr2", &(usr->uni_user_name) , usr->hdr_user_name .buffer, ps, depth); /* username unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_full_name) , usr->hdr_full_name .buffer, ps, depth); /* user's full name unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_home_dir) , usr->hdr_home_dir .buffer, ps, depth); /* home directory unicode string */
+ smb_io_unistr2("unistr2", &(usr->uni_dir_drive) , usr->hdr_dir_drive .buffer, ps, depth); /* home directory drive unicode string */
+
+ prs_align(ps);
+ prs_uint32("num_groups2 ", ps, depth, &(usr->num_groups2)); /* num groups */
SMB_ASSERT_ARRAY(usr->gids, usr->num_groups2);
- for (i = 0; i < usr->num_groups2; i++) {
- if(!smb_io_gid("", &usr->gids[i], ps, depth)) /* group info */
- return False;
+ for (i = 0; i < usr->num_groups2; i++)
+ {
+ smb_io_gid("", &(usr->gids[i]), ps, depth); /* group info */
}
- if(!smb_io_unistr2("unistr2", &usr->uni_logon_srv, usr->hdr_logon_srv.buffer, ps, depth)) /* logon server unicode string */
- return False;
- if(!smb_io_unistr2("unistr2", &usr->uni_logon_dom, usr->hdr_logon_srv.buffer, ps, depth)) /* logon domain unicode string */
- return False;
+ smb_io_unistr2("unistr2", &( usr->uni_logon_srv), usr->hdr_logon_srv.buffer, ps, depth); /* logon server unicode string */
+ smb_io_unistr2("unistr2", &( usr->uni_logon_dom), usr->hdr_logon_srv.buffer, ps, depth); /* logon domain unicode string */
- if(!smb_io_dom_sid2("", &usr->dom_sid, ps, depth)) /* domain SID */
- return False;
+ smb_io_dom_sid2("sid", &(usr->dom_sid), ps, depth); /* domain SID */
SMB_ASSERT_ARRAY(usr->other_sids, usr->num_other_sids);
- for (i = 0; i < usr->num_other_sids; i++) {
- if(!smb_io_dom_sid2("", &usr->other_sids[i], ps, depth)) /* other domain SIDs */
- return False;
+ for (i = 0; i < usr->num_other_sids; i++)
+ {
+ smb_io_dom_sid2("sids", &(usr->other_sids[i]), ps, depth); /* other domain SIDs */
}
+ prs_uint32("auth_resp ", ps, depth, &usr->auth_resp); /* 1 - Authoritative response; 0 - Non-Auth? */
+
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
+BOOL net_io_q_sam_logon(char *desc, NET_Q_SAM_LOGON *q_l, prs_struct *ps, int depth)
{
- if (q_l == NULL)
- return False;
+ if (q_l == NULL) return False;
prs_debug(ps, depth, desc, "net_io_q_sam_logon");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_sam_info("", &q_l->sam_id, ps, depth)) /* domain SID */
- return False;
-
- if(!prs_uint16("validation_level", ps, depth, &q_l->validation_level))
- return False;
+ smb_io_sam_info("", &(q_l->sam_id), ps, depth); /* domain SID */
+ prs_uint16("validation_level", ps, depth, &(q_l->validation_level));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+makes a NET_R_SAM_LOGON structure.
********************************************************************/
+BOOL make_r_sam_logon(NET_R_SAM_LOGON *r_s,
+ const DOM_CRED *srv_creds,
+ uint16 switch_value,
+ NET_USER_INFO_3 *user_info,
+ uint32 status)
+{
+ if (r_s == NULL) return False;
+
+ /* XXXX we may want this behaviour:
+ if (status == NT_STATUS_NOPROBLEMO)
+ {
+ */
+
+ r_s->buffer_creds = 1;
+
+ if (status == NT_STATUS_NOPROBLEMO)
+ {
+ memcpy(&(r_s->srv_creds), srv_creds, sizeof(r_s->srv_creds));
+ /* store the user information, if there is any. */
+ r_s->user = user_info;
+ if (user_info != NULL)
+ {
+ r_s->ptr_user_info = 1;
+ r_s->switch_value = 3; /* indicates type of validation user info */
+ }
+ else
+ {
+ r_s->ptr_user_info = 0;
+ r_s->switch_value = 0; /* indicates no info */
+ }
+ }
+ else
+ {
+ /* XXXX we may want this behaviour:
+ r_s->buffer_creds = 0;
+ */
+ r_s->ptr_user_info = 0;
+ r_s->switch_value = 0;
+ r_s->user = NULL;
+ }
+
+ r_s->status = status;
+
+ return True;
+}
-BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL net_io_r_sam_logon(char *desc, NET_R_SAM_LOGON *r_l, prs_struct *ps, int depth)
{
- if (r_l == NULL)
- return False;
+ if (r_l == NULL) return False;
prs_debug(ps, depth, desc, "net_io_r_sam_logon");
depth++;
- if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
- return False;
- if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials. server time stamp appears to be ignored. */
- return False;
+ prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
+ smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials. server time stamp appears to be ignored. */
- if(!prs_uint16("switch_value", ps, depth, &r_l->switch_value))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint16("switch_value", ps, depth, &(r_l->switch_value));
+ prs_align(ps);
+ prs_uint32("ptr_user_info ", ps, depth, &r_l->ptr_user_info);
- if (r_l->switch_value != 0) {
- if(!net_io_user_info3("", r_l->user, ps, depth))
- return False;
+ if (r_l->switch_value != 0 && r_l->ptr_user_info != 0)
+ {
+ net_io_user_info3("", r_l->user, ps, depth);
}
- if(!prs_uint32("auth_resp ", ps, depth, &r_l->auth_resp)) /* 1 - Authoritative response; 0 - Non-Auth? */
- return False;
-
- if(!prs_uint32("status ", ps, depth, &r_l->status))
- return False;
+ prs_uint32("status ", ps, depth, &(r_l->status));
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL net_io_q_sam_logoff(char *desc, NET_Q_SAM_LOGOFF *q_l, prs_struct *ps, int depth)
{
- if (q_l == NULL)
- return False;
+ if (q_l == NULL) return False;
prs_debug(ps, depth, desc, "net_io_q_sam_logoff");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_sam_info("", &q_l->sam_id, ps, depth)) /* domain SID */
- return False;
+ smb_io_sam_info("", &(q_l->sam_id), ps, depth); /* domain SID */
return True;
}
/*******************************************************************
- Reads or writes a structure.
+makes a NET_R_SAM_LOGOFF structure.
********************************************************************/
+BOOL make_r_sam_logoff(NET_R_SAM_LOGOFF *r_s,
+ const DOM_CRED *srv_cred,
+ uint32 status)
+{
+ if (r_s == NULL) return False;
+
+ /* XXXX we may want this behaviour:
+ if (status == NT_STATUS_NOPROBLEMO)
+ {
+ */
+ /* XXXX maybe we want to say 'no', reject the client's credentials */
+ r_s->buffer_creds = 1; /* yes, we have valid server credentials */
+ memcpy(&(r_s->srv_creds), srv_cred, sizeof(r_s->srv_creds));
+
+ /* XXXX we may want this behaviour:
+ }
+ else
+ {
+ r_s->buffer_creds = 0;
+ }
+ */
+
+ r_s->status = status;
+
+ return True;
+}
-BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL net_io_r_sam_logoff(char *desc, NET_R_SAM_LOGOFF *r_l, prs_struct *ps, int depth)
{
- if (r_l == NULL)
- return False;
+ if (r_l == NULL) return False;
prs_debug(ps, depth, desc, "net_io_r_sam_logoff");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint32("buffer_creds", ps, depth, &(r_l->buffer_creds)); /* undocumented buffer pointer */
+ smb_io_cred("", &(r_l->srv_creds), ps, depth); /* server credentials. server time stamp appears to be ignored. */
+
+ prs_uint32("status ", ps, depth, &(r_l->status));
+
+ return True;
+}
+
+/*******************************************************************
+makes a NET_Q_SAM_SYNC structure.
+********************************************************************/
+BOOL make_q_sam_sync(NET_Q_SAM_SYNC *q_s,
+ const char *srv_name,
+ const char *cli_name,
+ DOM_CRED *cli_creds, uint32 database_id)
+{
+ if (q_s == NULL) return False;
+
+ DEBUG(5,("make_q_sam_sync\n"));
+
+ make_unistr2(&(q_s->uni_srv_name), srv_name, strlen(srv_name)+1);
+ make_unistr2(&(q_s->uni_cli_name), cli_name, strlen(cli_name)+1);
+
+ memcpy(&(q_s->cli_creds), cli_creds, sizeof(q_s->cli_creds));
+ memset(&(q_s->ret_creds), 0, sizeof(q_s->ret_creds));
+
+ q_s->database_id = database_id;
+ q_s->restart_state = 0;
+ q_s->sync_context = 0;
+ q_s->max_size = 0xffff;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL net_io_q_sam_sync(char *desc, NET_Q_SAM_SYNC *q_s, prs_struct *ps, int depth)
+{
+ if (q_s == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_q_sam_sync");
+ depth++;
+
+ smb_io_unistr2("", &(q_s->uni_srv_name), True, ps, depth);
+ smb_io_unistr2("", &(q_s->uni_cli_name), True, ps, depth);
+
+ smb_io_cred("", &(q_s->cli_creds), ps, depth);
+ smb_io_cred("", &(q_s->ret_creds), ps, depth);
+
+ prs_uint32("database_id ", ps, depth, &(q_s->database_id ));
+ prs_uint32("restart_state", ps, depth, &(q_s->restart_state));
+ prs_uint32("sync_context ", ps, depth, &(q_s->sync_context ));
+
+ prs_uint32("max_size", ps, depth, &(q_s->max_size));
+
+ return True;
+}
+
+/*******************************************************************
+makes a SAM_DELTA_HDR structure.
+********************************************************************/
+BOOL make_sam_delta_hdr(SAM_DELTA_HDR *delta, uint16 type, uint32 rid)
+{
+ if (delta == NULL) return False;
+
+ DEBUG(5,("make_sam_delta_hdr\n"));
+
+ delta->type2 = delta->type = type;
+ delta->target_rid = rid;
+
+ delta->type3 = type;
+ delta->ptr_delta = 1;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_delta_hdr(char *desc, SAM_DELTA_HDR *delta, prs_struct *ps, int depth)
+{
+ if (delta == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_sam_delta_hdr");
+ depth++;
+
+ prs_uint16("type", ps, depth, &(delta->type ));
+ prs_uint16("type2", ps, depth, &(delta->type2 ));
+ prs_uint32("target_rid", ps, depth, &(delta->target_rid));
+
+ prs_uint32("type3", ps, depth, &(delta->type3 ));
+ prs_uint32("ptr_delta", ps, depth, &(delta->ptr_delta ));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_domain_info(char *desc, SAM_DOMAIN_INFO *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_sam_domain_info");
+ depth++;
+
+ smb_io_unihdr("hdr_dom_name" , &(info->hdr_dom_name) , ps, depth);
+ smb_io_unihdr("hdr_oem_info" , &(info->hdr_oem_info) , ps, depth);
+
+ smb_io_bigint("force_logoff" , &(info->force_logoff) , ps, depth);
+ prs_uint16("min_pwd_len" , ps, depth, &(info->min_pwd_len ));
+ prs_uint16("pwd_history_len" , ps, depth, &(info->pwd_history_len));
+ smb_io_bigint("max_pwd_age" , &(info->max_pwd_age) , ps, depth);
+ smb_io_bigint("min_pwd_age" , &(info->min_pwd_age) , ps, depth);
+ smb_io_bigint("dom_mod_count", &(info->dom_mod_count), ps, depth);
+ smb_io_time("creation_time" , &(info->creation_time), ps, depth);
+
+ smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc) , ps, depth);
+ smb_io_unihdr ("hdr_unknown" , &(info->hdr_unknown) , ps, depth);
+ ps->offset += 40;
+
+ smb_io_unistr2("uni_dom_name", &(info->uni_dom_name),
+ info->hdr_dom_name.buffer, ps, depth);
+ smb_io_unistr2("buf_oem_info", &(info->buf_oem_info),
+ info->hdr_oem_info.buffer, ps, depth);
+
+ smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
+ info->hdr_sec_desc.buffer, ps, depth);
+ smb_io_unistr2("buf_unknown" , &(info->buf_unknown ),
+ info->hdr_unknown .buffer, ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_group_info(char *desc, SAM_GROUP_INFO *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_sam_group_info");
+ depth++;
+
+ smb_io_unihdr ("hdr_grp_name", &(info->hdr_grp_name), ps, depth);
+ smb_io_gid ("gid", &(info->gid), ps, depth);
+ smb_io_unihdr ("hdr_grp_desc", &(info->hdr_grp_desc), ps, depth);
+ smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc), ps, depth);
+ ps->offset += 48;
+
+ smb_io_unistr2("uni_grp_name", &(info->uni_grp_name),
+ info->hdr_grp_name.buffer, ps, depth);
+ smb_io_unistr2("uni_grp_desc", &(info->uni_grp_desc),
+ info->hdr_grp_desc.buffer, ps, depth);
+ smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
+ info->hdr_sec_desc.buffer, ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+makes a SAM_ACCOUNT_INFO structure.
+********************************************************************/
+BOOL make_sam_account_info(SAM_ACCOUNT_INFO *info,
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ uint32 user_rid, uint32 group_rid,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *desc,
+ uint32 acb_info,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial)
+{
+ int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
+ int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
+ int len_home_dir = home_dir != NULL ? home_dir ->uni_str_len : 0;
+ int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
+ int len_logon_script = log_scr != NULL ? log_scr ->uni_str_len : 0;
+ int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
+ int len_description = desc != NULL ? desc ->uni_str_len : 0;
+ int len_workstations = wkstas != NULL ? wkstas ->uni_str_len : 0;
+ int len_unknown_str = unk_str != NULL ? unk_str ->uni_str_len : 0;
+ int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
+
+ DEBUG(5,("make_sam_account_info\n"));
+
+ make_uni_hdr(&(info->hdr_acct_name ), len_user_name );
+ make_uni_hdr(&(info->hdr_full_name ), len_full_name );
+ make_uni_hdr(&(info->hdr_home_dir ), len_home_dir );
+ make_uni_hdr(&(info->hdr_dir_drive ), len_dir_drive );
+ make_uni_hdr(&(info->hdr_logon_script), len_logon_script);
+ make_uni_hdr(&(info->hdr_profile ), len_profile_path);
+ make_uni_hdr(&(info->hdr_acct_desc ), len_description );
+ make_uni_hdr(&(info->hdr_workstations), len_workstations);
+ make_uni_hdr(&(info->hdr_comment ), len_unknown_str );
+ make_uni_hdr(&(info->hdr_parameters ), len_munged_dial );
+
+ /* not present */
+ make_bufhdr2(&(info->hdr_sec_desc), 0, 0, 0);
+
+ info->user_rid = user_rid;
+ info->group_rid = group_rid;
+
+ init_nt_time(&(info->logon_time));
+ init_nt_time(&(info->logoff_time));
+ init_nt_time(&(info->pwd_last_set_time));
+ init_nt_time(&(info->acct_expiry_time));
+
+ info->logon_divs = 0xA8;
+ info->ptr_logon_hrs = 0; /* Don't care right now */
+
+ info->bad_pwd_count = 0;
+ info->logon_count = 0;
+ info->acb_info = acb_info;
+ info->nt_pwd_present = 0;
+ info->lm_pwd_present = 0;
+ info->pwd_expired = 0;
+ info->country = 0;
+ info->codepage = 0;
+
+ info->unknown1 = 0x4EC;
+ info->unknown2 = 0;
+
+ copy_unistr2(&(info->uni_acct_name ), user_name);
+ copy_unistr2(&(info->uni_full_name ), full_name);
+ copy_unistr2(&(info->uni_home_dir ), home_dir );
+ copy_unistr2(&(info->uni_dir_drive ), dir_drive);
+ copy_unistr2(&(info->uni_logon_script), log_scr );
+ copy_unistr2(&(info->uni_profile ), prof_path);
+ copy_unistr2(&(info->uni_acct_desc ), desc );
+ copy_unistr2(&(info->uni_workstations), wkstas );
+ copy_unistr2(&(info->uni_comment ), unk_str );
+ copy_unistr2(&(info->uni_parameters ), mung_dial);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_passwd_info(char *desc, SAM_PWD *pwd,
+ prs_struct *ps, int depth)
+{
+ if (pwd == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_sam_passwd_info");
+ depth++;
+
+ prs_uint32("unk_0 ", ps, depth, &(pwd->unk_0 ));
+
+ smb_io_unihdr ("hdr_lm_pwd", &(pwd->hdr_lm_pwd), ps, depth);
+ prs_uint8s(False, "buf_lm_pwd", ps, depth, pwd->buf_lm_pwd, 16);
- if(!prs_uint32("buffer_creds", ps, depth, &r_l->buffer_creds)) /* undocumented buffer pointer */
- return False;
- if(!smb_io_cred("", &r_l->srv_creds, ps, depth)) /* server credentials. server time stamp appears to be ignored. */
- return False;
+ smb_io_unihdr ("hdr_nt_pwd", &(pwd->hdr_nt_pwd), ps, depth);
+ prs_uint8s(False, "buf_nt_pwd", ps, depth, pwd->buf_nt_pwd, 16);
+
+ smb_io_unihdr("", &(pwd->hdr_empty_lm), ps, depth);
+ smb_io_unihdr("", &(pwd->hdr_empty_nt), ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_account_info(char *desc, uint8 sess_key[16],
+ SAM_ACCOUNT_INFO *info, prs_struct *ps, int depth)
+{
+ BUFHDR2 hdr_priv_data;
+ uint32 i;
+
+ if (info == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_sam_account_info");
+ depth++;
+
+ smb_io_unihdr("hdr_acct_name", &(info->hdr_acct_name), ps, depth);
+ smb_io_unihdr("hdr_full_name", &(info->hdr_full_name), ps, depth);
+
+ prs_uint32("user_rid ", ps, depth, &(info->user_rid ));
+ prs_uint32("group_rid", ps, depth, &(info->group_rid));
+
+ smb_io_unihdr("hdr_home_dir " , &(info->hdr_home_dir ), ps, depth);
+ smb_io_unihdr("hdr_dir_drive" , &(info->hdr_dir_drive), ps, depth);
+ smb_io_unihdr("hdr_logon_script", &(info->hdr_logon_script), ps, depth);
+ smb_io_unihdr("hdr_acct_desc" , &(info->hdr_acct_desc), ps, depth);
+ smb_io_unihdr("hdr_workstations", &(info->hdr_workstations), ps, depth);
+
+ smb_io_time("logon_time" , &(info->logon_time ), ps, depth);
+ smb_io_time("logoff_time", &(info->logoff_time), ps, depth);
+
+ prs_uint32("logon_divs ", ps, depth, &(info->logon_divs ));
+ prs_uint32("ptr_logon_hrs", ps, depth, &(info->ptr_logon_hrs));
+
+ prs_uint16("bad_pwd_count", ps, depth, &(info->bad_pwd_count));
+ prs_uint16("logon_count" , ps, depth, &(info->logon_count ));
+ smb_io_time("pwd_last_set_time", &(info->pwd_last_set_time), ps, depth);
+ smb_io_time("acct_expiry_time" , &(info->acct_expiry_time ), ps, depth);
+
+ prs_uint32("acb_info", ps, depth, &(info->acb_info));
+ prs_uint8s(False, "nt_pwd", ps, depth, info->nt_pwd, 16);
+ prs_uint8s(False, "lm_pwd", ps, depth, info->lm_pwd, 16);
+ prs_uint8("lm_pwd_present", ps, depth, &(info->lm_pwd_present));
+ prs_uint8("nt_pwd_present", ps, depth, &(info->nt_pwd_present));
+ prs_uint8("pwd_expired" , ps, depth, &(info->pwd_expired ));
+
+ smb_io_unihdr("hdr_comment" , &(info->hdr_comment ), ps, depth);
+ smb_io_unihdr("hdr_parameters", &(info->hdr_parameters), ps, depth);
+ prs_uint16("country" , ps, depth, &(info->country ));
+ prs_uint16("codepage", ps, depth, &(info->codepage));
+
+ smb_io_bufhdr2("hdr_priv_data", &(hdr_priv_data), ps, depth);
+ smb_io_bufhdr2("hdr_sec_desc" , &(info->hdr_sec_desc) , ps, depth);
+ smb_io_unihdr ("hdr_profile" , &(info->hdr_profile) , ps, depth);
+
+ for (i = 0; i < 3; i++)
+ {
+ smb_io_unihdr("hdr_reserved", &(info->hdr_reserved[i]), ps, depth);
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ prs_uint32("dw_reserved", ps, depth, &(info->dw_reserved[i]));
+ }
+
+ smb_io_unistr2("uni_acct_name", &(info->uni_acct_name),
+ info->hdr_acct_name.buffer, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_full_name", &(info->uni_full_name),
+ info->hdr_full_name.buffer, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_home_dir ", &(info->uni_home_dir ),
+ info->hdr_home_dir .buffer, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_dir_drive", &(info->uni_dir_drive),
+ info->hdr_dir_drive.buffer, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_logon_script", &(info->uni_logon_script),
+ info->hdr_logon_script.buffer, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_acct_desc", &(info->uni_acct_desc),
+ info->hdr_acct_desc.buffer, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_workstations", &(info->uni_workstations),
+ info->hdr_workstations.buffer, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("unknown1", ps, depth, &(info->unknown1));
+ prs_uint32("unknown2", ps, depth, &(info->unknown2));
+
+ smb_io_buffer4("buf_logon_hrs" , &(info->buf_logon_hrs ),
+ info->ptr_logon_hrs, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_comment" , &(info->uni_comment ),
+ info->hdr_comment.buffer, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_parameters", &(info->uni_parameters),
+ info->hdr_parameters.buffer, ps, depth);
+ prs_align(ps);
+ if (hdr_priv_data.buffer != 0)
+ {
+ int old_offset;
+ uint32 len = 0x44;
+ prs_uint32("pwd_len", ps, depth, &len);
+ old_offset = ps->offset;
+ if (len == 0x44)
+ {
+ if (ps->io)
+ {
+ /* reading */
+ prs_hash1(ps, ps->offset, sess_key);
+ }
+ net_io_sam_passwd_info("pass", &(info->pass), ps, depth);
+ if (!ps->io)
+ {
+ /* writing */
+ prs_hash1(ps, old_offset, sess_key);
+ }
+ }
+ ps->offset = old_offset + len;
+ }
+ smb_io_buffer4("buf_sec_desc" , &(info->buf_sec_desc ),
+ info->hdr_sec_desc.buffer, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_profile" , &(info->uni_profile ),
+ info->hdr_profile.buffer, ps, depth);
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_group_mem_info(char *desc, SAM_GROUP_MEM_INFO *info, prs_struct *ps, int depth)
+{
+ uint32 i;
+ fstring tmp;
+
+ if (info == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_sam_group_mem_info");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("ptr_rids ", ps, depth, &(info->ptr_rids ));
+ prs_uint32("ptr_attribs", ps, depth, &(info->ptr_attribs));
+ prs_uint32("num_members", ps, depth, &(info->num_members));
+ ps->offset += 16;
+
+ if (info->ptr_rids != 0)
+ {
+ prs_uint32("num_members2", ps, depth, &(info->num_members2));
+ if (info->num_members2 != info->num_members)
+ {
+ /* RPC fault */
+ return False;
+ }
+
+ SMB_ASSERT_ARRAY(info->rids, info->num_members2);
+
+ for (i = 0; i < info->num_members2; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "rids[%02d]", i);
+ prs_uint32(tmp, ps, depth, &(info->rids[i]));
+ }
+ }
+
+ if (info->ptr_attribs != 0)
+ {
+ prs_uint32("num_members3", ps, depth, &(info->num_members3));
+ if (info->num_members3 != info->num_members)
+ {
+ /* RPC fault */
+ return False;
+ }
+
+ SMB_ASSERT_ARRAY(info->attribs, info->num_members3);
+
+ for (i = 0; i < info->num_members3; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "attribs[%02d]", i);
+ prs_uint32(tmp, ps, depth, &(info->attribs[i]));
+ }
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_alias_info(char *desc, SAM_ALIAS_INFO *info, prs_struct *ps, int depth)
+{
+ if (info == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_sam_alias_info");
+ depth++;
+
+ smb_io_unihdr ("hdr_als_name", &(info->hdr_als_name), ps, depth);
+ prs_uint32("als_rid", ps, depth, &(info->als_rid));
+ smb_io_bufhdr2("hdr_sec_desc", &(info->hdr_sec_desc), ps, depth);
+ smb_io_unihdr ("hdr_als_desc", &(info->hdr_als_desc), ps, depth);
+ ps->offset += 40;
+
+ smb_io_unistr2("uni_als_name", &(info->uni_als_name),
+ info->hdr_als_name.buffer, ps, depth);
+ smb_io_buffer4("buf_sec_desc", &(info->buf_sec_desc),
+ info->hdr_sec_desc.buffer, ps, depth);
+ smb_io_unistr2("uni_als_desc", &(info->uni_als_desc),
+ info->hdr_als_name.buffer, ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_alias_mem_info(char *desc, SAM_ALIAS_MEM_INFO *info, prs_struct *ps, int depth)
+{
+ uint32 i;
+ fstring tmp;
+
+ if (info == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_sam_alias_mem_info");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("num_members", ps, depth, &(info->num_members));
+ prs_uint32("ptr_members", ps, depth, &(info->ptr_members));
+ ps->offset += 16;
+
+ if (info->ptr_members != 0)
+ {
+ prs_uint32("num_sids", ps, depth, &(info->num_sids));
+ if (info->num_sids != info->num_members)
+ {
+ /* RPC fault */
+ return False;
+ }
+
+ SMB_ASSERT_ARRAY(info->ptr_sids, info->num_sids);
+
+ for (i = 0; i < info->num_sids; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "ptr_sids[%02d]", i);
+ prs_uint32(tmp, ps, depth, &(info->ptr_sids[i]));
+ }
+
+ SMB_ASSERT_ARRAY(info->sids, info->num_sids);
+
+ for (i = 0; i < info->num_sids; i++)
+ {
+ if (info->ptr_sids[i] != 0)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "sids[%02d]", i);
+ smb_io_dom_sid2(tmp, &(info->sids[i]), ps, depth);
+ }
+ }
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL net_io_sam_delta_ctr(char *desc, uint8 sess_key[16],
+ SAM_DELTA_CTR *delta, uint16 type,
+ prs_struct *ps, int depth)
+{
+ if (delta == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_sam_delta_ctr");
+ depth++;
+
+ switch (type)
+ {
+ case 1:
+ {
+ net_io_sam_domain_info("", &(delta->domain_info),
+ ps, depth);
+ break;
+ }
+ case 2:
+ {
+ net_io_sam_group_info("", &(delta->group_info),
+ ps, depth);
+ break;
+ }
+ case 5:
+ {
+ net_io_sam_account_info("", sess_key,
+ &(delta->account_info),
+ ps, depth);
+ break;
+ }
+ case 8:
+ {
+ net_io_sam_group_mem_info("", &(delta->grp_mem_info),
+ ps, depth);
+ break;
+ }
+ case 9:
+ {
+ net_io_sam_alias_info("", &(delta->alias_info),
+ ps, depth);
+ break;
+ }
+ case 0xC:
+ {
+ net_io_sam_alias_mem_info("", &(delta->als_mem_info),
+ ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(0, ("Replication error: Unknown delta type %x\n", type));
+ break;
+ }
+ }
+
+ return True;
+}
+
+/*******************************************************************
+makes a NET_R_SAM_SYNC structure.
+********************************************************************/
+BOOL make_r_sam_sync(NET_R_SAM_SYNC *r_s,
+ const DOM_CRED *srv_cred,
+ uint32 sync_context,
+ uint32 num_deltas,
+ uint32 num_deltas2,
+ SAM_DELTA_HDR *hdr_deltas,
+ SAM_DELTA_CTR *deltas,
+ uint32 status)
+{
+ if (r_s == NULL) return False;
+
+ memcpy(&(r_s->srv_creds), srv_cred, sizeof(r_s->srv_creds));
+ r_s->sync_context = sync_context;
+ r_s->num_deltas = num_deltas;
+ r_s->num_deltas2 = num_deltas2;
+ r_s->hdr_deltas = hdr_deltas;
+ r_s->deltas = deltas;
+ r_s->status = status;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL net_io_r_sam_sync(char *desc, uint8 sess_key[16],
+ NET_R_SAM_SYNC *r_s, prs_struct *ps, int depth)
+{
+ uint32 i;
+
+ if (r_s == NULL) return False;
+
+ prs_debug(ps, depth, desc, "net_io_r_sam_sync");
+ depth++;
+
+ smb_io_cred("", &(r_s->srv_creds), ps, depth);
+ prs_uint32("sync_context", ps, depth, &(r_s->sync_context));
+
+ prs_uint32("ptr_deltas", ps, depth, &(r_s->ptr_deltas));
+ if (r_s->ptr_deltas != 0)
+ {
+ prs_uint32("num_deltas ", ps, depth, &(r_s->num_deltas ));
+ prs_uint32("ptr_deltas2", ps, depth, &(r_s->ptr_deltas2));
+ if (r_s->ptr_deltas2 != 0)
+ {
+ prs_uint32("num_deltas2", ps, depth, &(r_s->num_deltas2));
+ if (r_s->num_deltas2 != r_s->num_deltas)
+ {
+ /* RPC fault */
+ return False;
+ }
+
+ for (i = 0; i < r_s->num_deltas2; i++)
+ {
+ net_io_sam_delta_hdr("", &r_s->hdr_deltas[i], ps, depth);
+ }
+
+ for (i = 0; i < r_s->num_deltas2; i++)
+ {
+ net_io_sam_delta_ctr("", sess_key,
+ &r_s->deltas[i],
+ r_s->hdr_deltas[i].type3, ps, depth);
+ }
+ }
+ }
- if(!prs_uint32("status ", ps, depth, &r_l->status))
- return False;
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_s->status));
return True;
}
diff --git a/source/rpc_parse/parse_netsec.c b/source/rpc_parse/parse_netsec.c
new file mode 100644
index 00000000000..43ad697afa5
--- /dev/null
+++ b/source/rpc_parse/parse_netsec.c
@@ -0,0 +1,351 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+checks an RPC_HDR_AUTH structure.
+********************************************************************/
+BOOL rpc_hdr_netsec_auth_chk(RPC_HDR_AUTH *rai)
+{
+ return (rai->auth_type == 0x44 && rai->auth_level == 0x06);
+}
+
+/*******************************************************************
+creates an RPC_AUTH_NETSEC_NEG structure.
+********************************************************************/
+BOOL make_rpc_auth_netsec_neg(RPC_AUTH_NETSEC_NEG *neg,
+ fstring domain,
+ fstring myname)
+{
+ if (neg == NULL) return False;
+
+ fstrcpy(neg->domain, domain);
+ fstrcpy(neg->myname, myname);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an RPC_AUTH_NETSEC_NEG structure.
+
+*** lkclXXXX HACK ALERT! ***
+
+********************************************************************/
+BOOL smb_io_rpc_auth_netsec_neg(char *desc, RPC_AUTH_NETSEC_NEG *neg, prs_struct *ps, int depth)
+{
+ if (neg == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_neg");
+ depth++;
+
+ prs_string("domain", ps, depth, neg->domain, 0, sizeof(neg->domain));
+ prs_string("myname", ps, depth, neg->myname, 0, sizeof(neg->myname));
+
+ return True;
+}
+
+/*******************************************************************
+creates an RPC_AUTH_NETSEC_RESP structure.
+
+*** lkclXXXX FUDGE! HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
+*** lkclXXXX the actual offset is at the start of the auth verifier ***
+
+********************************************************************/
+BOOL make_rpc_auth_netsec_resp(RPC_AUTH_NETSEC_RESP *rsp, uint32 flags)
+{
+ DEBUG(5,("make_rpc_auth_netsec_resp\n"));
+
+ if (rsp == NULL) return False;
+
+ rsp->flags = flags;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an RPC_AUTH_NETSEC_RESP structure.
+
+*** lkclXXXX FUDGE! HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
+*** lkclXXXX the actual offset is at the start of the auth verifier ***
+
+********************************************************************/
+BOOL smb_io_rpc_auth_netsec_resp(char *desc, RPC_AUTH_NETSEC_RESP *rsp, prs_struct *ps, int depth)
+{
+ if (rsp == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_resp");
+ depth++;
+
+ prs_uint32("flags", ps, depth, &rsp->flags);
+
+ return True;
+}
+
+/*******************************************************************
+checks an RPC_AUTH_NETSEC_CHK structure.
+********************************************************************/
+BOOL rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk)
+{
+ static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
+
+ if (chk == NULL)
+ {
+ return False;
+ }
+
+ if (memcmp(chk, netsec_sig, 8) != 0)
+ {
+ return False;
+ }
+ return True;
+}
+
+/*******************************************************************
+creates an RPC_AUTH_NETSEC_CHK structure.
+********************************************************************/
+BOOL make_rpc_auth_netsec_chk(RPC_AUTH_NETSEC_CHK *chk,
+ const uchar sig[8],
+ const uchar data1[8],
+ const uchar data3[8],
+ const uchar data8[8])
+{
+ if (chk == NULL) return False;
+
+ if (sig != NULL)
+ {
+ memcpy(chk->sig , sig , sizeof(chk->sig ));
+ }
+ if (data1 != NULL)
+ {
+ memcpy(chk->data1, data1, sizeof(chk->data1));
+ }
+ if (data3 != NULL)
+ {
+ memcpy(chk->data3, data3, sizeof(chk->data3));
+ }
+ if (data8 != NULL)
+ {
+ memcpy(chk->data8, data8, sizeof(chk->data8));
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an RPC_AUTH_NETSEC_CHK structure.
+********************************************************************/
+BOOL smb_io_rpc_auth_netsec_chk(char *desc, RPC_AUTH_NETSEC_CHK *chk, prs_struct *ps, int depth)
+{
+ if (chk == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_chk");
+ depth++;
+
+ prs_uint8s(False, "sig ", ps, depth, chk->sig , sizeof(chk->sig ));
+ prs_uint8s(False, "data3", ps, depth, chk->data3, sizeof(chk->data3));
+ prs_uint8s(False, "data1", ps, depth, chk->data1, sizeof(chk->data1));
+ prs_uint8s(False, "data8", ps, depth, chk->data8, sizeof(chk->data8));
+
+ return True;
+}
+
+static void netsechash(uchar *key, uchar *data, int data_len)
+{
+ uchar hash[256];
+ uchar index_i = 0;
+ uchar index_j = 0;
+ uchar j = 0;
+ int ind;
+
+ for (ind = 0; ind < 256; ind++)
+ {
+ hash[ind] = (uchar)ind;
+ }
+
+ for( ind = 0; ind < 256; ind++)
+ {
+ uchar tc;
+
+ j += (hash[ind] + key[ind%16]);
+
+ tc = hash[ind];
+ hash[ind] = hash[j];
+ hash[j] = tc;
+ }
+
+ for( ind = 0; ind < data_len; ind++)
+ {
+ uchar tc;
+ uchar t;
+
+ index_i++;
+ index_j += hash[index_i];
+
+ tc = hash[index_i];
+ hash[index_i] = hash[index_j];
+ hash[index_j] = tc;
+
+ t = hash[index_i] + hash[index_j];
+ data[ind] ^= hash[t];
+ }
+}
+
+
+BOOL netsec_encode(struct netsec_auth_struct *a,
+ RPC_AUTH_NETSEC_CHK *verf,
+ char *data, size_t data_len)
+{
+ char dataN[4];
+ char digest1[16];
+ struct MD5Context ctx3;
+ uchar sess_kf0[16];
+ int i;
+
+ /* store the sequence number */
+ SIVAL(dataN, 0, a->seq_num);
+
+ for (i = 0; i < sizeof(sess_kf0); i++)
+ {
+ sess_kf0[i] = a->sess_key[i] ^ 0xf0;
+ }
+
+ dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
+ dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN));
+
+ MD5Init(&ctx3);
+ MD5Update(&ctx3, dataN, 0x4);
+ MD5Update(&ctx3, verf->sig, 8);
+
+ MD5Update(&ctx3, verf->data8, 8);
+
+ dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
+ dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
+
+ hmac_md5(sess_kf0, dataN, 0x4, digest1 );
+ dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1));
+ hmac_md5(digest1, verf->data3, 8, digest1);
+ dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
+ netsechash(digest1, verf->data8, 8);
+
+ dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
+
+ dump_data_pw("data :\n", data, data_len);
+ MD5Update(&ctx3, data, data_len);
+
+ {
+ char digest_tmp[16];
+ char digest2[16];
+ MD5Final(digest_tmp, &ctx3);
+ hmac_md5(a->sess_key, digest_tmp, 16, digest2);
+ dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp));
+ dump_data_pw("digest:\n", digest2, sizeof(digest2));
+ memcpy(verf->data1, digest2, sizeof(verf->data1));
+ }
+
+ netsechash(digest1, data , data_len);
+ dump_data_pw("data:\n", data, data_len);
+
+ hmac_md5(a->sess_key, dataN , 0x4, digest1 );
+ dump_data_pw("ctx:\n", digest1, sizeof(digest1));
+
+ hmac_md5(digest1, verf->data1, 8, digest1);
+
+ dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
+
+ dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3));
+ netsechash(digest1, verf->data3, 8);
+ dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3));
+
+
+ return True;
+}
+
+BOOL netsec_decode(struct netsec_auth_struct *a,
+ RPC_AUTH_NETSEC_CHK *verf,
+ char *data, size_t data_len)
+{
+ char dataN[4];
+ char digest1[16];
+ struct MD5Context ctx3;
+ uchar sess_kf0[16];
+ int i;
+
+ /* store the sequence number */
+ SIVAL(dataN, 0, a->seq_num);
+
+ for (i = 0; i < sizeof(sess_kf0); i++)
+ {
+ sess_kf0[i] = a->sess_key[i] ^ 0xf0;
+ }
+
+ dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key));
+ dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN));
+ hmac_md5(a->sess_key, dataN , 0x4, digest1 );
+ dump_data_pw("ctx:\n", digest1, sizeof(digest1));
+
+ hmac_md5(digest1, verf->data1, 8, digest1);
+
+ dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
+ dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3));
+ netsechash(digest1, verf->data3, 8);
+ dump_data_pw("verf->data3_dec:\n", verf->data3, sizeof(verf->data3));
+
+ MD5Init(&ctx3);
+ MD5Update(&ctx3, dataN, 0x4);
+ MD5Update(&ctx3, verf->sig, 8);
+
+ dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0));
+
+ hmac_md5(sess_kf0, dataN, 0x4, digest1 );
+ dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1));
+ hmac_md5(digest1, verf->data3, 8, digest1);
+ dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1));
+
+ dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8));
+ netsechash(digest1, verf->data8, 8);
+ dump_data_pw("verf->data8_dec:\n", verf->data8, sizeof(verf->data8));
+ MD5Update(&ctx3, verf->data8, 8);
+
+ dump_data_pw("data :\n", data, data_len);
+ netsechash(digest1, data , data_len);
+ dump_data_pw("datadec:\n", data, data_len);
+
+ MD5Update(&ctx3, data, data_len);
+ {
+ char digest_tmp[16];
+ MD5Final(digest_tmp, &ctx3);
+ hmac_md5(a->sess_key, digest_tmp, 16, digest1);
+ dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp));
+ }
+
+ dump_data_pw("digest:\n", digest1, sizeof(digest1));
+ dump_data_pw("verf->data1:\n", verf->data1, sizeof(verf->data1));
+
+ return memcmp(digest1, verf->data1, sizeof(verf->data1)) == 0;
+}
diff --git a/source/rpc_parse/parse_ntlmssp.c b/source/rpc_parse/parse_ntlmssp.c
new file mode 100644
index 00000000000..bf102f84455
--- /dev/null
+++ b/source/rpc_parse/parse_ntlmssp.c
@@ -0,0 +1,394 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+checks an RPC_HDR_AUTH structure.
+********************************************************************/
+BOOL rpc_hdr_ntlmssp_auth_chk(RPC_HDR_AUTH *rai)
+{
+ return (rai->auth_type == 0x0a && rai->auth_level == 0x06);
+}
+
+/*******************************************************************
+creates an RPC_AUTH_NTLMSSP_NEG structure.
+********************************************************************/
+BOOL make_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
+ uint32 neg_flgs,
+ fstring myname, fstring domain)
+{
+ int len_myname = strlen(myname);
+ int len_domain = strlen(domain);
+
+ if (neg == NULL) return False;
+
+ neg->neg_flgs = neg_flgs ; /* 0x00b2b3 */
+
+ make_str_hdr(&neg->hdr_domain, len_domain, len_domain, 0x20 + len_myname);
+ make_str_hdr(&neg->hdr_myname, len_myname, len_myname, 0x20);
+
+ fstrcpy(neg->myname, myname);
+ fstrcpy(neg->domain, domain);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an RPC_AUTH_NTLMSSP_NEG structure.
+
+*** lkclXXXX HACK ALERT! ***
+
+********************************************************************/
+BOOL smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth)
+{
+ int start_offset = ps->offset;
+ if (neg == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_neg");
+ depth++;
+
+ prs_uint32("neg_flgs ", ps, depth, &(neg->neg_flgs));
+
+ if (ps->io)
+ {
+ uint32 old_offset;
+
+ /* reading */
+
+ ZERO_STRUCTP(neg);
+
+ smb_io_strhdr("hdr_domain", &(neg->hdr_domain), ps, depth);
+ smb_io_strhdr("hdr_myname", &(neg->hdr_myname), ps, depth);
+
+ old_offset = ps->offset;
+
+ ps->offset = neg->hdr_myname .buffer + start_offset - 12;
+ prs_uint8s(True , "myname", ps, depth, (uint8*)neg->myname , MIN(neg->hdr_myname .str_str_len, sizeof(neg->myname )));
+ old_offset += neg->hdr_myname .str_str_len;
+
+ ps->offset = neg->hdr_domain .buffer + start_offset - 12;
+ prs_uint8s(True , "domain", ps, depth, (uint8*)neg->domain , MIN(neg->hdr_domain .str_str_len, sizeof(neg->domain )));
+ old_offset += neg->hdr_domain .str_str_len;
+
+ ps->offset = old_offset;
+ }
+ else
+ {
+ /* writing */
+ smb_io_strhdr("hdr_domain", &(neg->hdr_domain), ps, depth);
+ smb_io_strhdr("hdr_myname", &(neg->hdr_myname), ps, depth);
+
+ prs_uint8s(True , "myname", ps, depth, (uint8*)neg->myname , MIN(neg->hdr_myname .str_str_len, sizeof(neg->myname )));
+ prs_uint8s(True , "domain", ps, depth, (uint8*)neg->domain , MIN(neg->hdr_domain .str_str_len, sizeof(neg->domain )));
+ }
+
+ return True;
+}
+
+/*******************************************************************
+creates an RPC_AUTH_NTLMSSP_CHAL structure.
+********************************************************************/
+BOOL make_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
+ uint32 neg_flags,
+ uint8 challenge[8])
+{
+ if (chl == NULL) return False;
+
+ chl->unknown_1 = 0x0;
+ chl->unknown_2 = 0x00000028;
+ chl->neg_flags = neg_flags; /* 0x0082b1 */
+
+ memcpy(chl->challenge, challenge, sizeof(chl->challenge));
+ bzero (chl->reserved , sizeof(chl->reserved));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an RPC_AUTH_NTLMSSP_CHAL structure.
+********************************************************************/
+BOOL smb_io_rpc_auth_ntlmssp_chal(char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth)
+{
+ if (chl == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_chal");
+ depth++;
+
+ prs_uint32("unknown_1", ps, depth, &(chl->unknown_1)); /* 0x0000 0000 */
+ prs_uint32("unknown_2", ps, depth, &(chl->unknown_2)); /* 0x0000 b2b3 */
+ prs_uint32("neg_flags", ps, depth, &(chl->neg_flags)); /* 0x0000 82b1 */
+
+ prs_uint8s (False, "challenge", ps, depth, chl->challenge, sizeof(chl->challenge));
+ prs_uint8s (False, "reserved ", ps, depth, chl->reserved , sizeof(chl->reserved ));
+
+ return True;
+}
+
+/*******************************************************************
+creates an RPC_AUTH_NTLMSSP_RESP structure.
+
+*** lkclXXXX FUDGE! HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
+*** lkclXXXX the actual offset is at the start of the auth verifier ***
+
+********************************************************************/
+BOOL make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
+ uchar lm_resp[24],
+ uchar *nt_resp, size_t nt_len,
+ char *domain, char *user, char *wks,
+ uint32 neg_flags)
+{
+ uint32 offset;
+ int dom_len = strlen(domain);
+ int wks_len = strlen(wks );
+ int usr_len = strlen(user );
+ int lm_len = nt_len != 0 ? (lm_resp != NULL ? 24 : 0) : 1;
+
+ DEBUG(5,("make_rpc_auth_ntlmssp_resp\n"));
+
+ if (rsp == NULL) return False;
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("lm_resp\n"));
+ if (lm_resp != NULL)
+ {
+ dump_data(100, lm_resp, lm_len);
+ }
+ DEBUG(100,("nt_resp\n"));
+ if (nt_resp != NULL)
+ {
+ dump_data(100, nt_resp, nt_len);
+ }
+#endif
+
+ DEBUG(6,("dom: %s user: %s wks: %s neg_flgs: 0x%x\n",
+ domain, user, wks, neg_flags));
+
+ offset = 0x40;
+
+ if (IS_BITS_SET_ALL(neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
+ {
+ dom_len *= 2;
+ wks_len *= 2;
+ usr_len *= 2;
+ }
+
+ make_str_hdr(&rsp->hdr_domain , dom_len, dom_len, offset);
+ offset += dom_len;
+
+ make_str_hdr(&rsp->hdr_usr , usr_len, usr_len, offset);
+ offset += usr_len;
+
+ make_str_hdr(&rsp->hdr_wks , wks_len, wks_len, offset);
+ offset += wks_len;
+
+ make_str_hdr(&rsp->hdr_lm_resp, lm_len , lm_len , offset);
+ offset += lm_len;
+
+ make_str_hdr(&rsp->hdr_nt_resp, nt_len , nt_len , offset);
+ offset += nt_len;
+
+ make_str_hdr(&rsp->hdr_sess_key, 0, 0, offset);
+
+ rsp->neg_flags = neg_flags;
+
+ if (lm_resp != NULL && lm_len != 1)
+ {
+ memcpy(rsp->lm_resp, lm_resp, lm_len);
+ }
+ else
+ {
+ rsp->lm_resp[0] = 0;
+ }
+ if (nt_resp != NULL)
+ {
+ memcpy(rsp->nt_resp, nt_resp, nt_len);
+ }
+ else
+ {
+ rsp->nt_resp[0] = 0;
+ }
+
+ if (IS_BITS_SET_ALL(neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
+ {
+ ascii_to_unibuf(rsp->domain, domain, sizeof(rsp->domain)-2);
+ ascii_to_unibuf(rsp->user , user , sizeof(rsp->user )-2);
+ ascii_to_unibuf(rsp->wks , wks , sizeof(rsp->wks )-2);
+ }
+ else
+ {
+ fstrcpy(rsp->domain, domain);
+ fstrcpy(rsp->user , user );
+ fstrcpy(rsp->wks , wks );
+ }
+ rsp->sess_key[0] = 0;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an RPC_AUTH_NTLMSSP_RESP structure.
+
+*** lkclXXXX FUDGE! HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
+*** lkclXXXX the actual offset is at the start of the auth verifier ***
+
+********************************************************************/
+BOOL smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth)
+{
+ if (rsp == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_resp");
+ depth++;
+
+ if (ps->io)
+ {
+ uint32 old_offset;
+
+ /* reading */
+
+ ZERO_STRUCTP(rsp);
+
+ smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp , ps, depth);
+ smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp , ps, depth);
+ smb_io_strhdr("hdr_domain ", &rsp->hdr_domain , ps, depth);
+ smb_io_strhdr("hdr_user ", &rsp->hdr_usr , ps, depth);
+ smb_io_strhdr("hdr_wks ", &rsp->hdr_wks , ps, depth);
+ smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth);
+
+ prs_uint32("neg_flags", ps, depth, &(rsp->neg_flags)); /* 0x0000 82b1 */
+
+ old_offset = ps->offset;
+
+ ps->offset = rsp->hdr_domain .buffer + 0xc;
+ prs_uint8s(True , "domain ", ps, depth, (uint8*)rsp->domain , MIN(rsp->hdr_domain .str_str_len, sizeof(rsp->domain )));
+ old_offset += rsp->hdr_domain .str_str_len;
+
+ ps->offset = rsp->hdr_usr .buffer + 0xc;
+ prs_uint8s(True , "user ", ps, depth, (uint8*)rsp->user , MIN(rsp->hdr_usr .str_str_len, sizeof(rsp->user )));
+ old_offset += rsp->hdr_usr .str_str_len;
+
+ ps->offset = rsp->hdr_wks .buffer + 0xc;
+ prs_uint8s(True , "wks ", ps, depth, (uint8*)rsp->wks , MIN(rsp->hdr_wks .str_str_len, sizeof(rsp->wks )));
+ old_offset += rsp->hdr_wks .str_str_len;
+
+ ps->offset = rsp->hdr_lm_resp .buffer + 0xc;
+ prs_uint8s(False, "lm_resp ", ps, depth, (uint8*)rsp->lm_resp , MIN(rsp->hdr_lm_resp .str_str_len, sizeof(rsp->lm_resp )));
+ old_offset += rsp->hdr_lm_resp .str_str_len;
+
+ ps->offset = rsp->hdr_nt_resp .buffer + 0xc;
+ prs_uint8s(False, "nt_resp ", ps, depth, (uint8*)rsp->nt_resp , MIN(rsp->hdr_nt_resp .str_str_len, sizeof(rsp->nt_resp )));
+ old_offset += rsp->hdr_nt_resp .str_str_len;
+
+ if (rsp->hdr_sess_key.str_str_len != 0)
+ {
+ ps->offset = rsp->hdr_sess_key.buffer + 0x10;
+ old_offset += rsp->hdr_sess_key.str_str_len;
+ prs_uint8s(False, "sess_key", ps, depth, (uint8*)rsp->sess_key, MIN(rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key)));
+ }
+
+ ps->offset = old_offset;
+ }
+ else
+ {
+ /* writing */
+ smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp , ps, depth);
+ smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp , ps, depth);
+ smb_io_strhdr("hdr_domain ", &rsp->hdr_domain , ps, depth);
+ smb_io_strhdr("hdr_user ", &rsp->hdr_usr , ps, depth);
+ smb_io_strhdr("hdr_wks ", &rsp->hdr_wks , ps, depth);
+ smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth);
+
+ prs_uint32("neg_flags", ps, depth, &(rsp->neg_flags)); /* 0x0000 82b1 */
+
+ prs_uint8s(True , "domain ", ps, depth, (uint8*)rsp->domain , MIN(rsp->hdr_domain .str_str_len, sizeof(rsp->domain )));
+ prs_uint8s(True , "user ", ps, depth, (uint8*)rsp->user , MIN(rsp->hdr_usr .str_str_len, sizeof(rsp->user )));
+ prs_uint8s(True , "wks ", ps, depth, (uint8*)rsp->wks , MIN(rsp->hdr_wks .str_str_len, sizeof(rsp->wks )));
+ prs_uint8s(False, "lm_resp ", ps, depth, (uint8*)rsp->lm_resp , MIN(rsp->hdr_lm_resp .str_str_len, sizeof(rsp->lm_resp )));
+ prs_uint8s(False, "nt_resp ", ps, depth, (uint8*)rsp->nt_resp , MIN(rsp->hdr_nt_resp .str_str_len, sizeof(rsp->nt_resp )));
+ prs_uint8s(False, "sess_key", ps, depth, (uint8*)rsp->sess_key, MIN(rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key)));
+ }
+
+ return True;
+}
+
+/*******************************************************************
+checks an RPC_AUTH_NTLMSSP_CHK structure.
+********************************************************************/
+BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_num)
+{
+ if (chk == NULL)
+ {
+ return False;
+ }
+
+ if (chk->crc32 != crc32 ||
+ chk->ver != NTLMSSP_SIGN_VERSION ||
+ chk->seq_num != seq_num)
+ {
+ DEBUG(5,("verify failed - crc %x ver %x seq %d\n",
+ crc32, NTLMSSP_SIGN_VERSION, seq_num));
+ DEBUG(5,("verify expect - crc %x ver %x seq %d\n",
+ chk->crc32, chk->ver, chk->seq_num));
+ return False;
+ }
+ return True;
+}
+
+/*******************************************************************
+creates an RPC_AUTH_NTLMSSP_CHK structure.
+********************************************************************/
+BOOL make_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
+ uint32 ver, uint32 crc32, uint32 seq_num)
+{
+ if (chk == NULL) return False;
+
+ chk->ver = ver ;
+ chk->reserved = 0x0;
+ chk->crc32 = crc32 ;
+ chk->seq_num = seq_num ;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes an RPC_AUTH_NTLMSSP_CHK structure.
+********************************************************************/
+BOOL smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth)
+{
+ if (chk == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_chk");
+ depth++;
+
+ prs_uint32("ver ", ps, depth, &(chk->ver ));
+ prs_uint32("reserved", ps, depth, &(chk->reserved));
+ prs_uint32("crc32 ", ps, depth, &(chk->crc32 ));
+ prs_uint32("seq_num ", ps, depth, &(chk->seq_num ));
+
+ return True;
+}
+
diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c
index 5d0ea832c80..49481f7f2e7 100644
--- a/source/rpc_parse/parse_prs.c
+++ b/source/rpc_parse/parse_prs.c
@@ -2,9 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
Samba memory buffer functions
- Copyright (C) Andrew Tridgell 1992-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
- Copyright (C) Jeremy Allison 1999.
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -28,642 +27,963 @@ extern int DEBUGLEVEL;
/*******************************************************************
debug output for parsing info.
-
- XXXX side-effect of this function is to increase the debug depth XXXX
-
********************************************************************/
-void prs_debug(prs_struct *ps, int depth, char *desc, char *fn_name)
+void prs_debug(prs_struct *ps, int depth, const char *desc, const char *fn_name)
{
- DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc));
+ CHECK_STRUCT(ps);
+ DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->offset, fn_name, desc));
}
/*******************************************************************
- Initialise a parse structure - malloc the data if requested.
+ debug a parse structure
********************************************************************/
-
-BOOL prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io)
+void prs_debug_out(const prs_struct *ps, char *msg, int level)
{
- ZERO_STRUCTP(ps);
- ps->io = io;
- ps->bigendian_data = False;
- ps->align = align;
- ps->is_dynamic = False;
- ps->data_offset = 0;
- ps->buffer_size = 0;
- ps->data_p = NULL;
-
- if (size != 0) {
- ps->buffer_size = size;
- if((ps->data_p = (char *)malloc((size_t)size)) == NULL) {
- DEBUG(0,("prs_init: malloc fail for %u bytes.\n", (unsigned int)size));
- return False;
- }
- ps->is_dynamic = True; /* We own this memory. */
- }
+ CHECK_STRUCT(ps);
+ DEBUG(level,("%s ps: io %s align %d offset %d err %d data %p\n",
+ msg, BOOLSTR(ps->io), ps->align, ps->offset, ps->error,
+ ps->data));
- return True;
+ if (ps->data != NULL)
+ {
+ dump_data(level, ps->data, prs_buf_len(ps));
+ }
}
/*******************************************************************
- read from a socket into memory.
+ initialise a parse structure
********************************************************************/
-BOOL prs_read(prs_struct *ps, int fd, size_t len, int timeout)
+void prs_init(prs_struct *ps, uint32 size, uint8 align, BOOL io)
{
- BOOL ok;
- size_t prev_size = ps->buffer_size;
- if (!prs_grow(ps, len))
- {
- return False;
- }
+ ps->struct_start = 0xfefefefe;
+ ps->io = io;
+ ps->align = align;
+ ps->offset = 0;
+ ps->error = False;
+ ps->bigendian = False;
- if (timeout > 0)
- {
- ok = (read_with_timeout(fd, &ps->data_p[prev_size],
- len, len,timeout) == len);
- }
- else
+ ps->data = NULL;
+ ps->data_size = 0;
+
+ ps->start = 0;
+ ps->end = 0;
+
+ ps->next = NULL;
+
+ ps->struct_end = 0xdcdcdcdc;
+
+ if (size != 0)
{
- ok = (read_data(fd, &ps->data_p[prev_size], len) == len);
+ prs_realloc_data(ps, size);
+ ps->end = 0xffffffff;
}
- return ok;
+
+ CHECK_STRUCT(ps);
}
/*******************************************************************
- Delete the memory in a parse structure - if we own it.
+ set the packed data representation type in a parse structure
********************************************************************/
-
-void prs_mem_free(prs_struct *ps)
+void prs_set_packtype(prs_struct *ps, const uint8 *pack_type)
{
- if(ps->is_dynamic && (ps->data_p != NULL))
- free(ps->data_p);
- ps->is_dynamic = False;
- ps->data_p = NULL;
- ps->buffer_size = 0;
- ps->data_offset = 0;
+ CHECK_STRUCT(ps);
+ ps->bigendian = pack_type[0] == 0x0;
}
/*******************************************************************
- Hand some already allocated memory to a prs_struct.
+ create a parse structure
********************************************************************/
-
-void prs_give_memory(prs_struct *ps, char *buf, uint32 size, BOOL is_dynamic)
+void prs_create(prs_struct *ps, char *data, uint32 size, uint8 align, BOOL io)
{
- ps->is_dynamic = is_dynamic;
- ps->data_p = buf;
- ps->buffer_size = size;
+ DEBUG(200,("prs_create: data:%p size:%d align:%d io:%s\n",
+ data, size, align, BOOLSTR(io)));
+
+ prs_init(ps, 0, align, io);
+ ps->data = data;
+ ps->data_size = size;
+ ps->end = size;
+
+ CHECK_STRUCT(ps);
}
/*******************************************************************
- Take some memory back from a prs_struct.
+ copy a parse structure
********************************************************************/
-
-char *prs_take_memory(prs_struct *ps, uint32 *psize)
+BOOL prs_copy(prs_struct *ps, const prs_struct *from)
{
- char *ret = ps->data_p;
- if(psize)
- *psize = ps->buffer_size;
- ps->is_dynamic = False;
- prs_mem_free(ps);
- return ret;
+ int len = prs_buf_len(from);
+ CHECK_STRUCT(ps);
+ CHECK_STRUCT(from);
+ prs_init(ps, len, from->align, from->io);
+ ps->bigendian = from->bigendian;
+ if (len != 0)
+ {
+ if (ps->data == NULL)
+ {
+ return False;
+ }
+ if (!prs_buf_copy(ps->data, from, 0, len))
+ {
+ return False;
+ }
+ }
+ ps->offset = len;
+ prs_link(NULL, ps, NULL);
+ return True;
}
/*******************************************************************
- Attempt, if needed, to grow a data buffer.
- Also depends on the data stream mode (io).
+ allocate a memory buffer. assume it's empty
********************************************************************/
-
-BOOL prs_grow(prs_struct *ps, uint32 extra_space)
+BOOL prs_alloc_data(prs_struct *buf, int size)
{
- uint32 new_size;
- char *new_data;
+ CHECK_STRUCT(buf);
- if(ps->data_offset + extra_space <= ps->buffer_size)
- return True;
+ buf->data_size = size;
+ buf->data = (char*)malloc(buf->data_size);
- /*
- * We cannot grow the buffer if we're not reading
- * into the prs_struct, or if we don't own the memory.
- */
+ if (buf->data == NULL && size != 0)
+ {
+ DEBUG(3,("prs_alloc: could not malloc size %d\n",
+ buf->data_size));
+ buf->data_size = 0;
- if(UNMARSHALLING(ps) || !ps->is_dynamic) {
- DEBUG(0,("prs_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
- (unsigned int)extra_space));
return False;
}
-
- /*
- * Decide how much extra space we really need.
- */
- extra_space -= (ps->buffer_size - ps->data_offset);
- if(ps->buffer_size == 0) {
- /*
- * Ensure we have at least a PDU's length, or extra_space, whichever
- * is greater.
- */
+ bzero(buf->data, buf->data_size);
+ buf->end = buf->start + size;
+
+ CHECK_STRUCT(buf);
+ return True;
+}
+
+/*******************************************************************
+ search for a memory buffer that falls within the specified offset
+ ********************************************************************/
+static const prs_struct *prs_find(const prs_struct *buf, uint32 offset)
+{
+ const prs_struct *f;
+ if (buf == NULL) return False;
- new_size = MAX(MAX_PDU_FRAG_LEN,extra_space);
+ f = buf;
- if((new_data = malloc(new_size)) == NULL) {
- DEBUG(0,("prs_grow: Malloc failure for size %u.\n", (unsigned int)new_size));
- return False;
- }
- memset(new_data, '\0', new_size );
- } else {
- /*
- * If the current buffer size is bigger than the space needed, just
- * double it, else add extra_space.
- */
- new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space);
-
- if ((new_data = Realloc(ps->data_p, new_size)) == NULL) {
- DEBUG(0,("prs_grow: Realloc failure for size %u.\n",
- (unsigned int)new_size));
- return False;
- }
+ CHECK_STRUCT(f);
+ DEBUG(200,("prs_find: data[%d..%d] offset: %d\n",
+ f->start, f->end, offset));
+
+ while (f != NULL && offset >= f->end)
+ {
+ DEBUG(200,("prs_find: next[%d..%d]\n", f->start, f->end));
+
+ f = f->next;
}
- ps->buffer_size = new_size;
- ps->data_p = new_data;
- return True;
+ if (f != NULL)
+ {
+ DEBUG(200,("prs_find: found data[%d..%d]\n", f->start, f->end));
+ }
+
+ return f;
}
/*******************************************************************
- Attempt to force a data buffer to grow by len bytes.
- This is only used when appending more data onto a prs_struct
- when reading an rpc reply, before unmarshalling it.
+ allocates a memory buffer structure
********************************************************************/
-
-BOOL prs_force_grow(prs_struct *ps, uint32 extra_space)
+BOOL prs_buf_copy(char *copy_into, const prs_struct *buf,
+ uint32 offset, uint32 len)
{
- uint32 new_size = ps->buffer_size + extra_space;
- char *new_data;
+ uint32 end = offset + len;
+ char *q = NULL;
+ uint32 data_len = prs_buf_len(buf);
+ uint32 start_offset = offset;
+ const prs_struct *bcp = buf;
+
+ if (buf == NULL || copy_into == NULL) return False;
- if(!UNMARSHALLING(ps) || !ps->is_dynamic) {
- DEBUG(0,("prs_force_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
- (unsigned int)extra_space));
- return False;
- }
+ CHECK_STRUCT(buf);
+ DEBUG(200,("prs_struct_copy: data[%d..%d] offset %d len %d\n",
+ buf->start, data_len, offset, len));
- if((new_data = Realloc(ps->data_p, new_size)) == NULL) {
- DEBUG(0,("prs_force_grow: Realloc failure for size %u.\n",
- (unsigned int)new_size));
- return False;
+ prs_debug_out(bcp, "prs_struct_copy", 200);
+
+ /* there's probably an off-by-one bug, here, and i haven't even tested the code :-) */
+ while (offset < end && ((q = prs_data(bcp, offset)) != NULL))
+ {
+ uint32 copy_len;
+ bcp = prs_find(bcp, offset);
+ copy_len = bcp->end - offset;
+
+ DEBUG(200,("\tdata[%d..%d] - offset %d len %d\n",
+ bcp->start, bcp->end,
+ offset, copy_len));
+
+ memcpy(copy_into, q, copy_len);
+
+ offset += copy_len;
+ copy_into += copy_len;
}
- ps->buffer_size = new_size;
- ps->data_p = new_data;
+ if (bcp != NULL)
+ {
+ DEBUG(200,("prs_struct_copy: copied %d bytes\n", offset - start_offset));
+ }
+ else
+ {
+ DEBUG(200,("prs_struct_copy: failed\n"));
+ }
- return True;
+ return buf != NULL;
}
/*******************************************************************
- Get the data pointer (external interface).
+ frees up a memory buffer.
********************************************************************/
-
-char *prs_data_p(prs_struct *ps)
+void prs_struct_free(prs_struct **buf)
{
- return ps->data_p;
+ if (buf == NULL) return;
+ if ((*buf) == NULL) return;
+
+ CHECK_STRUCT(*buf);
+ prs_free_data(*buf); /* delete memory data */
+ free(*buf); /* delete item */
+ (*buf) = NULL;
}
/*******************************************************************
- Get the current data size (external interface).
+ frees a memory buffer chain. assumes that all items are malloced.
********************************************************************/
-
-uint32 prs_data_size(prs_struct *ps)
+static void prs_free_chain(prs_struct **buf)
{
- return ps->buffer_size;
+ if (buf == NULL) return;
+ if ((*buf) == NULL) return;
+
+ CHECK_STRUCT(*buf);
+ if ((*buf)->next != NULL)
+ {
+ prs_free_chain(&((*buf)->next)); /* delete all other items in chain */
+ }
+ prs_struct_free(buf);
}
/*******************************************************************
- Fetch the current offset (external interface).
+ frees a memory buffer.
********************************************************************/
+void prs_free_data(prs_struct *buf)
+{
+ if (buf == NULL) return;
+
+ if (buf->data != NULL)
+ {
+ CHECK_STRUCT(buf);
+ free(buf->data); /* delete data in this structure */
+ buf->data = NULL;
+ }
+ buf->data_size = 0;
+}
-uint32 prs_offset(prs_struct *ps)
+static void *prs_realloc(void *p, size_t size)
{
- return ps->data_offset;
+ void *ret;
+ if (size == 0)
+ {
+ safe_free(p);
+ return NULL;
+ }
+ ret = (void *)malloc(size);
+ if (!ret) return NULL;
+ if (p) {
+ memcpy(ret, p, size);
+ memset(p, 0, 1);
+ }
+ safe_free(p);
+ return ret;
}
/*******************************************************************
- Set the current offset (external interface).
- ********************************************************************/
-
-BOOL prs_set_offset(prs_struct *ps, uint32 offset)
+ reallocate a memory buffer
+********************************************************************/
+BOOL prs_realloc_data(prs_struct *buf, size_t new_size)
{
- if(offset <= ps->data_offset) {
- ps->data_offset = offset;
+ char *new_data;
+
+ CHECK_STRUCT(buf);
+
+ prs_debug_out(buf, "prs_realloc_data - before", 200);
+
+ if (new_size == 0)
+ {
+ prs_free_data(buf);
return True;
}
- if(!prs_grow(ps, offset - ps->data_offset))
+ new_data = (char*)Realloc(buf->data, new_size);
+
+ if (new_data != NULL)
+ {
+ if (new_size > buf->data_size)
+ {
+ memset(&new_data[buf->data_size], 0, new_size - buf->data_size);
+ }
+ buf->data = new_data;
+ buf->data_size = new_size;
+ }
+ else if (buf->data_size >= new_size)
+ {
+ DEBUG(3,("prs_realloc_data: warning - could not realloc to %d\n",
+ new_size));
+ }
+ else
+ {
+ DEBUG(3,("prs_realloc_data: error - could not realloc to %d\n",
+ new_size));
+
+ prs_free_data(buf);
return False;
+ }
+
+ buf->end = buf->start + new_size;
- ps->data_offset = offset;
+ prs_debug_out(buf, "prs_realloc_data - after", 200);
return True;
}
/*******************************************************************
- Append the data from one parse_struct into another.
+ reallocate a memory buffer, retrospectively :-)
********************************************************************/
-
-BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src)
+BOOL prs_grow_data(prs_struct *buf, BOOL io, int new_size, BOOL force_grow)
{
- if(!prs_grow(dst, prs_offset(src)))
+ if (buf == NULL)
+ {
return False;
+ }
- memcpy(&dst->data_p[dst->data_offset], prs_data_p(src), (size_t)prs_offset(src));
- dst->data_offset += prs_offset(src);
+ CHECK_STRUCT(buf);
+ if (new_size >= buf->data_size)
+ {
+ if (!io || force_grow)
+ {
+ /* writing or forge realloc */
+ return prs_realloc_data(buf, new_size);
+ }
+ else
+ {
+ }
+ }
return True;
}
+
/*******************************************************************
- Append some data from one parse_struct into another.
+ add up the lengths of all sections.
********************************************************************/
-
-BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uint32 len)
-{
- if(!prs_grow(dst, len))
- return False;
-
- memcpy(&dst->data_p[dst->data_offset], prs_data_p(src)+start, (size_t)len);
- dst->data_offset += len;
-
- return True;
+uint32 prs_buf_len(const prs_struct *buf)
+{
+ int len = 0;
+ CHECK_STRUCT(buf);
+ while (buf != NULL)
+ {
+ len += buf->end - buf->start;
+ buf = buf->next;
+ }
+ return len;
}
/*******************************************************************
- Append the data from a buffer into a parse_struct.
+ return the memory location specified by may return NULL.
********************************************************************/
+char *prs_data(const prs_struct *buf, uint32 offset)
+{
+ CHECK_STRUCT(buf);
+ buf = prs_find(buf, offset);
+ if (buf != NULL)
+ {
+ return &(buf->data[offset - buf->start]);
+ }
+ return NULL;
+}
+
-BOOL prs_append_data(prs_struct *dst, char *src, uint32 len)
+/*******************************************************************
+ link one parsing structure to another
+ ********************************************************************/
+void prs_link(prs_struct *prev, prs_struct *ps, prs_struct *next)
{
- if(!prs_grow(dst, len))
- return False;
+ CHECK_STRUCT(ps);
+ if (next != NULL)
+ {
+ CHECK_STRUCT(next);
+ }
+ if (prev != NULL)
+ {
+ CHECK_STRUCT(prev);
+ }
+ ps->start = prev != NULL ? prev->end : 0;
+ ps->end = ps->start + ps->offset;
- memcpy(&dst->data_p[dst->data_offset], src, (size_t)len);
- dst->data_offset += len;
+ ps->next = next;
- return True;
+ DEBUG(150,("prs_link: start %d end %d\n", ps->start, ps->end));
}
/*******************************************************************
- Set the data as big-endian (external interface).
+ align a pointer to a multiple of align_offset bytes. looks like it
+ will work for offsets of 0, 2 and 4...
********************************************************************/
-
-void prs_set_bigendian_data(prs_struct *ps)
+void prs_align(prs_struct *ps)
{
- ps->bigendian_data = True;
+ int mod;
+ CHECK_STRUCT(ps);
+ if (ps->error) return;
+ mod = ps->offset & (ps->align-1);
+ if (ps->align != 0 && mod != 0)
+ {
+ ps->offset += ps->align - mod;
+ prs_grow(ps, ps->offset);
+ }
}
/*******************************************************************
- Align a the data_len to a multiple of align bytes - filling with
- zeros.
+ attempt, if appropriate, to grow a data buffer.
+
+ depends on the data stream mode (io)
********************************************************************/
+BOOL prs_grow(prs_struct *ps, uint32 new_size)
+{
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+ return prs_grow_data(ps, ps->io, new_size, False);
+}
-BOOL prs_align(prs_struct *ps)
+/*******************************************************************
+ lengthens a buffer by len bytes and copies data into it.
+ ********************************************************************/
+BOOL prs_append_data(prs_struct *ps, const char *data, int len)
{
- uint32 mod = ps->data_offset & (ps->align-1);
+ int prev_size = ps->data_size;
+ int new_size = prev_size + len;
+ char *to;
- if (ps->align != 0 && mod != 0) {
- uint32 extra_space = (ps->align - mod);
- if(!prs_grow(ps, extra_space))
- return False;
- memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
- ps->data_offset += extra_space;
+ DEBUG(200,("prs_append_data: prev_size: %d new_size: %d\n",
+ prev_size, new_size));
+
+ CHECK_STRUCT(ps);
+ prs_realloc_data(ps, new_size);
+ to = prs_data(ps, prev_size);
+
+ if (to == NULL || ps->data_size != new_size)
+ {
+ return False;
}
+ memcpy(to, data, len);
return True;
}
-/*******************************************************************
- Ensure we can read/write to a given offset.
- ********************************************************************/
-
-char *prs_mem_get(prs_struct *ps, uint32 extra_size)
+BOOL prs_add_data(prs_struct *ps, const char *data, int len)
{
- if(UNMARSHALLING(ps)) {
- /*
- * If reading, ensure that we can read the requested size item.
- */
- if (ps->data_offset + extra_size > ps->buffer_size) {
- DEBUG(0,("prs_mem_get: reading data of size %u would overrun buffer.\n",
- (unsigned int)extra_size ));
- return NULL;
+ int prev_size;
+ int new_size;
+ char *to = NULL;
+
+ ps->offset = 0;
+
+ if (ps->data == NULL)
+ {
+ DEBUG(10,("prs_add_data: new_size: %d\n", len));
+ prs_init(ps, len, 4, True);
+ prev_size = 0;
+ new_size = len;
+ if (ps->data == NULL)
+ {
+ return False;
}
- } else {
- /*
- * Writing - grow the buffer if needed.
- */
- if(!prs_grow(ps, extra_size))
+ }
+ else
+ {
+ prev_size = ps->data_size;
+ new_size = prev_size + len;
+ DEBUG(10,("prs_add_data: prev_size: %d new_size: %d\n",
+ prev_size, new_size));
+ if (!prs_realloc_data(ps, new_size))
+ {
return False;
+ }
}
- return &ps->data_p[ps->data_offset];
-}
-/*******************************************************************
- Change the struct type.
- ********************************************************************/
+ DEBUG(10,("ps->start: %d\n", ps->start));
+ ps->start = 0x0;
-BOOL prs_switch_type(prs_struct *ps, BOOL io)
-{
- if ((ps->io ^ io) == True)
- ps->io=io;
+ to = prs_data(ps, prev_size);
+ if (to == NULL)
+ {
+ DEBUG(10,("prs_add_data: data could not be found\n"));
+ return False;
+ }
+ if (ps->data_size != new_size)
+ {
+ DEBUG(10,("prs_add_data: ERROR: data used %d new_size %d\n",
+ ps->data_size, new_size));
+ return False;
+ }
+ memcpy(to, data, len);
+ return True;
}
/*******************************************************************
- Force a prs_struct to be dynamic even when it's size is 0.
+ stream a uint8
********************************************************************/
-
-void prs_force_dynamic(prs_struct *ps)
+BOOL _prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
{
- ps->is_dynamic=True;
+ char *q;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+ prs_grow(ps, ps->offset + 1);
+ q = prs_data(ps, ps->offset);
+ if (q == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_uint8 error", 5);
+ return False;
+ }
+
+ DBG_RW_CVAL(name, depth, ps->offset, ps->io, q, *data8)
+ ps->offset += 1;
+
+
+ return True;
}
/*******************************************************************
- Stream a uint8.
+ stream a uint16
********************************************************************/
-
-BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8)
+BOOL _prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
{
- char *q = prs_mem_get(ps, sizeof(uint8));
+ char *q;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+ prs_grow(ps, ps->offset + 2);
+ q = prs_data(ps, ps->offset);
if (q == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_uint16 error", 5);
return False;
+ }
- DBG_RW_CVAL(name, depth, ps->data_offset, ps->io, q, *data8)
- ps->data_offset += sizeof(uint8);
+ DBG_RW_SVAL(name, depth, ps->offset, ps->io, ps->bigendian, q, *data16)
+ ps->offset += 2;
return True;
}
/*******************************************************************
- Stream a uint16.
+ hash a stream.
********************************************************************/
-
-BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16)
+BOOL _prs_hash1(prs_struct *ps, uint32 offset, uint8 sess_key[16])
{
- char *q = prs_mem_get(ps, sizeof(uint16));
+ char *q;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+ q = prs_data(ps, ps->offset);
if (q == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_hash1 error", 5);
return False;
+ }
- DBG_RW_SVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data16)
- ps->data_offset += sizeof(uint16);
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("prs_hash1\n"));
+ dump_data(100, sess_key, 16);
+ dump_data(100, q, 68);
+#endif
+ SamOEMhash((uchar*)q, sess_key, 2);
+#ifdef DEBUG_PASSWORD
+ dump_data(100, q, 68);
+#endif
return True;
}
/*******************************************************************
- Stream a uint32.
+ stream a uint32
********************************************************************/
-
-BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
+BOOL _prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32)
{
- char *q = prs_mem_get(ps, sizeof(uint32));
+ char *q;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+ prs_grow(ps, ps->offset + 4);
+ q = prs_data(ps, ps->offset);
if (q == NULL)
+ {
+ fstring str;
+ slprintf(str, sizeof(str)-1, "_prs_uint32 error (%s)", name);
+ ps->error = True;
+ prs_debug_out(ps, str, 5);
return False;
+ }
- DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data32)
- ps->data_offset += sizeof(uint32);
+ DBG_RW_IVAL(name, depth, ps->offset, ps->io, ps->bigendian, q, *data32)
+ ps->offset += 4;
return True;
}
/******************************************************************
- Stream an array of uint8s. Length is number of uint8s.
+ stream an array of uint8s. length is number of uint8s
********************************************************************/
-
-BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
+BOOL _prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len)
{
- char *q = prs_mem_get(ps, len * sizeof(uint8));
- if (q == NULL)
+ char *q;
+ int end_offset;
+ char *e;
+ CHECK_STRUCT(ps);
+
+ if (len == 0)
+ {
+ return True;
+ }
+
+ if (ps->error) return False;
+ end_offset = ps->offset + len * sizeof(uint8);
+ prs_grow(ps, end_offset);
+ q = prs_data(ps, ps->offset);
+ e = prs_data(ps, end_offset-1);
+
+ if (q == NULL || e == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_uint8s error", 5);
return False;
+ }
- DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, data8s, len)
- ps->data_offset += (len * sizeof(uint8));
+ DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, data8s, len)
+ ps->offset = end_offset;
return True;
}
/******************************************************************
- Stream an array of uint16s. Length is number of uint16s.
+ stream an array of uint16s. length is number of uint16s
********************************************************************/
-
-BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
+BOOL _prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len)
{
- char *q = prs_mem_get(ps, len * sizeof(uint16));
- if (q == NULL)
+ char *q;
+ int end_offset;
+ char *e;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+
+ if (len == 0)
+ {
+ return True;
+ }
+
+ end_offset = ps->offset + len * sizeof(uint16);
+ prs_grow(ps, end_offset);
+ q = prs_data(ps, ps->offset);
+ e = prs_data(ps, end_offset-1);
+
+ if (q == NULL || e == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_uint16s error", 5);
return False;
+ }
- DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len)
- ps->data_offset += (len * sizeof(uint16));
+ DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian, q, data16s, len)
+ ps->offset = end_offset;
return True;
}
/******************************************************************
- Stream an array of uint32s. Length is number of uint32s.
+ stream an array of uint32s. length is number of uint32s
********************************************************************/
-
-BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
+BOOL _prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len)
{
- char *q = prs_mem_get(ps, len * sizeof(uint32));
- if (q == NULL)
+ char *q;
+ int end_offset;
+ char *e;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+
+ if (len == 0)
+ {
+ return True;
+ }
+
+ end_offset = ps->offset + len * sizeof(uint32);
+ prs_grow(ps, end_offset);
+ q = prs_data(ps, ps->offset);
+ e = prs_data(ps, end_offset-1);
+
+ if (q == NULL || e == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_uint32s error", 5);
return False;
+ }
- DBG_RW_PIVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data32s, len)
- ps->data_offset += (len * sizeof(uint32));
+ DBG_RW_PIVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian, q, data32s, len)
+ ps->offset = end_offset;
return True;
}
/******************************************************************
- Stream a "not" unicode string, length/buffer specified separately,
- in byte chars. String is in little-endian format.
+ stream a "not" unicode string, length/buffer specified separately,
+ in byte chars
********************************************************************/
-
-BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str)
+BOOL _prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str)
{
- char *p = (char *)str->buffer;
- char *q = prs_mem_get(ps, str->buf_len);
- if (q == NULL)
+ char *q;
+ int end_offset;
+ char *e;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+
+ if (str->buf_len == 0)
+ {
+ return True;
+ }
+
+ end_offset = ps->offset + str->buf_len * sizeof(uint8);
+ prs_grow(ps, end_offset);
+ q = prs_data(ps, ps->offset);
+ e = prs_data(ps, end_offset-1);
+
+ if (q == NULL || e == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_buffer2 error", 5);
return False;
+ }
- /* If we're using big-endian, reverse to get little-endian. */
- if(ps->bigendian_data)
- DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, p, str->buf_len/2)
- else
- DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, p, str->buf_len)
- ps->data_offset += str->buf_len;
+ DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->buf_len)
+ ps->offset = end_offset;
return True;
}
/******************************************************************
- Stream a string, length/buffer specified separately,
+ stream a string, length/buffer specified separately,
in uint8 chars.
********************************************************************/
-
-BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
+BOOL _prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str)
{
- char *q = prs_mem_get(ps, str->str_str_len * sizeof(uint8));
- if (q == NULL)
+ char *q;
+ int end_offset;
+ char *e;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+
+ if (str->str_str_len == 0)
+ {
+ return True;
+ }
+
+ end_offset = ps->offset + str->str_str_len * sizeof(uint8);
+ prs_grow(ps, end_offset);
+ q = prs_data(ps, ps->offset);
+ e = prs_data(ps, end_offset-1);
+
+ if (q == NULL || e == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_string2 error", 5);
return False;
+ }
- DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, str->buffer, str->str_max_len)
- ps->data_offset += (str->str_str_len * sizeof(uint8));
+ DBG_RW_PCVAL(charmode, name, depth, ps->offset, ps->io, q, str->buffer, str->str_str_len)
+ ps->offset = end_offset;
return True;
}
/******************************************************************
- Stream a unicode string, length/buffer specified separately,
- in uint16 chars. We use DBG_RW_PCVAL, not DBG_RW_PSVAL here
- as the unicode string is already in little-endian format.
+ stream a unicode string, length/buffer specified separately,
+ in uint16 chars.
********************************************************************/
-
-BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
+BOOL _prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str)
{
- char *p = (char *)str->buffer;
- char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16));
- if (q == NULL)
+ char *q;
+ int end_offset;
+ char *e;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+
+ if (str->uni_str_len == 0)
+ {
+ return True;
+ }
+
+ end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
+ prs_grow(ps, end_offset);
+ q = prs_data(ps, ps->offset);
+ e = prs_data(ps, end_offset-1);
+
+ if (q == NULL || e == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_unistr2 error", 5);
return False;
+ }
- /* If we're using big-endian, reverse to get little-endian. */
- if(ps->bigendian_data)
- DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, p, str->uni_str_len)
- else
- DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, p, str->uni_str_len * 2)
- ps->data_offset += (str->uni_str_len * sizeof(uint16));
+ DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian, q, str->buffer, str->uni_str_len)
+ ps->offset = end_offset;
return True;
}
/******************************************************************
- Stream a unicode string, length/buffer specified separately,
- in uint16 chars. We use DBG_RW_PCVAL, not DBG_RW_PSVAL here
- as the unicode string is already in little-endian format.
+ stream a unicode string, length/buffer specified separately,
+ in uint16 chars.
********************************************************************/
-
-BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth)
+BOOL _prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth)
{
- char *p = (char *)str->str.buffer;
- char *q = prs_mem_get(ps, str->uni_str_len * sizeof(uint16));
- if (q == NULL)
+ char *q;
+ int end_offset;
+ char *e;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+
+ if (str->uni_str_len == 0)
+ {
+ return True;
+ }
+
+ end_offset = ps->offset + str->uni_str_len * sizeof(uint16);
+ prs_grow(ps, end_offset);
+ q = prs_data(ps, ps->offset);
+ e = prs_data(ps, end_offset-1);
+
+ if (q == NULL || e == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_unistr3 error", 5);
return False;
+ }
- /* If we're using big-endian, reverse to get little-endian. */
- if(ps->bigendian_data)
- DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, p, str->uni_str_len)
- else
- DBG_RW_PCVAL(charmode, name, depth, ps->data_offset, ps->io, q, p, str->uni_str_len * 2)
- ps->data_offset += (str->uni_str_len * sizeof(uint16));
+ DBG_RW_PSVAL(charmode, name, depth, ps->offset, ps->io, ps->bigendian, q, str->str.buffer, str->uni_str_len)
+ ps->offset = end_offset;
return True;
}
/*******************************************************************
- Stream a unicode null-terminated string. As the string is already
- in little-endian format then do it as a stream of bytes.
+ stream a unicode null-terminated string
********************************************************************/
-
-BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
+BOOL _prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
{
- int len = 0;
- unsigned char *p = (unsigned char *)str->buffer;
+ int i = -1;
uint8 *start;
- char *q;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+ start = (uint8*)prs_data(ps, ps->offset);
- for(len = 0; len < (sizeof(str->buffer) / sizeof(str->buffer[0])) &&
- str->buffer[len] != 0; len++)
- ;
-
- q = prs_mem_get(ps, len*2);
- if (q == NULL)
- return False;
-
- start = (uint8*)q;
-
- len = 0;
- do
- {
- if(ps->bigendian_data) {
- RW_SVAL(ps->io, ps->bigendian_data, q, *p, 0)
- p += 2;
- q += 2;
- } else {
- RW_CVAL(ps->io, q, *p, 0);
- p++;
- q++;
- RW_CVAL(ps->io, q, *p, 0);
- p++;
- q++;
+ do
+ {
+ char *q;
+ i++;
+ prs_grow(ps, ps->offset + (i+1)*2);
+ q = prs_data(ps, ps->offset + i*2);
+ if (q == NULL)
+ {
+ ps->error = True;
+ prs_debug_out(ps, "_prs_unistr error", 5);
+ return False;
}
- len++;
- } while ((len < (sizeof(str->buffer) / sizeof(str->buffer[0]))) &&
- (str->buffer[len] != 0));
+ RW_SVAL(ps->io, ps->bigendian, q, str->buffer[i],0);
+ }
+ while ((((size_t)i) < sizeof(str->buffer) / sizeof(str->buffer[0])) &&
+ (str->buffer[i] != 0));
+
- ps->data_offset += len*2;
+ ps->offset += (i+1)*2;
- dump_data(5+depth, (char *)start, len * 2);
+ dump_data(5+depth, (char *)start, i * 2);
return True;
}
/*******************************************************************
- Stream a null-terminated string. len is strlen, and therefore does
+ stream a null-terminated string. len is strlen, and therefore does
not include the null-termination character.
- ********************************************************************/
-BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, int len, int max_buf_size)
+ len == 0 indicates variable length string
+ (up to max size of pstring - 1024 chars).
+
+ ********************************************************************/
+BOOL _prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size)
{
- char *q;
- uint8 *start;
- int i;
+ int i = -1; /* start off at zero after 1st i++ */
+ BOOL len_limited;
- len = MIN(len, (max_buf_size-1));
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
- q = prs_mem_get(ps, len+1);
- if (q == NULL)
- return False;
+ len_limited = len == 0 || !ps->io;
- start = (uint8*)q;
+ DEBUG(200,("_prs_string: string %s len %d max %d\n",
+ str, len, max_buf_size));
- for(i = 0; i < len; i++) {
- RW_CVAL(ps->io, q, str[i],0);
- q++;
- }
+ DEBUG(10,("%s%04x %s: ", tab_depth(depth), ps->offset, name != NULL ? name : ""));
+ do
+ {
+ char *q;
+ i++;
+
+ prs_grow(ps, ps->offset + i+1);
+ q = prs_data(ps, ps->offset + i);
+ if (q == NULL)
+ {
+ ps->error = True;
+ DEBUG(10,("%s\n", str));
+ prs_debug_out(ps, "_prs_string error", 5);
+ return False;
+ }
- /* The terminating null. */
- str[i] = '\0';
+ if (i < len || len_limited)
+ {
+ RW_CVAL(ps->io, q, str[i], 0);
+ }
+ else
+ {
+ uint8 dummy = 0;
+ RW_CVAL(ps->io, q, dummy,0);
+ }
- if (MARSHALLING(ps)) {
- RW_CVAL(ps->io, q, str[i], 0);
- }
+ } while (i < max_buf_size && (len_limited ? str[i] != 0 : i < len) );
- ps->data_offset += len+1;
+ ps->offset += i+1;
- dump_data(5+depth, (char *)start, len);
+ DEBUG(10,("%s\n", str));
return True;
}
/*******************************************************************
- prs_uint16 wrapper. Call this and it sets up a pointer to where the
- uint16 should be stored, or gets the size if reading.
+ prs_uint16 wrapper. call this and it sets up a pointer to where the
+ uint16 should be stored, or gets the size if reading
********************************************************************/
-
-BOOL prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
+BOOL _prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset)
{
- (*offset) = ps->data_offset;
- if (UNMARSHALLING(ps)) {
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+ (*offset) = ps->offset;
+ if (ps->io)
+ {
/* reading. */
- return prs_uint16(name, ps, depth, data16);
- } else {
- char *q = prs_mem_get(ps, sizeof(uint16));
- if(q ==NULL)
- return False;
- ps->data_offset += sizeof(uint16);
+ return _prs_uint16(name, ps, depth, data16);
+ }
+ else
+ {
+ ps->offset += sizeof(uint16);
}
return True;
}
@@ -672,42 +992,45 @@ BOOL prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint3
prs_uint16 wrapper. call this and it retrospectively stores the size.
does nothing on reading, as that is already handled by ...._pre()
********************************************************************/
-
-BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
+BOOL _prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
uint32 ptr_uint16, uint32 start_offset)
{
- if (MARSHALLING(ps)) {
- /*
- * Writing - temporarily move the offset pointer.
- */
- uint16 data_size = ps->data_offset - start_offset;
- uint32 old_offset = ps->data_offset;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+ if (!ps->io)
+ {
+ /* storing: go back and do a retrospective job. i hate this */
+ uint16 data_size = ps->offset - start_offset;
+ uint32 old_offset = ps->offset;
- ps->data_offset = ptr_uint16;
- if(!prs_uint16(name, ps, depth, &data_size)) {
- ps->data_offset = old_offset;
- return False;
- }
- ps->data_offset = old_offset;
- } else {
- ps->data_offset = start_offset + (uint32)(*data16);
+ ps->offset = ptr_uint16;
+ prs_uint16(name, ps, depth, &data_size);
+ ps->offset = old_offset;
+ }
+ else
+ {
+ ps->offset = start_offset + (*data16);
}
return True;
}
/*******************************************************************
- prs_uint32 wrapper. Call this and it sets up a pointer to where the
- uint32 should be stored, or gets the size if reading.
+ prs_uint32 wrapper. call this and it sets up a pointer to where the
+ uint32 should be stored, or gets the size if reading
********************************************************************/
-
-BOOL prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
+BOOL _prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint32 *offset)
{
- (*offset) = ps->data_offset;
- if (UNMARSHALLING(ps)) {
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+ (*offset) = ps->offset;
+ if (ps->io)
+ {
/* reading. */
- return prs_uint32(name, ps, depth, data32);
- } else {
- ps->data_offset += sizeof(uint32);
+ return _prs_uint32(name, ps, depth, data32);
+ }
+ else
+ {
+ ps->offset += sizeof(uint32);
}
return True;
}
@@ -716,21 +1039,68 @@ BOOL prs_uint32_pre(char *name, prs_struct *ps, int depth, uint32 *data32, uint3
prs_uint32 wrapper. call this and it retrospectively stores the size.
does nothing on reading, as that is already handled by ...._pre()
********************************************************************/
-
-BOOL prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
+BOOL _prs_uint32_post(char *name, prs_struct *ps, int depth, uint32 *data32,
uint32 ptr_uint32, uint32 data_size)
{
- if (MARSHALLING(ps)) {
- /*
- * Writing - temporarily move the offset pointer.
- */
- uint32 old_offset = ps->data_offset;
- ps->data_offset = ptr_uint32;
- if(!prs_uint32(name, ps, depth, &data_size)) {
- ps->data_offset = old_offset;
- return False;
- }
- ps->data_offset = old_offset;
+ CHECK_STRUCT(ps);
+ if (ps->error) return False;
+ if (!ps->io)
+ {
+ /* storing: go back and do a retrospective job. i hate this */
+ uint32 old_offset = ps->offset;
+ ps->offset = ptr_uint32;
+ prs_uint32(name, ps, depth, &data_size);
+ ps->offset = old_offset;
+ }
+ else
+ {
+ ps->offset = data_size + (*data32);
}
return True;
}
+
+/*******************************************************************
+ prs_tdb_store. stores prs_struct data by prs_struct key
+ ********************************************************************/
+int prs_tdb_delete(TDB_CONTEXT *tdb, prs_struct *pk)
+{
+ TDB_DATA key;
+
+ key.dptr = (char*)prs_data(pk, 0);
+ key.dsize = prs_buf_len(pk);
+
+ return tdb_delete(tdb, key);
+}
+
+/*******************************************************************
+ prs_tdb_store. stores prs_struct data by prs_struct key
+ ********************************************************************/
+int prs_tdb_store(TDB_CONTEXT *tdb, int flgs, prs_struct *pk, prs_struct *pd)
+{
+ TDB_DATA key;
+ TDB_DATA data;
+
+ key.dptr = (char*)prs_data(pk, 0);
+ key.dsize = prs_buf_len(pk);
+
+ data.dptr = prs_data(pd, 0);
+ data.dsize = prs_buf_len(pd);
+
+ return tdb_store(tdb, key, data, flgs);
+}
+
+/*******************************************************************
+ prs_tdb_fetch. fetches prs_struct data by prs_struct key
+ ********************************************************************/
+void prs_tdb_fetch(TDB_CONTEXT *tdb, prs_struct *pk, prs_struct *pd)
+{
+ TDB_DATA key;
+ TDB_DATA data;
+
+ key.dptr = (char*)prs_data(pk, 0);
+ key.dsize = prs_buf_len(pk);
+
+ data = tdb_fetch(tdb, key);
+
+ prs_create(pd, data.dptr, data.dsize, 4, True);
+}
diff --git a/source/rpc_parse/parse_reg.c b/source/rpc_parse/parse_reg.c
index cc970e41500..db0294dc621 100644
--- a/source/rpc_parse/parse_reg.c
+++ b/source/rpc_parse/parse_reg.c
@@ -2,10 +2,9 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
- * Copyright (C) Hewlett-Packard Company 1999.
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Paul Ashton 1997-1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,48 +23,101 @@
#include "includes.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
/*******************************************************************
- Inits a structure.
+creates a structure.
********************************************************************/
-
-void init_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
+BOOL make_reg_q_open_hkcr(REG_Q_OPEN_HKCR *q_o,
uint16 unknown_0, uint32 level)
{
q_o->ptr = 1;
q_o->unknown_0 = unknown_0;
q_o->unknown_1 = 0x0; /* random - changes */
q_o->level = level;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
+BOOL reg_io_q_open_hkcr(char *desc, REG_Q_OPEN_HKCR *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return False;
-BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth)
+ prs_debug(ps, depth, desc, "reg_io_q_open_hkcr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+ if (r_q->ptr != 0)
+ {
+ prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0));
+ prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
+ prs_uint32("level ", ps, depth, &(r_q->level ));
+ }
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL reg_io_r_open_hkcr(char *desc, REG_R_OPEN_HKCR *r_r, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_r == NULL) return False;
- prs_debug(ps, depth, desc, "reg_io_q_open_hklm");
+ prs_debug(ps, depth, desc, "reg_io_r_open_hkcr");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_r->pol), ps, depth);
+
+ prs_uint32("status", ps, depth, &(r_r->status));
+
+ return True;
+}
+
+
+/*******************************************************************
+creates a structure.
+********************************************************************/
+BOOL make_reg_q_open_hklm(REG_Q_OPEN_HKLM *q_o,
+ uint16 unknown_0, uint32 access_mask)
+{
+ q_o->ptr = 1;
+ q_o->unknown_0 = unknown_0;
+ q_o->unknown_1 = 0x0; /* random - changes */
+ q_o->access_mask = access_mask;
+
+ return True;
+}
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
- return False;
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return False;
+
+ prs_debug(ps, depth, desc, "reg_io_q_open_hklm");
+ depth++;
- if (r_q->ptr != 0) {
- if(!prs_uint16("unknown_0", ps, depth, &r_q->unknown_0))
- return False;
- if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1))
- return False;
- if(!prs_uint32("level ", ps, depth, &r_q->level))
- return False;
+ prs_align(ps);
+
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+ if (r_q->ptr != 0)
+ {
+ prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0));
+ prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
+ prs_uint32("access_mask", ps, depth, &(r_q->access_mask));
}
return True;
@@ -75,75 +127,64 @@ BOOL reg_io_q_open_hklm(char *desc, REG_Q_OPEN_HKLM *r_q, prs_struct *ps, int d
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_open_hklm(char *desc, REG_R_OPEN_HKLM *r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL)
- return False;
+ if (r_r == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_open_hklm");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_r->pol), ps, depth);
- if(!prs_uint32("status", ps, depth, &r_r->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_r->status));
return True;
}
/*******************************************************************
- Inits a structure.
+creates a structure.
********************************************************************/
-
-void init_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol)
+BOOL make_reg_q_flush_key(REG_Q_FLUSH_KEY *q_u, POLICY_HND *pol)
{
- memcpy(&q_u->pol, pol, sizeof(q_u->pol));
+ memcpy(&(q_u->pol), pol, sizeof(q_u->pol));
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_flush_key(char *desc, REG_Q_FLUSH_KEY *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_flush_key");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
return True;
}
+
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL)
- return False;
+ if (r_r == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_flush_key");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_r->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_r->status));
return True;
}
@@ -151,197 +192,167 @@ BOOL reg_io_r_flush_key(char *desc, REG_R_FLUSH_KEY *r_r, prs_struct *ps, int d
/*******************************************************************
reads or writes SEC_DESC_BUF and SEC_DATA structures.
********************************************************************/
-
-static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec, SEC_DESC_BUF *data, prs_struct *ps, int depth)
+static BOOL reg_io_hdrbuf_sec(uint32 ptr, uint32 *ptr3, BUFHDR *hdr_sec,
+ SEC_DESC_BUF *data, prs_struct *ps, int depth)
{
- if (ptr != 0) {
+ if (ptr != 0)
+ {
uint32 hdr_offset;
uint32 old_offset;
- if(!smb_io_hdrbuf_pre("hdr_sec", hdr_sec, ps, depth, &hdr_offset))
- return False;
-
- old_offset = prs_offset(ps);
-
- if (ptr3 != NULL) {
- if(!prs_uint32("ptr3", ps, depth, ptr3))
- return False;
+ smb_io_hdrbuf_pre("hdr_sec", hdr_sec, ps, depth, &hdr_offset);
+ old_offset = ps->offset;
+ if (ptr3 != NULL)
+ {
+ prs_uint32("ptr3", ps, depth, ptr3);
}
-
- if (ptr3 == NULL || *ptr3 != 0) {
- if(!sec_io_desc_buf("data ", &data, ps, depth)) /* JRA - this line is probably wrong... */
- return False;
+ if (ptr3 == NULL || *ptr3 != 0)
+ {
+ sec_io_desc_buf("data ", data , ps, depth);
}
-
- if(!smb_io_hdrbuf_post("hdr_sec", hdr_sec, ps, depth, hdr_offset,
- data->max_len, data->len))
- return False;
- if(!prs_set_offset(ps, old_offset + data->len + sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3)))
- return False;
-
- if(!prs_align(ps))
- return False;
+ smb_io_hdrbuf_post("hdr_sec", hdr_sec, ps, depth, hdr_offset,
+ data->max_len, data->len);
+ ps->offset = old_offset + data->len + sizeof(uint32) * ((ptr3 != NULL) ? 5 : 3);
+ prs_align(ps);
}
return True;
}
+
/*******************************************************************
- Inits a structure.
+creates a structure.
********************************************************************/
-
-void init_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
- char *name, char *class, SEC_ACCESS *sam_access,
- SEC_DESC_BUF *sec_buf)
+BOOL make_reg_q_create_key(REG_Q_CREATE_KEY *q_c, POLICY_HND *hnd,
+ char *key_name, char *key_class,
+ SEC_ACCESS *sam_access,
+ SEC_DESC_BUF *sec_buf,
+ int sec_len, SEC_DESC *sec)
{
- int len_name = name != NULL ? strlen(name ) + 1: 0;
- int len_class = class != NULL ? strlen(class) + 1: 0;
+ int len_name = key_name != NULL ? strlen(key_name ) + 1: 0;
+ int len_class = key_class != NULL ? strlen(key_class) + 1: 0;
ZERO_STRUCTP(q_c);
- memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
+ memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
- init_uni_hdr(&q_c->hdr_name, len_name);
- init_unistr2(&q_c->uni_name, name, len_name);
+ make_uni_hdr(&(q_c->hdr_name), len_name);
+ make_unistr2(&(q_c->uni_name), key_name, len_name);
- init_uni_hdr(&q_c->hdr_class, len_class);
- init_unistr2(&q_c->uni_class, class, len_class);
+ make_uni_hdr(&(q_c->hdr_class), len_class);
+ make_unistr2(&(q_c->uni_class), key_class, len_class);
q_c->reserved = 0x00000000;
- memcpy(&q_c->sam_access, sam_access, sizeof(q_c->sam_access));
+ memcpy(&(q_c->sam_access), sam_access, sizeof(q_c->sam_access));
q_c->ptr1 = 1;
q_c->sec_info = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
q_c->data = sec_buf;
q_c->ptr2 = 1;
- init_buf_hdr(&q_c->hdr_sec, sec_buf->len, sec_buf->len);
+ make_buf_hdr(&(q_c->hdr_sec), sec_len, sec_len);
q_c->ptr3 = 1;
+ make_sec_desc_buf(q_c->data, sec_len, sec);
+
q_c->unknown_2 = 0x00000000;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_create_key(char *desc, REG_Q_CREATE_KEY *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_create_key");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
- return False;
-
- if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unihdr ("", &r_q->hdr_class, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_class, r_q->hdr_class.buffer, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("reserved", ps, depth, &r_q->reserved))
- return False;
- if(!sec_io_access("sam_access", &r_q->sam_access, ps, depth))
- return False;
-
- if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
- return False;
-
- if (r_q->ptr1 != 0) {
- if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
- return False;
+ smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
+
+ smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+ smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
+ prs_align(ps);
+
+ smb_io_unihdr ("", &(r_q->hdr_class), ps, depth);
+ smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("reserved", ps, depth, &(r_q->reserved));
+ sec_io_access("sam_access", &r_q->sam_access, ps, depth);
+
+ prs_uint32("ptr1", ps, depth, &(r_q->ptr1));
+ if (r_q->ptr1 != 0)
+ {
+ prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
}
- if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
- return False;
- if(!reg_io_hdrbuf_sec(r_q->ptr2, &r_q->ptr3, &r_q->hdr_sec, r_q->data, ps, depth))
- return False;
+ prs_uint32("ptr2", ps, depth, &(r_q->ptr2));
+ reg_io_hdrbuf_sec(r_q->ptr2, &r_q->ptr3, &r_q->hdr_sec, r_q->data, ps, depth);
- if(!prs_uint32("unknown_2", ps, depth, &r_q->unknown_2))
- return False;
+ prs_uint32("unknown_2", ps, depth, &(r_q->unknown_2));
return True;
}
+
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_create_key(char *desc, REG_R_CREATE_KEY *r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL)
- return False;
+ if (r_r == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_create_key");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_r->key_pol, ps, depth))
- return False;
- if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
- return False;
+ smb_io_pol_hnd("", &(r_r->key_pol), ps, depth);
+ prs_uint32("unknown", ps, depth, &(r_r->unknown));
- if(!prs_uint32("status", ps, depth, &r_r->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_r->status));
return True;
}
/*******************************************************************
- Inits a structure.
+creates a structure.
********************************************************************/
-
-void init_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
+BOOL make_reg_q_delete_val(REG_Q_DELETE_VALUE *q_c, POLICY_HND *hnd,
char *name)
{
int len_name = name != NULL ? strlen(name ) + 1: 0;
ZERO_STRUCTP(q_c);
- memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
+ memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
- init_uni_hdr(&q_c->hdr_name, len_name);
- init_unistr2(&q_c->uni_name, name, len_name);
+ make_uni_hdr(&(q_c->hdr_name), len_name);
+ make_unistr2(&(q_c->uni_name), name, len_name);
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_delete_val");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
- if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+ smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
+ prs_align(ps);
return True;
}
@@ -350,127 +361,112 @@ BOOL reg_io_q_delete_val(char *desc, REG_Q_DELETE_VALUE *r_q, prs_struct *ps, i
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_delete_val(char *desc, REG_R_DELETE_VALUE *r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL)
- return False;
+ if (r_r == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_delete_val");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_r->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_r->status));
return True;
}
+
/*******************************************************************
- Inits a structure.
+creates a structure.
********************************************************************/
-
-void init_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
+BOOL make_reg_q_delete_key(REG_Q_DELETE_KEY *q_c, POLICY_HND *hnd,
char *name)
{
int len_name = name != NULL ? strlen(name ) + 1: 0;
ZERO_STRUCTP(q_c);
- memcpy(&q_c->pnt_pol, hnd, sizeof(q_c->pnt_pol));
+ memcpy(&(q_c->pnt_pol), hnd, sizeof(q_c->pnt_pol));
+
+ make_uni_hdr(&(q_c->hdr_name), len_name);
+ make_unistr2(&(q_c->uni_name), name, len_name);
- init_uni_hdr(&q_c->hdr_name, len_name);
- init_unistr2(&q_c->uni_name, name, len_name);
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_delete_key(char *desc, REG_Q_DELETE_KEY *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_delete_key");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_q->pnt_pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_q->pnt_pol), ps, depth);
- if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+ smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
+ prs_align(ps);
return True;
}
+
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_delete_key(char *desc, REG_R_DELETE_KEY *r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL)
- return False;
+ if (r_r == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_delete_key");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_r->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_r->status));
return True;
}
+
/*******************************************************************
- Inits a structure.
+creates a structure.
********************************************************************/
-
-void init_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
+BOOL make_reg_q_query_key(REG_Q_QUERY_KEY *q_o, POLICY_HND *hnd,
uint32 max_class_len)
{
ZERO_STRUCTP(q_o);
- memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
- init_uni_hdr(&q_o->hdr_class, max_class_len);
+ memcpy(&(q_o->pol), hnd, sizeof(q_o->pol));
+ q_o->hdr_class.uni_str_len = 0;
+ q_o->hdr_class.uni_max_len = max_class_len * 2;
+ q_o->hdr_class.buffer = max_class_len > 0 ? 1 : 0;
q_o->uni_class.uni_max_len = max_class_len;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_query_key");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
- if(!smb_io_unihdr ("", &r_q->hdr_class, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_class, r_q->hdr_class.buffer, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+ smb_io_unihdr ("", &(r_q->hdr_class), ps, depth);
+ smb_io_unistr2("", &(r_q->uni_class), r_q->hdr_class.buffer, ps, depth);
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
return True;
}
@@ -479,198 +475,168 @@ BOOL reg_io_q_query_key(char *desc, REG_Q_QUERY_KEY *r_q, prs_struct *ps, int d
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_query_key(char *desc, REG_R_QUERY_KEY *r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL)
- return False;
+ if (r_r == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_query_key");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unihdr ("", &r_r->hdr_class, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_r->uni_class, r_r->hdr_class.buffer, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("num_subkeys ", ps, depth, &r_r->num_subkeys))
- return False;
- if(!prs_uint32("max_subkeylen ", ps, depth, &r_r->max_subkeylen))
- return False;
- if(!prs_uint32("mak_subkeysize", ps, depth, &r_r->max_subkeysize))
- return False;
- if(!prs_uint32("num_values ", ps, depth, &r_r->num_values))
- return False;
- if(!prs_uint32("max_valnamelen", ps, depth, &r_r->max_valnamelen))
- return False;
- if(!prs_uint32("max_valbufsize", ps, depth, &r_r->max_valbufsize))
- return False;
- if(!prs_uint32("sec_desc ", ps, depth, &r_r->sec_desc))
- return False;
- if(!smb_io_time("mod_time ", &r_r->mod_time, ps, depth))
- return False;
+ smb_io_unihdr ("", &(r_r->hdr_class), ps, depth);
+ smb_io_unistr2("", &(r_r->uni_class), r_r->hdr_class.buffer, ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("num_subkeys ", ps, depth, &(r_r->num_subkeys ));
+ prs_uint32("max_subkeylen ", ps, depth, &(r_r->max_subkeylen ));
+ prs_uint32("mak_subkeysize", ps, depth, &(r_r->max_subkeysize));
+ prs_uint32("num_values ", ps, depth, &(r_r->num_values ));
+ prs_uint32("max_valnamelen", ps, depth, &(r_r->max_valnamelen));
+ prs_uint32("max_valbufsize", ps, depth, &(r_r->max_valbufsize));
+ prs_uint32("sec_desc ", ps, depth, &(r_r->sec_desc ));
+ smb_io_time("mod_time ", &(r_r->mod_time), ps, depth);
- if(!prs_uint32("status", ps, depth, &r_r->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_r->status));
return True;
}
+
/*******************************************************************
- Inits a structure.
+creates a structure.
********************************************************************/
-
-void init_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd)
+BOOL make_reg_q_unk_1a(REG_Q_UNK_1A *q_o, POLICY_HND *hnd)
{
- memcpy(&q_o->pol, hnd, sizeof(q_o->pol));
+ memcpy(&(q_o->pol), hnd, sizeof(q_o->pol));
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_unk_1a(char *desc, REG_Q_UNK_1A *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_unk_1a");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
return True;
}
+
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_unk_1a(char *desc, REG_R_UNK_1A *r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL)
- return False;
+ if (r_r == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_unk_1a");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("unknown", ps, depth, &r_r->unknown))
- return False;
- if(!prs_uint32("status" , ps, depth, &r_r->status))
- return False;
+ prs_uint32("unknown", ps, depth, &(r_r->unknown));
+ prs_uint32("status" , ps, depth, &(r_r->status ));
return True;
}
+
/*******************************************************************
- Inits a structure.
+creates a structure.
********************************************************************/
-
-void init_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
+BOOL make_reg_q_open_hku(REG_Q_OPEN_HKU *q_o,
uint16 unknown_0, uint32 level)
{
q_o->ptr = 1;
q_o->unknown_0 = unknown_0;
q_o->unknown_1 = 0x0; /* random - changes */
q_o->level = level;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_open_hku(char *desc, REG_Q_OPEN_HKU *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_open_hku");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
- return False;
- if (r_q->ptr != 0) {
- if(!prs_uint16("unknown_0", ps, depth, &r_q->unknown_0))
- return False;
- if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1))
- return False;
- if(!prs_uint32("level ", ps, depth, &r_q->level))
- return False;
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+ if (r_q->ptr != 0)
+ {
+ prs_uint16("unknown_0", ps, depth, &(r_q->unknown_0));
+ prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
+ prs_uint32("level ", ps, depth, &(r_q->level ));
}
return True;
}
+
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_open_hku(char *desc, REG_R_OPEN_HKU *r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL)
- return False;
+ if (r_r == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_open_hku");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_r->pol), ps, depth);
- if(!prs_uint32("status", ps, depth, &r_r->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_r->status));
return True;
}
+
/*******************************************************************
- Inits an REG_Q_CLOSE structure.
+makes an REG_Q_CLOSE structure.
********************************************************************/
-
-void init_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd)
+BOOL make_reg_q_close(REG_Q_CLOSE *q_c, POLICY_HND *hnd)
{
- DEBUG(5,("init_reg_q_close\n"));
+ if (q_c == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_reg_q_close\n"));
+
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
- memcpy(&q_c->pol, hnd, sizeof(q_c->pol));
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_close(char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "reg_io_q_unknown_1");
+ prs_debug(ps, depth, desc, "reg_io_q_close");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &q_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ prs_align(ps);
return True;
}
@@ -678,25 +644,19 @@ BOOL reg_io_q_close(char *desc, REG_Q_CLOSE *q_u, prs_struct *ps, int depth)
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "reg_io_r_unknown_1");
+ prs_debug(ps, depth, desc, "reg_io_r_close");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("", &(r_u->pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
@@ -704,43 +664,41 @@ BOOL reg_io_r_close(char *desc, REG_R_CLOSE *r_u, prs_struct *ps, int depth)
/*******************************************************************
makes a structure.
********************************************************************/
-
-void init_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol, SEC_DESC_BUF *sec_desc_buf)
+BOOL make_reg_q_set_key_sec(REG_Q_SET_KEY_SEC *q_i, POLICY_HND *pol,
+ uint32 sec_info,
+ uint32 buf_len, SEC_DESC *sec_desc)
{
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ if (q_i == NULL) return False;
- q_i->sec_info = DACL_SECURITY_INFORMATION;
+ memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
+
+ q_i->sec_info = sec_info;
q_i->ptr = 1;
- init_buf_hdr(&q_i->hdr_sec, sec_desc_buf->len, sec_desc_buf->len);
- q_i->data = sec_desc_buf;
+ make_buf_hdr(&(q_i->hdr_sec), buf_len, buf_len);
+ make_sec_desc_buf(q_i->data, buf_len, sec_desc);
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_set_key_sec");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
- if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
- return False;
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
- return False;
+ prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
- if(!reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth))
- return False;
+ reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth);
return True;
}
@@ -748,20 +706,16 @@ BOOL reg_io_q_set_key_sec(char *desc, REG_Q_SET_KEY_SEC *r_q, prs_struct *ps, i
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_set_key_sec");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_q->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_q->status));
return True;
}
@@ -770,47 +724,46 @@ BOOL reg_io_r_set_key_sec(char *desc, REG_R_SET_KEY_SEC *r_q, prs_struct *ps, in
/*******************************************************************
makes a structure.
********************************************************************/
-
-void init_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol,
- uint32 sec_buf_size, SEC_DESC_BUF *psdb)
+BOOL make_reg_q_get_key_sec(REG_Q_GET_KEY_SEC *q_i, POLICY_HND *pol,
+ uint32 sec_info,
+ uint32 buf_len, SEC_DESC_BUF *sec_buf)
{
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ if (q_i == NULL) return False;
+
+ memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
- q_i->sec_info = OWNER_SECURITY_INFORMATION |
- GROUP_SECURITY_INFORMATION |
- DACL_SECURITY_INFORMATION;
+ q_i->sec_info = sec_info;
- q_i->ptr = psdb != NULL ? 1 : 0;
- q_i->data = psdb;
+ q_i->ptr = sec_buf != NULL ? 1 : 0;
+ q_i->data = sec_buf;
- init_buf_hdr(&q_i->hdr_sec, sec_buf_size, 0);
+ if (sec_buf != NULL)
+ {
+ make_buf_hdr(&(q_i->hdr_sec), buf_len, 0);
+ make_sec_desc_buf(q_i->data, buf_len, NULL);
+ }
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_get_key_sec");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
- if(!prs_uint32("sec_info", ps, depth, &r_q->sec_info))
- return False;
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
- return False;
+ prs_uint32("sec_info", ps, depth, &(r_q->sec_info));
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
- if(!reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth))
- return False;
+ reg_io_hdrbuf_sec(r_q->ptr, NULL, &r_q->hdr_sec, r_q->data, ps, depth);
return True;
}
@@ -819,217 +772,196 @@ BOOL reg_io_q_get_key_sec(char *desc, REG_Q_GET_KEY_SEC *r_q, prs_struct *ps, i
/*******************************************************************
makes a structure.
********************************************************************/
- void init_reg_r_get_key_sec(REG_R_GET_KEY_SEC *r_i, POLICY_HND *pol,
+ void make_reg_r_get_key_sec(REG_R_GET_KEY_SEC *r_i, POLICY_HND *pol,
uint32 buf_len, uint8 *buf,
uint32 status)
{
+ if (r_i == NULL) return False;
+
r_i->ptr = 1;
- init_buf_hdr(&r_i->hdr_sec, buf_len, buf_len);
- init_sec_desc_buf(r_i->data, buf_len, 1);
+ make_buf_hdr(&(r_i->hdr_sec), buf_len, buf_len);
+ make_sec_desc_buf(r_i->data, buf_len, 1);
r_i->status = status; /* 0x0000 0000 or 0x0000 007a */
+
+ return True;
}
#endif
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_get_key_sec(char *desc, REG_R_GET_KEY_SEC *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_get_key_sec");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr ", ps, depth, &r_q->ptr))
- return False;
-
- if (r_q->ptr != 0) {
- if(!smb_io_hdrbuf("", &r_q->hdr_sec, ps, depth))
- return False;
- if(!sec_io_desc_buf("", &r_q->data, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint32("ptr ", ps, depth, &(r_q->ptr ));
+
+ if (r_q->ptr != 0)
+ {
+ smb_io_hdrbuf("", &(r_q->hdr_sec), ps, depth);
+ sec_io_desc_buf("", r_q->data, ps, depth);
+
+ prs_align(ps);
}
- if(!prs_uint32("status", ps, depth, &r_q->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_q->status));
return True;
}
+
/*******************************************************************
makes a structure.
********************************************************************/
-
-void init_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, char *product_type,
- time_t unix_time, uint8 major, uint8 minor)
+BOOL make_reg_q_info(REG_Q_INFO *q_i, POLICY_HND *pol, const char *val_name,
+ uint8 major, uint8 minor)
{
- int len_type = strlen(product_type);
+ int len_type = val_name != NULL ? strlen(val_name) + 1 : 0;
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ if (q_i == NULL) return False;
- init_uni_hdr(&q_i->hdr_type, len_type);
- init_unistr2(&q_i->uni_type, product_type, len_type);
+ memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
- q_i->ptr1 = 1;
- unix_to_nt_time(&q_i->time, unix_time);
- q_i->major_version1 = major;
- q_i->minor_version1 = minor;
- memset(q_i->pad1, 0, sizeof(q_i->pad1));
+ make_uni_hdr(&(q_i->hdr_val), len_type);
+ make_unistr2(&(q_i->uni_val), val_name, len_type);
- q_i->ptr2 = 1;
- q_i->major_version2 = major;
- q_i->minor_version2 = minor;
- memset(q_i->pad2, 0, sizeof(q_i->pad2));
+ q_i->ptr_type = 1;
+ q_i->type = 0x77872314;
- q_i->ptr3 = 1;
- q_i->unknown = 0x00000000;
+ q_i->ptr_uni_type = 0x1;
+ q_i->uni_type.buf_max_len = 0x104;
+ q_i->uni_type.buf_len = 0x0;
+ q_i->uni_type.undoc = 0;
+
+ q_i->ptr_max_len = 1;
+ q_i->buf_max_len = 0x104;
+
+ q_i->ptr_len = 1;
+ q_i->buf_len = 0x0;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_info(char *desc, REG_Q_INFO *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
- if(!smb_io_unihdr ("", &r_q->hdr_type, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_type, r_q->hdr_type.buffer, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+ smb_io_unihdr ("", &(r_q->hdr_val), ps, depth);
+ smb_io_unistr2("", &(r_q->uni_val), r_q->hdr_val.buffer, ps, depth);
+
+ prs_align(ps);
- if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
- return False;
-
- if (r_q->ptr1 != 0) {
- if(!smb_io_time("", &r_q->time, ps, depth))
- return False;
- if(!prs_uint8 ("major_version1", ps, depth, &r_q->major_version1))
- return False;
- if(!prs_uint8 ("minor_version1", ps, depth, &r_q->minor_version1))
- return False;
- if(!prs_uint8s(False, "pad1", ps, depth, r_q->pad1, sizeof(r_q->pad1)))
- return False;
+ prs_uint32("ptr_type", ps, depth, &(r_q->ptr_type));
+ if (r_q->ptr_type != 0)
+ {
+ prs_uint32("type", ps, depth, &(r_q->type));
}
- if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
- return False;
+ prs_uint32("ptr_uni_type", ps, depth, &(r_q->ptr_uni_type));
- if (r_q->ptr2 != 0) {
- if(!prs_uint8 ("major_version2", ps, depth, &r_q->major_version2))
- return False;
- if(!prs_uint8 ("minor_version2", ps, depth, &r_q->minor_version2))
- return False;
- if(!prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2)))
- return False;
- }
+ smb_io_buffer2("uni_type", &(r_q->uni_type), r_q->ptr_uni_type, ps, depth);
+ prs_align(ps);
- if(!prs_uint32("ptr3", ps, depth, &r_q->ptr3))
- return False;
+ prs_uint32("ptr_max_len", ps, depth, &(r_q->ptr_max_len));
+ if (r_q->ptr_max_len != 0)
+ {
+ prs_uint32("buf_max_len", ps, depth, &(r_q->buf_max_len));
+ }
- if (r_q->ptr3 != 0) {
- if(!prs_uint32("unknown", ps, depth, &r_q->unknown))
- return False;
+ prs_uint32("ptr_len", ps, depth, &(r_q->ptr_len));
+ if (r_q->ptr_len != 0)
+ {
+ prs_uint32("buf_len", ps, depth, &(r_q->buf_len));
}
return True;
}
+
/*******************************************************************
- Inits a structure.
+creates a structure.
********************************************************************/
-
-void init_reg_r_info(REG_R_INFO *r_r,
- uint32 level, char *os_type,
- uint32 unknown_0, uint32 unknown_1,
+BOOL make_reg_r_info(REG_R_INFO *r_r,
+ uint32 *type, BUFFER2 *buf,
uint32 status)
{
- uint8 buf[512];
- int len = dos_struni2((char *)buf, os_type, sizeof(buf));
+ if (r_r == NULL) return False;
- r_r->ptr1 = 1;
- r_r->level = level;
+ r_r->ptr_type = type != NULL ? 1 : 0;
+ r_r->type = type;
- r_r->ptr_type = 1;
- init_buffer2(&r_r->uni_type, buf, len*2);
+ r_r->ptr_uni_type = buf != NULL ? 1 : 0;
+ r_r->uni_type = buf;
- r_r->ptr2 = 1;
- r_r->unknown_0 = unknown_0;
-
- r_r->ptr3 = 1;
- r_r->unknown_1 = unknown_1;
+ if (buf != NULL)
+ {
+ r_r->ptr_max_len = 1;
+ r_r->buf_max_len = r_r->uni_type->buf_max_len;
+ r_r->ptr_len = 1;
+ r_r->buf_len = r_r->uni_type->buf_len;
+ }
+ else
+ {
+ r_r->ptr_max_len = 0;
+ r_r->ptr_len = 0;
+ }
+
r_r->status = status;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL)
- return False;
+ if (r_r == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr1", ps, depth, &r_r->ptr1))
- return False;
-
- if (r_r->ptr1 != 0) {
- if(!prs_uint32("level", ps, depth, &r_r->level))
- return False;
- if(!prs_uint32("ptr_type", ps, depth, &r_r->ptr_type))
- return False;
-
- if(!smb_io_buffer2("uni_type", &r_r->uni_type, r_r->ptr_type, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr2", ps, depth, &r_r->ptr2))
- return False;
-
- if (r_r->ptr2 != 0) {
- if(!prs_uint32("unknown_0", ps, depth, &r_r->unknown_0))
- return False;
- }
+ prs_uint32("ptr_type", ps, depth, &(r_r->ptr_type));
+ if (r_r->ptr_type != 0)
+ {
+ prs_uint32("type", ps, depth, r_r->type);
+ }
- if(!prs_uint32("ptr3", ps, depth, &r_r->ptr3))
- return False;
+ prs_uint32("ptr_uni_type", ps, depth, &(r_r->ptr_uni_type));
+ smb_io_buffer2("uni_type", r_r->uni_type, r_r->ptr_uni_type, ps, depth);
+ prs_align(ps);
- if (r_r->ptr3 != 0) {
- if(!prs_uint32("unknown_1", ps, depth, &r_r->unknown_1))
- return False;
- }
+ prs_uint32("ptr_max_len", ps, depth, &(r_r->ptr_max_len));
+ if (r_r->ptr_max_len != 0)
+ {
+ prs_uint32("buf_max_len", ps, depth, &(r_r->buf_max_len));
+ }
+ prs_uint32("ptr_len", ps, depth, &(r_r->ptr_len));
+ if (r_r->ptr_len != 0)
+ {
+ prs_uint32("buf_len", ps, depth, &(r_r->buf_len));
}
- if(!prs_uint32("status", ps, depth, &r_r->status))
- return False;
+
+ prs_uint32("status", ps, depth, &(r_r->status));
return True;
}
@@ -1037,17 +969,20 @@ BOOL reg_io_r_info(char *desc, REG_R_INFO *r_r, prs_struct *ps, int depth)
/*******************************************************************
makes a structure.
********************************************************************/
-
-void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
+BOOL make_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
uint32 val_idx, uint32 max_val_len,
uint32 max_buf_len)
{
+ if (q_i == NULL) return False;
+
ZERO_STRUCTP(q_i);
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
q_i->val_index = val_idx;
- init_uni_hdr(&q_i->hdr_name, max_val_len);
+ q_i->hdr_name.uni_str_len = 0;
+ q_i->hdr_name.uni_max_len = max_val_len * 2;
+ q_i->hdr_name.buffer = max_val_len > 0 ? 1 : 0;
q_i->uni_name.uni_max_len = max_val_len;
q_i->ptr_type = 1;
@@ -1061,61 +996,49 @@ void init_reg_q_enum_val(REG_Q_ENUM_VALUE *q_i, POLICY_HND *pol,
q_i->ptr2 = 1;
q_i->len_value2 = 0;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int depth)
{
- if (q_q == NULL)
- return False;
+ if (q_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_enum_val");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
- if(!prs_uint32("val_index", ps, depth, &q_q->val_index))
- return False;
- if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_type", ps, depth, &q_q->ptr_type))
- return False;
-
- if (q_q->ptr_type != 0) {
- if(!prs_uint32("type", ps, depth, &q_q->type))
- return False;
+ prs_uint32("val_index", ps, depth, &(q_q->val_index));
+ smb_io_unihdr ("hdr_name", &(q_q->hdr_name), ps, depth);
+ smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("ptr_type", ps, depth, &(q_q->ptr_type));
+
+ if (q_q->ptr_type != 0)
+ {
+ prs_uint32("type", ps, depth, &(q_q->type));
}
- if(!prs_uint32("ptr_value", ps, depth, &q_q->ptr_value))
- return False;
- if(!smb_io_buffer2("buf_value", &q_q->buf_value, q_q->ptr_value, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr1", ps, depth, &q_q->ptr1))
- return False;
- if (q_q->ptr1 != 0) {
- if(!prs_uint32("len_value1", ps, depth, &q_q->len_value1))
- return False;
+ prs_uint32("ptr_value", ps, depth, &(q_q->ptr_value));
+ smb_io_buffer2("buf_value", &(q_q->buf_value), q_q->ptr_value, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("ptr1", ps, depth, &(q_q->ptr1));
+ if (q_q->ptr1 != 0)
+ {
+ prs_uint32("len_value1", ps, depth, &(q_q->len_value1));
}
- if(!prs_uint32("ptr2", ps, depth, &q_q->ptr2))
- return False;
- if (q_q->ptr2 != 0) {
- if(!prs_uint32("len_value2", ps, depth, &q_q->len_value2))
- return False;
+ prs_uint32("ptr2", ps, depth, &(q_q->ptr2));
+ if (q_q->ptr2 != 0)
+ {
+ prs_uint32("len_value2", ps, depth, &(q_q->len_value2));
}
return True;
@@ -1124,56 +1047,43 @@ BOOL reg_io_q_enum_val(char *desc, REG_Q_ENUM_VALUE *q_q, prs_struct *ps, int d
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_enum_val");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unihdr ("hdr_name", &r_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_name", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_type", ps, depth, &r_q->ptr_type))
- return False;
-
- if (r_q->ptr_type != 0) {
- if(!prs_uint32("type", ps, depth, &r_q->type))
- return False;
+ smb_io_unihdr ("hdr_name", &(r_q->hdr_name), ps, depth);
+ smb_io_unistr2("uni_name", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("ptr_type", ps, depth, &(r_q->ptr_type));
+
+ if (r_q->ptr_type != 0)
+ {
+ prs_uint32("type", ps, depth, &(r_q->type));
}
- if(!prs_uint32("ptr_value", ps, depth, &r_q->ptr_value))
- return False;
- if(!smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
- return False;
- if (r_q->ptr1 != 0) {
- if(!prs_uint32("len_value1", ps, depth, &r_q->len_value1))
- return False;
+ prs_uint32("ptr_value", ps, depth, &(r_q->ptr_value));
+ smb_io_buffer2("buf_value", r_q->buf_value, r_q->ptr_value, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("ptr1", ps, depth, &(r_q->ptr1));
+ if (r_q->ptr1 != 0)
+ {
+ prs_uint32("len_value1", ps, depth, &(r_q->len_value1));
}
- if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
- return False;
- if (r_q->ptr2 != 0) {
- if(!prs_uint32("len_value2", ps, depth, &r_q->len_value2))
- return False;
+ prs_uint32("ptr2", ps, depth, &(r_q->ptr2));
+ if (r_q->ptr2 != 0)
+ {
+ prs_uint32("len_value2", ps, depth, &(r_q->len_value2));
}
- if(!prs_uint32("status", ps, depth, &r_q->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_q->status));
return True;
}
@@ -1181,55 +1091,48 @@ BOOL reg_io_r_enum_val(char *desc, REG_R_ENUM_VALUE *r_q, prs_struct *ps, int d
/*******************************************************************
makes a structure.
********************************************************************/
-
-void init_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
+BOOL make_reg_q_create_val(REG_Q_CREATE_VALUE *q_i, POLICY_HND *pol,
char *val_name, uint32 type,
BUFFER3 *val)
{
int val_len = strlen(val_name) + 1;
+ if (q_i == NULL) return False;
+
ZERO_STRUCTP(q_i);
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
- init_uni_hdr(&q_i->hdr_name, val_len);
- init_unistr2(&q_i->uni_name, val_name, val_len);
+ make_uni_hdr(&q_i->hdr_name, val_len);
+ make_unistr2(&(q_i->uni_name), val_name, val_len);
q_i->type = type;
q_i->buf_value = val;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct *ps, int depth)
{
- if (q_q == NULL)
- return False;
+ if (q_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_create_val");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
- if(!smb_io_unihdr ("hdr_name", &q_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_name", &q_q->uni_name, q_q->hdr_name.buffer, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("type", ps, depth, &q_q->type))
- return False;
- if(!smb_io_buffer3("buf_value", q_q->buf_value, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_unihdr ("hdr_name", &(q_q->hdr_name), ps, depth);
+ smb_io_unistr2("uni_name", &(q_q->uni_name), q_q->hdr_name.buffer, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("type", ps, depth, &(q_q->type));
+ smb_io_buffer3("buf_value", q_q->buf_value, ps, depth);
+ prs_align(ps);
return True;
}
@@ -1237,20 +1140,16 @@ BOOL reg_io_q_create_val(char *desc, REG_Q_CREATE_VALUE *q_q, prs_struct *ps, i
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_create_val");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_q->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_q->status));
return True;
}
@@ -1258,10 +1157,11 @@ BOOL reg_io_r_create_val(char *desc, REG_R_CREATE_VALUE *r_q, prs_struct *ps, i
/*******************************************************************
makes a structure.
********************************************************************/
-
-void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
+BOOL make_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
{
- memcpy(&q_i->pol, pol, sizeof(q_i->pol));
+ if (q_i == NULL) return False;
+
+ memcpy(&(q_i->pol), pol, sizeof(q_i->pol));
q_i->key_index = key_idx;
q_i->key_name_len = 0;
@@ -1275,58 +1175,49 @@ void init_reg_q_enum_key(REG_Q_ENUM_KEY *q_i, POLICY_HND *pol, uint32 key_idx)
memset(q_i->pad2, 0, sizeof(q_i->pad2));
q_i->ptr3 = 1;
- unix_to_nt_time(&q_i->time, 0); /* current time? */
+ init_nt_time(&(q_i->time)); /* ignored ? */
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, int depth)
{
- if (q_q == NULL)
- return False;
+ if (q_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_enum_key");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &q_q->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(q_q->pol), ps, depth);
- if(!prs_uint32("key_index", ps, depth, &q_q->key_index))
- return False;
- if(!prs_uint16("key_name_len", ps, depth, &q_q->key_name_len))
- return False;
- if(!prs_uint16("unknown_1", ps, depth, &q_q->unknown_1))
- return False;
-
- if(!prs_uint32("ptr1", ps, depth, &q_q->ptr1))
- return False;
-
- if (q_q->ptr1 != 0) {
- if(!prs_uint32("unknown_2", ps, depth, &q_q->unknown_2))
- return False;
- if(!prs_uint8s(False, "pad1", ps, depth, q_q->pad1, sizeof(q_q->pad1)))
- return False;
+ prs_uint32("key_index", ps, depth, &(q_q->key_index));
+ prs_uint16("key_name_len", ps, depth, &(q_q->key_name_len));
+ prs_uint16("unknown_1", ps, depth, &(q_q->unknown_1));
+
+ prs_uint32("ptr1", ps, depth, &(q_q->ptr1));
+
+ if (q_q->ptr1 != 0)
+ {
+ prs_uint32("unknown_2", ps, depth, &(q_q->unknown_2));
+ prs_uint8s(False, "pad1", ps, depth, q_q->pad1, sizeof(q_q->pad1));
}
- if(!prs_uint32("ptr2", ps, depth, &q_q->ptr2))
- return False;
+ prs_uint32("ptr2", ps, depth, &(q_q->ptr2));
- if (q_q->ptr2 != 0) {
- if(!prs_uint8s(False, "pad2", ps, depth, q_q->pad2, sizeof(q_q->pad2)))
- return False;
+ if (q_q->ptr2 != 0)
+ {
+ prs_uint8s(False, "pad2", ps, depth, q_q->pad2, sizeof(q_q->pad2));
}
- if(!prs_uint32("ptr3", ps, depth, &q_q->ptr3))
- return False;
+ prs_uint32("ptr3", ps, depth, &(q_q->ptr3));
- if (q_q->ptr3 != 0) {
- if(!smb_io_time("", &q_q->time, ps, depth))
- return False;
+ if (q_q->ptr3 != 0)
+ {
+ smb_io_time("", &(q_q->time), ps, depth);
}
return True;
@@ -1335,141 +1226,193 @@ BOOL reg_io_q_enum_key(char *desc, REG_Q_ENUM_KEY *q_q, prs_struct *ps, int dep
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_enum_key(char *desc, REG_R_ENUM_KEY *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_enum_key");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint16("key_name_len", ps, depth, &r_q->key_name_len))
- return False;
- if(!prs_uint16("unknown_1", ps, depth, &r_q->unknown_1))
- return False;
-
- if(!prs_uint32("ptr1", ps, depth, &r_q->ptr1))
- return False;
-
- if (r_q->ptr1 != 0) {
- if(!prs_uint32("unknown_2", ps, depth, &r_q->unknown_2))
- return False;
- if(!prs_uint32("unknown_3", ps, depth, &r_q->unknown_3))
- return False;
- if(!smb_io_unistr3("key_name", &r_q->key_name, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint16("key_name_len", ps, depth, &(r_q->key_name_len));
+ prs_uint16("unknown_1", ps, depth, &(r_q->unknown_1));
+
+ prs_uint32("ptr1", ps, depth, &(r_q->ptr1));
+
+ if (r_q->ptr1 != 0)
+ {
+ prs_uint32("unknown_2", ps, depth, &(r_q->unknown_2));
+ prs_uint32("unknown_3", ps, depth, &(r_q->unknown_3));
+ smb_io_unistr3("key_name", &(r_q->key_name), ps, depth);
+ prs_align(ps);
}
- if(!prs_uint32("ptr2", ps, depth, &r_q->ptr2))
- return False;
+ prs_uint32("ptr2", ps, depth, &(r_q->ptr2));
- if (r_q->ptr2 != 0) {
- if(!prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2)))
- return False;
+ if (r_q->ptr2 != 0)
+ {
+ prs_uint8s(False, "pad2", ps, depth, r_q->pad2, sizeof(r_q->pad2));
}
- if(!prs_uint32("ptr3", ps, depth, &r_q->ptr3))
- return False;
+ prs_uint32("ptr3", ps, depth, &(r_q->ptr3));
- if (r_q->ptr3 != 0) {
- if(!smb_io_time("", &r_q->time, ps, depth))
- return False;
+ if (r_q->ptr3 != 0)
+ {
+ smb_io_time("", &(r_q->time), ps, depth);
}
- if(!prs_uint32("status", ps, depth, &r_q->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_q->status));
return True;
}
+
/*******************************************************************
makes a structure.
********************************************************************/
-
-void init_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
- char *key_name, uint32 unk)
+BOOL make_reg_q_open_entry(REG_Q_OPEN_ENTRY *r_q, POLICY_HND *pol,
+ char *key_name, uint32 access_mask)
{
int len_name = strlen(key_name)+1;
- memcpy(&r_q->pol, pol, sizeof(r_q->pol));
+ if (r_q == NULL) return False;
+
+ memcpy(&(r_q->pol), pol, sizeof(r_q->pol));
- init_uni_hdr(&r_q->hdr_name, len_name);
- init_unistr2(&r_q->uni_name, key_name, len_name);
+ make_uni_hdr(&(r_q->hdr_name), len_name);
+ make_unistr2(&(r_q->uni_name), key_name, len_name);
r_q->unknown_0 = 0x00000000;
- r_q->unknown_1 = unk;
+ r_q->access_mask = access_mask;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_q_open_entry(char *desc, REG_Q_OPEN_ENTRY *r_q, prs_struct *ps, int depth)
{
- if (r_q == NULL)
- return False;
+ if (r_q == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_q_entry");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_q->pol, ps, depth))
- return False;
- if(!smb_io_unihdr ("", &r_q->hdr_name, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_q->uni_name, r_q->hdr_name.buffer, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("", &(r_q->pol), ps, depth);
+ smb_io_unihdr ("", &(r_q->hdr_name), ps, depth);
+ smb_io_unistr2("", &(r_q->uni_name), r_q->hdr_name.buffer, ps, depth);
+
+ prs_align(ps);
- if(!prs_uint32("unknown_0", ps, depth, &r_q->unknown_0))
- return False;
- if(!prs_uint32("unknown_1", ps, depth, &r_q->unknown_1))
- return False;
+ prs_uint32("unknown_0", ps, depth, &(r_q->unknown_0));
+ prs_uint32("access_mask", ps, depth, &(r_q->access_mask));
return True;
}
+
/*******************************************************************
- Inits a structure.
+creates a structure.
********************************************************************/
-
-void init_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
+BOOL make_reg_r_open_entry(REG_R_OPEN_ENTRY *r_r,
POLICY_HND *pol, uint32 status)
{
- memcpy(&r_r->pol, pol, sizeof(r_r->pol));
+ if (r_r == NULL) return False;
+
+ memcpy(&(r_r->pol), pol, sizeof(r_r->pol));
r_r->status = status;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
BOOL reg_io_r_open_entry(char *desc, REG_R_OPEN_ENTRY *r_r, prs_struct *ps, int depth)
{
- if (r_r == NULL)
- return False;
+ if (r_r == NULL) return False;
prs_debug(ps, depth, desc, "reg_io_r_open_entry");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("", &r_r->pol, ps, depth))
- return False;
+ smb_io_pol_hnd("", &(r_r->pol), ps, depth);
- if(!prs_uint32("status", ps, depth, &r_r->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_r->status));
return True;
}
+
+/*******************************************************************
+makes a structure.
+********************************************************************/
+BOOL make_reg_q_shutdown(REG_Q_SHUTDOWN *q_i,
+ const char *msg, uint32 timeout, uint16 flags)
+{
+ int len = strlen(msg) + 1;
+
+ if (q_i == NULL) return False;
+
+ ZERO_STRUCTP(q_i);
+
+ q_i->ptr_0 = 1;
+ q_i->ptr_1 = 1;
+ q_i->ptr_2 = 1;
+
+ make_uni_hdr(&q_i->hdr_msg, len);
+ make_unistr2(&(q_i->uni_msg), msg, len);
+
+ q_i->timeout = timeout;
+ q_i->flags = flags;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL reg_io_q_shutdown(char *desc, REG_Q_SHUTDOWN *q_q, prs_struct *ps, int depth)
+{
+ if (q_q == NULL) return False;
+
+ prs_debug(ps, depth, desc, "reg_io_q_shutdown");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_0", ps, depth, &(q_q->ptr_0));
+ prs_uint32("ptr_1", ps, depth, &(q_q->ptr_1));
+ prs_uint32("ptr_2", ps, depth, &(q_q->ptr_2));
+
+ smb_io_unihdr ("hdr_msg", &(q_q->hdr_msg), ps, depth);
+ smb_io_unistr2("uni_msg", &(q_q->uni_msg), q_q->hdr_msg.buffer, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("timeout", ps, depth, &(q_q->timeout));
+ prs_uint16("flags ", ps, depth, &(q_q->flags ));
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL reg_io_r_shutdown(char *desc, REG_R_SHUTDOWN *r_q, prs_struct *ps, int depth)
+{
+ if (r_q == NULL) return False;
+
+ prs_debug(ps, depth, desc, "reg_io_r_shutdown");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_q->status));
+
+ return True;
+}
+
diff --git a/source/rpc_parse/parse_rpc.c b/source/rpc_parse/parse_rpc.c
index 54d3eea74d8..18ba14a0630 100644
--- a/source/rpc_parse/parse_rpc.c
+++ b/source/rpc_parse/parse_rpc.c
@@ -3,10 +3,9 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jeremy Allison 1999.
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Paul Ashton 1997-1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,6 +24,7 @@
#include "includes.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
@@ -33,475 +33,556 @@ extern int DEBUGLEVEL;
interface/version dce/rpc pipe identification
********************************************************************/
-#define TRANS_SYNT_V2 \
-{ \
- { \
- 0x8a885d04, 0x1ceb, 0x11c9, \
- { 0x9f, 0xe8, 0x08, 0x00, \
- 0x2b, 0x10, 0x48, 0x60 } \
- }, 0x02 \
-}
-
-#define SYNT_NETLOGON_V2 \
-{ \
- { \
- 0x8a885d04, 0x1ceb, 0x11c9, \
- { 0x9f, 0xe8, 0x08, 0x00, \
- 0x2b, 0x10, 0x48, 0x60 } \
- }, 0x02 \
-}
-
-#define SYNT_WKSSVC_V1 \
-{ \
- { \
- 0x6bffd098, 0xa112, 0x3610, \
- { 0x98, 0x33, 0x46, 0xc3, \
- 0xf8, 0x7e, 0x34, 0x5a } \
- }, 0x01 \
-}
-
-#define SYNT_SRVSVC_V3 \
-{ \
- { \
- 0x4b324fc8, 0x1670, 0x01d3, \
- { 0x12, 0x78, 0x5a, 0x47, \
- 0xbf, 0x6e, 0xe1, 0x88 } \
- }, 0x03 \
-}
-
-#define SYNT_LSARPC_V0 \
-{ \
- { \
- 0x12345778, 0x1234, 0xabcd, \
- { 0xef, 0x00, 0x01, 0x23, \
- 0x45, 0x67, 0x89, 0xab } \
- }, 0x00 \
-}
-
-#define SYNT_SAMR_V1 \
-{ \
- { \
- 0x12345778, 0x1234, 0xabcd, \
- { 0xef, 0x00, 0x01, 0x23, \
- 0x45, 0x67, 0x89, 0xac } \
- }, 0x01 \
-}
-
-#define SYNT_NETLOGON_V1 \
-{ \
- { \
- 0x12345678, 0x1234, 0xabcd, \
- { 0xef, 0x00, 0x01, 0x23, \
- 0x45, 0x67, 0xcf, 0xfb } \
- }, 0x01 \
-}
-
-#define SYNT_WINREG_V1 \
-{ \
- { \
- 0x338cd001, 0x2244, 0x31f1, \
- { 0xaa, 0xaa, 0x90, 0x00, \
- 0x38, 0x00, 0x10, 0x03 } \
- }, 0x01 \
-}
-
-#define SYNT_SPOOLSS_V1 \
-{ \
- { \
- 0x12345678, 0x1234, 0xabcb, \
- { 0xef, 0x00, 0x01, 0x23, \
- 0x45, 0x67, 0x89, 0xab } \
- }, 0x01 \
-}
-
-#define SYNT_NONE_V0 \
-{ \
- { \
- 0x0, 0x0, 0x0, \
- { 0x00, 0x00, 0x00, 0x00, \
- 0x00, 0x00, 0x00, 0x00 } \
- }, 0x00 \
-}
-
+#define TRANS_SYNT_V2 \
+{ \
+ { \
+ 0x04, 0x5d, 0x88, 0x8a, \
+ 0xeb, 0x1c, 0xc9, 0x11, \
+ 0x9f, 0xe8, 0x08, 0x00, \
+ 0x2b, 0x10, 0x48, 0x60 \
+ }, 0x02 \
+} \
+
+#define SYNT_SVCCTL_V2 \
+{ \
+ { \
+ 0x81, 0xbb, 0x7a, 0x36, \
+ 0x44, 0x98, 0xf1, 0x35, \
+ 0xad, 0x32, 0x98, 0xf0, \
+ 0x38, 0x00, 0x10, 0x03 \
+ }, 0x02 \
+} \
+
+#define SYNT_BROWSER_V0 \
+{ \
+ { \
+ 0x98, 0xd0, 0xff, 0x6b, \
+ 0x12, 0xa1, 0x10, 0x36, \
+ 0x98, 0x33, 0x01, 0x28, \
+ 0x92, 0x02, 0x01, 0x62 \
+ }, 0x00 \
+} \
+
+#define SYNT_NETLOGON_V2 \
+{ \
+ { \
+ 0x04, 0x5d, 0x88, 0x8a, \
+ 0xeb, 0x1c, 0xc9, 0x11, \
+ 0x9f, 0xe8, 0x08, 0x00, \
+ 0x2b, 0x10, 0x48, 0x60 \
+ }, 0x02 \
+} \
+
+#define SYNT_WKSSVC_V1 \
+{ \
+ { \
+ 0x98, 0xd0, 0xff, 0x6b, \
+ 0x12, 0xa1, 0x10, 0x36, \
+ 0x98, 0x33, 0x46, 0xc3, \
+ 0xf8, 0x7e, 0x34, 0x5a \
+ }, 0x01 \
+} \
+
+#define SYNT_SRVSVC_V3 \
+{ \
+ { \
+ 0xc8, 0x4f, 0x32, 0x4b, \
+ 0x70, 0x16, 0xd3, 0x01, \
+ 0x12, 0x78, 0x5a, 0x47, \
+ 0xbf, 0x6e, 0xe1, 0x88 \
+ }, 0x03 \
+} \
+
+#define SYNT_LSARPC_V0 \
+{ \
+ { \
+ 0x78, 0x57, 0x34, 0x12, \
+ 0x34, 0x12, 0xcd, 0xab, \
+ 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0x89, 0xab \
+ }, 0x00 \
+} \
+
+#define SYNT_SAMR_V1 \
+{ \
+ { \
+ 0x78, 0x57, 0x34, 0x12, \
+ 0x34, 0x12, 0xcd, 0xab, \
+ 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0x89, 0xac \
+ }, 0x01 \
+} \
+
+#define SYNT_NETLOGON_V1 \
+{ \
+ { \
+ 0x78, 0x56, 0x34, 0x12, \
+ 0x34, 0x12, 0xcd, 0xab, \
+ 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0xcf, 0xfb \
+ }, 0x01 \
+} \
+
+#define SYNT_WINREG_V1 \
+{ \
+ { \
+ 0x01, 0xd0, 0x8c, 0x33, \
+ 0x44, 0x22, 0xf1, 0x31, \
+ 0xaa, 0xaa, 0x90, 0x00, \
+ 0x38, 0x00, 0x10, 0x03 \
+ }, 0x01 \
+} \
+
+#define SYNT_ATSVC_V1 \
+{ \
+ { \
+ 0x82, 0x06, 0xf7, 0x1f, \
+ 0x51, 0x0a, 0xe8, 0x30, \
+ 0x07, 0x6d, 0x74, 0x0b, \
+ 0xe8, 0xce, 0xe9, 0x8b \
+ }, 0x01 \
+} \
+
+#define SYNT_SPOOLSS_V1 \
+{ \
+ { \
+ 0x78, 0x56, 0x34, 0x12, \
+ 0x34, 0x12, 0xcd, 0xab, \
+ 0xef, 0x00, 0x01, 0x23, \
+ 0x45, 0x67, 0x89, 0xab \
+ }, 0x01 \
+} \
+
+#define SYNT_NONE_V0 \
+{ \
+ { \
+ 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00, \
+ 0x00, 0x00, 0x00, 0x00 \
+ }, 0x00 \
+} \
+
+#define SYNT_EVENTLOG_V0 \
+{ \
+ { \
+ 0xdc, 0x3f, 0x27, 0x82, \
+ 0x2a, 0xe3, 0xc3, 0x18, \
+ 0x3f, 0x78, 0x82, 0x79, \
+ 0x29, 0xdc, 0x23, 0xea \
+ }, 0x00 \
+}
+ \
struct pipe_id_info pipe_names [] =
{
/* client pipe , abstract syntax , server pipe , transfer syntax */
{ PIPE_LSARPC , SYNT_LSARPC_V0 , PIPE_LSASS , TRANS_SYNT_V2 },
+ { PIPE_BROWSER , SYNT_BROWSER_V0 , PIPE_NTSVCS , TRANS_SYNT_V2 },
{ PIPE_SAMR , SYNT_SAMR_V1 , PIPE_LSASS , TRANS_SYNT_V2 },
{ PIPE_NETLOGON, SYNT_NETLOGON_V1, PIPE_LSASS , TRANS_SYNT_V2 },
{ PIPE_SRVSVC , SYNT_SRVSVC_V3 , PIPE_NTSVCS , TRANS_SYNT_V2 },
+ { PIPE_SVCCTL , SYNT_SVCCTL_V2 , PIPE_NTSVCS , TRANS_SYNT_V2 },
{ PIPE_WKSSVC , SYNT_WKSSVC_V1 , PIPE_NTSVCS , TRANS_SYNT_V2 },
{ PIPE_WINREG , SYNT_WINREG_V1 , PIPE_WINREG , TRANS_SYNT_V2 },
+ { PIPE_ATSVC , SYNT_ATSVC_V1 , PIPE_ATSVC , TRANS_SYNT_V2 },
{ PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS , TRANS_SYNT_V2 },
+ { PIPE_EVENTLOG, SYNT_EVENTLOG_V0, PIPE_EVENTLOG , TRANS_SYNT_V2 },
{ NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 }
};
/*******************************************************************
- Inits an RPC_HDR structure.
+creates an RPC_HDR structure.
********************************************************************/
-
-void init_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
+BOOL make_rpc_hdr(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, uint8 flags,
uint32 call_id, int data_len, int auth_len)
{
+ if (hdr == NULL) return False;
+
hdr->major = 5; /* RPC version 5 */
hdr->minor = 0; /* minor version 0 */
hdr->pkt_type = pkt_type; /* RPC packet type */
hdr->flags = flags; /* dce/rpc flags */
- hdr->pack_type[0] = 0x10; /* little-endian data representation */
- hdr->pack_type[1] = 0; /* packed data representation */
- hdr->pack_type[2] = 0; /* packed data representation */
- hdr->pack_type[3] = 0; /* packed data representation */
+ hdr->pack_type[0] = 0x10; /* packed data - intel-endian */
+ hdr->pack_type[1] = 0x0; /* packed data representation */
+ hdr->pack_type[2] = 0x0; /* packed data representation */
+ hdr->pack_type[3] = 0x0; /* packed data representation */
hdr->frag_len = data_len; /* fragment length, fill in later */
hdr->auth_len = auth_len; /* authentication length */
hdr->call_id = call_id; /* call identifier - match incoming RPC */
+
+ return True;
}
/*******************************************************************
- Reads or writes an RPC_HDR structure.
+reads or writes an RPC_HDR structure.
********************************************************************/
-
BOOL smb_io_rpc_hdr(char *desc, RPC_HDR *rpc, prs_struct *ps, int depth)
{
- if (rpc == NULL)
- return False;
+ if (rpc == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_hdr");
depth++;
- if(!prs_uint8 ("major ", ps, depth, &rpc->major))
- return False;
+ prs_uint8 ("major ", ps, depth, &rpc->major);
+ prs_uint8 ("minor ", ps, depth, &rpc->minor);
+ prs_uint8 ("pkt_type ", ps, depth, &rpc->pkt_type);
+ prs_uint8 ("flags ", ps, depth, &rpc->flags);
+ prs_uint8s(False, "pack_type ", ps, depth, rpc->pack_type,
+ sizeof(rpc->pack_type));
+ if (ps->io)
+ {
+ /* reading - set packed data representation type */
+ prs_set_packtype(ps, rpc->pack_type);
+ }
- if(!prs_uint8 ("minor ", ps, depth, &rpc->minor))
- return False;
- if(!prs_uint8 ("pkt_type ", ps, depth, &rpc->pkt_type))
- return False;
- if(!prs_uint8 ("flags ", ps, depth, &rpc->flags))
- return False;
- if(!prs_uint8("pack_type0", ps, depth, &rpc->pack_type[0]))
- return False;
- if(!prs_uint8("pack_type1", ps, depth, &rpc->pack_type[1]))
- return False;
- if(!prs_uint8("pack_type2", ps, depth, &rpc->pack_type[2]))
- return False;
- if(!prs_uint8("pack_type3", ps, depth, &rpc->pack_type[3]))
- return False;
+ prs_uint16("frag_len ", ps, depth, &rpc->frag_len);
+ prs_uint16("auth_len ", ps, depth, &rpc->auth_len);
+ prs_uint32("call_id ", ps, depth, &rpc->call_id);
- /*
- * If reading and pack_type[0] == 0 then the data is in big-endian
- * format. Set the flag in the prs_struct to specify reverse-endainness.
- */
+ return True;
+}
- if (ps->io && rpc->pack_type[0] == 0) {
- DEBUG(10,("smb_io_rpc_hdr: PDU data format is big-endian. Setting flag.\n"));
- prs_set_bigendian_data(ps);
- }
+/*******************************************************************
+checks a PDU structure.
+********************************************************************/
+BOOL is_complete_pdu(prs_struct *ps)
+{
+ RPC_HDR hdr;
+ int len = ps->data_size;
- if(!prs_uint16("frag_len ", ps, depth, &rpc->frag_len))
- return False;
- if(!prs_uint16("auth_len ", ps, depth, &rpc->auth_len))
+ DEBUG(10,("is_complete_pdu - len %d\n", len));
+ ps->offset = 0x0;
+
+ if (!ps->io)
+ {
+ /* writing. oops!! */
+ DEBUG(4,("is_complete_pdu: write set, not read!\n"));
return False;
- if(!prs_uint32("call_id ", ps, depth, &rpc->call_id))
+ }
+
+ if (!smb_io_rpc_hdr("hdr", &hdr, ps, 0))
+ {
return False;
+ }
+
+ DEBUG(10,("is_complete_pdu - frag_len %d\n", hdr.frag_len));
+
+ /* check that the fragment length is equal to the data length so far */
+ return hdr.frag_len == len;
+}
+
+/*******************************************************************
+reads or writes an RPC_HDR_NACK structure.
+********************************************************************/
+BOOL smb_io_rpc_hdr_nack(char *desc, RPC_HDR_NACK *rpc, prs_struct *ps, int depth)
+{
+ if (rpc == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_hdr_nack");
+ depth++;
+
+ prs_uint16("rej_code", ps, depth, &(rpc->rej_code));
+
return True;
}
/*******************************************************************
- Reads or writes an RPC_IFACE structure.
+reads or writes an RPC_HDR_FAULT structure.
********************************************************************/
+BOOL smb_io_rpc_hdr_fault(char *desc, RPC_HDR_FAULT *rpc, prs_struct *ps, int depth)
+{
+ if (rpc == NULL) return False;
+
+ prs_debug(ps, depth, desc, "smb_io_rpc_hdr_fault");
+ depth++;
+
+ prs_uint32("status ", ps, depth, &(rpc->status ));
+ prs_uint32("reserved", ps, depth, &(rpc->reserved));
-static BOOL smb_io_rpc_iface(char *desc, RPC_IFACE *ifc, prs_struct *ps, int depth)
+ return True;
+}
+
+/*******************************************************************
+reads or writes an RPC_IFACE structure.
+********************************************************************/
+static BOOL smb_io_rpc_iface(char *desc, RPC_IFACE *ifc, prs_struct *ps, int depth)
{
- if (ifc == NULL)
- return False;
+ if (ifc == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_iface");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32 ("data ", ps, depth, &ifc->uuid.time_low))
- return False;
- if(!prs_uint16 ("data ", ps, depth, &ifc->uuid.time_mid))
- return False;
- if(!prs_uint16 ("data ", ps, depth, &ifc->uuid.time_hi_and_version))
- return False;
-
- if(!prs_uint8s (False, "data ", ps, depth, ifc->uuid.remaining, sizeof(ifc->uuid.remaining)))
- return False;
- if(!prs_uint32 ( "version", ps, depth, &(ifc->version)))
- return False;
+ prs_uint8s (False, "data ", ps, depth, ifc->data, sizeof(ifc->data));
+ prs_uint32 ( "version", ps, depth, &(ifc->version));
return True;
}
/*******************************************************************
- Inits an RPC_ADDR_STR structure.
-********************************************************************/
+creates an RPC_ADDR_STR structure.
-static void init_rpc_addr_str(RPC_ADDR_STR *str, char *name)
+The name can be null (RPC Alter-Context)
+********************************************************************/
+static BOOL make_rpc_addr_str(RPC_ADDR_STR *str, const char *name)
{
- str->len = strlen(name) + 1;
- fstrcpy(str->str, name);
+ if (str == NULL ) return False;
+ if (name == NULL)
+ {
+ str->len = 1;
+ fstrcpy(str->str, "");
+ }
+ else
+ {
+ str->len = strlen(name) + 1;
+ fstrcpy(str->str, name);
+ }
+
+ return True;
}
/*******************************************************************
- Reads or writes an RPC_ADDR_STR structure.
+reads or writes an RPC_ADDR_STR structure.
********************************************************************/
-
static BOOL smb_io_rpc_addr_str(char *desc, RPC_ADDR_STR *str, prs_struct *ps, int depth)
{
- if (str == NULL)
- return False;
+ if (str == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_addr_str");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint16 ( "len", ps, depth, &(str->len));
+ prs_uint8s (True, "str", ps, depth, (uchar*)str->str, str->len);
- if(!prs_uint16 ( "len", ps, depth, &str->len))
- return False;
- if(!prs_uint8s (True, "str", ps, depth, (uchar*)str->str, MIN(str->len, sizeof(str->str)) ))
- return False;
return True;
}
/*******************************************************************
- Inits an RPC_HDR_BBA structure.
+creates an RPC_HDR_BBA structure.
********************************************************************/
-
-static void init_rpc_hdr_bba(RPC_HDR_BBA *bba, uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid)
+static BOOL make_rpc_hdr_bba(RPC_HDR_BBA *bba, uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid)
{
+ if (bba == NULL) return False;
+
bba->max_tsize = max_tsize; /* maximum transmission fragment size (0x1630) */
bba->max_rsize = max_rsize; /* max receive fragment size (0x1630) */
bba->assoc_gid = assoc_gid; /* associated group id (0x0) */
+
+ return True;
}
/*******************************************************************
- Reads or writes an RPC_HDR_BBA structure.
+reads or writes an RPC_HDR_BBA structure.
********************************************************************/
-
static BOOL smb_io_rpc_hdr_bba(char *desc, RPC_HDR_BBA *rpc, prs_struct *ps, int depth)
{
- if (rpc == NULL)
- return False;
+ if (rpc == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_hdr_bba");
depth++;
- if(!prs_uint16("max_tsize", ps, depth, &rpc->max_tsize))
- return False;
- if(!prs_uint16("max_rsize", ps, depth, &rpc->max_rsize))
- return False;
- if(!prs_uint32("assoc_gid", ps, depth, &rpc->assoc_gid))
- return False;
+ prs_uint16("max_tsize", ps, depth, &(rpc->max_tsize));
+ prs_uint16("max_rsize", ps, depth, &(rpc->max_rsize));
+ prs_uint32("assoc_gid", ps, depth, &(rpc->assoc_gid));
+
return True;
}
/*******************************************************************
- Inits an RPC_HDR_RB structure.
+creates an RPC_HDR_RB structure.
********************************************************************/
-
-void init_rpc_hdr_rb(RPC_HDR_RB *rpc,
+BOOL make_rpc_hdr_rb(RPC_HDR_RB *rpc,
uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
uint32 num_elements, uint16 context_id, uint8 num_syntaxes,
RPC_IFACE *abstract, RPC_IFACE *transfer)
{
- init_rpc_hdr_bba(&rpc->bba, max_tsize, max_rsize, assoc_gid);
+ if (rpc == NULL) return False;
+
+ make_rpc_hdr_bba(&(rpc->bba), max_tsize, max_rsize, assoc_gid);
rpc->num_elements = num_elements ; /* the number of elements (0x1) */
rpc->context_id = context_id ; /* presentation context identifier (0x0) */
rpc->num_syntaxes = num_syntaxes ; /* the number of syntaxes (has always been 1?)(0x1) */
/* num and vers. of interface client is using */
- rpc->abstract = *abstract;
+ memcpy(&(rpc->abstract), abstract, sizeof(rpc->abstract));
/* num and vers. of interface to use for replies */
- rpc->transfer = *transfer;
+ memcpy(&(rpc->transfer), transfer, sizeof(rpc->transfer));
+
+ return True;
}
/*******************************************************************
- Reads or writes an RPC_HDR_RB structure.
+reads or writes an RPC_HDR_RB structure.
********************************************************************/
-
-BOOL smb_io_rpc_hdr_rb(char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth)
+BOOL smb_io_rpc_hdr_rb(char *desc, RPC_HDR_RB *rpc, prs_struct *ps, int depth)
{
- if (rpc == NULL)
- return False;
+ if (rpc == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_hdr_rb");
depth++;
- if(!smb_io_rpc_hdr_bba("", &rpc->bba, ps, depth))
- return False;
+ smb_io_rpc_hdr_bba("", &(rpc->bba), ps, depth);
- if(!prs_uint32("num_elements", ps, depth, &rpc->num_elements))
- return False;
- if(!prs_uint16("context_id ", ps, depth, &rpc->context_id ))
- return False;
- if(!prs_uint8 ("num_syntaxes", ps, depth, &rpc->num_syntaxes))
- return False;
+ prs_uint32("num_elements", ps, depth, &(rpc->num_elements));
+ prs_uint16("context_id ", ps, depth, &(rpc->context_id ));
+ prs_uint8 ("num_syntaxes", ps, depth, &(rpc->num_syntaxes));
- if(!smb_io_rpc_iface("", &rpc->abstract, ps, depth))
- return False;
- if(!smb_io_rpc_iface("", &rpc->transfer, ps, depth))
- return False;
+ smb_io_rpc_iface("", &(rpc->abstract), ps, depth);
+ smb_io_rpc_iface("", &(rpc->transfer), ps, depth);
return True;
}
/*******************************************************************
- Inits an RPC_RESULTS structure.
+creates an RPC_RESULTS structure.
- lkclXXXX only one reason at the moment!
-********************************************************************/
+lkclXXXX only one reason at the moment!
-static void init_rpc_results(RPC_RESULTS *res,
+********************************************************************/
+static BOOL make_rpc_results(RPC_RESULTS *res,
uint8 num_results, uint16 result, uint16 reason)
{
+ if (res == NULL) return False;
+
res->num_results = num_results; /* the number of results (0x01) */
res->result = result ; /* result (0x00 = accept) */
res->reason = reason ; /* reason (0x00 = no reason specified) */
+
+ return True;
}
/*******************************************************************
- Reads or writes an RPC_RESULTS structure.
+reads or writes an RPC_RESULTS structure.
- lkclXXXX only one reason at the moment!
-********************************************************************/
+lkclXXXX only one reason at the moment!
-static BOOL smb_io_rpc_results(char *desc, RPC_RESULTS *res, prs_struct *ps, int depth)
+********************************************************************/
+static BOOL smb_io_rpc_results(char *desc, RPC_RESULTS *res, prs_struct *ps, int depth)
{
- if (res == NULL)
- return False;
+ if (res == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_results");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint8 ("num_results", ps, depth, &res->num_results))
- return False;
+ prs_uint8 ("num_results", ps, depth, &(res->num_results));
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint16("result ", ps, depth, &res->result))
- return False;
- if(!prs_uint16("reason ", ps, depth, &res->reason))
- return False;
+ prs_uint16("result ", ps, depth, &(res->result ));
+ prs_uint16("reason ", ps, depth, &(res->reason ));
+
return True;
}
/*******************************************************************
- Init an RPC_HDR_BA structure.
+creates an RPC_HDR_BA structure.
- lkclXXXX only one reason at the moment!
+lkclXXXX only one reason at the moment!
+jfm: nope two ! The pipe_addr can be NULL !
********************************************************************/
-
-void init_rpc_hdr_ba(RPC_HDR_BA *rpc,
+BOOL make_rpc_hdr_ba(RPC_HDR_BA *rpc,
uint16 max_tsize, uint16 max_rsize, uint32 assoc_gid,
- char *pipe_addr,
+ const char *pipe_addr,
uint8 num_results, uint16 result, uint16 reason,
RPC_IFACE *transfer)
{
- init_rpc_hdr_bba (&rpc->bba, max_tsize, max_rsize, assoc_gid);
- init_rpc_addr_str(&rpc->addr, pipe_addr);
- init_rpc_results (&rpc->res, num_results, result, reason);
+ if (rpc == NULL || transfer == NULL) return False;
+
+ make_rpc_hdr_bba (&(rpc->bba ), max_tsize, max_rsize, assoc_gid);
+ make_rpc_addr_str(&(rpc->addr), pipe_addr);
+ make_rpc_results (&(rpc->res ), num_results, result, reason);
/* the transfer syntax from the request */
- memcpy(&rpc->transfer, transfer, sizeof(rpc->transfer));
+ memcpy(&(rpc->transfer), transfer, sizeof(rpc->transfer));
+
+ return True;
}
/*******************************************************************
- Reads or writes an RPC_HDR_BA structure.
+reads or writes an RPC_HDR_BA structure.
********************************************************************/
-
-BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth)
+BOOL smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth)
{
- if (rpc == NULL)
- return False;
+ if (rpc == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_hdr_ba");
depth++;
- if(!smb_io_rpc_hdr_bba("", &rpc->bba, ps, depth))
- return False;
- if(!smb_io_rpc_addr_str("", &rpc->addr, ps, depth))
- return False;
- if(!smb_io_rpc_results("", &rpc->res, ps, depth))
- return False;
- if(!smb_io_rpc_iface("", &rpc->transfer, ps, depth))
- return False;
+ smb_io_rpc_hdr_bba ("", &(rpc->bba) , ps, depth);
+ smb_io_rpc_addr_str("", &(rpc->addr) , ps, depth);
+ smb_io_rpc_results ("", &(rpc->res) , ps, depth);
+ smb_io_rpc_iface ("", &(rpc->transfer), ps, depth);
+
return True;
}
/*******************************************************************
- Init an RPC_HDR_REQ structure.
+creates an RPC_HDR_REQ structure.
********************************************************************/
-
-void init_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 opnum)
+BOOL make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 alloc_hint, uint16 vuid,
+ uint16 opnum)
{
+ if (hdr == NULL) return False;
+
hdr->alloc_hint = alloc_hint; /* allocation hint */
- hdr->context_id = 0; /* presentation context identifier */
+ hdr->context_id = vuid; /* presentation context identifier */
hdr->opnum = opnum; /* opnum */
+
+ return True;
}
/*******************************************************************
- Reads or writes an RPC_HDR_REQ structure.
+reads or writes an RPC_HDR_REQ structure.
********************************************************************/
-
-BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth)
+BOOL smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth)
{
- if (rpc == NULL)
- return False;
+ if (rpc == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_hdr_req");
depth++;
- if(!prs_uint32("alloc_hint", ps, depth, &rpc->alloc_hint))
- return False;
- if(!prs_uint16("context_id", ps, depth, &rpc->context_id))
- return False;
- if(!prs_uint16("opnum ", ps, depth, &rpc->opnum))
- return False;
+ prs_uint32("alloc_hint", ps, depth, &(rpc->alloc_hint));
+ prs_uint16("context_id", ps, depth, &(rpc->context_id));
+ prs_uint16("opnum ", ps, depth, &(rpc->opnum));
+
return True;
}
/*******************************************************************
- Reads or writes an RPC_HDR_RESP structure.
+reads or writes an RPC_HDR_RESP structure.
********************************************************************/
-
-BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth)
+BOOL smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth)
{
- if (rpc == NULL)
- return False;
+ if (rpc == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_hdr_resp");
depth++;
- if(!prs_uint32("alloc_hint", ps, depth, &rpc->alloc_hint))
- return False;
- if(!prs_uint16("context_id", ps, depth, &rpc->context_id))
- return False;
- if(!prs_uint8 ("cancel_ct ", ps, depth, &rpc->cancel_count))
- return False;
- if(!prs_uint8 ("reserved ", ps, depth, &rpc->reserved))
- return False;
+ prs_uint32("alloc_hint", ps, depth, &(rpc->alloc_hint));
+ prs_uint16("context_id", ps, depth, &(rpc->context_id));
+ prs_uint8 ("cancel_ct ", ps, depth, &(rpc->cancel_count));
+ prs_uint8 ("reserved ", ps, depth, &(rpc->reserved));
+
return True;
}
/*******************************************************************
- Init an RPC_HDR_AUTHA structure.
+creates an RPC_HDR_AUTHA structure.
********************************************************************/
-
-void init_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
+BOOL make_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
uint16 max_tsize, uint16 max_rsize,
uint8 auth_type, uint8 auth_level,
uint8 stub_type_len)
{
+ if (rai == NULL) return False;
+
rai->max_tsize = max_tsize; /* maximum transmission fragment size (0x1630) */
rai->max_rsize = max_rsize; /* max receive fragment size (0x1630) */
@@ -511,550 +592,110 @@ void init_rpc_hdr_autha(RPC_HDR_AUTHA *rai,
rai->padding = 0; /* padding 0x00 */
rai->unknown = 0x0014a0c0; /* non-zero pointer to something */
+
+ return True;
}
/*******************************************************************
- Reads or writes an RPC_HDR_AUTHA structure.
+reads or writes an RPC_HDR_AUTHA structure.
********************************************************************/
-
BOOL smb_io_rpc_hdr_autha(char *desc, RPC_HDR_AUTHA *rai, prs_struct *ps, int depth)
{
- if (rai == NULL)
- return False;
+ if (rai == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_hdr_autha");
depth++;
- if(!prs_uint16("max_tsize ", ps, depth, &rai->max_tsize))
- return False;
- if(!prs_uint16("max_rsize ", ps, depth, &rai->max_rsize))
- return False;
+ prs_uint16("max_tsize ", ps, depth, &(rai->max_tsize));
+ prs_uint16("max_rsize ", ps, depth, &(rai->max_rsize));
- if(!prs_uint8 ("auth_type ", ps, depth, &rai->auth_type)) /* 0x0a nt lm ssp */
- return False;
- if(!prs_uint8 ("auth_level ", ps, depth, &rai->auth_level)) /* 0x06 */
- return False;
- if(!prs_uint8 ("stub_type_len", ps, depth, &rai->stub_type_len))
- return False;
- if(!prs_uint8 ("padding ", ps, depth, &rai->padding))
- return False;
+ prs_uint8 ("auth_type ", ps, depth, &(rai->auth_type )); /* 0x0a nt lm ssp */
+ prs_uint8 ("auth_level ", ps, depth, &(rai->auth_level ));/* 0x06 */
+ prs_uint8 ("stub_type_len", ps, depth, &(rai->stub_type_len));
+ prs_uint8 ("padding ", ps, depth, &(rai->padding ));
- if(!prs_uint32("unknown ", ps, depth, &rai->unknown)) /* 0x0014a0c0 */
- return False;
+ prs_uint32("unknown ", ps, depth, &(rai->unknown )); /* 0x0014a0c0 */
return True;
}
/*******************************************************************
- Checks an RPC_HDR_AUTH structure.
-********************************************************************/
-
-BOOL rpc_hdr_auth_chk(RPC_HDR_AUTH *rai)
-{
- return (rai->auth_type == NTLMSSP_AUTH_TYPE && rai->auth_level == NTLMSSP_AUTH_LEVEL);
-}
-
-/*******************************************************************
- Inits an RPC_HDR_AUTH structure.
+creates an RPC_HDR_AUTH structure.
********************************************************************/
-
-void init_rpc_hdr_auth(RPC_HDR_AUTH *rai,
+BOOL make_rpc_hdr_auth(RPC_HDR_AUTH *rai,
uint8 auth_type, uint8 auth_level,
uint8 stub_type_len,
uint32 ptr)
{
+ if (rai == NULL) return False;
+
rai->auth_type = auth_type; /* nt lm ssp 0x0a */
rai->auth_level = auth_level; /* 0x06 */
rai->stub_type_len = stub_type_len; /* 0x00 */
rai->padding = 0; /* padding 0x00 */
rai->unknown = ptr; /* non-zero pointer to something */
+
+ return True;
}
/*******************************************************************
- Reads or writes an RPC_HDR_AUTH structure.
+reads or writes an RPC_HDR_AUTH structure.
********************************************************************/
-
BOOL smb_io_rpc_hdr_auth(char *desc, RPC_HDR_AUTH *rai, prs_struct *ps, int depth)
{
- if (rai == NULL)
- return False;
+ if (rai == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_hdr_auth");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint8 ("auth_type ", ps, depth, &rai->auth_type)) /* 0x0a nt lm ssp */
- return False;
- if(!prs_uint8 ("auth_level ", ps, depth, &rai->auth_level)) /* 0x06 */
- return False;
- if(!prs_uint8 ("stub_type_len", ps, depth, &rai->stub_type_len))
- return False;
- if(!prs_uint8 ("padding ", ps, depth, &rai->padding))
- return False;
+ prs_uint8 ("auth_type ", ps, depth, &(rai->auth_type )); /* 0x0a nt lm ssp */
+ prs_uint8 ("auth_level ", ps, depth, &(rai->auth_level ));/* 0x06 */
+ prs_uint8 ("stub_type_len", ps, depth, &(rai->stub_type_len));
+ prs_uint8 ("padding ", ps, depth, &(rai->padding ));
- if(!prs_uint32("unknown ", ps, depth, &rai->unknown)) /* 0x0014a0c0 */
- return False;
+ prs_uint32("unknown ", ps, depth, &(rai->unknown )); /* 0x0014a0c0 */
return True;
}
/*******************************************************************
- Checks an RPC_AUTH_VERIFIER structure.
+creates an RPC_AUTH_VERIFIER structure.
********************************************************************/
-
-BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
+BOOL make_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
char *signature, uint32 msg_type)
{
- return (strequal(rav->signature, signature) && rav->msg_type == msg_type);
-}
+ if (rav == NULL) return False;
-/*******************************************************************
- Inits an RPC_AUTH_VERIFIER structure.
-********************************************************************/
+ fstrcpy(rav->signature, signature);
+ rav->msg_type = msg_type;
-void init_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav,
- char *signature, uint32 msg_type)
-{
- fstrcpy(rav->signature, signature); /* "NTLMSSP" */
- rav->msg_type = msg_type; /* NTLMSSP_MESSAGE_TYPE */
+ return True;
}
/*******************************************************************
- Reads or writes an RPC_AUTH_VERIFIER structure.
+reads or writes an RPC_AUTH_VERIFIER structure.
********************************************************************/
-
BOOL smb_io_rpc_auth_verifier(char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth)
{
- if (rav == NULL)
- return False;
+ if (rav == NULL) return False;
prs_debug(ps, depth, desc, "smb_io_rpc_auth_verifier");
depth++;
- /* "NTLMSSP" */
- if(!prs_string("signature", ps, depth, rav->signature, strlen("NTLMSSP"),
- sizeof(rav->signature)))
- return False;
- if(!prs_uint32("msg_type ", ps, depth, &rav->msg_type)) /* NTLMSSP_MESSAGE_TYPE */
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits an RPC_AUTH_NTLMSSP_NEG structure.
-********************************************************************/
-
-void init_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg,
- uint32 neg_flgs,
- fstring myname, fstring domain)
-{
- int len_myname = strlen(myname);
- int len_domain = strlen(domain);
-
- neg->neg_flgs = neg_flgs ; /* 0x00b2b3 */
-
- init_str_hdr(&neg->hdr_domain, len_domain, len_domain, 0x20 + len_myname);
- init_str_hdr(&neg->hdr_myname, len_myname, len_myname, 0x20);
-
- fstrcpy(neg->myname, myname);
- fstrcpy(neg->domain, domain);
-}
-
-/*******************************************************************
- Reads or writes an RPC_AUTH_NTLMSSP_NEG structure.
-
- *** lkclXXXX HACK ALERT! ***
-********************************************************************/
-
-BOOL smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth)
-{
- if (neg == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_neg");
- depth++;
-
- if(!prs_uint32("neg_flgs ", ps, depth, &neg->neg_flgs))
- return False;
-
- if (ps->io) {
- uint32 old_offset;
- uint32 old_neg_flags = neg->neg_flgs;
-
- /* reading */
-
- ZERO_STRUCTP(neg);
-
- neg->neg_flgs = old_neg_flags;
-
- if(!smb_io_strhdr("hdr_domain", &neg->hdr_domain, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_myname", &neg->hdr_myname, ps, depth))
- return False;
-
- old_offset = prs_offset(ps);
-
- /* lkclXXXX HACK! */
- if(!prs_set_offset(ps, neg->hdr_myname.buffer + 0x50))
- return False;
-
- if(!prs_uint8s(True, "myname", ps, depth, (uint8*)neg->myname,
- MIN(neg->hdr_myname.str_str_len, sizeof(neg->myname))))
- return False;
-
- old_offset += neg->hdr_myname.str_str_len;
-
- /* lkclXXXX HACK! */
- if(!prs_set_offset(ps, neg->hdr_domain.buffer + 0x50))
- return False;
-
- if(!prs_uint8s(True, "domain", ps, depth, (uint8*)neg->domain,
- MIN(neg->hdr_domain.str_str_len, sizeof(neg->domain ))))
- return False;
-
- old_offset += neg->hdr_domain .str_str_len;
-
- if(!prs_set_offset(ps, old_offset))
- return False;
- } else {
- /* writing */
- if(!smb_io_strhdr("hdr_domain", &neg->hdr_domain, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_myname", &neg->hdr_myname, ps, depth))
- return False;
-
- if(!prs_uint8s(True, "myname", ps, depth, (uint8*)neg->myname,
- MIN(neg->hdr_myname.str_str_len, sizeof(neg->myname))))
- return False;
- if(!prs_uint8s(True, "domain", ps, depth, (uint8*)neg->domain,
- MIN(neg->hdr_domain.str_str_len, sizeof(neg->domain ))))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
-creates an RPC_AUTH_NTLMSSP_CHAL structure.
-********************************************************************/
-
-void init_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl,
- uint32 neg_flags,
- uint8 challenge[8])
-{
- chl->unknown_1 = 0x0;
- chl->unknown_2 = 0x00000028;
- chl->neg_flags = neg_flags; /* 0x0082b1 */
-
- memcpy(chl->challenge, challenge, sizeof(chl->challenge));
- memset((char *)chl->reserved , '\0', sizeof(chl->reserved));
-}
-
-/*******************************************************************
- Reads or writes an RPC_AUTH_NTLMSSP_CHAL structure.
-********************************************************************/
-
-BOOL smb_io_rpc_auth_ntlmssp_chal(char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth)
-{
- if (chl == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_chal");
- depth++;
-
- if(!prs_uint32("unknown_1", ps, depth, &chl->unknown_1)) /* 0x0000 0000 */
- return False;
- if(!prs_uint32("unknown_2", ps, depth, &chl->unknown_2)) /* 0x0000 b2b3 */
- return False;
- if(!prs_uint32("neg_flags", ps, depth, &chl->neg_flags)) /* 0x0000 82b1 */
- return False;
-
- if(!prs_uint8s (False, "challenge", ps, depth, chl->challenge, sizeof(chl->challenge)))
- return False;
- if(!prs_uint8s (False, "reserved ", ps, depth, chl->reserved , sizeof(chl->reserved )))
- return False;
+ prs_string("signature", ps, depth, rav->signature, 0, sizeof(rav->signature));
+ prs_align(ps);
+ prs_uint32("msg_type ", ps, depth, &(rav->msg_type ));
return True;
}
/*******************************************************************
- Inits an RPC_AUTH_NTLMSSP_RESP structure.
-
- *** lkclXXXX FUDGE! HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
- *** lkclXXXX the actual offset is at the start of the auth verifier ***
+checks an RPC_AUTH_VERIFIER structure.
********************************************************************/
-
-void init_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp,
- uchar lm_resp[24], uchar nt_resp[24],
- char *domain, char *user, char *wks,
- uint32 neg_flags)
-{
- uint32 offset;
- int dom_len = strlen(domain);
- int wks_len = strlen(wks);
- int usr_len = strlen(user);
- int lm_len = (lm_resp != NULL) ? 24 : 0;
- int nt_len = (nt_resp != NULL) ? 24 : 0;
-
- DEBUG(5,("make_rpc_auth_ntlmssp_resp\n"));
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("lm_resp\n"));
- dump_data(100, (char *)lm_resp, 24);
- DEBUG(100,("nt_resp\n"));
- dump_data(100, (char *)nt_resp, 24);
-#endif
-
- DEBUG(6,("dom: %s user: %s wks: %s neg_flgs: 0x%x\n",
- domain, user, wks, neg_flags));
-
- offset = 0x40;
-
- if (IS_BITS_SET_ALL(neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
- {
- dom_len *= 2;
- wks_len *= 2;
- usr_len *= 2;
- }
-
- init_str_hdr(&rsp->hdr_domain, dom_len, dom_len, offset);
- offset += dom_len;
-
- init_str_hdr(&rsp->hdr_usr, usr_len, usr_len, offset);
- offset += usr_len;
-
- init_str_hdr(&rsp->hdr_wks, wks_len, wks_len, offset);
- offset += wks_len;
-
- init_str_hdr(&rsp->hdr_lm_resp, lm_len, lm_len, offset);
- offset += lm_len;
-
- init_str_hdr(&rsp->hdr_nt_resp, nt_len, nt_len, offset);
- offset += nt_len;
-
- init_str_hdr(&rsp->hdr_sess_key, 0, 0, offset);
-
- rsp->neg_flags = neg_flags;
-
- memcpy(rsp->lm_resp, lm_resp, 24);
- memcpy(rsp->nt_resp, nt_resp, 24);
-
- if (IS_BITS_SET_ALL(neg_flags, NTLMSSP_NEGOTIATE_UNICODE)) {
- dos_struni2(rsp->domain, domain, sizeof(rsp->domain));
- dos_struni2(rsp->user, user, sizeof(rsp->user));
- dos_struni2(rsp->wks, wks, sizeof(rsp->wks));
- } else {
- fstrcpy(rsp->domain, domain);
- fstrcpy(rsp->user, user);
- fstrcpy(rsp->wks, wks);
- }
- rsp->sess_key[0] = 0;
-}
-
-/*******************************************************************
- Reads or writes an RPC_AUTH_NTLMSSP_RESP structure.
-
- *** lkclXXXX FUDGE! HAVE TO MANUALLY SPECIFY OFFSET HERE (0x1c bytes) ***
- *** lkclXXXX the actual offset is at the start of the auth verifier ***
-********************************************************************/
-
-BOOL smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth)
-{
- if (rsp == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_resp");
- depth++;
-
- if (ps->io) {
- uint32 old_offset;
-
- /* reading */
-
- ZERO_STRUCTP(rsp);
-
- if(!smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_domain ", &rsp->hdr_domain, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_user ", &rsp->hdr_usr, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_wks ", &rsp->hdr_wks, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth))
- return False;
-
- if(!prs_uint32("neg_flags", ps, depth, &rsp->neg_flags)) /* 0x0000 82b1 */
- return False;
-
- old_offset = prs_offset(ps);
-
- if(!prs_set_offset(ps, rsp->hdr_domain.buffer + 0x1c))
- return False;
-
- if(!prs_uint8s(True , "domain ", ps, depth, (uint8*)rsp->domain,
- MIN(rsp->hdr_domain.str_str_len, sizeof(rsp->domain))))
- return False;
-
- old_offset += rsp->hdr_domain.str_str_len;
-
- if(!prs_set_offset(ps, rsp->hdr_usr.buffer + 0x1c))
- return False;
-
- if(!prs_uint8s(True , "user ", ps, depth, (uint8*)rsp->user,
- MIN(rsp->hdr_usr.str_str_len, sizeof(rsp->user))))
- return False;
-
- old_offset += rsp->hdr_usr.str_str_len;
-
- if(!prs_set_offset(ps, rsp->hdr_wks.buffer + 0x1c))
- return False;
-
- if(!prs_uint8s(True, "wks ", ps, depth, (uint8*)rsp->wks,
- MIN(rsp->hdr_wks.str_str_len, sizeof(rsp->wks))))
- return False;
-
- old_offset += rsp->hdr_wks.str_str_len;
-
- if(!prs_set_offset(ps, rsp->hdr_lm_resp.buffer + 0x1c))
- return False;
-
- if(!prs_uint8s(False, "lm_resp ", ps, depth, (uint8*)rsp->lm_resp,
- MIN(rsp->hdr_lm_resp.str_str_len, sizeof(rsp->lm_resp ))))
- return False;
-
- old_offset += rsp->hdr_lm_resp.str_str_len;
-
- if(!prs_set_offset(ps, rsp->hdr_nt_resp.buffer + 0x1c))
- return False;
-
- if(!prs_uint8s(False, "nt_resp ", ps, depth, (uint8*)rsp->nt_resp,
- MIN(rsp->hdr_nt_resp.str_str_len, sizeof(rsp->nt_resp ))))
- return False;
-
- old_offset += rsp->hdr_nt_resp.str_str_len;
-
- if (rsp->hdr_sess_key.str_str_len != 0) {
-
- if(!prs_set_offset(ps, rsp->hdr_sess_key.buffer + 0x1c))
- return False;
-
- old_offset += rsp->hdr_sess_key.str_str_len;
-
- if(!prs_uint8s(False, "sess_key", ps, depth, (uint8*)rsp->sess_key,
- MIN(rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key))))
- return False;
- }
-
- if(!prs_set_offset(ps, old_offset))
- return False;
- } else {
- /* writing */
- if(!smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_domain ", &rsp->hdr_domain, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_user ", &rsp->hdr_usr, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_wks ", &rsp->hdr_wks, ps, depth))
- return False;
- if(!smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth))
- return False;
-
- if(!prs_uint32("neg_flags", ps, depth, &rsp->neg_flags)) /* 0x0000 82b1 */
- return False;
-
- if(!prs_uint8s(True , "domain ", ps, depth, (uint8*)rsp->domain,
- MIN(rsp->hdr_domain.str_str_len, sizeof(rsp->domain))))
- return False;
-
- if(!prs_uint8s(True , "user ", ps, depth, (uint8*)rsp->user,
- MIN(rsp->hdr_usr.str_str_len, sizeof(rsp->user))))
- return False;
-
- if(!prs_uint8s(True , "wks ", ps, depth, (uint8*)rsp->wks,
- MIN(rsp->hdr_wks.str_str_len, sizeof(rsp->wks))))
- return False;
- if(!prs_uint8s(False, "lm_resp ", ps, depth, (uint8*)rsp->lm_resp,
- MIN(rsp->hdr_lm_resp .str_str_len, sizeof(rsp->lm_resp))))
- return False;
- if(!prs_uint8s(False, "nt_resp ", ps, depth, (uint8*)rsp->nt_resp,
- MIN(rsp->hdr_nt_resp .str_str_len, sizeof(rsp->nt_resp ))))
- return False;
- if(!prs_uint8s(False, "sess_key", ps, depth, (uint8*)rsp->sess_key,
- MIN(rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key))))
- return False;
- }
-
- return True;
-}
-
-/*******************************************************************
- Checks an RPC_AUTH_NTLMSSP_CHK structure.
-********************************************************************/
-
-BOOL rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk, uint32 crc32, uint32 seq_num)
-{
- if (chk == NULL)
- return False;
-
- if (chk->crc32 != crc32 ||
- chk->ver != NTLMSSP_SIGN_VERSION ||
- chk->seq_num != seq_num)
- {
- DEBUG(5,("verify failed - crc %x ver %x seq %d\n",
- crc32, NTLMSSP_SIGN_VERSION, seq_num));
- DEBUG(5,("verify expect - crc %x ver %x seq %d\n",
- chk->crc32, chk->ver, chk->seq_num));
- return False;
- }
- return True;
-}
-
-/*******************************************************************
- Inits an RPC_AUTH_NTLMSSP_CHK structure.
-********************************************************************/
-
-void init_rpc_auth_ntlmssp_chk(RPC_AUTH_NTLMSSP_CHK *chk,
- uint32 ver, uint32 crc32, uint32 seq_num)
-{
- chk->ver = ver;
- chk->reserved = 0x0;
- chk->crc32 = crc32;
- chk->seq_num = seq_num;
-}
-
-/*******************************************************************
- Reads or writes an RPC_AUTH_NTLMSSP_CHK structure.
-********************************************************************/
-
-BOOL smb_io_rpc_auth_ntlmssp_chk(char *desc, RPC_AUTH_NTLMSSP_CHK *chk, prs_struct *ps, int depth)
+BOOL rpc_auth_verifier_chk(RPC_AUTH_VERIFIER *rav,
+ char *signature, uint32 msg_type)
{
- if (chk == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_chk");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ver ", ps, depth, &chk->ver))
- return False;
- if(!prs_uint32("reserved", ps, depth, &chk->reserved))
- return False;
- if(!prs_uint32("crc32 ", ps, depth, &chk->crc32))
- return False;
- if(!prs_uint32("seq_num ", ps, depth, &chk->seq_num))
- return False;
-
- return True;
+ return (strequal(rav->signature, signature) &&
+ rav->msg_type == msg_type);
}
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index 2327ee7798d..1d4b8950029 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -2,9 +2,9 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Paul Ashton 1997-1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,319 +23,527 @@
#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
extern int DEBUGLEVEL;
/*******************************************************************
- Inits a SAMR_Q_CLOSE_HND structure.
+makes a SAMR_Q_CLOSE_HND structure.
********************************************************************/
-
-void init_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd)
+BOOL make_samr_q_close_hnd(SAMR_Q_CLOSE_HND *q_c, POLICY_HND *hnd)
{
- DEBUG(5,("init_samr_q_close_hnd\n"));
+ if (q_c == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_samr_q_close_hnd\n"));
+
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
- memcpy(&q_c->pol, hnd, sizeof(q_c->pol));
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL samr_io_q_close_hnd(char *desc, SAMR_Q_CLOSE_HND *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_q_close_hnd");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL samr_io_r_close_hnd(char *desc, SAMR_R_CLOSE_HND *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_r_close_hnd");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("pol", &(r_u->pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
+/*******************************************************************
+makes a SAMR_Q_LOOKUP_DOMAIN structure.
+********************************************************************/
+BOOL make_samr_q_lookup_domain(SAMR_Q_LOOKUP_DOMAIN *q_u,
+ POLICY_HND *pol, const char *dom_name)
+{
+ int len_name = strlen(dom_name);
+
+ if (q_u == NULL) return False;
+
+ DEBUG(5,("make_samr_q_lookup_domain\n"));
+
+ memcpy(&(q_u->connect_pol), pol, sizeof(*pol));
+
+ make_uni_hdr(&(q_u->hdr_domain), len_name);
+ make_unistr2(&(q_u->uni_domain), dom_name, len_name);
+
+ return True;
+}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_q_lookup_domain(char *desc, SAMR_Q_LOOKUP_DOMAIN *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
-void init_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
- POLICY_HND *connect_pol, uint32 rid,
- DOM_SID *sid)
+ prs_debug(ps, depth, desc, "samr_io_q_lookup_domain");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("connect_pol", &(q_u->connect_pol), ps, depth);
+ prs_align(ps);
+
+ smb_io_unihdr("hdr_domain", &(q_u->hdr_domain), ps, depth);
+ smb_io_unistr2("uni_domain", &(q_u->uni_domain),
+ q_u->hdr_domain.buffer, ps, depth);
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+makes a SAMR_R_LOOKUP_DOMAIN structure.
+********************************************************************/
+BOOL make_samr_r_lookup_domain(SAMR_R_LOOKUP_DOMAIN *r_u,
+ DOM_SID *dom_sid, uint32 status)
{
- DEBUG(5,("samr_init_q_open_domain\n"));
+ if (r_u == NULL) return False;
- memcpy(&q_u->connect_pol, connect_pol, sizeof(q_u->connect_pol));
- q_u->rid = rid;
- init_dom_sid2(&q_u->dom_sid, sid);
+ DEBUG(5,("make_samr_r_lookup_domain\n"));
+
+ r_u->status = status;
+ r_u->ptr_sid = 0;
+ if (status == 0x0)
+ {
+ r_u->ptr_sid = 1;
+ make_dom_sid2(&(r_u->dom_sid), dom_sid);
+ }
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_r_lookup_domain(char *desc, SAMR_R_LOOKUP_DOMAIN *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_lookup_domain");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr", ps, depth, &(r_u->ptr_sid));
+
+ if (r_u->ptr_sid != 0)
+ {
+ smb_io_dom_sid2("sid", &(r_u->dom_sid), ps, depth);
+ prs_align(ps);
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
-BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth)
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL make_samr_q_unknown_2d(SAMR_Q_UNKNOWN_2D *q_u,
+ const POLICY_HND *dom_pol,
+ const DOM_SID *sid)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_open_domain");
+ DEBUG(5,("samr_make_samr_q_unknown_2d\n"));
+
+ memcpy(&q_u->dom_pol, dom_pol, sizeof(q_u->dom_pol));
+ make_dom_sid2(&(q_u->sid), sid);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_unknown_2d(char *desc, SAMR_Q_UNKNOWN_2D *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_unknown_2d");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("connect_pol", &q_u->connect_pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("domain_pol", &(q_u->dom_pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint32("rid", ps, depth, &q_u->rid))
- return False;
+ smb_io_dom_sid2("sid", &(q_u->sid), ps, depth);
+ prs_align(ps);
- if(!smb_io_dom_sid2("sid", &q_u->dom_sid, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_unknown_2d(char *desc, SAMR_R_UNKNOWN_2D *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_unknown_2d");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL make_samr_q_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
+ const POLICY_HND *connect_pol, uint32 flags,
+ const DOM_SID *sid)
+{
+ if (q_u == NULL) return False;
+
+ DEBUG(5,("samr_make_samr_q_open_domain\n"));
+
+ memcpy(&q_u->connect_pol, connect_pol, sizeof(q_u->connect_pol));
+ q_u->flags = flags;
+ make_dom_sid2(&(q_u->dom_sid), sid);
+
+ return True;
+}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_q_open_domain(char *desc, SAMR_Q_OPEN_DOMAIN *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
-BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth)
+ prs_debug(ps, depth, desc, "samr_io_q_open_domain");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("connect_pol", &(q_u->connect_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("flags", ps, depth, &(q_u->flags));
+
+ smb_io_dom_sid2("sid", &(q_u->dom_sid), ps, depth);
+ prs_align(ps);
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_open_domain(char *desc, SAMR_R_OPEN_DOMAIN *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_r_open_domain");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("domain_pol", &r_u->domain_pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("domain_pol", &(r_u->domain_pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-void init_samr_q_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u, POLICY_HND *user_pol)
+BOOL make_samr_q_get_usrdom_pwinfo(SAMR_Q_GET_USRDOM_PWINFO *q_u, POLICY_HND *user_pol)
{
- DEBUG(5,("samr_init_q_unknown_2c\n"));
+ if (q_u == NULL) return False;
+
+ DEBUG(5,("samr_make_samr_q_get_usrdom_pwinfo\n"));
memcpy(&q_u->user_pol, user_pol, sizeof(q_u->user_pol));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_q_unknown_2c(char *desc, SAMR_Q_UNKNOWN_2C *q_u, prs_struct *ps, int depth)
+BOOL samr_io_q_get_usrdom_pwinfo(char *desc, SAMR_Q_GET_USRDOM_PWINFO *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_unknown_2c");
+ prs_debug(ps, depth, desc, "samr_io_q_get_usrdom_pwinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("user_pol", &q_u->user_pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("user_pol", &(q_u->user_pol), ps, depth);
+ prs_align(ps);
return True;
}
/*******************************************************************
- Inits a structure.
+makes a structure.
********************************************************************/
-
-void init_samr_r_unknown_2c(SAMR_R_UNKNOWN_2C *q_u, uint32 status)
+BOOL make_samr_r_get_usrdom_pwinfo(SAMR_R_GET_USRDOM_PWINFO *q_u, uint32 status)
{
- DEBUG(5,("samr_init_r_unknown_2c\n"));
+ if (q_u == NULL) return False;
- q_u->unknown_0 = 0x00160000;
+ DEBUG(5,("samr_make_r_get_usrdom_pwinfo\n"));
+
+ q_u->unknown_0 = 0x00150000;
q_u->unknown_1 = 0x00000000;
q_u->status = status;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_r_unknown_2c(char *desc, SAMR_R_UNKNOWN_2C *r_u, prs_struct *ps, int depth)
+BOOL samr_io_r_get_usrdom_pwinfo(char *desc, SAMR_R_GET_USRDOM_PWINFO *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_unknown_2c");
+ prs_debug(ps, depth, desc, "samr_io_r_get_usrdom_pwinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("unknown_0", ps, depth, &r_u->unknown_0))
- return False;
- if(!prs_uint32("unknown_1", ps, depth, &r_u->unknown_1))
- return False;
- if(!prs_uint32("status ", ps, depth, &r_u->status))
- return False;
+ prs_uint32("unknown_0", ps, depth, &(r_u->unknown_0));
+ prs_uint32("unknown_1", ps, depth, &(r_u->unknown_1));
+ prs_uint32("status ", ps, depth, &(r_u->status ));
return True;
}
/*******************************************************************
- Inits a SAMR_Q_UNKNOWN_3 structure.
+reads or writes a structure.
********************************************************************/
-
-void init_samr_q_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
- POLICY_HND *user_pol, uint16 switch_value)
+BOOL make_samr_q_query_sec_obj(SAMR_Q_QUERY_SEC_OBJ *q_u,
+ const POLICY_HND *user_pol, uint32 sec_info)
{
- DEBUG(5,("samr_init_q_unknown_3\n"));
+ if (q_u == NULL) return False;
+
+ DEBUG(5,("samr_make_samr_q_query_sec_obj\n"));
memcpy(&q_u->user_pol, user_pol, sizeof(q_u->user_pol));
- q_u->switch_value = switch_value;
+ q_u->sec_info = sec_info;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_q_unknown_3(char *desc, SAMR_Q_UNKNOWN_3 *q_u, prs_struct *ps, int depth)
+BOOL samr_io_q_query_sec_obj(char *desc, SAMR_Q_QUERY_SEC_OBJ *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_unknown_3");
+ prs_debug(ps, depth, desc, "samr_io_q_query_sec_obj");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_pol_hnd("user_pol", &q_u->user_pol, ps, depth))
- return False;
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("user_pol", &(q_u->user_pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint32("sec_info", ps, depth, &(q_u->sec_info));
return True;
}
/*******************************************************************
- Inits a SAMR_Q_QUERY_DOMAIN_INFO structure.
+reads or writes a structure.
********************************************************************/
-
-void init_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
+BOOL make_samr_q_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
POLICY_HND *domain_pol, uint16 switch_value)
{
- DEBUG(5,("init_samr_q_query_dom_info\n"));
+ if (q_u == NULL) return False;
+
+ DEBUG(5,("samr_make_samr_q_query_dom_info\n"));
memcpy(&q_u->domain_pol, domain_pol, sizeof(q_u->domain_pol));
q_u->switch_value = switch_value;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL samr_io_q_query_dom_info(char *desc, SAMR_Q_QUERY_DOMAIN_INFO *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_q_query_dom_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint16("switch_value", ps, depth, &(q_u->switch_value));
+ prs_align(ps);
+
+ return True;
+}
+
+
+/*******************************************************************
+makes a structure.
+********************************************************************/
+BOOL make_unk_info3(SAM_UNK_INFO_3 *u_3)
+{
+ if (u_3 == NULL) return False;
+
+ u_3->unknown_0 = 0x00000000;
+ u_3->unknown_1 = 0x80000000;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_unk_info3(char *desc, SAM_UNK_INFO_3 *u_3, prs_struct *ps, int depth)
+{
+ if (u_3 == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info3");
+ depth++;
+
+ prs_uint32("unknown_0", ps, depth, &u_3->unknown_0); /* 0x0000 0000 */
+ prs_uint32("unknown_1", ps, depth, &u_3->unknown_1); /* 0x8000 0000 */
+ prs_align(ps);
+
+
+ return True;
+}
+
+/*******************************************************************
+makes a structure.
+********************************************************************/
+BOOL make_unk_info6(SAM_UNK_INFO_6 *u_6)
+{
+ if (u_6 == NULL) return False;
+
+ u_6->unknown_0 = 0x00000000;
+ u_6->ptr_0 = 1;
+ memset(u_6->padding, 0, sizeof(u_6->padding)); /* 12 bytes zeros */
return True;
}
/*******************************************************************
- Inits a structure.
+reads or writes a structure.
********************************************************************/
+static BOOL sam_io_unk_info6(char *desc, SAM_UNK_INFO_6 *u_6, prs_struct *ps, int depth)
+{
+ if (u_6 == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info6");
+ depth++;
+
+ prs_uint32("unknown_0", ps, depth, &u_6->unknown_0); /* 0x0000 0000 */
+ prs_uint32("ptr_0", ps, depth, &u_6->ptr_0); /* pointer to unknown structure */
+ prs_uint8s(False, "padding", ps, depth, u_6->padding, sizeof(u_6->padding)); /* 12 bytes zeros */
+
+ prs_align(ps);
+
+
+ return True;
+}
+
+/*******************************************************************
+makes a structure.
+********************************************************************/
+BOOL make_unk_info7(SAM_UNK_INFO_7 *u_7)
+{
+ if (u_7 == NULL) return False;
+
+ u_7->unknown_0 = 0x0003;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_unk_info7(char *desc, SAM_UNK_INFO_7 *u_7, prs_struct *ps, int depth)
+{
+ if (u_7 == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info7");
+ depth++;
+
+ prs_uint16("unknown_0", ps, depth, &u_7->unknown_0); /* 0x0003 */
+ prs_align(ps);
+
+
+ return True;
+}
-void init_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server)
+/*******************************************************************
+makes a structure.
+********************************************************************/
+BOOL make_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server)
{
int len_domain = strlen(domain);
int len_server = strlen(server);
+ if (u_2 == NULL) return False;
+
u_2->unknown_0 = 0x00000000;
u_2->unknown_1 = 0x80000000;
u_2->unknown_2 = 0x00000000;
u_2->ptr_0 = 1;
- init_uni_hdr(&u_2->hdr_domain, len_domain);
- init_uni_hdr(&u_2->hdr_server, len_server);
+ make_uni_hdr(&(u_2->hdr_domain), len_domain);
+ make_uni_hdr(&(u_2->hdr_server), len_server);
u_2->seq_num = 0x10000000;
u_2->unknown_3 = 0x00000000;
@@ -343,2244 +551,4178 @@ void init_unk_info2(SAM_UNK_INFO_2 *u_2, char *domain, char *server)
u_2->unknown_4 = 0x00000001;
u_2->unknown_5 = 0x00000003;
u_2->unknown_6 = 0x00000001;
- u_2->num_domain_usrs = 0x00000008;
- u_2->num_domain_grps = 0x00000003;
- u_2->num_local_grps = 0x00000003;
+ u_2->num_domain_usrs = MAX_SAM_ENTRIES;
+ u_2->num_domain_grps = MAX_SAM_ENTRIES;
+ u_2->num_local_grps = MAX_SAM_ENTRIES;
memset(u_2->padding, 0, sizeof(u_2->padding)); /* 12 bytes zeros */
- init_unistr2(&u_2->uni_domain, domain, len_domain);
- init_unistr2(&u_2->uni_server, server, len_server);
+ make_unistr2(&u_2->uni_domain, domain, len_domain);
+ make_unistr2(&u_2->uni_server, server, len_server);
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth)
+static BOOL sam_io_unk_info2(char *desc, SAM_UNK_INFO_2 *u_2, prs_struct *ps, int depth)
{
- if (u_2 == NULL)
- return False;
+ if (u_2 == NULL) return False;
prs_debug(ps, depth, desc, "sam_io_unk_info2");
depth++;
- if(!prs_uint32("unknown_0", ps, depth, &u_2->unknown_0)) /* 0x0000 0000 */
- return False;
- if(!prs_uint32("unknown_1", ps, depth, &u_2->unknown_1)) /* 0x8000 0000 */
- return False;
- if(!prs_uint32("unknown_2", ps, depth, &u_2->unknown_2)) /* 0x0000 0000 */
- return False;
+ prs_uint32("unknown_0", ps, depth, &u_2->unknown_0); /* 0x0000 0000 */
+ prs_uint32("unknown_1", ps, depth, &u_2->unknown_1); /* 0x8000 0000 */
+ prs_uint32("unknown_2", ps, depth, &u_2->unknown_2); /* 0x0000 0000 */
- if(!prs_uint32("ptr_0", ps, depth, &u_2->ptr_0)) /* pointer to unknown structure */
- return False;
- if(!smb_io_unihdr("hdr_domain", &u_2->hdr_domain, ps, depth)) /* domain name unicode header */
- return False;
- if(!smb_io_unihdr("hdr_server", &u_2->hdr_server, ps, depth)) /* server name unicode header */
- return False;
+ prs_uint32("ptr_0", ps, depth, &u_2->ptr_0); /* pointer to unknown structure */
+ smb_io_unihdr("hdr_domain", &u_2->hdr_domain, ps, depth); /* domain name unicode header */
+ smb_io_unihdr("hdr_server", &u_2->hdr_server, ps, depth); /* server name unicode header */
/* put all the data in here, at the moment, including what the above
pointer is referring to
*/
- if(!prs_uint32("seq_num ", ps, depth, &u_2->seq_num )) /* 0x0000 0099 or 0x1000 0000 */
- return False;
- if(!prs_uint32("unknown_3 ", ps, depth, &u_2->unknown_3 )) /* 0x0000 0000 */
- return False;
+ prs_uint32("seq_num ", ps, depth, &u_2->seq_num ); /* 0x0000 0099 or 0x1000 0000 */
+ prs_uint32("unknown_3 ", ps, depth, &u_2->unknown_3 ); /* 0x0000 0000 */
- if(!prs_uint32("unknown_4 ", ps, depth, &u_2->unknown_4 )) /* 0x0000 0001 */
- return False;
- if(!prs_uint32("unknown_5 ", ps, depth, &u_2->unknown_5 )) /* 0x0000 0003 */
- return False;
- if(!prs_uint32("unknown_6 ", ps, depth, &u_2->unknown_6 )) /* 0x0000 0001 */
- return False;
- if(!prs_uint32("num_domain_usrs ", ps, depth, &u_2->num_domain_usrs )) /* 0x0000 0008 */
- return False;
- if(!prs_uint32("num_domain_grps", ps, depth, &u_2->num_domain_grps)) /* 0x0000 0003 */
- return False;
- if(!prs_uint32("num_local_grps", ps, depth, &u_2->num_local_grps)) /* 0x0000 0003 */
- return False;
+ prs_uint32("unknown_4 ", ps, depth, &u_2->unknown_4 ); /* 0x0000 0001 */
+ prs_uint32("unknown_5 ", ps, depth, &u_2->unknown_5 ); /* 0x0000 0003 */
+ prs_uint32("unknown_6 ", ps, depth, &u_2->unknown_6 ); /* 0x0000 0001 */
+ prs_uint32("num_domain_usrs ", ps, depth, &u_2->num_domain_usrs ); /* 0x0000 0008 */
+ prs_uint32("num_domain_grps", ps, depth, &u_2->num_domain_grps); /* 0x0000 0003 */
+ prs_uint32("num_local_grps", ps, depth, &u_2->num_local_grps); /* 0x0000 0003 */
- if(!prs_uint8s(False, "padding", ps, depth, u_2->padding, sizeof(u_2->padding))) /* 12 bytes zeros */
- return False;
+ prs_uint8s(False, "padding", ps, depth, u_2->padding, sizeof(u_2->padding)); /* 12 bytes zeros */
- if(!smb_io_unistr2( "uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth)) /* domain name unicode string */
- return False;
- if(!smb_io_unistr2( "uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth)) /* server name unicode string */
- return False;
+ smb_io_unistr2( "uni_domain", &u_2->uni_domain, u_2->hdr_domain.buffer, ps, depth); /* domain name unicode string */
+ prs_align(ps);
+ smb_io_unistr2( "uni_server", &u_2->uni_server, u_2->hdr_server.buffer, ps, depth); /* server name unicode string */
+
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
return True;
}
/*******************************************************************
- Inits a SAMR_R_QUERY_DOMAIN_INFO structure.
+makes a structure.
********************************************************************/
+BOOL make_unk_info1(SAM_UNK_INFO_1 *u_1)
+{
+ if (u_1 == NULL) return False;
+
+ memset(u_1->padding, 0, sizeof(u_1->padding)); /* 12 bytes zeros */
+ u_1->unknown_1 = 0x80000000;
+ u_1->unknown_2 = 0x00000000;
-void init_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u,
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_unk_info1(char *desc, SAM_UNK_INFO_1 *u_1, prs_struct *ps, int depth)
+{
+ if (u_1 == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_unk_info1");
+ depth++;
+
+ prs_uint8s(False, "padding", ps, depth, u_1->padding, sizeof(u_1->padding)); /* 12 bytes zeros */
+
+ prs_uint32("unknown_1", ps, depth, &u_1->unknown_1); /* 0x8000 0000 */
+ prs_uint32("unknown_2", ps, depth, &u_1->unknown_2); /* 0x0000 0000 */
+
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+makes a SAMR_R_QUERY_DOMAIN_INFO structure.
+********************************************************************/
+BOOL make_samr_r_query_dom_info(SAMR_R_QUERY_DOMAIN_INFO *r_u,
uint16 switch_value, SAM_UNK_CTR *ctr,
uint32 status)
{
- DEBUG(5,("init_samr_r_query_dom_info\n"));
+ if (r_u == NULL || ctr == NULL) return False;
+
+ DEBUG(5,("make_samr_r_query_dom_info\n"));
r_u->ptr_0 = 0;
r_u->switch_value = 0;
r_u->status = status; /* return status */
- if (status == 0) {
+ if (status == 0)
+ {
r_u->switch_value = switch_value;
r_u->ptr_0 = 1;
r_u->ctr = ctr;
}
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL samr_io_r_query_dom_info(char *desc, SAMR_R_QUERY_DOMAIN_INFO *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_r_query_dom_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_0 ", ps, depth, &r_u->ptr_0))
- return False;
- if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0));
+
+ if (r_u->ptr_0 != 0 && r_u->ctr != NULL)
+ {
+ prs_uint16("switch_value", ps, depth, &(r_u->switch_value));
+ prs_align(ps);
- if (r_u->ptr_0 != 0 && r_u->ctr != NULL) {
- switch (r_u->switch_value) {
- case 0x02:
- if(!sam_io_unk_info2("unk_inf2", &r_u->ctr->info.inf2, ps, depth))
+ switch (r_u->switch_value)
+ {
+ case 0x07:
+ {
+ sam_io_unk_info7("unk_inf7", &r_u->ctr->info.inf7, ps, depth);
+ break;
+ }
+ case 0x06:
+ {
+ sam_io_unk_info6("unk_inf6", &r_u->ctr->info.inf6, ps, depth);
+ break;
+ }
+ case 0x03:
+ {
+ sam_io_unk_info3("unk_inf3", &r_u->ctr->info.inf3, ps, depth);
+ break;
+ }
+ case 0x02:
+ {
+ sam_io_unk_info2("unk_inf2", &r_u->ctr->info.inf2, ps, depth);
+ break;
+ }
+ case 0x01:
+ {
+ sam_io_unk_info1("unk_inf1", &r_u->ctr->info.inf1, ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(3,("samr_io_r_query_dom_info: unknown switch level 0x%x\n",
+ r_u->switch_value));
+ r_u->status = 0xC0000000|NT_STATUS_INVALID_INFO_CLASS;
return False;
- break;
- default:
- DEBUG(3,("samr_io_r_query_dom_info: unknown switch level 0x%x\n",
- r_u->switch_value));
- return False;
+ }
}
}
+ prs_uint32("status ", ps, depth, &(r_u->status));
+
return True;
}
/*******************************************************************
- Inits a DOM_SID3 structure.
- Calculate length by adding up the size of the components.
- ********************************************************************/
+reads or writes a SAMR_R_QUERY_SEC_OBJ structure.
+********************************************************************/
+BOOL samr_io_r_query_sec_obj(char *desc, SAMR_R_QUERY_SEC_OBJ *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_query_sec_obj");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr", ps, depth, &(r_u->ptr));
+ if (r_u->ptr != 0x0)
+ {
+ sec_io_desc_buf("sec", &r_u->buf, ps, depth);
+ }
+ prs_uint32("status", ps, depth, &(r_u->status));
-void init_dom_sid3(DOM_SID3 *sid3, uint16 unk_0, uint16 unk_1, DOM_SID *sid)
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SAM_STR1 structure.
+********************************************************************/
+static BOOL sam_io_sam_str1(char *desc, SAM_STR1 *sam, uint32 acct_buf, uint32 name_buf, uint32 desc_buf, prs_struct *ps, int depth)
{
- sid3->sid = *sid;
- sid3->len = 2 + 8 + sid3->sid.num_auths * 4;
+ if (sam == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_str1");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("unistr2", &(sam->uni_acct_name), acct_buf, ps, depth); /* account name unicode string */
+ prs_align(ps);
+ smb_io_unistr2("unistr2", &(sam->uni_full_name), name_buf, ps, depth); /* full name unicode string */
+ prs_align(ps);
+ smb_io_unistr2("unistr2", &(sam->uni_acct_desc), desc_buf, ps, depth); /* account desc unicode string */
+ prs_align(ps);
+
+ return True;
}
/*******************************************************************
- Reads or writes a SAM_SID3 structure.
+makes a SAM_ENTRY1 structure.
+********************************************************************/
+static BOOL make_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx,
+ uint32 len_sam_name, uint32 len_sam_full, uint32 len_sam_desc,
+ uint32 rid_user, uint16 acb_info)
+{
+ if (sam == NULL) return False;
+
+ DEBUG(5,("make_sam_entry1\n"));
+
+ sam->user_idx = user_idx;
+ sam->rid_user = rid_user;
+ sam->acb_info = acb_info;
+ sam->pad = 0;
- this one's odd, because the length (in bytes) is specified at the beginning.
- the length _includes_ the length of the length, too :-)
+ make_uni_hdr(&(sam->hdr_acct_name), len_sam_name);
+ make_uni_hdr(&(sam->hdr_user_name), len_sam_full);
+ make_uni_hdr(&(sam->hdr_user_desc), len_sam_desc);
+
+ return True;
+}
+/*******************************************************************
+reads or writes a SAM_ENTRY1 structure.
********************************************************************/
+static BOOL sam_io_sam_entry1(char *desc, SAM_ENTRY1 *sam, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_entry1");
+ depth++;
-static BOOL sam_io_dom_sid3(char *desc, DOM_SID3 *sid3, prs_struct *ps, int depth)
+ prs_align(ps);
+
+ prs_uint32("user_idx ", ps, depth, &(sam->user_idx ));
+
+ prs_uint32("rid_user ", ps, depth, &(sam->rid_user ));
+ prs_uint16("acb_info ", ps, depth, &(sam->acb_info ));
+ prs_uint16("pad ", ps, depth, &(sam->pad ));
+
+ smb_io_unihdr("unihdr", &(sam->hdr_acct_name), ps, depth); /* account name unicode string header */
+ smb_io_unihdr("unihdr", &(sam->hdr_user_name), ps, depth); /* account name unicode string header */
+ smb_io_unihdr("unihdr", &(sam->hdr_user_desc), ps, depth); /* account name unicode string header */
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SAM_STR2 structure.
+********************************************************************/
+static BOOL sam_io_sam_str2(char *desc, SAM_STR2 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth)
{
- if (sid3 == NULL)
- return False;
+ if (sam == NULL) return False;
- prs_debug(ps, depth, desc, "sam_io_dom_sid3");
+ prs_debug(ps, depth, desc, "sam_io_sam_str2");
depth++;
- if(!prs_uint16("len", ps, depth, &sid3->len))
- return False;
- if(!prs_align(ps))
- return False;
- if(!smb_io_dom_sid("", &sid3->sid, ps, depth))
- return False;
+ prs_align(ps);
+
+ smb_io_unistr2("unistr2", &(sam->uni_srv_name), acct_buf, ps, depth); /* account name unicode string */
+ prs_align(ps);
+ smb_io_unistr2("unistr2", &(sam->uni_srv_desc), desc_buf, ps, depth); /* account desc unicode string */
+ prs_align(ps);
return True;
}
/*******************************************************************
- Inits a SAMR_R_UNKNOWN3 structure.
+makes a SAM_ENTRY2 structure.
+********************************************************************/
+static BOOL make_sam_entry2(SAM_ENTRY2 *sam, uint32 user_idx,
+ uint32 len_sam_name, uint32 len_sam_desc,
+ uint32 rid_user, uint16 acb_info)
+{
+ if (sam == NULL) return False;
+
+ DEBUG(5,("make_sam_entry2\n"));
-unknown_2 : 0x0001
-unknown_3 : 0x8004
+ sam->user_idx = user_idx;
+ sam->rid_user = rid_user;
+ sam->acb_info = acb_info;
+ sam->pad = 0;
-unknown_4,5 : 0x0000 0014
+ make_uni_hdr(&(sam->hdr_srv_name), len_sam_name);
+ make_uni_hdr(&(sam->hdr_srv_desc), len_sam_desc);
-unknown_6 : 0x0002
-unknown_7 : 0x5800 or 0x0070
+ return True;
+}
+/*******************************************************************
+reads or writes a SAM_ENTRY2 structure.
********************************************************************/
+static BOOL sam_io_sam_entry2(char *desc, SAM_ENTRY2 *sam, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return False;
-static void init_sam_sid_stuff(SAM_SID_STUFF *stf,
- uint16 unknown_2, uint16 unknown_3,
- uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
- int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS])
+ prs_debug(ps, depth, desc, "sam_io_sam_entry2");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("user_idx ", ps, depth, &(sam->user_idx ));
+
+ prs_uint32("rid_user ", ps, depth, &(sam->rid_user ));
+ prs_uint16("acb_info ", ps, depth, &(sam->acb_info ));
+ prs_uint16("pad ", ps, depth, &(sam->pad ));
+
+ smb_io_unihdr("unihdr", &(sam->hdr_srv_name), ps, depth); /* account name unicode string header */
+ smb_io_unihdr("unihdr", &(sam->hdr_srv_desc), ps, depth); /* account name unicode string header */
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SAM_STR3 structure.
+********************************************************************/
+static BOOL sam_io_sam_str3(char *desc, SAM_STR3 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth)
{
- stf->unknown_2 = unknown_2;
- stf->unknown_3 = unknown_3;
+ if (sam == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_str3");
+ depth++;
+
+ prs_align(ps);
- memset((char *)stf->padding1, '\0', sizeof(stf->padding1));
+ smb_io_unistr2("unistr2", &(sam->uni_grp_name), acct_buf, ps, depth); /* account name unicode string */
+ prs_align(ps);
+ smb_io_unistr2("unistr2", &(sam->uni_grp_desc), desc_buf, ps, depth); /* account desc unicode string */
+ prs_align(ps);
+
+ return True;
+}
- stf->unknown_4 = unknown_4;
- stf->unknown_5 = unknown_4;
+/*******************************************************************
+makes a SAM_ENTRY3 structure.
+********************************************************************/
+static BOOL make_sam_entry3(SAM_ENTRY3 *sam, uint32 grp_idx,
+ uint32 len_grp_name, uint32 len_grp_desc, uint32 rid_grp)
+{
+ if (sam == NULL) return False;
- stf->unknown_6 = unknown_6;
- stf->unknown_7 = unknown_7;
+ DEBUG(5,("make_sam_entry3\n"));
- stf->num_sids = num_sid3s;
+ sam->grp_idx = grp_idx;
+ sam->rid_grp = rid_grp;
+ sam->attr = 0x07; /* group rid attributes - gets ignored by nt 4.0 */
- stf->padding2 = 0x0000;
+ make_uni_hdr(&(sam->hdr_grp_name), len_grp_name);
+ make_uni_hdr(&(sam->hdr_grp_desc), len_grp_desc);
- memcpy(stf->sid, sid3, sizeof(DOM_SID3) * num_sid3s);
+ return True;
}
/*******************************************************************
- Reads or writes a SAM_SID_STUFF structure.
+reads or writes a SAM_ENTRY3 structure.
********************************************************************/
+static BOOL sam_io_sam_entry3(char *desc, SAM_ENTRY3 *sam, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_entry3");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("grp_idx", ps, depth, &(sam->grp_idx));
+
+ prs_uint32("rid_grp", ps, depth, &(sam->rid_grp));
+ prs_uint32("attr ", ps, depth, &(sam->attr ));
+
+ smb_io_unihdr("unihdr", &(sam->hdr_grp_name), ps, depth); /* account name unicode string header */
+ smb_io_unihdr("unihdr", &(sam->hdr_grp_desc), ps, depth); /* account name unicode string header */
-static BOOL sam_io_sid_stuff(char *desc, SAM_SID_STUFF *stf, prs_struct *ps, int depth)
+ return True;
+}
+
+/*******************************************************************
+makes a SAM_ENTRY4 structure.
+********************************************************************/
+static BOOL make_sam_entry4(SAM_ENTRY4 *sam, uint32 user_idx,
+ uint32 len_acct_name)
{
- int i;
+ if (sam == NULL) return False;
- if (stf == NULL)
- return False;
+ DEBUG(5,("make_sam_entry4\n"));
- DEBUG(5,("init_sam_sid_stuff\n"));
+ sam->user_idx = user_idx;
+ make_str_hdr(&(sam->hdr_acct_name), len_acct_name, len_acct_name,
+ len_acct_name != 0);
- if(!prs_uint16("unknown_2", ps, depth, &stf->unknown_2))
- return False;
- if(!prs_uint16("unknown_3", ps, depth, &stf->unknown_3))
- return False;
+ return True;
+}
- if(!prs_uint8s(False, "padding1", ps, depth, stf->padding1, sizeof(stf->padding1)))
- return False;
-
- if(!prs_uint32("unknown_4", ps, depth, &stf->unknown_4))
- return False;
- if(!prs_uint32("unknown_5", ps, depth, &stf->unknown_5))
- return False;
- if(!prs_uint16("unknown_6", ps, depth, &stf->unknown_6))
- return False;
- if(!prs_uint16("unknown_7", ps, depth, &stf->unknown_7))
- return False;
+/*******************************************************************
+reads or writes a SAM_ENTRY4 structure.
+********************************************************************/
+static BOOL sam_io_sam_entry4(char *desc, SAM_ENTRY4 *sam, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return False;
- if(!prs_uint32("num_sids ", ps, depth, &stf->num_sids ))
- return False;
- if(!prs_uint16("padding2 ", ps, depth, &stf->padding2 ))
- return False;
+ prs_debug(ps, depth, desc, "sam_io_sam_entry4");
+ depth++;
- SMB_ASSERT_ARRAY(stf->sid, stf->num_sids);
+ prs_align(ps);
- for (i = 0; i < stf->num_sids; i++) {
- if(!sam_io_dom_sid3("", &(stf->sid[i]), ps, depth))
- return False;
- }
+ prs_uint32("user_idx", ps, depth, &(sam->user_idx));
+ smb_io_strhdr("strhdr", &(sam->hdr_acct_name), ps, depth);
return True;
}
/*******************************************************************
- Inits or writes a SAMR_R_UNKNOWN3 structure.
+makes a SAM_ENTRY5 structure.
********************************************************************/
+static BOOL make_sam_entry5(SAM_ENTRY5 *sam, uint32 grp_idx,
+ uint32 len_grp_name)
+{
+ if (sam == NULL) return False;
-void init_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
- uint16 unknown_2, uint16 unknown_3,
- uint32 unknown_4, uint16 unknown_6, uint16 unknown_7,
- int num_sid3s, DOM_SID3 sid3[MAX_SAM_SIDS],
- uint32 status)
+ DEBUG(5,("make_sam_entry5\n"));
+
+ sam->grp_idx = grp_idx;
+ make_str_hdr(&(sam->hdr_grp_name), len_grp_name, len_grp_name,
+ len_grp_name != 0);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SAM_ENTRY5 structure.
+********************************************************************/
+static BOOL sam_io_sam_entry5(char *desc, SAM_ENTRY5 *sam, prs_struct *ps, int depth)
{
- DEBUG(5,("samr_init_r_unknown_3\n"));
+ if (sam == NULL) return False;
- r_u->ptr_0 = 0;
- r_u->ptr_1 = 0;
+ prs_debug(ps, depth, desc, "sam_io_sam_entry5");
+ depth++;
- if (status == 0x0) {
- r_u->ptr_0 = 1;
- r_u->ptr_1 = 1;
- init_sam_sid_stuff(&(r_u->sid_stuff), unknown_2, unknown_3,
- unknown_4, unknown_6, unknown_7,
- num_sid3s, sid3);
- }
+ prs_align(ps);
- r_u->status = status;
+ prs_uint32("grp_idx", ps, depth, &(sam->grp_idx));
+ smb_io_strhdr("strhdr", &(sam->hdr_grp_name), ps, depth);
+
+ return True;
}
/*******************************************************************
- Reads or writes a SAMR_R_UNKNOWN_3 structure.
+makes a SAM_ENTRY structure.
+********************************************************************/
+BOOL make_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid)
+{
+ if (sam == NULL) return False;
+
+ DEBUG(10,("make_sam_entry: %d %d\n", len_sam_name, rid));
-this one's odd, because the daft buggers use a different mechanism
-for writing out the array of sids. they put the number of sids in
-only one place: they've calculated the length of each sid and jumped
-by that amount. then, retrospectively, the length of the whole buffer
-is put at the beginning of the data stream.
+ sam->rid = rid;
+ make_uni_hdr(&(sam->hdr_name), len_sam_name);
-wierd.
+ return True;
+}
+/*******************************************************************
+reads or writes a SAM_ENTRY structure.
********************************************************************/
+static BOOL sam_io_sam_entry(char *desc, SAM_ENTRY *sam, prs_struct *ps, int depth)
+{
+ if (sam == NULL) return False;
-BOOL samr_io_r_unknown_3(char *desc, SAMR_R_UNKNOWN_3 *r_u, prs_struct *ps, int depth)
+ prs_debug(ps, depth, desc, "sam_io_sam_entry");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("rid", ps, depth, &(sam->rid ));
+ smb_io_unihdr("unihdr", &(sam->hdr_name), ps, depth); /* account name unicode string header */
+
+ return True;
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_ENUM_DOM_USERS structure.
+********************************************************************/
+BOOL make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
+ uint32 start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size)
{
- int ptr_len0=0;
- int ptr_len1=0;
- int ptr_sid_stuff = 0;
+ if (q_e == NULL || pol == NULL) return False;
- if (r_u == NULL)
- return False;
+ DEBUG(5,("make_samr_q_enum_dom_users\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ q_e->start_idx = start_idx; /* zero indicates lots */
+ q_e->acb_mask = acb_mask;
+ q_e->unknown_1 = unk_1;
+ q_e->max_size = size;
- prs_debug(ps, depth, desc, "samr_io_r_unknown_3");
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_enum_dom_users");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_0 ", ps, depth, &r_u->ptr_0))
- return False;
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
- if (ps->io) {
- /* reading. do the length later */
- if(!prs_uint32("sid_stuff_len0", ps, depth, &r_u->sid_stuff_len0))
- return False;
- } else {
- /* storing */
- ptr_len0 = prs_offset(ps);
- if(!prs_set_offset(ps, ptr_len0 + 4))
- return False;
+ prs_uint32("start_idx", ps, depth, &(q_e->start_idx));
+ prs_uint16("acb_mask ", ps, depth, &(q_e->acb_mask ));
+ prs_uint16("unknown_1", ps, depth, &(q_e->unknown_1));
+
+ prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
+
+ prs_align(ps);
+
+ return True;
+}
+
+
+/*******************************************************************
+makes a SAMR_R_ENUM_DOM_USERS structure.
+********************************************************************/
+BOOL make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
+ uint32 next_idx,
+ uint32 num_sam_entries)
+{
+ if (r_u == NULL) return False;
+
+ DEBUG(5,("make_samr_r_enum_dom_users\n"));
+
+ r_u->next_idx = next_idx;
+
+ if (num_sam_entries != 0)
+ {
+ r_u->ptr_entries1 = 1;
+ r_u->ptr_entries2 = 1;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->num_entries3 = num_sam_entries;
+
+ r_u->num_entries4 = num_sam_entries;
+ }
+ else
+ {
+ r_u->ptr_entries1 = 0;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->ptr_entries2 = 1;
}
- if (r_u->ptr_0 != 0) {
- if(!prs_uint32("ptr_1 ", ps, depth, &r_u->ptr_1))
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth)
+{
+ uint32 i;
+
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_enum_dom_users");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("next_idx ", ps, depth, &(r_u->next_idx ));
+ prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
+
+ if (r_u->ptr_entries1 != 0)
+ {
+ prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+ prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
+ prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
+
+ if (ps->io)
+ {
+ r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
+ r_u->uni_acct_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_acct_name[0]));
+ }
+
+ if ((r_u->sam == NULL || r_u->uni_acct_name == NULL) && r_u->num_entries2 != 0)
+ {
+ DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_USERS\n"));
+ r_u->num_entries4 = 0;
+ r_u->status = 0xC0000000|NT_STATUS_MEMORY_NOT_ALLOCATED;
return False;
- if (ps->io) {
- /* reading. do the length later */
- if(!prs_uint32("sid_stuff_len1", ps, depth, &r_u->sid_stuff_len1))
- return False;
- } else {
- /* storing */
- ptr_len1 = prs_offset(ps);
- if(!prs_set_offset(ps, ptr_len1 + 4))
- return False;
}
- if (r_u->ptr_1 != 0) {
- ptr_sid_stuff = prs_offset(ps);
- if(!sam_io_sid_stuff("", &r_u->sid_stuff, ps, depth))
- return False;
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
}
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ smb_io_unistr2("", &(r_u->uni_acct_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
+ prs_align(ps);
+ }
+
+ prs_align(ps);
+
}
- if (!(ps->io)) {
- /* storing not reading. do the length, now. */
+ prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
+ prs_uint32("status", ps, depth, &(r_u->status));
- if (ptr_sid_stuff != 0) {
- int old_len = prs_offset(ps);
- uint32 sid_stuff_len = old_len - ptr_sid_stuff;
+ return True;
+}
- if(!prs_set_offset(ps, ptr_len0))
- return False;
- if(!prs_uint32("sid_stuff_len0", ps, depth, &sid_stuff_len))
- return False;
+/*******************************************************************
+makes a SAMR_Q_QUERY_DISPINFO structure.
+********************************************************************/
+BOOL make_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
+ uint16 switch_level, uint32 start_idx,
+ uint32 max_entries)
+{
+ if (q_e == NULL || pol == NULL) return False;
- if(!prs_set_offset(ps, ptr_len1))
- return False;
- if(!prs_uint32("sid_stuff_len1", ps, depth, &sid_stuff_len))
- return False;
+ DEBUG(5,("make_samr_q_query_dispinfo\n"));
- if(!prs_set_offset(ps, old_len))
- return False;
- }
- }
+ memcpy(&(q_e->domain_pol), pol, sizeof(*pol));
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ q_e->switch_level = switch_level;
+
+ q_e->start_idx = start_idx;
+ q_e->max_entries = max_entries;
+ q_e->max_size = 0xffff; /* Not especially useful */
return True;
}
/*******************************************************************
- Reads or writes a SAM_STR1 structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL sam_io_sam_str1(char *desc, SAM_STR1 *sam, uint32 acct_buf,
- uint32 name_buf, uint32 desc_buf, prs_struct *ps, int depth)
+BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth)
{
- if (sam == NULL)
- return False;
+ if (q_e == NULL) return False;
- prs_debug(ps, depth, desc, "sam_io_sam_str1");
+ prs_debug(ps, depth, desc, "samr_io_q_query_dispinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unistr2("unistr2", &sam->uni_acct_name, acct_buf, ps, depth)) /* account name unicode string */
- return False;
- if(!smb_io_unistr2("unistr2", &sam->uni_full_name, name_buf, ps, depth)) /* full name unicode string */
- return False;
- if(!smb_io_unistr2("unistr2", &sam->uni_acct_desc, desc_buf, ps, depth)) /* account description unicode string */
- return False;
+ smb_io_pol_hnd("domain_pol", &(q_e->domain_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
+ prs_align(ps);
+
+ prs_uint32("start_idx ", ps, depth, &(q_e->start_idx ));
+ prs_uint32("max_entries ", ps, depth, &(q_e->max_entries ));
+ prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
return True;
}
+
/*******************************************************************
- Inits a SAM_ENTRY1 structure.
+makes a SAM_DISPINFO_1 structure.
********************************************************************/
+BOOL make_sam_dispinfo_1(SAM_DISPINFO_1 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+{
+ uint32 len_sam_name, len_sam_full, len_sam_desc;
+ uint32 max_entries, max_data_size;
+ uint32 dsize = 0;
+ uint32 i;
-static void init_sam_entry1(SAM_ENTRY1 *sam, uint32 user_idx,
- uint32 len_sam_name, uint32 len_sam_full, uint32 len_sam_desc,
- uint32 rid_user, uint16 acb_info)
+ if (sam == NULL || num_entries == NULL || data_size == NULL) return False;
+
+ max_entries = *num_entries;
+ max_data_size = *data_size;
+
+ DEBUG(5,("make_sam_dispinfo_1: max_entries: %d max_dsize: 0x%x\n",
+ max_entries, max_data_size));
+
+ for (i = 0; (i < max_entries) && (dsize < max_data_size); i++)
+ {
+ len_sam_name = pass[i].uni_user_name.uni_str_len;
+ len_sam_full = pass[i].uni_full_name.uni_str_len;
+ len_sam_desc = pass[i].uni_acct_desc.uni_str_len;
+
+ make_sam_entry1(&(sam->sam[i]), start_idx + i + 1,
+ len_sam_name, len_sam_full, len_sam_desc,
+ pass[i].user_rid, pass[i].acb_info);
+
+ copy_unistr2(&(sam->str[i].uni_acct_name), &(pass[i].uni_user_name));
+ copy_unistr2(&(sam->str[i].uni_full_name), &(pass[i].uni_full_name));
+ copy_unistr2(&(sam->str[i].uni_acct_desc), &(pass[i].uni_acct_desc));
+
+ dsize += sizeof(SAM_ENTRY1);
+ dsize += len_sam_name + len_sam_full + len_sam_desc;
+ }
+
+ *num_entries = i;
+ *data_size = dsize;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_sam_dispinfo_1(char *desc, SAM_DISPINFO_1 *sam, uint32 num_entries, prs_struct *ps, int depth)
{
- DEBUG(5,("init_sam_entry1\n"));
+ uint32 i;
- sam->user_idx = user_idx;
- sam->rid_user = rid_user;
- sam->acb_info = acb_info;
- sam->pad = 0;
+ if (sam == NULL) return False;
- init_uni_hdr(&sam->hdr_acct_name, len_sam_name);
- init_uni_hdr(&sam->hdr_user_name, len_sam_full);
- init_uni_hdr(&sam->hdr_user_desc, len_sam_desc);
+ prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_1");
+ depth++;
+
+ prs_align(ps);
+
+ SMB_ASSERT_ARRAY(sam->sam, num_entries);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ sam_io_sam_entry1("", &(sam->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ sam_io_sam_str1 ("", &(sam->str[i]),
+ sam->sam[i].hdr_acct_name.buffer,
+ sam->sam[i].hdr_user_name.buffer,
+ sam->sam[i].hdr_user_desc.buffer,
+ ps, depth);
+ }
+
+ return True;
}
+
/*******************************************************************
- Reads or writes a SAM_ENTRY1 structure.
+makes a SAM_DISPINFO_2 structure.
********************************************************************/
+BOOL make_sam_dispinfo_2(SAM_DISPINFO_2 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+{
+ uint32 len_sam_name, len_sam_desc;
+ uint32 max_entries, max_data_size;
+ uint32 dsize = 0;
+ uint32 i;
-static BOOL sam_io_sam_entry1(char *desc, SAM_ENTRY1 *sam, prs_struct *ps, int depth)
+ if (sam == NULL || num_entries == NULL || data_size == NULL) return False;
+
+ DEBUG(5,("make_sam_dispinfo_2\n"));
+
+ max_entries = *num_entries;
+ max_data_size = *data_size;
+
+ for (i = 0; (i < max_entries) && (dsize < max_data_size); i++)
+ {
+ len_sam_name = pass[i].uni_user_name.uni_str_len;
+ len_sam_desc = pass[i].uni_acct_desc.uni_str_len;
+
+ make_sam_entry2(&(sam->sam[i]), start_idx + i + 1,
+ len_sam_name, len_sam_desc,
+ pass[i].user_rid, pass[i].acb_info);
+
+ copy_unistr2(&(sam->str[i].uni_srv_name), &(pass[i].uni_user_name));
+ copy_unistr2(&(sam->str[i].uni_srv_desc), &(pass[i].uni_acct_desc));
+
+ dsize += sizeof(SAM_ENTRY2);
+ dsize += len_sam_name + len_sam_desc;
+ }
+
+ *num_entries = i;
+ *data_size = dsize;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_sam_dispinfo_2(char *desc, SAM_DISPINFO_2 *sam, uint32 num_entries, prs_struct *ps, int depth)
{
- if (sam == NULL)
- return False;
+ uint32 i;
- prs_debug(ps, depth, desc, "sam_io_sam_entry1");
+ if (sam == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("user_idx ", ps, depth, &sam->user_idx))
- return False;
+ SMB_ASSERT_ARRAY(sam->sam, num_entries);
- if(!prs_uint32("rid_user ", ps, depth, &sam->rid_user))
- return False;
- if(!prs_uint16("acb_info ", ps, depth, &sam->acb_info))
- return False;
- if(!prs_uint16("pad ", ps, depth, &sam->pad))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ sam_io_sam_entry2("", &(sam->sam[i]), ps, depth);
+ }
- if(!smb_io_unihdr("unihdr", &sam->hdr_acct_name, ps, depth)) /* account name unicode string header */
- return False;
- if(!smb_io_unihdr("unihdr", &sam->hdr_user_name, ps, depth)) /* account name unicode string header */
- return False;
- if(!smb_io_unihdr("unihdr", &sam->hdr_user_desc, ps, depth)) /* account name unicode string header */
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ sam_io_sam_str2 ("", &(sam->str[i]),
+ sam->sam[i].hdr_srv_name.buffer,
+ sam->sam[i].hdr_srv_desc.buffer,
+ ps, depth);
+ }
return True;
}
+
/*******************************************************************
- Reads or writes a SAM_STR2 structure.
+makes a SAM_DISPINFO_3 structure.
********************************************************************/
+BOOL make_sam_dispinfo_3(SAM_DISPINFO_3 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ DOMAIN_GRP *grp)
+{
+ uint32 len_sam_name, len_sam_desc;
+ uint32 max_entries, max_data_size;
+ uint32 dsize = 0;
+ uint32 i;
-static BOOL sam_io_sam_str2(char *desc, SAM_STR2 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth)
+ if (sam == NULL || num_entries == NULL || data_size == NULL) return False;
+
+ DEBUG(5,("make_sam_dispinfo_3\n"));
+
+ max_entries = *num_entries;
+ max_data_size = *data_size;
+
+ for (i = 0; (i < max_entries) && (dsize < max_data_size); i++)
+ {
+ len_sam_name = strlen(grp[i].name);
+ len_sam_desc = strlen(grp[i].comment);
+
+ make_sam_entry3(&(sam->sam[i]), start_idx + i + 1,
+ len_sam_name, len_sam_desc,
+ grp[i].rid);
+
+ make_unistr2(&(sam->str[i].uni_grp_name), grp[i].name , len_sam_name);
+ make_unistr2(&(sam->str[i].uni_grp_desc), grp[i].comment, len_sam_desc);
+
+ dsize += sizeof(SAM_ENTRY3);
+ dsize += (len_sam_name + len_sam_desc) * 2;
+ dsize += 14;
+ }
+
+ *num_entries = i;
+ *data_size = dsize;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_sam_dispinfo_3(char *desc, SAM_DISPINFO_3 *sam, uint32 num_entries, prs_struct *ps, int depth)
{
- if (sam == NULL)
- return False;
+ uint32 i;
- prs_debug(ps, depth, desc, "sam_io_sam_str2");
+ if (sam == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_3");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unistr2("unistr2", &sam->uni_srv_name, acct_buf, ps, depth)) /* account name unicode string */
- return False;
- if(!smb_io_unistr2("unistr2", &sam->uni_srv_desc, desc_buf, ps, depth)) /* account description unicode string */
- return False;
+ SMB_ASSERT_ARRAY(sam->sam, num_entries);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ sam_io_sam_entry3("", &(sam->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ sam_io_sam_str3 ("", &(sam->str[i]),
+ sam->sam[i].hdr_grp_name.buffer,
+ sam->sam[i].hdr_grp_desc.buffer,
+ ps, depth);
+ }
return True;
}
+
/*******************************************************************
- Inits a SAM_ENTRY2 structure.
+makes a SAM_DISPINFO_4 structure.
********************************************************************/
+BOOL make_sam_dispinfo_4(SAM_DISPINFO_4 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+{
+ fstring sam_name;
+ uint32 len_sam_name;
+ uint32 max_entries, max_data_size;
+ uint32 dsize = 0;
+ uint32 i;
-static void init_sam_entry2(SAM_ENTRY2 *sam, uint32 user_idx,
- uint32 len_sam_name, uint32 len_sam_desc,
- uint32 rid_user, uint16 acb_info)
+ if (sam == NULL || num_entries == NULL || data_size == NULL) return False;
+
+ DEBUG(5,("make_sam_dispinfo_4\n"));
+
+ max_entries = *num_entries;
+ max_data_size = *data_size;
+
+ for (i = 0; (i < max_entries) && (dsize < max_data_size); i++)
+ {
+ len_sam_name = pass[i].uni_user_name.uni_str_len;
+
+ make_sam_entry4(&(sam->sam[i]), start_idx + i + 1,
+ len_sam_name);
+
+ unistr2_to_ascii(sam_name, &(pass[i].uni_user_name), sizeof(sam_name));
+ make_string2(&(sam->str[i].acct_name), sam_name, len_sam_name);
+
+ dsize += sizeof(SAM_ENTRY4);
+ dsize += len_sam_name;
+ }
+
+ *num_entries = i;
+ *data_size = dsize;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_sam_dispinfo_4(char *desc, SAM_DISPINFO_4 *sam, uint32 num_entries, prs_struct *ps, int depth)
{
- DEBUG(5,("init_sam_entry2\n"));
+ uint32 i;
- sam->user_idx = user_idx;
- sam->rid_user = rid_user;
- sam->acb_info = acb_info;
- sam->pad = 0;
+ if (sam == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_4");
+ depth++;
+
+ prs_align(ps);
+
+ SMB_ASSERT_ARRAY(sam->sam, num_entries);
+
+ for (i = 0; i < num_entries; i++)
+ {
+ sam_io_sam_entry4("", &(sam->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ smb_io_string2("acct_name", &(sam->str[i].acct_name),
+ sam->sam[i].hdr_acct_name.buffer, ps, depth);
+ prs_align(ps);
+ }
- init_uni_hdr(&sam->hdr_srv_name, len_sam_name);
- init_uni_hdr(&sam->hdr_srv_desc, len_sam_desc);
+ return True;
}
+
/*******************************************************************
- Reads or writes a SAM_ENTRY2 structure.
+makes a SAM_DISPINFO_5 structure.
********************************************************************/
+BOOL make_sam_dispinfo_5(SAM_DISPINFO_5 *sam, uint32 *num_entries,
+ uint32 *data_size, uint32 start_idx,
+ DOMAIN_GRP *grp)
+{
+ uint32 len_sam_name;
+ uint32 max_entries, max_data_size;
+ uint32 dsize = 0;
+ uint32 i;
-static BOOL sam_io_sam_entry2(char *desc, SAM_ENTRY2 *sam, prs_struct *ps, int depth)
+ if (sam == NULL || num_entries == NULL || data_size == NULL) return False;
+
+ DEBUG(5,("make_sam_dispinfo_5\n"));
+
+ max_entries = *num_entries;
+ max_data_size = *data_size;
+
+ for (i = 0; (i < max_entries) && (dsize < max_data_size); i++)
+ {
+ len_sam_name = strlen(grp[i].name);
+
+ make_sam_entry5(&(sam->sam[i]), start_idx + i + 1,
+ len_sam_name);
+
+ make_string2(&(sam->str[i].grp_name), grp[i].name,
+ len_sam_name);
+
+ dsize += sizeof(SAM_ENTRY5);
+ dsize += len_sam_name;
+ }
+
+ *num_entries = i;
+ *data_size = dsize;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_sam_dispinfo_5(char *desc, SAM_DISPINFO_5 *sam, uint32 num_entries, prs_struct *ps, int depth)
{
- if (sam == NULL)
- return False;
+ uint32 i;
- prs_debug(ps, depth, desc, "sam_io_sam_entry2");
+ if (sam == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_sam_dispinfo_5");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("user_idx ", ps, depth, &sam->user_idx))
- return False;
+ SMB_ASSERT_ARRAY(sam->sam, num_entries);
- if(!prs_uint32("rid_user ", ps, depth, &sam->rid_user))
- return False;
- if(!prs_uint16("acb_info ", ps, depth, &sam->acb_info))
- return False;
- if(!prs_uint16("pad ", ps, depth, &sam->pad))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ sam_io_sam_entry5("", &(sam->sam[i]), ps, depth);
+ }
- if(!smb_io_unihdr("unihdr", &sam->hdr_srv_name, ps, depth)) /* account name unicode string header */
- return False;
- if(!smb_io_unihdr("unihdr", &sam->hdr_srv_desc, ps, depth)) /* account name unicode string header */
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ smb_io_string2("grp_name", &(sam->str[i].grp_name),
+ sam->sam[i].hdr_grp_name.buffer, ps, depth);
+ prs_align(ps);
+ }
return True;
}
+
/*******************************************************************
- Reads or writes a SAM_STR3 structure.
+makes a SAMR_R_QUERY_DISPINFO structure.
********************************************************************/
+BOOL make_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
+ uint32 num_entries, uint32 data_size,
+ uint16 switch_level, SAM_DISPINFO_CTR *ctr,
+ uint32 status)
+{
+ if (r_u == NULL) return False;
-static BOOL sam_io_sam_str3(char *desc, SAM_STR3 *sam, uint32 acct_buf, uint32 desc_buf, prs_struct *ps, int depth)
+ DEBUG(5,("make_samr_r_query_dispinfo: level %d\n", switch_level));
+
+ r_u->total_size = data_size; /* not calculated */
+ r_u->data_size = data_size;
+
+ r_u->switch_level = switch_level;
+ r_u->num_entries = num_entries;
+ r_u->ptr_entries = 1;
+ r_u->num_entries2 = num_entries;
+ r_u->ctr = ctr;
+
+ r_u->status = status;
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth)
{
- if (sam == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "sam_io_sam_str3");
+ prs_debug(ps, depth, desc, "samr_io_r_query_dispinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unistr2("unistr2", &sam->uni_grp_name, acct_buf, ps, depth)) /* account name unicode string */
- return False;
- if(!smb_io_unistr2("unistr2", &sam->uni_grp_desc, desc_buf, ps, depth)) /* account description unicode string */
- return False;
+ prs_uint32("total_size ", ps, depth, &(r_u->total_size ));
+ prs_uint32("data_size ", ps, depth, &(r_u->data_size ));
+ prs_uint16("switch_level", ps, depth, &(r_u->switch_level));
+ prs_align(ps);
+
+ prs_uint32("num_entries ", ps, depth, &(r_u->num_entries ));
+ prs_uint32("ptr_entries ", ps, depth, &(r_u->ptr_entries ));
+ prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+
+ switch (r_u->switch_level)
+ {
+ case 0x1:
+ {
+ sam_io_sam_dispinfo_1("users", r_u->ctr->sam.info1, r_u->num_entries, ps, depth);
+ break;
+ }
+ case 0x2:
+ {
+ sam_io_sam_dispinfo_2("servers", r_u->ctr->sam.info2, r_u->num_entries, ps, depth);
+ break;
+ }
+ case 0x3:
+ {
+ sam_io_sam_dispinfo_3("groups", r_u->ctr->sam.info3, r_u->num_entries, ps, depth);
+ break;
+ }
+ case 0x4:
+ {
+ sam_io_sam_dispinfo_4("user list", r_u->ctr->sam.info4,r_u->num_entries, ps, depth);
+ break;
+ }
+ case 0x5:
+ {
+ sam_io_sam_dispinfo_5("group list", r_u->ctr->sam.info5, r_u->num_entries, ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("samr_io_r_query_dispinfo: unknown switch value\n"));
+ break;
+ }
+ }
+
+ prs_align(ps);
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
+
/*******************************************************************
- Inits a SAM_ENTRY3 structure.
+makes a SAMR_Q_OPEN_GROUP structure.
********************************************************************/
-
-static void init_sam_entry3(SAM_ENTRY3 *sam, uint32 grp_idx,
- uint32 len_grp_name, uint32 len_grp_desc, uint32 rid_grp)
+BOOL make_samr_q_open_group(SAMR_Q_OPEN_GROUP *q_c,
+ const POLICY_HND *hnd,
+ uint32 access_mask, uint32 rid)
{
- DEBUG(5,("init_sam_entry3\n"));
+ if (q_c == NULL || hnd == NULL) return False;
- sam->grp_idx = grp_idx;
- sam->rid_grp = rid_grp;
- sam->attr = 0x07; /* group rid attributes - gets ignored by nt 4.0 */
+ DEBUG(5,("make_samr_q_open_group\n"));
+
+ memcpy(&(q_c->domain_pol), hnd, sizeof(q_c->domain_pol));
+ q_c->access_mask = access_mask;
+ q_c->rid_group = rid;
- init_uni_hdr(&sam->hdr_grp_name, len_grp_name);
- init_uni_hdr(&sam->hdr_grp_desc, len_grp_desc);
+ return True;
}
/*******************************************************************
- Reads or writes a SAM_ENTRY3 structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_q_open_group(char *desc, SAMR_Q_OPEN_GROUP *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
-static BOOL sam_io_sam_entry3(char *desc, SAM_ENTRY3 *sam, prs_struct *ps, int depth)
+ prs_debug(ps, depth, desc, "samr_io_q_open_group");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth);
+
+ prs_uint32("access_mask", ps, depth, &(q_u->access_mask));
+ prs_uint32("rid_group", ps, depth, &(q_u->rid_group));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_open_group(char *desc, SAMR_R_OPEN_GROUP *r_u, prs_struct *ps, int depth)
{
- if (sam == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "sam_io_sam_entry3");
+ prs_debug(ps, depth, desc, "samr_io_r_open_group");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("grp_idx", ps, depth, &sam->grp_idx))
- return False;
+ smb_io_pol_hnd("pol", &(r_u->pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint32("rid_grp", ps, depth, &sam->rid_grp))
- return False;
- if(!prs_uint32("attr ", ps, depth, &sam->attr))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
- if(!smb_io_unihdr("unihdr", &sam->hdr_grp_name, ps, depth)) /* account name unicode string header */
- return False;
- if(!smb_io_unihdr("unihdr", &sam->hdr_grp_desc, ps, depth)) /* account name unicode string header */
- return False;
+ return True;
+}
+
+
+/*******************************************************************
+makes a GROUP_INFO1 structure.
+********************************************************************/
+BOOL make_samr_group_info1(GROUP_INFO1 *gr1,
+ char *acct_name, char *acct_desc,
+ uint32 num_members)
+{
+ int desc_len = acct_desc != NULL ? strlen(acct_desc) : 0;
+ int acct_len = acct_name != NULL ? strlen(acct_name) : 0;
+ if (gr1 == NULL) return False;
+
+ DEBUG(5,("make_samr_group_info1\n"));
+
+ make_uni_hdr(&(gr1->hdr_acct_name), acct_len);
+
+ gr1->unknown_1 = 0x3;
+ gr1->num_members = num_members;
+
+ make_uni_hdr(&(gr1->hdr_acct_desc), desc_len);
+
+ make_unistr2(&(gr1->uni_acct_name), acct_name, acct_len);
+ make_unistr2(&(gr1->uni_acct_desc), acct_desc, desc_len);
return True;
}
+
/*******************************************************************
- Inits a SAM_ENTRY structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_group_info1(char *desc, GROUP_INFO1 *gr1, prs_struct *ps, int depth)
+{
+ if (gr1 == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_group_info1");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unihdr ("hdr_acct_name", &(gr1->hdr_acct_name) , ps, depth);
+
+ prs_uint32("unknown_1", ps, depth, &(gr1->unknown_1));
+ prs_uint32("num_members", ps, depth, &(gr1->num_members));
-static void init_sam_entry(SAM_ENTRY *sam, uint32 len_sam_name, uint32 rid)
+ smb_io_unihdr ("hdr_acct_desc", &(gr1->hdr_acct_desc) , ps, depth);
+
+ smb_io_unistr2("uni_acct_name", &(gr1->uni_acct_name), gr1->hdr_acct_name.buffer, ps, depth);
+ prs_align(ps);
+
+ smb_io_unistr2("uni_acct_desc", &(gr1->uni_acct_desc), gr1->hdr_acct_desc.buffer, ps, depth);
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+makes a GROUP_INFO4 structure.
+********************************************************************/
+BOOL make_samr_group_info4(GROUP_INFO4 *gr4, const char *acct_desc)
{
- DEBUG(5,("init_sam_entry\n"));
+ int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
+ if (gr4 == NULL) return False;
- sam->rid = rid;
- init_uni_hdr(&sam->hdr_name, len_sam_name);
+ DEBUG(5,("make_samr_group_info4\n"));
+
+ make_uni_hdr(&(gr4->hdr_acct_desc), acct_len);
+ make_unistr2(&(gr4->uni_acct_desc), acct_desc, acct_len);
+
+ return True;
}
+
/*******************************************************************
- Reads or writes a SAM_ENTRY structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_group_info4(char *desc, GROUP_INFO4 *gr4, prs_struct *ps, int depth)
+{
+ if (gr4 == NULL) return False;
-static BOOL sam_io_sam_entry(char *desc, SAM_ENTRY *sam, prs_struct *ps, int depth)
+ prs_debug(ps, depth, desc, "samr_io_group_info4");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unihdr ("hdr_acct_desc", &(gr4->hdr_acct_desc) , ps, depth);
+ smb_io_unistr2("uni_acct_desc", &(gr4->uni_acct_desc), gr4->hdr_acct_desc.buffer, ps, depth);
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_group_info_ctr(char *desc, GROUP_INFO_CTR *ctr, prs_struct *ps, int depth)
{
- if (sam == NULL)
- return False;
+ if (ctr == NULL) return False;
- prs_debug(ps, depth, desc, "sam_io_sam_entry");
+ prs_debug(ps, depth, desc, "samr_group_info_ctr");
depth++;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("rid", ps, depth, &sam->rid))
- return False;
- if(!smb_io_unihdr("unihdr", &sam->hdr_name, ps, depth)) /* account name unicode string header */
- return False;
+ prs_uint16("switch_value1", ps, depth, &(ctr->switch_value1));
+ prs_uint16("switch_value2", ps, depth, &(ctr->switch_value2));
+
+ switch (ctr->switch_value1)
+ {
+ case 1:
+ {
+ samr_io_group_info1("group_info1", &(ctr->group.info1), ps, depth);
+ break;
+ }
+ case 4:
+ {
+ samr_io_group_info4("group_info4", &(ctr->group.info4), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(4,("samr_group_info_ctr: unsupported switch level\n"));
+ break;
+ }
+ }
+
+ prs_align(ps);
return True;
}
/*******************************************************************
- Inits a SAMR_Q_ENUM_DOM_USERS structure.
+makes a SAMR_Q_CREATE_DOM_GROUP structure.
********************************************************************/
+BOOL make_samr_q_create_dom_group(SAMR_Q_CREATE_DOM_GROUP *q_e,
+ POLICY_HND *pol,
+ const char *acct_desc)
+{
+ int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
+ if (q_e == NULL || pol == NULL) return False;
-void init_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
- uint16 req_num_entries, uint16 unk_0,
- uint16 acb_mask, uint16 unk_1, uint32 size)
+ DEBUG(5,("make_samr_q_create_dom_group\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ make_uni_hdr(&(q_e->hdr_acct_desc), acct_len);
+ make_unistr2(&(q_e->uni_acct_desc), acct_desc, acct_len);
+
+ q_e->access_mask = 0x00020001;
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_create_dom_group(char *desc, SAMR_Q_CREATE_DOM_GROUP *q_e, prs_struct *ps, int depth)
{
- DEBUG(5,("init_q_enum_dom_users\n"));
+ if (q_e == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_create_dom_group");
+ depth++;
- memcpy(&q_e->pol, pol, sizeof(*pol));
+ prs_align(ps);
- q_e->req_num_entries = req_num_entries; /* zero indicates lots */
- q_e->unknown_0 = unk_0; /* this gets returned in the response */
- q_e->acb_mask = acb_mask;
- q_e->unknown_1 = unk_1;
- q_e->max_size = size;
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
+
+ smb_io_unihdr ("hdr_acct_desc", &(q_e->hdr_acct_desc), ps, depth);
+ smb_io_unistr2("uni_acct_desc", &(q_e->uni_acct_desc), q_e->hdr_acct_desc.buffer, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("access", ps, depth, &(q_e->access_mask));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_r_create_dom_group(char *desc, SAMR_R_CREATE_DOM_GROUP *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
-BOOL samr_io_q_enum_dom_users(char *desc, SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth)
+ prs_debug(ps, depth, desc, "samr_io_r_create_dom_group");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(r_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("rid ", ps, depth, &(r_u->rid ));
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+makes a SAMR_Q_DELETE_DOM_GROUP structure.
+********************************************************************/
+BOOL make_samr_q_delete_dom_group(SAMR_Q_DELETE_DOM_GROUP *q_c, POLICY_HND *hnd)
{
- if (q_e == NULL)
- return False;
+ if (q_c == NULL || hnd == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_enum_dom_users");
+ DEBUG(5,("make_samr_q_delete_dom_group\n"));
+
+ memcpy(&(q_c->group_pol), hnd, sizeof(q_c->group_pol));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_delete_dom_group(char *desc, SAMR_Q_DELETE_DOM_GROUP *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_delete_dom_group");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("group_pol", &(q_u->group_pol), ps, depth);
- if(!prs_uint16("req_num_entries", ps, depth, &q_e->req_num_entries))
- return False;
- if(!prs_uint16("unknown_0 ", ps, depth, &q_e->unknown_0))
- return False;
+ return True;
+}
- if(!prs_uint16("acb_mask ", ps, depth, &q_e->acb_mask))
- return False;
- if(!prs_uint16("unknown_1 ", ps, depth, &q_e->unknown_1))
- return False;
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_delete_dom_group(char *desc, SAMR_R_DELETE_DOM_GROUP *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
- if(!prs_uint32("max_size ", ps, depth, &q_e->max_size))
- return False;
+ prs_debug(ps, depth, desc, "samr_io_r_delete_dom_group");
+ depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
+
/*******************************************************************
- Inits a SAMR_R_ENUM_DOM_USERS structure.
+makes a SAMR_Q_DEL_GROUPMEM structure.
********************************************************************/
+BOOL make_samr_q_del_groupmem(SAMR_Q_DEL_GROUPMEM *q_e,
+ POLICY_HND *pol,
+ uint32 rid)
+{
+ if (q_e == NULL || pol == NULL) return False;
+
+ DEBUG(5,("make_samr_q_del_groupmem\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
-void init_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
- uint16 total_num_entries, uint16 unk_0,
- uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status)
+ q_e->rid = rid;
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_del_groupmem(char *desc, SAMR_Q_DEL_GROUPMEM *q_e, prs_struct *ps, int depth)
{
- int i;
+ if (q_e == NULL) return False;
- DEBUG(5,("init_samr_r_enum_dom_users\n"));
+ prs_debug(ps, depth, desc, "samr_io_q_del_groupmem");
+ depth++;
- if (num_sam_entries >= MAX_SAM_ENTRIES) {
- num_sam_entries = MAX_SAM_ENTRIES;
- DEBUG(5,("limiting number of entries to %d\n",
- num_sam_entries));
- }
+ prs_align(ps);
- r_u->total_num_entries = total_num_entries;
- r_u->unknown_0 = unk_0;
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
- if (total_num_entries > 0) {
- r_u->ptr_entries1 = 1;
- r_u->ptr_entries2 = 1;
- r_u->num_entries2 = num_sam_entries;
- r_u->num_entries3 = num_sam_entries;
+ prs_uint32("rid ", ps, depth, &(q_e->rid));
- SMB_ASSERT_ARRAY(r_u->sam, num_sam_entries);
- SMB_ASSERT_ARRAY(r_u->uni_acct_name, num_sam_entries);
+ return True;
+}
- for (i = 0; i < num_sam_entries; i++) {
- init_sam_entry(&(r_u->sam[i]),
- pass[i].uni_user_name.uni_str_len,
- pass[i].user_rid);
- copy_unistr2(&r_u->uni_acct_name[i], &(pass[i].uni_user_name));
- }
+/*******************************************************************
+makes a SAMR_R_DEL_GROUPMEM structure.
+********************************************************************/
+BOOL make_samr_r_del_groupmem(SAMR_R_DEL_GROUPMEM *r_u, POLICY_HND *pol,
+ uint32 status)
+{
+ if (r_u == NULL) return False;
- r_u->num_entries4 = num_sam_entries;
- } else {
- r_u->ptr_entries1 = 0;
- r_u->num_entries2 = num_sam_entries;
- r_u->ptr_entries2 = 1;
- }
+ DEBUG(5,("make_samr_r_del_groupmem\n"));
r_u->status = status;
+
+ return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_r_del_groupmem(char *desc, SAMR_R_DEL_GROUPMEM *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_del_groupmem");
+ depth++;
+
+ prs_align(ps);
-BOOL samr_io_r_enum_dom_users(char *desc, SAMR_R_ENUM_DOM_USERS *r_u, prs_struct *ps, int depth)
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_ADD_GROUPMEM structure.
+********************************************************************/
+BOOL make_samr_q_add_groupmem(SAMR_Q_ADD_GROUPMEM *q_e,
+ POLICY_HND *pol,
+ uint32 rid)
{
- int i;
+ if (q_e == NULL || pol == NULL) return False;
- if (r_u == NULL)
- return False;
+ DEBUG(5,("make_samr_q_add_groupmem\n"));
- prs_debug(ps, depth, desc, "samr_io_r_enum_dom_users");
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ q_e->rid = rid;
+ q_e->unknown = 0x0005;
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_add_groupmem(char *desc, SAMR_Q_ADD_GROUPMEM *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_add_groupmem");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint16("total_num_entries", ps, depth, &r_u->total_num_entries))
- return False;
- if(!prs_uint16("unknown_0 ", ps, depth, &r_u->unknown_0))
- return False;
- if(!prs_uint32("ptr_entries1", ps, depth, &r_u->ptr_entries1))
- return False;
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
- if (r_u->total_num_entries != 0 && r_u->ptr_entries1 != 0) {
- if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
- return False;
- if(!prs_uint32("ptr_entries2", ps, depth, &r_u->ptr_entries2))
- return False;
- if(!prs_uint32("num_entries3", ps, depth, &r_u->num_entries3))
- return False;
+ prs_uint32("rid ", ps, depth, &(q_e->rid));
+ prs_uint32("unknown", ps, depth, &(q_e->unknown));
- SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries2);
+ return True;
+}
- for (i = 0; i < r_u->num_entries2; i++) {
- if(!sam_io_sam_entry("", &r_u->sam[i], ps, depth))
- return False;
- }
- SMB_ASSERT_ARRAY(r_u->uni_acct_name, r_u->num_entries2);
+/*******************************************************************
+makes a SAMR_R_ADD_GROUPMEM structure.
+********************************************************************/
+BOOL make_samr_r_add_groupmem(SAMR_R_ADD_GROUPMEM *r_u, POLICY_HND *pol,
+ uint32 status)
+{
+ if (r_u == NULL) return False;
- for (i = 0; i < r_u->num_entries2; i++) {
- if(!smb_io_unistr2("", &r_u->uni_acct_name[i],
- r_u->sam[i].hdr_name.buffer, ps, depth))
- return False;
- }
+ DEBUG(5,("make_samr_r_add_groupmem\n"));
- if(!prs_align(ps))
- return False;
+ r_u->status = status;
- if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
- return False;
- }
+ return True;
+}
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_add_groupmem(char *desc, SAMR_R_ADD_GROUPMEM *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_add_groupmem");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
+
/*******************************************************************
- Inits a SAMR_Q_ENUM_DOM_ALIASES structure.
+makes a SAMR_Q_SET_GROUPINFO structure.
********************************************************************/
+BOOL make_samr_q_set_groupinfo(SAMR_Q_SET_GROUPINFO *q_e,
+ POLICY_HND *pol, GROUP_INFO_CTR *ctr)
+{
+ if (q_e == NULL || pol == NULL) return False;
+
+ DEBUG(5,("make_samr_q_set_groupinfo\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+ q_e->ctr = ctr;
-void init_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol, uint32 size)
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_set_groupinfo(char *desc, SAMR_Q_SET_GROUPINFO *q_e, prs_struct *ps, int depth)
{
- DEBUG(5,("init_q_enum_dom_aliases\n"));
+ if (q_e == NULL) return False;
- memcpy(&q_e->pol, pol, sizeof(*pol));
+ prs_debug(ps, depth, desc, "samr_io_q_set_groupinfo");
+ depth++;
- q_e->unknown_0 = 0;
- q_e->max_size = size;
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
+
+ samr_group_info_ctr("ctr", q_e->ctr, ps, depth);
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+makes a SAMR_R_SET_GROUPINFO structure.
********************************************************************/
+BOOL make_samr_r_set_groupinfo(SAMR_R_SET_GROUPINFO *r_u,
+ uint32 status)
+{
+ if (r_u == NULL) return False;
-BOOL samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth)
+ DEBUG(5,("make_samr_r_set_groupinfo\n"));
+
+ r_u->status = status;
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_set_groupinfo(char *desc, SAMR_R_SET_GROUPINFO *r_u, prs_struct *ps, int depth)
{
- if (q_e == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_enum_dom_aliases");
+ prs_debug(ps, depth, desc, "samr_io_r_set_groupinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
- if(!prs_uint32("unknown_0", ps, depth, &q_e->unknown_0))
- return False;
- if(!prs_uint32("max_size ", ps, depth, &q_e->max_size ))
- return False;
+ return True;
+}
- if(!prs_align(ps))
- return False;
+/*******************************************************************
+makes a SAMR_Q_QUERY_GROUPINFO structure.
+********************************************************************/
+BOOL make_samr_q_query_groupinfo(SAMR_Q_QUERY_GROUPINFO *q_e,
+ POLICY_HND *pol,
+ uint16 switch_level)
+{
+ if (q_e == NULL || pol == NULL) return False;
+
+ DEBUG(5,("make_samr_q_query_groupinfo\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ q_e->switch_level = switch_level;
return True;
}
/*******************************************************************
- Inits a SAMR_R_ENUM_DOM_ALIASES structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_q_query_groupinfo(char *desc, SAMR_Q_QUERY_GROUPINFO *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_query_groupinfo");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
+
+ return True;
+}
-void init_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
- uint32 num_sam_entries, SAM_USER_INFO_21 grps[MAX_SAM_ENTRIES],
+
+/*******************************************************************
+makes a SAMR_R_QUERY_GROUPINFO structure.
+********************************************************************/
+BOOL make_samr_r_query_groupinfo(SAMR_R_QUERY_GROUPINFO *r_u, GROUP_INFO_CTR *ctr,
uint32 status)
{
- int i;
+ if (r_u == NULL) return False;
+
+ DEBUG(5,("make_samr_r_query_groupinfo\n"));
+
+ r_u->ptr = (status == 0x0 && ctr != NULL) ? 1 : 0;
+ r_u->ctr = ctr;
+ r_u->status = status;
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_query_groupinfo(char *desc, SAMR_R_QUERY_GROUPINFO *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
- DEBUG(5,("init_samr_r_enum_dom_aliases\n"));
+ prs_debug(ps, depth, desc, "samr_io_r_query_groupinfo");
+ depth++;
+
+ prs_align(ps);
- if (num_sam_entries >= MAX_SAM_ENTRIES) {
- num_sam_entries = MAX_SAM_ENTRIES;
- DEBUG(5,("limiting number of entries to %d\n",
- num_sam_entries));
+ prs_uint32("ptr", ps, depth, &(r_u->ptr));
+
+ if (r_u->ptr != 0)
+ {
+ samr_group_info_ctr("ctr", r_u->ctr, ps, depth);
}
- r_u->num_entries = num_sam_entries;
+ prs_uint32("status", ps, depth, &(r_u->status));
- if (num_sam_entries > 0) {
- r_u->ptr_entries = 1;
- r_u->num_entries2 = num_sam_entries;
- r_u->ptr_entries2 = 1;
- r_u->num_entries3 = num_sam_entries;
+ return True;
+}
- SMB_ASSERT_ARRAY(r_u->sam, num_sam_entries);
- for (i = 0; i < num_sam_entries; i++) {
- init_sam_entry(&r_u->sam[i],
- grps[i].uni_user_name.uni_str_len,
- grps[i].user_rid);
+/*******************************************************************
+makes a SAMR_Q_QUERY_GROUPMEM structure.
+********************************************************************/
+BOOL make_samr_q_query_groupmem(SAMR_Q_QUERY_GROUPMEM *q_c, POLICY_HND *hnd)
+{
+ if (q_c == NULL || hnd == NULL) return False;
- copy_unistr2(&r_u->uni_grp_name[i], &(grps[i].uni_user_name));
- }
+ DEBUG(5,("make_samr_q_query_groupmem\n"));
- r_u->num_entries4 = num_sam_entries;
- } else {
- r_u->ptr_entries = 0;
+ memcpy(&(q_c->group_pol), hnd, sizeof(q_c->group_pol));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_query_groupmem(char *desc, SAMR_Q_QUERY_GROUPMEM *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_query_groupmem");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("group_pol", &(q_u->group_pol), ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+makes a SAMR_R_QUERY_GROUPMEM structure.
+********************************************************************/
+BOOL make_samr_r_query_groupmem(SAMR_R_QUERY_GROUPMEM *r_u,
+ uint32 num_entries, uint32 *rid, uint32 *attr, uint32 status)
+{
+ if (r_u == NULL) return False;
+
+ DEBUG(5,("make_samr_r_query_groupmem\n"));
+
+ if (status == 0x0)
+ {
+ r_u->ptr = 1;
+ r_u->num_entries = num_entries;
+
+ r_u->ptr_attrs = attr != NULL ? 1 : 0;
+ r_u->ptr_rids = rid != NULL ? 1 : 0;
+
+ r_u->num_rids = num_entries;
+ r_u->rid = rid;
+
+ r_u->num_attrs = num_entries;
+ r_u->attr = attr;
+ }
+ else
+ {
+ r_u->ptr = 0;
+ r_u->num_entries = 0;
}
r_u->status = status;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth)
+BOOL samr_io_r_query_groupmem(char *desc, SAMR_R_QUERY_GROUPMEM *r_u, prs_struct *ps, int depth)
{
- int i;
+ uint32 i;
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_enum_dom_aliases");
+ prs_debug(ps, depth, desc, "samr_io_r_query_groupmem");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("num_entries", ps, depth, &r_u->num_entries))
- return False;
- if(!prs_uint32("ptr_entries", ps, depth, &r_u->ptr_entries))
- return False;
+ prs_align(ps);
- if (r_u->num_entries != 0 && r_u->ptr_entries != 0) {
- if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
- return False;
- if(!prs_uint32("ptr_entries2", ps, depth, &r_u->ptr_entries2))
- return False;
- if(!prs_uint32("num_entries3", ps, depth, &r_u->num_entries3))
- return False;
+ prs_uint32("ptr", ps, depth, &(r_u->ptr));
+ prs_uint32("num_entries ", ps, depth, &(r_u->num_entries));
- SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries);
+ if (r_u->ptr != 0)
+ {
+ prs_uint32("ptr_rids ", ps, depth, &(r_u->ptr_rids ));
+ prs_uint32("ptr_attrs", ps, depth, &(r_u->ptr_attrs));
- for (i = 0; i < r_u->num_entries; i++) {
- if(!sam_io_sam_entry("", &r_u->sam[i], ps, depth))
- return False;
+ if (r_u->ptr_rids != 0)
+ {
+ prs_uint32("num_rids", ps, depth, &(r_u->num_rids));
+ if (r_u->num_rids != 0)
+ {
+ r_u->rid = (uint32*)Realloc(r_u->rid,
+ sizeof(r_u->rid[0]) *
+ r_u->num_rids);
+ if (r_u->rid == NULL)
+ {
+ samr_free_r_query_groupmem(r_u);
+ return False;
+ }
+ }
+ for (i = 0; i < r_u->num_rids; i++)
+ {
+ prs_uint32("", ps, depth, &(r_u->rid[i]));
+ }
}
- for (i = 0; i < r_u->num_entries; i++) {
- if(!smb_io_unistr2("", &r_u->uni_grp_name[i], r_u->sam[i].hdr_name.buffer, ps, depth))
- return False;
+ if (r_u->ptr_attrs != 0)
+ {
+ prs_uint32("num_attrs", ps, depth, &(r_u->num_attrs));
+
+ if (r_u->num_attrs != 0)
+ {
+ r_u->attr = (uint32*)Realloc(r_u->attr,
+ sizeof(r_u->attr[0]) *
+ r_u->num_attrs);
+ if (r_u->attr == NULL)
+ {
+ samr_free_r_query_groupmem(r_u);
+ return False;
+ }
+ }
+ for (i = 0; i < r_u->num_attrs; i++)
+ {
+ prs_uint32("", ps, depth, &(r_u->attr[i]));
+ }
}
+ }
- if(!prs_align(ps))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
- if(!prs_uint32("num_entries4", ps, depth, &r_u->num_entries4))
- return False;
+ if (!ps->io)
+ {
+ /* storing. memory no longer needed */
+ samr_free_r_query_groupmem(r_u);
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
-
return True;
}
/*******************************************************************
- Inits a SAMR_Q_QUERY_DISPINFO structure.
+frees a structure.
********************************************************************/
+void samr_free_r_query_groupmem(SAMR_R_QUERY_GROUPMEM *r_u)
+{
+ if (r_u->rid != NULL)
+ {
+ free(r_u->rid);
+ r_u->rid = NULL;
+ }
+ if (r_u->attr != NULL)
+ {
+ free(r_u->attr);
+ r_u->attr = NULL;
+ }
+}
-void init_samr_q_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_e, POLICY_HND *pol,
- uint16 switch_level, uint32 start_idx, uint32 size)
+/*******************************************************************
+makes a SAMR_Q_QUERY_USERGROUPS structure.
+********************************************************************/
+BOOL make_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
+ POLICY_HND *hnd)
{
- DEBUG(5,("init_q_query_dispinfo\n"));
+ if (q_u == NULL || hnd == NULL) return False;
- memcpy(&q_e->pol, pol, sizeof(*pol));
+ DEBUG(5,("make_samr_q_query_usergroups\n"));
- q_e->switch_level = switch_level;
+ memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
- q_e->unknown_0 = 0;
- q_e->start_idx = start_idx;
- q_e->unknown_1 = 0x000007d0;
- q_e->max_size = size;
+ return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_q_query_dispinfo(char *desc, SAMR_Q_QUERY_DISPINFO *q_e, prs_struct *ps, int depth)
+BOOL samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth)
{
- if (q_e == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_query_dispinfo");
+ prs_debug(ps, depth, desc, "samr_io_q_query_usergroups");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
- return False;
- if(!prs_uint16("unknown_0 ", ps, depth, &q_e->unknown_0))
- return False;
- if(!prs_uint32("start_idx ", ps, depth, &q_e->start_idx))
- return False;
- if(!prs_uint32("unknown_1 ", ps, depth, &q_e->unknown_1))
- return False;
- if(!prs_uint32("max_size ", ps, depth, &q_e->max_size))
- return False;
+ return True;
+}
- if(!prs_align(ps))
- return False;
+/*******************************************************************
+makes a SAMR_R_QUERY_USERGROUPS structure.
+********************************************************************/
+BOOL make_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
+ uint32 num_gids, DOM_GID *gid, uint32 status)
+{
+ if (r_u == NULL) return False;
+
+ DEBUG(5,("make_samr_r_query_usergroups\n"));
+
+ if (status == 0x0)
+ {
+ r_u->ptr_0 = 1;
+ r_u->num_entries = num_gids;
+ r_u->ptr_1 = (num_gids != 0) ? 1 : 0;
+ r_u->num_entries2 = num_gids;
+
+ r_u->gid = gid;
+ }
+ else
+ {
+ r_u->ptr_0 = 0;
+ r_u->num_entries = 0;
+ r_u->ptr_1 = 0;
+ r_u->gid = NULL;
+ }
+
+ r_u->status = status;
return True;
}
-
/*******************************************************************
- Inits a SAM_INFO_2 structure.
+reads or writes a structure.
********************************************************************/
-
-void init_sam_info_2(SAM_INFO_2 *sam, uint32 acb_mask,
- uint32 start_idx, uint32 num_sam_entries,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+BOOL samr_io_gids(char *desc, uint32 *num_gids, DOM_GID **gid, prs_struct *ps, int depth)
{
- int i;
- int entries_added;
+ uint32 i;
+ if (gid == NULL) return False;
- DEBUG(5,("init_sam_info_2\n"));
+ prs_debug(ps, depth, desc, "samr_io_gids");
+ depth++;
- if (num_sam_entries >= MAX_SAM_ENTRIES) {
- num_sam_entries = MAX_SAM_ENTRIES;
- DEBUG(5,("limiting number of entries to %d\n",
- num_sam_entries));
- }
+ prs_align(ps);
- for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) {
- if (IS_BITS_SET_ALL(pass[i].acb_info, acb_mask)) {
- init_sam_entry2(&sam->sam[entries_added],
- start_idx + entries_added + 1,
- pass[i].uni_user_name.uni_str_len,
- pass[i].uni_acct_desc.uni_str_len,
- pass[i].user_rid,
- pass[i].acb_info);
+ prs_uint32("num_gids", ps, depth, num_gids);
- copy_unistr2(&sam->str[entries_added].uni_srv_name, &pass[i].uni_user_name);
- copy_unistr2(&sam->str[entries_added].uni_srv_desc, &pass[i].uni_acct_desc);
+ if ((*num_gids) != 0)
+ {
+ if (ps->io)
+ {
+ (*gid) = g_renew(DOM_GID, (*gid), (*num_gids));
+ }
- entries_added++;
+ if ((*gid) == NULL)
+ {
+ return False;
}
- sam->num_entries = entries_added;
- sam->ptr_entries = 1;
- sam->num_entries2 = entries_added;
+ for (i = 0; i < (*num_gids); i++)
+ {
+ smb_io_gid("gids", &(*gid)[i], ps, depth);
+ }
}
+ if (!ps->io)
+ {
+ /* storing. memory no longer needed */
+ safe_free((*gid));
+ (*gid) = NULL;
+ }
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL sam_io_sam_info_2(char *desc, SAM_INFO_2 *sam, prs_struct *ps, int depth)
+BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth)
{
- int i;
-
- if (sam == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "sam_io_sam_info_2");
+ prs_debug(ps, depth, desc, "samr_io_r_query_usergroups");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("num_entries ", ps, depth, &sam->num_entries))
- return False;
- if(!prs_uint32("ptr_entries ", ps, depth, &sam->ptr_entries))
- return False;
+ prs_align(ps);
- if(!prs_uint32("num_entries2 ", ps, depth, &sam->num_entries2))
- return False;
+ prs_uint32("ptr_0 ", ps, depth, &(r_u->ptr_0 ));
- SMB_ASSERT_ARRAY(sam->sam, sam->num_entries);
+ if (r_u->ptr_0 != 0)
+ {
+ prs_uint32("num_entries ", ps, depth, &(r_u->num_entries));
+ prs_uint32("ptr_1 ", ps, depth, &(r_u->ptr_1 ));
- for (i = 0; i < sam->num_entries; i++) {
- if(!sam_io_sam_entry2("", &sam->sam[i], ps, depth))
- return False;
- }
-
- for (i = 0; i < sam->num_entries; i++) {
- if(!sam_io_sam_str2 ("", &sam->str[i],
- sam->sam[i].hdr_srv_name.buffer,
- sam->sam[i].hdr_srv_desc.buffer,
- ps, depth))
- return False;
+ if (r_u->num_entries != 0 && r_u->ptr_1 != 0)
+ {
+ samr_io_gids("gids", &(r_u->num_entries2), &r_u->gid, ps, depth);
+ }
}
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
+
/*******************************************************************
- Inits a SAM_INFO_1 structure.
+makes a SAMR_Q_ENUM_DOMAINS structure.
********************************************************************/
+BOOL make_samr_q_enum_domains(SAMR_Q_ENUM_DOMAINS *q_e, POLICY_HND *pol,
+ uint32 start_idx, uint32 size)
+{
+ if (q_e == NULL || pol == NULL) return False;
+
+ DEBUG(5,("make_samr_q_enum_domains\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ q_e->start_idx = start_idx;
+ q_e->max_size = size;
+
+ return True;
+}
+
-void init_sam_info_1(SAM_INFO_1 *sam, uint32 acb_mask,
- uint32 start_idx, uint32 num_sam_entries,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_enum_domains(char *desc, SAMR_Q_ENUM_DOMAINS *q_e, prs_struct *ps, int depth)
{
- int i;
- int entries_added;
+ if (q_e == NULL) return False;
- DEBUG(5,("init_sam_info_1\n"));
+ prs_debug(ps, depth, desc, "samr_io_q_enum_domains");
+ depth++;
- if (num_sam_entries >= MAX_SAM_ENTRIES) {
- num_sam_entries = MAX_SAM_ENTRIES;
- DEBUG(5,("limiting number of entries to %d\n",
- num_sam_entries));
- }
+ prs_align(ps);
- for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) {
- if (IS_BITS_SET_ALL(pass[i].acb_info, acb_mask)) {
- init_sam_entry1(&sam->sam[entries_added],
- start_idx + entries_added + 1,
- pass[i].uni_user_name.uni_str_len,
- pass[i].uni_full_name.uni_str_len,
- pass[i].uni_acct_desc.uni_str_len,
- pass[i].user_rid,
- pass[i].acb_info);
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
- copy_unistr2(&sam->str[entries_added].uni_acct_name, &pass[i].uni_user_name);
- copy_unistr2(&sam->str[entries_added].uni_full_name, &pass[i].uni_full_name);
- copy_unistr2(&sam->str[entries_added].uni_acct_desc, &pass[i].uni_acct_desc);
+ prs_uint32("start_idx", ps, depth, &(q_e->start_idx));
+ prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
- entries_added++;
- }
- }
+ prs_align(ps);
- sam->num_entries = entries_added;
- sam->ptr_entries = 1;
- sam->num_entries2 = entries_added;
+ return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+makes a SAMR_R_ENUM_DOMAINS structure.
********************************************************************/
+BOOL make_samr_r_enum_domains(SAMR_R_ENUM_DOMAINS *r_u,
+ uint32 next_idx, uint32 num_sam_entries)
+{
+ if (r_u == NULL) return False;
-static BOOL sam_io_sam_info_1(char *desc, SAM_INFO_1 *sam, prs_struct *ps, int depth)
+ DEBUG(5,("make_samr_r_enum_domains\n"));
+
+ r_u->next_idx = next_idx;
+
+ if (num_sam_entries != 0)
+ {
+ r_u->ptr_entries1 = 1;
+ r_u->ptr_entries2 = 1;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->num_entries3 = num_sam_entries;
+
+ r_u->num_entries4 = num_sam_entries;
+ }
+ else
+ {
+ r_u->ptr_entries1 = 0;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->ptr_entries2 = 1;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_enum_domains(char *desc, SAMR_R_ENUM_DOMAINS *r_u, prs_struct *ps, int depth)
{
- int i;
+ uint32 i;
- if (sam == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "sam_io_sam_info_1");
+ prs_debug(ps, depth, desc, "samr_io_r_enum_domains");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("num_entries ", ps, depth, &sam->num_entries))
- return False;
- if(!prs_uint32("ptr_entries ", ps, depth, &sam->ptr_entries))
- return False;
+ prs_uint32("next_idx ", ps, depth, &(r_u->next_idx ));
+ prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
- if(!prs_uint32("num_entries2 ", ps, depth, &sam->num_entries2))
- return False;
+ if (r_u->ptr_entries1 != 0)
+ {
+ prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+ prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
+ prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
- SMB_ASSERT_ARRAY(sam->sam, sam->num_entries);
+ if (ps->io)
+ {
+ r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
+ r_u->uni_dom_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_dom_name[0]));
+ }
- for (i = 0; i < sam->num_entries; i++) {
- if(!sam_io_sam_entry1("", &sam->sam[i], ps, depth))
+ if ((r_u->sam == NULL || r_u->uni_dom_name == NULL) && r_u->num_entries2 != 0)
+ {
+ DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOMAINS\n"));
+ r_u->num_entries4 = 0;
+ r_u->status = 0xC0000000|NT_STATUS_MEMORY_NOT_ALLOCATED;
return False;
- }
+ }
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ fstring tmp;
+ slprintf(tmp, sizeof(tmp)-1, "dom[%d]", i);
+ sam_io_sam_entry(tmp, &(r_u->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ fstring tmp;
+ slprintf(tmp, sizeof(tmp)-1, "dom[%d]", i);
+ smb_io_unistr2(tmp, &(r_u->uni_dom_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
+ prs_align(ps);
+ }
+
+ prs_align(ps);
- for (i = 0; i < sam->num_entries; i++) {
- if(!sam_io_sam_str1 ("", &sam->str[i],
- sam->sam[i].hdr_acct_name.buffer,
- sam->sam[i].hdr_user_name.buffer,
- sam->sam[i].hdr_user_desc.buffer,
- ps, depth))
- return False;
}
+ prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+makes a SAMR_Q_ENUM_DOM_GROUPS structure.
+********************************************************************/
+BOOL make_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
+ uint32 start_idx, uint32 size)
+{
+ if (q_e == NULL || pol == NULL) return False;
+
+ DEBUG(5,("make_samr_q_enum_dom_groups\n"));
+
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
+
+ q_e->start_idx = start_idx;
+ q_e->max_size = size;
+
return True;
}
+
/*******************************************************************
- Inits a SAMR_R_QUERY_DISPINFO structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth)
+{
+ if (q_e == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_enum_dom_groups");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("start_idx", ps, depth, &(q_e->start_idx));
+ prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
+
+ prs_align(ps);
+
+ return True;
+}
+
-void init_samr_r_query_dispinfo(SAMR_R_QUERY_DISPINFO *r_u,
- uint16 switch_level, SAM_INFO_CTR *ctr, uint32 status)
+/*******************************************************************
+makes a SAMR_R_ENUM_DOM_GROUPS structure.
+********************************************************************/
+BOOL make_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
+ uint32 next_idx, uint32 num_sam_entries)
{
- DEBUG(5,("init_samr_r_query_dispinfo\n"));
+ if (r_u == NULL) return False;
+
+ DEBUG(5,("make_samr_r_enum_dom_groups\n"));
+
+ r_u->next_idx = next_idx;
- if (status == 0x0) {
- r_u->unknown_0 = 0x0000001;
- r_u->unknown_1 = 0x0000001;
- } else {
- r_u->unknown_0 = 0x0;
- r_u->unknown_1 = 0x0;
+ if (num_sam_entries != 0)
+ {
+ r_u->ptr_entries1 = 1;
+ r_u->ptr_entries2 = 1;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->num_entries3 = num_sam_entries;
+
+ r_u->num_entries4 = num_sam_entries;
+ }
+ else
+ {
+ r_u->ptr_entries1 = 0;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->ptr_entries2 = 1;
}
- r_u->switch_level = switch_level;
- r_u->ctr = ctr;
- r_u->status = status;
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_r_query_dispinfo(char *desc, SAMR_R_QUERY_DISPINFO *r_u, prs_struct *ps, int depth)
+BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ uint32 i;
- prs_debug(ps, depth, desc, "samr_io_r_query_dispinfo");
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_enum_dom_groups");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("unknown_0 ", ps, depth, &r_u->unknown_0))
- return False;
- if(!prs_uint32("unknown_1 ", ps, depth, &r_u->unknown_1))
- return False;
- if(!prs_uint16("switch_level ", ps, depth, &r_u->switch_level))
- return False;
+ prs_uint32("next_idx ", ps, depth, &(r_u->next_idx ));
+ prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
- if(!prs_align(ps))
- return False;
+ if (r_u->ptr_entries1 != 0)
+ {
+ prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+ prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
+ prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
- switch (r_u->switch_level) {
- case 0x1:
- if(!sam_io_sam_info_1("users", r_u->ctr->sam.info1, ps, depth))
- return False;
- break;
- case 0x2:
- if(!sam_io_sam_info_2("servers", r_u->ctr->sam.info2, ps, depth))
+ if (ps->io)
+ {
+ r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
+ r_u->uni_grp_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_grp_name[0]));
+ }
+
+ if ((r_u->sam == NULL || r_u->uni_grp_name == NULL) && r_u->num_entries2 != 0)
+ {
+ DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_GROUPS\n"));
+ r_u->num_entries4 = 0;
+ r_u->status = 0xC0000000|NT_STATUS_MEMORY_NOT_ALLOCATED;
return False;
- break;
- default:
- DEBUG(5,("samr_io_r_query_dispinfo: unknown switch value\n"));
- break;
+ }
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
+ }
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ smb_io_unistr2("", &(r_u->uni_grp_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
+ prs_align(ps);
+ }
+
+ prs_align(ps);
+
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
/*******************************************************************
- Inits a SAMR_Q_ENUM_DOM_GROUPS structure.
+makes a SAMR_Q_ENUM_DOM_ALIASES structure.
********************************************************************/
-
-void init_samr_q_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_e, POLICY_HND *pol,
- uint16 switch_level, uint32 start_idx, uint32 size)
+BOOL make_samr_q_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_e, POLICY_HND *pol,
+ uint32 start_idx, uint32 size)
{
- DEBUG(5,("init_q_enum_dom_groups\n"));
+ if (q_e == NULL || pol == NULL) return False;
- memcpy(&q_e->pol, pol, sizeof(*pol));
+ DEBUG(5,("make_samr_q_enum_dom_aliases\n"));
- q_e->switch_level = switch_level;
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
- q_e->unknown_0 = 0;
q_e->start_idx = start_idx;
- q_e->unknown_1 = 0x000007d0;
- q_e->max_size = size;
+ q_e->max_size = size;
+
+ return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_q_enum_dom_groups(char *desc, SAMR_Q_ENUM_DOM_GROUPS *q_e, prs_struct *ps, int depth)
+BOOL samr_io_q_enum_dom_aliases(char *desc, SAMR_Q_ENUM_DOM_ALIASES *q_e, prs_struct *ps, int depth)
{
- if (q_e == NULL)
- return False;
+ if (q_e == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_enum_dom_groups");
+ prs_debug(ps, depth, desc, "samr_io_q_enum_dom_aliases");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
- return False;
- if(!prs_uint16("unknown_0 ", ps, depth, &q_e->unknown_0))
- return False;
- if(!prs_uint32("start_idx ", ps, depth, &q_e->start_idx))
- return False;
- if(!prs_uint32("unknown_1 ", ps, depth, &q_e->unknown_1))
- return False;
- if(!prs_uint32("max_size ", ps, depth, &q_e->max_size))
- return False;
+ prs_uint32("start_idx", ps, depth, &(q_e->start_idx));
+ prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
return True;
}
/*******************************************************************
- Inits a SAMR_R_ENUM_DOM_GROUPS structure.
+makes a SAMR_R_ENUM_DOM_ALIASES structure.
********************************************************************/
-
-void init_samr_r_enum_dom_groups(SAMR_R_ENUM_DOM_GROUPS *r_u,
- uint32 start_idx, uint32 num_sam_entries,
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES],
- uint32 status)
+BOOL make_samr_r_enum_dom_aliases(SAMR_R_ENUM_DOM_ALIASES *r_u,
+ uint32 next_idx,
+ uint32 num_sam_entries)
{
- int i;
- int entries_added;
+ if (r_u == NULL) return False;
- DEBUG(5,("init_samr_r_enum_dom_groups\n"));
+ DEBUG(5,("make_samr_r_enum_dom_aliases\n"));
- if (num_sam_entries >= MAX_SAM_ENTRIES) {
- num_sam_entries = MAX_SAM_ENTRIES;
- DEBUG(5,("limiting number of entries to %d\n",
- num_sam_entries));
+ r_u->next_idx = next_idx;
+
+ if (num_sam_entries != 0)
+ {
+ r_u->ptr_entries1 = 1;
+ r_u->ptr_entries2 = 1;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->num_entries3 = num_sam_entries;
+
+ r_u->num_entries4 = num_sam_entries;
}
+ else
+ {
+ r_u->ptr_entries1 = 0;
+ r_u->num_entries2 = num_sam_entries;
+ r_u->ptr_entries2 = 1;
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_enum_dom_aliases(char *desc, SAMR_R_ENUM_DOM_ALIASES *r_u, prs_struct *ps, int depth)
+{
+ uint32 i;
+
+ if (r_u == NULL) return False;
- if (status == 0x0) {
- for (i = start_idx, entries_added = 0; i < num_sam_entries; i++) {
- init_sam_entry3(&r_u->sam[entries_added],
- start_idx + entries_added + 1,
- pass[i].uni_user_name.uni_str_len,
- pass[i].uni_acct_desc.uni_str_len,
- pass[i].user_rid);
+ prs_debug(ps, depth, desc, "samr_io_r_enum_dom_aliases");
+ depth++;
- copy_unistr2(&r_u->str[entries_added].uni_grp_name,
- &pass[i].uni_user_name);
- copy_unistr2(&r_u->str[entries_added].uni_grp_desc,
- &pass[i].uni_acct_desc);
+ prs_align(ps);
- entries_added++;
+ prs_uint32("next_idx ", ps, depth, &(r_u->next_idx ));
+ prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
+
+ if (r_u->ptr_entries1 != 0)
+ {
+ prs_uint32("num_entries2", ps, depth, &(r_u->num_entries2));
+ prs_uint32("ptr_entries2", ps, depth, &(r_u->ptr_entries2));
+ prs_uint32("num_entries3", ps, depth, &(r_u->num_entries3));
+
+ if (ps->io)
+ {
+ r_u->sam = (SAM_ENTRY*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->sam[0]));
+ r_u->uni_grp_name = (UNISTR2*)Realloc(NULL, r_u->num_entries2 * sizeof(r_u->uni_grp_name[0]));
+ }
+
+ if ((r_u->sam == NULL || r_u->uni_grp_name == NULL) && r_u->num_entries2 != 0)
+ {
+ DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_ALIASES\n"));
+ r_u->num_entries4 = 0;
+ r_u->status = 0xC0000000|NT_STATUS_MEMORY_NOT_ALLOCATED;
+ return False;
}
- if (entries_added > 0) {
- r_u->unknown_0 = 0x0000492;
- r_u->unknown_1 = 0x000049a;
- } else {
- r_u->unknown_0 = 0x0;
- r_u->unknown_1 = 0x0;
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ sam_io_sam_entry("", &(r_u->sam[i]), ps, depth);
}
- r_u->switch_level = 3;
- r_u->num_entries = entries_added;
- r_u->ptr_entries = 1;
- r_u->num_entries2 = entries_added;
- } else {
- r_u->switch_level = 0;
+
+ for (i = 0; i < r_u->num_entries2; i++)
+ {
+ smb_io_unistr2("", &(r_u->uni_grp_name[i]), r_u->sam[i].hdr_name.buffer, ps, depth);
+ prs_align(ps);
+ }
+
+ prs_align(ps);
+
}
- r_u->status = status;
+ prs_uint32("num_entries4", ps, depth, &(r_u->num_entries4));
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+makes a ALIAS_INFO3 structure.
********************************************************************/
-
-BOOL samr_io_r_enum_dom_groups(char *desc, SAMR_R_ENUM_DOM_GROUPS *r_u, prs_struct *ps, int depth)
+BOOL make_samr_alias_info3(ALIAS_INFO3 *al3, const char *acct_desc)
{
- int i;
+ int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
+ if (al3 == NULL) return False;
- if (r_u == NULL)
- return False;
+ DEBUG(5,("make_samr_alias_info3\n"));
- prs_debug(ps, depth, desc, "samr_io_r_enum_dom_groups");
+ make_uni_hdr(&(al3->hdr_acct_desc), acct_len);
+ make_unistr2(&(al3->uni_acct_desc), acct_desc, acct_len);
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_alias_info3(char *desc, ALIAS_INFO3 *al3, prs_struct *ps, int depth)
+{
+ if (al3 == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_alias_info3");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("unknown_0 ", ps, depth, &r_u->unknown_0))
- return False;
- if(!prs_uint32("unknown_1 ", ps, depth, &r_u->unknown_1))
- return False;
- if(!prs_uint32("switch_level ", ps, depth, &r_u->switch_level))
- return False;
+ smb_io_unihdr ("hdr_acct_desc", &(al3->hdr_acct_desc) , ps, depth);
+ smb_io_unistr2("uni_acct_desc", &(al3->uni_acct_desc), al3->hdr_acct_desc.buffer, ps, depth);
+ prs_align(ps);
- if (r_u->switch_level != 0) {
- if(!prs_uint32("num_entries ", ps, depth, &r_u->num_entries))
- return False;
- if(!prs_uint32("ptr_entries ", ps, depth, &r_u->ptr_entries))
- return False;
+ return True;
+}
- if(!prs_uint32("num_entries2 ", ps, depth, &r_u->num_entries2))
- return False;
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_alias_info_ctr(char *desc, ALIAS_INFO_CTR *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_alias_info_ctr");
+ depth++;
- SMB_ASSERT_ARRAY(r_u->sam, r_u->num_entries);
+ prs_uint16("switch_value1", ps, depth, &(ctr->switch_value1));
+ prs_uint16("switch_value2", ps, depth, &(ctr->switch_value2));
- for (i = 0; i < r_u->num_entries; i++) {
- if(!sam_io_sam_entry3("", &r_u->sam[i], ps, depth))
- return False;
+ switch (ctr->switch_value1)
+ {
+ case 3:
+ {
+ samr_io_alias_info3("alias_info3", &(ctr->alias.info3), ps, depth);
+ break;
}
-
- for (i = 0; i < r_u->num_entries; i++) {
- if(!sam_io_sam_str3 ("", &r_u->str[i],
- r_u->sam[i].hdr_grp_name.buffer,
- r_u->sam[i].hdr_grp_desc.buffer,
- ps, depth))
- return False;
+ default:
+ {
+ DEBUG(4,("samr_alias_info_ctr: unsupported switch level\n"));
+ break;
}
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_align(ps);
return True;
}
+
/*******************************************************************
- Inits a SAMR_Q_QUERY_ALIASINFO structure.
+makes a SAMR_Q_QUERY_ALIASINFO structure.
********************************************************************/
-
-void init_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
+BOOL make_samr_q_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_e,
POLICY_HND *pol,
uint16 switch_level)
{
- DEBUG(5,("init_q_query_aliasinfo\n"));
+ if (q_e == NULL || pol == NULL) return False;
+
+ DEBUG(5,("make_samr_q_query_aliasinfo\n"));
- memcpy(&q_e->pol, pol, sizeof(*pol));
+ memcpy(&(q_e->pol), pol, sizeof(*pol));
q_e->switch_level = switch_level;
+
+ return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL samr_io_q_query_aliasinfo(char *desc, SAMR_Q_QUERY_ALIASINFO *q_e, prs_struct *ps, int depth)
{
- if (q_e == NULL)
- return False;
+ if (q_e == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_q_query_aliasinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &q_e->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("pol", &(q_e->pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
- return False;
+ prs_uint16("switch_level", ps, depth, &(q_e->switch_level));
return True;
}
+
/*******************************************************************
- Inits a SAMR_R_QUERY_ALIASINFO structure.
+makes a SAMR_R_QUERY_ALIASINFO structure.
********************************************************************/
-
-void init_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u,
- uint16 switch_value, char *acct_desc,
+BOOL make_samr_r_query_aliasinfo(SAMR_R_QUERY_ALIASINFO *r_u, ALIAS_INFO_CTR *ctr,
uint32 status)
{
- DEBUG(5,("init_samr_r_query_aliasinfo\n"));
+ if (r_u == NULL) return False;
- r_u->ptr = 0;
+ DEBUG(5,("make_samr_r_query_aliasinfo\n"));
- if (status == 0) {
- r_u->switch_value = switch_value;
+ r_u->ptr = (status == 0x0 && ctr != NULL) ? 1 : 0;
+ r_u->ctr = ctr;
+ r_u->status = status;
- switch (switch_value) {
- case 3:
- {
- int acct_len = acct_desc ? strlen(acct_desc) : 0;
+ return True;
+}
- r_u->ptr = 1;
- init_uni_hdr(&r_u->alias.info3.hdr_acct_desc, acct_len);
- init_unistr2(&r_u->alias.info3.uni_acct_desc, acct_desc, acct_len);
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
- break;
- }
- default:
- DEBUG(4,("init_samr_r_query_aliasinfo: unsupported switch level\n"));
- break;
- }
+ prs_debug(ps, depth, desc, "samr_io_r_query_aliasinfo");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr", ps, depth, &(r_u->ptr));
+
+ if (r_u->ptr != 0)
+ {
+ samr_alias_info_ctr("ctr", r_u->ctr, ps, depth);
}
- r_u->status = status;
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+makes a SAMR_Q_SET_ALIASINFO structure.
********************************************************************/
+BOOL make_samr_q_set_aliasinfo(SAMR_Q_SET_ALIASINFO *q_u, POLICY_HND *hnd,
+ ALIAS_INFO_CTR *ctr)
+{
+ if (q_u == NULL) return False;
-BOOL samr_io_r_query_aliasinfo(char *desc, SAMR_R_QUERY_ALIASINFO *r_u, prs_struct *ps, int depth)
+ DEBUG(5,("make_samr_q_set_aliasinfo\n"));
+
+ memcpy(&(q_u->alias_pol), hnd, sizeof(q_u->alias_pol));
+ q_u->ctr = ctr;
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_set_aliasinfo(char *desc, SAMR_Q_SET_ALIASINFO *q_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_query_aliasinfo");
+ prs_debug(ps, depth, desc, "samr_io_q_set_aliasinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr ", ps, depth, &r_u->ptr))
- return False;
-
- if (r_u->ptr != 0) {
- if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth);
+ samr_alias_info_ctr("ctr", q_u->ctr, ps, depth);
- if (r_u->switch_value != 0) {
- switch (r_u->switch_value) {
- case 3:
- if(!smb_io_unihdr ("", &r_u->alias.info3.hdr_acct_desc, ps, depth))
- return False;
- if(!smb_io_unistr2("", &r_u->alias.info3.uni_acct_desc,
- r_u->alias.info3.hdr_acct_desc.buffer, ps, depth))
- return False;
- break;
- default:
- DEBUG(4,("samr_io_r_query_aliasinfo: unsupported switch level\n"));
- break;
- }
- }
- }
+ return True;
+}
- if(!prs_align(ps))
- return False;
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_set_aliasinfo(char *desc, SAMR_R_SET_ALIASINFO *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_debug(ps, depth, desc, "samr_io_r_set_aliasinfo");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
+
+
/*******************************************************************
- Reads or writes a SAMR_Q_LOOKUP_IDS structure.
+makes a SAMR_Q_QUERY_USERALIASES structure.
********************************************************************/
+BOOL make_samr_q_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u,
+ const POLICY_HND *hnd,
+ uint32 *ptr_sid, DOM_SID2 *sid)
+{
+ if (q_u == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_samr_q_query_useraliases\n"));
-BOOL samr_io_q_lookup_ids(char *desc, SAMR_Q_LOOKUP_IDS *q_u, prs_struct *ps, int depth)
+ memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
+
+ q_u->num_sids1 = 1;
+ q_u->ptr = 1;
+ q_u->num_sids2 = 1;
+
+ q_u->ptr_sid = ptr_sid;
+ q_u->sid = sid;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SAMR_Q_QUERY_USERALIASES structure.
+********************************************************************/
+BOOL samr_io_q_query_useraliases(char *desc, SAMR_Q_QUERY_USERALIASES *q_u, prs_struct *ps, int depth)
{
fstring tmp;
- int i;
+ uint32 i;
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_lookup_ids");
+ prs_debug(ps, depth, desc, "samr_io_q_query_useraliases");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &(q_u->pol), ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint32("num_sids1", ps, depth, &q_u->num_sids1))
- return False;
- if(!prs_uint32("ptr ", ps, depth, &q_u->ptr))
- return False;
- if(!prs_uint32("num_sids2", ps, depth, &q_u->num_sids2))
- return False;
+ prs_uint32("num_sids1", ps, depth, &(q_u->num_sids1));
+ prs_uint32("ptr ", ps, depth, &(q_u->ptr ));
+ prs_uint32("num_sids2", ps, depth, &(q_u->num_sids2));
+
+ if (q_u->num_sids2 != 0)
+ {
+ q_u->ptr_sid = (uint32*)Realloc(q_u->ptr_sid,
+ sizeof(q_u->ptr_sid[0]) * q_u->num_sids2);
+ if (q_u->ptr_sid == NULL)
+ {
+ samr_free_q_query_useraliases(q_u);
+ return False;
+ }
- SMB_ASSERT_ARRAY(q_u->ptr_sid, q_u->num_sids2);
+ q_u->sid = (DOM_SID2*)Realloc(q_u->sid,
+ sizeof(q_u->sid[0]) * q_u->num_sids2);
+ if (q_u->sid == NULL)
+ {
+ samr_free_q_query_useraliases(q_u);
+ return False;
+ }
+ }
- for (i = 0; i < q_u->num_sids2; i++) {
+ for (i = 0; i < q_u->num_sids2; i++)
+ {
slprintf(tmp, sizeof(tmp) - 1, "ptr[%02d]", i);
- if(!prs_uint32(tmp, ps, depth, &q_u->ptr_sid[i]))
- return False;
+ prs_uint32(tmp, ps, depth, &(q_u->ptr_sid[i]));
}
- for (i = 0; i < q_u->num_sids2; i++) {
- if (q_u->ptr_sid[i] != 0) {
+ for (i = 0; i < q_u->num_sids2; i++)
+ {
+ if (q_u->ptr_sid[i] != 0)
+ {
slprintf(tmp, sizeof(tmp)-1, "sid[%02d]", i);
- if(!smb_io_dom_sid2(tmp, &q_u->sid[i], ps, depth))
- return False;
+ smb_io_dom_sid2(tmp, &(q_u->sid[i]), ps, depth);
}
}
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+ if (!ps->io)
+ {
+ /* storing. memory no longer needed */
+ samr_free_q_query_useraliases(q_u);
+ }
return True;
}
/*******************************************************************
- Inits a SAMR_R_LOOKUP_IDS structure.
+frees memory in a SAMR_Q_QUERY_USERALIASES structure.
********************************************************************/
+void samr_free_q_query_useraliases(SAMR_Q_QUERY_USERALIASES *q_u)
+{
+ if (q_u->ptr_sid == NULL)
+ {
+ free(q_u->ptr_sid);
+ q_u->ptr_sid = NULL;
+ }
+
+ if (q_u->sid == NULL)
+ {
+ free(q_u->sid);
+ q_u->sid = NULL;
+ }
+}
-void init_samr_r_lookup_ids(SAMR_R_LOOKUP_IDS *r_u,
+/*******************************************************************
+makes a SAMR_R_QUERY_USERALIASES structure.
+********************************************************************/
+BOOL make_samr_r_query_useraliases(SAMR_R_QUERY_USERALIASES *r_u,
uint32 num_rids, uint32 *rid, uint32 status)
{
- int i;
+ if (r_u == NULL) return False;
- DEBUG(5,("init_samr_r_lookup_ids\n"));
+ DEBUG(5,("make_samr_r_query_useraliases\n"));
- if (status == 0x0) {
+ if (status == 0x0)
+ {
r_u->num_entries = num_rids;
r_u->ptr = 1;
r_u->num_entries2 = num_rids;
- SMB_ASSERT_ARRAY(r_u->rid, num_rids);
-
- for (i = 0; i < num_rids; i++) {
- r_u->rid[i] = rid[i];
- }
- } else {
+ r_u->rid = rid;
+ }
+ else
+ {
r_u->num_entries = 0;
r_u->ptr = 0;
r_u->num_entries2 = 0;
}
r_u->status = status;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_r_lookup_ids(char *desc, SAMR_R_LOOKUP_IDS *r_u, prs_struct *ps, int depth)
+BOOL samr_io_rids(char *desc, uint32 *num_rids, uint32 **rid, prs_struct *ps, int depth)
{
fstring tmp;
- int i;
-
- if (r_u == NULL)
- return False;
+ uint32 i;
+ if (rid == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_lookup_ids");
+ prs_debug(ps, depth, desc, "samr_io_rids");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("num_entries", ps, depth, &r_u->num_entries))
- return False;
- if(!prs_uint32("ptr ", ps, depth, &r_u->ptr))
- return False;
- if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
- return False;
+ prs_uint32("num_rids", ps, depth, num_rids);
- if (r_u->num_entries != 0) {
- SMB_ASSERT_ARRAY(r_u->rid, r_u->num_entries2);
+ if ((*num_rids) != 0)
+ {
+ if (ps->io)
+ {
+ /* reading */
+ (*rid) = g_renew(uint32, (*rid), (*num_rids));
+ }
+ if ((*rid) == NULL)
+ {
+ return False;
+ }
- for (i = 0; i < r_u->num_entries2; i++) {
+ for (i = 0; i < (*num_rids); i++)
+ {
slprintf(tmp, sizeof(tmp)-1, "rid[%02d]", i);
- if(!prs_uint32(tmp, ps, depth, &r_u->rid[i]))
- return False;
+ prs_uint32(tmp, ps, depth, &((*rid)[i]));
}
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ if (!ps->io)
+ {
+ /* storing. memory no longer needed */
+ safe_free(*rid);
+ (*rid) = NULL;
+ }
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_query_useraliases(char *desc, SAMR_R_QUERY_USERALIASES *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_query_useraliases");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_entries", ps, depth, &(r_u->num_entries));
+ prs_uint32("ptr ", ps, depth, &(r_u->ptr ));
+
+ if (r_u->ptr != 0)
+ {
+ samr_io_rids("rids", &r_u->num_entries2, &r_u->rid, ps, depth);
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+makes a SAMR_Q_OPEN_ALIAS structure.
********************************************************************/
+BOOL make_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u, const POLICY_HND *pol,
+ uint32 unknown_0, uint32 rid)
+{
+ if (q_u == NULL) return False;
-BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth)
+ DEBUG(5,("make_samr_q_open_alias\n"));
+
+ memcpy(&(q_u->dom_pol), pol, sizeof(q_u->dom_pol));
+
+ /* example values: 0x0000 0008 */
+ q_u->unknown_0 = unknown_0;
+
+ q_u->rid_alias = rid;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth)
{
- int i;
+ if (q_u == NULL) return False;
- if (q_u == NULL)
- return False;
+ prs_debug(ps, depth, desc, "samr_io_q_open_alias");
+ depth++;
- prs_debug(ps, depth, desc, "samr_io_q_lookup_names");
+ prs_align(ps);
+
+ smb_io_pol_hnd("dom_pol", &(q_u->dom_pol), ps, depth);
+
+ prs_uint32("unknown_0", ps, depth, &(q_u->unknown_0));
+ prs_uint32("rid_alias", ps, depth, &(q_u->rid_alias));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_open_alias");
depth++;
prs_align(ps);
- if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("pol", &(r_u->pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint32("num_names1", ps, depth, &q_u->num_names1))
- return False;
- if(!prs_uint32("flags ", ps, depth, &q_u->flags))
- return False;
- if(!prs_uint32("ptr ", ps, depth, &q_u->ptr))
- return False;
- if(!prs_uint32("num_names2", ps, depth, &q_u->num_names2))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
- SMB_ASSERT_ARRAY(q_u->hdr_name, q_u->num_names2);
+ return True;
+}
- for (i = 0; i < q_u->num_names2; i++) {
- if(!smb_io_unihdr ("", &q_u->hdr_name[i], ps, depth))
- return False;
+/*******************************************************************
+makes a SAMR_Q_LOOKUP_RIDS structure.
+********************************************************************/
+BOOL make_samr_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u,
+ const POLICY_HND *pol, uint32 flags,
+ uint32 num_rids, const uint32 *rid)
+{
+ if (q_u == NULL) return False;
+
+ DEBUG(5,("make_samr_q_lookup_rids\n"));
+
+ q_u->pol = *pol;
+
+ q_u->num_rids1 = num_rids;
+ q_u->flags = flags;
+ q_u->ptr = 0;
+ q_u->num_rids2 = num_rids;
+ q_u->rid = (uint32 *) memdup(rid, num_rids * sizeof(q_u->rid[0]));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_lookup_rids(char *desc, SAMR_Q_LOOKUP_RIDS *q_u, prs_struct *ps, int depth)
+{
+ uint32 i;
+ fstring tmp;
+
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_lookup_rids");
+ depth++;
+
+ if (ps->io)
+ {
+ ZERO_STRUCTP(q_u);
}
- for (i = 0; i < q_u->num_names2; i++) {
- if(!smb_io_unistr2("", &q_u->uni_name[i], q_u->hdr_name[i].buffer, ps, depth))
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("num_rids1", ps, depth, &(q_u->num_rids1));
+ prs_uint32("flags ", ps, depth, &(q_u->flags ));
+ prs_uint32("ptr ", ps, depth, &(q_u->ptr ));
+ prs_uint32("num_rids2", ps, depth, &(q_u->num_rids2));
+
+ if (q_u->num_rids2 != 0)
+ {
+ q_u->rid = (uint32*)Realloc(q_u->rid, sizeof(q_u->rid[0]) *
+ q_u->num_rids2);
+ if (q_u->rid == NULL)
+ {
+ samr_free_q_lookup_rids(q_u);
return False;
+ }
+ }
+
+ for (i = 0; i < q_u->num_rids2; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "rid[%02d] ", i);
+ prs_uint32(tmp, ps, depth, &(q_u->rid[i]));
+ }
+
+ prs_align(ps);
+
+ if (!ps->io)
+ {
+ /* storing. don't need memory any more */
+ samr_free_q_lookup_rids(q_u);
}
return True;
}
-
/*******************************************************************
- Inits a SAMR_R_LOOKUP_NAMES structure.
+frees a structure.
********************************************************************/
+void samr_free_q_lookup_rids(SAMR_Q_LOOKUP_RIDS *q_u)
+{
+ if (q_u->rid != NULL)
+ {
+ free(q_u->rid);
+ q_u->rid = NULL;
+ }
+}
-void init_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
- uint32 num_rids, uint32 *rid, uint8 *type, uint32 status)
+
+/*******************************************************************
+makes a SAMR_R_LOOKUP_RIDS structure.
+********************************************************************/
+BOOL make_samr_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u,
+ uint32 num_names, UNIHDR *hdr_name, UNISTR2 *uni_name,
+ uint32 *type)
{
- int i;
+ if (r_u == NULL) return False;
- DEBUG(5,("init_samr_r_lookup_names\n"));
+ DEBUG(5,("make_samr_r_lookup_rids\n"));
- if (status == 0x0) {
- r_u->num_types1 = num_rids;
- r_u->ptr_types = 1;
- r_u->num_types2 = num_rids;
+ r_u->hdr_name = NULL;
+ r_u->uni_name = NULL;
+ r_u->type = NULL;
- r_u->num_rids1 = num_rids;
- r_u->ptr_rids = 1;
- r_u->num_rids2 = num_rids;
+ if (num_names != 0)
+ {
+ r_u->num_names1 = num_names;
+ r_u->ptr_names = 1;
+ r_u->num_names2 = num_names;
- SMB_ASSERT_ARRAY(r_u->rid, num_rids);
+ r_u->num_types1 = num_names;
+ r_u->ptr_types = 1;
+ r_u->num_types2 = num_names;
- for (i = 0; i < num_rids; i++) {
- r_u->rid [i] = rid [i];
- r_u->type[i] = type[i];
- }
- } else {
- r_u->num_types1 = 0;
- r_u->ptr_types = 0;
- r_u->num_types2 = 0;
+ r_u->hdr_name = hdr_name;
+ r_u->uni_name = uni_name;
+ r_u->type = type;
+ }
+ else
+ {
+ r_u->num_names1 = num_names;
+ r_u->ptr_names = 0;
+ r_u->num_names2 = num_names;
- r_u->num_rids1 = 0;
- r_u->ptr_rids = 0;
- r_u->num_rids2 = 0;
+ r_u->num_types1 = num_names;
+ r_u->ptr_types = 0;
+ r_u->num_types2 = num_names;
}
- r_u->status = status;
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth)
+BOOL samr_io_r_lookup_rids(char *desc, SAMR_R_LOOKUP_RIDS *r_u, prs_struct *ps, int depth)
{
- int i;
+ uint32 i;
fstring tmp;
+ if (r_u == NULL) return False;
- if (r_u == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "samr_io_r_lookup_names");
+ prs_debug(ps, depth, desc, "samr_io_r_lookup_rids");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("num_rids1", ps, depth, &r_u->num_rids1))
- return False;
- if(!prs_uint32("ptr_rids ", ps, depth, &r_u->ptr_rids ))
- return False;
+ prs_uint32("num_names1", ps, depth, &(r_u->num_names1));
+ prs_uint32("ptr_names ", ps, depth, &(r_u->ptr_names ));
+ prs_uint32("num_names2", ps, depth, &(r_u->num_names2));
- if (r_u->ptr_rids != 0) {
- if(!prs_uint32("num_rids2", ps, depth, &r_u->num_rids2))
+ if (r_u->ptr_names != 0 && r_u->num_names1 != 0)
+ {
+ r_u->hdr_name = (UNIHDR*)Realloc(r_u->hdr_name,
+ r_u->num_names2 * sizeof(r_u->hdr_name[0]));
+ if (r_u->hdr_name == NULL)
+ {
return False;
+ }
- if (r_u->num_rids2 != r_u->num_rids1) {
- /* RPC fault */
+ r_u->uni_name = (UNISTR2*)Realloc(r_u->uni_name,
+ r_u->num_names2 * sizeof(r_u->uni_name[0]));
+ if (r_u->uni_name == NULL)
+ {
+ free(r_u->hdr_name);
return False;
}
-
- for (i = 0; i < r_u->num_rids2; i++) {
- slprintf(tmp, sizeof(tmp) - 1, "rid[%02d] ", i);
- if(!prs_uint32(tmp, ps, depth, &r_u->rid[i]))
- return False;
+ for (i = 0; i < r_u->num_names2; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "hdr[%02d] ", i);
+ smb_io_unihdr ("", &(r_u->hdr_name[i]), ps, depth);
+ }
+ for (i = 0; i < r_u->num_names2; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "str[%02d] ", i);
+ smb_io_unistr2("", &(r_u->uni_name[i]), r_u->hdr_name[i].buffer, ps, depth);
+ prs_align(ps);
}
}
- if(!prs_uint32("num_types1", ps, depth, &r_u->num_types1))
- return False;
- if(!prs_uint32("ptr_types ", ps, depth, &r_u->ptr_types))
- return False;
-
- if (r_u->ptr_types != 0) {
- if(!prs_uint32("num_types2", ps, depth, &r_u->num_types2))
- return False;
+ prs_align(ps);
- if (r_u->num_types2 != r_u->num_types1) {
- /* RPC fault */
+ prs_uint32("num_types1", ps, depth, &(r_u->num_types1));
+ prs_uint32("ptr_types ", ps, depth, &(r_u->ptr_types ));
+ prs_uint32("num_types2", ps, depth, &(r_u->num_types2));
+
+ if (r_u->ptr_types != 0 && r_u->num_types1 != 0)
+ {
+ r_u->type = (uint32*)Realloc(r_u->type, r_u->num_types2 *
+ sizeof(r_u->type[0]));
+ if (r_u->type == NULL)
+ {
+ if (r_u->uni_name != NULL)
+ {
+ free(r_u->uni_name);
+ }
+ if (r_u->hdr_name != NULL)
+ {
+ free(r_u->hdr_name);
+ }
return False;
}
- for (i = 0; i < r_u->num_types2; i++) {
+ for (i = 0; i < r_u->num_types2; i++)
+ {
slprintf(tmp, sizeof(tmp) - 1, "type[%02d] ", i);
- if(!prs_uint32(tmp, ps, depth, &r_u->type[i]))
- return False;
+ prs_uint32(tmp, ps, depth, &(r_u->type[i]));
}
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ if (!ps->io)
+ {
+ /* storing. don't need memory any more */
+ samr_free_r_lookup_rids(r_u);
+ }
return True;
}
/*******************************************************************
- Reads or writes a structure.
+frees a structure.
********************************************************************/
+void samr_free_r_lookup_rids(SAMR_R_LOOKUP_RIDS *r_u)
+{
+ if (r_u->uni_name != NULL)
+ {
+ free(r_u->uni_name);
+ r_u->uni_name = NULL;
+ }
+ if (r_u->hdr_name != NULL)
+ {
+ free(r_u->hdr_name);
+ r_u->hdr_name = NULL;
+ }
+ if (r_u->type != NULL)
+ {
+ free(r_u->type);
+ r_u->type = NULL;
+ }
+}
-BOOL samr_io_q_unknown_12(char *desc, SAMR_Q_UNKNOWN_12 *q_u, prs_struct *ps, int depth)
+/*******************************************************************
+makes a SAMR_Q_OPEN_ALIAS structure.
+********************************************************************/
+BOOL make_samr_q_delete_alias(SAMR_Q_DELETE_DOM_ALIAS *q_u, POLICY_HND *hnd)
{
- int i;
- fstring tmp;
+ if (q_u == NULL) return False;
- if (q_u == NULL)
- return False;
+ DEBUG(5,("make_samr_q_delete_alias\n"));
- prs_debug(ps, depth, desc, "samr_io_q_unknown_12");
- depth++;
+ memcpy(&(q_u->alias_pol), hnd, sizeof(q_u->alias_pol));
- if(!prs_align(ps))
- return False;
+ return True;
+}
- if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("num_gids1", ps, depth, &q_u->num_gids1))
- return False;
- if(!prs_uint32("rid ", ps, depth, &q_u->rid))
- return False;
- if(!prs_uint32("ptr ", ps, depth, &q_u->ptr))
- return False;
- if(!prs_uint32("num_gids2", ps, depth, &q_u->num_gids2))
- return False;
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_delete_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
- SMB_ASSERT_ARRAY(q_u->gid, q_u->num_gids2);
+ prs_debug(ps, depth, desc, "samr_io_q_delete_alias");
+ depth++;
- for (i = 0; i < q_u->num_gids2; i++) {
- slprintf(tmp, sizeof(tmp) - 1, "gid[%02d] ", i);
- if(!prs_uint32(tmp, ps, depth, &q_u->gid[i]))
- return False;
- }
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth);
return True;
}
/*******************************************************************
- Inits a SAMR_R_UNKNOWN_12 structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_r_delete_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
-void init_samr_r_unknown_12(SAMR_R_UNKNOWN_12 *r_u,
- uint32 num_aliases, fstring *als_name, uint32 *num_als_usrs,
- uint32 status)
+ prs_debug(ps, depth, desc, "samr_io_r_delete_alias");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(r_u->pol), ps, depth);
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_CREATE_DOM_ALIAS structure.
+********************************************************************/
+BOOL make_samr_q_create_dom_alias(SAMR_Q_CREATE_DOM_ALIAS *q_u, POLICY_HND *hnd,
+ const char *acct_desc)
{
- int i;
+ int acct_len = acct_desc != NULL ? strlen(acct_desc) : 0;
+ if (q_u == NULL) return False;
- DEBUG(5,("init_samr_r_unknown_12\n"));
+ DEBUG(5,("make_samr_q_create_dom_alias\n"));
- if (status == 0x0) {
- r_u->num_aliases1 = num_aliases;
- r_u->ptr_aliases = 1;
- r_u->num_aliases2 = num_aliases;
+ memcpy(&(q_u->dom_pol), hnd, sizeof(q_u->dom_pol));
- r_u->num_als_usrs1 = num_aliases;
- r_u->ptr_als_usrs = 1;
- r_u->num_als_usrs2 = num_aliases;
+ make_uni_hdr(&(q_u->hdr_acct_desc), acct_len);
+ make_unistr2(&(q_u->uni_acct_desc), acct_desc, acct_len);
- SMB_ASSERT_ARRAY(r_u->hdr_als_name, num_aliases);
+ q_u->access_mask = 0x001f000f;
- for (i = 0; i < num_aliases; i++) {
- int als_len = als_name[i] != NULL ? strlen(als_name[i]) : 0;
- init_uni_hdr(&r_u->hdr_als_name[i], als_len);
- init_unistr2(&r_u->uni_als_name[i], als_name[i], als_len);
- r_u->num_als_usrs[i] = num_als_usrs[i];
- }
- } else {
- r_u->num_aliases1 = num_aliases;
- r_u->ptr_aliases = 0;
- r_u->num_aliases2 = num_aliases;
+ return True;
+}
- r_u->num_als_usrs1 = num_aliases;
- r_u->ptr_als_usrs = 0;
- r_u->num_als_usrs2 = num_aliases;
- }
- r_u->status = status;
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_create_dom_alias(char *desc, SAMR_Q_CREATE_DOM_ALIAS *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_create_dom_alias");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("dom_pol", &(q_u->dom_pol), ps, depth);
+
+ smb_io_unihdr ("hdr_acct_desc", &(q_u->hdr_acct_desc) , ps, depth);
+ smb_io_unistr2("uni_acct_desc", &(q_u->uni_acct_desc), q_u->hdr_acct_desc.buffer, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("access_mask", ps, depth, &(q_u->access_mask));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_r_create_dom_alias(char *desc, SAMR_R_CREATE_DOM_ALIAS *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_create_dom_alias");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("alias_pol", &(r_u->alias_pol), ps, depth);
+ prs_uint32("rid", ps, depth, &(r_u->rid));
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
-BOOL samr_io_r_unknown_12(char *desc, SAMR_R_UNKNOWN_12 *r_u, prs_struct *ps, int depth)
+
+/*******************************************************************
+makes a SAMR_Q_ADD_ALIASMEM structure.
+********************************************************************/
+BOOL make_samr_q_add_aliasmem(SAMR_Q_ADD_ALIASMEM *q_u, POLICY_HND *hnd,
+ DOM_SID *sid)
{
- int i;
- fstring tmp;
+ if (q_u == NULL) return False;
- if (r_u == NULL)
- return False;
+ DEBUG(5,("make_samr_q_add_aliasmem\n"));
+
+ memcpy(&(q_u->alias_pol), hnd, sizeof(q_u->alias_pol));
+ make_dom_sid2(&q_u->sid, sid);
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_add_aliasmem(char *desc, SAMR_Q_ADD_ALIASMEM *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_unknown_12");
+ prs_debug(ps, depth, desc, "samr_io_q_add_aliasmem");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("num_aliases1", ps, depth, &r_u->num_aliases1))
- return False;
- if(!prs_uint32("ptr_aliases ", ps, depth, &r_u->ptr_aliases ))
- return False;
- if(!prs_uint32("num_aliases2", ps, depth, &r_u->num_aliases2))
- return False;
+ smb_io_pol_hnd ("alias_pol", &(q_u->alias_pol), ps, depth);
+ smb_io_dom_sid2("sid ", &(q_u->sid ), ps, depth);
- if (r_u->ptr_aliases != 0 && r_u->num_aliases1 != 0) {
- SMB_ASSERT_ARRAY(r_u->hdr_als_name, r_u->num_aliases2);
+ return True;
+}
- for (i = 0; i < r_u->num_aliases2; i++) {
- slprintf(tmp, sizeof(tmp) - 1, "als_hdr[%02d] ", i);
- if(!smb_io_unihdr ("", &r_u->hdr_als_name[i], ps, depth))
- return False;
- }
- for (i = 0; i < r_u->num_aliases2; i++) {
- slprintf(tmp, sizeof(tmp) - 1, "als_str[%02d] ", i);
- if(!smb_io_unistr2("", &r_u->uni_als_name[i], r_u->hdr_als_name[i].buffer, ps, depth))
- return False;
- }
- }
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_add_aliasmem(char *desc, SAMR_R_ADD_ALIASMEM *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
- if(!prs_align(ps))
- return False;
+ prs_debug(ps, depth, desc, "samr_io_r_add_aliasmem");
+ depth++;
- if(!prs_uint32("num_als_usrs1", ps, depth, &r_u->num_als_usrs1))
- return False;
- if(!prs_uint32("ptr_als_usrs ", ps, depth, &r_u->ptr_als_usrs))
- return False;
- if(!prs_uint32("num_als_usrs2", ps, depth, &r_u->num_als_usrs2))
- return False;
+ prs_align(ps);
- if (r_u->ptr_als_usrs != 0 && r_u->num_als_usrs1 != 0) {
- SMB_ASSERT_ARRAY(r_u->num_als_usrs, r_u->num_als_usrs2);
+ prs_uint32("status", ps, depth, &(r_u->status));
- for (i = 0; i < r_u->num_als_usrs2; i++) {
- slprintf(tmp, sizeof(tmp) - 1, "als_usrs[%02d] ", i);
- if(!prs_uint32(tmp, ps, depth, &r_u->num_als_usrs[i]))
- return False;
- }
- }
+ return True;
+}
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+
+/*******************************************************************
+makes a SAMR_Q_DEL_ALIASMEM structure.
+********************************************************************/
+BOOL make_samr_q_del_aliasmem(SAMR_Q_DEL_ALIASMEM *q_u, POLICY_HND *hnd,
+ DOM_SID *sid)
+{
+ if (q_u == NULL) return False;
+
+ DEBUG(5,("make_samr_q_del_aliasmem\n"));
+
+ memcpy(&(q_u->alias_pol), hnd, sizeof(q_u->alias_pol));
+ make_dom_sid2(&q_u->sid, sid);
return True;
}
/*******************************************************************
- Inits a SAMR_Q_OPEN_USER struct.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_q_del_aliasmem(char *desc, SAMR_Q_DEL_ALIASMEM *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
-void init_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
- POLICY_HND *pol,
- uint32 unk_0, uint32 rid)
+ prs_debug(ps, depth, desc, "samr_io_q_del_aliasmem");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth);
+ smb_io_dom_sid2("sid ", &(q_u->sid ), ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_del_aliasmem(char *desc, SAMR_R_DEL_ALIASMEM *r_u, prs_struct *ps, int depth)
{
- DEBUG(5,("samr_init_q_open_user\n"));
+ if (r_u == NULL) return False;
- memcpy(&q_u->domain_pol, pol, sizeof(q_u->domain_pol));
-
- q_u->unknown_0 = unk_0;
- q_u->user_rid = rid;
+ prs_debug(ps, depth, desc, "samr_io_r_del_aliasmem");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+makes a SAMR_Q_DELETE_DOM_ALIAS structure.
********************************************************************/
+BOOL make_samr_q_delete_dom_alias(SAMR_Q_DELETE_DOM_ALIAS *q_c, POLICY_HND *hnd)
+{
+ if (q_c == NULL || hnd == NULL) return False;
-BOOL samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth)
+ DEBUG(5,("make_samr_q_delete_dom_alias\n"));
+
+ memcpy(&(q_c->alias_pol), hnd, sizeof(q_c->alias_pol));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_delete_dom_alias(char *desc, SAMR_Q_DELETE_DOM_ALIAS *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_open_user");
+ prs_debug(ps, depth, desc, "samr_io_q_delete_dom_alias");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("domain_pol", &q_u->domain_pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth);
- if(!prs_uint32("unknown_0", ps, depth, &q_u->unknown_0))
- return False;
- if(!prs_uint32("user_rid ", ps, depth, &q_u->user_rid))
- return False;
+ return True;
+}
- if(!prs_align(ps))
- return False;
+/*******************************************************************
+makes a SAMR_R_DELETE_DOM_ALIAS structure.
+********************************************************************/
+BOOL make_samr_r_delete_dom_alias(SAMR_R_DELETE_DOM_ALIAS *r_u,
+ uint32 status)
+{
+ if (r_u == NULL) return False;
+
+ DEBUG(5,("make_samr_r_delete_dom_alias\n"));
+
+ r_u->status = status;
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth)
+BOOL samr_io_r_delete_dom_alias(char *desc, SAMR_R_DELETE_DOM_ALIAS *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_open_user");
+ prs_debug(ps, depth, desc, "samr_io_r_delete_dom_alias");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("user_pol", &r_u->user_pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ return True;
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_QUERY_ALIASMEM structure.
+********************************************************************/
+BOOL make_samr_q_query_aliasmem(SAMR_Q_QUERY_ALIASMEM *q_c,
+ const POLICY_HND *hnd)
+{
+ if (q_c == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_samr_q_query_aliasmem\n"));
+
+ memcpy(&(q_c->alias_pol), hnd, sizeof(q_c->alias_pol));
return True;
}
/*******************************************************************
- Inits a SAMR_Q_QUERY_USERGROUPS structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_q_query_aliasmem(char *desc, SAMR_Q_QUERY_ALIASMEM *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
-void init_samr_q_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
- POLICY_HND *hnd)
+ prs_debug(ps, depth, desc, "samr_io_q_query_aliasmem");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("alias_pol", &(q_u->alias_pol), ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+makes a SAMR_R_QUERY_ALIASMEM structure.
+********************************************************************/
+BOOL make_samr_r_query_aliasmem(SAMR_R_QUERY_ALIASMEM *r_u,
+ uint32 num_sids, DOM_SID2 *sid, uint32 status)
{
- DEBUG(5,("init_samr_q_query_usergroups\n"));
+ if (r_u == NULL) return False;
+
+ DEBUG(5,("make_samr_r_query_aliasmem\n"));
+
+ if (status == 0x0)
+ {
+ r_u->num_sids = num_sids;
+ r_u->ptr = (num_sids != 0) ? 1 : 0;
+ r_u->num_sids1 = num_sids;
- memcpy(&q_u->pol, hnd, sizeof(q_u->pol));
+ r_u->sid = sid;
+ }
+ else
+ {
+ r_u->ptr = 0;
+ r_u->num_sids = 0;
+ }
+
+ r_u->status = status;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
+BOOL samr_io_r_query_aliasmem(char *desc, SAMR_R_QUERY_ALIASMEM *r_u, prs_struct *ps, int depth)
+{
+ uint32 i;
+ uint32 ptr_sid[MAX_LOOKUP_SIDS];
-BOOL samr_io_q_query_usergroups(char *desc, SAMR_Q_QUERY_USERGROUPS *q_u, prs_struct *ps, int depth)
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_query_aliasmem");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("num_sids ", ps, depth, &(r_u->num_sids));
+ prs_uint32("ptr", ps, depth, &(r_u->ptr));
+
+ if (r_u->ptr != 0)
+ {
+ SMB_ASSERT_ARRAY(ptr_sid, r_u->num_sids);
+
+ if (r_u->num_sids != 0)
+ {
+ prs_uint32("num_sids1", ps, depth, &(r_u->num_sids1));
+
+ for (i = 0; i < r_u->num_sids1; i++)
+ {
+ ptr_sid[i] = 1;
+ prs_uint32("", ps, depth, &(ptr_sid[i]));
+ }
+ for (i = 0; i < r_u->num_sids1; i++)
+ {
+ if (ptr_sid[i] != 0)
+ {
+ smb_io_dom_sid2("", &(r_u->sid[i]), ps, depth);
+ }
+ }
+ }
+ }
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+
+/*******************************************************************
+makes a SAMR_Q_LOOKUP_NAMES structure.
+********************************************************************/
+BOOL make_samr_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
+ const POLICY_HND *pol, uint32 flags,
+ uint32 num_names, char **name)
{
- if (q_u == NULL)
- return False;
+ uint32 i;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_query_usergroups");
+ DEBUG(5,("make_samr_q_lookup_names\n"));
+
+ memcpy(&(q_u->pol), pol, sizeof(*pol));
+
+ q_u->num_names1 = num_names;
+ q_u->flags = flags;
+ q_u->ptr = 0;
+ q_u->num_names2 = num_names;
+
+ for (i = 0; i < num_names; i++)
+ {
+ int len_name = name[i] != NULL ? strlen(name[i]) : 0;
+ make_uni_hdr(&(q_u->hdr_name[i]), len_name); /* unicode header for user_name */
+ make_unistr2(&(q_u->uni_name[i]), name[i], len_name); /* unicode string for machine account */
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_lookup_names(char *desc, SAMR_Q_LOOKUP_NAMES *q_u, prs_struct *ps, int depth)
+{
+ uint32 i;
+
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_lookup_names");
depth++;
- if(!prs_align(ps))
- return False;
+ if (ps->io)
+ {
+ ZERO_STRUCTP(q_u);
+ }
- if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("num_names1", ps, depth, &(q_u->num_names1));
+ prs_uint32("flags ", ps, depth, &(q_u->flags ));
+ prs_uint32("ptr ", ps, depth, &(q_u->ptr ));
+ prs_uint32("num_names2", ps, depth, &(q_u->num_names2));
+
+ SMB_ASSERT_ARRAY(q_u->hdr_name, q_u->num_names2);
+
+ for (i = 0; i < q_u->num_names2; i++)
+ {
+ smb_io_unihdr ("", &(q_u->hdr_name[i]), ps, depth);
+ }
+ for (i = 0; i < q_u->num_names2; i++)
+ {
+ smb_io_unistr2("", &(q_u->uni_name[i]), q_u->hdr_name[i].buffer, ps, depth);
+ prs_align(ps);
+ }
+
+ prs_align(ps);
+
+ if (!ps->io)
+ {
+ /* storing. memory no longer needed */
+ samr_free_q_lookup_names(q_u);
+ }
return True;
}
/*******************************************************************
- Inits a SAMR_R_QUERY_USERGROUPS structure.
+frees a structure.
********************************************************************/
+void samr_free_q_lookup_names(SAMR_Q_LOOKUP_NAMES *q_l)
+{
+}
-void init_samr_r_query_usergroups(SAMR_R_QUERY_USERGROUPS *r_u,
- uint32 num_gids, DOM_GID *gid, uint32 status)
+/*******************************************************************
+makes a SAMR_R_LOOKUP_NAMES structure.
+********************************************************************/
+BOOL make_samr_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_u,
+ uint32 num_rids,
+ const uint32 *rid, const uint32 *type,
+ uint32 status)
{
- DEBUG(5,("init_samr_r_query_usergroups\n"));
+ if (r_u == NULL) return False;
- if (status == 0x0) {
- r_u->ptr_0 = 1;
- r_u->num_entries = num_gids;
- r_u->ptr_1 = 1;
- r_u->num_entries2 = num_gids;
+ DEBUG(5,("make_samr_r_lookup_names\n"));
- r_u->gid = gid;
- } else {
- r_u->ptr_0 = 0;
- r_u->num_entries = 0;
- r_u->ptr_1 = 0;
+ if ((status == 0x0) && (num_rids != 0))
+ {
+ uint32 i;
+
+ r_u->num_types1 = num_rids;
+ r_u->ptr_types = 1;
+ r_u->num_types2 = num_rids;
+
+ r_u->num_rids1 = num_rids;
+ r_u->ptr_rids = 1;
+ r_u->num_rids2 = num_rids;
+
+ r_u->rids = g_new(uint32, num_rids);
+ r_u->types = g_new(uint32, num_rids);
+
+ if (! r_u->rids || ! r_u->types)
+ {
+ samr_free_r_lookup_names(r_u);
+ return False;
+ }
+
+ for (i = 0; i < num_rids; i++)
+ {
+ r_u->rids [i] = rid [i];
+ r_u->types[i] = type[i];
+ }
+ }
+ else
+ {
+ r_u->num_types1 = 0;
+ r_u->ptr_types = 0;
+ r_u->num_types2 = 0;
+
+ r_u->num_rids1 = 0;
+ r_u->ptr_rids = 0;
+ r_u->num_rids2 = 0;
+
+ r_u->rids = NULL;
+ r_u->types = NULL;
}
r_u->status = status;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_r_query_usergroups(char *desc, SAMR_R_QUERY_USERGROUPS *r_u, prs_struct *ps, int depth)
+BOOL samr_io_r_lookup_names(char *desc, SAMR_R_LOOKUP_NAMES *r_u, prs_struct *ps, int depth)
{
- int i;
+ uint32 i;
+ fstring tmp;
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_query_usergroups");
+ prs_debug(ps, depth, desc, "samr_io_r_lookup_names");
depth++;
- if(!prs_align(ps))
- return False;
+ if (ps->io)
+ {
+ ZERO_STRUCTP(r_u);
+ }
- if(!prs_uint32("ptr_0 ", ps, depth, &r_u->ptr_0))
- return False;
+ prs_align(ps);
+
+ prs_uint32("num_rids1", ps, depth, &(r_u->num_rids1));
+ prs_uint32("ptr_rids ", ps, depth, &(r_u->ptr_rids ));
+
+ if (r_u->ptr_rids != 0)
+ {
+ prs_uint32("num_rids2", ps, depth, &(r_u->num_rids2));
+
+ if (r_u->num_rids2 != r_u->num_rids1)
+ {
+ /* RPC fault */
+ return False;
+ }
- if (r_u->ptr_0 != 0) {
- if(!prs_uint32("num_entries ", ps, depth, &r_u->num_entries))
+ if (ps->io)
+ r_u->rids = g_new(uint32, r_u->num_rids2);
+
+ if (! r_u->rids)
+ {
+ DEBUG(0, ("NULL rids in samr_io_r_lookup_names\n"));
+ samr_free_r_lookup_names(r_u);
return False;
- if(!prs_uint32("ptr_1 ", ps, depth, &r_u->ptr_1))
+ }
+
+ for (i = 0; i < r_u->num_rids2; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "rid[%02d] ", i);
+ prs_uint32(tmp, ps, depth, &(r_u->rids[i]));
+ }
+ }
+
+ prs_uint32("num_types1", ps, depth, &(r_u->num_types1));
+ prs_uint32("ptr_types ", ps, depth, &(r_u->ptr_types ));
+
+ if (r_u->ptr_types != 0)
+ {
+ prs_uint32("num_types2", ps, depth, &(r_u->num_types2));
+
+ if (r_u->num_types2 != r_u->num_types1)
+ {
+ /* RPC fault */
return False;
+ }
- if (r_u->num_entries != 0) {
- if(!prs_uint32("num_entries2", ps, depth, &r_u->num_entries2))
- return False;
+ if (ps->io)
+ r_u->types = g_new(uint32, r_u->num_types2);
- for (i = 0; i < r_u->num_entries2; i++) {
- if(!smb_io_gid("", &r_u->gid[i], ps, depth))
- return False;
- }
+ if (! r_u->types)
+ {
+ DEBUG(0, ("NULL types in samr_io_r_lookup_names\n"));
+ samr_free_r_lookup_names(r_u);
+ return False;
+ }
+
+ for (i = 0; i < r_u->num_types2; i++)
+ {
+ slprintf(tmp, sizeof(tmp) - 1, "type[%02d] ", i);
+ prs_uint32(tmp, ps, depth, &(r_u->types[i]));
}
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ if (!ps->io)
+ {
+ /* storing. memory no longer needed */
+ samr_free_r_lookup_names(r_u);
+ }
return True;
}
/*******************************************************************
- Inits a SAMR_Q_QUERY_USERINFO structure.
+frees a structure.
********************************************************************/
+void samr_free_r_lookup_names(SAMR_R_LOOKUP_NAMES *r_l)
+{
+ if (r_l->rids != NULL)
+ {
+ free(r_l->rids);
+ r_l->rids = NULL;
+ }
+ if (r_l->types != NULL)
+ {
+ free(r_l->types);
+ r_l->types = NULL;
+ }
+ r_l->num_types1 = 0;
+ r_l->ptr_types = 0;
+ r_l->num_types2 = 0;
+
+ r_l->num_rids1 = 0;
+ r_l->ptr_rids = 0;
+ r_l->num_rids2 = 0;
+}
+
+/*******************************************************************
+makes a SAMR_Q_DELETE_DOM_USER structure.
+********************************************************************/
+BOOL make_samr_q_delete_dom_user(SAMR_Q_DELETE_DOM_USER *q_c, POLICY_HND *hnd)
+{
+ if (q_c == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_samr_q_delete_dom_user\n"));
+
+ memcpy(&(q_c->user_pol), hnd, sizeof(q_c->user_pol));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_delete_dom_user(char *desc, SAMR_Q_DELETE_DOM_USER *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_delete_dom_user");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("user_pol", &(q_u->user_pol), ps, depth);
+
+ return True;
+}
-void init_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_delete_dom_user(char *desc, SAMR_R_DELETE_DOM_USER *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_delete_dom_user");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL make_samr_q_open_user(SAMR_Q_OPEN_USER *q_u,
+ const POLICY_HND *pol,
+ uint32 access_mask, uint32 rid)
+{
+ if (q_u == NULL) return False;
+
+ DEBUG(5,("samr_make_samr_q_open_user\n"));
+
+ memcpy(&q_u->domain_pol, pol, sizeof(q_u->domain_pol));
+
+ q_u->access_mask = access_mask;
+ q_u->user_rid = rid;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_open_user(char *desc, SAMR_Q_OPEN_USER *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_open_user");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("access_mask", ps, depth, &(q_u->access_mask));
+ prs_uint32("user_rid ", ps, depth, &(q_u->user_rid ));
+
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_open_user(char *desc, SAMR_R_OPEN_USER *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_open_user");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("user_pol", &(r_u->user_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL make_samr_q_create_user(SAMR_Q_CREATE_USER *q_u,
+ POLICY_HND *pol,
+ const char *name,
+ uint16 acb_info, uint32 access_mask)
+{
+ int len_name;
+ if (q_u == NULL) return False;
+ len_name = strlen(name);
+
+ DEBUG(5,("samr_make_samr_q_create_user\n"));
+
+ memcpy(&q_u->domain_pol, pol, sizeof(q_u->domain_pol));
+
+ make_uni_hdr(&(q_u->hdr_name), len_name);
+ make_unistr2(&(q_u->uni_name), name, len_name);
+
+ q_u->acb_info = acb_info;
+ q_u->access_mask = access_mask;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_create_user(char *desc, SAMR_Q_CREATE_USER *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_create_user");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("domain_pol", &(q_u->domain_pol), ps, depth);
+ prs_align(ps);
+
+ smb_io_unihdr ("unihdr", &(q_u->hdr_name), ps, depth);
+ smb_io_unistr2("unistr2", &(q_u->uni_name), q_u->hdr_name.buffer, ps, depth);
+ prs_align(ps);
+
+ prs_uint16("acb_info ", ps, depth, &(q_u->acb_info ));
+ prs_align(ps);
+ prs_uint32("access_mask", ps, depth, &(q_u->access_mask));
+
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_r_create_user(char *desc, SAMR_R_CREATE_USER *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_r_create_user");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("user_pol", &(r_u->user_pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("unknown_0", ps, depth, &(r_u->unknown_0));
+ prs_uint32("user_rid ", ps, depth, &(r_u->user_rid ));
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+makes a SAMR_Q_QUERY_USERINFO structure.
+********************************************************************/
+BOOL make_samr_q_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
POLICY_HND *hnd, uint16 switch_value)
{
- DEBUG(5,("init_samr_q_query_userinfo\n"));
+ if (q_u == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_samr_q_query_userinfo\n"));
- memcpy(&q_u->pol, hnd, sizeof(q_u->pol));
+ memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
q_u->switch_value = switch_value;
+
+ return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL samr_io_q_query_userinfo(char *desc, SAMR_Q_QUERY_USERINFO *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_q_query_userinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value)) /* 0x0015 or 0x0011 */
- return False;
+ prs_uint16("switch_value", ps, depth, &(q_u->switch_value)); /* 0x0015 or 0x0011 */
+
+ prs_align(ps);
return True;
}
/*******************************************************************
- Reads or writes a LOGON_HRS structure.
+reads or writes a LOGON_HRS structure.
********************************************************************/
-
static BOOL sam_io_logon_hrs(char *desc, LOGON_HRS *hrs, prs_struct *ps, int depth)
{
- if (hrs == NULL)
- return False;
+ if (hrs == NULL) return False;
prs_debug(ps, depth, desc, "sam_io_logon_hrs");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32 ( "len ", ps, depth, &hrs->len))
- return False;
+ prs_uint32 ( "len ", ps, depth, &(hrs->len ));
- if (hrs->len > 64) {
+ if (hrs->len > 64)
+ {
DEBUG(5,("sam_io_logon_hrs: truncating length\n"));
hrs->len = 64;
}
- if(!prs_uint8s (False, "hours", ps, depth, hrs->hours, hrs->len))
- return False;
+ prs_uint8s (False, "hours", ps, depth, hrs->hours, hrs->len);
return True;
}
/*******************************************************************
- Inits a SAM_USER_INFO_10 structure.
+makes a SAM_USER_INFO_12 structure.
********************************************************************/
+BOOL make_sam_user_info12(SAM_USER_INFO_12 *usr,
+ uint16 acb_info,
+ const uint8 lm_pwd[16],
+ const uint8 nt_pwd[16])
-void init_sam_user_info10(SAM_USER_INFO_10 *usr,
- uint32 acb_info)
{
- DEBUG(5,("init_sam_user_info10\n"));
+ if (usr == NULL) return False;
+
+ DEBUG(5,("make_sam_user_info12\n"));
usr->acb_info = acb_info;
+
+ if (lm_pwd == NULL)
+ {
+ bzero(usr->lm_pwd, sizeof(usr->lm_pwd));
+ }
+ else
+ {
+ memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd));
+ }
+
+ if (nt_pwd == NULL)
+ {
+ bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
+ }
+ else
+ {
+ memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd));
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL sam_io_user_info12(char *desc, SAM_USER_INFO_12 *u, prs_struct *ps, int depth)
+{
+ if (u == NULL) return False;
+
+ DEBUG(0,("possible security breach!\n"));
+
+ return False;
+#if 0
+ prs_debug(ps, depth, desc, "samr_io_r_user_info12");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint16("acb_info", ps, depth, &u->acb_info);
+ prs_align(ps);
+
+ prs_uint8s(False, "lm_pwd", ps, depth, u->lm_pwd, sizeof(u->lm_pwd));
+ prs_uint8s(False, "nt_pwd", ps, depth, u->nt_pwd, sizeof(u->nt_pwd));
+
+ return True;
+#endif
}
/*******************************************************************
- Reads or writes a structure.
+makes a SAM_USER_INFO_10 structure.
********************************************************************/
+BOOL make_sam_user_info10(SAM_USER_INFO_10 *usr,
+ uint32 acb_info)
+{
+ if (usr == NULL) return False;
+
+ DEBUG(5,("make_sam_user_info10\n"));
+
+ usr->acb_info = acb_info;
+
+ return True;
+}
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
BOOL sam_io_user_info10(char *desc, SAM_USER_INFO_10 *usr, prs_struct *ps, int depth)
{
- if (usr == NULL)
- return False;
+ if (usr == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_r_user_info10");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("acb_info", ps, depth, &usr->acb_info))
- return False;
+ prs_uint32("acb_info", ps, depth, &(usr->acb_info));
return True;
}
/*******************************************************************
- Inits a SAM_USER_INFO_11 structure.
+makes a SAM_USER_INFO_11 structure.
********************************************************************/
-
-void init_sam_user_info11(SAM_USER_INFO_11 *usr,
+BOOL make_sam_user_info11(SAM_USER_INFO_11 *usr,
NTTIME *expiry,
char *mach_acct,
uint32 rid_user,
@@ -2589,26 +4731,27 @@ void init_sam_user_info11(SAM_USER_INFO_11 *usr,
{
int len_mach_acct;
+ if (usr == NULL || expiry == NULL || mach_acct == NULL) return False;
- DEBUG(5,("init_sam_user_info11\n"));
+ DEBUG(5,("make_sam_user_info11\n"));
len_mach_acct = strlen(mach_acct);
- memcpy(&usr->expiry,expiry, sizeof(usr->expiry)); /* expiry time or something? */
- memset((char *)usr->padding_1, '\0', sizeof(usr->padding_1)); /* 0 - padding 24 bytes */
+ memcpy(&(usr->expiry),expiry, sizeof(usr->expiry)); /* expiry time or something? */
+ bzero(usr->padding_1, sizeof(usr->padding_1)); /* 0 - padding 24 bytes */
- init_uni_hdr(&usr->hdr_mach_acct, len_mach_acct); /* unicode header for machine account */
+ make_uni_hdr(&(usr->hdr_mach_acct), len_mach_acct); /* unicode header for machine account */
usr->padding_2 = 0; /* 0 - padding 4 bytes */
usr->ptr_1 = 1; /* pointer */
- memset((char *)usr->padding_3, '\0', sizeof(usr->padding_3)); /* 0 - padding 32 bytes */
+ bzero(usr->padding_3, sizeof(usr->padding_3)); /* 0 - padding 32 bytes */
usr->padding_4 = 0; /* 0 - padding 4 bytes */
usr->ptr_2 = 1; /* pointer */
usr->padding_5 = 0; /* 0 - padding 4 bytes */
usr->ptr_3 = 1; /* pointer */
- memset((char *)usr->padding_6, '\0', sizeof(usr->padding_6)); /* 0 - padding 32 bytes */
+ bzero(usr->padding_6, sizeof(usr->padding_6)); /* 0 - padding 32 bytes */
usr->rid_user = rid_user;
usr->rid_group = rid_group;
@@ -2619,99 +4762,552 @@ void init_sam_user_info11(SAM_USER_INFO_11 *usr,
usr->unknown_4 = 0x003f; /* 0x003f - 16 bit unknown */
usr->unknown_5 = 0x003c; /* 0x003c - 16 bit unknown */
- memset((char *)usr->padding_7, '\0', sizeof(usr->padding_7)); /* 0 - padding 16 bytes */
+ bzero(usr->padding_7, sizeof(usr->padding_7)); /* 0 - padding 16 bytes */
usr->padding_8 = 0; /* 0 - padding 4 bytes */
- init_unistr2(&usr->uni_mach_acct, mach_acct, len_mach_acct); /* unicode string for machine account */
+ make_unistr2(&(usr->uni_mach_acct), mach_acct, len_mach_acct); /* unicode string for machine account */
- memset((char *)usr->padding_9, '\0', sizeof(usr->padding_9)); /* 0 - padding 48 bytes */
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL sam_io_user_info11(char *desc, SAM_USER_INFO_11 *usr, prs_struct *ps, int depth)
{
- if (usr == NULL)
- return False;
+ if (usr == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_unknown_24");
+ prs_debug(ps, depth, desc, "samr_io_r_unknown_11");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint8s (False, "padding_0", ps, depth, usr->padding_0, sizeof(usr->padding_0)))
- return False;
+ prs_uint8s (False, "padding_0", ps, depth, usr->padding_0, sizeof(usr->padding_0));
- if(!smb_io_time("time", &(usr->expiry), ps, depth))
- return False;
+ smb_io_time("time", &(usr->expiry), ps, depth);
- if(!prs_uint8s (False, "padding_1", ps, depth, usr->padding_1, sizeof(usr->padding_1)))
- return False;
+ prs_uint8s (False, "padding_1", ps, depth, usr->padding_1, sizeof(usr->padding_1));
- if(!smb_io_unihdr ("unihdr", &usr->hdr_mach_acct, ps, depth))
- return False;
- if(!prs_uint32( "padding_2", ps, depth, &usr->padding_2))
- return False;
+ smb_io_unihdr ("unihdr", &(usr->hdr_mach_acct), ps, depth);
+ prs_uint32( "padding_2", ps, depth, &(usr->padding_2));
- if(!prs_uint32( "ptr_1 ", ps, depth, &usr->ptr_1))
- return False;
- if(!prs_uint8s (False, "padding_3", ps, depth, usr->padding_3, sizeof(usr->padding_3)))
- return False;
- if(!prs_uint32( "padding_4", ps, depth, &usr->padding_4))
- return False;
+ prs_uint32( "ptr_1 ", ps, depth, &(usr->ptr_1 ));
+ prs_uint8s (False, "padding_3", ps, depth, usr->padding_3, sizeof(usr->padding_3));
+ prs_uint32( "padding_4", ps, depth, &(usr->padding_4));
- if(!prs_uint32( "ptr_2 ", ps, depth, &usr->ptr_2))
- return False;
- if(!prs_uint32( "padding_5", ps, depth, &usr->padding_5))
- return False;
+ prs_uint32( "ptr_2 ", ps, depth, &(usr->ptr_2 ));
+ prs_uint32( "padding_5", ps, depth, &(usr->padding_5));
- if(!prs_uint32( "ptr_3 ", ps, depth, &usr->ptr_3))
- return False;
- if(!prs_uint8s(False, "padding_6", ps, depth, usr->padding_6, sizeof(usr->padding_6)))
- return False;
+ prs_uint32( "ptr_3 ", ps, depth, &(usr->ptr_3 ));
+ prs_uint8s (False, "padding_6", ps, depth, usr->padding_6, sizeof(usr->padding_6));
- if(!prs_uint32( "rid_user ", ps, depth, &usr->rid_user))
- return False;
- if(!prs_uint32( "rid_group", ps, depth, &usr->rid_group))
- return False;
- if(!prs_uint16( "acct_ctrl", ps, depth, &usr->acct_ctrl))
- return False;
- if(!prs_uint16( "unknown_3", ps, depth, &usr->unknown_3))
- return False;
- if(!prs_uint16( "unknown_4", ps, depth, &usr->unknown_4))
- return False;
- if(!prs_uint16( "unknown_5", ps, depth, &usr->unknown_5))
- return False;
+ prs_uint32( "rid_user ", ps, depth, &(usr->rid_user ));
+ prs_uint32( "rid_group", ps, depth, &(usr->rid_group));
+ prs_uint16( "acct_ctrl", ps, depth, &(usr->acct_ctrl));
+ prs_uint16( "unknown_3", ps, depth, &(usr->unknown_3));
+ prs_uint16( "unknown_4", ps, depth, &(usr->unknown_4));
+ prs_uint16( "unknown_5", ps, depth, &(usr->unknown_5));
- if(!prs_uint8s (False, "padding_7", ps, depth, usr->padding_7, sizeof(usr->padding_7)))
- return False;
- if(!prs_uint32( "padding_8", ps, depth, &usr->padding_8))
- return False;
+ prs_uint8s (False, "padding_7", ps, depth, usr->padding_7, sizeof(usr->padding_7));
+ prs_uint32( "padding_8", ps, depth, &(usr->padding_8));
- if(!smb_io_unistr2("unistr2", &usr->uni_mach_acct, True, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_unistr2("unistr2", &(usr->uni_mach_acct), True, ps, depth);
+ prs_align(ps);
- if(!prs_uint8s(False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9)))
- return False;
+ prs_uint8s (False, "padding_9", ps, depth, usr->padding_9, sizeof(usr->padding_9));
+
+ return True;
+}
+
+/*************************************************************************
+ make_sam_user_infoa
+
+ unknown_3 = 0x09f8 27fa
+ unknown_5 = 0x0001 0000
+ unknown_6 = 0x0000 04ec
+
+ *************************************************************************/
+BOOL make_sam_user_info24(SAM_USER_INFO_24 *usr,
+ const char newpass[516], uint16 passlen)
+{
+ DEBUG(10,("make_sam_user_info24: passlen: %d\n", passlen));
+ memcpy(usr->pass, newpass, sizeof(usr->pass));
+ usr->unk_0 = passlen;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_user_info24(char *desc, SAM_USER_INFO_24 *usr, prs_struct *ps, int depth)
+{
+ if (usr == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_user_info24");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint8s (False, "password", ps, depth, usr->pass, sizeof(usr->pass));
+ prs_uint16("unk_0", ps, depth, &(usr->unk_0)); /* unknown */
+ prs_align(ps);
+
+ return True;
+}
+
+
+/*************************************************************************
+ make_sam_user_info23
+
+ unknown_3 = 0x09f8 27fa
+ unknown_5 = 0x0001 0000
+ unknown_6 = 0x0000 04ec
+
+ *************************************************************************/
+BOOL make_sam_user_info23W(SAM_USER_INFO_23 *usr,
+
+ const NTTIME *logon_time, /* all zeros */
+ const NTTIME *logoff_time, /* all zeros */
+ const NTTIME *kickoff_time, /* all zeros */
+ const NTTIME *pass_last_set_time, /* all zeros */
+ const NTTIME *pass_can_change_time, /* all zeros */
+ const NTTIME *pass_must_change_time, /* all zeros */
+
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *desc,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial,
+
+ uint32 user_rid, /* 0x0000 0000 */
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS *hrs,
+ uint32 unknown_5,
+ char newpass[516]
+#if 0
+ , uint32 unknown_6
+#endif
+ )
+{
+ int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
+ int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
+ int len_home_dir = home_dir != NULL ? home_dir ->uni_str_len : 0;
+ int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
+ int len_logon_script = log_scr != NULL ? log_scr ->uni_str_len : 0;
+ int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
+ int len_description = desc != NULL ? desc ->uni_str_len : 0;
+ int len_workstations = wkstas != NULL ? wkstas ->uni_str_len : 0;
+ int len_unknown_str = unk_str != NULL ? unk_str ->uni_str_len : 0;
+ int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
+
+ usr->logon_time = *logon_time; /* all zeros */
+ usr->logoff_time = *logoff_time; /* all zeros */
+ usr->kickoff_time = *kickoff_time; /* all zeros */
+ usr->pass_last_set_time = *pass_last_set_time; /* all zeros */
+ usr->pass_can_change_time = *pass_can_change_time; /* all zeros */
+ usr->pass_must_change_time = *pass_must_change_time; /* all zeros */
+
+ make_uni_hdr(&(usr->hdr_user_name ), len_user_name ); /* NULL */
+ make_uni_hdr(&(usr->hdr_full_name ), len_full_name );
+ make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir );
+ make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive );
+ make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
+ make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
+ make_uni_hdr(&(usr->hdr_acct_desc ), len_description );
+ make_uni_hdr(&(usr->hdr_workstations), len_workstations);
+ make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str );
+ make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial );
+
+ bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
+ bzero(usr->lm_pwd, sizeof(usr->lm_pwd));
+
+ usr->user_rid = user_rid; /* 0x0000 0000 */
+ usr->group_rid = group_rid;
+ usr->acb_info = acb_info;
+ usr->unknown_3 = unknown_3; /* 09f8 27fa */
+
+ usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
+ usr->ptr_logon_hrs = hrs ? 1 : 0;
+
+ bzero(usr->padding1, sizeof(usr->padding1));
+
+ usr->unknown_5 = unknown_5; /* 0x0001 0000 */
+
+ memcpy(usr->pass, newpass, sizeof(usr->pass));
+
+ copy_unistr2(&(usr->uni_user_name ), user_name);
+ copy_unistr2(&(usr->uni_full_name ), full_name);
+ copy_unistr2(&(usr->uni_home_dir ), home_dir );
+ copy_unistr2(&(usr->uni_dir_drive ), dir_drive);
+ copy_unistr2(&(usr->uni_logon_script), log_scr );
+ copy_unistr2(&(usr->uni_profile_path), prof_path);
+ copy_unistr2(&(usr->uni_acct_desc ), desc );
+ copy_unistr2(&(usr->uni_workstations), wkstas );
+ copy_unistr2(&(usr->uni_unknown_str ), unk_str );
+ copy_unistr2(&(usr->uni_munged_dial ), mung_dial);
+
+#if 0
+ usr->unknown_6 = unknown_6; /* 0x0000 04ec */
+ usr->padding4 = 0;
+#endif
+
+ if (hrs)
+ {
+ memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
+ }
+ else
+ {
+ memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
+ }
+
+ return True;
+}
+
+/*************************************************************************
+ make_sam_user_info23
+
+ unknown_3 = 0x09f8 27fa
+ unknown_5 = 0x0001 0000
+ unknown_6 = 0x0000 04ec
+
+ *************************************************************************/
+BOOL make_sam_user_info23A(SAM_USER_INFO_23 *usr,
+
+ NTTIME *logon_time, /* all zeros */
+ NTTIME *logoff_time, /* all zeros */
+ NTTIME *kickoff_time, /* all zeros */
+ NTTIME *pass_last_set_time, /* all zeros */
+ NTTIME *pass_can_change_time, /* all zeros */
+ NTTIME *pass_must_change_time, /* all zeros */
+
+ char *user_name, /* NULL */
+ char *full_name,
+ char *home_dir,
+ char *dir_drive,
+ char *log_scr,
+ char *prof_path,
+ char *desc,
+ char *wkstas,
+ char *unk_str,
+ char *mung_dial,
+
+ uint32 user_rid, /* 0x0000 0000 */
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ LOGON_HRS *hrs,
+ uint32 unknown_5,
+ char newpass[516]
+#if 0
+ , uint32 unknown_6
+#endif
+ )
+{
+ int len_user_name = user_name != NULL ? strlen(user_name) : 0;
+ int len_full_name = full_name != NULL ? strlen(full_name) : 0;
+ int len_home_dir = home_dir != NULL ? strlen(home_dir ) : 0;
+ int len_dir_drive = dir_drive != NULL ? strlen(dir_drive) : 0;
+ int len_logon_script = log_scr != NULL ? strlen(log_scr ) : 0;
+ int len_profile_path = prof_path != NULL ? strlen(prof_path) : 0;
+ int len_description = desc != NULL ? strlen(desc ) : 0;
+ int len_workstations = wkstas != NULL ? strlen(wkstas ) : 0;
+ int len_unknown_str = unk_str != NULL ? strlen(unk_str ) : 0;
+ int len_munged_dial = mung_dial != NULL ? strlen(mung_dial) : 0;
+
+ usr->logon_time = *logon_time; /* all zeros */
+ usr->logoff_time = *logoff_time; /* all zeros */
+ usr->kickoff_time = *kickoff_time; /* all zeros */
+ usr->pass_last_set_time = *pass_last_set_time; /* all zeros */
+ usr->pass_can_change_time = *pass_can_change_time; /* all zeros */
+ usr->pass_must_change_time = *pass_must_change_time; /* all zeros */
+
+ make_uni_hdr(&(usr->hdr_user_name ), len_user_name ); /* NULL */
+ make_uni_hdr(&(usr->hdr_full_name ), len_full_name );
+ make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir );
+ make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive );
+ make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
+ make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
+ make_uni_hdr(&(usr->hdr_acct_desc ), len_description );
+ make_uni_hdr(&(usr->hdr_workstations), len_workstations);
+ make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str );
+ make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial );
+
+ bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
+ bzero(usr->lm_pwd, sizeof(usr->lm_pwd));
+
+ usr->user_rid = user_rid; /* 0x0000 0000 */
+ usr->group_rid = group_rid;
+ usr->acb_info = acb_info;
+ usr->unknown_3 = unknown_3; /* 09f8 27fa */
+
+ usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
+ usr->ptr_logon_hrs = hrs ? 1 : 0;
+
+ bzero(usr->padding1, sizeof(usr->padding1));
+
+ usr->unknown_5 = unknown_5; /* 0x0001 0000 */
+
+ memcpy(usr->pass, newpass, sizeof(usr->pass));
+
+ make_unistr2(&(usr->uni_user_name ), user_name , len_user_name ); /* NULL */
+ make_unistr2(&(usr->uni_full_name ), full_name , len_full_name );
+ make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir );
+ make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive );
+ make_unistr2(&(usr->uni_logon_script), log_scr, len_logon_script);
+ make_unistr2(&(usr->uni_profile_path), prof_path, len_profile_path);
+ make_unistr2(&(usr->uni_acct_desc ), desc , len_description );
+ make_unistr2(&(usr->uni_workstations), wkstas, len_workstations);
+ make_unistr2(&(usr->uni_unknown_str ), unk_str , len_unknown_str );
+ make_unistr2(&(usr->uni_munged_dial ), mung_dial , len_munged_dial );
+
+#if 0
+ usr->unknown_6 = unknown_6; /* 0x0000 04ec */
+ usr->padding4 = 0;
+#endif
+
+ if (hrs)
+ {
+ memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
+ }
+ else
+ {
+ memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL sam_io_user_info23(char *desc, SAM_USER_INFO_23 *usr, prs_struct *ps, int depth)
+{
+ if (usr == NULL) return False;
+
+ prs_debug(ps, depth, desc, "sam_io_user_info23");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_time("logon_time ", &(usr->logon_time) , ps, depth);
+ smb_io_time("logoff_time ", &(usr->logoff_time) , ps, depth);
+ smb_io_time("kickoff_time ", &(usr->kickoff_time) , ps, depth);
+ smb_io_time("pass_last_set_time ", &(usr->pass_last_set_time) , ps, depth);
+ smb_io_time("pass_can_change_time ", &(usr->pass_can_change_time) , ps, depth);
+ smb_io_time("pass_must_change_time", &(usr->pass_must_change_time), ps, depth);
+
+ smb_io_unihdr("hdr_user_name ", &(usr->hdr_user_name) , ps, depth); /* username unicode string header */
+ smb_io_unihdr("hdr_full_name ", &(usr->hdr_full_name) , ps, depth); /* user's full name unicode string header */
+ smb_io_unihdr("hdr_home_dir ", &(usr->hdr_home_dir) , ps, depth); /* home directory unicode string header */
+ smb_io_unihdr("hdr_dir_drive ", &(usr->hdr_dir_drive) , ps, depth); /* home directory drive */
+ smb_io_unihdr("hdr_logon_script", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
+ smb_io_unihdr("hdr_profile_path", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
+ smb_io_unihdr("hdr_acct_desc ", &(usr->hdr_acct_desc ) , ps, depth); /* account desc */
+ smb_io_unihdr("hdr_workstations", &(usr->hdr_workstations), ps, depth); /* wkstas user can log on from */
+ smb_io_unihdr("hdr_unknown_str ", &(usr->hdr_unknown_str ), ps, depth); /* unknown string */
+ smb_io_unihdr("hdr_munged_dial ", &(usr->hdr_munged_dial ), ps, depth); /* wkstas user can log on from */
+
+ prs_uint8s (False, "lm_pwd ", ps, depth, usr->lm_pwd , sizeof(usr->lm_pwd ));
+ prs_uint8s (False, "nt_pwd ", ps, depth, usr->nt_pwd , sizeof(usr->nt_pwd ));
+
+ prs_uint32("user_rid ", ps, depth, &(usr->user_rid )); /* User ID */
+ prs_uint32("group_rid ", ps, depth, &(usr->group_rid )); /* Group ID */
+ prs_uint16("acb_info ", ps, depth, &(usr->acb_info )); /* Group ID */
+ prs_align(ps);
+
+ prs_uint32("unknown_3 ", ps, depth, &(usr->unknown_3 ));
+ prs_uint16("logon_divs ", ps, depth, &(usr->logon_divs )); /* logon divisions per week */
+ prs_align(ps);
+ prs_uint32("ptr_logon_hrs ", ps, depth, &(usr->ptr_logon_hrs));
+ prs_uint8s (False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1));
+ prs_uint32("unknown_5 ", ps, depth, &(usr->unknown_5 ));
+
+ prs_uint8s (False, "password ", ps, depth, usr->pass, sizeof(usr->pass));
+
+ /* here begins pointed-to data */
+
+ smb_io_unistr2("uni_user_name ", &(usr->uni_user_name) , usr->hdr_user_name .buffer, ps, depth); /* username unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_full_name ", &(usr->uni_full_name) , usr->hdr_full_name .buffer, ps, depth); /* user's full name unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_home_dir ", &(usr->uni_home_dir) , usr->hdr_home_dir .buffer, ps, depth); /* home directory unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_dir_drive ", &(usr->uni_dir_drive) , usr->hdr_dir_drive .buffer, ps, depth); /* home directory drive unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_logon_script", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_profile_path", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_acct_desc ", &(usr->uni_acct_desc ), usr->hdr_acct_desc .buffer, ps, depth); /* user desc unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_workstations", &(usr->uni_workstations), usr->hdr_workstations.buffer, ps, depth); /* worksations user can log on from */
+ prs_align(ps);
+ smb_io_unistr2("uni_unknown_str ", &(usr->uni_unknown_str ), usr->hdr_unknown_str .buffer, ps, depth); /* unknown string */
+ prs_align(ps);
+ smb_io_unistr2("uni_munged_dial ", &(usr->uni_munged_dial ), usr->hdr_munged_dial .buffer, ps, depth); /* worksations user can log on from */
+ prs_align(ps);
+
+#if 0
+ prs_uint32("unknown_6 ", ps, depth, &(usr->unknown_6 ));
+ prs_uint32("padding4 ", ps, depth, &(usr->padding4 ));
+#endif
+
+ if (usr->ptr_logon_hrs)
+ {
+ sam_io_logon_hrs("logon_hrs", &(usr->logon_hrs) , ps, depth);
+ prs_align(ps);
+ }
return True;
}
+
/*************************************************************************
- init_sam_user_info21
+ make_sam_user_info21W
unknown_3 = 0x00ff ffff
unknown_5 = 0x0002 0000
unknown_6 = 0x0000 04ec
*************************************************************************/
+BOOL make_sam_user_info21W(SAM_USER_INFO_21 *usr,
+
+ const NTTIME *logon_time,
+ const NTTIME *logoff_time,
+ const NTTIME *kickoff_time,
+ const NTTIME *pass_last_set_time,
+ const NTTIME *pass_can_change_time,
+ const NTTIME *pass_must_change_time,
+
+ const UNISTR2 *user_name,
+ const UNISTR2 *full_name,
+ const UNISTR2 *home_dir,
+ const UNISTR2 *dir_drive,
+ const UNISTR2 *log_scr,
+ const UNISTR2 *prof_path,
+ const UNISTR2 *desc,
+ const UNISTR2 *wkstas,
+ const UNISTR2 *unk_str,
+ const UNISTR2 *mung_dial,
+
+ const uchar lm_pwd[16],
+ const uchar nt_pwd[16],
+
+ uint32 user_rid,
+ uint32 group_rid,
+ uint16 acb_info,
+
+ uint32 unknown_3,
+ uint16 logon_divs,
+ const LOGON_HRS *hrs,
+ uint32 unknown_5,
+ uint32 unknown_6)
+{
+ int len_user_name = user_name != NULL ? user_name->uni_str_len : 0;
+ int len_full_name = full_name != NULL ? full_name->uni_str_len : 0;
+ int len_home_dir = home_dir != NULL ? home_dir ->uni_str_len : 0;
+ int len_dir_drive = dir_drive != NULL ? dir_drive->uni_str_len : 0;
+ int len_logon_script = log_scr != NULL ? log_scr ->uni_str_len : 0;
+ int len_profile_path = prof_path != NULL ? prof_path->uni_str_len : 0;
+ int len_description = desc != NULL ? desc ->uni_str_len : 0;
+ int len_workstations = wkstas != NULL ? wkstas ->uni_str_len : 0;
+ int len_unknown_str = unk_str != NULL ? unk_str ->uni_str_len : 0;
+ int len_munged_dial = mung_dial != NULL ? mung_dial->uni_str_len : 0;
+
+ usr->logon_time = *logon_time;
+ usr->logoff_time = *logoff_time;
+ usr->kickoff_time = *kickoff_time;
+ usr->pass_last_set_time = *pass_last_set_time;
+ usr->pass_can_change_time = *pass_can_change_time;
+ usr->pass_must_change_time = *pass_must_change_time;
+
+ make_uni_hdr(&(usr->hdr_user_name ), len_user_name );
+ make_uni_hdr(&(usr->hdr_full_name ), len_full_name );
+ make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir );
+ make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive );
+ make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
+ make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
+ make_uni_hdr(&(usr->hdr_acct_desc ), len_description );
+ make_uni_hdr(&(usr->hdr_workstations), len_workstations);
+ make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str );
+ make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial );
+
+ if (lm_pwd == NULL)
+ {
+ bzero(usr->lm_pwd, sizeof(usr->lm_pwd));
+ }
+ else
+ {
+ memcpy(usr->lm_pwd, lm_pwd, sizeof(usr->lm_pwd));
+ }
+ if (nt_pwd == NULL)
+ {
+ bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
+ }
+ else
+ {
+ memcpy(usr->nt_pwd, nt_pwd, sizeof(usr->nt_pwd));
+ }
+
+ usr->user_rid = user_rid;
+ usr->group_rid = group_rid;
+ usr->acb_info = acb_info;
+ usr->unknown_3 = unknown_3; /* 0x00ff ffff */
+
+ usr->logon_divs = logon_divs; /* should be 168 (hours/week) */
+ usr->ptr_logon_hrs = hrs ? 1 : 0;
+ usr->unknown_5 = unknown_5; /* 0x0002 0000 */
+
+ bzero(usr->padding1, sizeof(usr->padding1));
+
+ copy_unistr2(&(usr->uni_user_name ), user_name);
+ copy_unistr2(&(usr->uni_full_name ), full_name);
+ copy_unistr2(&(usr->uni_home_dir ), home_dir );
+ copy_unistr2(&(usr->uni_dir_drive ), dir_drive);
+ copy_unistr2(&(usr->uni_logon_script), log_scr );
+ copy_unistr2(&(usr->uni_profile_path), prof_path);
+ copy_unistr2(&(usr->uni_acct_desc ), desc );
+ copy_unistr2(&(usr->uni_workstations), wkstas );
+ copy_unistr2(&(usr->uni_unknown_str ), unk_str );
+ copy_unistr2(&(usr->uni_munged_dial ), mung_dial);
+
+ usr->unknown_6 = unknown_6; /* 0x0000 04ec */
+ usr->padding4 = 0;
+
+ if (hrs)
+ {
+ memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
+ }
+ else
+ {
+ memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
+ }
+
+ return True;
+}
+
+/*************************************************************************
+ make_sam_user_info21
+
+ unknown_3 = 0x00ff ffff
+ unknown_5 = 0x0002 0000
+ unknown_6 = 0x0000 04ec
+
+ *************************************************************************/
+BOOL make_sam_user_info21A(SAM_USER_INFO_21 *usr,
-void init_sam_user_info21(SAM_USER_INFO_21 *usr,
NTTIME *logon_time,
NTTIME *logoff_time,
NTTIME *kickoff_time,
@@ -2723,12 +5319,12 @@ void init_sam_user_info21(SAM_USER_INFO_21 *usr,
char *full_name,
char *home_dir,
char *dir_drive,
- char *logon_script,
- char *profile_path,
- char *description,
- char *workstations,
- char *unknown_str,
- char *munged_dial,
+ char *log_scr,
+ char *prof_path,
+ char *desc,
+ char *wkstas,
+ char *unk_str,
+ char *mung_dial,
uint32 user_rid,
uint32 group_rid,
@@ -2740,16 +5336,16 @@ void init_sam_user_info21(SAM_USER_INFO_21 *usr,
uint32 unknown_5,
uint32 unknown_6)
{
- int len_user_name = user_name != NULL ? strlen(user_name ) : 0;
- int len_full_name = full_name != NULL ? strlen(full_name ) : 0;
- int len_home_dir = home_dir != NULL ? strlen(home_dir ) : 0;
- int len_dir_drive = dir_drive != NULL ? strlen(dir_drive ) : 0;
- int len_logon_script = logon_script != NULL ? strlen(logon_script) : 0;
- int len_profile_path = profile_path != NULL ? strlen(profile_path) : 0;
- int len_description = description != NULL ? strlen(description ) : 0;
- int len_workstations = workstations != NULL ? strlen(workstations) : 0;
- int len_unknown_str = unknown_str != NULL ? strlen(unknown_str ) : 0;
- int len_munged_dial = munged_dial != NULL ? strlen(munged_dial ) : 0;
+ int len_user_name = user_name != NULL ? strlen(user_name) : 0;
+ int len_full_name = full_name != NULL ? strlen(full_name) : 0;
+ int len_home_dir = home_dir != NULL ? strlen(home_dir ) : 0;
+ int len_dir_drive = dir_drive != NULL ? strlen(dir_drive) : 0;
+ int len_logon_script = log_scr != NULL ? strlen(log_scr ) : 0;
+ int len_profile_path = prof_path != NULL ? strlen(prof_path) : 0;
+ int len_description = desc != NULL ? strlen(desc ) : 0;
+ int len_workstations = wkstas != NULL ? strlen(wkstas ) : 0;
+ int len_unknown_str = unk_str != NULL ? strlen(unk_str ) : 0;
+ int len_munged_dial = mung_dial != NULL ? strlen(mung_dial) : 0;
usr->logon_time = *logon_time;
usr->logoff_time = *logoff_time;
@@ -2758,19 +5354,19 @@ void init_sam_user_info21(SAM_USER_INFO_21 *usr,
usr->pass_can_change_time = *pass_can_change_time;
usr->pass_must_change_time = *pass_must_change_time;
- init_uni_hdr(&usr->hdr_user_name, len_user_name);
- init_uni_hdr(&usr->hdr_full_name, len_full_name);
- init_uni_hdr(&usr->hdr_home_dir, len_home_dir);
- init_uni_hdr(&usr->hdr_dir_drive, len_dir_drive);
- init_uni_hdr(&usr->hdr_logon_script, len_logon_script);
- init_uni_hdr(&usr->hdr_profile_path, len_profile_path);
- init_uni_hdr(&usr->hdr_acct_desc, len_description);
- init_uni_hdr(&usr->hdr_workstations, len_workstations);
- init_uni_hdr(&usr->hdr_unknown_str, len_unknown_str);
- init_uni_hdr(&usr->hdr_munged_dial, len_munged_dial);
+ make_uni_hdr(&(usr->hdr_user_name ), len_user_name );
+ make_uni_hdr(&(usr->hdr_full_name ), len_full_name );
+ make_uni_hdr(&(usr->hdr_home_dir ), len_home_dir );
+ make_uni_hdr(&(usr->hdr_dir_drive ), len_dir_drive );
+ make_uni_hdr(&(usr->hdr_logon_script), len_logon_script);
+ make_uni_hdr(&(usr->hdr_profile_path), len_profile_path);
+ make_uni_hdr(&(usr->hdr_acct_desc ), len_description );
+ make_uni_hdr(&(usr->hdr_workstations), len_workstations);
+ make_uni_hdr(&(usr->hdr_unknown_str ), len_unknown_str );
+ make_uni_hdr(&(usr->hdr_munged_dial ), len_munged_dial );
- memset((char *)usr->nt_pwd, '\0', sizeof(usr->nt_pwd));
- memset((char *)usr->lm_pwd, '\0', sizeof(usr->lm_pwd));
+ bzero(usr->nt_pwd, sizeof(usr->nt_pwd));
+ bzero(usr->lm_pwd, sizeof(usr->lm_pwd));
usr->user_rid = user_rid;
usr->group_rid = group_rid;
@@ -2781,658 +5377,835 @@ void init_sam_user_info21(SAM_USER_INFO_21 *usr,
usr->ptr_logon_hrs = hrs ? 1 : 0;
usr->unknown_5 = unknown_5; /* 0x0002 0000 */
- memset((char *)usr->padding1, '\0', sizeof(usr->padding1));
+ bzero(usr->padding1, sizeof(usr->padding1));
- init_unistr2(&usr->uni_user_name, user_name, len_user_name);
- init_unistr2(&usr->uni_full_name, full_name, len_full_name);
- init_unistr2(&usr->uni_home_dir, home_dir, len_home_dir);
- init_unistr2(&usr->uni_dir_drive, dir_drive, len_dir_drive);
- init_unistr2(&usr->uni_logon_script, logon_script, len_logon_script);
- init_unistr2(&usr->uni_profile_path, profile_path, len_profile_path);
- init_unistr2(&usr->uni_acct_desc, description, len_description);
- init_unistr2(&usr->uni_workstations, workstations, len_workstations);
- init_unistr2(&usr->uni_unknown_str, unknown_str, len_unknown_str);
- init_unistr2(&usr->uni_munged_dial, munged_dial, len_munged_dial);
+ make_unistr2(&(usr->uni_user_name ), user_name , len_user_name );
+ make_unistr2(&(usr->uni_full_name ), full_name , len_full_name );
+ make_unistr2(&(usr->uni_home_dir ), home_dir , len_home_dir );
+ make_unistr2(&(usr->uni_dir_drive ), dir_drive , len_dir_drive );
+ make_unistr2(&(usr->uni_logon_script), log_scr, len_logon_script);
+ make_unistr2(&(usr->uni_profile_path), prof_path, len_profile_path);
+ make_unistr2(&(usr->uni_acct_desc ), desc , len_description );
+ make_unistr2(&(usr->uni_workstations), wkstas, len_workstations);
+ make_unistr2(&(usr->uni_unknown_str ), unk_str , len_unknown_str );
+ make_unistr2(&(usr->uni_munged_dial ), mung_dial , len_munged_dial );
usr->unknown_6 = unknown_6; /* 0x0000 04ec */
usr->padding4 = 0;
if (hrs)
+ {
memcpy(&(usr->logon_hrs), hrs, sizeof(usr->logon_hrs));
+ }
else
+ {
memset(&(usr->logon_hrs), 0xff, sizeof(usr->logon_hrs));
+ }
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *ps, int depth)
+BOOL sam_io_user_info21(char *desc, SAM_USER_INFO_21 *usr, prs_struct *ps, int depth)
{
- if (usr == NULL)
- return False;
+ if (usr == NULL) return False;
- prs_debug(ps, depth, desc, "lsa_io_user_info");
+ prs_debug(ps, depth, desc, "sam_io_user_info21");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_time("logon_time ", &usr->logon_time, ps, depth))
- return False;
- if(!smb_io_time("logoff_time ", &usr->logoff_time, ps, depth))
- return False;
- if(!smb_io_time("kickoff_time ", &usr->kickoff_time, ps, depth))
- return False;
- if(!smb_io_time("pass_last_set_time ", &usr->pass_last_set_time, ps, depth))
- return False;
- if(!smb_io_time("pass_can_change_time ", &usr->pass_can_change_time, ps, depth))
- return False;
- if(!smb_io_time("pass_must_change_time", &usr->pass_must_change_time, ps, depth))
- return False;
-
- if(!smb_io_unihdr("hdr_user_name ", &usr->hdr_user_name, ps, depth)) /* username unicode string header */
- return False;
- if(!smb_io_unihdr("hdr_full_name ", &usr->hdr_full_name, ps, depth)) /* user's full name unicode string header */
- return False;
- if(!smb_io_unihdr("hdr_home_dir ", &usr->hdr_home_dir, ps, depth)) /* home directory unicode string header */
- return False;
- if(!smb_io_unihdr("hdr_dir_drive ", &usr->hdr_dir_drive, ps, depth)) /* home directory drive */
- return False;
- if(!smb_io_unihdr("hdr_logon_script", &usr->hdr_logon_script, ps, depth)) /* logon script unicode string header */
- return False;
- if(!smb_io_unihdr("hdr_profile_path", &usr->hdr_profile_path, ps, depth)) /* profile path unicode string header */
- return False;
- if(!smb_io_unihdr("hdr_acct_desc ", &usr->hdr_acct_desc, ps, depth)) /* account description */
- return False;
- if(!smb_io_unihdr("hdr_workstations", &usr->hdr_workstations, ps, depth)) /* workstations user can log on from */
- return False;
- if(!smb_io_unihdr("hdr_unknown_str ", &usr->hdr_unknown_str, ps, depth)) /* unknown string */
- return False;
- if(!smb_io_unihdr("hdr_munged_dial ", &usr->hdr_munged_dial, ps, depth)) /* workstations user can log on from */
- return False;
-
- if(!prs_uint8s (False, "lm_pwd ", ps, depth, usr->lm_pwd, sizeof(usr->lm_pwd)))
- return False;
- if(!prs_uint8s (False, "nt_pwd ", ps, depth, usr->nt_pwd, sizeof(usr->nt_pwd)))
- return False;
-
- if(!prs_uint32("user_rid ", ps, depth, &usr->user_rid)) /* User ID */
- return False;
- if(!prs_uint32("group_rid ", ps, depth, &usr->group_rid)) /* Group ID */
- return False;
- if(!prs_uint16("acb_info ", ps, depth, &usr->acb_info)) /* Group ID */
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_time("logon_time ", &(usr->logon_time) , ps, depth);
+ smb_io_time("logoff_time ", &(usr->logoff_time) , ps, depth);
+ smb_io_time("kickoff_time ", &(usr->kickoff_time) , ps, depth);
+ smb_io_time("pass_last_set_time ", &(usr->pass_last_set_time) , ps, depth);
+ smb_io_time("pass_can_change_time ", &(usr->pass_can_change_time) , ps, depth);
+ smb_io_time("pass_must_change_time", &(usr->pass_must_change_time), ps, depth);
+
+ smb_io_unihdr("hdr_user_name ", &(usr->hdr_user_name) , ps, depth); /* username unicode string header */
+ smb_io_unihdr("hdr_full_name ", &(usr->hdr_full_name) , ps, depth); /* user's full name unicode string header */
+ smb_io_unihdr("hdr_home_dir ", &(usr->hdr_home_dir) , ps, depth); /* home directory unicode string header */
+ smb_io_unihdr("hdr_dir_drive ", &(usr->hdr_dir_drive) , ps, depth); /* home directory drive */
+ smb_io_unihdr("hdr_logon_script", &(usr->hdr_logon_script), ps, depth); /* logon script unicode string header */
+ smb_io_unihdr("hdr_profile_path", &(usr->hdr_profile_path), ps, depth); /* profile path unicode string header */
+ smb_io_unihdr("hdr_acct_desc ", &(usr->hdr_acct_desc ) , ps, depth); /* account desc */
+ smb_io_unihdr("hdr_workstations", &(usr->hdr_workstations), ps, depth); /* wkstas user can log on from */
+ smb_io_unihdr("hdr_unknown_str ", &(usr->hdr_unknown_str ), ps, depth); /* unknown string */
+ smb_io_unihdr("hdr_munged_dial ", &(usr->hdr_munged_dial ), ps, depth); /* wkstas user can log on from */
+
+ prs_uint8s (False, "lm_pwd ", ps, depth, usr->lm_pwd , sizeof(usr->lm_pwd ));
+ prs_uint8s (False, "nt_pwd ", ps, depth, usr->nt_pwd , sizeof(usr->nt_pwd ));
+
+ prs_uint32("user_rid ", ps, depth, &(usr->user_rid )); /* User ID */
+ prs_uint32("group_rid ", ps, depth, &(usr->group_rid )); /* Group ID */
+ prs_uint16("acb_info ", ps, depth, &(usr->acb_info )); /* Group ID */
+ prs_align(ps);
- if(!prs_uint32("unknown_3 ", ps, depth, &usr->unknown_3))
- return False;
- if(!prs_uint16("logon_divs ", ps, depth, &usr->logon_divs)) /* logon divisions per week */
- return False;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("ptr_logon_hrs ", ps, depth, &usr->ptr_logon_hrs))
- return False;
- if(!prs_uint32("unknown_5 ", ps, depth, &usr->unknown_5))
- return False;
+ prs_uint32("unknown_3 ", ps, depth, &(usr->unknown_3 ));
+ prs_uint16("logon_divs ", ps, depth, &(usr->logon_divs )); /* logon divisions per week */
+ prs_align(ps);
+ prs_uint32("ptr_logon_hrs ", ps, depth, &(usr->ptr_logon_hrs));
+ prs_uint32("unknown_5 ", ps, depth, &(usr->unknown_5 ));
- if(!prs_uint8s (False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1)))
- return False;
+ prs_uint8s (False, "padding1 ", ps, depth, usr->padding1, sizeof(usr->padding1));
/* here begins pointed-to data */
- if(!smb_io_unistr2("uni_user_name ", &usr->uni_user_name, usr->hdr_user_name.buffer, ps, depth)) /* username unicode string */
- return False;
- if(!smb_io_unistr2("uni_full_name ", &usr->uni_full_name, usr->hdr_full_name.buffer, ps, depth)) /* user's full name unicode string */
- return False;
- if(!smb_io_unistr2("uni_home_dir ", &usr->uni_home_dir, usr->hdr_home_dir.buffer, ps, depth)) /* home directory unicode string */
- return False;
- if(!smb_io_unistr2("uni_dir_drive ", &usr->uni_dir_drive, usr->hdr_dir_drive.buffer, ps, depth)) /* home directory drive unicode string */
- return False;
- if(!smb_io_unistr2("uni_logon_script", &usr->uni_logon_script, usr->hdr_logon_script.buffer, ps, depth)) /* logon script unicode string */
- return False;
- if(!smb_io_unistr2("uni_profile_path", &usr->uni_profile_path, usr->hdr_profile_path.buffer, ps, depth)) /* profile path unicode string */
- return False;
- if(!smb_io_unistr2("uni_acct_desc ", &usr->uni_acct_desc, usr->hdr_acct_desc.buffer, ps, depth)) /* user description unicode string */
- return False;
- if(!smb_io_unistr2("uni_workstations", &usr->uni_workstations, usr->hdr_workstations.buffer, ps, depth)) /* worksations user can log on from */
- return False;
- if(!smb_io_unistr2("uni_unknown_str ", &usr->uni_unknown_str, usr->hdr_unknown_str .buffer, ps, depth)) /* unknown string */
- return False;
- if(!smb_io_unistr2("uni_munged_dial ", &usr->uni_munged_dial, usr->hdr_munged_dial .buffer, ps, depth)) /* worksations user can log on from */
- return False;
+ smb_io_unistr2("uni_user_name ", &(usr->uni_user_name) , usr->hdr_user_name .buffer, ps, depth); /* username unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_full_name ", &(usr->uni_full_name) , usr->hdr_full_name .buffer, ps, depth); /* user's full name unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_home_dir ", &(usr->uni_home_dir) , usr->hdr_home_dir .buffer, ps, depth); /* home directory unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_dir_drive ", &(usr->uni_dir_drive) , usr->hdr_dir_drive .buffer, ps, depth); /* home directory drive unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_logon_script", &(usr->uni_logon_script), usr->hdr_logon_script.buffer, ps, depth); /* logon script unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_profile_path", &(usr->uni_profile_path), usr->hdr_profile_path.buffer, ps, depth); /* profile path unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_acct_desc ", &(usr->uni_acct_desc ), usr->hdr_acct_desc .buffer, ps, depth); /* user desc unicode string */
+ prs_align(ps);
+ smb_io_unistr2("uni_workstations", &(usr->uni_workstations), usr->hdr_workstations.buffer, ps, depth); /* worksations user can log on from */
+ prs_align(ps);
+ smb_io_unistr2("uni_unknown_str ", &(usr->uni_unknown_str ), usr->hdr_unknown_str .buffer, ps, depth); /* unknown string */
+ prs_align(ps);
+ smb_io_unistr2("uni_munged_dial ", &(usr->uni_munged_dial ), usr->hdr_munged_dial .buffer, ps, depth); /* worksations user can log on from */
+ prs_align(ps);
- if(!prs_uint32("unknown_6 ", ps, depth, &usr->unknown_6))
- return False;
- if(!prs_uint32("padding4 ", ps, depth, &usr->padding4))
- return False;
+ prs_uint32("unknown_6 ", ps, depth, &(usr->unknown_6 ));
+ prs_uint32("padding4 ", ps, depth, &(usr->padding4 ));
- if (usr->ptr_logon_hrs) {
- if(!sam_io_logon_hrs("logon_hrs", &usr->logon_hrs, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ if (usr->ptr_logon_hrs)
+ {
+ sam_io_logon_hrs("logon_hrs", &(usr->logon_hrs) , ps, depth);
+ prs_align(ps);
}
return True;
}
/*******************************************************************
- Inits a SAMR_R_QUERY_USERINFO structure.
+makes a SAM_USERINFO_CTR structure.
********************************************************************/
-
-void init_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
- uint16 switch_value, void *info, uint32 status)
+uint32 make_samr_userinfo_ctr_usr21(SAM_USERINFO_CTR *ctr,
+ uint16 switch_value,
+ const SAM_USER_INFO_21 *usr)
{
- DEBUG(5,("init_samr_r_query_userinfo\n"));
+ if (ctr == NULL || usr == NULL) return NT_STATUS_INVALID_PARAMETER;
- r_u->ptr = 0;
- r_u->switch_value = 0;
+ DEBUG(5,("make_samr_userinfo_ctr\n"));
- if (status == 0) {
- r_u->switch_value = switch_value;
+ ctr->switch_value = switch_value;
+ ctr->info.id = NULL;
- switch (switch_value) {
+ switch (switch_value)
+ {
case 0x10:
- r_u->ptr = 1;
- r_u->info.id10 = (SAM_USER_INFO_10*)info;
+ {
+ ctr->info.id = (SAM_USER_INFO_10*)Realloc(NULL,
+ sizeof(*ctr->info.id10));
+ if (ctr->info.id == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+ make_sam_user_info10(ctr->info.id10, usr->acb_info);
break;
-
+ }
+#if 0
+/* whoops - got this wrong. i think. or don't understand what's happening. */
case 0x11:
- r_u->ptr = 1;
- r_u->info.id11 = (SAM_USER_INFO_11*)info;
- break;
+ {
+ NTTIME expire;
+ info = (void*)&id11;
+
+ expire.low = 0xffffffff;
+ expire.high = 0x7fffffff;
+
+ ctr->info.id = (SAM_USER_INFO_11*)Realloc(NULL,
+ sizeof(*ctr->info.id11));
+ make_sam_user_info11(ctr->info.id11, &expire,
+ "BROOKFIELDS$", /* name */
+ 0x03ef, /* user rid */
+ 0x201, /* group rid */
+ 0x0080); /* acb info */
+ break;
+ }
+#endif
+ case 0x12:
+ {
+ ctr->info.id = (SAM_USER_INFO_12*)Realloc(NULL,
+ sizeof(*ctr->info.id12));
+ if (ctr->info.id == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (IS_BITS_SET_ALL(usr->acb_info, ACB_DISABLED))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ make_sam_user_info12(ctr->info.id12,
+ usr->acb_info,
+ usr->lm_pwd, usr->nt_pwd);
+ break;
+ }
case 21:
- r_u->ptr = 1;
- r_u->info.id21 = (SAM_USER_INFO_21*)info;
+ {
+ SAM_USER_INFO_21 *cusr;
+ cusr = (SAM_USER_INFO_21*)Realloc(NULL,
+ sizeof(*cusr));
+ ctr->info.id = cusr;
+ if (ctr->info.id == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+ memcpy(cusr, usr, sizeof(*usr));
+ memset(cusr->lm_pwd, 0, sizeof(cusr->lm_pwd));
+ memset(cusr->nt_pwd, 0, sizeof(cusr->nt_pwd));
break;
-
+ }
default:
- DEBUG(4,("init_samr_r_query_aliasinfo: unsupported switch level\n"));
- break;
+ {
+ DEBUG(4,("make_samr_userinfo_ctr: unsupported info\n"));
+ return NT_STATUS_INVALID_INFO_CLASS;
}
}
- r_u->status = status; /* return status */
+ return NT_STATUS_NOPROBLEMO;
}
/*******************************************************************
- Reads or writes a structure.
+makes a SAM_USERINFO_CTR structure.
********************************************************************/
+BOOL make_samr_userinfo_ctr(SAM_USERINFO_CTR *ctr, const uchar *sess_key,
+ uint16 switch_value, void *info)
+{
+ if (ctr == NULL) return False;
-BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth)
+ DEBUG(5,("make_samr_userinfo_ctr\n"));
+
+ ctr->switch_value = switch_value;
+ ctr->info.id = info;
+
+ switch (switch_value)
+ {
+ case 0x18:
+ {
+ SamOEMhash(ctr->info.id24->pass, sess_key, 1);
+ dump_data_pw("sess_key", sess_key, 16);
+ dump_data_pw("passwd", ctr->info.id24->pass, 516);
+ break;
+ }
+ case 0x17:
+ {
+ SamOEMhash(ctr->info.id23->pass, sess_key, 1);
+ dump_data_pw("sess_key", sess_key, 16);
+ dump_data_pw("passwd", ctr->info.id23->pass, 516);
+ break;
+ }
+ default:
+ {
+ DEBUG(4,("make_samr_userinfo_ctr: unsupported switch level\n"));
+ return False;
+ }
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_userinfo_ctr(char *desc, SAM_USERINFO_CTR *ctr, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (ctr == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_query_userinfo");
+ prs_debug(ps, depth, desc, "samr_io_userinfo_ctr");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr ", ps, depth, &r_u->ptr))
- return False;
- if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint16("switch_value", ps, depth, &(ctr->switch_value));
+ prs_align(ps);
- if (r_u->ptr != 0 && r_u->switch_value != 0) {
- switch (r_u->switch_value) {
+ switch (ctr->switch_value)
+ {
case 0x10:
- if (r_u->info.id10 != NULL) {
- if(!sam_io_user_info10("", r_u->info.id10, ps, depth))
- return False;
- } else {
- DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
+ {
+ if (ps->io)
+ {
+ /* reading */
+ ctr->info.id = (SAM_USER_INFO_10*)Realloc(NULL,
+ sizeof(*ctr->info.id10));
+ }
+ if (ctr->info.id10 != NULL)
+ {
+ sam_io_user_info10("", ctr->info.id10, ps, depth);
+ }
+ else
+ {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
return False;
}
break;
-/*
+ }
case 0x11:
- if (r_u->info.id11 != NULL) {
- if(!sam_io_user_info11("", r_u->info.id11, ps, depth))
- return False;
- } else {
- DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
+ {
+ if (ps->io)
+ {
+ /* reading */
+ ctr->info.id = (SAM_USER_INFO_11*)Realloc(NULL,
+ sizeof(*ctr->info.id11));
+ }
+ if (ctr->info.id11 != NULL)
+ {
+ sam_io_user_info11("", ctr->info.id11, ps, depth);
+ }
+ else
+ {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ break;
+ }
+ case 0x12:
+ {
+ DEBUG(0,("samr_io_userinfo_ctr: security breach!\n"));
+ return False;
+#if 0
+ if (ps->io)
+ {
+ /* reading */
+ ctr->info.id = (SAM_USER_INFO_12*)Realloc(NULL,
+ sizeof(*ctr->info.id12));
+ }
+ if (ctr->info.id12 != NULL)
+ {
+ sam_io_user_info12("", ctr->info.id12, ps, depth);
+ }
+ else
+ {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
return False;
}
break;
-*/
+#endif
+ }
case 21:
- if (r_u->info.id21 != NULL) {
- if(!sam_io_user_info21("", r_u->info.id21, ps, depth))
- return False;
- } else {
- DEBUG(2,("samr_io_r_query_userinfo: info pointer not initialised\n"));
+ {
+ if (ps->io)
+ {
+ /* reading */
+ ctr->info.id = (SAM_USER_INFO_21*)Realloc(NULL,
+ sizeof(*ctr->info.id21));
+ }
+ if (ctr->info.id21 != NULL)
+ {
+ sam_io_user_info21("", ctr->info.id21, ps, depth);
+ }
+ else
+ {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
return False;
}
break;
+ }
+ case 23:
+ {
+ if (ps->io)
+ {
+ /* reading */
+ ctr->info.id = (SAM_USER_INFO_23*)Realloc(NULL,
+ sizeof(*ctr->info.id23));
+ }
+ if (ctr->info.id23 != NULL)
+ {
+ sam_io_user_info23("", ctr->info.id23, ps, depth);
+ }
+ else
+ {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ break;
+ }
+ case 24:
+ {
+ if (ps->io)
+ {
+ /* reading */
+ ctr->info.id = (SAM_USER_INFO_24*)Realloc(NULL,
+ sizeof(*ctr->info.id24));
+ }
+ if (ctr->info.id24 != NULL)
+ {
+ sam_io_user_info24("", ctr->info.id24, ps, depth);
+ }
+ else
+ {
+ DEBUG(2,("samr_io_userinfo_ctr: info pointer not initialised\n"));
+ return False;
+ }
+ break;
+ }
default:
- DEBUG(2,("samr_io_r_query_userinfo: unknown switch level\n"));
+ {
+ DEBUG(2,("samr_io_userinfo_ctr: unknown switch level\n"));
break;
}
+
}
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_align(ps);
return True;
}
/*******************************************************************
- Reads or writes a structure.
+frees a structure.
********************************************************************/
-
-BOOL samr_io_q_unknown_32(char *desc, SAMR_Q_UNKNOWN_32 *q_u, prs_struct *ps, int depth)
+void free_samr_userinfo_ctr(SAM_USERINFO_CTR *ctr)
{
- if (q_u == NULL)
- return False;
+ if (ctr->info.id == NULL)
+ {
+ free(ctr->info.id);
+ }
+ ctr->info.id = NULL;
+}
- prs_debug(ps, depth, desc, "samr_io_q_unknown_32");
- depth++;
- if(!prs_align(ps))
- return False;
+/*******************************************************************
+makes a SAMR_R_QUERY_USERINFO structure.
+********************************************************************/
+BOOL make_samr_r_query_userinfo(SAMR_R_QUERY_USERINFO *r_u,
+ SAM_USERINFO_CTR *ctr, uint32 status)
+
+{
+ if (r_u == NULL) return False;
- if(!smb_io_pol_hnd("pol", &q_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ DEBUG(5,("make_samr_r_query_userinfo\n"));
- if(!smb_io_unihdr ("", &q_u->hdr_mach_acct, ps, depth))
- return False;
- if(!smb_io_unistr2("", &q_u->uni_mach_acct, q_u->hdr_mach_acct.buffer, ps, depth))
- return False;
+ r_u->ptr = 0;
+ r_u->ctr = NULL;
- if(!prs_align(ps))
- return False;
+ if (status == 0)
+ {
+ r_u->ptr = 1;
+ r_u->ctr = ctr;
+ }
- if(!prs_uint32("acct_ctrl", ps, depth, &q_u->acct_ctrl))
- return False;
- if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
- return False;
- if(!prs_uint16("unknown_2", ps, depth, &q_u->unknown_2))
- return False;
+ r_u->status = status; /* return status */
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_r_unknown_32(char *desc, SAMR_R_UNKNOWN_32 *r_u, prs_struct *ps, int depth)
+BOOL samr_io_r_query_userinfo(char *desc, SAMR_R_QUERY_USERINFO *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_unknown_32");
+ prs_debug(ps, depth, desc, "samr_io_r_query_userinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint32("ptr", ps, depth, &(r_u->ptr));
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ if (r_u->ptr != 0)
+ {
+ samr_io_userinfo_ctr("ctr", r_u->ctr, ps, depth);
+ }
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+ if (!ps->io)
+ {
+ /* writing */
+ if (r_u->ctr != NULL)
+ {
+ free_samr_userinfo_ctr(r_u->ctr);
+ }
+ }
return True;
}
/*******************************************************************
- Inits a SAMR_Q_CONNECT structure.
+makes a SAMR_Q_SET_USERINFO structure.
********************************************************************/
-
-void init_samr_q_connect(SAMR_Q_CONNECT *q_u,
- char *srv_name, uint32 unknown_0)
+BOOL make_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u,
+ POLICY_HND *hnd,
+ uint16 switch_value, void *info)
{
- int len_srv_name = strlen(srv_name);
+ uchar sess_key[16];
+ if (q_u == NULL || hnd == NULL) return False;
- DEBUG(5,("init_q_connect\n"));
+ DEBUG(5,("make_samr_q_set_userinfo\n"));
- /* make PDC server name \\server */
- q_u->ptr_srv_name = len_srv_name > 0 ? 1 : 0;
- init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name+1);
+ memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
+ q_u->switch_value = switch_value;
- /* example values: 0x0000 0002 */
- q_u->unknown_0 = unknown_0;
+ if (!cli_get_usr_sesskey(hnd, sess_key))
+ {
+ DEBUG(0,("make_samr_set_userinfo: could not obtain session key\n"));
+ return False;
+ }
+ if (!make_samr_userinfo_ctr(q_u->ctr, sess_key, switch_value, info))
+ {
+ return False;
+ }
+
+ return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth)
+BOOL samr_io_q_set_userinfo(char *desc, SAMR_Q_SET_USERINFO *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_connect");
+ prs_debug(ps, depth, desc, "samr_io_q_set_userinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
- return False;
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
+ prs_uint16("switch_value", ps, depth, &(q_u->switch_value));
+ samr_io_userinfo_ctr("ctr", q_u->ctr, ps, depth);
- if(!prs_uint32("unknown_0 ", ps, depth, &q_u->unknown_0))
- return False;
+ if (!ps->io)
+ {
+ /* writing */
+ free_samr_q_set_userinfo(q_u);
+ }
return True;
}
/*******************************************************************
- Reads or writes a structure.
+frees a structure.
********************************************************************/
-
-BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT *r_u, prs_struct *ps, int depth)
+void free_samr_q_set_userinfo(SAMR_Q_SET_USERINFO *q_u)
{
- if (r_u == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "samr_io_r_connect");
- depth++;
+ free_samr_userinfo_ctr(q_u->ctr);
+}
- if(!prs_align(ps))
- return False;
+/*******************************************************************
+makes a SAMR_R_SET_USERINFO structure.
+********************************************************************/
+BOOL make_samr_r_set_userinfo(SAMR_R_SET_USERINFO *r_u, uint32 status)
+
+{
+ if (r_u == NULL) return False;
- if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ DEBUG(5,("make_samr_r_set_userinfo\n"));
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ r_u->status = status; /* return status */
return True;
}
/*******************************************************************
- Inits a SAMR_Q_CONNECT_ANON structure.
+reads or writes a structure.
********************************************************************/
-
-void init_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u)
+BOOL samr_io_r_set_userinfo(char *desc, SAMR_R_SET_USERINFO *r_u, prs_struct *ps, int depth)
{
- DEBUG(5,("init_q_connect_anon\n"));
+ if (r_u == NULL) return False;
- q_u->ptr = 1;
- q_u->unknown_0 = 0x5c; /* server name (?!!) */
- q_u->unknown_1 = 0x01;
- q_u->unknown_2 = 0x20;
+ prs_debug(ps, depth, desc, "samr_io_r_set_userinfo");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+makes a SAMR_Q_SET_USERINFO2 structure.
********************************************************************/
-
-BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth)
+BOOL make_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u,
+ POLICY_HND *hnd,
+ uint16 switch_value,
+ SAM_USERINFO_CTR *ctr)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL || hnd == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_connect_anon");
- depth++;
+ DEBUG(5,("make_samr_q_set_userinfo2\n"));
- if(!prs_align(ps))
- return False;
+ memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
+ q_u->switch_value = switch_value;
+ q_u->ctr = ctr;
- if(!prs_uint32("ptr ", ps, depth, &q_u->ptr))
- return False;
- if(!prs_uint16("unknown_0", ps, depth, &q_u->unknown_0))
- return False;
- if(!prs_uint16("unknown_1", ps, depth, &q_u->unknown_1))
- return False;
- if(!prs_uint32("unknown_2", ps, depth, &q_u->unknown_2))
- return False;
+ if (q_u->ctr != NULL)
+ {
+ q_u->ctr->switch_value = switch_value;
+ }
return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth)
+BOOL samr_io_q_set_userinfo2(char *desc, SAMR_Q_SET_USERINFO2 *q_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_connect_anon");
+ prs_debug(ps, depth, desc, "samr_io_q_set_userinfo2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_pol_hnd("pol", &(q_u->pol), ps, depth);
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint16("switch_value ", ps, depth, &(q_u->switch_value ));
+ samr_io_userinfo_ctr("ctr", q_u->ctr, ps, depth);
+
+ if (!ps->io)
+ {
+ /* writing */
+ free_samr_q_set_userinfo2(q_u);
+ }
return True;
}
/*******************************************************************
- Inits a SAMR_Q_OPEN_ALIAS structure.
+frees a structure.
********************************************************************/
-void init_samr_q_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
- uint32 unknown_0, uint32 rid)
+void free_samr_q_set_userinfo2(SAMR_Q_SET_USERINFO2 *q_u)
{
- DEBUG(5,("init_q_open_alias\n"));
+ free_samr_userinfo_ctr(q_u->ctr);
+}
- /* example values: 0x0000 0008 */
- q_u->unknown_0 = unknown_0;
+/*******************************************************************
+makes a SAMR_R_SET_USERINFO2 structure.
+********************************************************************/
+BOOL make_samr_r_set_userinfo2(SAMR_R_SET_USERINFO2 *r_u,
+ uint32 status)
+{
+ if (r_u == NULL) return False;
- q_u->rid_alias = rid;
+ DEBUG(5,("make_samr_r_set_userinfo2\n"));
+
+ r_u->status = status; /* return status */
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_q_open_alias(char *desc, SAMR_Q_OPEN_ALIAS *q_u, prs_struct *ps, int depth)
+BOOL samr_io_r_set_userinfo2(char *desc, SAMR_R_SET_USERINFO2 *r_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_q_open_alias");
+ prs_debug(ps, depth, desc, "samr_io_r_set_userinfo2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("unknown_0", ps, depth, &q_u->unknown_0))
- return False;
- if(!prs_uint32("rid_alias", ps, depth, &q_u->rid_alias))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+makes a SAMR_Q_CONNECT structure.
********************************************************************/
+BOOL make_samr_q_connect(SAMR_Q_CONNECT *q_u,
+ const char *srv_name, uint32 access_mask)
+{
+ int len_srv_name = strlen(srv_name);
-BOOL samr_io_r_open_alias(char *desc, SAMR_R_OPEN_ALIAS *r_u, prs_struct *ps, int depth)
+ if (q_u == NULL) return False;
+
+ DEBUG(5,("make_samr_q_connect\n"));
+
+ /* make PDC server name \\server */
+ q_u->ptr_srv_name = len_srv_name > 0 ? 1 : 0;
+ make_unistr2(&(q_u->uni_srv_name), srv_name, len_srv_name+1);
+
+ /* example values: 0x0000 0002 */
+ q_u->access_mask = access_mask;
+
+ return True;
+}
+
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL samr_io_q_connect(char *desc, SAMR_Q_CONNECT *q_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_open_alias");
+ prs_debug(ps, depth, desc, "samr_io_q_connect");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_pol_hnd("pol", &r_u->pol, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint32("ptr_srv_name", ps, depth, &(q_u->ptr_srv_name));
+ smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps, depth);
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_align(ps);
+
+ prs_uint32("access_mask", ps, depth, &(q_u->access_mask));
return True;
}
/*******************************************************************
- Inits a SAMR_Q_UNKNOWN_12 structure.
+reads or writes a structure.
********************************************************************/
-
-void init_samr_q_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
- POLICY_HND *pol, uint32 rid,
- uint32 num_gids, uint32 *gid)
+BOOL samr_io_r_connect(char *desc, SAMR_R_CONNECT *r_u, prs_struct *ps, int depth)
{
- int i;
+ if (r_u == NULL) return False;
- DEBUG(5,("init_samr_r_unknwon_12\n"));
+ prs_debug(ps, depth, desc, "samr_io_r_connect");
+ depth++;
- memcpy(&q_u->pol, pol, sizeof(*pol));
+ prs_align(ps);
- q_u->num_gids1 = num_gids;
- q_u->rid = rid;
- q_u->ptr = 0;
- q_u->num_gids2 = num_gids;
+ smb_io_pol_hnd("connect_pol", &(r_u->connect_pol), ps, depth);
+ prs_align(ps);
- for (i = 0; i < num_gids; i++) {
- q_u->gid[i] = gid[i];
- }
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
}
/*******************************************************************
- Inits a SAMR_Q_UNKNOWN_21 structure.
+makes a SAMR_Q_CONNECT_ANON structure.
********************************************************************/
-
-void init_samr_q_unknown_21(SAMR_Q_UNKNOWN_21 *q_c,
- POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
+BOOL make_samr_q_connect_anon(SAMR_Q_CONNECT_ANON *q_u)
{
- DEBUG(5,("init_samr_q_unknown_21\n"));
+ if (q_u == NULL) return False;
- memcpy(&q_c->group_pol, hnd, sizeof(q_c->group_pol));
- q_c->unknown_1 = unk_1;
- q_c->unknown_2 = unk_2;
+ DEBUG(5,("make_samr_q_connect_anon\n"));
+
+ q_u->ptr = 1;
+ q_u->unknown_0 = 0x5c; /* server name (?!!) */
+ q_u->unknown_1 = 0x01;
+ q_u->access_mask = 0x20;
+
+ return True;
}
/*******************************************************************
- Inits a SAMR_Q_UNKNOWN_13 structure.
+reads or writes a structure.
********************************************************************/
-
-void init_samr_q_unknown_13(SAMR_Q_UNKNOWN_13 *q_c,
- POLICY_HND *hnd, uint16 unk_1, uint16 unk_2)
+BOOL samr_io_q_connect_anon(char *desc, SAMR_Q_CONNECT_ANON *q_u, prs_struct *ps, int depth)
{
- DEBUG(5,("init_samr_q_unknown_13\n"));
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_connect_anon");
+ depth++;
- memcpy(&q_c->alias_pol, hnd, sizeof(q_c->alias_pol));
- q_c->unknown_1 = unk_1;
- q_c->unknown_2 = unk_2;
+ prs_align(ps);
+
+ prs_uint32("ptr ", ps, depth, &(q_u->ptr ));
+ prs_uint16("unknown_0", ps, depth, &(q_u->unknown_0));
+ prs_uint16("unknown_1", ps, depth, &(q_u->unknown_1));
+ prs_uint32("access_mask", ps, depth, &(q_u->access_mask));
+
+ return True;
}
/*******************************************************************
- Inits a SAMR_Q_UNKNOWN_38 structure.
+reads or writes a structure.
********************************************************************/
-void init_samr_q_unknown_38(SAMR_Q_UNKNOWN_38 *q_u, char *srv_name)
+BOOL samr_io_r_connect_anon(char *desc, SAMR_R_CONNECT_ANON *r_u, prs_struct *ps, int depth)
{
- int len_srv_name = strlen(srv_name);
+ if (r_u == NULL) return False;
- DEBUG(5,("init_q_unknown_38\n"));
+ prs_debug(ps, depth, desc, "samr_io_r_connect_anon");
+ depth++;
- q_u->ptr = 1;
- init_uni_hdr(&q_u->hdr_srv_name, len_srv_name);
- init_unistr2(&q_u->uni_srv_name, srv_name, len_srv_name);
+ prs_align(ps);
+
+ smb_io_pol_hnd("connect_pol", &(r_u->connect_pol), ps, depth);
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+makes a SAMR_Q_GET_DOM_PWINFO structure.
********************************************************************/
-
-BOOL samr_io_q_unknown_38(char *desc, SAMR_Q_UNKNOWN_38 *q_u, prs_struct *ps, int depth)
+BOOL make_samr_q_get_dom_pwinfo(SAMR_Q_GET_DOM_PWINFO *q_u, const char *srv_name)
{
- if (q_u == NULL)
- return False;
+ int len_srv_name = strlen(srv_name);
- prs_debug(ps, depth, desc, "samr_io_q_unknown_38");
- depth++;
+ if (q_u == NULL) return False;
- if(!prs_align(ps))
- return False;
+ DEBUG(5,("make_samr_q_get_dom_pwinfo\n"));
- if(!prs_uint32("ptr", ps, depth, &q_u->ptr))
- return False;
+ q_u->ptr = 1;
+ make_uni_hdr(&(q_u->hdr_srv_name), len_srv_name);
+ make_unistr2(&(q_u->uni_srv_name), srv_name, len_srv_name);
- if (q_u->ptr != 0) {
- if(!smb_io_unihdr ("", &q_u->hdr_srv_name, ps, depth))
- return False;
- if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->hdr_srv_name.buffer, ps, depth))
- return False;
- }
return True;
}
/*******************************************************************
- Inits a SAMR_R_UNKNOWN_38 structure.
+reads or writes a structure.
********************************************************************/
-
-void init_samr_r_unknown_38(SAMR_R_UNKNOWN_38 *r_u)
+BOOL samr_io_q_get_dom_pwinfo(char *desc, SAMR_Q_GET_DOM_PWINFO *q_u, prs_struct *ps, int depth)
{
- DEBUG(5,("init_r_unknown_38\n"));
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "samr_io_q_get_dom_pwinfo");
+ depth++;
- r_u->unk_0 = 0;
- r_u->unk_1 = 0;
- r_u->unk_2 = 0;
+ prs_align(ps);
+
+ prs_uint32("ptr", ps, depth, &(q_u->ptr));
+ if (q_u->ptr != 0)
+ {
+ smb_io_unihdr ("", &(q_u->hdr_srv_name), ps, depth);
+ smb_io_unistr2("", &(q_u->uni_srv_name), q_u->hdr_srv_name.buffer, ps, depth);
+ prs_align(ps);
+ }
- r_u->status = 0x0;
+ return True;
}
+
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL samr_io_r_unknown_38(char *desc, SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, int depth)
+BOOL samr_io_r_get_dom_pwinfo(char *desc, SAMR_R_GET_DOM_PWINFO *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "samr_io_r_unknown_38");
+ prs_debug(ps, depth, desc, "samr_io_r_get_dom_pwinfo");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint16("unk_0", ps, depth, &r_u->unk_0))
- return False;
- if(!prs_align(ps))
- return False;
- if(!prs_uint16("unk_1", ps, depth, &r_u->unk_1))
- return False;
- if(!prs_align(ps))
- return False;
- if(!prs_uint16("unk_2", ps, depth, &r_u->unk_2))
- return False;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint16("unk_0", ps, depth, &(r_u->unk_0));
+ prs_align(ps);
+ prs_uint16("unk_1", ps, depth, &(r_u->unk_1));
+ prs_align(ps);
+ prs_uint16("unk_2", ps, depth, &(r_u->unk_2));
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
@@ -3440,169 +6213,182 @@ BOOL samr_io_r_unknown_38(char *desc, SAMR_R_UNKNOWN_38 *r_u, prs_struct *ps, i
/*******************************************************************
make a SAMR_ENC_PASSWD structure.
********************************************************************/
-
-void init_enc_passwd(SAMR_ENC_PASSWD *pwd, char pass[512])
+BOOL make_enc_passwd(SAMR_ENC_PASSWD *pwd, const char pass[512])
{
+ ZERO_STRUCTP(pwd);
+
+ if (pwd == NULL) return False;
+
+ if (pass == NULL)
+ {
+ pwd->ptr = 0;
+ return True;
+ }
pwd->ptr = 1;
memcpy(pwd->pass, pass, sizeof(pwd->pass));
+
+ return True;
}
/*******************************************************************
- Reads or writes a SAMR_ENC_PASSWD structure.
+reads or writes a SAMR_ENC_PASSWD structure.
********************************************************************/
-
BOOL samr_io_enc_passwd(char *desc, SAMR_ENC_PASSWD *pwd, prs_struct *ps, int depth)
{
- if (pwd == NULL)
- return False;
+ if (pwd == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_enc_passwd");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr", ps, depth, &pwd->ptr))
- return False;
- if(!prs_uint8s(False, "pwd", ps, depth, pwd->pass, sizeof(pwd->pass)))
- return False;
+ prs_uint32("ptr", ps, depth, &(pwd->ptr));
+ if (pwd->ptr != 0)
+ {
+ prs_uint8s(False, "pwd", ps, depth, pwd->pass, sizeof(pwd->pass));
+ }
return True;
}
/*******************************************************************
- Inits a SAMR_ENC_HASH structure.
+makes a SAMR_ENC_HASH structure.
********************************************************************/
-
-void init_enc_hash(SAMR_ENC_HASH *hsh, uchar hash[16])
+BOOL make_enc_hash(SAMR_ENC_HASH *hsh, const uchar hash[16])
{
+ ZERO_STRUCTP(hsh);
+
+ if (hsh == NULL) return False;
+
+ if (hash == NULL)
+ {
+ hsh->ptr = 0;
+ return True;
+ }
+
hsh->ptr = 1;
memcpy(hsh->hash, hash, sizeof(hsh->hash));
+
+ return True;
}
/*******************************************************************
- Reads or writes a SAMR_ENC_HASH structure.
+reads or writes a SAMR_ENC_HASH structure.
********************************************************************/
-
BOOL samr_io_enc_hash(char *desc, SAMR_ENC_HASH *hsh, prs_struct *ps, int depth)
{
- if (hsh == NULL)
- return False;
+ if (hsh == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_enc_hash");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr ", ps, depth, &hsh->ptr))
- return False;
- if(!prs_uint8s(False, "hash", ps, depth, hsh->hash, sizeof(hsh->hash)))
- return False;
+ prs_uint32("ptr ", ps, depth, &(hsh->ptr));
+ if (hsh->ptr != 0)
+ {
+ prs_uint8s(False, "hash", ps, depth, hsh->hash, sizeof(hsh->hash));
+ }
return True;
}
/*******************************************************************
- Inits a SAMR_R_UNKNOWN_38 structure.
+makes a SAMR_R_GET_DOM_PWINFO structure.
********************************************************************/
-
-void init_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
- char *dest_host, char *user_name,
- char nt_newpass[516], uchar nt_oldhash[16],
- char lm_newpass[516], uchar lm_oldhash[16])
+BOOL make_samr_q_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
+ const char *dest_host, const char *user_name,
+ const char nt_newpass[516],
+ const uchar nt_oldhash[16],
+ const char lm_newpass[516],
+ const uchar lm_oldhash[16])
{
int len_dest_host = strlen(dest_host);
int len_user_name = strlen(user_name);
- DEBUG(5,("init_samr_q_chgpasswd_user\n"));
+ if (q_u == NULL) return False;
+
+ DEBUG(5,("make_samr_q_chgpasswd_user\n"));
q_u->ptr_0 = 1;
- init_uni_hdr(&q_u->hdr_dest_host, len_dest_host);
- init_unistr2(&q_u->uni_dest_host, dest_host, len_dest_host);
- init_uni_hdr(&q_u->hdr_user_name, len_user_name);
- init_unistr2(&q_u->uni_user_name, user_name, len_user_name);
+ make_uni_hdr(&(q_u->hdr_dest_host), len_dest_host);
+ make_unistr2(&(q_u->uni_dest_host), dest_host, len_dest_host);
+ make_uni_hdr(&(q_u->hdr_user_name), len_user_name);
+ make_unistr2(&(q_u->uni_user_name), user_name, len_user_name);
- init_enc_passwd(&q_u->nt_newpass, nt_newpass);
- init_enc_hash(&q_u->nt_oldhash, nt_oldhash);
+ make_enc_passwd(&(q_u->nt_newpass), nt_newpass);
+ make_enc_hash (&(q_u->nt_oldhash), nt_oldhash);
q_u->unknown = 0x01;
- init_enc_passwd(&q_u->lm_newpass, lm_newpass);
- init_enc_hash (&q_u->lm_oldhash, lm_oldhash);
+ make_enc_passwd(&(q_u->lm_newpass), lm_newpass);
+ make_enc_hash (&(q_u->lm_oldhash), lm_oldhash);
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL samr_io_q_chgpasswd_user(char *desc, SAMR_Q_CHGPASSWD_USER *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_q_chgpasswd_user");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_0", ps, depth, &q_u->ptr_0))
- return False;
+ prs_uint32("ptr_0", ps, depth, &(q_u->ptr_0));
- if(!smb_io_unihdr ("", &q_u->hdr_dest_host, ps, depth))
- return False;
- if(!smb_io_unistr2("", &q_u->uni_dest_host, q_u->hdr_dest_host.buffer, ps, depth))
- return False;
- if(!smb_io_unihdr ("", &q_u->hdr_user_name, ps, depth))
- return False;
- if(!smb_io_unistr2("", &q_u->uni_user_name, q_u->hdr_user_name.buffer, ps, depth))
- return False;
+ smb_io_unihdr ("", &(q_u->hdr_dest_host), ps, depth);
+ smb_io_unistr2("", &(q_u->uni_dest_host), q_u->hdr_dest_host.buffer, ps, depth);
+ prs_align(ps);
- if(!samr_io_enc_passwd("nt_newpass", &q_u->nt_newpass, ps, depth))
- return False;
- if(!samr_io_enc_hash ("nt_oldhash", &q_u->nt_oldhash, ps, depth))
- return False;
+ smb_io_unihdr ("", &(q_u->hdr_user_name), ps, depth);
+ smb_io_unistr2("", &(q_u->uni_user_name), q_u->hdr_user_name.buffer, ps, depth);
+ prs_align(ps);
- if(!prs_uint32("unknown", ps, depth, &q_u->unknown))
- return False;
+ samr_io_enc_passwd("nt_newpass", &(q_u->nt_newpass), ps, depth);
+ samr_io_enc_hash ("nt_oldhash", &(q_u->nt_oldhash), ps, depth);
- if(!samr_io_enc_passwd("lm_newpass", &q_u->lm_newpass, ps, depth))
- return False;
- if(!samr_io_enc_hash("lm_oldhash", &q_u->lm_oldhash, ps, depth))
- return False;
+ prs_uint32("unknown", ps, depth, &(q_u->unknown));
+
+ samr_io_enc_passwd("lm_newpass", &(q_u->lm_newpass), ps, depth);
+ samr_io_enc_hash ("lm_oldhash", &(q_u->lm_oldhash), ps, depth);
return True;
}
/*******************************************************************
- Inits a SAMR_R_CHGPASSWD_USER structure.
+makes a SAMR_R_CHGPASSWD_USER structure.
********************************************************************/
-
-void init_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status)
+BOOL make_samr_r_chgpasswd_user(SAMR_R_CHGPASSWD_USER *r_u, uint32 status)
{
- DEBUG(5,("init_r_chgpasswd_user\n"));
+ if (r_u == NULL) return False;
+
+ DEBUG(5,("make_r_chgpasswd_user\n"));
r_u->status = status;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL samr_io_r_chgpasswd_user(char *desc, SAMR_R_CHGPASSWD_USER *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "samr_io_r_chgpasswd_user");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
+
+
diff --git a/source/rpc_parse/parse_sec.c b/source/rpc_parse/parse_sec.c
index 541949e51e4..7a71a777ae1 100644
--- a/source/rpc_parse/parse_sec.c
+++ b/source/rpc_parse/parse_sec.c
@@ -2,10 +2,10 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1998,
- * Copyright (C) Jeremy R. Allison 1995-1998
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998.
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Jeremy R. Allison 1995-1999
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Paul Ashton 1997-1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,596 +24,512 @@
#include "includes.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
-#define SD_HEADER_SIZE 0x14
/*******************************************************************
- Sets up a SEC_ACCESS structure.
+makes a structure.
********************************************************************/
-
-void init_sec_access(SEC_ACCESS *t, uint32 mask)
+BOOL make_sec_access(SEC_ACCESS *t, uint32 mask)
{
t->mask = mask;
+
+ return True;
}
/*******************************************************************
- Reads or writes a SEC_ACCESS structure.
+reads or writes a structure.
********************************************************************/
-
BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth)
{
- if (t == NULL)
- return False;
+ if (t == NULL) return False;
prs_debug(ps, depth, desc, "sec_io_access");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("mask", ps, depth, &(t->mask)))
- return False;
+ prs_uint32("mask", ps, depth, &(t->mask));
return True;
}
/*******************************************************************
- Sets up a SEC_ACE structure.
+makes a structure.
********************************************************************/
-
-void init_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
+BOOL make_sec_ace(SEC_ACE *t, DOM_SID *sid, uint8 type, SEC_ACCESS mask, uint8 flag)
{
t->type = type;
t->flags = flag;
t->size = sid_size(sid) + 8;
t->info = mask;
- ZERO_STRUCTP(&t->sid);
sid_copy(&t->sid, sid);
+
+ return True;
}
/*******************************************************************
- Reads or writes a SEC_ACE structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth)
+BOOL sec_io_ace(char *desc, SEC_ACE *t, prs_struct *ps, int depth)
{
uint32 old_offset;
uint32 offset_ace_size;
-
- if (psa == NULL)
- return False;
+ if (t == NULL) return False;
prs_debug(ps, depth, desc, "sec_io_ace");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- old_offset = prs_offset(ps);
-
- if(!prs_uint8("type ", ps, depth, &psa->type))
- return False;
-
- if(!prs_uint8("flags", ps, depth, &psa->flags))
- return False;
+ old_offset = ps->offset;
- if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size))
- return False;
-
- if(!sec_io_access("info ", &psa->info, ps, depth))
- return False;
+ prs_uint8 ("type ", ps, depth, &(t->type));
+ prs_uint8 ("flags", ps, depth, &(t->flags));
+ prs_uint16_pre("size ", ps, depth, &(t->size ), &offset_ace_size);
- if(!prs_align(ps))
- return False;
+ sec_io_access ("info ", &t->info, ps, depth);
+ prs_align(ps);
+ smb_io_dom_sid("sid ", &t->sid , ps, depth);
+ prs_align(ps);
- if(!smb_io_dom_sid("sid ", &psa->sid , ps, depth))
- return False;
-
- if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset))
- return False;
+ prs_uint16_post("size ", ps, depth, &t->size, offset_ace_size, old_offset);
return True;
}
/*******************************************************************
- Create a SEC_ACL structure.
+makes a structure.
********************************************************************/
-
-SEC_ACL *make_sec_acl(uint16 revision, int num_aces, SEC_ACE *ace_list)
+BOOL make_sec_acl(SEC_ACL *t, uint16 revision, int num_aces, SEC_ACE *ace)
{
- SEC_ACL *dst;
int i;
-
- if((dst = (SEC_ACL *)malloc(sizeof(SEC_ACL))) == NULL)
- return NULL;
-
- ZERO_STRUCTP(dst);
-
- dst->revision = revision;
- dst->num_aces = num_aces;
- dst->size = 8;
-
- if((dst->ace_list = (SEC_ACE *)malloc( sizeof(SEC_ACE) * num_aces )) == NULL) {
- free_sec_acl(&dst);
- return NULL;
+ t->revision = revision;
+ t->num_aces = num_aces;
+ t->size = 4;
+ t->ace = ace;
+
+ for (i = 0; i < num_aces; i++)
+ {
+ t->size += ace[i].size;
}
- for (i = 0; i < num_aces; i++) {
- dst->ace_list[i] = ace_list[i]; /* Structure copy. */
- dst->size += ace_list[i].size;
- }
-
- return dst;
-}
-
-/*******************************************************************
- Duplicate a SEC_ACL structure.
-********************************************************************/
-
-SEC_ACL *dup_sec_acl( SEC_ACL *src)
-{
- if(src == NULL)
- return NULL;
-
- return make_sec_acl( src->revision, src->num_aces, src->ace_list);
+ return True;
}
/*******************************************************************
- Delete a SEC_ACL structure.
+frees a structure.
********************************************************************/
-
-void free_sec_acl(SEC_ACL **ppsa)
+void free_sec_acl(SEC_ACL *t)
{
- SEC_ACL *psa;
-
- if(ppsa == NULL || *ppsa == NULL)
- return;
-
- psa = *ppsa;
- if (psa->ace_list != NULL)
- free(psa->ace_list);
-
- free(psa);
- *ppsa = NULL;
+ if (t->ace != NULL)
+ {
+ free(t->ace);
+ }
}
/*******************************************************************
- Reads or writes a SEC_ACL structure.
+reads or writes a structure.
- First of the xx_io_xx functions that allocates its data structures
+first of the xx_io_xx functions that allocates its data structures
for you as it reads them.
********************************************************************/
-
-BOOL sec_io_acl(char *desc, SEC_ACL **ppsa, prs_struct *ps, int depth)
+BOOL sec_io_acl(char *desc, SEC_ACL *t, prs_struct *ps, int depth)
{
- int i;
+ uint32 i;
uint32 old_offset;
uint32 offset_acl_size;
- SEC_ACL *psa;
- if (ppsa == NULL)
- return False;
-
- psa = *ppsa;
-
- if(UNMARSHALLING(ps) && psa == NULL) {
- /*
- * This is a read and we must allocate the stuct to read into.
- */
- if((psa = (SEC_ACL *)malloc(sizeof(SEC_ACL))) == NULL)
- return False;
- ZERO_STRUCTP(psa);
- *ppsa = psa;
- }
+ if (t == NULL) return False;
prs_debug(ps, depth, desc, "sec_io_acl");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- old_offset = prs_offset(ps);
+ old_offset = ps->offset;
- if(!prs_uint16("revision", ps, depth, &psa->revision))
- return False;
+ prs_uint16("revision", ps, depth, &(t->revision));
+ prs_uint16_pre("size ", ps, depth, &(t->size ), &offset_acl_size);
+ prs_uint32("num_aces ", ps, depth, &(t->num_aces ));
- if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size))
- return False;
+ if (ps->io && t->num_aces != 0)
+ {
+ /* reading */
+ t->ace = (SEC_ACE*)malloc(sizeof(t->ace[0]) * t->num_aces);
+ ZERO_STRUCTP(t->ace);
+ }
- if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces))
+ if (t->ace == NULL && t->num_aces != 0)
+ {
+ DEBUG(0,("INVALID ACL\n"));
+ ps->offset = 0xfffffffe;
return False;
-
- if (UNMARSHALLING(ps) && psa->num_aces != 0) {
- /* reading */
- if((psa->ace_list = malloc(sizeof(psa->ace_list[0]) * psa->num_aces)) == NULL)
- return False;
- ZERO_STRUCTP(psa->ace_list);
}
- for (i = 0; i < psa->num_aces; i++) {
+ for (i = 0; i < MIN(t->num_aces, MAX_SEC_ACES); i++)
+ {
fstring tmp;
- slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i);
- if(!sec_io_ace(tmp, &psa->ace_list[i], ps, depth))
- return False;
+ slprintf(tmp, sizeof(tmp)-1, "ace[%02d]: ", i);
+ sec_io_ace(tmp, &t->ace[i], ps, depth);
}
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset))
- return False;
+ prs_uint16_post("size ", ps, depth, &t->size , offset_acl_size, old_offset);
return True;
}
+
/*******************************************************************
- Creates a SEC_DESC structure
+makes a structure
********************************************************************/
-
-SEC_DESC *make_sec_desc(uint16 revision, uint16 type,
+int make_sec_desc(SEC_DESC *t, uint16 revision, uint16 type,
DOM_SID *owner_sid, DOM_SID *grp_sid,
- SEC_ACL *sacl, SEC_ACL *dacl, size_t *sec_desc_size)
+ SEC_ACL *sacl, SEC_ACL *dacl)
{
- SEC_DESC *dst;
uint32 offset;
- *sec_desc_size = 0;
-
- if(( dst = (SEC_DESC *)malloc(sizeof(SEC_DESC))) == NULL)
- return NULL;
-
- ZERO_STRUCTP(dst);
-
- dst->revision = revision;
- dst->type = type;
-
- dst->off_owner_sid = 0;
- dst->off_grp_sid = 0;
- dst->off_sacl = 0;
- dst->off_dacl = 0;
-
- if(owner_sid && ((dst->owner_sid = sid_dup(owner_sid)) == NULL))
- goto error_exit;
+ t->revision = revision;
+ t->type = type;
- if(grp_sid && ((dst->grp_sid = sid_dup(grp_sid)) == NULL))
- goto error_exit;
+ t->off_owner_sid = 0;
+ t->off_grp_sid = 0;
+ t->off_sacl = 0;
+ t->off_dacl = 0;
- if(sacl && ((dst->sacl = dup_sec_acl(sacl)) == NULL))
- goto error_exit;
+ t->dacl = dacl;
+ t->sacl = sacl;
+ t->owner_sid = owner_sid;
+ t->grp_sid = grp_sid;
- if(dacl && ((dst->dacl = dup_sec_acl(dacl)) == NULL))
- goto error_exit;
-
offset = 0x0;
- /*
- * Work out the linearization sizes.
- */
-
- if (dst->owner_sid != NULL) {
-
+ if (dacl != NULL)
+ {
if (offset == 0)
- offset = SD_HEADER_SIZE;
-
- dst->off_owner_sid = offset;
- offset += ((sid_size(dst->owner_sid) + 3) & ~3);
+ {
+ offset = 0x14;
+ }
+ t->off_dacl = offset;
+ offset += dacl->size;
}
- if (dst->grp_sid != NULL) {
-
+ if (sacl != NULL)
+ {
if (offset == 0)
- offset = SD_HEADER_SIZE;
-
- dst->off_grp_sid = offset;
- offset += ((sid_size(dst->grp_sid) + 3) & ~3);
+ {
+ offset = 0x14;
+ }
+ t->off_dacl = offset;
+ offset += dacl->size;
}
- if (dst->sacl != NULL) {
-
+ if (owner_sid != NULL)
+ {
if (offset == 0)
- offset = SD_HEADER_SIZE;
-
- dst->off_sacl = offset;
- offset += ((sacl->size + 3) & ~3);
+ {
+ offset = 0x14;
+ }
+ t->off_owner_sid = offset;
+ offset += sid_size(owner_sid);
}
- if (dst->dacl != NULL) {
-
+ if (grp_sid != NULL)
+ {
if (offset == 0)
- offset = SD_HEADER_SIZE;
-
- dst->off_dacl = offset;
- offset += ((dacl->size + 3) & ~3);
+ {
+ offset = 0x14;
+ }
+ t->off_grp_sid = offset;
+ offset += sid_size(grp_sid);
}
- *sec_desc_size = (size_t)((offset == 0) ? SD_HEADER_SIZE : offset);
- return dst;
-
-error_exit:
-
- *sec_desc_size = 0;
- free_sec_desc(&dst);
- return NULL;
+ return (offset == 0) ? 0x14 : offset;
}
-/*******************************************************************
- Duplicate a SEC_DESC structure.
-********************************************************************/
-
-SEC_DESC *dup_sec_desc( SEC_DESC *src)
-{
- size_t dummy;
-
- if(src == NULL)
- return NULL;
-
- return make_sec_desc( src->revision, src->type,
- src->owner_sid, src->grp_sid, src->sacl,
- src->dacl, &dummy);
-}
/*******************************************************************
- Deletes a SEC_DESC structure
+frees a structure
********************************************************************/
-
-void free_sec_desc(SEC_DESC **ppsd)
+void free_sec_desc(SEC_DESC *t)
{
- SEC_DESC *psd;
-
- if(ppsd == NULL || *ppsd == NULL)
- return;
+ if (t->dacl != NULL)
+ {
+ free_sec_acl(t->dacl);
+ }
- psd = *ppsd;
+ if (t->sacl != NULL)
+ {
+ free_sec_acl(t->dacl);
- free_sec_acl(&psd->dacl);
- free_sec_acl(&psd->dacl);
- free(psd->owner_sid);
- free(psd->grp_sid);
- free(psd);
- *ppsd = NULL;
-}
+ }
-/*******************************************************************
- Creates a SEC_DESC structure with typical defaults.
-********************************************************************/
+ if (t->owner_sid != NULL)
+ {
+ free(t->owner_sid);
+ }
-SEC_DESC *make_standard_sec_desc(DOM_SID *owner_sid, DOM_SID *grp_sid,
- SEC_ACL *dacl, size_t *sec_desc_size)
-{
- return make_sec_desc(1, SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
- owner_sid, grp_sid, NULL, dacl, sec_desc_size);
+ if (t->grp_sid != NULL)
+ {
+ free(t->grp_sid);
+ }
}
/*******************************************************************
- Reads or writes a SEC_DESC structure.
- If reading and the *ppsd = NULL, allocates the structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth)
+BOOL sec_io_desc(char *desc, SEC_DESC *t, prs_struct *ps, int depth)
{
+#if 0
+ uint32 off_owner_sid;
+ uint32 off_grp_sid ;
+ uint32 off_sacl ;
+ uint32 off_dacl ;
+#endif
uint32 old_offset;
uint32 max_offset = 0; /* after we're done, move offset to end */
- SEC_DESC *psd;
-
- if (ppsd == NULL)
- return False;
- psd = *ppsd;
-
- if(UNMARSHALLING(ps) && psd == NULL) {
- if((psd = (SEC_DESC *)malloc(sizeof(SEC_DESC))) == NULL)
- return False;
- ZERO_STRUCTP(psd);
- *ppsd = psd;
- }
+ if (t == NULL) return False;
prs_debug(ps, depth, desc, "sec_io_desc");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
/* start of security descriptor stored for back-calc offset purposes */
- old_offset = prs_offset(ps);
-
- if(!prs_uint16("revision ", ps, depth, &psd->revision))
- return False;
-
- if(!prs_uint16("type ", ps, depth, &psd->type))
- return False;
-
- if(!prs_uint32("off_owner_sid", ps, depth, &psd->off_owner_sid))
- return False;
-
- if(!prs_uint32("off_grp_sid ", ps, depth, &psd->off_grp_sid))
- return False;
-
- if(!prs_uint32("off_sacl ", ps, depth, &psd->off_sacl))
- return False;
+ old_offset = ps->offset;
+ max_offset = old_offset;
+
+ prs_uint16("revision ", ps, depth, &(t->revision ));
+ prs_uint16("type ", ps, depth, &(t->type ));
+
+ prs_uint32("off_owner_sid", ps, depth, &(t->off_owner_sid));
+ prs_uint32("off_grp_sid ", ps, depth, &(t->off_grp_sid ));
+ prs_uint32("off_sacl ", ps, depth, &(t->off_sacl ));
+ prs_uint32("off_dacl ", ps, depth, &(t->off_dacl ));
+#if 0
+ prs_uint32_pre("off_owner_sid", ps, depth, &(t->off_owner_sid), &off_owner_sid);
+ prs_uint32_pre("off_grp_sid ", ps, depth, &(t->off_grp_sid ), &off_grp_sid );
+ prs_uint32_pre("off_sacl ", ps, depth, &(t->off_sacl ), &off_sacl );
+ prs_uint32_pre("off_dacl ", ps, depth, &(t->off_dacl ), &off_dacl );
+#endif
+ max_offset = MAX(max_offset, ps->offset);
+
+ if (IS_BITS_SET_ALL(t->type, SEC_DESC_DACL_PRESENT))
+ {
+#if 0
+ prs_uint32_post("off_dacl ", ps, depth, &(t->off_dacl ), off_dacl , ps->offset - old_offset);
+#endif
+ ps->offset = old_offset + t->off_dacl;
+ if (ps->io)
+ {
+ /* reading */
+ t->dacl = (SEC_ACL*)malloc(sizeof(*t->dacl));
+ ZERO_STRUCTP(t->dacl);
+ }
- if(!prs_uint32("off_dacl ", ps, depth, &psd->off_dacl))
- return False;
+ if (t->dacl == NULL)
+ {
+ DEBUG(0,("INVALID DACL\n"));
+ ps->offset = 0xfffffffe;
+ return False;
+ }
- max_offset = MAX(max_offset, prs_offset(ps));
+ sec_io_acl ("dacl" , t->dacl , ps, depth);
+ prs_align(ps);
+ }
+#if 0
+ else
+ {
+ prs_uint32_post("off_dacl ", ps, depth, &(t->off_dacl ), off_dacl , 0);
+ }
+#endif
+
+ max_offset = MAX(max_offset, ps->offset);
+
+ if (IS_BITS_SET_ALL(t->type, SEC_DESC_SACL_PRESENT))
+ {
+#if 0
+ prs_uint32_post("off_sacl ", ps, depth, &(t->off_sacl ), off_sacl , ps->offset - old_offset);
+#endif
+ ps->offset = old_offset + t->off_sacl;
+ if (ps->io)
+ {
+ /* reading */
+ t->sacl = (SEC_ACL*)malloc(sizeof(*t->sacl));
+ ZERO_STRUCTP(t->sacl);
+ }
- if (psd->off_owner_sid != 0) {
+ if (t->sacl == NULL)
+ {
+ DEBUG(0,("INVALID SACL\n"));
+ ps->offset = 0xfffffffe;
+ return False;
+ }
- if (UNMARSHALLING(ps)) {
- if(!prs_set_offset(ps, old_offset + psd->off_owner_sid))
- return False;
+ sec_io_acl ("sacl" , t->sacl , ps, depth);
+ prs_align(ps);
+ }
+#if 0
+ else
+ {
+ prs_uint32_post("off_sacl ", ps, depth, &(t->off_sacl ), off_sacl , 0);
+ }
+#endif
+
+ max_offset = MAX(max_offset, ps->offset);
+
+#if 0
+ prs_uint32_post("off_owner_sid", ps, depth, &(t->off_owner_sid), off_owner_sid, ps->offset - old_offset);
+#endif
+ if (t->off_owner_sid != 0)
+ {
+ if (ps->io)
+ {
+ ps->offset = old_offset + t->off_owner_sid;
+ }
+ if (ps->io)
+ {
/* reading */
- if((psd->owner_sid = malloc(sizeof(*psd->owner_sid))) == NULL)
- return False;
- ZERO_STRUCTP(psd->owner_sid);
+ t->owner_sid = (DOM_SID*)malloc(sizeof(*t->owner_sid));
+ ZERO_STRUCTP(t->owner_sid);
}
- if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth))
- return False;
- if(!prs_align(ps))
+ if (t->owner_sid == NULL)
+ {
+ DEBUG(0,("INVALID OWNER SID\n"));
+ ps->offset = 0xfffffffe;
return False;
+ }
+
+ smb_io_dom_sid("owner_sid ", t->owner_sid , ps, depth);
+ prs_align(ps);
}
- max_offset = MAX(max_offset, prs_offset(ps));
+ max_offset = MAX(max_offset, ps->offset);
- if (psd->off_grp_sid != 0) {
+#if 0
+ prs_uint32_post("off_grp_sid ", ps, depth, &(t->off_grp_sid ), off_grp_sid , ps->offset - old_offset);
+#endif
+ if (t->off_grp_sid != 0)
+ {
+ if (ps->io)
+ {
+ ps->offset = old_offset + t->off_grp_sid;
- if (UNMARSHALLING(ps)) {
+ }
+ if (ps->io)
+ {
/* reading */
- if(!prs_set_offset(ps, old_offset + psd->off_grp_sid))
- return False;
- if((psd->grp_sid = malloc(sizeof(*psd->grp_sid))) == NULL)
- return False;
- ZERO_STRUCTP(psd->grp_sid);
+ t->grp_sid = (DOM_SID*)malloc(sizeof(*t->grp_sid));
+ ZERO_STRUCTP(t->grp_sid);
}
- if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth))
- return False;
- if(!prs_align(ps))
+ if (t->grp_sid == NULL)
+ {
+ DEBUG(0,("INVALID GROUP SID\n"));
+ ps->offset = 0xfffffffe;
return False;
- }
-
- max_offset = MAX(max_offset, prs_offset(ps));
+ }
- if (IS_BITS_SET_ALL(psd->type, SEC_DESC_SACL_PRESENT) && psd->off_sacl) {
- if(!prs_set_offset(ps, old_offset + psd->off_sacl))
- return False;
- if(!sec_io_acl("sacl", &psd->sacl, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ smb_io_dom_sid("grp_sid", t->grp_sid, ps, depth);
+ prs_align(ps);
}
- max_offset = MAX(max_offset, prs_offset(ps));
-
- if (IS_BITS_SET_ALL(psd->type, SEC_DESC_DACL_PRESENT) && psd->off_dacl != 0) {
- if(!prs_set_offset(ps, old_offset + psd->off_dacl))
- return False;
- if(!sec_io_acl("dacl", &psd->dacl, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- }
+ max_offset = MAX(max_offset, ps->offset);
- max_offset = MAX(max_offset, prs_offset(ps));
+ ps->offset = max_offset;
- if(!prs_set_offset(ps, max_offset))
- return False;
return True;
}
/*******************************************************************
- Creates a SEC_DESC_BUF structure.
+creates a SEC_DESC_BUF structure.
********************************************************************/
-
-SEC_DESC_BUF *make_sec_desc_buf(int len, SEC_DESC *sec_desc)
+BOOL make_sec_desc_buf(SEC_DESC_BUF *buf, int len, SEC_DESC *data)
{
- SEC_DESC_BUF *dst;
-
- if((dst = (SEC_DESC_BUF *)malloc(sizeof(SEC_DESC_BUF))) == NULL)
- return NULL;
-
- ZERO_STRUCTP(dst);
+ ZERO_STRUCTP(buf);
/* max buffer size (allocated size) */
- dst->max_len = len;
- dst->len = len;
-
- if(sec_desc && ((dst->sec = dup_sec_desc(sec_desc)) == NULL)) {
- free_sec_desc_buf(&dst);
- return NULL;
- }
+ buf->max_len = len;
+ buf->undoc = 0;
+ buf->len = data != NULL ? len : 0;
+ buf->sec = data;
- return dst;
-}
-
-/*******************************************************************
- Duplicates a SEC_DESC_BUF structure.
-********************************************************************/
-
-SEC_DESC_BUF *dup_sec_desc_buf(SEC_DESC_BUF *src)
-{
- if(src == NULL)
- return NULL;
-
- return make_sec_desc_buf( src->len, src->sec);
+ return True;
}
/*******************************************************************
- Deletes a SEC_DESC_BUF structure.
+frees a SEC_DESC_BUF structure.
********************************************************************/
-
-void free_sec_desc_buf(SEC_DESC_BUF **ppsdb)
+void free_sec_desc_buf(SEC_DESC_BUF *buf)
{
- SEC_DESC_BUF *psdb;
-
- if(ppsdb == NULL || *ppsdb == NULL)
- return;
-
- psdb = *ppsdb;
- free_sec_desc(&psdb->sec);
- free(psdb);
- *ppsdb = NULL;
+ if (buf->sec != NULL)
+ {
+ free_sec_desc(buf->sec);
+ free(buf->sec);
+ }
}
/*******************************************************************
- Reads or writes a SEC_DESC_BUF structure.
+reads or writes a SEC_DESC_BUF structure.
********************************************************************/
-
-BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth)
+BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF *sec, prs_struct *ps, int depth)
{
uint32 off_len;
uint32 off_max_len;
uint32 old_offset;
uint32 size;
- SEC_DESC_BUF *psdb;
-
- if (ppsdb == NULL)
- return False;
-
- psdb = *ppsdb;
- if (UNMARSHALLING(ps) && psdb == NULL) {
- if((psdb = (SEC_DESC_BUF *)malloc(sizeof(SEC_DESC_BUF))) == NULL)
- return False;
- ZERO_STRUCTP(psdb);
- *ppsdb = psdb;
- }
+ if (sec == NULL) return False;
prs_debug(ps, depth, desc, "sec_io_desc_buf");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32_pre("max_len", ps, depth, &psdb->max_len, &off_max_len))
- return False;
+ prs_uint32_pre("max_len", ps, depth, &(sec->max_len), &off_max_len);
+ prs_uint32 ("undoc ", ps, depth, &(sec->undoc ));
+ prs_uint32_pre("len ", ps, depth, &(sec->len ), &off_len);
- if(!prs_uint32 ("undoc ", ps, depth, &psdb->undoc))
- return False;
+ old_offset = ps->offset;
- if(!prs_uint32_pre("len ", ps, depth, &psdb->len, &off_len))
- return False;
+ if (sec->len != 0 && ps->io)
+ {
+ /* reading */
+ sec->sec = (SEC_DESC*)malloc(sizeof(*sec->sec));
+ ZERO_STRUCTP(sec->sec);
- old_offset = prs_offset(ps);
+ if (sec->sec == NULL)
+ {
+ DEBUG(0,("INVALID SEC_DESC\n"));
+ ps->offset = 0xfffffffe;
+ return False;
+ }
+ }
/* reading, length is non-zero; writing, descriptor is non-NULL */
- if ((psdb->len != 0 || MARSHALLING(ps)) && psdb->sec != NULL) {
- if(!sec_io_desc("sec ", &psdb->sec, ps, depth))
- return False;
+ if ((sec->len != 0 || (!ps->io)) && sec->sec != NULL)
+ {
+ sec_io_desc("sec ", sec->sec, ps, depth);
}
- size = prs_offset(ps) - old_offset;
- if(!prs_uint32_post("max_len", ps, depth, &psdb->max_len, off_max_len, size == 0 ? psdb->max_len : size))
- return False;
+ prs_align(ps);
+
+ size = ps->offset - old_offset - 8;
+ prs_uint32_post("max_len", ps, depth, &(sec->max_len), off_max_len, size == 0 ? sec->max_len : size + 8);
+ prs_uint32_post("len ", ps, depth, &(sec->len ), off_len , size == 0 ? 0 : size + 8);
- if(!prs_uint32_post("len ", ps, depth, &psdb->len, off_len, size))
- return False;
+ ps->offset = old_offset + size + 8;
return True;
}
+
diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c
index 452cbb1531d..22e072bd21e 100644
--- a/source/rpc_parse/parse_spoolss.c
+++ b/source/rpc_parse/parse_spoolss.c
@@ -2,9 +2,9 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-2000,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
- * Copyright (C) Jean François Micouleau 1998-2000.
+ * Copyright (C) Andrew Tridgell 1992-1998,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ * Copyright (C) Jean François Micouleau 1998.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,9 +23,12 @@
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
+
+
/*******************************************************************
return the length of a UNISTR string.
********************************************************************/
@@ -179,26 +182,24 @@ static BOOL smb_io_doc_info_container(char *desc, DOC_INFO_CONTAINER *cont, prs_
/*******************************************************************
reads or writes an NOTIFY OPTION TYPE structure.
********************************************************************/
-static BOOL smb_io_notify_option_type(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
+static BOOL smb_io_notify_option_type(char *desc,
+ SPOOL_NOTIFY_OPTION_TYPE *type,
+ prs_struct *ps, int depth)
{
+ uint32 useless_ptr;
+
prs_debug(ps, depth, desc, "smb_io_notify_option_type");
depth++;
- if (!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint16("type", ps, depth, &(type->type));
+ prs_uint16("reserved0", ps, depth, &(type->reserved0));
+ prs_uint32("reserved1", ps, depth, &(type->reserved1));
+ prs_uint32("reserved2", ps, depth, &(type->reserved2));
+ prs_uint32("count", ps, depth, &(type->count));
+ prs_uint32("useless ptr", ps, depth, &useless_ptr);
- if(!prs_uint16("type", ps, depth, &type->type))
- return False;
- if(!prs_uint16("reserved0", ps, depth, &type->reserved0))
- return False;
- if(!prs_uint32("reserved1", ps, depth, &type->reserved1))
- return False;
- if(!prs_uint32("reserved2", ps, depth, &type->reserved2))
- return False;
- if(!prs_uint32("count", ps, depth, &type->count))
- return False;
- if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr))
- return False;
return True;
}
@@ -206,97 +207,79 @@ static BOOL smb_io_notify_option_type(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type
/*******************************************************************
reads or writes an NOTIFY OPTION TYPE DATA.
********************************************************************/
-static BOOL smb_io_notify_option_type_data(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth)
+static BOOL smb_io_notify_option_type_data(char *desc,
+ SPOOL_NOTIFY_OPTION_TYPE *type,
+ prs_struct *ps, int depth)
{
+ uint32 count;
int i;
prs_debug(ps, depth, desc, "smb_io_notify_option_type_data");
depth++;
- /* if there are no fields just return */
- if (type->fields_ptr==0)
- return True;
-
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("count2", ps, depth, &type->count2))
- return False;
+ prs_uint32("count", ps, depth, &count);
- if (type->count2 != type->count)
- DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2));
+ if (count != type->count)
+ {
+ DEBUG(4,("What a mess, count was %x now is %x !\n",type->count,count));
+ type->count=count;
+ }
+ for(i=0;i<count;i++)
+ {
+ /* read the option type struct */
+ prs_uint16("fields",ps,depth,&(type->fields[i]));
+ }
- /* parse the option type data */
- for(i=0;i<type->count2;i++)
- if(!prs_uint16("fields",ps,depth,&(type->fields[i])))
- return False;
return True;
}
/*******************************************************************
reads or writes an NOTIFY OPTION structure.
********************************************************************/
-static BOOL smb_io_notify_option_type_ctr(char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth)
-{
+static BOOL smb_io_notify_option(char *desc, SPOOL_NOTIFY_OPTION *option,
+ prs_struct *ps, int depth)
+{
+ uint32 useless_ptr;
int i;
-
- prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr");
- depth++;
-
- if(!prs_uint32("count", ps, depth, &ctr->count))
- return False;
-
- /* reading */
- if (UNMARSHALLING(ps))
- ctr->type=(SPOOL_NOTIFY_OPTION_TYPE *)malloc(ctr->count*sizeof(SPOOL_NOTIFY_OPTION_TYPE));
-
- /* the option type struct */
- for(i=0;i<ctr->count;i++)
- if(!smb_io_notify_option_type("", &(ctr->type[i]) , ps, depth))
- return False;
-
- /* the type associated with the option type struct */
- for(i=0;i<ctr->count;i++)
- if(!smb_io_notify_option_type_data("", &(ctr->type[i]) , ps, depth))
- return False;
-
- return True;
-}
-/*******************************************************************
-reads or writes an NOTIFY OPTION structure.
-********************************************************************/
-static BOOL smb_io_notify_option(char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth)
-{
prs_debug(ps, depth, desc, "smb_io_notify_option");
depth++;
-
- if(!prs_uint32("version", ps, depth, &option->version))
- return False;
- if(!prs_uint32("flags", ps, depth, &option->flags))
- return False;
- if(!prs_uint32("count", ps, depth, &option->count))
- return False;
- if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr))
- return False;
+
+ prs_align(ps);
+
+ /* memory pointer to the struct */
+ prs_uint32("useless ptr", ps, depth, &useless_ptr);
- /* marshalling or unmarshalling, that would work */
- if (option->option_type_ptr!=0) {
- if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth))
- return False;
+ prs_uint32("version", ps, depth, &(option->version));
+ prs_uint32("reserved", ps, depth, &(option->reserved));
+ prs_uint32("count", ps, depth, &(option->count));
+ prs_uint32("useless ptr", ps, depth, &useless_ptr);
+ prs_uint32("count", ps, depth, &(option->count));
+
+ /* read the option type struct */
+ for(i=0;i<option->count;i++)
+ {
+ smb_io_notify_option_type("",&(option->type[i]) ,ps, depth);
}
- else {
- option->ctr.type=NULL;
- option->ctr.count=0;
+
+ /* now read the type associated with the option type struct */
+ for(i=0;i<option->count;i++)
+ {
+ smb_io_notify_option_type_data("",&(option->type[i]) ,ps, depth);
}
+
return True;
}
+
/*******************************************************************
reads or writes an NOTIFY INFO DATA structure.
********************************************************************/
-static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth)
+static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
+ prs_struct *ps, int depth)
{
uint32 useless_ptr=0xADDE0FF0;
@@ -374,16 +357,19 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data,
/*******************************************************************
reads or writes an NOTIFY INFO structure.
********************************************************************/
-static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth)
+static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info,
+ prs_struct *ps, int depth)
{
+ uint32 useless_ptr=0x0001;
int i;
+ info->version=0x02;
prs_debug(ps, depth, desc, "smb_io_notify_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
prs_uint32("count", ps, depth, &(info->count));
prs_uint32("version", ps, depth, &(info->version));
prs_uint32("flags", ps, depth, &(info->flags));
@@ -397,241 +383,74 @@ static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *
/* now do the strings at the end of the stream */
for (i=0;i<info->count;i++)
{
- smb_io_notify_info_data_strings(desc, &(info->data[i]), ps, depth);
+ smb_io_notify_info_data_strings(desc, &(info->data[i]),
+ ps, depth);
}
return True;
}
-
-/*******************************************************************
-********************************************************************/
-static BOOL spool_io_user_level_1(char *desc, SPOOL_USER_1 *q_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "");
- depth++;
-
- /* reading */
- if (ps->io)
- ZERO_STRUCTP(q_u);
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("size", ps, depth, &(q_u->size)))
- return False;
- if (!prs_uint32("client_name_ptr", ps, depth, &(q_u->client_name_ptr)))
- return False;
- if (!prs_uint32("user_name_ptr", ps, depth, &(q_u->user_name_ptr)))
- return False;
- if (!prs_uint32("build", ps, depth, &(q_u->build)))
- return False;
- if (!prs_uint32("major", ps, depth, &(q_u->major)))
- return False;
- if (!prs_uint32("minor", ps, depth, &(q_u->minor)))
- return False;
- if (!prs_uint32("processor", ps, depth, &(q_u->processor)))
- return False;
-
- if (!smb_io_unistr2("", &(q_u->client_name), q_u->client_name_ptr, ps, depth))
- return False;
- if (!prs_align(ps))
- return False;
- if (!smb_io_unistr2("", &(q_u->user_name), q_u->user_name_ptr, ps, depth))
- return False;
-
- return True;
-}
-
/*******************************************************************
-********************************************************************/
-static BOOL spool_io_user_level(char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth)
+ * write a structure.
+ * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
+ * called from spoolss_open_printer_ex (cli_spoolss.c)
+ ********************************************************************/
+BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
{
- if (q_u==NULL)
- return False;
+ if (r_u == NULL) return False;
- prs_debug(ps, depth, desc, "spool_io_user_level");
+ prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
depth++;
+ prs_align(ps);
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("level", ps, depth, &q_u->level))
- return False;
- if (!prs_uint32("ptr", ps, depth, &q_u->ptr))
- return False;
-
- switch (q_u->level) {
- case 1:
- if (!spool_io_user_level_1("", &(q_u->user1), ps, depth))
- return False;
- break;
- default:
- return False;
- }
+ smb_io_prt_hnd("printer handle",&(r_u->handle),ps,depth);
- return True;
-}
+/* prs_align(ps);*/
-/*******************************************************************
- * read or write a DEVICEMODE struct.
- * on reading allocate memory for the private member
- ********************************************************************/
-static BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
-{
- prs_debug(ps, depth, desc, "spoolss_io_devmode");
- depth++;
-
- if (!prs_uint16s(True,"devicename", ps, depth, devmode->devicename.buffer, 32))
- return False;
- if (!prs_uint16("specversion", ps, depth, &(devmode->specversion)))
- return False;
- if (!prs_uint16("driverversion", ps, depth, &(devmode->driverversion)))
- return False;
- if (!prs_uint16("size", ps, depth, &(devmode->size)))
- return False;
- if (!prs_uint16("driverextra", ps, depth, &(devmode->driverextra)))
- return False;
- if (!prs_uint32("fields", ps, depth, &(devmode->fields)))
- return False;
- if (!prs_uint16("orientation", ps, depth, &(devmode->orientation)))
- return False;
- if (!prs_uint16("papersize", ps, depth, &(devmode->papersize)))
- return False;
- if (!prs_uint16("paperlength", ps, depth, &(devmode->paperlength)))
- return False;
- if (!prs_uint16("paperwidth", ps, depth, &(devmode->paperwidth)))
- return False;
- if (!prs_uint16("scale", ps, depth, &(devmode->scale)))
- return False;
- if (!prs_uint16("copies", ps, depth, &(devmode->copies)))
- return False;
- if (!prs_uint16("defaultsource", ps, depth, &(devmode->defaultsource)))
- return False;
- if (!prs_uint16("printquality", ps, depth, &(devmode->printquality)))
- return False;
- if (!prs_uint16("color", ps, depth, &(devmode->color)))
- return False;
- if (!prs_uint16("duplex", ps, depth, &(devmode->duplex)))
- return False;
- if (!prs_uint16("yresolution", ps, depth, &(devmode->yresolution)))
- return False;
- if (!prs_uint16("ttoption", ps, depth, &(devmode->ttoption)))
- return False;
- if (!prs_uint16("collate", ps, depth, &(devmode->collate)))
- return False;
- if (!prs_uint16s(True, "formname", ps, depth, devmode->formname.buffer, 32))
- return False;
- if (!prs_uint16("logpixels", ps, depth, &(devmode->logpixels)))
- return False;
- if (!prs_uint32("bitsperpel", ps, depth, &(devmode->bitsperpel)))
- return False;
- if (!prs_uint32("pelswidth", ps, depth, &(devmode->pelswidth)))
- return False;
- if (!prs_uint32("pelsheight", ps, depth, &(devmode->pelsheight)))
- return False;
- if (!prs_uint32("displayflags", ps, depth, &(devmode->displayflags)))
- return False;
- if (!prs_uint32("displayfrequency", ps, depth, &(devmode->displayfrequency)))
- return False;
- if (!prs_uint32("icmmethod", ps, depth, &(devmode->icmmethod)))
- return False;
- if (!prs_uint32("icmintent", ps, depth, &(devmode->icmintent)))
- return False;
- if (!prs_uint32("mediatype", ps, depth, &(devmode->mediatype)))
- return False;
- if (!prs_uint32("dithertype", ps, depth, &(devmode->dithertype)))
- return False;
- if (!prs_uint32("reserved1", ps, depth, &(devmode->reserved1)))
- return False;
- if (!prs_uint32("reserved2", ps, depth, &(devmode->reserved2)))
- return False;
- if (!prs_uint32("panningwidth", ps, depth, &(devmode->panningwidth)))
- return False;
- if (!prs_uint32("panningheight", ps, depth, &(devmode->panningheight)))
- return False;
+ prs_uint32("status code", ps, depth, &(r_u->status));
- if (devmode->driverextra!=0)
- {
- if (UNMARSHALLING(ps)) {
- devmode->private=(uint8 *)malloc(devmode->driverextra*sizeof(uint8));
- DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for private\n",devmode->driverextra));
- }
-
- DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of private\n",devmode->driverextra));
- if (!prs_uint8s(True, "private", ps, depth, devmode->private, devmode->driverextra))
- return False;
- }
return True;
}
/*******************************************************************
- Read or write a DEVICEMODE container
-********************************************************************/
-static BOOL spoolss_io_devmode_cont(char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth)
+ * make a structure.
+ ********************************************************************/
+BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
+ const char *printername,
+ uint32 cbbuf, uint32 devmod, uint32 des_access,
+ const char *station,
+ const char *username)
{
- if (dm_c==NULL)
- return False;
+ int len_name = printername != NULL ? strlen(printername) : 0;
+ int len_sta = station != NULL ? strlen(station ) : 0;
+ int len_user = username != NULL ? strlen(username ) : 0;
- prs_debug(ps, depth, desc, "spoolss_io_devmode_cont");
- depth++;
-
- if(!prs_align(ps))
- return False;
-
- if (!prs_uint32("size", ps, depth, &dm_c->size))
- return False;
-
- if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr))
- return False;
-
- if (dm_c->size==0 || dm_c->devmode_ptr==0) {
- if (UNMARSHALLING(ps))
- /* if while reading there is no DEVMODE ... */
- dm_c->devmode=NULL;
- return True;
- }
-
- /* so we have a DEVICEMODE to follow */
- if (UNMARSHALLING(ps)) {
- DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
- dm_c->devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE));
- ZERO_STRUCTP(dm_c->devmode);
- }
-
- /* this is bad code, shouldn't be there */
- if (!prs_uint32("size", ps, depth, &dm_c->size))
- return False;
-
- if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-static BOOL spoolss_io_printer_default(char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth)
-{
- if (pd==NULL)
- return False;
+ if (q_u == NULL) return False;
- prs_debug(ps, depth, desc, "spoolss_io_printer_default");
- depth++;
+ DEBUG(5,("make_spoolss_io_q_open_printer_ex\n"));
- if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr))
- return False;
+ q_u->ptr = 1;
+ make_unistr2(&(q_u->printername), printername, len_name);
- if (!smb_io_unistr2("datatype", &(pd->datatype), pd->datatype_ptr, ps,depth))
- return False;
-
- if (!prs_align(ps))
- return False;
+ q_u->unknown0 = 0x0; /* 0x0000 0000 */
+ q_u->cbbuf = cbbuf; /* 0x0000 0000 */
+ q_u->devmod = devmod; /* 0x0000 0000 */
+ q_u->access_required = des_access;
- if (!spoolss_io_devmode_cont("", &(pd->devmode_cont), ps, depth))
- return False;
+ q_u->unknown1 = 0x1;
+ q_u->unknown2 = 0x1;
+ q_u->unknown3 = 0x149f7d8; /* looks like a pointer */
+ q_u->unknown4 = 0x1c;
+ q_u->unknown5 = 0x00b94dd0;
+ q_u->unknown6 = 0x0149f5cc; /* looks like _another_ pointer */
+ q_u->unknown7 = 0x00000565;
+ q_u->unknown8 = 0x2;
+ q_u->unknown9 = 0x0;
+ q_u->unknown10 = 0x0;
- if (!prs_uint32("access_required", ps, depth, &pd->access_required))
- return False;
+ make_unistr2(&(q_u->station), station, len_sta);
+ make_unistr2(&(q_u->username), username, len_user);
return True;
}
@@ -642,57 +461,45 @@ static BOOL spoolss_io_printer_default(char *desc, PRINTER_DEFAULT *pd, prs_stru
********************************************************************/
BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex");
depth++;
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr))
- return False;
- if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth))
- return False;
-
- if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
- return False;
- if (!spool_io_user_level("", &q_u->user_ctr, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- * write a structure.
- * called from static spoolss_r_open_printer_ex (srv_spoolss.c)
- * called from spoolss_open_printer_ex (cli_spoolss.c)
- ********************************************************************/
-BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth)
-{
- if (r_u == NULL) return False;
+ prs_align(ps);
- prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex");
- depth++;
+ prs_uint32("ptr", ps, depth, &(q_u->ptr));
+ smb_io_unistr2("", &(q_u->printername),True,ps,depth);
- if (!prs_align(ps))
- return False;
-
- if (!smb_io_prt_hnd("printer handle",&(r_u->handle),ps,depth))
- return False;
+ prs_align(ps);
- if (!prs_uint32("status code", ps, depth, &(r_u->status)))
- return False;
+ prs_uint32("unknown0", ps, depth, &(q_u->unknown0));
+ prs_uint32("cbbuf", ps, depth, &(q_u->cbbuf));
+ prs_uint32("devmod", ps, depth, &(q_u->devmod));
+ prs_uint32("access required", ps, depth, &(q_u->access_required));
+
+ /* don't care to decode end of packet by now */
+ /* but when acl will be implemented, it will be useful */
+
+ prs_uint32("unknown1", ps, depth, &(q_u->unknown1));
+ prs_uint32("unknown2", ps, depth, &(q_u->unknown2));
+ prs_uint32("unknown3", ps, depth, &(q_u->unknown3));
+ prs_uint32("unknown4", ps, depth, &(q_u->unknown4));
+ prs_uint32("unknown5", ps, depth, &(q_u->unknown5));
+ prs_uint32("unknown6", ps, depth, &(q_u->unknown6));
+ prs_uint32("unknown7", ps, depth, &(q_u->unknown7));
+ prs_uint32("unknown8", ps, depth, &(q_u->unknown8));
+ prs_uint32("unknown9", ps, depth, &(q_u->unknown9));
+ prs_uint32("unknown10", ps, depth, &(q_u->unknown10));
+
+ smb_io_unistr2("", &(q_u->station),True,ps,depth);
+ prs_align(ps);
+ smb_io_unistr2("", &(q_u->username),True,ps,depth);
+ prs_align(ps);
return True;
}
+
/*******************************************************************
* make a structure.
********************************************************************/
@@ -708,7 +515,7 @@ BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u,
DEBUG(5,("make_spoolss_q_getprinterdata\n"));
memcpy(&(q_u->handle), handle, sizeof(q_u->handle));
- init_unistr2(&(q_u->valuename), valuename, len_name);
+ make_unistr2(&(q_u->valuename), valuename, len_name);
q_u->size = size;
return True;
@@ -725,18 +532,12 @@ BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_st
prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata");
depth++;
- if (!prs_align(ps))
- return False;
- if (!smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth))
- return False;
- if (!prs_align(ps))
- return False;
- if (!smb_io_unistr2("valuename", &(q_u->valuename),True,ps,depth))
- return False;
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("size", ps, depth, &(q_u->size)))
- return False;
+ prs_align(ps);
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
+ prs_align(ps);
+ smb_io_unistr2("", &(q_u->valuename),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("size", ps, depth, &(q_u->size));
return True;
}
@@ -747,30 +548,22 @@ BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_st
********************************************************************/
BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata");
depth++;
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("type", ps, depth, &(r_u->type)))
- return False;
- if (!prs_uint32("size", ps, depth, &(r_u->size)))
- return False;
+ prs_align(ps);
+ prs_uint32("type", ps, depth, &(r_u->type));
+ prs_uint32("size", ps, depth, &(r_u->size));
- if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size))
- return False;
-
- if (!prs_align(ps))
- return False;
+ prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size);
+ prs_align(ps);
- if (!prs_uint32("needed", ps, depth, &(r_u->needed)))
- return False;
- if (!prs_uint32("status", ps, depth, &(r_u->status)))
- return False;
-
+ prs_uint32("needed", ps, depth, &(r_u->needed));
+ prs_uint32("status", ps, depth, &(r_u->status));
+ prs_align(ps);
+
return True;
}
@@ -800,11 +593,9 @@ BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct
prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter");
depth++;
- if (!prs_align(ps))
- return False;
+ prs_align(ps);
- if (!smb_io_prt_hnd("printer handle",&q_u->handle,ps,depth))
- return False;
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
return True;
}
@@ -818,15 +609,12 @@ BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct
{
prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter");
depth++;
-
- if (!prs_align(ps))
- return False;
+ prs_align(ps);
- if (!smb_io_prt_hnd("printer handle",&r_u->handle,ps,depth))
- return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ smb_io_prt_hnd("printer handle",&(r_u->handle),ps,depth);
+ prs_uint32("status", ps, depth, &(r_u->status));
+
return True;
}
@@ -1002,43 +790,29 @@ BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct
* read a structure.
* called from spoolss_q_rffpcnex (srv_spoolss.c)
********************************************************************/
-BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth)
+BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u,
+ prs_struct *ps, int depth)
{
+ uint32 useless_ptr;
+
prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex");
depth++;
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
+ prs_uint32("flags", ps, depth, &(q_u->flags));
+ prs_uint32("options", ps, depth, &(q_u->options));
+ prs_uint32("useless ptr", ps, depth, &useless_ptr);
+ /*prs_align(ps);*/
- if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth))
- return False;
- if(!prs_uint32("flags", ps, depth, &q_u->flags))
- return False;
- if(!prs_uint32("options", ps, depth, &q_u->options))
- return False;
- if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr))
- return False;
- if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth))
- return False;
+ smb_io_unistr2("", &(q_u->localmachine), True, ps, depth);
+
+ prs_align(ps);
+ prs_uint32("printerlocal", ps, depth, &(q_u->printerlocal));
+
+ smb_io_notify_option("notify option", &(q_u->option), ps, depth);
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal))
- return False;
- if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
- return False;
-
- if (q_u->option_ptr!=0) {
-
- if (UNMARSHALLING(ps))
- q_u->option=(SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION));
-
- if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
- return False;
- }
-
return True;
}
@@ -1046,13 +820,13 @@ BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, in
* write a structure.
* called from spoolss_r_rffpcnex (srv_spoolss.c)
********************************************************************/
-BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth)
+BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u,
+ prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex");
depth++;
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
@@ -1061,31 +835,20 @@ BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, in
* read a structure.
* called from spoolss_q_rfnpcnex (srv_spoolss.c)
********************************************************************/
-BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth)
+BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u,
+ prs_struct *ps, int depth)
{
+
prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_prt_hnd("printer handle",&q_u->handle,ps,depth))
- return False;
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
- if(!prs_uint32("change", ps, depth, &q_u->change))
- return False;
-
- if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr))
- return False;
-
- if (q_u->option_ptr!=0) {
+ prs_uint32("change", ps, depth, &(q_u->change));
- if (UNMARSHALLING(ps))
- q_u->option=(SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION));
-
- if(!smb_io_notify_option("notify option", q_u->option, ps, depth))
- return False;
- }
+ smb_io_notify_option("notify option",&(q_u->option),ps,depth);
return True;
}
@@ -1094,24 +857,18 @@ BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, in
* write a structure.
* called from spoolss_r_rfnpcnex (srv_spoolss.c)
********************************************************************/
-BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth)
+BOOL spoolss_io_r_rfnpcnex(char *desc,
+ SPOOL_R_RFNPCNEX *r_u,
+ prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex");
depth++;
- if(!prs_align(ps))
- return False;
-
- if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr))
- return False;
+ prs_align(ps);
- if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth))
- return False;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ smb_io_notify_info("notify info",&(r_u->info),ps,depth);
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &r_u->status);
return True;
}
@@ -1122,6 +879,8 @@ BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, in
static uint32 size_of_uint32(uint32 *value)
{
return (sizeof(*value));
+
+ return True;
}
/*******************************************************************
@@ -1137,8 +896,9 @@ static uint32 size_of_relative_string(UNISTR *string)
size=size+1; /* add the leading zero */
size=size*2; /* convert in char */
size=size+4; /* add the size of the ptr */
+ return (size);
- return size;
+ return True;
}
/*******************************************************************
@@ -1150,6 +910,8 @@ static uint32 size_of_device_mode(DEVICEMODE *devmode)
return (4);
else
return (0xDC+4);
+
+ return True;
}
/*******************************************************************
@@ -1161,24 +923,23 @@ static uint32 size_of_systemtime(SYSTEMTIME *systime)
return (4);
else
return (sizeof(SYSTEMTIME) +4);
+
+ return True;
}
/*******************************************************************
* write a UNICODE string.
* used by all the RPC structs passing a buffer
********************************************************************/
-static BOOL spoolss_smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
+static BOOL spoolss_smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth)
{
- uint16 zero=0;
- if (uni == NULL)
- return False;
+ if (uni == NULL) return False;
prs_debug(ps, depth, desc, "spoolss_smb_io_unistr");
depth++;
- if (!prs_unistr("unistr", ps, depth, uni))
- return False;
- if (!prs_uint16("null", ps, depth, &zero))
- return False;
+ prs_unistr("unistr", ps, depth, uni);
+
+ return True;
}
@@ -1191,15 +952,15 @@ static BOOL smb_io_relstr(char *desc, prs_struct *ps, int depth, UNISTR *buffer,
{
if (!ps->io)
{
- uint32 struct_offset = prs_offset(ps);
+ uint32 struct_offset = ps->offset;
uint32 relative_offset;
/* writing */
*end_offset -= 2*(str_len_uni(buffer)+1);
- prs_set_offset(ps, *end_offset);
+ ps->offset=*end_offset;
spoolss_smb_io_unistr(desc, buffer, ps, depth);
- prs_set_offset(ps,struct_offset);
+ ps->offset=struct_offset;
relative_offset=*end_offset-*start_offset;
prs_uint32("offset", ps, depth, &(relative_offset));
@@ -1211,73 +972,13 @@ static BOOL smb_io_relstr(char *desc, prs_struct *ps, int depth, UNISTR *buffer,
prs_uint32("offset", ps, depth, &(relative_offset));
- old_offset = prs_offset(ps);
- prs_set_offset(ps, (*start_offset) + relative_offset);
+ old_offset = ps->offset;
+ ps->offset = (*start_offset) + relative_offset;
spoolss_smb_io_unistr(desc, buffer, ps, depth);
- *end_offset = prs_offset(ps);
- prs_set_offset(ps, old_offset);
- }
- return True;
-}
-
-/*******************************************************************
- * write a UNICODE string and its relative pointer.
- * used by all the RPC structs passing a buffer
- *
- * As I'm a nice guy, I'm forcing myself to explain this code.
- * MS did a good job in the overall spoolss code except in some
- * functions where they are passing the API buffer directly in the
- * RPC request/reply. That's to maintain compatiility at the API level.
- * They could have done it the good way the first time.
- *
- * So what happen is: the strings are written at the buffer's end,
- * in the reverse order of the original structure. Some pointers to
- * the strings are also in the buffer. Those are relative to the
- * buffer's start.
- *
- * If you don't understand or want to change that function,
- * first get in touch with me: jfm@samba.org
- *
- ********************************************************************/
-static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR *string)
-{
- prs_struct *ps=&(buffer->prs);
-
- if (MARSHALLING(ps)) {
- uint32 struct_offset = prs_offset(ps);
- uint32 relative_offset;
-
- buffer->string_at_end -= 2*(str_len_uni(string)+1);
- prs_set_offset(ps, buffer->string_at_end);
-
- /* write the string */
- if (!spoolss_smb_io_unistr(desc, string, ps, depth))
- return False;
-
- prs_set_offset(ps, struct_offset);
-
- relative_offset=buffer->string_at_end - buffer->struct_start;
- /* write its offset */
- if (!prs_uint32("offset", ps, depth, &relative_offset))
- return False;
- }
- else {
- uint32 old_offset;
-
- /* read the offset */
- if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
- return False;
-
- old_offset = prs_offset(ps);
- prs_set_offset(ps, buffer->string_at_end);
-
- /* read the string */
- if (!spoolss_smb_io_unistr(desc, string, ps, depth))
- return False;
-
- prs_set_offset(ps, old_offset);
+ *end_offset = ps->offset;
+ ps->offset = old_offset;
}
return True;
}
@@ -1287,74 +988,13 @@ static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR
* write a array UNICODE strings and its relative pointer.
* used by 2 RPC structs
********************************************************************/
-static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR ***string)
-{
- prs_struct *ps=&(buffer->prs);
-
- if (MARSHALLING(ps)) {
- uint32 struct_offset = prs_offset(ps);
- uint32 relative_offset;
- int i=0;
-
- while ( (*string)[i]!=0x0000 )
- i++;
- i--;
-
- /* count the ending NULL of the array */
- buffer->string_at_end -= 2;
-
- /* jfm: FIXME: write a (uint16) 0 for the ending NULL */
-
- do
- {
- buffer->string_at_end -= 2*(str_len_uni((*string)[i])+1);
- prs_set_offset(ps, buffer->string_at_end);
-
- /* write the string */
- if (!spoolss_smb_io_unistr(desc, (*string)[i], ps, depth))
- return False;
-
- i--;
- }
- while (i>=0);
-
- prs_set_offset(ps, struct_offset);
-
- relative_offset=buffer->string_at_end - buffer->struct_start;
- /* write its offset */
- if (!prs_uint32("offset", ps, depth, &relative_offset))
- return False;
- }
- else {
- uint32 old_offset;
-
- /* read the offset */
- if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
- return False;
-
- old_offset = prs_offset(ps);
- prs_set_offset(ps, buffer->string_at_end);
-
- /* read the string */
-
- /* jfm: FIXME: alloc memory and read all the strings until the string is NULL */
-
-/*
- if (!spoolss_smb_io_unistr(desc, string, ps, depth))
- return False;
-*/
- prs_set_offset(ps, old_offset);
- }
- return True;
-}
-
static BOOL smb_io_relarraystr(char *desc, prs_struct *ps, int depth, UNISTR ***buffer,
uint32 *start_offset, uint32 *end_offset)
{
int i=0;
uint32 struct_offset;
uint32 relative_offset;
- struct_offset=prs_offset(ps);
+ struct_offset=ps->offset;
while ( (*buffer)[i]!=0x0000 )
{
@@ -1369,14 +1009,14 @@ static BOOL smb_io_relarraystr(char *desc, prs_struct *ps, int depth, UNISTR ***
do
{
*end_offset-= 2*(str_len_uni((*buffer)[i])+1);
- prs_set_offset(ps, *end_offset);
+ ps->offset=*end_offset;
spoolss_smb_io_unistr(desc, (*buffer)[i], ps, depth);
i--;
}
while (i>=0);
- prs_set_offset(ps, struct_offset);
+ ps->offset=struct_offset;
relative_offset=*end_offset-*start_offset;
prs_uint32("offset", ps, depth, &(relative_offset));
@@ -1385,54 +1025,69 @@ static BOOL smb_io_relarraystr(char *desc, prs_struct *ps, int depth, UNISTR ***
}
/*******************************************************************
- Parse a DEVMODE structure and its relative pointer.
-********************************************************************/
-static BOOL new_smb_io_reldevmode(char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE *devmode)
+ * write a DEVICEMODE struct.
+ * on reading allocate memory for the private member
+ ********************************************************************/
+static BOOL smb_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_reldevmode");
+ prs_debug(ps, depth, desc, "smb_io_devmode");
depth++;
- if (MARSHALLING(ps)) {
- uint32 struct_offset = prs_offset(ps);
- uint32 relative_offset;
-
- buffer->string_at_end -= (devmode->size+devmode->driverextra);
-
- prs_set_offset(ps, buffer->string_at_end);
-
- /* write the DEVMODE */
- if (!spoolss_io_devmode(desc, ps, depth, devmode))
- return False;
-
- prs_set_offset(ps, struct_offset);
-
- relative_offset=buffer->string_at_end - buffer->struct_start;
- /* write its offset */
- if (!prs_uint32("offset", ps, depth, &relative_offset))
- return False;
- }
- else {
- uint32 old_offset;
-
- /* read the offset */
- if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end)))
- return False;
-
- old_offset = prs_offset(ps);
- prs_set_offset(ps, buffer->string_at_end + buffer->struct_start);
+ prs_uint16s(True,"devicename", ps, depth, devmode->devicename.buffer, 32);
+ prs_uint16("specversion", ps, depth, &(devmode->specversion));
+ prs_uint16("driverversion", ps, depth, &(devmode->driverversion));
+ prs_uint16("size", ps, depth, &(devmode->size));
+ prs_uint16("driverextra", ps, depth, &(devmode->driverextra));
+ prs_uint32("fields", ps, depth, &(devmode->fields));
+ prs_uint16("orientation", ps, depth, &(devmode->orientation));
+ prs_uint16("papersize", ps, depth, &(devmode->papersize));
+ prs_uint16("paperlength", ps, depth, &(devmode->paperlength));
+ prs_uint16("paperwidth", ps, depth, &(devmode->paperwidth));
+ prs_uint16("scale", ps, depth, &(devmode->scale));
+ prs_uint16("copies", ps, depth, &(devmode->copies));
+ prs_uint16("defaultsource", ps, depth, &(devmode->defaultsource));
+ prs_uint16("printquality", ps, depth, &(devmode->printquality));
+ prs_uint16("color", ps, depth, &(devmode->color));
+ prs_uint16("duplex", ps, depth, &(devmode->duplex));
+ prs_uint16("yresolution", ps, depth, &(devmode->yresolution));
+ prs_uint16("ttoption", ps, depth, &(devmode->ttoption));
+ prs_uint16("collate", ps, depth, &(devmode->collate));
+ prs_uint16s(True, "formname", ps, depth, devmode->formname.buffer, 32);
+ prs_uint16("logpixels", ps, depth, &(devmode->logpixels));
+ prs_uint32("bitsperpel", ps, depth, &(devmode->bitsperpel));
+ prs_uint32("pelswidth", ps, depth, &(devmode->pelswidth));
+ prs_uint32("pelsheight", ps, depth, &(devmode->pelsheight));
+ prs_uint32("displayflags", ps, depth, &(devmode->displayflags));
+ prs_uint32("displayfrequency", ps, depth, &(devmode->displayfrequency));
+ prs_uint32("icmmethod", ps, depth, &(devmode->icmmethod));
+ prs_uint32("icmintent", ps, depth, &(devmode->icmintent));
+ prs_uint32("mediatype", ps, depth, &(devmode->mediatype));
+ prs_uint32("dithertype", ps, depth, &(devmode->dithertype));
+ prs_uint32("reserved1", ps, depth, &(devmode->reserved1));
+ prs_uint32("reserved2", ps, depth, &(devmode->reserved2));
+ prs_uint32("panningwidth", ps, depth, &(devmode->panningwidth));
+ prs_uint32("panningheight", ps, depth, &(devmode->panningheight));
- /* read the string */
- if (!spoolss_io_devmode(desc, ps, depth, devmode))
- return False;
+ if (devmode->driverextra!=0)
+ {
+ if (ps->io)
+ {
+ devmode->private=(uint8 *)malloc(devmode->driverextra*sizeof(uint8));
+ DEBUG(7,("smb_io_devmode: allocated memory [%d] for private\n",devmode->driverextra));
+ }
+ DEBUG(7,("smb_io_devmode: parsing [%d] bytes of private\n",devmode->driverextra));
- prs_set_offset(ps, old_offset);
+ prs_uint8s(True, "private", ps, depth, devmode->private, devmode->driverextra);
+ DEBUG(8,("smb_io_devmode: parsed\n"));
}
+
return True;
}
-
+/*******************************************************************
+ * write a DEVMODE struct and its relative pointer.
+ * used by all the RPC structs passing a buffer
+ ********************************************************************/
static BOOL smb_io_reldevmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode,
uint32 *start_offset, uint32 *end_offset)
{
@@ -1442,13 +1097,13 @@ static BOOL smb_io_reldevmode(char *desc, prs_struct *ps, int depth, DEVICEMODE
prs_debug(ps, depth, desc, "smb_io_reldevmode");
depth++;
- struct_offset=prs_offset(ps);
+ struct_offset=ps->offset;
*end_offset-= (devmode->size+devmode->driverextra);
- prs_set_offset(ps, *end_offset);
+ ps->offset=*end_offset;
- spoolss_io_devmode(desc, ps, depth, devmode);
+ smb_io_devmode(desc, ps, depth, devmode);
- prs_set_offset(ps, struct_offset);
+ ps->offset=struct_offset;
relative_offset=*end_offset-*start_offset;
prs_uint32("offset", ps, depth, &(relative_offset));
@@ -1457,196 +1112,126 @@ static BOOL smb_io_reldevmode(char *desc, prs_struct *ps, int depth, DEVICEMODE
}
/*******************************************************************
- Parse a PRINTER_INFO_0 structure.
********************************************************************/
-BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth)
+static BOOL smb_io_printer_info_0(char *desc, PRINTER_INFO_0 *info, prs_struct *ps, int depth,
+ uint32 *start_offset, uint32 *end_offset)
{
- prs_struct *ps=&(buffer->prs);
-
prs_debug(ps, depth, desc, "smb_io_printer_info_0");
depth++;
+ *start_offset=ps->offset;
- buffer->struct_start=prs_offset(ps);
-
- if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
- return False;
- if (!new_smb_io_relstr("servername", buffer, depth, &info->servername))
- return False;
-
- if(!prs_uint32("cjobs", ps, depth, &info->cjobs))
- return False;
- if(!prs_uint32("attributes", ps, depth, &info->attributes))
- return False;
-
- if(!prs_uint32("unknown0", ps, depth, &info->unknown0))
- return False;
- if(!prs_uint32("unknown1", ps, depth, &info->unknown1))
- return False;
- if(!prs_uint32("unknown2", ps, depth, &info->unknown2))
- return False;
- if(!prs_uint32("unknown3", ps, depth, &info->unknown3))
- return False;
- if(!prs_uint32("unknown4", ps, depth, &info->unknown4))
- return False;
- if(!prs_uint32("unknown5", ps, depth, &info->unknown5))
- return False;
- if(!prs_uint32("unknown6", ps, depth, &info->unknown6))
- return False;
- if(!prs_uint16("majorversion", ps, depth, &info->majorversion))
- return False;
- if(!prs_uint16("buildversion", ps, depth, &info->buildversion))
- return False;
- if(!prs_uint32("unknown7", ps, depth, &info->unknown7))
- return False;
- if(!prs_uint32("unknown8", ps, depth, &info->unknown8))
- return False;
- if(!prs_uint32("unknown9", ps, depth, &info->unknown9))
- return False;
- if(!prs_uint32("unknown10", ps, depth, &info->unknown10))
- return False;
- if(!prs_uint32("unknown11", ps, depth, &info->unknown11))
- return False;
- if(!prs_uint32("unknown12", ps, depth, &info->unknown12))
- return False;
- if(!prs_uint32("unknown13", ps, depth, &info->unknown13))
- return False;
- if(!prs_uint32("unknown14", ps, depth, &info->unknown14))
- return False;
- if(!prs_uint32("unknown15", ps, depth, &info->unknown15))
- return False;
- if(!prs_uint32("unknown16", ps, depth, &info->unknown16))
- return False;
- if(!prs_uint32("unknown17", ps, depth, &info->unknown17))
- return False;
- if(!prs_uint32("unknown18", ps, depth, &info->unknown18))
- return False;
- if(!prs_uint32("status" , ps, depth, &info->status))
- return False;
- if(!prs_uint32("unknown20", ps, depth, &info->unknown20))
- return False;
- if(!prs_uint32("unknown21", ps, depth, &info->unknown21))
- return False;
- if(!prs_uint16("unknown22", ps, depth, &info->unknown22))
- return False;
- if(!prs_uint32("unknown23", ps, depth, &info->unknown23))
- return False;
+ smb_io_relstr("printername",ps, depth, &(info->printername), start_offset, end_offset);
+ smb_io_relstr("servername",ps, depth, &(info->servername), start_offset, end_offset);
+ prs_uint32("cjobs", ps, depth, &(info->cjobs));
+ prs_uint32("attributes", ps, depth, &(info->attributes));
+
+ prs_uint32("unknown0", ps, depth, &(info->unknown0));
+ prs_uint32("unknown1", ps, depth, &(info->unknown1));
+ prs_uint32("unknown2", ps, depth, &(info->unknown2));
+ prs_uint32("unknown3", ps, depth, &(info->unknown3));
+ prs_uint32("unknown4", ps, depth, &(info->unknown4));
+ prs_uint32("unknown5", ps, depth, &(info->unknown5));
+ prs_uint32("unknown6", ps, depth, &(info->unknown6));
+ prs_uint16("majorversion", ps, depth, &(info->majorversion));
+ prs_uint16("buildversion", ps, depth, &(info->buildversion));
+ prs_uint32("unknown7", ps, depth, &(info->unknown7));
+ prs_uint32("unknown8", ps, depth, &(info->unknown8));
+ prs_uint32("unknown9", ps, depth, &(info->unknown9));
+ prs_uint32("unknown10", ps, depth, &(info->unknown10));
+ prs_uint32("unknown11", ps, depth, &(info->unknown11));
+ prs_uint32("unknown12", ps, depth, &(info->unknown12));
+ prs_uint32("unknown13", ps, depth, &(info->unknown13));
+ prs_uint32("unknown14", ps, depth, &(info->unknown14));
+ prs_uint32("unknown15", ps, depth, &(info->unknown15));
+ prs_uint32("unknown16", ps, depth, &(info->unknown16));
+ prs_uint32("unknown17", ps, depth, &(info->unknown17));
+ prs_uint32("unknown18", ps, depth, &(info->unknown18));
+ prs_uint32("status" , ps, depth, &(info->status));
+ prs_uint32("unknown20", ps, depth, &(info->unknown20));
+ prs_uint32("unknown21", ps, depth, &(info->unknown21));
+ prs_uint16("unknown22", ps, depth, &(info->unknown22));
+ prs_uint32("unknown23", ps, depth, &(info->unknown23));
return True;
}
/*******************************************************************
- Parse a PRINTER_INFO_1 structure.
********************************************************************/
-BOOL new_smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth)
+static BOOL smb_io_printer_info_1(char *desc, PRINTER_INFO_1 *info, prs_struct *ps, int depth,
+ uint32 *start_offset, uint32 *end_offset)
{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_printer_info_1");
+ prs_debug(ps, depth, desc, "smb_io_printer_info_1");
depth++;
+ *start_offset=ps->offset;
- buffer->struct_start=prs_offset(ps);
-
- if (!prs_uint32("flags", ps, depth, &info->flags))
- return False;
- if (!new_smb_io_relstr("description", buffer, depth, &info->description))
- return False;
- if (!new_smb_io_relstr("name", buffer, depth, &info->name))
- return False;
- if (!new_smb_io_relstr("comment", buffer, depth, &info->comment))
- return False;
+ prs_uint32("flags", ps, depth, &(info->flags));
+ smb_io_relstr("description",ps, depth, &(info->description), start_offset, end_offset);
+ smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset);
+ smb_io_relstr("comment",ps, depth, &(info->comment), start_offset, end_offset);
return True;
}
/*******************************************************************
- Parse a PRINTER_INFO_2 structure.
********************************************************************/
-BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
+static BOOL smb_io_printer_info_2(char *desc, PRINTER_INFO_2 *info, prs_struct *ps, int depth,
+ uint32 *start_offset, uint32 *end_offset)
{
- /* hack for the SEC DESC */
uint32 pipo=0;
+ uint32 devmode_offset;
+ uint32 backup_offset;
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_printer_info_2");
+ prs_debug(ps, depth, desc, "smb_io_printer_info_2");
depth++;
+ *start_offset=ps->offset;
- buffer->struct_start=prs_offset(ps);
-
- if (!new_smb_io_relstr("servername", buffer, depth, &info->servername))
- return False;
- if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
- return False;
- if (!new_smb_io_relstr("sharename", buffer, depth, &info->sharename))
- return False;
- if (!new_smb_io_relstr("portname", buffer, depth, &info->portname))
- return False;
- if (!new_smb_io_relstr("drivername", buffer, depth, &info->drivername))
- return False;
- if (!new_smb_io_relstr("comment", buffer, depth, &info->comment))
- return False;
- if (!new_smb_io_relstr("location", buffer, depth, &info->location))
- return False;
-
- /* NT parses the DEVMODE at the end of the struct */
- if (!new_smb_io_reldevmode("devmode", buffer, depth, info->devmode))
- return False;
+ smb_io_relstr("servername", ps, depth, &(info->servername), start_offset, end_offset);
+ smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset);
+ smb_io_relstr("sharename", ps, depth, &(info->sharename), start_offset, end_offset);
+ smb_io_relstr("portname", ps, depth, &(info->portname), start_offset, end_offset);
+ smb_io_relstr("drivername", ps, depth, &(info->drivername), start_offset, end_offset);
+ smb_io_relstr("comment", ps, depth, &(info->comment), start_offset, end_offset);
+ smb_io_relstr("location", ps, depth, &(info->location), start_offset, end_offset);
+
+ devmode_offset=ps->offset;
+ ps->offset=ps->offset+4;
- if (!new_smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
- return False;
- if (!new_smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
- return False;
- if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype))
- return False;
- if (!new_smb_io_relstr("parameters", buffer, depth, &info->parameters))
- return False;
+ smb_io_relstr("sepfile", ps, depth, &(info->sepfile), start_offset, end_offset);
+ smb_io_relstr("printprocessor",ps, depth, &(info->printprocessor), start_offset, end_offset);
+ smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset);
+ smb_io_relstr("parameters", ps, depth, &(info->parameters), start_offset, end_offset);
+
+ prs_uint32("security descriptor", ps, depth, &(pipo));
+
+ prs_uint32("attributes", ps, depth, &(info->attributes));
+ prs_uint32("priority", ps, depth, &(info->priority));
+ prs_uint32("defpriority", ps, depth, &(info->defaultpriority));
+ prs_uint32("starttime", ps, depth, &(info->starttime));
+ prs_uint32("untiltime", ps, depth, &(info->untiltime));
+ prs_uint32("status", ps, depth, &(info->status));
+ prs_uint32("jobs", ps, depth, &(info->cjobs));
+ prs_uint32("averageppm", ps, depth, &(info->averageppm));
- if (!prs_uint32("security descriptor", ps, depth, &pipo))
- return False;
- if (!prs_uint32("attributes", ps, depth, &info->attributes))
- return False;
- if (!prs_uint32("priority", ps, depth, &info->priority))
- return False;
- if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority))
- return False;
- if (!prs_uint32("starttime", ps, depth, &info->starttime))
- return False;
- if (!prs_uint32("untiltime", ps, depth, &info->untiltime))
- return False;
- if (!prs_uint32("status", ps, depth, &info->status))
- return False;
- if (!prs_uint32("jobs", ps, depth, &info->cjobs))
- return False;
- if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
- return False;
+ /*
+ I'm not sure if putting the devmode at the end the struct is worth it
+ but NT does it
+ */
+ backup_offset=ps->offset;
+ ps->offset=devmode_offset;
+ smb_io_reldevmode("devmode", ps, depth, info->devmode, start_offset, end_offset);
+ ps->offset=backup_offset;
return True;
}
/*******************************************************************
- Parse a DRIVER_INFO_1 structure.
-********************************************************************/
-BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth)
-{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_1");
- depth++;
-
- buffer->struct_start=prs_offset(ps);
-
- if (!new_smb_io_relstr("name", buffer, depth, &info->name))
- return False;
-
- return True;
-}
-
+********************************************************************/
static BOOL smb_io_printer_driver_info_1(char *desc, DRIVER_INFO_1 *info, prs_struct *ps, int depth,
uint32 *start_offset, uint32 *end_offset)
{
prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1");
depth++;
- *start_offset=prs_offset(ps);
+ *start_offset=ps->offset;
smb_io_relstr("name", ps, depth, &(info->name), start_offset, end_offset);
@@ -1654,39 +1239,13 @@ static BOOL smb_io_printer_driver_info_1(char *desc, DRIVER_INFO_1 *info, prs_st
}
/*******************************************************************
- Parse a DRIVER_INFO_2 structure.
-********************************************************************/
-BOOL new_smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth)
-{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_2");
- depth++;
-
- buffer->struct_start=prs_offset(ps);
-
- if (!prs_uint32("version", ps, depth, &info->version))
- return False;
- if (!new_smb_io_relstr("name", buffer, depth, &info->name))
- return False;
- if (!new_smb_io_relstr("architecture", buffer, depth, &info->architecture))
- return False;
- if (!new_smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
- return False;
- if (!new_smb_io_relstr("datafile", buffer, depth, &info->datafile))
- return False;
- if (!new_smb_io_relstr("configfile", buffer, depth, &info->configfile))
- return False;
-
- return True;
-}
-
+********************************************************************/
static BOOL smb_io_printer_driver_info_2(char *desc, DRIVER_INFO_2 *info,prs_struct *ps, int depth,
uint32 *start_offset, uint32 *end_offset)
{
prs_debug(ps, depth, desc, "smb_io_printer_xxx");
depth++;
- *start_offset=prs_offset(ps);
+ *start_offset=ps->offset;
prs_uint32("version", ps, depth, &(info->version));
smb_io_relstr("name", ps, depth, &(info->name), start_offset, end_offset);
@@ -1699,49 +1258,13 @@ static BOOL smb_io_printer_driver_info_2(char *desc, DRIVER_INFO_2 *info,prs_str
}
/*******************************************************************
- Parse a DRIVER_INFO_3 structure.
-********************************************************************/
-BOOL new_smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth)
-{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_3");
- depth++;
-
- buffer->struct_start=prs_offset(ps);
-
- if (!prs_uint32("version", ps, depth, &info->version))
- return False;
- if (!new_smb_io_relstr("name", buffer, depth, &info->name))
- return False;
- if (!new_smb_io_relstr("architecture", buffer, depth, &info->architecture))
- return False;
- if (!new_smb_io_relstr("driverpath", buffer, depth, &info->driverpath))
- return False;
- if (!new_smb_io_relstr("datafile", buffer, depth, &info->datafile))
- return False;
- if (!new_smb_io_relstr("configfile", buffer, depth, &info->configfile))
- return False;
- if (!new_smb_io_relstr("helpfile", buffer, depth, &info->helpfile))
- return False;
-
- if (!new_smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles))
- return False;
-
- if (!new_smb_io_relstr("monitorname", buffer, depth, &info->monitorname))
- return False;
- if (!new_smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype))
- return False;
-
- return True;
-}
-
+********************************************************************/
static BOOL smb_io_printer_driver_info_3(char *desc, DRIVER_INFO_3 *info,prs_struct *ps, int depth,
uint32 *start_offset, uint32 *end_offset)
{
prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3");
depth++;
- *start_offset=prs_offset(ps);
+ *start_offset=ps->offset;
prs_uint32("version", ps, depth, &(info->version));
smb_io_relstr("name", ps, depth, &(info->name), start_offset, end_offset);
@@ -1760,262 +1283,80 @@ static BOOL smb_io_printer_driver_info_3(char *desc, DRIVER_INFO_3 *info,prs_str
}
/*******************************************************************
- Parse a JOB_INFO_1 structure.
********************************************************************/
-BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth)
+static BOOL smb_io_job_info_1(char *desc, JOB_INFO_1 *info, prs_struct *ps, int depth,
+ uint32 *start_offset, uint32 *end_offset)
{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_job_info_1");
+ prs_debug(ps, depth, desc, "smb_io_job_info_1");
depth++;
+ *start_offset=ps->offset;
- buffer->struct_start=prs_offset(ps);
-
- if (!prs_uint32("jobid", ps, depth, &info->jobid))
- return False;
- if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
- return False;
- if (!new_smb_io_relstr("machinename", buffer, depth, &info->machinename))
- return False;
- if (!new_smb_io_relstr("username", buffer, depth, &info->username))
- return False;
- if (!new_smb_io_relstr("document", buffer, depth, &info->document))
- return False;
- if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype))
- return False;
- if (!new_smb_io_relstr("text_status", buffer, depth, &info->text_status))
- return False;
- if (!prs_uint32("status", ps, depth, &info->status))
- return False;
- if (!prs_uint32("priority", ps, depth, &info->priority))
- return False;
- if (!prs_uint32("position", ps, depth, &info->position))
- return False;
- if (!prs_uint32("totalpages", ps, depth, &info->totalpages))
- return False;
- if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted))
- return False;
- if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted))
- return False;
+ prs_uint32("jobid", ps, depth, &(info->jobid));
+ smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset);
+ smb_io_relstr("machinename", ps, depth, &(info->machinename), start_offset, end_offset);
+ smb_io_relstr("username", ps, depth, &(info->username), start_offset, end_offset);
+ smb_io_relstr("document", ps, depth, &(info->document), start_offset, end_offset);
+ smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset);
+ smb_io_relstr("text_status", ps, depth, &(info->text_status), start_offset, end_offset);
+ prs_uint32("status", ps, depth, &(info->status));
+ prs_uint32("priority", ps, depth, &(info->priority));
+ prs_uint32("position", ps, depth, &(info->position));
+ prs_uint32("totalpages", ps, depth, &(info->totalpages));
+ prs_uint32("pagesprinted", ps, depth, &(info->pagesprinted));
+ spoolss_io_system_time("submitted", ps, depth, &(info->submitted) );
return True;
}
/*******************************************************************
- Parse a JOB_INFO_2 structure.
********************************************************************/
-BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth)
+static BOOL smb_io_job_info_2(char *desc, JOB_INFO_2 *info, prs_struct *ps, int depth,
+ uint32 *start_offset, uint32 *end_offset)
{
int pipo=0;
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_job_info_2");
+ prs_debug(ps, depth, desc, "smb_io_job_info_2");
depth++;
-
- buffer->struct_start=prs_offset(ps);
+ *start_offset=ps->offset;
- if (!prs_uint32("jobid",ps, depth, &info->jobid))
- return False;
- if (!new_smb_io_relstr("printername", buffer, depth, &info->printername))
- return False;
- if (!new_smb_io_relstr("machinename", buffer, depth, &info->machinename))
- return False;
- if (!new_smb_io_relstr("username", buffer, depth, &info->username))
- return False;
- if (!new_smb_io_relstr("document", buffer, depth, &info->document))
- return False;
- if (!new_smb_io_relstr("notifyname", buffer, depth, &info->notifyname))
- return False;
- if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype))
- return False;
-
- if (!new_smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
- return False;
- if (!new_smb_io_relstr("parameters", buffer, depth, &info->parameters))
- return False;
- if (!new_smb_io_relstr("drivername", buffer, depth, &info->drivername))
- return False;
- if (!new_smb_io_reldevmode("devmode", buffer, depth, info->devmode))
- return False;
- if (!new_smb_io_relstr("text_status", buffer, depth, &info->text_status))
- return False;
+ prs_uint32("jobid", ps, depth, &(info->jobid));
+ smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset);
+ smb_io_relstr("machinename", ps, depth, &(info->machinename), start_offset, end_offset);
+ smb_io_relstr("username", ps, depth, &(info->username), start_offset, end_offset);
+ smb_io_relstr("document", ps, depth, &(info->document), start_offset, end_offset);
+ smb_io_relstr("notifyname", ps, depth, &(info->notifyname), start_offset, end_offset);
+ smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset);
+
+ smb_io_relstr("printprocessor", ps, depth, &(info->printprocessor), start_offset, end_offset);
+ smb_io_relstr("parameters", ps, depth, &(info->parameters), start_offset, end_offset);
+ smb_io_relstr("drivername", ps, depth, &(info->drivername), start_offset, end_offset);
+ smb_io_reldevmode("devmode", ps, depth, info->devmode, start_offset, end_offset);
+ smb_io_relstr("text_status", ps, depth, &(info->text_status), start_offset, end_offset);
/* SEC_DESC sec_desc;*/
- if (!prs_uint32("Hack! sec desc", ps, depth, &pipo))
- return False;
-
- if (!prs_uint32("status",ps, depth, &info->status))
- return False;
- if (!prs_uint32("priority",ps, depth, &info->priority))
- return False;
- if (!prs_uint32("position",ps, depth, &info->position))
- return False;
- if (!prs_uint32("starttime",ps, depth, &info->starttime))
- return False;
- if (!prs_uint32("untiltime",ps, depth, &info->untiltime))
- return False;
- if (!prs_uint32("totalpages",ps, depth, &info->totalpages))
- return False;
- if (!prs_uint32("size",ps, depth, &info->size))
- return False;
- if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) )
- return False;
- if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed))
- return False;
- if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-BOOL new_smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth)
-{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_form_1");
- depth++;
-
- buffer->struct_start=prs_offset(ps);
-
- if (!prs_uint32("flag", ps, depth, &(info->flag)))
- return False;
-
- if (!new_smb_io_relstr("name", buffer, depth, &(info->name)))
- return False;
-
- if (!prs_uint32("width", ps, depth, &(info->width)))
- return False;
- if (!prs_uint32("length", ps, depth, &(info->length)))
- return False;
- if (!prs_uint32("left", ps, depth, &(info->left)))
- return False;
- if (!prs_uint32("top", ps, depth, &(info->top)))
- return False;
- if (!prs_uint32("right", ps, depth, &(info->right)))
- return False;
- if (!prs_uint32("bottom", ps, depth, &(info->bottom)))
- return False;
+ prs_uint32("Hack! sec desc", ps, depth, &pipo);
+
+ prs_uint32("status", ps, depth, &(info->status));
+ prs_uint32("priority", ps, depth, &(info->priority));
+ prs_uint32("position", ps, depth, &(info->position));
+ prs_uint32("starttime", ps, depth, &(info->starttime));
+ prs_uint32("untiltime", ps, depth, &(info->untiltime));
+ prs_uint32("totalpages", ps, depth, &(info->totalpages));
+ prs_uint32("size", ps, depth, &(info->size));
+ spoolss_io_system_time("submitted", ps, depth, &(info->submitted) );
+ prs_uint32("timeelapsed", ps, depth, &(info->timeelapsed));
+ prs_uint32("pagesprinted", ps, depth, &(info->pagesprinted));
return True;
}
/*******************************************************************
- Read/write a BUFFER struct.
-********************************************************************/
-static BOOL new_spoolss_io_buffer(char *desc, prs_struct *ps, int depth, NEW_BUFFER *buffer)
-{
- if (buffer == NULL)
- return False;
-
- prs_debug(ps, depth, desc, "new_spoolss_io_buffer");
- depth++;
-
- if (!prs_uint32("ptr", ps, depth, &(buffer->ptr)))
- return False;
-
- /* reading */
- if (UNMARSHALLING(ps)) {
- buffer->size=0;
- buffer->string_at_end=0;
-
- if (buffer->ptr==0) {
- if (!prs_init(&(buffer->prs), 0, 4, UNMARSHALL))
- return False;
- return True;
- }
-
- if (!prs_uint32("size", ps, depth, &buffer->size))
- return False;
-
- if (!prs_init(&(buffer->prs), buffer->size, 4, UNMARSHALL))
- return False;
-
- if (!prs_append_some_prs_data(&(buffer->prs), ps, prs_offset(ps), buffer->size))
- return False;
-
- if (!prs_set_offset(&buffer->prs, 0))
- return False;
-
- if (!prs_set_offset(ps, buffer->size+prs_offset(ps)))
- return False;
-
- buffer->string_at_end=buffer->size;
-
- return True;
- }
- else {
- /* writing */
- if (buffer->ptr==0)
- return True;
-
- if (!prs_uint32("size", ps, depth, &(buffer->size)))
- return False;
- if (!prs_append_some_prs_data(ps, &(buffer->prs), 0, buffer->size))
- return False;
- }
-}
-
-/*******************************************************************
- move a BUFFER from the query to the reply.
-********************************************************************/
-void new_spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest)
-{
- prs_switch_type(&(src->prs), MARSHALL);
- prs_set_offset(&(src->prs), 0);
- prs_force_dynamic(&(src->prs));
-
- *dest=src;
-}
-
-/*******************************************************************
- create a BUFFER struct.
-********************************************************************/
-void new_spoolss_allocate_buffer(NEW_BUFFER **buffer)
-{
- if (buffer==NULL)
- return;
-
- *buffer=(NEW_BUFFER *)malloc(sizeof(NEW_BUFFER));
-
- (*buffer)->ptr=0x0;
- (*buffer)->size=0;
- (*buffer)->string_at_end=0;
-}
-
-/*******************************************************************
- Destroy a BUFFER struct.
-********************************************************************/
-void new_spoolss_free_buffer(NEW_BUFFER *buffer)
-{
- if (buffer==NULL)
- return;
-
- prs_mem_free(&(buffer->prs));
- buffer->ptr=0x0;
- buffer->size=0;
- buffer->string_at_end=0;
-
- free(buffer);
-}
-
-/*******************************************************************
- Get the size of a BUFFER struct.
-********************************************************************/
-uint32 new_get_buffer_size(NEW_BUFFER *buffer)
-{
- return (buffer->size);
-}
-
-/*******************************************************************
********************************************************************/
static BOOL smb_io_form_1(char *desc, FORM_1 *info, prs_struct *ps, int depth,
uint32 *start_offset, uint32 *end_offset)
{
prs_debug(ps, depth, desc, "smb_io_form_1");
depth++;
- *start_offset=prs_offset(ps);
+ *start_offset=ps->offset;
prs_uint32("flag", ps, depth, &(info->flag));
smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset);
@@ -2030,73 +1371,13 @@ static BOOL smb_io_form_1(char *desc, FORM_1 *info, prs_struct *ps, int depth,
}
/*******************************************************************
- Parse a DRIVER_DIRECTORY_1 structure.
********************************************************************/
-BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth)
-{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_driverdir_1");
- depth++;
-
- buffer->struct_start=prs_offset(ps);
-
- if(!new_smb_io_relstr("name", buffer, depth, &info->name))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Parse a PORT_INFO_1 structure.
-********************************************************************/
-BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth)
-{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_port_1");
- depth++;
-
- buffer->struct_start=prs_offset(ps);
-
- if(!new_smb_io_relstr("port_name", buffer, depth, &info->port_name))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Parse a PORT_INFO_2 structure.
-********************************************************************/
-BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth)
-{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "new_smb_io_port_2");
- depth++;
-
- buffer->struct_start=prs_offset(ps);
-
- if(!new_smb_io_relstr("port_name", buffer, depth, &info->port_name))
- return False;
- if(!new_smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name))
- return False;
- if(!new_smb_io_relstr("description", buffer, depth, &info->description))
- return False;
- if(!prs_uint32("port_type", ps, depth, &info->port_type))
- return False;
- if(!prs_uint32("reserved", ps, depth, &info->reserved))
- return False;
-
- return True;
-}
-
static BOOL smb_io_port_2(char *desc, PORT_INFO_2 *info, prs_struct *ps, int depth,
uint32 *start_offset, uint32 *end_offset)
{
- prs_debug(ps, depth, desc, "smb_io_port_2");
+ prs_debug(ps, depth, desc, "smb_io_form_1");
depth++;
- *start_offset=prs_offset(ps);
+ *start_offset=ps->offset;
smb_io_relstr("port_name",ps, depth, &(info->port_name), start_offset, end_offset);
smb_io_relstr("monitor_name",ps, depth, &(info->monitor_name), start_offset, end_offset);
@@ -2109,72 +1390,28 @@ static BOOL smb_io_port_2(char *desc, PORT_INFO_2 *info, prs_struct *ps, int dep
/*******************************************************************
********************************************************************/
-BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth)
-{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1");
- depth++;
-
- buffer->struct_start=prs_offset(ps);
-
- if (new_smb_io_relstr("name", buffer, depth, &info->name))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-BOOL smb_io_printprocdatatype_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth)
-{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1");
- depth++;
-
- buffer->struct_start=prs_offset(ps);
-
- if (new_smb_io_relstr("name", buffer, depth, &info->name))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
-BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth)
+static BOOL smb_io_processor_info_1(char *desc, PRINTPROCESSOR_1 *info, prs_struct *ps, int depth,
+ uint32 *start_offset, uint32 *end_offset)
{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1");
+ prs_debug(ps, depth, desc, "smb_io_processor_info_1");
depth++;
+ *start_offset=ps->offset;
- buffer->struct_start=prs_offset(ps);
-
- if (!new_smb_io_relstr("name", buffer, depth, &info->name))
- return False;
+ smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset);
return True;
}
/*******************************************************************
********************************************************************/
-BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth)
+static BOOL smb_io_monitor_info_1(char *desc, PRINTMONITOR_1 *info, prs_struct *ps, int depth,
+ uint32 *start_offset, uint32 *end_offset)
{
- prs_struct *ps=&(buffer->prs);
-
- prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2");
+ prs_debug(ps, depth, desc, "smb_io_monitor_info_1");
depth++;
+ *start_offset=ps->offset;
- buffer->struct_start=prs_offset(ps);
-
- if (!new_smb_io_relstr("name", buffer, depth, &info->name))
- return False;
- if (!new_smb_io_relstr("environment", buffer, depth, &info->environment))
- return False;
- if (!new_smb_io_relstr("dll_name", buffer, depth, &info->dll_name))
- return False;
+ smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset);
return True;
}
@@ -2182,24 +1419,22 @@ BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *
/*******************************************************************
return the size required by a struct in the stream
********************************************************************/
-uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
+static uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info)
{
int size=0;
-
- size+=24*4;
- size+=6;
-
+
size+=size_of_uint32( &(info->attributes) );
size+=size_of_relative_string( &(info->printername) );
size+=size_of_relative_string( &(info->servername) );
+ return (size);
- return size;
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
********************************************************************/
-uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
+static uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
{
int size=0;
@@ -2207,14 +1442,15 @@ uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info)
size+=size_of_relative_string( &(info->description) );
size+=size_of_relative_string( &(info->name) );
size+=size_of_relative_string( &(info->comment) );
+ return (size);
- return size;
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
-********************************************************************/
-uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
+********************************************************************/
+static uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
{
int size=0;
@@ -2243,26 +1479,33 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
size+=size_of_uint32( &(info->status) );
size+=size_of_uint32( &(info->cjobs) );
size+=size_of_uint32( &(info->averageppm) );
- return size;
+ return (size);
+
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
-********************************************************************/
-uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
+********************************************************************/
+static uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info)
{
int size=0;
+ DEBUG(9,("Sizing driver info_1\n"));
size+=size_of_relative_string( &(info->name) );
- return size;
+ DEBUGADD(9,("size: [%d]\n", size));
+ return (size);
+
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
-********************************************************************/
-uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
+********************************************************************/
+static uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
{
int size=0;
+ DEBUG(9,("Sizing driver info_2\n"));
size+=size_of_uint32( &(info->version) );
size+=size_of_relative_string( &(info->name) );
size+=size_of_relative_string( &(info->architecture) );
@@ -2270,18 +1513,22 @@ uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info)
size+=size_of_relative_string( &(info->datafile) );
size+=size_of_relative_string( &(info->configfile) );
- return size;
+ DEBUGADD(9,("size: [%d]\n", size));
+ return (size);
+
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
-********************************************************************/
-uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
+********************************************************************/
+static uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
{
int size=0;
UNISTR **string;
int i=0;
+ DEBUG(9,("Sizing driver info_3\n"));
size+=size_of_uint32( &(info->version) );
size+=size_of_relative_string( &(info->name) );
size+=size_of_relative_string( &(info->architecture) );
@@ -2301,13 +1548,16 @@ uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info)
}
size+=6;
- return size;
+ DEBUGADD(9,("size: [%d]\n", size));
+ return (size);
+
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
********************************************************************/
-uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
+static uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
{
int size=0;
size+=size_of_uint32( &(info->jobid) );
@@ -2323,14 +1573,15 @@ uint32 spoolss_size_job_info_1(JOB_INFO_1 *info)
size+=size_of_uint32( &(info->totalpages) );
size+=size_of_uint32( &(info->pagesprinted) );
size+=size_of_systemtime( &(info->submitted) );
+ return (size);
- return size;
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
********************************************************************/
-uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
+static uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
{
int size=0;
@@ -2359,14 +1610,15 @@ uint32 spoolss_size_job_info_2(JOB_INFO_2 *info)
size+=size_of_systemtime( &(info->submitted) );
size+=size_of_uint32( &(info->timeelapsed) );
size+=size_of_uint32( &(info->pagesprinted) );
+ return (size);
- return size;
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
-********************************************************************/
-uint32 spoolss_size_form_1(FORM_1 *info)
+********************************************************************/
+static uint32 spoolss_size_form_1(FORM_1 *info)
{
int size=0;
@@ -2379,131 +1631,171 @@ uint32 spoolss_size_form_1(FORM_1 *info)
size+=size_of_uint32( &(info->right) );
size+=size_of_uint32( &(info->bottom) );
- return size;
+ return (size);
+
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
********************************************************************/
-uint32 spoolss_size_port_info_1(PORT_INFO_1 *info)
+static uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
{
int size=0;
- size+=size_of_relative_string( &info->port_name );
+ size+=size_of_relative_string( &(info->port_name) );
+ size+=size_of_relative_string( &(info->monitor_name) );
+ size+=size_of_relative_string( &(info->description) );
+
+ size+=size_of_uint32( &(info->port_type) );
+ size+=size_of_uint32( &(info->reserved) );
- return size;
+ return (size);
+
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
********************************************************************/
-uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info)
+static uint32 spoolss_size_processor_info_1(PRINTPROCESSOR_1 *info)
{
int size=0;
+ size+=size_of_relative_string( &(info->name) );
- size+=size_of_relative_string( &info->name );
+ return (size);
- return size;
+ return True;
}
/*******************************************************************
return the size required by a struct in the stream
********************************************************************/
-uint32 spoolss_size_port_info_2(PORT_INFO_2 *info)
+static uint32 spoolss_size_monitor_info_1(PRINTMONITOR_1 *info)
{
int size=0;
+ size+=size_of_relative_string( &(info->name) );
- size+=size_of_relative_string( &info->port_name );
- size+=size_of_relative_string( &info->monitor_name );
- size+=size_of_relative_string( &info->description );
-
- size+=size_of_uint32( &info->port_type );
- size+=size_of_uint32( &info->reserved );
+ return (size);
- return size;
+ return True;
}
/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info)
+ * make a structure.
+ ********************************************************************/
+static BOOL make_spoolss_buffer(BUFFER* buffer, uint32 size)
{
- int size=0;
- size+=size_of_relative_string( &info->name );
+ buffer->ptr = (size != 0) ? 1 : 0;
+ buffer->size = size;
+ buffer->data = (uint8 *)Realloc( NULL, (buffer->size) * sizeof(uint8) );
- return size;
+ return (buffer->data != NULL || size == 0);
}
/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info)
+ * read a uint8 buffer of size *size.
+ * allocate memory for it
+ * return a pointer to the allocated memory and the size
+ * return NULL and a size of 0 if the buffer is empty
+ *
+ * jfmxxxx: fix it to also write a buffer
+ ********************************************************************/
+static BOOL spoolss_io_read_buffer(char *desc, prs_struct *ps, int depth, BUFFER *buffer)
{
- int size=0;
- size+=size_of_relative_string( &info->name );
+ prs_debug(ps, depth, desc, "spoolss_io_read_buffer");
+ depth++;
- return size;
-}
+ prs_align(ps);
-/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info)
-{
- int size=0;
- size+=size_of_relative_string( &info->name );
+ prs_uint32("pointer", ps, depth, &(buffer->ptr));
+
+ if (buffer->ptr != 0x0000)
+ {
+ prs_uint32("size", ps, depth, &(buffer->size));
+ if (ps->io)
+ {
+ /* reading */
+ buffer->data=(uint8 *)Realloc(NULL, buffer->size * sizeof(uint8) );
+ }
+ if (buffer->data == NULL)
+ {
+ return False;
+ }
+ prs_uint8s(True, "buffer", ps, depth, buffer->data, buffer->size);
+ prs_align(ps);
- return size;
+ }
+ else
+ {
+ if (ps->io)
+ {
+ /* reading */
+ buffer->data=0x0000;
+ buffer->size=0x0000;
+ }
+ }
+
+ if (!ps->io)
+ {
+ /* writing */
+ if (buffer->data != NULL)
+ {
+ free(buffer->data);
+ }
+ buffer->data = NULL;
+ }
+ return True;
}
/*******************************************************************
-return the size required by a struct in the stream
-********************************************************************/
-uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info)
+ * read a uint8 buffer of size *size.
+ * allocate memory for it
+ * return a pointer to the allocated memory and the size
+ * return NULL and a size of 0 if the buffer is empty
+ *
+ * jfmxxxx: fix it to also write a buffer
+ ********************************************************************/
+BOOL spoolss_io_free_buffer(BUFFER *buffer)
{
- int size=0;
- size+=size_of_relative_string( &info->name);
- size+=size_of_relative_string( &info->environment);
- size+=size_of_relative_string( &info->dll_name);
+ DEBUG(8,("spoolss_io_free_buffer\n"));
+
+ if (buffer->ptr != 0x0000)
+ {
+ free(buffer->data);
+ }
- return size;
+ return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_getprinterdriver2 (srv_spoolss.c)
********************************************************************/
-BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth)
+BOOL spoolss_io_q_getprinterdriver2(char *desc,
+ SPOOL_Q_GETPRINTERDRIVER2 *q_u,
+ prs_struct *ps, int depth)
{
+ uint32 useless_ptr;
prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth))
- return False;
- if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr))
- return False;
- if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth))
- return False;
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ smb_io_unistr2("architecture", &(q_u->architecture),True,ps,depth);
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("level", ps, depth, &q_u->level))
- return False;
-
- if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
+ prs_align(ps);
+
+ prs_uint32("level", ps, depth, &(q_u->level));
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
-
- if(!prs_uint32("unknown", ps, depth, &q_u->unknown))
- return False;
+ prs_uint32("buffer size", ps, depth, &(q_u->buf_size));
+ DEBUG(0,("spoolss_io_q_getprinterdriver2: renamed status - unknown\n"));
+ prs_uint32("unknown", ps, depth, &(q_u->unknown));
return True;
}
@@ -2512,94 +1804,384 @@ BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u,
* read a structure.
* called from spoolss_getprinterdriver2 (srv_spoolss.c)
********************************************************************/
-BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth)
+BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u,
+ prs_struct *ps, int depth)
{
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+ uint32 pipo=0;
+ DRIVER_INFO_1 *info1;
+ DRIVER_INFO_2 *info2;
+ DRIVER_INFO_3 *info3;
+
prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2");
depth++;
- if (!prs_align(ps))
- return False;
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+
+ info1 = r_u->ctr.driver.info1;
+ info2 = r_u->ctr.driver.info2;
+ info3 = r_u->ctr.driver.info3;
+
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ bufsize_required += spoolss_size_printer_driver_info_1(info1);
+ break;
+ }
+ case 2:
+ {
+ bufsize_required += spoolss_size_printer_driver_info_2(info2);
+ break;
+ }
+ case 3:
+ {
+ bufsize_required += spoolss_size_printer_driver_info_3(info3);
+ break;
+ }
+ }
+
+ if (ps->io)
+ {
+ /* reading */
+ r_u->offered = bufsize_required;
+ }
+
+ DEBUG(4,("spoolss_io_r_getprinterdriver2, size needed: %d\n",bufsize_required));
+ DEBUG(4,("spoolss_io_r_getprinterdriver2, size offered: %d\n",r_u->offered));
+
+ /* check if the buffer is big enough for the datas */
+ if (r_u->offered < bufsize_required)
+ {
+ /* it's too small */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered=0; /* don't send back the buffer */
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
+ DEBUG(4,("spoolss_io_r_getprinterdriver2, buffer too small\n"));
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
- if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0))
- return False;
- if (!prs_uint32("unknown1", ps, depth, &r_u->unknown1))
- return False;
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ DEBUG(4,("spoolss_io_r_getprinterdriver2, buffer large enough\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
+
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ smb_io_printer_driver_info_1(desc,
+ info1,
+ ps,
+ depth,
+ &start_offset,
+ &end_offset);
+ break;
+ }
+ case 2:
+ {
+ smb_io_printer_driver_info_2(desc,
+ info2,
+ ps,
+ depth,
+ &start_offset,
+ &end_offset);
+ break;
+ }
+ case 3:
+ {
+ smb_io_printer_driver_info_3(desc,
+ info3,
+ ps,
+ depth,
+ &start_offset,
+ &end_offset);
+ break;
+ }
+
+ }
+
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+
+ if (!ps->io)
+ {
+ /* writing */
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ safe_free(info1);
+ break;
+ }
+ case 2:
+ {
+ safe_free(info2);
+ break;
+ }
+ case 3:
+ {
+ if (info3!=NULL)
+ {
+ UNISTR **dependentfiles;
+ int j=0;
+ dependentfiles=info3->dependentfiles;
+ while ( dependentfiles[j] != NULL )
+ {
+ free(dependentfiles[j]);
+ j++;
+ }
+ free(dependentfiles);
+
+ free(info3);
+ }
+ break;
+ }
+
+ }
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("pipo", ps, depth, &pipo);
+ prs_uint32("pipo", ps, depth, &pipo);
+ prs_uint32("status", ps, depth, &(r_u->status));
- return True;
+ return True;
+}
+
+/*******************************************************************
+ * make a structure.
+ ********************************************************************/
+BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u,
+ uint32 flags,
+ const char* servername,
+ uint32 level,
+ uint32 size)
+{
+ size_t len_name = servername != NULL ? strlen(servername) : 0;
+
+ DEBUG(5,("make_spoolss_q_enumprinters. size: %d\n", size));
+
+ q_u->flags = flags;
+
+ make_unistr2(&q_u->servername, servername, len_name);
+
+ q_u->level = level;
+ make_spoolss_buffer(&q_u->buffer, size);
+ q_u->buf_size = size;
+
+ return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_enumprinters (srv_spoolss.c)
********************************************************************/
-BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth)
+BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u,
+ prs_struct *ps, int depth)
{
+ uint32 useless_ptr = 0x01;
prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters");
depth++;
- if (!prs_align(ps))
- return False;
+ prs_align(ps);
- if (!prs_uint32("flags", ps, depth, &q_u->flags))
- return False;
- if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr))
- return False;
+ prs_uint32("flags", ps, depth, &(q_u->flags));
+ prs_uint32("useless ptr", ps, depth, &useless_ptr);
- if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth))
- return False;
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("level", ps, depth, &q_u->level))
- return False;
+ smb_io_unistr2("", &q_u->servername,True,ps,depth);
+ prs_align(ps);
- if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
+ prs_uint32("level", ps, depth, &(q_u->level));
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ spoolss_io_read_buffer("buffer", ps, depth, &(q_u->buffer));
+
+ prs_uint32("buf_size", ps, depth, &q_u->buf_size);
return True;
}
+/****************************************************************************
+****************************************************************************/
+void free_r_enumprinters(SPOOL_R_ENUMPRINTERS *r_u)
+{
+ DEBUG(4,("free_enum_printers_info: [%d] structs to free at level [%d]\n", r_u->returned, r_u->level));
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ free_print1_array(r_u->returned, r_u->ctr.printer.printers_1);
+ break;
+ }
+ case 2:
+ {
+ free_print2_array(r_u->returned, r_u->ctr.printer.printers_2);
+ break;
+ }
+ }
+}
+
/*******************************************************************
- Parse a SPOOL_R_ENUMPRINTERS structure.
+ * write a structure.
+ * called from spoolss_r_enum_printers (srv_spoolss.c)
+ *
********************************************************************/
-BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "new_spoolss_io_r_enumprinters");
+BOOL spoolss_io_r_enumprinters(char *desc,
+ SPOOL_R_ENUMPRINTERS *r_u,
+ prs_struct *ps, int depth)
+{
+ uint32 useless_ptr=0xADDE0FF0;
+ int i;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+ uint32 tmp_ct = 0;
+
+ PRINTER_INFO_1 *info1;
+ PRINTER_INFO_2 *info2;
+ fstring tmp;
+
+ slprintf(tmp, sizeof(tmp)-1, "spoolss_io_r_enumprinters %d", r_u->level);
+
+ prs_debug(ps, depth, desc, tmp);
depth++;
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
- if (!prs_align(ps))
- return False;
-
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
+ if (!ps->io)
+ {
+ /* writing */
+ for(i=0;i<r_u->returned;i++)
+ {
+ switch (r_u->level)
+ {
+ case 1:
+ info1 = r_u->ctr.printer.printers_1[i];
+ bufsize_required += spoolss_size_printer_info_1(info1);
+ break;
+ case 2:
+ info2 = r_u->ctr.printer.printers_2[i];
+ bufsize_required += spoolss_size_printer_info_2(info2);
+ break;
+ }
+ }
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
+ DEBUG(4,("spoolss_io_r_enumprinters, size needed: %d\n",bufsize_required));
+ DEBUG(4,("spoolss_io_r_enumprinters, size offered: %d\n",r_u->offered));
+
+ if (r_u->offered<bufsize_required)
+ {
+ /*
+ * so the buffer is too small to handle datas
+ * reply the minimum size required in the status
+ * make the buffer equal 0
+ * and reply no printers in buffer
+ */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER;
+ r_u->offered=0;
+ /*r_u->returned=0;*/
+
+ DEBUG(4,("spoolss_io_r_enumprinters, buffer too small\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("count", ps, depth, &(r_u->returned));
+ prs_uint32("status", ps, depth, &(r_u->status));
+ return False;
+ }
- if (!prs_uint32("returned", ps, depth, &r_u->returned))
- return False;
+ DEBUG(4,("spoolss_io_r_enumprinters, buffer large enough\n"));
+ }
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+
+ /* have to skip to end of buffer when reading, and have to record
+ * size of buffer when writing. *shudder*.
+ */
+
+ beginning = ps->offset;
+ start_offset = ps->offset;
+ end_offset = start_offset + r_u->offered;
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ if (ps->io)
+ {
+ /* reading */
+ ps->offset = beginning + r_u->offered;
+
+ prs_align(ps);
+ prs_uint32("buffer size", ps, depth, &(bufsize_required));
+ prs_uint32("count", ps, depth, &(r_u->returned));
- return True;
+ ps->offset = beginning;
+ }
+
+ for(i=0;i<r_u->returned;i++)
+ {
+
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ if (ps->io)
+ {
+ /* reading */
+ r_u->ctr.printer.printers_1[i] = add_print1_to_array(&tmp_ct, &r_u->ctr.printer.printers_1, NULL);
+ }
+ info1 = r_u->ctr.printer.printers_1[i];
+ if (info1 == NULL)
+ {
+ return False;
+ }
+ smb_io_printer_info_1(desc, info1, ps, depth,
+ &start_offset, &end_offset);
+ break;
+ }
+ case 2:
+ {
+ if (ps->io)
+ {
+ /* reading */
+ r_u->ctr.printer.printers_2[i] = add_print2_to_array(&tmp_ct, &r_u->ctr.printer.printers_2, NULL);
+ }
+ info2 = r_u->ctr.printer.printers_2[i];
+ if (info2 == NULL)
+ {
+ return False;
+ }
+ smb_io_printer_info_2(desc, info2, ps, depth,
+ &start_offset, &end_offset);
+ break;
+ }
+ }
+ }
+
+ ps->offset = beginning + r_u->offered;
+ prs_align(ps);
+
+ prs_uint32("buffer size", ps, depth, &(bufsize_required));
+ prs_uint32("count", ps, depth, &(r_u->returned));
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ if (!ps->io)
+ {
+ /* writing */
+ free_r_enumprinters(r_u);
+ }
+
+ return True;
}
/*******************************************************************
@@ -2607,55 +2189,229 @@ BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_st
* called from spoolss_r_enum_printers (srv_spoolss.c)
*
********************************************************************/
-BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth)
+BOOL spoolss_io_r_getprinter(char *desc,
+ SPOOL_R_GETPRINTER *r_u,
+ prs_struct *ps, int depth)
{
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+
prs_debug(ps, depth, desc, "spoolss_io_r_getprinter");
depth++;
- if (!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+
+ switch (r_u->level)
+ {
+ case 0:
+ {
+ PRINTER_INFO_0 *info;
+ info = r_u->ctr.printer.info0;
+ bufsize_required += spoolss_size_printer_info_0(info);
+ break;
+ }
+ case 1:
+ {
+ PRINTER_INFO_1 *info;
+ info = r_u->ctr.printer.info1;
+ bufsize_required += spoolss_size_printer_info_1(info);
+ break;
+ }
+ case 2:
+ {
+ PRINTER_INFO_2 *info;
+ info = r_u->ctr.printer.info2;
+ bufsize_required += spoolss_size_printer_info_2(info);
+ break;
+ }
+ }
+
+ DEBUG(4,("spoolss_io_r_getprinter, size needed: %d\n",bufsize_required));
+ DEBUG(4,("spoolss_io_r_getprinter, size offered: %d\n",r_u->offered));
+
+ /* check if the buffer is big enough for the datas */
+ if (r_u->offered < bufsize_required)
+ {
+ /* it's too small */
+ r_u->status = ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered = 0; /* don't send back the buffer */
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
+ DEBUG(4,("spoolss_io_r_getprinter, buffer too small\n"));
- if (!prs_align(ps))
- return False;
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ DEBUG(4,("spoolss_io_r_getprinter, buffer large enough\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+
+ if (ps->io)
+ {
+ /* reading */
+ r_u->ctr.printer.info = Realloc(NULL, r_u->offered);
+ }
+
+ if (bufsize_required <= r_u->offered)
+ {
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
+ switch (r_u->level)
+ {
+ case 0:
+ {
+ PRINTER_INFO_0 *info;
+ info = r_u->ctr.printer.info0;
+ smb_io_printer_info_0(desc,
+ info,
+ ps,
+ depth,
+ &start_offset,
+ &end_offset);
+ if (!ps->io)
+ {
+ /* writing */
+ free(info);
+ }
+ break;
+ }
+ case 1:
+ {
+ PRINTER_INFO_1 *info;
+ info = r_u->ctr.printer.info1;
+ smb_io_printer_info_1(desc,
+ info,
+ ps,
+ depth,
+ &start_offset,
+ &end_offset);
+ if (!ps->io)
+ {
+ /* writing */
+ free(info);
+ }
+ break;
+ }
+ case 2:
+ {
+ PRINTER_INFO_2 *info;
+ info = r_u->ctr.printer.info2;
+ smb_io_printer_info_2(desc,
+ info,
+ ps,
+ depth,
+ &start_offset,
+ &end_offset);
+ if (!ps->io)
+ {
+ /* writing */
+ free_printer_info_2(info);
+ }
+ break;
+ }
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ }
+
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+ * read a uint8 buffer of size *size.
+ * allocate memory for it
+ * return a pointer to the allocated memory and the size
+ * return NULL and a size of 0 if the buffer is empty
+ *
+ * jfmxxxx: fix it to also write a buffer
+ ********************************************************************/
+static BOOL spoolss_io_read_buffer8(char *desc, prs_struct *ps, uint8 **buffer, uint32 *size,int depth)
+{
+ prs_debug(ps, depth, desc, "spoolss_io_read_buffer8");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("buffer size", ps, depth, size);
+ *buffer = (uint8 *)Realloc(NULL, (*size) * sizeof(uint8) );
+ prs_uint8s(True,"buffer",ps,depth,*buffer,*size);
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+ * make a structure.
+ * called from spoolss_getprinter (srv_spoolss.c)
+ ********************************************************************/
+BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u,
+ POLICY_HND *hnd,
+ uint32 level,
+ uint32 buf_size)
+{
+ if (q_u == NULL) return False;
+
+ memcpy(&q_u->handle, hnd, sizeof(q_u->handle));
+
+ q_u->level = level;
+ q_u->buffer = (uint8 *)Realloc(NULL, (buf_size) * sizeof(uint8) );
+ q_u->offered = buf_size;
- return True;
+ return True;
}
/*******************************************************************
* read a structure.
* called from spoolss_getprinter (srv_spoolss.c)
********************************************************************/
-BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth)
+BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u,
+ prs_struct *ps, int depth)
{
+ uint32 count = 0;
+ uint32 buf_ptr = q_u->buffer != NULL ? 1 : 0;
prs_debug(ps, depth, desc, "spoolss_io_q_getprinter");
depth++;
- if (!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth))
- return False;
- if (!prs_uint32("level", ps, depth, &q_u->level))
- return False;
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
+
+ prs_uint32("level", ps, depth, &(q_u->level));
- if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
+ if (!ps->io)
+ {
+ /* writing */
+ buf_ptr = q_u->buffer != NULL ? 1 : 0;
+ }
+ prs_uint32("buffer pointer", ps, depth, &buf_ptr);
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ if (buf_ptr != 0)
+ {
+ spoolss_io_read_buffer8("",ps, &q_u->buffer, &count,depth);
+ }
+ if (q_u->buffer != NULL)
+ {
+ free(q_u->buffer);
+ }
+ prs_uint32("buffer size", ps, depth, &(q_u->offered));
- return True;
+ return count == q_u->offered;
}
/*******************************************************************
@@ -2674,30 +2430,61 @@ BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps
/*******************************************************************
********************************************************************/
+static BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE **devmode)
+{
+ uint32 devmode_size=0x0;
+ uint32 useless_ptr=0x0;
+
+ prs_debug(ps, depth, desc, "spoolss_io_devmode");
+ depth++;
+
+ prs_uint32("devmode_size", ps, depth, &(devmode_size));
+ prs_uint32("useless_ptr", ps, depth, &(useless_ptr));
+
+ if (devmode_size!=0 && useless_ptr!=0)
+ {
+ /* so we have a DEVICEMODE to follow */
+ if (ps->io)
+ {
+ DEBUG(9,("Allocating memory for spoolss_io_devmode\n"));
+ *devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE));
+ ZERO_STRUCTP(*devmode);
+ }
+
+ /* this is bad code, shouldn't be there */
+ prs_uint32("devmode_size", ps, depth, &(devmode_size));
+
+ smb_io_devmode(desc, ps, depth, *devmode);
+ }
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_q_setprinter");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_prt_hnd("printer handle", &q_u->handle ,ps, depth))
- return False;
- if(!prs_uint32("level", ps, depth, &q_u->level))
- return False;
+ smb_io_prt_hnd("printer handle", &(q_u->handle),ps,depth);
+ prs_uint32("level", ps, depth, &(q_u->level));
- if(!spool_io_printer_info_level("", &q_u->info, ps, depth))
- return False;
+ /* again a designed mess */
+ /* sometimes I'm wondering how all of this work ! */
- if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth))
- return False;
+ /* To be correct it need to be split in 3 functions */
+
+ spool_io_printer_info_level("", &(q_u->info), ps, depth);
+
+ spoolss_io_devmode(desc, ps, depth, &(q_u->devmode));
- prs_uint32("security.size_of_buffer", ps, depth, &q_u->security.size_of_buffer);
- prs_uint32("security.data", ps, depth, &q_u->security.data);
+ prs_uint32("security.size_of_buffer", ps, depth, &(q_u->security.size_of_buffer));
+ prs_uint32("security.data", ps, depth, &(q_u->security.data));
- if(!prs_uint32("command", ps, depth, &q_u->command))
- return False;
+ prs_uint32("command", ps, depth, &(q_u->command));
return True;
}
@@ -2739,11 +2526,9 @@ BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int de
prs_debug(ps, depth, desc, "");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
@@ -2752,57 +2537,208 @@ BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int de
********************************************************************/
BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth)
{
+
prs_debug(ps, depth, desc, "");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth))
- return False;
- if(!prs_uint32("level", ps, depth, &q_u->level))
- return False;
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
+ prs_uint32("level", ps, depth, &(q_u->level));
- if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
return True;
}
+/****************************************************************************
+****************************************************************************/
+void free_job_info_ctr(JOB_INFO_CTR *ctr, uint32 level, uint32 numofjobs)
+{
+ DEBUG(4,("free_enum_jobs_info: [%d] structs to free at level [%d]\n",
+ numofjobs, level));
+ switch (level)
+ {
+ case 1:
+ {
+ free_job1_array(numofjobs,
+ ctr->job.job_info_1);
+ break;
+ }
+ case 2:
+ {
+ free_job2_array(numofjobs,
+ ctr->job.job_info_2);
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+****************************************************************************/
+void free_r_enumjobs(SPOOL_R_ENUMJOBS *r_u)
+{
+ free_job_info_ctr(&r_u->ctr, r_u->level, r_u->numofjobs);
+}
+
/*******************************************************************
********************************************************************/
BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth)
{
+ uint32 useless_ptr = 0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+ uint32 tmp_ct = 0;
+ int i;
+
prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs");
depth++;
- if (!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ if (!ps->io)
+ {
+ /* writing */
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ for (i=0; i<r_u->numofjobs; i++)
+ {
+ JOB_INFO_1 *info;
+ info=r_u->ctr.job.job_info_1[i];
+ bufsize_required += spoolss_size_job_info_1(&(info[i]));
+ }
+ break;
+ }
+ case 2:
+ {
+ for (i=0; i<r_u->numofjobs; i++)
+ {
+ JOB_INFO_2 *info;
+ info=r_u->ctr.job.job_info_2[i];
+
+ bufsize_required += spoolss_size_job_info_2(&(info[i]));
+ }
+ break;
+ }
+ }
+
+ DEBUG(4,("spoolss_io_r_enumjobs, size needed: %d\n",
+ bufsize_required));
+ DEBUG(4,("spoolss_io_r_enumjobs, size offered: %d\n",
+ r_u->offered));
+
+ /* check if the buffer is big enough for the datas */
+ if (r_u->offered<bufsize_required)
+ {
+ /* it's too small */
+ r_u->status = ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered = bufsize_required;
+ useless_ptr = 0;
+
+ DEBUG(4,("spoolss_io_r_enumjobs, buffer too small\n"));
+
+ }
+ else
+ {
+ useless_ptr = 1;
+ }
+ }
+
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+
+ if (useless_ptr != 0)
+ {
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
+ tmp_ct = 0;
- if (!prs_align(ps))
- return False;
+ if (ps->io)
+ {
+ /* reading */
+ ps->offset = beginning + r_u->offered;
+
+ prs_align(ps);
+ prs_uint32("buffer size", ps, depth, &(bufsize_required));
+ prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs));
+
+ ps->offset = beginning;
+ }
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ JOB_INFO_1 *info;
+ for (i=0; i<r_u->numofjobs; i++)
+ {
+ if (ps->io)
+ {
+ /* reading */
+ r_u->ctr.job.job_info_1[i] = add_job1_to_array(&tmp_ct, &r_u->ctr.job.job_info_1, NULL);
+ }
+ info = r_u->ctr.job.job_info_1[i];
+ smb_io_job_info_1(desc,
+ info,
+ ps,
+ depth,
+ &start_offset,
+ &end_offset);
+ }
+ break;
+ }
+ case 2:
+ {
+ JOB_INFO_2 *info;
+ for (i=0; i<r_u->numofjobs; i++)
+ {
+ if (ps->io)
+ {
+ /* reading */
+ r_u->ctr.job.job_info_2[i] = add_job2_to_array(&tmp_ct, &r_u->ctr.job.job_info_2, NULL);
+ }
+ info = r_u->ctr.job.job_info_2[i];
+ smb_io_job_info_2(desc,
+ info,
+ ps,
+ depth,
+ &start_offset,
+ &end_offset);
+ }
+ break;
+ }
- if (!prs_uint32("returned", ps, depth, &r_u->returned))
- return False;
+ }
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("buffer size", ps, depth, &(bufsize_required));
+ }
- return True;
-}
+ prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs));
+ prs_uint32("status", ps, depth, &(r_u->status));
+ if (!ps->io)
+ {
+ /* writing */
+ free_r_enumjobs(r_u);
+ }
+
+ return True;
+}
/*******************************************************************
********************************************************************/
@@ -2820,13 +2756,13 @@ BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd,
q_u->firstjob = firstjob;
q_u->numofjobs = numofjobs;
q_u->level = level;
-/*
+
if (!make_spoolss_buffer(&q_u->buffer, buf_size))
{
return False;
}
q_u->buf_size = buf_size;
-*/
+
return True;
}
@@ -2837,24 +2773,16 @@ BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, in
prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs");
depth++;
- if (!prs_align(ps))
- return False;
-
- if (!smb_io_prt_hnd("printer handle",&q_u->handle, ps, depth))
- return False;
-
- if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob))
- return False;
- if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs))
- return False;
- if (!prs_uint32("level", ps, depth, &q_u->level))
- return False;
+ prs_align(ps);
- if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
+ prs_uint32("firstjob", ps, depth, &(q_u->firstjob));
+ prs_uint32("numofjobs", ps, depth, &(q_u->numofjobs));
+ prs_uint32("level", ps, depth, &(q_u->level));
+
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
- if (!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
return True;
}
@@ -2924,268 +2852,506 @@ BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int de
}
/*******************************************************************
- Parse a SPOOL_R_ENUMPRINTERDRIVERS structure.
********************************************************************/
-BOOL new_spoolss_io_r_enumprinterdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "new_spoolss_io_r_enumprinterdrivers");
+BOOL spoolss_io_r_enumdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth)
+{
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+ int i;
+
+ prs_debug(ps, depth, desc, "spoolss_io_r_enumdrivers");
depth++;
- if (!prs_align(ps))
- return False;
-
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
-
- if (!prs_uint32("returned", ps, depth, &r_u->returned))
- return False;
+ DEBUG(7,("Level [%d], number [%d]\n", r_u->level, r_u->numofdrivers));
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ DRIVER_INFO_1 *driver_info_1;
+ driver_info_1=r_u->ctr.driver.info1;
+
+ for (i=0; i<r_u->numofdrivers; i++)
+ {
+ bufsize_required += spoolss_size_printer_driver_info_1(&(driver_info_1[i]));
+ }
+ break;
+ }
+ case 2:
+ {
+ DRIVER_INFO_2 *driver_info_2;
+ driver_info_2=r_u->ctr.driver.info2;
+
+ for (i=0; i<r_u->numofdrivers; i++)
+ {
+ bufsize_required += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
+ }
+ break;
+ }
+ case 3:
+ {
+ DRIVER_INFO_3 *driver_info_3;
+ driver_info_3=r_u->ctr.driver.info3;
+
+ for (i=0; i<r_u->numofdrivers; i++)
+ {
+ bufsize_required += spoolss_size_printer_driver_info_3(&(driver_info_3[i]));
+ }
+ break;
+ }
+ }
+
+ DEBUGADD(7,("size needed: %d\n",bufsize_required));
+ DEBUGADD(7,("size offered: %d\n",r_u->offered));
+
+ /* check if the buffer is big enough for the datas */
+
+ if (r_u->offered<bufsize_required)
+ {
+
+ /* it's too small */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered=0; /* don't send back the buffer */
+ DEBUGADD(8,("buffer too small\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ DEBUGADD(8,("buffer large enough\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ DRIVER_INFO_1 *info;
+ for (i=0; i<r_u->numofdrivers; i++)
+ {
+ info = &(r_u->ctr.driver.info1[i]);
+ smb_io_printer_driver_info_1(desc, info, ps, depth, &start_offset, &end_offset);
+ }
+ break;
+ }
+ case 2:
+ {
+ DRIVER_INFO_2 *info;
+ for (i=0; i<r_u->numofdrivers; i++)
+ {
+ info = &(r_u->ctr.driver.info2[i]);
+ smb_io_printer_driver_info_2(desc, info, ps, depth, &start_offset, &end_offset);
+ }
+ break;
+ }
+ case 3:
+ {
+ DRIVER_INFO_3 *info;
+ for (i=0; i<r_u->numofdrivers; i++)
+ {
+ info = &(r_u->ctr.driver.info3[i]);
+ smb_io_printer_driver_info_3(desc, info, ps, depth, &start_offset, &end_offset);
+ }
+ break;
+ }
+ }
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("numofdrivers", ps, depth, &(r_u->numofdrivers));
+ prs_uint32("status", ps, depth, &(r_u->status));
- return True;
+ return True;
}
+void free_spoolss_r_enumdrivers(SPOOL_R_ENUMPRINTERDRIVERS *r_u)
+{
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ DRIVER_INFO_1 *driver_info_1;
+ driver_info_1=r_u->ctr.driver.info1;
+
+ free(driver_info_1);
+ break;
+ }
+ case 2:
+ {
+ DRIVER_INFO_2 *driver_info_2;
+ driver_info_2=r_u->ctr.driver.info2;
+
+ free(driver_info_2);
+ break;
+ }
+ case 3:
+ {
+ DRIVER_INFO_3 *driver_info_3;
+
+ UNISTR **dependentfiles;
+ int i;
+
+ driver_info_3=r_u->ctr.driver.info3;
+
+ for (i=0; i<r_u->numofdrivers; i++)
+ {
+ int j=0;
+ dependentfiles=(driver_info_3[i]).dependentfiles;
+ while ( dependentfiles[j] != NULL )
+ {
+ free(dependentfiles[j]);
+ j++;
+ }
+
+ free(dependentfiles);
+ }
+ free(driver_info_3);
+ break;
+ }
+ }
+}
+
/*******************************************************************
- Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure.
********************************************************************/
BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers");
+ uint32 useless_ptr=0xADDE0FF0;
+ prs_debug(ps, depth, desc, "");
depth++;
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
- return False;
- if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth))
- return False;
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr))
- return False;
- if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
- return False;
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("level", ps, depth, &q_u->level))
- return False;
-
- if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ smb_io_unistr2("", &(q_u->name),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ smb_io_unistr2("", &(q_u->environment),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("level", ps, depth, &(q_u->level));
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+ prs_align(ps);
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
return True;
}
/*******************************************************************
********************************************************************/
-BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
-{
-
- prs_debug(ps, depth, desc, "spoolss_io_q_enumforms");
+BOOL spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
+{
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+ int i;
+
+ prs_debug(ps, depth, desc, "spoolss_io_r_enumforms");
depth++;
- if (!prs_align(ps))
- return False;
- if (!smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth))
- return False;
- if (!prs_uint32("level", ps, depth, &(q_u->level)))
- return False;
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ FORM_1 *forms_1;
+ forms_1=r_u->forms_1;
+
+ for (i=0; i<r_u->numofforms; i++)
+ {
+ bufsize_required += spoolss_size_form_1(&(forms_1[i]));
+ }
+ break;
+ }
+ }
- if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
+ DEBUG(4,("spoolss_io_r_enumforms, size needed: %d\n",bufsize_required));
+ DEBUG(4,("spoolss_io_r_enumforms, size offered: %d\n",r_u->offered));
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("offered", ps, depth, &(q_u->offered)))
- return False;
+ /* check if the buffer is big enough for the datas */
+
+ if (r_u->offered<bufsize_required)
+ {
+
+ /* it's too small */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered=0; /* don't send back the buffer */
+
+ DEBUG(4,("spoolss_io_r_enumforms, buffer too small\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ DEBUG(4,("spoolss_io_r_enumforms, buffer large enough\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+
+ if (r_u->offered!=0)
+ {
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
+
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ FORM_1 *info;
+ for (i=0; i<r_u->numofforms; i++)
+ {
+ info = &(r_u->forms_1[i]);
+ smb_io_form_1(desc, info, ps, depth, &start_offset, &end_offset);
+ }
+ break;
+ }
+ }
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("numofforms", ps, depth, &(r_u->numofforms));
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
/*******************************************************************
********************************************************************/
-BOOL new_spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth)
+void spoolss_free_r_enumforms(SPOOL_R_ENUMFORMS *r_u)
{
- prs_debug(ps, depth, desc, "new_spoolss_io_r_enumforms");
- depth++;
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ free(r_u->forms_1);
+ break;
+ }
+ }
+}
- if (!prs_align(ps))
- return False;
-
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
+/*******************************************************************
+********************************************************************/
+BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth)
+{
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("size of buffer needed", ps, depth, &(r_u->needed)))
- return False;
-
- if (!prs_uint32("numofforms", ps, depth, &(r_u->numofforms)))
- return False;
-
- if (!prs_uint32("status", ps, depth, &(r_u->status)))
- return False;
+ prs_debug(ps, depth, desc, "");
+ depth++;
+
+ prs_align(ps);
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
+ prs_uint32("level", ps, depth, &(q_u->level));
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+ prs_align(ps);
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
return True;
-
}
/*******************************************************************
- Parse a SPOOL_R_ENUMPORTS structure.
********************************************************************/
-BOOL new_spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "new_spoolss_io_r_enumports");
+BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth)
+{
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+ int i;
+
+ prs_debug(ps, depth, desc, "spoolss_io_r_enumports");
depth++;
- if (!prs_align(ps))
- return False;
-
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ switch (r_u->level)
+ {
+ case 2:
+ {
+ PORT_INFO_2 *port_2;
+ port_2=r_u->ctr.port.info_2;
+
+ for (i=0; i<r_u->numofports; i++)
+ {
+ bufsize_required += spoolss_size_port_info_2(&(port_2[i]));
+ }
+ break;
+ }
+ }
+
+ DEBUG(4,("size needed: %d\n",bufsize_required));
+ DEBUG(4,("size offered: %d\n",r_u->offered));
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
+ /* check if the buffer is big enough for the datas */
+ if (r_u->offered<bufsize_required)
+ {
+
+ /* it's too small */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered=0; /* don't send back the buffer */
- if (!prs_uint32("returned", ps, depth, &r_u->returned))
- return False;
+ DEBUG(4,("buffer too small\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ DEBUG(4,("buffer large enough\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ switch (r_u->level)
+ {
+ case 2:
+ {
+ PORT_INFO_2 *info;
+ for (i=0; i<r_u->numofports; i++)
+ {
+ info = &(r_u->ctr.port.info_2[i]);
+ smb_io_port_2(desc, info, ps, depth, &start_offset, &end_offset);
+ }
+ break;
+ }
+ }
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("numofports", ps, depth, &(r_u->numofports));
+ prs_uint32("status", ps, depth, &(r_u->status));
- return True;
+ return True;
}
+void spoolss_free_r_enumports(SPOOL_R_ENUMPORTS *r_u)
+{
+ switch (r_u->level)
+ {
+ case 2:
+ {
+ safe_free(r_u->ctr.port.info_2);
+ break;
+ }
+ }
+}
/*******************************************************************
********************************************************************/
BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth)
{
+ uint32 useless;
prs_debug(ps, depth, desc, "");
depth++;
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("", ps, depth, &q_u->name_ptr))
- return False;
- if (!smb_io_unistr2("", &q_u->name,True,ps,depth))
- return False;
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("level", ps, depth, &q_u->level))
- return False;
-
- if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
-
- if (!prs_align(ps))
- return False;
- if (!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ prs_align(ps);
+ prs_uint32("useless", ps, depth, &useless);
+ smb_io_unistr2("", &(q_u->name),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("level", ps, depth, &(q_u->level));
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+ prs_align(ps);
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
return True;
}
+
/*******************************************************************
- Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure.
********************************************************************/
-BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth)
+BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "spool_io_printer_info_level_2");
+ SPOOL_PRINTER_INFO_LEVEL_2 *il;
+
+ prs_debug(ps, depth, desc, "");
depth++;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr))
- return False;
- if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr))
- return False;
- if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr))
- return False;
- if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr))
- return False;
- if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr))
- return False;
- if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr))
- return False;
- if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr))
- return False;
- if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr))
- return False;
- if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr))
- return False;
- if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr))
- return False;
- if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr))
- return False;
- if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr))
- return False;
- if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr))
- return False;
+ /* reading */
+ if (ps->io)
+ {
+ il=(SPOOL_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2));
+ ZERO_STRUCTP(il);
+ *q_u=il;
+ DEBUG(7,("lecture: memoire ok\n"));
+ }
+ else
+ {
+ il=*q_u;
+ }
+
+ prs_align(ps);
+
+ prs_uint32("servername_ptr", ps, depth, &(il->servername_ptr));
+ prs_uint32("printername_ptr", ps, depth, &(il->printername_ptr));
+ prs_uint32("sharename_ptr", ps, depth, &(il->sharename_ptr));
+ prs_uint32("portname_ptr", ps, depth, &(il->portname_ptr));
+ prs_uint32("drivername_ptr", ps, depth, &(il->drivername_ptr));
+ prs_uint32("comment_ptr", ps, depth, &(il->comment_ptr));
+ prs_uint32("location_ptr", ps, depth, &(il->location_ptr));
+ prs_uint32("devmode_ptr", ps, depth, &(il->devmode_ptr));
+ prs_uint32("sepfile_ptr", ps, depth, &(il->sepfile_ptr));
+ prs_uint32("printprocessor_ptr", ps, depth, &(il->printprocessor_ptr));
+ prs_uint32("datatype_ptr", ps, depth, &(il->datatype_ptr));
+ prs_uint32("parameters_ptr", ps, depth, &(il->parameters_ptr));
+ prs_uint32("secdesc_ptr", ps, depth, &(il->secdesc_ptr));
+
+ prs_uint32("attributes", ps, depth, &(il->attributes));
+ prs_uint32("priority", ps, depth, &(il->priority));
+ prs_uint32("default_priority", ps, depth, &(il->default_priority));
+ prs_uint32("starttime", ps, depth, &(il->starttime));
+ prs_uint32("untiltime", ps, depth, &(il->untiltime));
+ prs_uint32("status", ps, depth, &(il->status));
+ prs_uint32("cjobs", ps, depth, &(il->cjobs));
+ prs_uint32("averageppm", ps, depth, &(il->averageppm));
+
+ smb_io_unistr2("", &(il->servername), il->servername_ptr, ps, depth);
+ smb_io_unistr2("", &(il->printername), il->printername_ptr, ps, depth);
+ smb_io_unistr2("", &(il->sharename), il->sharename_ptr, ps, depth);
+ smb_io_unistr2("", &(il->portname), il->portname_ptr, ps, depth);
+ smb_io_unistr2("", &(il->drivername), il->drivername_ptr, ps, depth);
+ smb_io_unistr2("", &(il->comment), il->comment_ptr, ps, depth);
+ smb_io_unistr2("", &(il->location), il->location_ptr, ps, depth);
+ smb_io_unistr2("", &(il->sepfile), il->sepfile_ptr, ps, depth);
+ smb_io_unistr2("", &(il->printprocessor), il->printprocessor_ptr, ps, depth);
+ smb_io_unistr2("", &(il->datatype), il->datatype_ptr, ps, depth);
+ smb_io_unistr2("", &(il->parameters), il->parameters_ptr, ps, depth);
- if(!prs_uint32("attributes", ps, depth, &il->attributes))
- return False;
- if(!prs_uint32("priority", ps, depth, &il->priority))
- return False;
- if(!prs_uint32("default_priority", ps, depth, &il->default_priority))
- return False;
- if(!prs_uint32("starttime", ps, depth, &il->starttime))
- return False;
- if(!prs_uint32("untiltime", ps, depth, &il->untiltime))
- return False;
- if(!prs_uint32("status", ps, depth, &il->status))
- return False;
- if(!prs_uint32("cjobs", ps, depth, &il->cjobs))
- return False;
- if(!prs_uint32("averageppm", ps, depth, &il->averageppm))
- return False;
+ prs_align(ps);
- if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth))
- return False;
+ /* this code as nothing to do here !!!
+
+ if (il->secdesc_ptr)
+ {
+ il->secdesc=NULL;
+ sec_io_desc_buf("", &(il->secdesc), ps, depth);
+ }
+
+ */
return True;
}
@@ -3194,24 +3360,17 @@ BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, p
********************************************************************/
BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "spool_io_printer_info_level");
+ uint32 useless;
+ uint32 level;
+ prs_debug(ps, depth, desc, "");
depth++;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("level", ps, depth, &il->level))
- return False;
- if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr))
- return False;
-
- /* if no struct inside just return */
- if (il->info_ptr==0) {
- if (UNMARSHALLING(ps))
- il->info_2=NULL;
- return True;
- }
-
- switch (il->level) {
+ prs_align(ps);
+ prs_uint32("info level", ps, depth, &level);
+ prs_uint32("useless", ps, depth, &useless);
+
+ switch (level)
+ {
/*
* level 0 is used by setprinter when managing the queue
* (hold, stop, start a queue)
@@ -3223,13 +3382,71 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s
* and by setprinter when updating printer's info
*/
case 2:
- if (UNMARSHALLING(ps))
- il->info_2=(SPOOL_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2));
- if (!spool_io_printer_info_level_2("", il->info_2, ps, depth))
- return False;
+ spool_io_printer_info_level_2("", &(il->info_2), ps, depth);
break;
}
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL spool_io_user_level_1(char *desc, SPOOL_USER_LEVEL_1 **q_u, prs_struct *ps, int depth)
+{
+ SPOOL_USER_LEVEL_1 *il;
+ prs_debug(ps, depth, desc, "");
+ depth++;
+
+ /* reading */
+ if (ps->io)
+ {
+ il=(SPOOL_USER_LEVEL_1 *)malloc(sizeof(SPOOL_USER_LEVEL_1));
+ ZERO_STRUCTP(il);
+ *q_u=il;
+ }
+ else
+ {
+ il=*q_u;
+ }
+
+ prs_align(ps);
+ prs_uint32("size", ps, depth, &(il->size));
+ prs_uint32("client_name_ptr", ps, depth, &(il->client_name_ptr));
+ prs_uint32("user_name_ptr", ps, depth, &(il->user_name_ptr));
+ prs_uint32("build", ps, depth, &(il->build));
+ prs_uint32("major", ps, depth, &(il->major));
+ prs_uint32("minor", ps, depth, &(il->minor));
+ prs_uint32("processor", ps, depth, &(il->processor));
+
+ smb_io_unistr2("", &(il->client_name), il->client_name_ptr, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("", &(il->user_name), il->user_name_ptr, ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+********************************************************************/
+BOOL spool_io_user_level(char *desc, SPOOL_USER_LEVEL *q_u, prs_struct *ps, int depth)
+{
+ uint32 useless;
+ uint32 level;
+ prs_debug(ps, depth, desc, "spool_io_user_level");
+ depth++;
+
+ prs_align(ps);
+ prs_uint32("info_level", ps, depth, &level);
+ prs_uint32("useless", ps, depth, &useless);
+
+ switch (level)
+ {
+ case 1:
+ spool_io_user_level_1("", &(q_u->user_level_1), ps, depth);
+ break;
+
+ }
+
return True;
}
@@ -3237,6 +3454,7 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s
********************************************************************/
BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth)
{
+ uint32 useless;
prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
depth++;
@@ -3246,44 +3464,32 @@ BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct
* the info level are handled in a nice way.
*/
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
- return False;
- if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("info_level", ps, depth, &q_u->level))
- return False;
-
- if(!spool_io_printer_info_level("", &(q_u->info), ps, depth))
- return False;
+ prs_align(ps);
+ prs_uint32("useless", ps, depth, &useless);
+ smb_io_unistr2("", &(q_u->server_name),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("info_level", ps, depth, &(q_u->level));
+
+ spool_io_printer_info_level("", &(q_u->info), ps, depth);
+
/* the 4 unknown are all 0 */
-
+
/*
* en fait ils sont pas inconnu
* par recoupement avec rpcSetPrinter
* c'est le devicemode
* et le security descriptor.
*/
-
- if(!prs_uint32("unk0", ps, depth, &q_u->unk0))
- return False;
- if(!prs_uint32("unk1", ps, depth, &q_u->unk1))
- return False;
- if(!prs_uint32("unk2", ps, depth, &q_u->unk2))
- return False;
- if(!prs_uint32("unk3", ps, depth, &q_u->unk3))
- return False;
+
+ prs_uint32("unk0", ps, depth, &(q_u->unk0));
+ prs_uint32("unk1", ps, depth, &(q_u->unk1));
+ prs_uint32("unk2", ps, depth, &(q_u->unk2));
+ prs_uint32("unk3", ps, depth, &(q_u->unk3));
- if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch))
- return False;
- if(!spool_io_user_level("", &q_u->user_ctr, ps, depth))
- return False;
+ prs_uint32("info_level", ps, depth, &(q_u->user_level));
+
+ spool_io_user_level("", &(q_u->user), ps, depth);
return True;
}
@@ -3310,71 +3516,52 @@ BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_
{
SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il;
- prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3");
+ prs_debug(ps, depth, desc, "");
depth++;
/* reading */
- if (UNMARSHALLING(ps)) {
+ if (ps->io)
+ {
il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3));
ZERO_STRUCTP(il);
*q_u=il;
+ DEBUG(1,("lecture: memoire ok\n"));
}
- else {
+ else
+ {
il=*q_u;
}
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("cversion", ps, depth, &il->cversion))
- return False;
- if(!prs_uint32("name", ps, depth, &il->name_ptr))
- return False;
- if(!prs_uint32("environment", ps, depth, &il->environment_ptr))
- return False;
- if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr))
- return False;
- if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr))
- return False;
- if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr))
- return False;
- if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr))
- return False;
- if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr))
- return False;
- if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr))
- return False;
- if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize))
- return False;
- if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr))
- return False;
-
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint32("cversion", ps, depth, &(il->cversion));
+ prs_uint32("name", ps, depth, &(il->name_ptr));
+ prs_uint32("environment", ps, depth, &(il->environment_ptr));
+ prs_uint32("driverpath", ps, depth, &(il->driverpath_ptr));
+ prs_uint32("datafile", ps, depth, &(il->datafile_ptr));
+ prs_uint32("configfile", ps, depth, &(il->configfile_ptr));
+ prs_uint32("helpfile", ps, depth, &(il->helpfile_ptr));
+ prs_uint32("monitorname", ps, depth, &(il->monitorname_ptr));
+ prs_uint32("defaultdatatype", ps, depth, &(il->defaultdatatype_ptr));
+ prs_uint32("dependentfilessize", ps, depth, &(il->dependentfilessize));
+ prs_uint32("dependentfiles", ps, depth, &(il->dependentfiles_ptr));
+
+ prs_align(ps);
- if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth))
- return False;
- if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
-
+ smb_io_unistr2("", &(il->name), il->name_ptr, ps, depth);
+ smb_io_unistr2("", &(il->environment), il->environment_ptr, ps, depth);
+ smb_io_unistr2("", &(il->driverpath), il->driverpath_ptr, ps, depth);
+ smb_io_unistr2("", &(il->datafile), il->datafile_ptr, ps, depth);
+ smb_io_unistr2("", &(il->configfile), il->configfile_ptr, ps, depth);
+ smb_io_unistr2("", &(il->helpfile), il->helpfile_ptr, ps, depth);
+ smb_io_unistr2("", &(il->monitorname), il->monitorname_ptr, ps, depth);
+ smb_io_unistr2("", &(il->defaultdatatype), il->defaultdatatype_ptr, ps, depth);
+
+ prs_align(ps);
if (il->dependentfiles_ptr)
smb_io_buffer5("", &(il->dependentfiles), ps, depth);
+
return True;
}
@@ -3460,25 +3647,23 @@ BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth)
********************************************************************/
BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level");
+ uint32 useless;
+ uint32 level;
+ prs_debug(ps, depth, desc, "");
depth++;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("level", ps, depth, &il->level))
- return False;
- if(!prs_uint32("ptr", ps, depth, &il->ptr))
- return False;
-
- if (il->ptr==0)
- return True;
+ prs_align(ps);
+ prs_uint32("info level", ps, depth, &level);
+ prs_uint32("useless", ps, depth, &useless);
- switch (il->level) {
+ switch (level)
+ {
case 3:
spool_io_printer_driver_info_level_3("", &(il->info_3), ps, depth);
break;
}
+
return True;
}
@@ -3486,24 +3671,17 @@ BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LE
********************************************************************/
BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver");
+ uint32 useless;
+ prs_debug(ps, depth, desc, "");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+ prs_uint32("useless", ps, depth, &useless);
+ smb_io_unistr2("", &(q_u->server_name),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("info_level", ps, depth, &(q_u->level));
- if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr))
- return False;
- if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("info_level", ps, depth, &q_u->level))
- return False;
-
- if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth))
- return False;
+ spool_io_printer_driver_info_level("", &(q_u->info), ps, depth);
return True;
}
@@ -3512,11 +3690,10 @@ BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, pr
********************************************************************/
BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver");
+ prs_debug(ps, depth, desc, "");
depth++;
- if(!prs_uint32("status", ps, depth, &q_u->status))
- return False;
+ prs_uint32("status", ps, depth, &(q_u->status));
return True;
}
@@ -3607,98 +3784,186 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
}
/*******************************************************************
- Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure.
********************************************************************/
-BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir");
+BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
+{
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+
+ prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
depth++;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
- return False;
- if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth))
- return False;
+ prs_align(ps);
+
+ prs_uint32("pointer", ps, depth, &useless_ptr);
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("", ps, depth, &q_u->environment_ptr))
- return False;
- if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ DRIVER_DIRECTORY_1 *driver_info_1;
+ driver_info_1=&(r_u->ctr.driver.info_1);
+
+ bufsize_required = size_of_relative_string(&(driver_info_1->name));
+ break;
+ }
+ }
+
+ DEBUG(4,("spoolss_io_r_getprinterdriverdir, size needed: %d\n",bufsize_required));
+ DEBUG(4,("spoolss_io_r_getprinterdriverdir, size offered: %d\n",r_u->offered));
- if(!prs_uint32("level", ps, depth, &q_u->level))
- return False;
-
- if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
-
- if(!prs_align(ps))
- return False;
+ /* check if the buffer is big enough for the datas */
+
+ if (r_u->offered<bufsize_required)
+ {
+
+ /* it's too small */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered=0; /* don't send back the buffer */
+ DEBUG(4,("spoolss_io_r_getprinterdriverdir, buffer too small\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ DEBUG(4,("spoolss_io_r_getprinterdriverdir, buffer large enough\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
- if(!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ DRIVER_DIRECTORY_1 *info;
+ info = &(r_u->ctr.driver.info_1);
+ prs_unistr("name", ps, depth, &(info->name));
+ /*smb_io_printer_driver_dir_1(desc, info, ps, depth, &start_offset, &end_offset);*/
+ break;
+ }
+ }
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
/*******************************************************************
- Parse a SPOOL_R_GETPRINTERDRIVERDIR structure.
********************************************************************/
-BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir");
- depth++;
+BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth)
+{
- if (!prs_align(ps))
- return False;
-
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
+ uint32 useless_ptr=0xADDE0FF0;
+ prs_debug(ps, depth, desc, "");
+ depth++;
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
-
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ smb_io_unistr2("", &(q_u->name),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ smb_io_unistr2("", &(q_u->environment),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("level", ps, depth, &(q_u->level));
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+ prs_align(ps);
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
- return True;
+ return True;
}
/*******************************************************************
********************************************************************/
BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth)
{
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+ int i;
+
prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors");
depth++;
- if (!prs_align(ps))
- return False;
-
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ PRINTPROCESSOR_1 *info_1;
+ info_1=r_u->info_1;
+
+ for (i=0; i<r_u->numofprintprocessors; i++)
+ {
+ bufsize_required += spoolss_size_processor_info_1(&(info_1[i]));
+ }
+ break;
+ }
+ }
+
+ DEBUG(4,("size needed: %d\n",bufsize_required));
+ DEBUG(4,("size offered: %d\n",r_u->offered));
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
+ /* check if the buffer is big enough for the datas */
+ if (r_u->offered<bufsize_required)
+ {
+
+ /* it's too small */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered=0; /* don't send back the buffer */
- if (!prs_uint32("returned", ps, depth, &r_u->returned))
- return False;
+ DEBUG(4,("buffer too small\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ DEBUG(4,("buffer large enough\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ PRINTPROCESSOR_1 *info_1;
+ for (i=0; i<r_u->numofprintprocessors; i++)
+ {
+ info_1 = &(r_u->info_1[i]);
+ smb_io_processor_info_1(desc, info_1, ps, depth, &start_offset, &end_offset);
+ }
+ break;
+ }
+ }
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("numofprintprocessors", ps, depth, &(r_u->numofprintprocessors));
+ prs_uint32("status", ps, depth, &(r_u->status));
- return True;
+ return True;
}
/*******************************************************************
@@ -3709,199 +3974,141 @@ BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q
prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors");
depth++;
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
- return False;
- if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("", ps, depth, &q_u->environment_ptr))
- return False;
- if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("level", ps, depth, &q_u->level))
- return False;
-
- if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ prs_align(ps);
+ prs_uint32("useless", ps, depth, &useless);
+ smb_io_unistr2("", &(q_u->name),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("useless", ps, depth, &useless);
+ smb_io_unistr2("", &(q_u->environment),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("level", ps, depth, &(q_u->level));
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+ prs_align(ps);
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
return True;
}
/*******************************************************************
********************************************************************/
-BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth)
+BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes");
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+ int i;
+
+ prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
depth++;
- if (!prs_align(ps))
- return False;
-
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
-
- if (!prs_uint32("returned", ps, depth, &r_u->returned))
- return False;
-
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
+ prs_align(ps);
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ PRINTMONITOR_1 *info_1;
+ info_1=r_u->info_1;
+
+ for (i=0; i<r_u->numofprintmonitors; i++)
+ {
+ bufsize_required += spoolss_size_monitor_info_1(&(info_1[i]));
+ }
+ break;
+ }
+ }
+
+ DEBUG(4,("size needed: %d\n",bufsize_required));
+ DEBUG(4,("size offered: %d\n",r_u->offered));
-/*******************************************************************
-********************************************************************/
-BOOL spoolss_io_q_enumprintprocdatatypes(char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth)
-{
- uint32 useless;
- prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes");
- depth++;
+ /* check if the buffer is big enough for the datas */
+ if (r_u->offered<bufsize_required)
+ {
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
- return False;
- if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
- return False;
-
- if (!prs_align(ps))
- return False;
+ /* it's too small */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered=0; /* don't send back the buffer */
- if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr))
- return False;
- if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth))
- return False;
+ DEBUG(4,("buffer too small\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ DEBUG(4,("buffer large enough\n"));
- if (!prs_align(ps))
- return False;
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
- if (!prs_uint32("level", ps, depth, &q_u->level))
- return False;
-
- if(!new_spoolss_io_buffer("buffer", ps, depth, q_u->buffer))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ PRINTMONITOR_1 *info_1;
+ for (i=0; i<r_u->numofprintmonitors; i++)
+ {
+ info_1 = &(r_u->info_1[i]);
+ smb_io_monitor_info_1(desc, info_1, ps, depth, &start_offset, &end_offset);
+ }
+ break;
+ }
+ }
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("numofprintmonitors", ps, depth, &(r_u->numofprintmonitors));
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
/*******************************************************************
- Parse a SPOOL_Q_ENUMPRINTMONITORS structure.
********************************************************************/
BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth)
{
+ uint32 useless;
prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors");
depth++;
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr))
- return False;
- if (!smb_io_unistr2("name", &q_u->name, True, ps, depth))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("level", ps, depth, &q_u->level))
- return False;
-
- if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ prs_align(ps);
+ prs_uint32("useless", ps, depth, &useless);
+ smb_io_unistr2("", &(q_u->name),True,ps,depth);
+ prs_align(ps);
+ prs_uint32("level", ps, depth, &(q_u->level));
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
+ prs_align(ps);
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
return True;
}
/*******************************************************************
********************************************************************/
-BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth)
-{
- prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors");
- depth++;
-
- if (!prs_align(ps))
- return False;
-
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
-
- if (!prs_align(ps))
- return False;
-
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
-
- if (!prs_uint32("returned", ps, depth, &r_u->returned))
- return False;
-
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
-
- return True;
-}
-
-/*******************************************************************
-********************************************************************/
BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata");
depth++;
- if(!prs_align(ps))
- return False;
- if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize))
- return False;
- if(!prs_uint16s(False, "value", ps, depth, r_u->value, r_u->valuesize))
- return False;
- if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize))
- return False;
+ prs_align(ps);
+ prs_uint32("valuesize", ps, depth, &(r_u->valuesize));
+ prs_unistr("value", ps, depth, &(r_u->value));
+ prs_uint32("realvaluesize", ps, depth, &(r_u->realvaluesize));
- if(!prs_uint32("type", ps, depth, &r_u->type))
- return False;
+ prs_uint32("type", ps, depth, &(r_u->type));
- if(!prs_uint32("datasize", ps, depth, &r_u->datasize))
- return False;
- if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize))
- return False;
- if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize))
- return False;
- if(!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ prs_uint32("datasize", ps, depth, &(r_u->datasize));
+ prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize);
+ prs_uint32("realdatasize", ps, depth, &(r_u->realdatasize));
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
@@ -3913,16 +4120,11 @@ BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_
prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata");
depth++;
- if(!prs_align(ps))
- return False;
- if(!smb_io_prt_hnd("printer handle",&q_u->handle,ps,depth))
- return False;
- if(!prs_uint32("index", ps, depth, &q_u->index))
- return False;
- if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize))
- return False;
- if(!prs_uint32("datasize", ps, depth, &q_u->datasize))
- return False;
+ prs_align(ps);
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
+ prs_uint32("index", ps, depth, &(q_u->index));
+ prs_uint32("valuesize", ps, depth, &(q_u->valuesize));
+ prs_uint32("datasize", ps, depth, &(q_u->datasize));
return True;
}
@@ -4008,23 +4210,23 @@ BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
********************************************************************/
static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "spoolss_io_addform");
- depth++;
- prs_align(ps);
+ prs_debug(ps, depth, desc, "spoolss_io_addform");
+ depth++;
+ prs_align(ps);
- if (ptr!=0)
- {
- prs_uint32("flags", ps, depth, &(f->flags));
- prs_uint32("name_ptr", ps, depth, &(f->name_ptr));
- prs_uint32("size_x", ps, depth, &(f->size_x));
- prs_uint32("size_y", ps, depth, &(f->size_y));
- prs_uint32("left", ps, depth, &(f->left));
- prs_uint32("top", ps, depth, &(f->top));
- prs_uint32("right", ps, depth, &(f->right));
- prs_uint32("bottom", ps, depth, &(f->bottom));
-
- smb_io_unistr2("", &(f->name), f->name_ptr, ps, depth);
- }
+ if (ptr!=0)
+ {
+ prs_uint32("flags", ps, depth, &(f->flags));
+ prs_uint32("name_ptr", ps, depth, &(f->name_ptr));
+ prs_uint32("size_x", ps, depth, &(f->size_x));
+ prs_uint32("size_y", ps, depth, &(f->size_y));
+ prs_uint32("left", ps, depth, &(f->left));
+ prs_uint32("top", ps, depth, &(f->top));
+ prs_uint32("right", ps, depth, &(f->right));
+ prs_uint32("bottom", ps, depth, &(f->bottom));
+
+ smb_io_unistr2("", &(f->name), f->name_ptr, ps, depth);
+ }
return True;
}
@@ -4033,20 +4235,20 @@ static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps,
********************************************************************/
BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth)
{
- uint32 useless_ptr=0;
- prs_debug(ps, depth, desc, "spoolss_io_q_addform");
- depth++;
+ uint32 useless_ptr=0;
+ prs_debug(ps, depth, desc, "spoolss_io_q_addform");
+ depth++;
- prs_align(ps);
- smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth);
- prs_uint32("level", ps, depth, &(q_u->level));
- prs_uint32("level2", ps, depth, &(q_u->level2));
+ prs_align(ps);
+ smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth);
+ prs_uint32("level", ps, depth, &(q_u->level));
+ prs_uint32("level2", ps, depth, &(q_u->level2));
- if (q_u->level==1)
- {
- prs_uint32("useless_ptr", ps, depth, &(useless_ptr));
- spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth);
- }
+ if (q_u->level==1)
+ {
+ prs_uint32("useless_ptr", ps, depth, &(useless_ptr));
+ spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth);
+ }
return True;
}
@@ -4055,11 +4257,11 @@ BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int
********************************************************************/
BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth)
{
- prs_debug(ps, depth, desc, "spoolss_io_r_addform");
- depth++;
+ prs_debug(ps, depth, desc, "spoolss_io_r_addform");
+ depth++;
- prs_align(ps);
- prs_uint32("status", ps, depth, &(r_u->status));
+ prs_align(ps);
+ prs_uint32("status", ps, depth, &(r_u->status));
return True;
}
@@ -4104,57 +4306,134 @@ BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int
}
/*******************************************************************
- Parse a SPOOL_R_GETJOB structure.
********************************************************************/
BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth)
{
+ uint32 useless_ptr=0xADDE0FF0;
+ uint32 start_offset, end_offset, beginning;
+ uint32 bufsize_required=0;
+
prs_debug(ps, depth, desc, "spoolss_io_r_getjob");
depth++;
- if (!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint32("pointer", ps, depth, &useless_ptr);
+
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ JOB_INFO_1 *info;
+ info=r_u->ctr.job.job_info_1;
+
+ bufsize_required += spoolss_size_job_info_1(info);
+ break;
+ }
+ case 2:
+ {
+ JOB_INFO_2 *info;
+ info=r_u->ctr.job.job_info_2;
+
+ bufsize_required += spoolss_size_job_info_2(info);
+ break;
+ }
+ }
+
+ DEBUG(4,("spoolss_io_r_getjob, size needed: %d\n",bufsize_required));
+ DEBUG(4,("spoolss_io_r_getjob, size offered: %d\n",r_u->offered));
+
+ /* check if the buffer is big enough for the datas */
+ if (r_u->offered<bufsize_required)
+ {
+ /* it's too small */
+ r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */
+ r_u->offered=0; /* don't send back the buffer */
- if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer))
- return False;
+ DEBUG(4,("spoolss_io_r_getjob, buffer too small\n"));
- if (!prs_align(ps))
- return False;
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ }
+ else
+ {
+ DEBUG(4,("spoolss_io_r_enumjobs, buffer large enough\n"));
+
+ prs_uint32("size of buffer", ps, depth, &(r_u->offered));
+ beginning=ps->offset;
+ start_offset=ps->offset;
+ end_offset=start_offset+r_u->offered;
- if (!prs_uint32("needed", ps, depth, &r_u->needed))
- return False;
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ JOB_INFO_1 *info;
+ info = r_u->ctr.job.job_info_1;
+ smb_io_job_info_1(desc, info, ps, depth, &start_offset, &end_offset);
+ break;
+ }
+ case 2:
+ {
+ JOB_INFO_2 *info;
+ info = r_u->ctr.job.job_info_2;
+ smb_io_job_info_2(desc, info, ps, depth, &start_offset, &end_offset);
+ break;
+ }
- if (!prs_uint32("status", ps, depth, &r_u->status))
- return False;
+ }
+ ps->offset=beginning+r_u->offered;
+ prs_align(ps);
+ }
+
+ /*
+ * if the buffer was too small, send the minimum required size
+ * if it was too large, send the real needed size
+ */
+
+ prs_uint32("size of buffer needed", ps, depth, &(bufsize_required));
+ prs_uint32("status", ps, depth, &(r_u->status));
- return True;
+ return True;
+}
+
+/****************************************************************************
+****************************************************************************/
+void free_spoolss_r_getjob(SPOOL_R_GETJOB *r_u)
+{
+ switch (r_u->level)
+ {
+ case 1:
+ {
+ free(r_u->ctr.job.job_info_1);
+ break;
+ }
+ case 2:
+ {
+ free_job_info_2(r_u->ctr.job.job_info_2);
+ break;
+ }
+ }
}
/*******************************************************************
- Parse a SPOOL_Q_GETJOB structure.
********************************************************************/
BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth)
{
+
prs_debug(ps, depth, desc, "");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth))
- return False;
- if(!prs_uint32("jobid", ps, depth, &q_u->jobid))
- return False;
- if(!prs_uint32("level", ps, depth, &q_u->level))
- return False;
+ smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth);
+ prs_uint32("jobid", ps, depth, &(q_u->jobid));
+ prs_uint32("level", ps, depth, &(q_u->level));
- if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer))
- return False;
+ spoolss_io_read_buffer("", ps, depth, &(q_u->buffer));
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("offered", ps, depth, &q_u->offered))
- return False;
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
return True;
}
diff --git a/source/rpc_parse/parse_srv.c b/source/rpc_parse/parse_srv.c
index 8997b05e0b7..3b22054f129 100644
--- a/source/rpc_parse/parse_srv.c
+++ b/source/rpc_parse/parse_srv.c
@@ -3,10 +3,10 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jeremy Allison 1999.
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Paul Ashton 1997-2000,
+ * Copyright (C) Elrond 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,40 +25,49 @@
#include "includes.h"
+#include "nterr.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
+
/*******************************************************************
- Inits a SH_INFO_1_STR structure
+ makes a SH_INFO_1_STR structure
********************************************************************/
-
-void init_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark)
+BOOL make_srv_share_info1_str(SH_INFO_1_STR *sh1,
+ const char *net_name, const char *remark)
{
- DEBUG(5,("init_srv_share_info1_str\n"));
+ if (sh1 == NULL) return False;
+
+ DEBUG(5,("make_srv_share_info1_str\n"));
+
+ make_unistr2(&(sh1->uni_netname), net_name, strlen(net_name)+1);
+ make_unistr2(&(sh1->uni_remark ), remark , strlen(remark )+1);
+
+ return True;
+}
- init_unistr2(&sh1->uni_netname, net_name, strlen(net_name)+1);
- init_unistr2(&sh1->uni_remark, remark, strlen(remark)+1);
+static void srv_free_share_info1_str(SH_INFO_1_STR *sh1)
+{
+ safe_free(sh1);
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *ps, int depth)
+static BOOL srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *ps, int depth)
{
- if (sh1 == NULL)
- return False;
+ if (sh1 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_share_info1_str");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unistr2("", &sh1->uni_netname, True, ps, depth))
- return False;
- if(!smb_io_unistr2("", &sh1->uni_remark, True, ps, depth))
- return False;
+ smb_io_unistr2("", &(sh1->uni_netname), True, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("", &(sh1->uni_remark ), True, ps, depth);
+ prs_align(ps);
return True;
}
@@ -66,768 +75,919 @@ static BOOL srv_io_share_info1_str(char *desc, SH_INFO_1_STR *sh1, prs_struct *p
/*******************************************************************
makes a SH_INFO_1 structure
********************************************************************/
-
-void init_srv_share_info1(SH_INFO_1 *sh1, char *net_name, uint32 type, char *remark)
+BOOL make_srv_share_info1(SH_INFO_1 *sh1,
+ const char *net_name, uint32 type,
+ const char *remark)
{
- DEBUG(5,("init_srv_share_info1: %s %8x %s\n", net_name, type, remark));
+ if (sh1 == NULL) return False;
+
+ DEBUG(5,("make_srv_share_info1: %s %8x %s\n", net_name, type, remark));
- sh1->ptr_netname = (net_name != NULL) ? 1 : 0;
+ sh1->ptr_netname = net_name != NULL ? 1 : 0;
sh1->type = type;
- sh1->ptr_remark = (remark != NULL) ? 1 : 0;
+ sh1->ptr_remark = remark != NULL ? 1 : 0;
+
+ return True;
+}
+
+static void srv_free_share_info1(SH_INFO_1 *sh1)
+{
+ safe_free(sh1);
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_share_info1(char *desc, SH_INFO_1 *sh1, prs_struct *ps, int depth)
+static BOOL srv_io_share_info1(char *desc, SH_INFO_1 *sh1, prs_struct *ps, int depth)
{
- if (sh1 == NULL)
- return False;
+ if (sh1 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_share_info1");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_netname", ps, depth, &sh1->ptr_netname))
- return False;
- if(!prs_uint32("type ", ps, depth, &sh1->type))
- return False;
- if(!prs_uint32("ptr_remark ", ps, depth, &sh1->ptr_remark))
- return False;
+ prs_uint32("ptr_netname", ps, depth, &(sh1->ptr_netname));
+ prs_uint32("type ", ps, depth, &(sh1->type ));
+ prs_uint32("ptr_remark ", ps, depth, &(sh1->ptr_remark));
return True;
}
/*******************************************************************
- Inits a SH_INFO_2_STR structure
+reads or writes a structure.
********************************************************************/
+static void srv_free_srv_share_info_1(SRV_SHARE_INFO_1 *ctr)
+{
+ void(*fn)(void*) = (void(*)(void*))&srv_free_share_info1;
+ void(*fnstr)(void*) = (void(*)(void*))&srv_free_share_info1_str;
+
+ if (!ctr) return;
-void init_srv_share_info2_str(SH_INFO_2_STR *sh2,
- char *net_name, char *remark,
- char *path, char *passwd)
+ free_void_array(ctr->num_entries_read,
+ (void**) ctr->info_1, *fn);
+ ctr->info_1 = NULL;
+ free_void_array(ctr->num_entries_read,
+ (void**) ctr->info_1_str, *fnstr);
+ ctr->info_1_str = NULL;
+
+ ctr->num_entries_read = 0;
+ ctr->ptr_share_info = 0;
+ ctr->num_entries_read2 = 0;
+}
+
+static BOOL srv_io_srv_share_info_1(char *desc, SRV_SHARE_INFO_1 *ctr, prs_struct *ps, int depth)
{
- DEBUG(5,("init_srv_share_info2_str\n"));
+ if (ctr == NULL) return False;
+
+ prs_debug(ps, depth, desc, "srv_io_share_1_ctr");
+ depth++;
+
+ if (ps->io)
+ {
+ ZERO_STRUCTP(ctr);
+ }
+
+ prs_align(ps);
- init_unistr2(&sh2->uni_netname, net_name, strlen(net_name)+1);
- init_unistr2(&sh2->uni_remark, remark, strlen(remark)+1);
- init_unistr2(&sh2->uni_path, path, strlen(path)+1);
- init_unistr2(&sh2->uni_passwd, passwd, strlen(passwd)+1);
+ prs_uint32("num_entries_read", ps, depth, &(ctr->num_entries_read));
+ prs_uint32("ptr_share_info", ps, depth, &(ctr->ptr_share_info));
+
+ if (ctr->ptr_share_info != 0)
+ {
+ uint32 i;
+ uint32 num_entries = ctr->num_entries_read;
+
+ prs_uint32("num_entries_read2", ps, depth, &(ctr->num_entries_read2));
+
+ if(ps->io)
+ {
+ ctr->info_1 = g_new0(SH_INFO_1 *, num_entries);
+ ctr->info_1_str = g_new0(SH_INFO_1_STR *, num_entries);
+ if (! ctr->info_1 || ! ctr->info_1_str)
+ {
+ srv_free_srv_share_info_1(ctr);
+ return False;
+ }
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ if(ps->io)
+ {
+ ctr->info_1[i] = g_new(SH_INFO_1, 1);
+ }
+ if (!srv_io_share_info1("", ctr->info_1[i], ps, depth))
+ {
+ srv_free_srv_share_info_1(ctr);
+ return False;
+ }
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ if(ps->io)
+ {
+ ctr->info_1_str[i] = g_new(SH_INFO_1_STR, 1);
+ }
+ if (!srv_io_share_info1_str("", ctr->info_1_str[i],
+ ps, depth))
+ {
+ srv_free_srv_share_info_1(ctr);
+ return False;
+ }
+ }
+
+ prs_align(ps);
+ }
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+ makes a SH_INFO_2_STR structure
********************************************************************/
+BOOL make_srv_share_info2_str(SH_INFO_2_STR *sh2,
+ const char *net_name, const char *remark,
+ const char *path, const char *pass)
+{
+ if (sh2 == NULL) return False;
-static BOOL srv_io_share_info2_str(char *desc, SH_INFO_2_STR *sh2, prs_struct *ps, int depth)
+ DEBUG(5,("make_srv_share_info2_str\n"));
+
+ make_unistr2(&(sh2->uni_netname), net_name, strlen(net_name)+1);
+ make_unistr2(&(sh2->uni_remark ), remark , strlen(remark )+1);
+ make_unistr2(&(sh2->uni_path ), path , strlen(path )+1);
+ make_unistr2(&(sh2->uni_passwd ), pass , strlen(pass )+1);
+
+ return True;
+}
+
+static void srv_free_share_info2_str(SH_INFO_2_STR *sh2)
+{
+ safe_free(sh2);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL srv_io_share_info2_str(char *desc, SH_INFO_2_STR *ss2, SH_INFO_2 *sh2, prs_struct *ps, int depth)
{
- if (sh2 == NULL)
- return False;
+ if (ss2 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_share_info2_str");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unistr2("", &sh2->uni_netname, True, ps, depth))
- return False;
- if(!smb_io_unistr2("", &sh2->uni_remark, True, ps, depth))
- return False;
- if(!smb_io_unistr2("", &sh2->uni_path, True, ps, depth))
- return False;
- if(!smb_io_unistr2("", &sh2->uni_passwd, True, ps, depth))
- return False;
+ smb_io_unistr2("netname", &(ss2->uni_netname), sh2->ptr_netname, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("remark ", &(ss2->uni_remark ), sh2->ptr_remark , ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("path ", &(ss2->uni_path ), sh2->ptr_path , ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("passwd ", &(ss2->uni_passwd ), sh2->ptr_passwd , ps, depth);
+ prs_align(ps);
return True;
}
/*******************************************************************
- Inits a SH_INFO_2 structure
+ makes a SH_INFO_2 structure
********************************************************************/
-
-void init_srv_share_info2(SH_INFO_2 *sh2,
- char *net_name, uint32 type, char *remark,
- uint32 perms, uint32 max_uses, uint32 num_uses,
- char *path, char *passwd)
+BOOL make_srv_share_info2(SH_INFO_2 *sh2,
+ const char *net_name, uint32 type,
+ const char *remark,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ const char *path, const char *pass)
{
- DEBUG(5,("init_srv_share_info2: %s %8x %s\n", net_name, type, remark));
+ if (sh2 == NULL) return False;
- sh2->ptr_netname = (net_name != NULL) ? 1 : 0;
+ DEBUG(5,("make_srv_share_info2: %s %8x %s\n", net_name, type, remark));
+
+ sh2->ptr_netname = net_name != NULL ? 1 : 0;
sh2->type = type;
- sh2->ptr_remark = (remark != NULL) ? 1 : 0;
+ sh2->ptr_remark = remark != NULL ? 1 : 0;
sh2->perms = perms;
sh2->max_uses = max_uses;
sh2->num_uses = num_uses;
sh2->type = type;
- sh2->ptr_path = (path != NULL) ? 1 : 0;
- sh2->ptr_passwd = (passwd != NULL) ? 1 : 0;
+ sh2->ptr_path = path != NULL ? 1 : 0;
+ sh2->ptr_passwd = pass != NULL ? 1 : 0;
+
+ return True;
+}
+
+static void srv_free_share_info2(SH_INFO_2 *sh2)
+{
+ safe_free(sh2);
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_share_info2(char *desc, SH_INFO_2 *sh2, prs_struct *ps, int depth)
+static BOOL srv_io_share_info2(char *desc, SH_INFO_2 *sh2, prs_struct *ps, int depth)
{
- if (sh2 == NULL)
- return False;
+ if (sh2 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_share_info2");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_netname", ps, depth, &sh2->ptr_netname))
- return False;
- if(!prs_uint32("type ", ps, depth, &sh2->type))
- return False;
- if(!prs_uint32("ptr_remark ", ps, depth, &sh2->ptr_remark))
- return False;
- if(!prs_uint32("perms ", ps, depth, &sh2->perms))
- return False;
- if(!prs_uint32("max_uses ", ps, depth, &sh2->max_uses))
- return False;
- if(!prs_uint32("num_uses ", ps, depth, &sh2->num_uses))
- return False;
- if(!prs_uint32("ptr_path ", ps, depth, &sh2->ptr_path))
- return False;
- if(!prs_uint32("ptr_passwd ", ps, depth, &sh2->ptr_passwd))
- return False;
+ prs_uint32("ptr_netname", ps, depth, &(sh2->ptr_netname));
+ prs_uint32("type ", ps, depth, &(sh2->type ));
+ prs_uint32("ptr_remark ", ps, depth, &(sh2->ptr_remark ));
+ prs_uint32("perms ", ps, depth, &(sh2->perms ));
+ prs_uint32("max_uses ", ps, depth, &(sh2->max_uses ));
+ prs_uint32("num_uses ", ps, depth, &(sh2->num_uses ));
+ prs_uint32("ptr_path ", ps, depth, &(sh2->ptr_path ));
+ prs_uint32("ptr_passwd ", ps, depth, &(sh2->ptr_passwd ));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
+static BOOL srv_io_share_info502_hdr(char *desc, SH_INFO_502_HDR *sh502,
+ prs_struct *ps, int depth)
+{
+ if (sh502 == NULL) return False;
+
+ prs_debug(ps, depth, desc, "srv_io_share_info502_hdr");
+ depth++;
+
+ prs_align(ps);
+
+ srv_io_share_info2("", &(sh502->info2_hdr), ps, depth);
+
+ prs_uint32("sd_size", ps, depth, &(sh502->sd_size));
+ prs_uint32("sd_ptr ", ps, depth, &(sh502->sd_ptr));
-static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct *ps, int depth)
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL srv_io_share_info502_data(char *desc,
+ SH_INFO_502_DATA *sh502,
+ SH_INFO_502_HDR *si502,
+ prs_struct *ps, int depth)
{
- if (ctr == NULL)
- return False;
+ if (sh502 == NULL) return False;
- prs_debug(ps, depth, desc, "srv_io_srv_share_ctr");
+ prs_debug(ps, depth, desc, "srv_io_share_info502_data");
depth++;
- if (UNMARSHALLING(ps)) {
- memset(ctr, '\0', sizeof(SRV_SHARE_INFO_CTR));
+ prs_align(ps);
+
+ srv_io_share_info2_str("", &(sh502->info2_str), &(si502->info2_hdr),
+ ps, depth);
+ prs_align(ps);
+
+ if (si502->sd_ptr)
+ {
+ prs_uint32("sd_size2", ps, depth, &(sh502->sd_size2));
+
+ sec_io_desc("", &(sh502->sd), ps, depth);
}
- if(!prs_align(ps))
- return False;
+ return True;
+}
- if(!prs_uint32("info_level", ps, depth, &ctr->info_level))
- return False;
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL srv_io_share_info502(char *desc,
+ SHARE_INFO_502 *sh502,
+ prs_struct *ps, int depth)
+{
+ if (sh502 == NULL) return False;
- if (ctr->info_level == 0)
- return True;
+ prs_debug(ps, depth, desc, "srv_io_share_info502");
+ depth++;
- if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
- return False;
- if(!prs_uint32("ptr_share_info", ps, depth, &ctr->ptr_share_info))
- return False;
+ prs_align(ps);
- if (ctr->ptr_share_info == 0)
- return True;
+ srv_io_share_info502_hdr("", &(sh502->info502_hdr), ps, depth);
+ srv_io_share_info502_data("",
+ &(sh502->info502_data),
+ &(sh502->info502_hdr),
+ ps, depth);
- if(!prs_uint32("num_entries", ps, depth, &ctr->num_entries))
- return False;
- if(!prs_uint32("ptr_entries", ps, depth, &ctr->ptr_entries))
- return False;
+ return True;
+}
- if (ctr->ptr_entries == 0) {
- if (ctr->num_entries == 0)
- return True;
- else
- return False;
- }
- if(!prs_uint32("num_entries2", ps, depth, &ctr->num_entries2))
- return False;
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_free_srv_share_info_2(SRV_SHARE_INFO_2 *ctr)
+{
+ void(*fn)(void*) = (void(*)(void*))&srv_free_share_info2;
+ void(*fnstr)(void*) = (void(*)(void*))&srv_free_share_info2_str;
- if (ctr->num_entries2 != ctr->num_entries)
- return False;
+ if (!ctr) return;
- switch (ctr->switch_value) {
- case 1:
- {
- SRV_SHARE_INFO_1 *info1 = ctr->share.info1;
- int num_entries = ctr->num_entries;
- int i;
+ free_void_array(ctr->num_entries_read,
+ (void**) ctr->info_2, *fn);
+ free_void_array(ctr->num_entries_read,
+ (void**) ctr->info_2_str, *fnstr);
- if (UNMARSHALLING(ps)) {
- if (!(info1 = malloc(num_entries * sizeof(SRV_SHARE_INFO_1))))
- return False;
- memset(info1, '\0', num_entries * sizeof(SRV_SHARE_INFO_1));
- ctr->share.info1 = info1;
- }
+ ctr->num_entries_read = 0;
+ ctr->ptr_share_info = 0;
+}
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_share_info1("", &info1[i].info_1, ps, depth))
- return False;
- }
+static BOOL srv_io_srv_share_info_2(char *desc, SRV_SHARE_INFO_2 *ctr, prs_struct *ps, int depth)
+{
+ if (ctr == NULL) return False;
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_share_info1_str("", &info1[i].info_1_str, ps, depth))
- return False;
- }
+ prs_debug(ps, depth, desc, "srv_io_share_2_ctr");
+ depth++;
- break;
+ if(ps->io)
+ {
+ ZERO_STRUCTP(ctr);
}
- case 2:
- {
- SRV_SHARE_INFO_2 *info2 = ctr->share.info2;
- int num_entries = ctr->num_entries;
- int i;
+ prs_align(ps);
- if (UNMARSHALLING(ps)) {
- if (!(info2 = malloc(num_entries * sizeof(SRV_SHARE_INFO_2))))
+ prs_uint32("num_entries_read", ps, depth, &(ctr->num_entries_read));
+ prs_uint32("ptr_share_info", ps, depth, &(ctr->ptr_share_info));
+
+ if (ctr->ptr_share_info != 0)
+ {
+ uint32 i;
+ uint32 num_entries = ctr->num_entries_read;
+
+ prs_uint32("num_entries_read2", ps, depth, &(ctr->num_entries_read2));
+
+ if(ps->io)
+ {
+ ctr->info_2 = g_new0(SH_INFO_2 *, num_entries);
+ ctr->info_2_str = g_new0(SH_INFO_2_STR *, num_entries);
+ if (! ctr->info_2 || ! ctr->info_2_str)
+ {
+ srv_free_srv_share_info_2(ctr);
return False;
- memset(info2, '\0', num_entries * sizeof(SRV_SHARE_INFO_2));
- ctr->share.info2 = info2;
+ }
}
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_share_info2("", &info2[i].info_2, ps, depth))
+ for (i = 0; i < num_entries; i++)
+ {
+ if(ps->io)
+ {
+ ctr->info_2[i] = g_new(SH_INFO_2, 1);
+ }
+ if (!srv_io_share_info2("", ctr->info_2[i], ps, depth))
+ {
+ srv_free_srv_share_info_2(ctr);
return False;
+ }
}
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_share_info2_str("", &info2[i].info_2_str, ps, depth))
+ for (i = 0; i < num_entries; i++)
+ {
+ if(ps->io)
+ {
+ ctr->info_2_str[i] = g_new(SH_INFO_2_STR, 1);
+ }
+ if (!srv_io_share_info2_str("", ctr->info_2_str[i], ctr->info_2[i], ps, depth))
+ {
+ srv_free_srv_share_info_2(ctr);
return False;
+ }
}
- break;
- }
-
- default:
- DEBUG(5,("%s no share info at switch_value %d\n",
- tab_depth(depth), ctr->switch_value));
- break;
+ prs_align(ps);
}
return True;
}
/*******************************************************************
- Frees a SRV_SHARE_INFO_CTR structure.
+reads or writes a structure.
********************************************************************/
-
-void free_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr)
+void srv_free_srv_share_ctr(SRV_SHARE_INFO_CTR *ctr)
{
- if(!ctr)
- return;
- if(ctr->share.info)
- free(ctr->share.info);
- memset(ctr, '\0', sizeof(SRV_SHARE_INFO_CTR));
+ if(! ctr) return;
+ switch (ctr->switch_value)
+ {
+ case 2:
+ srv_free_srv_share_info_2(&(ctr->share.info2));
+ break;
+ case 1:
+ srv_free_srv_share_info_1(&(ctr->share.info1));
+ break;
+ }
}
-/*******************************************************************
- Frees a SRV_Q_NET_SHARE_ENUM structure.
-********************************************************************/
-
-void free_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n)
+static BOOL srv_io_srv_share_ctr(char *desc, SRV_SHARE_INFO_CTR *ctr, prs_struct *ps, int depth)
{
- if(!q_n)
- return;
- free_srv_share_info_ctr(&q_n->ctr);
- memset(q_n, '\0', sizeof(SRV_Q_NET_SHARE_ENUM));
-}
+ if (ctr == NULL) return False;
-/*******************************************************************
- Frees a SRV_R_NET_SHARE_ENUM structure.
-********************************************************************/
+ prs_debug(ps, depth, desc, "srv_io_srv_share_ctr");
+ depth++;
-void free_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n)
-{
- if(!r_n)
- return;
- free_srv_share_info_ctr(&r_n->ctr);
- memset(r_n, '\0', sizeof(SRV_R_NET_SHARE_ENUM));
+ prs_align(ps);
+
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_share_ctr", ps, depth, &(ctr->ptr_share_ctr));
+
+ if (ctr->ptr_share_ctr != 0)
+ {
+ switch (ctr->switch_value)
+ {
+ case 2:
+ {
+ srv_io_srv_share_info_2("", &(ctr->share.info2), ps, depth);
+ break;
+ }
+ case 1:
+ {
+ srv_io_srv_share_info_1("", &(ctr->share.info1), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s no share info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
+ }
+ }
+
+ return True;
}
/*******************************************************************
- Inits a SRV_Q_NET_SHARE_ENUM structure.
+reads or writes a structure.
********************************************************************/
-
-void init_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
- char *srv_name, uint32 info_level,
- uint32 preferred_len, ENUM_HND *hnd)
+BOOL make_srv_q_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
+ const char *srv_name,
+ uint32 share_level, SRV_SHARE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
{
+ if (q_n == NULL || ctr == NULL || hnd == NULL) return False;
- DEBUG(5,("init_q_net_share_enum\n"));
+ q_n->ctr = ctr;
+
+ DEBUG(5,("make_q_net_share_enum\n"));
- init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
+ make_buf_unistr2(&(q_n->uni_srv_name), &(q_n->ptr_srv_name), srv_name);
- q_n->ctr.info_level = q_n->ctr.switch_value = info_level;
- q_n->ctr.ptr_share_info = 0;
+ q_n->share_level = share_level;
q_n->preferred_len = preferred_len;
- memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
+ memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL srv_io_q_net_share_enum(char *desc, SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth)
+BOOL srv_io_q_net_share_enum(char *desc, SRV_Q_NET_SHARE_ENUM *q_n, prs_struct *ps, int depth)
{
- if (q_n == NULL)
- return False;
+ if (q_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_q_net_share_enum");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint32("ptr_srv_name", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth);
- if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
- return False;
+ prs_align(ps);
- if(!srv_io_srv_share_ctr("share_ctr", &q_n->ctr, ps, depth))
- return False;
+ prs_uint32("share_level", ps, depth, &(q_n->share_level ));
- if(!prs_align(ps))
- return False;
+ if (((int)q_n->share_level) != -1)
+ {
+ srv_io_srv_share_ctr("share_ctr", q_n->ctr, ps, depth);
+ }
- if(!prs_uint32("preferred_len", ps, depth, &q_n->preferred_len))
- return False;
+ prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
- if(!smb_io_enum_hnd("enum_hnd", &q_n->enum_hnd, ps, depth))
- return False;
+ smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth);
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth)
+BOOL srv_io_r_net_share_enum(char *desc, SRV_R_NET_SHARE_ENUM *r_n, prs_struct *ps, int depth)
{
- if (r_n == NULL)
- return False;
+ if (r_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_r_net_share_enum");
depth++;
- if(!srv_io_srv_share_ctr("share_ctr", &r_n->ctr, ps, depth))
- return False;
+ prs_align(ps);
+
+ prs_uint32("share_level", ps, depth, &(r_n->share_level));
- if(!prs_align(ps))
- return False;
+ if (r_n->share_level != 0)
+ {
+ srv_io_srv_share_ctr("share_ctr", r_n->ctr, ps, depth);
+ }
- if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
- return False;
- if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
- return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
- return False;
+ prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
+ smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth);
+ prs_uint32("status ", ps, depth, &(r_n->status));
return True;
}
+
/*******************************************************************
- Frees a SRV_Q_NET_SHARE_GET_INFO structure.
+ makes a structure
********************************************************************/
-
-void free_srv_q_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n)
+BOOL make_srv_q_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n,
+ const UNISTR2 *srv_name,
+ const UNISTR2 *share_name,
+ uint32 info_level)
{
- if(!q_n)
- return;
- memset(q_n, '\0', sizeof(SRV_Q_NET_SHARE_GET_INFO));
-}
+ if (q_n == NULL) return False;
-/*******************************************************************
- Frees a SRV_R_NET_SHARE_GET_INFO structure.
-********************************************************************/
+ q_n->ptr_srv_name = (srv_name != NULL);
+ copy_unistr2(&(q_n->uni_srv_name), srv_name);
+ copy_unistr2(&(q_n->share_name), share_name);
+ q_n->info_level = info_level;
-void free_srv_r_net_share_get_info(SRV_R_NET_SHARE_GET_INFO *r_n)
-{
- if(!r_n)
- return;
- memset(r_n, '\0', sizeof(SRV_R_NET_SHARE_GET_INFO));
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL srv_io_q_net_share_get_info(char *desc, SRV_Q_NET_SHARE_GET_INFO *q_n, prs_struct *ps, int depth)
+BOOL srv_io_q_net_share_get_info(char *desc, SRV_Q_NET_SHARE_GET_INFO *q_n,
+ prs_struct *ps, int depth)
{
- if (q_n == NULL)
- return False;
+ if (q_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_q_net_share_get_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
- return False;
+ prs_uint32("ptr_srv_name", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("uni_srv_name", &(q_n->uni_srv_name), True, ps, depth);
+ prs_align(ps);
- if(!smb_io_unistr2("", &q_n->uni_share_name, True, ps, depth))
- return False;
+ smb_io_unistr2("share_name", &(q_n->share_name), True, ps, depth);
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("info_level", ps, depth, &q_n->info_level))
- return False;
+ prs_uint32("info_level", ps, depth, &(q_n->info_level));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+ makes a structure
********************************************************************/
-
-BOOL srv_io_r_net_share_get_info(char *desc, SRV_R_NET_SHARE_GET_INFO *r_n, prs_struct *ps, int depth)
+BOOL make_srv_r_net_share_get_info(SRV_R_NET_SHARE_GET_INFO *r_n,
+ uint32 info_level,
+ SHARE_INFO_CTR *ctr,
+ uint32 status)
{
- if (r_n == NULL)
- return False;
+ if (r_n == NULL) return False;
- prs_debug(ps, depth, desc, "srv_io_r_net_share_get_info");
- depth++;
+ r_n->info_level = info_level;
- if(!prs_align(ps))
- return False;
+ if (status == NT_STATUS_NOPROBLEMO)
+ {
+ r_n->info_ptr = (ctr != NULL ? 1 : 0);
+ }
+ else
+ {
+ r_n->info_ptr = 0;
+ }
- if(!prs_uint32("switch_value ", ps, depth, &r_n->switch_value ))
- return False;
+ r_n->status = status;
- if(!prs_uint32("ptr_share_ctr", ps, depth, &r_n->ptr_share_ctr))
- return False;
+ return True;
+}
- if (r_n->ptr_share_ctr != 0) {
- switch (r_n->switch_value) {
- case 1:
- if(!srv_io_share_info1("", &r_n->share.info1.info_1, ps, depth))
- return False;
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL srv_io_r_net_share_get_info(char *desc, SRV_R_NET_SHARE_GET_INFO *r_n,
+ prs_struct *ps, int depth)
+{
+ if (r_n == NULL) return False;
- if(!srv_io_share_info1_str("", &r_n->share.info1.info_1_str, ps, depth))
- return False;
+ prs_debug(ps, depth, desc, "srv_io_r_net_share_get_info");
+ depth++;
- break;
- case 2:
- if(!srv_io_share_info2("", &r_n->share.info2.info_2, ps, depth))
- return False;
+ prs_align(ps);
- if(!srv_io_share_info2_str("", &r_n->share.info2.info_2_str, ps, depth))
- return False;
+ prs_uint32("info_level", ps, depth, &(r_n->info_level));
+ prs_uint32("info_ptr ", ps, depth, &(r_n->info_ptr));
- break;
- default:
- DEBUG(5,("%s no share info at switch_value %d\n",
- tab_depth(depth), r_n->switch_value));
- break;
+ if (r_n->info_ptr)
+ {
+ switch (r_n->info_level)
+ {
+ case 502:
+ srv_io_share_info502("info",
+ &(r_n->info.info502),
+ ps, depth);
+ break;
+ default:
+ DEBUG(1, ("srv_io_r_net_share_get_info: Unsupported info level %d\n",
+ r_n->info_level));
+ return False;
+ break;
}
}
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("status", ps, depth, &r_n->status))
- return False;
+ prs_uint32("status ", ps, depth, &(r_n->status));
return True;
}
+
/*******************************************************************
- Inits a SESS_INFO_0_STR structure
+ makes a SESS_INFO_0_STR structure
********************************************************************/
-
-void init_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name)
+BOOL make_srv_sess_info0_str(SESS_INFO_0_STR *ss0, char *name)
{
- DEBUG(5,("init_srv_sess_info0_str\n"));
+ if (ss0 == NULL) return False;
+
+ DEBUG(5,("make_srv_sess_info0_str\n"));
- init_unistr2(&ss0->uni_name, name, strlen(name)+1);
+ make_unistr2(&(ss0->uni_name), name, strlen(name)+1);
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_sess_info0_str(char *desc, SESS_INFO_0_STR *ss0, prs_struct *ps, int depth)
+static BOOL srv_io_sess_info0_str(char *desc, SESS_INFO_0_STR *ss0,
+ const SESS_INFO_0 *si0,
+ prs_struct *ps, int depth)
{
- if (ss0 == NULL)
- return False;
+ if (ss0 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_sess_info0_str");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unistr2("", &ss0->uni_name, True, ps, depth))
- return False;
+ smb_io_unistr2("", &(ss0->uni_name), si0->ptr_name, ps, depth);
+ prs_align(ps);
return True;
}
/*******************************************************************
- Inits a SESS_INFO_0 structure
+ makes a SESS_INFO_0 structure
********************************************************************/
-
-void init_srv_sess_info0(SESS_INFO_0 *ss0, char *name)
+BOOL make_srv_sess_info0(SESS_INFO_0 *ss0, char *name)
{
- DEBUG(5,("init_srv_sess_info0: %s\n", name));
+ if (ss0 == NULL) return False;
+
+ DEBUG(5,("make_srv_sess_info0: %s\n", name));
+
+ ss0->ptr_name = name != NULL ? 1 : 0;
- ss0->ptr_name = (name != NULL) ? 1 : 0;
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_sess_info0(char *desc, SESS_INFO_0 *ss0, prs_struct *ps, int depth)
+static BOOL srv_io_sess_info0(char *desc, SESS_INFO_0 *ss0, prs_struct *ps, int depth)
{
- if (ss0 == NULL)
- return False;
+ if (ss0 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_sess_info0");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_name", ps, depth, &ss0->ptr_name))
- return False;
+ prs_uint32("ptr_name", ps, depth, &(ss0->ptr_name));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_srv_sess_info_0(char *desc, SRV_SESS_INFO_0 *ss0, prs_struct *ps, int depth)
+static BOOL srv_io_srv_sess_info_0(char *desc, SRV_SESS_INFO_0 *ss0, prs_struct *ps, int depth)
{
- if (ss0 == NULL)
- return False;
+ if (ss0 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_srv_sess_info_0");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("num_entries_read", ps, depth, &ss0->num_entries_read))
- return False;
- if(!prs_uint32("ptr_sess_info", ps, depth, &ss0->ptr_sess_info))
- return False;
+ prs_align(ps);
- if (ss0->ptr_sess_info != 0) {
- int i;
- int num_entries = ss0->num_entries_read;
+ prs_uint32("num_entries_read", ps, depth, &(ss0->num_entries_read));
+ prs_uint32("ptr_sess_info", ps, depth, &(ss0->ptr_sess_info));
- if (num_entries > MAX_SESS_ENTRIES) {
+ if (ss0->ptr_sess_info != 0)
+ {
+ uint32 i;
+ uint32 num_entries = ss0->num_entries_read;
+ if (num_entries > MAX_SESS_ENTRIES)
+ {
num_entries = MAX_SESS_ENTRIES; /* report this! */
}
- if(!prs_uint32("num_entries_read2", ps, depth, &ss0->num_entries_read2))
- return False;
+ prs_uint32("num_entries_read2", ps, depth, &(ss0->num_entries_read2));
SMB_ASSERT_ARRAY(ss0->info_0, num_entries);
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_sess_info0("", &ss0->info_0[i], ps, depth))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ srv_io_sess_info0("", &(ss0->info_0[i]), ps, depth);
}
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_sess_info0_str("", &ss0->info_0_str[i], ps, depth))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ srv_io_sess_info0_str("", &(ss0->info_0_str[i]),
+ &(ss0->info_0[i]),
+ ps, depth);
}
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
}
return True;
}
/*******************************************************************
- Inits a SESS_INFO_1_STR structure
+ makes a SESS_INFO_1_STR structure
********************************************************************/
-
-void init_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user)
+BOOL make_srv_sess_info1_str(SESS_INFO_1_STR *ss1, char *name, char *user)
{
- DEBUG(5,("init_srv_sess_info1_str\n"));
+ if (ss1 == NULL) return False;
+
+ DEBUG(5,("make_srv_sess_info1_str\n"));
- init_unistr2(&ss1->uni_name, name, strlen(name)+1);
- init_unistr2(&ss1->uni_user, name, strlen(user)+1);
+ make_unistr2(&(ss1->uni_name), name, strlen(name)+1);
+ make_unistr2(&(ss1->uni_user), name, strlen(user)+1);
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_sess_info1_str(char *desc, SESS_INFO_1_STR *ss1, prs_struct *ps, int depth)
+static BOOL srv_io_sess_info1_str(char *desc, SESS_INFO_1_STR *ss1,
+ SESS_INFO_1 *si1,
+ prs_struct *ps, int depth)
{
- if (ss1 == NULL)
- return False;
+ if (ss1 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_sess_info1_str");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unistr2("", &ss1->uni_name, True, ps, depth))
- return False;
- if(!smb_io_unistr2("", &(ss1->uni_user), True, ps, depth))
- return False;
+ smb_io_unistr2("", &(ss1->uni_name), si1->ptr_name, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("", &(ss1->uni_user), si1->ptr_user, ps, depth);
+ prs_align(ps);
return True;
}
/*******************************************************************
- Inits a SESS_INFO_1 structure
+ makes a SESS_INFO_1 structure
********************************************************************/
-
-void init_srv_sess_info1(SESS_INFO_1 *ss1,
+BOOL make_srv_sess_info1(SESS_INFO_1 *ss1,
char *name, char *user,
uint32 num_opens, uint32 open_time, uint32 idle_time,
uint32 user_flags)
{
- DEBUG(5,("init_srv_sess_info1: %s\n", name));
+ if (ss1 == NULL) return False;
+
+ DEBUG(5,("make_srv_sess_info1: %s\n", name));
- ss1->ptr_name = (name != NULL) ? 1 : 0;
- ss1->ptr_user = (user != NULL) ? 1 : 0;
+ ss1->ptr_name = name != NULL ? 1 : 0;
+ ss1->ptr_user = user != NULL ? 1 : 0;
ss1->num_opens = num_opens;
ss1->open_time = open_time;
ss1->idle_time = idle_time;
ss1->user_flags = user_flags;
+
+ return True;
}
/*******************************************************************
reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_sess_info1(char *desc, SESS_INFO_1 *ss1, prs_struct *ps, int depth)
+static BOOL srv_io_sess_info1(char *desc, SESS_INFO_1 *ss1, prs_struct *ps, int depth)
{
- if (ss1 == NULL)
- return False;
+ if (ss1 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_sess_info1");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_name ", ps, depth, &ss1->ptr_name))
- return False;
- if(!prs_uint32("ptr_user ", ps, depth, &ss1->ptr_user))
- return False;
+ prs_uint32("ptr_name ", ps, depth, &(ss1->ptr_name ));
+ prs_uint32("ptr_user ", ps, depth, &(ss1->ptr_user ));
- if(!prs_uint32("num_opens ", ps, depth, &ss1->num_opens))
- return False;
- if(!prs_uint32("open_time ", ps, depth, &ss1->open_time))
- return False;
- if(!prs_uint32("idle_time ", ps, depth, &ss1->idle_time))
- return False;
- if(!prs_uint32("user_flags", ps, depth, &ss1->user_flags))
- return False;
+ prs_uint32("num_opens ", ps, depth, &(ss1->num_opens ));
+ prs_uint32("open_time ", ps, depth, &(ss1->open_time ));
+ prs_uint32("idle_time ", ps, depth, &(ss1->idle_time ));
+ prs_uint32("user_flags", ps, depth, &(ss1->user_flags));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_srv_sess_info_1(char *desc, SRV_SESS_INFO_1 *ss1, prs_struct *ps, int depth)
+static BOOL srv_io_srv_sess_info_1(char *desc, SRV_SESS_INFO_1 *ss1, prs_struct *ps, int depth)
{
- if (ss1 == NULL)
- return False;
+ if (ss1 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_srv_sess_info_1");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("num_entries_read", ps, depth, &ss1->num_entries_read))
- return False;
- if(!prs_uint32("ptr_sess_info", ps, depth, &ss1->ptr_sess_info))
- return False;
+ prs_align(ps);
- if (ss1->ptr_sess_info != 0) {
- int i;
- int num_entries = ss1->num_entries_read;
+ prs_uint32("num_entries_read", ps, depth, &(ss1->num_entries_read));
+ prs_uint32("ptr_sess_info", ps, depth, &(ss1->ptr_sess_info));
- if (num_entries > MAX_SESS_ENTRIES) {
+ if (ss1->ptr_sess_info != 0)
+ {
+ uint32 i;
+ uint32 num_entries = ss1->num_entries_read;
+ if (num_entries > MAX_SESS_ENTRIES)
+ {
num_entries = MAX_SESS_ENTRIES; /* report this! */
}
- if(!prs_uint32("num_entries_read2", ps, depth, &ss1->num_entries_read2))
- return False;
+ prs_uint32("num_entries_read2", ps, depth, &(ss1->num_entries_read2));
SMB_ASSERT_ARRAY(ss1->info_1, num_entries);
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_sess_info1("", &ss1->info_1[i], ps, depth))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ srv_io_sess_info1("", &(ss1->info_1[i]), ps, depth);
}
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_sess_info1_str("", &ss1->info_1_str[i], ps, depth))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ srv_io_sess_info1_str("", &(ss1->info_1_str[i]),
+ &(ss1->info_1[i]),
+ ps, depth);
}
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
}
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_srv_sess_ctr(char *desc, SRV_SESS_INFO_CTR *ctr, prs_struct *ps, int depth)
+static BOOL srv_io_srv_sess_ctr(char *desc, SRV_SESS_INFO_CTR *ctr, prs_struct *ps, int depth)
{
- if (ctr == NULL)
- return False;
+ if (ctr == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_srv_sess_ctr");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
- return False;
- if(!prs_uint32("ptr_sess_ctr", ps, depth, &ctr->ptr_sess_ctr))
- return False;
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_sess_ctr", ps, depth, &(ctr->ptr_sess_ctr));
- if (ctr->ptr_sess_ctr != 0) {
- switch (ctr->switch_value) {
- case 0:
- if(!srv_io_srv_sess_info_0("", &ctr->sess.info0, ps, depth))
- return False;
- break;
- case 1:
- if(!srv_io_srv_sess_info_1("", &ctr->sess.info1, ps, depth))
- return False;
- break;
- default:
- DEBUG(5,("%s no session info at switch_value %d\n",
- tab_depth(depth), ctr->switch_value));
- break;
+ if (ctr->ptr_sess_ctr != 0)
+ {
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ srv_io_srv_sess_info_0("", &(ctr->sess.info0), ps, depth);
+ break;
+ }
+ case 1:
+ {
+ srv_io_srv_sess_info_1("", &(ctr->sess.info1), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s no session info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
}
}
@@ -835,229 +995,212 @@ static BOOL srv_io_srv_sess_ctr(char *desc, SRV_SESS_INFO_CTR *ctr, prs_struct *
}
/*******************************************************************
- Inits a SRV_Q_NET_SESS_ENUM structure.
+reads or writes a structure.
********************************************************************/
-
-void init_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
- char *srv_name, char *qual_name,
+BOOL make_srv_q_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
+ const char *srv_name, const char *qual_name,
+ char *user_name,
uint32 sess_level, SRV_SESS_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd)
{
+ if (q_n == NULL || ctr == NULL || hnd == NULL) return False;
+
q_n->ctr = ctr;
- DEBUG(5,("init_q_net_sess_enum\n"));
+ DEBUG(5,("make_q_net_sess_enum\n"));
- init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
- init_buf_unistr2(&q_n->uni_qual_name, &q_n->ptr_qual_name, qual_name);
+ make_buf_unistr2(&(q_n->uni_srv_name), &(q_n->ptr_srv_name), srv_name);
+ make_buf_unistr2(&(q_n->uni_qual_name), &(q_n->ptr_qual_name), qual_name);
+ make_buf_unistr2(&(q_n->uni_user_name), &(q_n->ptr_user_name), user_name);
q_n->sess_level = sess_level;
q_n->preferred_len = preferred_len;
- memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
+ memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL srv_io_q_net_sess_enum(char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth)
+BOOL srv_io_q_net_sess_enum(char *desc, SRV_Q_NET_SESS_ENUM *q_n, prs_struct *ps, int depth)
{
- if (q_n == NULL)
- return False;
+ if (q_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_q_net_sess_enum");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
- return False;
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
+ prs_uint32("ptr_srv_name", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth);
+ prs_align(ps);
- if(!prs_uint32("ptr_qual_name", ps, depth, &q_n->ptr_qual_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_qual_name, q_n->ptr_qual_name, ps, depth))
- return False;
+ prs_uint32("ptr_qual_name", ps, depth, &(q_n->ptr_qual_name));
+ smb_io_unistr2("", &(q_n->uni_qual_name), q_n->ptr_qual_name, ps, depth);
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
+ prs_uint32("ptr_user_name", ps, depth, &(q_n->ptr_user_name));
+ smb_io_unistr2("", &(q_n->uni_user_name), q_n->ptr_user_name, ps, depth);
+ prs_align(ps);
- if(!prs_uint32("sess_level", ps, depth, &q_n->sess_level))
- return False;
+ prs_uint32("sess_level", ps, depth, &(q_n->sess_level ));
- if (q_n->sess_level != -1) {
- if(!srv_io_srv_sess_ctr("sess_ctr", q_n->ctr, ps, depth))
- return False;
+ if (((int)q_n->sess_level) != -1)
+ {
+ srv_io_srv_sess_ctr("sess_ctr", q_n->ctr, ps, depth);
}
- if(!prs_uint32("preferred_len", ps, depth, &q_n->preferred_len))
- return False;
+ prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
- if(!smb_io_enum_hnd("enum_hnd", &q_n->enum_hnd, ps, depth))
- return False;
+ smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth);
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL srv_io_r_net_sess_enum(char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth)
+BOOL srv_io_r_net_sess_enum(char *desc, SRV_R_NET_SESS_ENUM *r_n, prs_struct *ps, int depth)
{
- if (r_n == NULL)
- return False;
+ if (r_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_r_net_sess_enum");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("sess_level", ps, depth, &r_n->sess_level))
- return False;
+ prs_uint32("sess_level", ps, depth, &(r_n->sess_level));
- if (r_n->sess_level != -1) {
- if(!srv_io_srv_sess_ctr("sess_ctr", r_n->ctr, ps, depth))
- return False;
+ if (((int)r_n->sess_level) != -1)
+ {
+ srv_io_srv_sess_ctr("sess_ctr", r_n->ctr, ps, depth);
}
- if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
- return False;
- if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
- return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
- return False;
+ prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
+ smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth);
+ prs_uint32("status ", ps, depth, &(r_n->status));
return True;
}
/*******************************************************************
- Inits a CONN_INFO_0 structure
+ makes a CONN_INFO_0 structure
********************************************************************/
-
-void init_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id)
+BOOL make_srv_conn_info0(CONN_INFO_0 *ss0, uint32 id)
{
- DEBUG(5,("init_srv_conn_info0\n"));
+ if (ss0 == NULL) return False;
+
+ DEBUG(5,("make_srv_conn_info0\n"));
ss0->id = id;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_conn_info0(char *desc, CONN_INFO_0 *ss0, prs_struct *ps, int depth)
+static BOOL srv_io_conn_info0(char *desc, CONN_INFO_0 *ss0, prs_struct *ps, int depth)
{
- if (ss0 == NULL)
- return False;
+ if (ss0 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_conn_info0");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("id", ps, depth, &ss0->id))
- return False;
+ prs_uint32("id", ps, depth, &(ss0->id));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_srv_conn_info_0(char *desc, SRV_CONN_INFO_0 *ss0, prs_struct *ps, int depth)
+static BOOL srv_io_srv_conn_info_0(char *desc, SRV_CONN_INFO_0 *ss0, prs_struct *ps, int depth)
{
- if (ss0 == NULL)
- return False;
+ if (ss0 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_srv_conn_info_0");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("num_entries_read", ps, depth, &ss0->num_entries_read))
- return False;
- if(!prs_uint32("ptr_conn_info", ps, depth, &ss0->ptr_conn_info))
- return False;
+ prs_uint32("num_entries_read", ps, depth, &(ss0->num_entries_read));
+ prs_uint32("ptr_conn_info", ps, depth, &(ss0->ptr_conn_info));
- if (ss0->ptr_conn_info != 0) {
- int i;
- int num_entries = ss0->num_entries_read;
-
- if (num_entries > MAX_CONN_ENTRIES) {
+ if (ss0->ptr_conn_info != 0)
+ {
+ uint32 i;
+ uint32 num_entries = ss0->num_entries_read;
+ if (num_entries > MAX_CONN_ENTRIES)
+ {
num_entries = MAX_CONN_ENTRIES; /* report this! */
}
- if(!prs_uint32("num_entries_read2", ps, depth, &ss0->num_entries_read2))
- return False;
+ prs_uint32("num_entries_read2", ps, depth, &(ss0->num_entries_read2));
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_conn_info0("", &ss0->info_0[i], ps, depth))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ srv_io_conn_info0("", &(ss0->info_0[i]), ps, depth);
}
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
}
return True;
}
/*******************************************************************
- Inits a CONN_INFO_1_STR structure
+ makes a CONN_INFO_1_STR structure
********************************************************************/
-
-void init_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name)
+BOOL make_srv_conn_info1_str(CONN_INFO_1_STR *ss1, char *usr_name, char *net_name)
{
- DEBUG(5,("init_srv_conn_info1_str\n"));
+ if (ss1 == NULL) return False;
- init_unistr2(&ss1->uni_usr_name, usr_name, strlen(usr_name)+1);
- init_unistr2(&ss1->uni_net_name, net_name, strlen(net_name)+1);
+ DEBUG(5,("make_srv_conn_info1_str\n"));
+
+ make_unistr2(&(ss1->uni_usr_name), usr_name, strlen(usr_name)+1);
+ make_unistr2(&(ss1->uni_net_name), net_name, strlen(net_name)+1);
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_conn_info1_str(char *desc, CONN_INFO_1_STR *ss1, prs_struct *ps, int depth)
+static BOOL srv_io_conn_info1_str(char *desc, CONN_INFO_1_STR *ss1,
+ CONN_INFO_1 *ci1, prs_struct *ps, int depth)
{
- if (ss1 == NULL)
- return False;
+ if (ss1 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_conn_info1_str");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unistr2("", &ss1->uni_usr_name, True, ps, depth))
- return False;
- if(!smb_io_unistr2("", &ss1->uni_net_name, True, ps, depth))
- return False;
+ smb_io_unistr2("", &(ss1->uni_usr_name), ci1->ptr_usr_name, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("", &(ss1->uni_net_name), ci1->ptr_net_name, ps, depth);
+ prs_align(ps);
return True;
}
/*******************************************************************
- Inits a CONN_INFO_1 structure
+ makes a CONN_INFO_1 structure
********************************************************************/
-
-void init_srv_conn_info1(CONN_INFO_1 *ss1,
+BOOL make_srv_conn_info1(CONN_INFO_1 *ss1,
uint32 id, uint32 type,
uint32 num_opens, uint32 num_users, uint32 open_time,
char *usr_name, char *net_name)
{
- DEBUG(5,("init_srv_conn_info1: %s %s\n", usr_name, net_name));
+ if (ss1 == NULL) return False;
+
+ DEBUG(5,("make_srv_conn_info1: %s %s\n", usr_name, net_name));
ss1->id = id ;
ss1->type = type ;
@@ -1065,126 +1208,115 @@ void init_srv_conn_info1(CONN_INFO_1 *ss1,
ss1->num_users = num_users;
ss1->open_time = open_time;
- ss1->ptr_usr_name = (usr_name != NULL) ? 1 : 0;
- ss1->ptr_net_name = (net_name != NULL) ? 1 : 0;
+ ss1->ptr_usr_name = usr_name != NULL ? 1 : 0;
+ ss1->ptr_net_name = net_name != NULL ? 1 : 0;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_conn_info1(char *desc, CONN_INFO_1 *ss1, prs_struct *ps, int depth)
+static BOOL srv_io_conn_info1(char *desc, CONN_INFO_1 *ss1, prs_struct *ps, int depth)
{
- if (ss1 == NULL)
- return False;
+ if (ss1 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_conn_info1");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("id ", ps, depth, &ss1->id))
- return False;
- if(!prs_uint32("type ", ps, depth, &ss1->type))
- return False;
- if(!prs_uint32("num_opens ", ps, depth, &ss1->num_opens))
- return False;
- if(!prs_uint32("num_users ", ps, depth, &ss1->num_users))
- return False;
- if(!prs_uint32("open_time ", ps, depth, &ss1->open_time))
- return False;
+ prs_uint32("id ", ps, depth, &(ss1->id ));
+ prs_uint32("type ", ps, depth, &(ss1->type ));
+ prs_uint32("num_opens ", ps, depth, &(ss1->num_opens ));
+ prs_uint32("num_users ", ps, depth, &(ss1->num_users ));
+ prs_uint32("open_time ", ps, depth, &(ss1->open_time ));
- if(!prs_uint32("ptr_usr_name", ps, depth, &ss1->ptr_usr_name))
- return False;
- if(!prs_uint32("ptr_net_name", ps, depth, &ss1->ptr_net_name))
- return False;
+ prs_uint32("ptr_usr_name", ps, depth, &(ss1->ptr_usr_name));
+ prs_uint32("ptr_net_name", ps, depth, &(ss1->ptr_net_name));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_srv_conn_info_1(char *desc, SRV_CONN_INFO_1 *ss1, prs_struct *ps, int depth)
+static BOOL srv_io_srv_conn_info_1(char *desc, SRV_CONN_INFO_1 *ss1, prs_struct *ps, int depth)
{
- if (ss1 == NULL)
- return False;
+ if (ss1 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_srv_conn_info_1");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("num_entries_read", ps, depth, &ss1->num_entries_read))
- return False;
- if(!prs_uint32("ptr_conn_info", ps, depth, &ss1->ptr_conn_info))
- return False;
+ prs_align(ps);
- if (ss1->ptr_conn_info != 0) {
- int i;
- int num_entries = ss1->num_entries_read;
+ prs_uint32("num_entries_read", ps, depth, &(ss1->num_entries_read));
+ prs_uint32("ptr_conn_info", ps, depth, &(ss1->ptr_conn_info));
- if (num_entries > MAX_CONN_ENTRIES) {
+ if (ss1->ptr_conn_info != 0)
+ {
+ uint32 i;
+ uint32 num_entries = ss1->num_entries_read;
+ if (num_entries > MAX_CONN_ENTRIES)
+ {
num_entries = MAX_CONN_ENTRIES; /* report this! */
}
- if(!prs_uint32("num_entries_read2", ps, depth, &ss1->num_entries_read2))
- return False;
+ prs_uint32("num_entries_read2", ps, depth, &(ss1->num_entries_read2));
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_conn_info1("", &ss1->info_1[i], ps, depth))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ srv_io_conn_info1("", &(ss1->info_1[i]), ps, depth);
}
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_conn_info1_str("", &ss1->info_1_str[i], ps, depth))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ srv_io_conn_info1_str("", &(ss1->info_1_str[i]),
+ &(ss1->info_1[i]),
+ ps, depth);
}
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
}
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_srv_conn_ctr(char *desc, SRV_CONN_INFO_CTR *ctr, prs_struct *ps, int depth)
+static BOOL srv_io_srv_conn_ctr(char *desc, SRV_CONN_INFO_CTR *ctr, prs_struct *ps, int depth)
{
- if (ctr == NULL)
- return False;
+ if (ctr == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_srv_conn_ctr");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
- return False;
- if(!prs_uint32("ptr_conn_ctr", ps, depth, &ctr->ptr_conn_ctr))
- return False;
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_conn_ctr", ps, depth, &(ctr->ptr_conn_ctr));
- if (ctr->ptr_conn_ctr != 0) {
- switch (ctr->switch_value) {
- case 0:
- if(!srv_io_srv_conn_info_0("", &ctr->conn.info0, ps, depth))
- return False;
- break;
- case 1:
- if(!srv_io_srv_conn_info_1("", &ctr->conn.info1, ps, depth))
- return False;
- break;
- default:
- DEBUG(5,("%s no connection info at switch_value %d\n",
- tab_depth(depth), ctr->switch_value));
- break;
+ if (ctr->ptr_conn_ctr != 0)
+ {
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ srv_io_srv_conn_info_0("", &(ctr->conn.info0), ps, depth);
+ break;
+ }
+ case 1:
+ {
+ srv_io_srv_conn_info_1("", &(ctr->conn.info1), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s no connection info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
}
}
@@ -1192,269 +1324,285 @@ static BOOL srv_io_srv_conn_ctr(char *desc, SRV_CONN_INFO_CTR *ctr, prs_struct *
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-void init_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
- char *srv_name, char *qual_name,
+BOOL make_srv_q_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
+ const char *srv_name, const char *qual_name,
uint32 conn_level, SRV_CONN_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd)
{
- DEBUG(5,("init_q_net_conn_enum\n"));
+ if (q_n == NULL || ctr == NULL || hnd == NULL) return False;
q_n->ctr = ctr;
- init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name );
- init_buf_unistr2(&q_n->uni_qual_name, &q_n->ptr_qual_name, qual_name);
+ DEBUG(5,("make_q_net_conn_enum\n"));
+
+ make_buf_unistr2(&(q_n->uni_srv_name ), &(q_n->ptr_srv_name ), srv_name );
+ make_buf_unistr2(&(q_n->uni_qual_name), &(q_n->ptr_qual_name), qual_name);
q_n->conn_level = conn_level;
q_n->preferred_len = preferred_len;
- memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
+ memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL srv_io_q_net_conn_enum(char *desc, SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth)
+BOOL srv_io_q_net_conn_enum(char *desc, SRV_Q_NET_CONN_ENUM *q_n, prs_struct *ps, int depth)
{
- if (q_n == NULL)
- return False;
+ if (q_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_q_net_conn_enum");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("ptr_srv_name ", ps, depth, &q_n->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_srv_name, q_n->ptr_srv_name, ps, depth))
- return False;
-
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_qual_name", ps, depth, &q_n->ptr_qual_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_qual_name, q_n->ptr_qual_name, ps, depth))
- return False;
+ prs_uint32("ptr_srv_name ", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("", &(q_n->uni_srv_name), q_n->ptr_srv_name, ps, depth);
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
+ prs_uint32("ptr_qual_name", ps, depth, &(q_n->ptr_qual_name));
+ smb_io_unistr2("", &(q_n->uni_qual_name), q_n->ptr_qual_name, ps, depth);
+ prs_align(ps);
- if(!prs_uint32("conn_level", ps, depth, &q_n->conn_level))
- return False;
+ prs_uint32("conn_level", ps, depth, &(q_n->conn_level ));
- if (q_n->conn_level != -1) {
- if(!srv_io_srv_conn_ctr("conn_ctr", q_n->ctr, ps, depth))
- return False;
+ if (((int)q_n->conn_level) != -1)
+ {
+ srv_io_srv_conn_ctr("conn_ctr", q_n->ctr, ps, depth);
}
- if(!prs_uint32("preferred_len", ps, depth, &q_n->preferred_len))
- return False;
+ prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
- if(!smb_io_enum_hnd("enum_hnd", &q_n->enum_hnd, ps, depth))
- return False;
+ smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth);
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
BOOL srv_io_r_net_conn_enum(char *desc, SRV_R_NET_CONN_ENUM *r_n, prs_struct *ps, int depth)
{
- if (r_n == NULL)
- return False;
+ if (r_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_r_net_conn_enum");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("conn_level", ps, depth, &r_n->conn_level))
- return False;
+ prs_uint32("conn_level", ps, depth, &(r_n->conn_level));
- if (r_n->conn_level != -1) {
- if(!srv_io_srv_conn_ctr("conn_ctr", r_n->ctr, ps, depth))
- return False;
+ if (((int)r_n->conn_level) != -1)
+ {
+ srv_io_srv_conn_ctr("conn_ctr", r_n->ctr, ps, depth);
}
- if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
- return False;
- if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
- return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
- return False;
+ prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
+ smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth);
+ prs_uint32("status ", ps, depth, &(r_n->status));
return True;
}
/*******************************************************************
- Inits a FILE_INFO_3_STR structure
+ makes a TPRT_INFO_0_STR structure
********************************************************************/
-
-void init_srv_file_info3_str(FILE_INFO_3_STR *fi3, char *user_name, char *path_name)
+BOOL make_srv_tprt_info0_str(TPRT_INFO_0_STR *tp0,
+ char *trans_name,
+ char *trans_addr, uint32 trans_addr_len,
+ char *addr_name)
{
- DEBUG(5,("init_srv_file_info3_str\n"));
+ if (tp0 == NULL) return False;
- init_unistr2(&fi3->uni_path_name, path_name, strlen(path_name)+1);
- init_unistr2(&fi3->uni_user_name, user_name, strlen(user_name)+1);
+ DEBUG(5,("make_srv_tprt_info0_str\n"));
+
+ make_unistr2(&(tp0->uni_trans_name), trans_name, strlen(trans_name)+1);
+ make_buffer4_str(&(tp0->buf_trans_addr), trans_addr, trans_addr_len);
+ make_unistr2(&(tp0->uni_addr_name ), addr_name, strlen(addr_name)+1);
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_file_info3_str(char *desc, FILE_INFO_3_STR *sh1, prs_struct *ps, int depth)
+static BOOL srv_io_tprt_info0_str(char *desc, TPRT_INFO_0_STR *tp0,
+ TPRT_INFO_0 *ti0,
+ prs_struct *ps, int depth)
{
- if (sh1 == NULL)
- return False;
+ if (tp0 == NULL) return False;
- prs_debug(ps, depth, desc, "srv_io_file_info3_str");
+ prs_debug(ps, depth, desc, "srv_io_tprt_info0_str");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!smb_io_unistr2("", &sh1->uni_path_name, True, ps, depth))
- return False;
- if(!smb_io_unistr2("", &sh1->uni_user_name, True, ps, depth))
- return False;
+ smb_io_unistr2("", &(tp0->uni_trans_name), ti0->ptr_trans_name, ps, depth);
+ prs_align(ps);
+ smb_io_buffer4("", &(tp0->buf_trans_addr), ti0->ptr_trans_addr, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("", &(tp0->uni_addr_name ), ti0->ptr_addr_name, ps, depth);
+ prs_align(ps);
return True;
}
/*******************************************************************
- Inits a FILE_INFO_3 structure
+ makes a TPRT_INFO_0 structure
********************************************************************/
-
-void init_srv_file_info3(FILE_INFO_3 *fl3,
- uint32 id, uint32 perms, uint32 num_locks,
- char *path_name, char *user_name)
+BOOL make_srv_tprt_info0(TPRT_INFO_0 *tp0,
+ uint32 num_vcs, uint32 trans_addr_len,
+ char *trans_name, char *trans_addr,
+ char *addr_name)
{
- DEBUG(5,("init_srv_file_info3: %s %s\n", path_name, user_name));
+ if (tp0 == NULL) return False;
- fl3->id = id;
- fl3->perms = perms;
- fl3->num_locks = num_locks;
+ DEBUG(5,("make_srv_tprt_info0: %s %s\n", trans_name, addr_name));
+
+ tp0->num_vcs = num_vcs;
+ tp0->ptr_trans_name = trans_name != NULL ? 1 : 0;
+ tp0->ptr_trans_addr = trans_addr != NULL ? 1 : 0;
+ tp0->trans_addr_len = trans_addr_len;
+ tp0->ptr_addr_name = addr_name != NULL ? 1 : 0;
- fl3->ptr_path_name = (path_name != NULL) ? 1 : 0;
- fl3->ptr_user_name = (user_name != NULL) ? 1 : 0;
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_file_info3(char *desc, FILE_INFO_3 *fl3, prs_struct *ps, int depth)
+static BOOL srv_io_tprt_info0(char *desc, TPRT_INFO_0 *tp0, prs_struct *ps, int depth)
{
- if (fl3 == NULL)
- return False;
+ if (tp0 == NULL) return False;
- prs_debug(ps, depth, desc, "srv_io_file_info3");
+ prs_debug(ps, depth, desc, "srv_io_tprt_info0");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("id ", ps, depth, &fl3->id))
- return False;
- if(!prs_uint32("perms ", ps, depth, &fl3->perms))
- return False;
- if(!prs_uint32("num_locks ", ps, depth, &fl3->num_locks))
- return False;
- if(!prs_uint32("ptr_path_name", ps, depth, &fl3->ptr_path_name))
- return False;
- if(!prs_uint32("ptr_user_name", ps, depth, &fl3->ptr_user_name))
- return False;
+ prs_uint32("num_vcs ", ps, depth, &(tp0->num_vcs ));
+ prs_uint32("ptr_trans_name", ps, depth, &(tp0->ptr_trans_name));
+ prs_uint32("ptr_trans_addr", ps, depth, &(tp0->ptr_trans_addr));
+ prs_uint32("trans_addr_len", ps, depth, &(tp0->trans_addr_len));
+ prs_uint32("ptr_addr_name ", ps, depth, &(tp0->ptr_addr_name ));
return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-static BOOL srv_io_srv_file_info_3(char *desc, SRV_FILE_INFO_3 *fl3, prs_struct *ps, int depth)
+static BOOL srv_io_srv_tprt_info_0(char *desc, SRV_TPRT_INFO_0 *tp0, prs_struct *ps, int depth)
{
- if (fl3 == NULL)
- return False;
+ if (tp0 == NULL) return False;
- prs_debug(ps, depth, desc, "srv_io_file_3_fl3");
+ prs_debug(ps, depth, desc, "srv_io_srv_tprt_info_0");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("num_entries_read", ps, depth, &fl3->num_entries_read))
- return False;
- if(!prs_uint32("ptr_file_fl3", ps, depth, &fl3->ptr_file_info))
- return False;
+ prs_uint32("num_entries_read", ps, depth, &(tp0->num_entries_read));
+ prs_uint32("ptr_tprt_info", ps, depth, &(tp0->ptr_tprt_info));
- if (fl3->ptr_file_info != 0) {
- int i;
- int num_entries = fl3->num_entries_read;
+ if (tp0->ptr_tprt_info != 0)
+ {
+ uint32 i;
+ uint32 num_entries = tp0->num_entries_read;
- if (num_entries > MAX_FILE_ENTRIES) {
- num_entries = MAX_FILE_ENTRIES; /* report this! */
- }
+ prs_uint32("num_entries_read2", ps, depth, &(tp0->num_entries_read2));
- if(!prs_uint32("num_entries_read2", ps, depth, &fl3->num_entries_read2))
- return False;
+ if (ps->io)
+ {
+ /* reading */
+ tp0->info_0 = (TPRT_INFO_0*)malloc(num_entries *
+ sizeof(tp0->info_0[0]));
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_file_info3("", &fl3->info_3[i], ps, depth))
+ tp0->info_0_str = (TPRT_INFO_0_STR*)malloc(num_entries *
+ sizeof(tp0->info_0_str[0]));
+
+ if (tp0->info_0 == NULL || tp0->info_0_str == NULL)
+ {
+ free_srv_tprt_info_0(tp0);
return False;
+ }
}
- for (i = 0; i < num_entries; i++) {
- if(!srv_io_file_info3_str("", &fl3->info_3_str[i], ps, depth))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ srv_io_tprt_info0("", &(tp0->info_0[i]), ps, depth);
}
- if(!prs_align(ps))
- return False;
+ for (i = 0; i < num_entries; i++)
+ {
+ srv_io_tprt_info0_str("", &(tp0->info_0_str[i]),
+ &(tp0->info_0[i]),
+ ps, depth);
+ }
+
+ prs_align(ps);
+ }
+
+ if (!ps->io)
+ {
+ /* writing */
+ free_srv_tprt_info_0(tp0);
}
return True;
}
/*******************************************************************
- Reads or writes a structure.
+frees a structure.
********************************************************************/
+void free_srv_tprt_info_0(SRV_TPRT_INFO_0 *tp0)
+{
+ if (tp0->info_0 != NULL)
+ {
+ free(tp0->info_0);
+ tp0->info_0 = NULL;
+ }
+ if (tp0->info_0_str != NULL)
+ {
+ free(tp0->info_0_str);
+ tp0->info_0_str = NULL;
+ }
+}
-static BOOL srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR *ctr, prs_struct *ps, int depth)
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL srv_io_srv_tprt_ctr(char *desc, SRV_TPRT_INFO_CTR *ctr, prs_struct *ps, int depth)
{
- if (ctr == NULL)
- return False;
+ if (ctr == NULL) return False;
- prs_debug(ps, depth, desc, "srv_io_srv_file_ctr");
+ prs_debug(ps, depth, desc, "srv_io_srv_tprt_ctr");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
- return False;
- if(!prs_uint32("ptr_file_ctr", ps, depth, &ctr->ptr_file_ctr))
- return False;
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_tprt_ctr", ps, depth, &(ctr->ptr_tprt_ctr));
- if (ctr->ptr_file_ctr != 0) {
- switch (ctr->switch_value) {
- case 3:
- if(!srv_io_srv_file_info_3("", &ctr->file.info3, ps, depth))
- return False;
- break;
- default:
- DEBUG(5,("%s no file info at switch_value %d\n",
- tab_depth(depth), ctr->switch_value));
- break;
+ if (ctr->ptr_tprt_ctr != 0)
+ {
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ srv_io_srv_tprt_info_0("", &(ctr->tprt.info0), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s no transport info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
}
}
@@ -1462,464 +1610,689 @@ static BOOL srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR *ctr, prs_struct *
}
/*******************************************************************
- Inits a SRV_Q_NET_FILE_ENUM structure.
+reads or writes a structure.
********************************************************************/
+void free_srv_tprt_ctr(SRV_TPRT_INFO_CTR *ctr)
+{
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ free_srv_tprt_info_0(&(ctr->tprt.info0));
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("no transport info at switch_value %d\n",
+ ctr->switch_value));
+ break;
+ }
+ }
+}
-void init_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
- char *srv_name, char *qual_name,
- uint32 file_level, SRV_FILE_INFO_CTR *ctr,
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL make_srv_q_net_tprt_enum(SRV_Q_NET_TPRT_ENUM *q_n,
+ const char *srv_name,
+ uint32 tprt_level, SRV_TPRT_INFO_CTR *ctr,
uint32 preferred_len,
ENUM_HND *hnd)
{
- DEBUG(5,("init_q_net_file_enum\n"));
+ if (q_n == NULL || ctr == NULL || hnd == NULL) return False;
q_n->ctr = ctr;
- init_buf_unistr2(&q_n->uni_srv_name, &q_n->ptr_srv_name, srv_name);
- init_buf_unistr2(&q_n->uni_qual_name, &q_n->ptr_qual_name, qual_name);
+ DEBUG(5,("make_q_net_tprt_enum\n"));
- q_n->file_level = file_level;
+ make_buf_unistr2(&(q_n->uni_srv_name ), &(q_n->ptr_srv_name ), srv_name );
+
+ q_n->tprt_level = tprt_level;
q_n->preferred_len = preferred_len;
- memcpy(&q_n->enum_hnd, hnd, sizeof(*hnd));
+ memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL srv_io_q_net_file_enum(char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth)
+BOOL srv_io_q_net_tprt_enum(char *desc, SRV_Q_NET_TPRT_ENUM *q_n, prs_struct *ps, int depth)
{
- if (q_n == NULL)
- return False;
+ if (q_n == NULL) return False;
- prs_debug(ps, depth, desc, "srv_io_q_net_file_enum");
+ prs_debug(ps, depth, desc, "srv_io_q_net_tprt_enum");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_srv_name", ps, depth, &q_n->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
- return False;
+ prs_uint32("ptr_srv_name ", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("", &(q_n->uni_srv_name), q_n->ptr_srv_name, ps, depth);
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
+ prs_uint32("tprt_level", ps, depth, &(q_n->tprt_level ));
+
+ if (((int)q_n->tprt_level) != -1)
+ {
+ srv_io_srv_tprt_ctr("tprt_ctr", q_n->ctr, ps, depth);
+ }
- if(!prs_uint32("ptr_qual_name", ps, depth, &q_n->ptr_qual_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_qual_name, q_n->ptr_qual_name, ps, depth))
- return False;
+ prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
- if(!prs_align(ps))
- return False;
+ smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth);
- if(!prs_uint32("file_level", ps, depth, &q_n->file_level))
- return False;
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL srv_io_r_net_tprt_enum(char *desc, SRV_R_NET_TPRT_ENUM *r_n, prs_struct *ps, int depth)
+{
+ if (r_n == NULL) return False;
+
+ prs_debug(ps, depth, desc, "srv_io_r_net_tprt_enum");
+ depth++;
- if (q_n->file_level != -1) {
- if(!srv_io_srv_file_ctr("file_ctr", q_n->ctr, ps, depth))
- return False;
+ prs_align(ps);
+
+ prs_uint32("tprt_level", ps, depth, &(r_n->tprt_level));
+
+ if (((int)r_n->tprt_level) != -1)
+ {
+ srv_io_srv_tprt_ctr("tprt_ctr", r_n->ctr, ps, depth);
}
- if(!prs_uint32("preferred_len", ps, depth, &q_n->preferred_len))
- return False;
+ prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
+ smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth);
+ prs_uint32("status ", ps, depth, &(r_n->status));
+
+ return True;
+}
+
+/*******************************************************************
+ makes a FILE_INFO_3_STR structure
+********************************************************************/
+BOOL make_srv_file_info3_str(FILE_INFO_3_STR *fi3,
+ const char *path_name, const char *user_name)
+{
+ if (fi3 == NULL) return False;
+
+ DEBUG(5,("make_srv_file_info3_str\n"));
- if(!smb_io_enum_hnd("enum_hnd", &q_n->enum_hnd, ps, depth))
- return False;
+ make_unistr2(&(fi3->uni_path_name), path_name, strlen(path_name)+1);
+ make_unistr2(&(fi3->uni_user_name), user_name, strlen(user_name)+1);
return True;
}
+static void srv_free_file_info3_str(FILE_INFO_3_STR *fs3)
+{
+ safe_free(fs3);
+}
+
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
+static BOOL srv_io_file_info3_str(char *desc, FILE_INFO_3_STR *sh1, prs_struct *ps, int depth)
+{
+ if (sh1 == NULL) return False;
-BOOL srv_io_r_net_file_enum(char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth)
+ prs_debug(ps, depth, desc, "srv_io_file_info3_str");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("path", &(sh1->uni_path_name), True, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("user", &(sh1->uni_user_name), True, ps, depth);
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+ makes a FILE_INFO_3 structure
+********************************************************************/
+BOOL make_srv_file_info3(FILE_INFO_3 *fl3,
+ uint32 id, uint32 perms, uint32 num_locks,
+ const char *path_name, const char *user_name)
{
- if (r_n == NULL)
- return False;
+ if (fl3 == NULL) return False;
- prs_debug(ps, depth, desc, "srv_io_r_net_file_enum");
+ DEBUG(5,("make_srv_file_info3: %s %s\n", path_name, user_name));
+
+ fl3->id = id;
+ fl3->perms = perms;
+ fl3->num_locks = num_locks;
+
+ fl3->ptr_path_name = path_name != NULL ? 1 : 0;
+ fl3->ptr_user_name = user_name != NULL ? 1 : 0;
+
+ return True;
+}
+
+static void srv_free_file_info3(FILE_INFO_3 *fi3)
+{
+ safe_free(fi3);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static BOOL srv_io_file_info3(char *desc, FILE_INFO_3 *fl3, prs_struct *ps, int depth)
+{
+ if (fl3 == NULL) return False;
+
+ prs_debug(ps, depth, desc, "srv_io_file_info3");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint32("id ", ps, depth, &(fl3->id ));
+ prs_uint32("perms ", ps, depth, &(fl3->perms ));
+ prs_uint32("num_locks ", ps, depth, &(fl3->num_locks ));
+ prs_uint32("ptr_path_name", ps, depth, &(fl3->ptr_path_name));
+ prs_uint32("ptr_user_name", ps, depth, &(fl3->ptr_user_name));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+static void srv_free_srv_file_info_3(SRV_FILE_INFO_3 *ctr)
+{
+ void(*fn)(void*) = (void(*)(void*)) srv_free_file_info3;
+ void(*fnstr)(void*) = (void(*)(void*)) srv_free_file_info3_str;
+
+ if (!ctr) return;
+
+ free_void_array(ctr->num_entries_read,
+ (void **) ctr->info_3, fn);
+ free_void_array(ctr->num_entries_read,
+ (void **) ctr->info_3_str, fnstr);
+
+ ctr->num_entries_read = 0;
+ ctr->ptr_file_info = 0;
+ ctr->num_entries_read2 = 0;
+}
+
+static BOOL srv_io_srv_file_info_3(char *desc, SRV_FILE_INFO_3 *fl3, prs_struct *ps, int depth)
+{
+ if (fl3 == NULL) return False;
- if(!prs_uint32("file_level", ps, depth, &r_n->file_level))
- return False;
+ prs_debug(ps, depth, desc, "srv_io_file_3_fl3");
+ depth++;
- if (r_n->file_level != 0) {
- if(!srv_io_srv_file_ctr("file_ctr", r_n->ctr, ps, depth))
- return False;
+ if (ps->io)
+ {
+ ZERO_STRUCTP(fl3);
}
- if(!prs_uint32("total_entries", ps, depth, &r_n->total_entries))
- return False;
- if(!smb_io_enum_hnd("enum_hnd", &r_n->enum_hnd, ps, depth))
- return False;
- if(!prs_uint32("status ", ps, depth, &r_n->status))
- return False;
+ prs_align(ps);
+
+ prs_uint32("num_entries_read", ps, depth, &(fl3->num_entries_read));
+ prs_uint32("ptr_file_fl3", ps, depth, &(fl3->ptr_file_info));
+ if (fl3->ptr_file_info != 0)
+ {
+ uint32 i;
+ uint32 num_entries;
+
+ prs_uint32("num_entries_read2", ps, depth, &(fl3->num_entries_read2));
+ num_entries = fl3->num_entries_read2;
+
+ if (ps->io)
+ {
+ fl3->info_3 = g_new0(FILE_INFO_3 *, num_entries);
+ fl3->info_3_str = g_new0(FILE_INFO_3_STR *, num_entries);
+ if (! fl3->info_3 || ! fl3->info_3_str)
+ {
+ srv_free_srv_file_info_3(fl3);
+ return False;
+ }
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ if (ps->io)
+ {
+ fl3->info_3[i] = g_new(FILE_INFO_3, 1);
+ }
+ if (!srv_io_file_info3("", fl3->info_3[i], ps, depth))
+ {
+ srv_free_srv_file_info_3(fl3);
+ return False;
+ }
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ if (ps->io)
+ {
+ fl3->info_3_str[i] = g_new(FILE_INFO_3_STR, 1);
+ }
+ if (!srv_io_file_info3_str("", fl3->info_3_str[i],
+ ps, depth))
+ {
+ srv_free_srv_file_info_3(fl3);
+ return False;
+ }
+ }
+
+ prs_align(ps);
+ }
return True;
}
/*******************************************************************
- Inits a SRV_INFO_101 structure.
- ********************************************************************/
+reads or writes a structure.
+********************************************************************/
+void srv_free_srv_file_ctr(SRV_FILE_INFO_CTR *ctr)
+{
+ switch (ctr->switch_value)
+ {
+ case 3:
+ srv_free_srv_file_info_3(&(ctr->file.info3));
+ break;
+ default:
+ DEBUG(5,("no file info at switch_value %d\n",
+ ctr->switch_value));
+ break;
+ }
+}
-void init_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id, char *name,
- uint32 ver_major, uint32 ver_minor,
- uint32 srv_type, char *comment)
+static BOOL srv_io_srv_file_ctr(char *desc, SRV_FILE_INFO_CTR *ctr, prs_struct *ps, int depth)
{
- DEBUG(5,("init_srv_info_101\n"));
+ if (ctr == NULL) return False;
+
+ prs_debug(ps, depth, desc, "srv_io_srv_file_ctr");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_file_ctr", ps, depth, &(ctr->ptr_file_ctr));
- sv101->platform_id = platform_id;
- init_buf_unistr2(&sv101->uni_name, &sv101->ptr_name, name);
- sv101->ver_major = ver_major;
- sv101->ver_minor = ver_minor;
- sv101->srv_type = srv_type;
- init_buf_unistr2(&sv101->uni_comment, &sv101->ptr_comment, comment);
+ if (ctr->ptr_file_ctr != 0)
+ {
+ switch (ctr->switch_value)
+ {
+ case 3:
+ {
+ srv_io_srv_file_info_3("", &(ctr->file.info3), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s no file info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
+ }
+ }
+
+ return True;
}
/*******************************************************************
- Reads or writes a SRV_INFO_101 structure.
- ********************************************************************/
+reads or writes a structure.
+********************************************************************/
+BOOL make_srv_q_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
+ const char *srv_name, const char *qual_name,
+ uint32 file_id,
+ uint32 file_level, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len,
+ ENUM_HND *hnd)
+{
+ if (q_n == NULL || ctr == NULL || hnd == NULL) return False;
+
+ q_n->ctr = ctr;
+
+ DEBUG(5,("make_q_net_file_enum\n"));
+
+ make_buf_unistr2(&(q_n->uni_srv_name), &(q_n->ptr_srv_name), srv_name);
+ make_buf_unistr2(&(q_n->uni_qual_name), &(q_n->ptr_qual_name), qual_name);
+
+ q_n->file_id = file_id;
+ q_n->file_level = file_level;
+ q_n->preferred_len = preferred_len;
+
+ memcpy(&(q_n->enum_hnd), hnd, sizeof(*hnd));
+
+ return True;
+}
-static BOOL srv_io_info_101(char *desc, SRV_INFO_101 *sv101, prs_struct *ps, int depth)
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL srv_io_q_net_file_enum(char *desc, SRV_Q_NET_FILE_ENUM *q_n, prs_struct *ps, int depth)
{
- if (sv101 == NULL)
- return False;
+ if (q_n == NULL) return False;
- prs_debug(ps, depth, desc, "srv_io_info_101");
+ prs_debug(ps, depth, desc, "srv_io_q_net_file_enum");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint32("ptr_srv_name", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("ptr_qual_name", ps, depth, &(q_n->ptr_qual_name));
+ smb_io_unistr2("", &(q_n->uni_qual_name), q_n->ptr_qual_name, ps, depth);
+ prs_align(ps);
- if(!prs_uint32("platform_id ", ps, depth, &sv101->platform_id))
- return False;
- if(!prs_uint32("ptr_name ", ps, depth, &sv101->ptr_name))
- return False;
- if(!prs_uint32("ver_major ", ps, depth, &sv101->ver_major))
- return False;
- if(!prs_uint32("ver_minor ", ps, depth, &sv101->ver_minor))
- return False;
- if(!prs_uint32("srv_type ", ps, depth, &sv101->srv_type))
- return False;
- if(!prs_uint32("ptr_comment ", ps, depth, &sv101->ptr_comment))
- return False;
+ prs_uint32("file_id ", ps, depth, &(q_n->file_id ));
+ prs_uint32("file_level", ps, depth, &(q_n->file_level));
- if(!prs_align(ps))
- return False;
+ if (((int)q_n->file_level) != -1)
+ {
+ srv_io_srv_file_ctr("file_ctr", q_n->ctr, ps, depth);
+ }
- if(!smb_io_unistr2("uni_name ", &sv101->uni_name, True, ps, depth))
- return False;
- if(!smb_io_unistr2("uni_comment ", &sv101->uni_comment, True, ps, depth))
- return False;
+ prs_uint32("preferred_len", ps, depth, &(q_n->preferred_len));
+
+ smb_io_enum_hnd("enum_hnd", &(q_n->enum_hnd), ps, depth);
return True;
}
/*******************************************************************
- Inits a SRV_INFO_102 structure.
- ********************************************************************/
-
-void init_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id, char *name,
- char *comment, uint32 ver_major, uint32 ver_minor,
- uint32 srv_type, uint32 users, uint32 disc, uint32 hidden,
- uint32 announce, uint32 ann_delta, uint32 licenses,
- char *usr_path)
+reads or writes a structure.
+********************************************************************/
+BOOL srv_io_r_net_file_enum(char *desc, SRV_R_NET_FILE_ENUM *r_n, prs_struct *ps, int depth)
{
- DEBUG(5,("init_srv_info_102\n"));
+ if (r_n == NULL) return False;
- sv102->platform_id = platform_id;
- init_buf_unistr2(&sv102->uni_name, &sv102->ptr_name, name);
- sv102->ver_major = ver_major;
- sv102->ver_minor = ver_minor;
- sv102->srv_type = srv_type;
- init_buf_unistr2(&sv102->uni_comment, &sv102->ptr_comment, comment);
+ prs_debug(ps, depth, desc, "srv_io_r_net_file_enum");
+ depth++;
- /* same as 101 up to here */
+ prs_align(ps);
- sv102->users = users;
- sv102->disc = disc;
- sv102->hidden = hidden;
- sv102->announce = announce;
- sv102->ann_delta =ann_delta;
- sv102->licenses = licenses;
- init_buf_unistr2(&sv102->uni_usr_path, &sv102->ptr_usr_path, usr_path);
-}
+ prs_uint32("file_level", ps, depth, &(r_n->file_level));
+ if (r_n->file_level != 0)
+ {
+ srv_io_srv_file_ctr("file_ctr", r_n->ctr, ps, depth);
+ }
+
+ prs_uint32("total_entries", ps, depth, &(r_n->total_entries));
+ smb_io_enum_hnd("enum_hnd", &(r_n->enum_hnd), ps, depth);
+ prs_uint32("status ", ps, depth, &(r_n->status));
+
+ return True;
+}
/*******************************************************************
- Reads or writes a SRV_INFO_102 structure.
+ reads or writes a SRV_INFO_101 structure.
********************************************************************/
+static BOOL srv_io_info_101(char *desc, SRV_INFO_101 *sv101, prs_struct *ps, int depth)
+{
+ if (sv101 == NULL) return False;
+
+ prs_debug(ps, depth, desc, "srv_io_info_101");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("platform_id ", ps, depth, &(sv101->platform_id ));
+ prs_uint32("ptr_name ", ps, depth, &(sv101->ptr_name ));
+ prs_uint32("ver_major ", ps, depth, &(sv101->ver_major ));
+ prs_uint32("ver_minor ", ps, depth, &(sv101->ver_minor ));
+ prs_uint32("srv_type ", ps, depth, &(sv101->srv_type ));
+ prs_uint32("ptr_comment ", ps, depth, &(sv101->ptr_comment ));
+
+ prs_align(ps);
+
+ smb_io_unistr2("uni_name ", &(sv101->uni_name ), True, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_comment ", &(sv101->uni_comment ), True, ps, depth);
+ prs_align(ps);
-static BOOL srv_io_info_102(char *desc, SRV_INFO_102 *sv102, prs_struct *ps, int depth)
+ return True;
+}
+
+/*******************************************************************
+ reads or writes a SRV_INFO_102 structure.
+ ********************************************************************/
+static BOOL srv_io_info_102(char *desc, SRV_INFO_102 *sv102, prs_struct *ps, int depth)
{
- if (sv102 == NULL)
- return False;
+ if (sv102 == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_info102");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("platform_id ", ps, depth, &sv102->platform_id))
- return False;
- if(!prs_uint32("ptr_name ", ps, depth, &sv102->ptr_name))
- return False;
- if(!prs_uint32("ver_major ", ps, depth, &sv102->ver_major))
- return False;
- if(!prs_uint32("ver_minor ", ps, depth, &sv102->ver_minor))
- return False;
- if(!prs_uint32("srv_type ", ps, depth, &sv102->srv_type))
- return False;
- if(!prs_uint32("ptr_comment ", ps, depth, &sv102->ptr_comment))
- return False;
+ prs_align(ps);
+
+ prs_uint32("platform_id ", ps, depth, &(sv102->platform_id ));
+ prs_uint32("ptr_name ", ps, depth, &(sv102->ptr_name ));
+ prs_uint32("ver_major ", ps, depth, &(sv102->ver_major ));
+ prs_uint32("ver_minor ", ps, depth, &(sv102->ver_minor ));
+ prs_uint32("srv_type ", ps, depth, &(sv102->srv_type ));
+ prs_uint32("ptr_comment ", ps, depth, &(sv102->ptr_comment ));
/* same as 101 up to here */
- if(!prs_uint32("users ", ps, depth, &sv102->users))
- return False;
- if(!prs_uint32("disc ", ps, depth, &sv102->disc))
- return False;
- if(!prs_uint32("hidden ", ps, depth, &sv102->hidden))
- return False;
- if(!prs_uint32("announce ", ps, depth, &sv102->announce))
- return False;
- if(!prs_uint32("ann_delta ", ps, depth, &sv102->ann_delta))
- return False;
- if(!prs_uint32("licenses ", ps, depth, &sv102->licenses))
- return False;
- if(!prs_uint32("ptr_usr_path", ps, depth, &sv102->ptr_usr_path))
- return False;
-
- if(!smb_io_unistr2("uni_name ", &sv102->uni_name, True, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- if(!smb_io_unistr2("uni_comment ", &sv102->uni_comment, True, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
- if(!smb_io_unistr2("uni_usr_path", &sv102->uni_usr_path, True, ps, depth))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Reads or writes a SRV_INFO_102 structure.
- ********************************************************************/
+ prs_uint32("users ", ps, depth, &(sv102->users ));
+ prs_uint32("disc ", ps, depth, &(sv102->disc ));
+ prs_uint32("hidden ", ps, depth, &(sv102->hidden ));
+ prs_uint32("announce ", ps, depth, &(sv102->announce ));
+ prs_uint32("ann_delta ", ps, depth, &(sv102->ann_delta ));
+ prs_uint32("licenses ", ps, depth, &(sv102->licenses ));
+ prs_uint32("ptr_usr_path", ps, depth, &(sv102->ptr_usr_path));
+
+ smb_io_unistr2("uni_name ", &(sv102->uni_name ), True, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_comment ", &(sv102->uni_comment ), True, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_usr_path", &(sv102->uni_usr_path), True, ps, depth);
+ prs_align(ps);
+
+ return True;
+}
-static BOOL srv_io_info_ctr(char *desc, SRV_INFO_CTR *ctr, prs_struct *ps, int depth)
+/*******************************************************************
+ reads or writes a SRV_INFO_102 structure.
+ ********************************************************************/
+static BOOL srv_io_info_ctr(char *desc, SRV_INFO_CTR *ctr, prs_struct *ps, int depth)
{
- if (ctr == NULL)
- return False;
+ if (ctr == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_info_ctr");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("switch_value", ps, depth, &ctr->switch_value))
- return False;
- if(!prs_uint32("ptr_srv_ctr ", ps, depth, &ctr->ptr_srv_ctr))
- return False;
+ prs_uint32("switch_value", ps, depth, &(ctr->switch_value));
+ prs_uint32("ptr_srv_ctr ", ps, depth, &(ctr->ptr_srv_ctr ));
- if (ctr->ptr_srv_ctr != 0 && ctr->switch_value != 0 && ctr != NULL) {
- switch (ctr->switch_value) {
- case 101:
- if(!srv_io_info_101("sv101", &ctr->srv.sv101, ps, depth))
- return False;
- break;
- case 102:
- if(!srv_io_info_102("sv102", &ctr->srv.sv102, ps, depth))
- return False;
- break;
- default:
- DEBUG(5,("%s no server info at switch_value %d\n",
- tab_depth(depth), ctr->switch_value));
- break;
+ if (ctr->ptr_srv_ctr != 0 && ctr->switch_value != 0 && ctr != NULL)
+ {
+ switch (ctr->switch_value)
+ {
+ case 101:
+ {
+ srv_io_info_101("sv101", &(ctr->srv.sv101), ps, depth);
+ break;
+ }
+ case 102:
+ {
+ srv_io_info_102("sv102", &(ctr->srv.sv102), ps, depth);
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("%s no server info at switch_value %d\n",
+ tab_depth(depth), ctr->switch_value));
+ break;
+ }
}
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
}
return True;
}
/*******************************************************************
- Inits a SRV_Q_NET_SRV_GET_INFO structure.
+ makes a SRV_Q_NET_SRV_GET_INFO structure.
********************************************************************/
-
-void init_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
+BOOL make_srv_q_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *srv,
char *server_name, uint32 switch_value)
{
- DEBUG(5,("init_srv_q_net_srv_get_info\n"));
+ if (srv == NULL) return False;
+
+ DEBUG(5,("make_srv_q_net_srv_get_info\n"));
- init_buf_unistr2(&srv->uni_srv_name, &srv->ptr_srv_name, server_name);
+ make_buf_unistr2(&(srv->uni_srv_name), &(srv->ptr_srv_name), server_name);
srv->switch_value = switch_value;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth)
+BOOL srv_io_q_net_srv_get_info(char *desc, SRV_Q_NET_SRV_GET_INFO *q_n, prs_struct *ps, int depth)
{
- if (q_n == NULL)
- return False;
+ if (q_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_q_net_srv_get_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_srv_name ", ps, depth, &q_n->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
- return False;
+ prs_uint32("ptr_srv_name ", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth);
+ prs_align(ps);
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("switch_value ", ps, depth, &q_n->switch_value))
- return False;
+ prs_uint32("switch_value ", ps, depth, &(q_n->switch_value));
return True;
}
/*******************************************************************
- Inits a SRV_R_NET_SRV_GET_INFO structure.
+ makes a SRV_R_NET_SRV_GET_INFO structure.
********************************************************************/
-
-void init_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
+BOOL make_srv_r_net_srv_get_info(SRV_R_NET_SRV_GET_INFO *srv,
uint32 switch_value, SRV_INFO_CTR *ctr, uint32 status)
{
- DEBUG(5,("init_srv_r_net_srv_get_info\n"));
+ if (srv == NULL) return False;
+
+ DEBUG(5,("make_srv_r_net_srv_get_info\n"));
srv->ctr = ctr;
- if (status == 0x0) {
+ if (status == 0x0)
+ {
srv->ctr->switch_value = switch_value;
srv->ctr->ptr_srv_ctr = 1;
- } else {
+ }
+ else
+ {
srv->ctr->switch_value = 0;
srv->ctr->ptr_srv_ctr = 0;
}
srv->status = status;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+ reads or writes a structure.
********************************************************************/
-
-BOOL srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth)
+BOOL srv_io_r_net_srv_get_info(char *desc, SRV_R_NET_SRV_GET_INFO *r_n, prs_struct *ps, int depth)
{
- if (r_n == NULL)
- return False;
+ if (r_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_r_net_srv_get_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!srv_io_info_ctr("ctr", r_n->ctr, ps, depth))
- return False;
+ srv_io_info_ctr("ctr", r_n->ctr, ps, depth);
- if(!prs_uint32("status ", ps, depth, &r_n->status))
- return False;
+ prs_uint32("status ", ps, depth, &(r_n->status ));
return True;
}
-
/*******************************************************************
- Reads or writes a structure.
+ makes a SRV_Q_NET_REMOTE_TOD structure.
********************************************************************/
+BOOL make_srv_q_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_t, char *server_name)
+{
+ if (q_t == NULL) return False;
-BOOL srv_io_q_net_remote_tod(char *desc, SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth)
+ DEBUG(5,("make_srv_q_net_remote_tod\n"));
+
+ make_buf_unistr2(&(q_t->uni_srv_name), &(q_t->ptr_srv_name), server_name);
+
+ return True;
+}
+
+/*******************************************************************
+ reads or writes a structure.
+ ********************************************************************/
+BOOL srv_io_q_net_remote_tod(char *desc, SRV_Q_NET_REMOTE_TOD *q_n, prs_struct *ps, int depth)
{
- if (q_n == NULL)
- return False;
+ if (q_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_q_net_remote_tod");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_srv_name ", ps, depth, &q_n->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_n->uni_srv_name, True, ps, depth))
- return False;
+ prs_uint32("ptr_srv_name ", ps, depth, &(q_n->ptr_srv_name));
+ smb_io_unistr2("", &(q_n->uni_srv_name), True, ps, depth);
+ prs_align(ps);
return True;
}
/*******************************************************************
- Reads or writes a TIME_OF_DAY_INFO structure.
+ reads or writes a TIME_OF_DAY_INFO structure.
********************************************************************/
-
-static BOOL srv_io_time_of_day_info(char *desc, TIME_OF_DAY_INFO *tod, prs_struct *ps, int depth)
+static BOOL srv_io_time_of_day_info(char *desc, TIME_OF_DAY_INFO *tod, prs_struct *ps, int depth)
{
- if (tod == NULL)
- return False;
+ if (tod == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_time_of_day_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("elapsedt ", ps, depth, &tod->elapsedt))
- return False;
- if(!prs_uint32("msecs ", ps, depth, &tod->msecs))
- return False;
- if(!prs_uint32("hours ", ps, depth, &tod->hours))
- return False;
- if(!prs_uint32("mins ", ps, depth, &tod->mins))
- return False;
- if(!prs_uint32("secs ", ps, depth, &tod->secs))
- return False;
- if(!prs_uint32("hunds ", ps, depth, &tod->hunds))
- return False;
- if(!prs_uint32("timezone ", ps, depth, &tod->zone))
- return False;
- if(!prs_uint32("tintervals ", ps, depth, &tod->tintervals))
- return False;
- if(!prs_uint32("day ", ps, depth, &tod->day))
- return False;
- if(!prs_uint32("month ", ps, depth, &tod->month))
- return False;
- if(!prs_uint32("year ", ps, depth, &tod->year))
- return False;
- if(!prs_uint32("weekday ", ps, depth, &tod->weekday))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Inits a TIME_OF_DAY_INFO structure.
- ********************************************************************/
+ prs_uint32("elapsedt ", ps, depth, &(tod->elapsedt ));
+ prs_uint32("msecs ", ps, depth, &(tod->msecs ));
+ prs_uint32("hours ", ps, depth, &(tod->hours ));
+ prs_uint32("mins ", ps, depth, &(tod->mins ));
+ prs_uint32("secs ", ps, depth, &(tod->secs ));
+ prs_uint32("hunds ", ps, depth, &(tod->hunds ));
+ prs_uint32("timezone ", ps, depth, &(tod->zone ));
+ prs_uint32("tintervals ", ps, depth, &(tod->tintervals));
+ prs_uint32("day ", ps, depth, &(tod->day ));
+ prs_uint32("month ", ps, depth, &(tod->month ));
+ prs_uint32("year ", ps, depth, &(tod->year ));
+ prs_uint32("weekday ", ps, depth, &(tod->weekday ));
-void init_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
+ return True;
+}
+
+/*******************************************************************
+ makes a TIME_OF_DAY_INFO structure.
+ ********************************************************************/
+BOOL make_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
uint32 hours, uint32 mins, uint32 secs, uint32 hunds,
uint32 zone, uint32 tintervals, uint32 day,
uint32 month, uint32 year, uint32 weekday)
{
- DEBUG(5,("init_time_of_day_info\n"));
+ if (tod == NULL) return False;
+
+ DEBUG(5,("make_time_of_day_info\n"));
tod->elapsedt = elapsedt;
tod->msecs = msecs;
@@ -1933,32 +2306,28 @@ void init_time_of_day_info(TIME_OF_DAY_INFO *tod, uint32 elapsedt, uint32 msecs,
tod->month = month;
tod->year = year;
tod->weekday = weekday;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+ reads or writes a structure.
********************************************************************/
-
BOOL srv_io_r_net_remote_tod(char *desc, SRV_R_NET_REMOTE_TOD *r_n, prs_struct *ps, int depth)
{
- if (r_n == NULL)
- return False;
+ if (r_n == NULL) return False;
prs_debug(ps, depth, desc, "srv_io_r_net_remote_tod");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_srv_tod ", ps, depth, &r_n->ptr_srv_tod))
- return False;
+ prs_uint32("ptr_srv_tod ", ps, depth, &(r_n->ptr_srv_tod));
- if(!srv_io_time_of_day_info("tod", r_n->tod, ps, depth))
- return False;
+ srv_io_time_of_day_info("tod", r_n->tod, ps, depth);
- if(!prs_uint32("status ", ps, depth, &r_n->status))
- return False;
+ prs_uint32("status ", ps, depth, &(r_n->status));
return True;
}
diff --git a/source/rpc_parse/parse_svc.c b/source/rpc_parse/parse_svc.c
new file mode 100644
index 00000000000..34618425431
--- /dev/null
+++ b/source/rpc_parse/parse_svc.c
@@ -0,0 +1,888 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ make_svc_q_open_sc_man
+ ********************************************************************/
+BOOL make_svc_q_open_sc_man(SVC_Q_OPEN_SC_MAN *q_u,
+ const char *server, const char *database,
+ uint32 des_access)
+{
+ DEBUG(5,("make_svc_q_open_sc_man\n"));
+
+ make_buf_unistr2(&(q_u->uni_srv_name), &(q_u->ptr_srv_name), server);
+ make_buf_unistr2(&(q_u->uni_db_name ), &(q_u->ptr_db_name), database);
+ q_u->des_access = des_access;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SVC_Q_OPEN_SC_MAN structure.
+********************************************************************/
+BOOL svc_io_q_open_sc_man(char *desc, SVC_Q_OPEN_SC_MAN *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_q_open_sc_man");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("ptr_srv_name", ps, depth, &(q_u->ptr_srv_name));
+ smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("ptr_db_name", ps, depth, &(q_u->ptr_db_name));
+ smb_io_unistr2("", &(q_u->uni_db_name), q_u->ptr_db_name, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("des_access", ps, depth, &(q_u->des_access));
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_r_open_sc_man(char *desc, SVC_R_OPEN_SC_MAN *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_open_sc_man");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_u->pol), ps, depth);
+
+ prs_uint32("status ", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+ make_svc_q_open_service
+ ********************************************************************/
+BOOL make_svc_q_open_service(SVC_Q_OPEN_SERVICE *q_u,
+ POLICY_HND *hnd,
+ const char *server,
+ uint32 des_access)
+{
+ DEBUG(5,("make_svc_q_open_service\n"));
+
+ memcpy(&(q_u->scman_pol), hnd, sizeof(q_u->scman_pol));
+ make_unistr2(&(q_u->uni_svc_name), server, strlen(server)+1);
+ q_u->des_access = des_access;
+
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SVC_Q_OPEN_SERVICE structure.
+********************************************************************/
+BOOL svc_io_q_open_service(char *desc, SVC_Q_OPEN_SERVICE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_q_open_service");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth);
+ prs_align(ps);
+
+ smb_io_unistr2("", &(q_u->uni_svc_name), 1, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("des_access", ps, depth, &(q_u->des_access));
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_r_open_service(char *desc, SVC_R_OPEN_SERVICE *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_open_service");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_u->pol), ps, depth);
+
+ prs_uint32("status ", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+makes an SVC_Q_STOP_SERVICE structure.
+********************************************************************/
+BOOL make_svc_q_stop_service(SVC_Q_STOP_SERVICE *q_c, POLICY_HND *hnd,
+ uint32 unk)
+{
+ if (q_c == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_svc_q_stop_service\n"));
+
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->unknown = unk;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SVC_Q_STOP_SERVICE structure.
+********************************************************************/
+BOOL svc_io_q_stop_service(char *desc, SVC_Q_STOP_SERVICE *q_s, prs_struct *ps, int depth)
+{
+ if (q_s == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_q_stop_service");
+ depth++;
+
+ prs_align(ps);
+ smb_io_pol_hnd("", &(q_s->pol), ps, depth);
+
+ prs_align(ps);
+
+ prs_uint32("unknown", ps, depth, &(q_s->unknown));
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_r_stop_service(char *desc, SVC_R_STOP_SERVICE *r_s, prs_struct *ps, int depth)
+{
+ if (r_s == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_stop_service");
+ depth++;
+
+ prs_uint32("unknown0", ps, depth, &(r_s->unknown0));
+ prs_uint32("unknown1", ps, depth, &(r_s->unknown1));
+ prs_uint32("unknown2", ps, depth, &(r_s->unknown2));
+ prs_uint32("unknown3", ps, depth, &(r_s->unknown3));
+ prs_uint32("unknown4", ps, depth, &(r_s->unknown4));
+ prs_uint32("unknown5", ps, depth, &(r_s->unknown5));
+ prs_uint32("unknown6", ps, depth, &(r_s->unknown6));
+ prs_uint32("status", ps, depth, &(r_s->status));
+
+ return True;
+}
+
+/*******************************************************************
+makes an SVC_Q_START_SERVICE structure.
+********************************************************************/
+BOOL make_svc_q_start_service(SVC_Q_START_SERVICE *q_c, POLICY_HND *hnd,
+ uint32 argc,
+ char **argv)
+{
+ uint32 i;
+
+ if (q_c == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_svc_q_start_service\n"));
+
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->argc = argc;
+ q_c->ptr_args = 1;
+ q_c->argc2 = argc;
+
+ for (i = 0; i < argc; i++)
+ {
+ size_t len_argv = argv[i] != NULL ? strlen(argv[i])+1 : 0;
+ q_c->ptr_argv[i] = argv[i] != NULL ? 1 : 0;
+ make_unistr2(&(q_c->argv[i]), argv[i], len_argv);
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SVC_Q_START_SERVICE structure.
+********************************************************************/
+BOOL svc_io_q_start_service(char *desc, SVC_Q_START_SERVICE *q_s, prs_struct *ps, int depth)
+{
+ if (q_s == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_q_start_service");
+ depth++;
+
+ prs_align(ps);
+ smb_io_pol_hnd("", &(q_s->pol), ps, depth);
+
+ prs_align(ps);
+ prs_uint32("argc ", ps, depth, &(q_s->argc ));
+ prs_uint32("ptr_args", ps, depth, &(q_s->ptr_args));
+
+ if (q_s->ptr_args != 0)
+ {
+ uint32 i;
+
+ prs_uint32("argc2 ", ps, depth, &(q_s->argc2));
+
+ if (q_s->argc2 > MAX_SVC_ARGS)
+ {
+ return False;
+ }
+
+ for (i = 0; i < q_s->argc2; i++)
+ {
+ prs_uint32("", ps, depth, &(q_s->ptr_argv[i]));
+ }
+ for (i = 0; i < q_s->argc2; i++)
+ {
+ smb_io_unistr2("", &(q_s->argv[i]), q_s->ptr_argv[i], ps, depth);
+ prs_align(ps);
+ }
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_r_start_service(char *desc, SVC_R_START_SERVICE *r_s, prs_struct *ps, int depth)
+{
+ if (r_s == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_start_service");
+ depth++;
+
+ prs_uint32("status", ps, depth, &(r_s->status));
+
+ return True;
+}
+
+/*******************************************************************
+ make_svc_query_svc_cfg
+ ********************************************************************/
+BOOL make_svc_query_svc_cfg(QUERY_SERVICE_CONFIG *q_u,
+ uint32 service_type, uint32 start_type,
+ uint32 error_control,
+ char* bin_path_name, char* load_order_grp,
+ uint32 tag_id,
+ char* dependencies, char* service_start_name,
+ char* disp_name)
+{
+ DEBUG(5,("make_svc_query_svc_cfg\n"));
+
+ q_u->service_type = service_type;
+ q_u->start_type = start_type;
+ q_u->error_control = error_control;
+ make_buf_unistr2(&(q_u->uni_bin_path_name ), &(q_u->ptr_bin_path_name ), bin_path_name );
+ make_buf_unistr2(&(q_u->uni_load_order_grp ), &(q_u->ptr_load_order_grp ), load_order_grp );
+ q_u->tag_id = tag_id;
+ make_buf_unistr2(&(q_u->uni_dependencies ), &(q_u->ptr_dependencies ), dependencies );
+ make_buf_unistr2(&(q_u->uni_service_start_name), &(q_u->ptr_service_start_name), service_start_name);
+ make_buf_unistr2(&(q_u->uni_display_name ), &(q_u->ptr_display_name ), disp_name );
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a QUERY_SERVICE_CONFIG structure.
+********************************************************************/
+BOOL svc_io_query_svc_cfg(char *desc, QUERY_SERVICE_CONFIG *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_query_svc_cfg");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("service_type ", ps, depth, &(q_u->service_type ));
+ prs_uint32("start_type ", ps, depth, &(q_u->start_type ));
+ prs_uint32("error_control ", ps, depth, &(q_u->error_control ));
+ prs_uint32("ptr_bin_path_name ", ps, depth, &(q_u->ptr_bin_path_name ));
+ prs_uint32("ptr_load_order_grp ", ps, depth, &(q_u->ptr_load_order_grp ));
+ prs_uint32("tag_id ", ps, depth, &(q_u->tag_id ));
+ prs_uint32("ptr_dependencies ", ps, depth, &(q_u->ptr_dependencies ));
+ prs_uint32("ptr_service_start_name", ps, depth, &(q_u->ptr_service_start_name));
+ prs_uint32("ptr_display_name ", ps, depth, &(q_u->ptr_display_name ));
+
+ smb_io_unistr2("uni_bin_path_name ", &(q_u->uni_bin_path_name ), q_u->ptr_bin_path_name , ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_load_order_grp ", &(q_u->uni_load_order_grp ), q_u->ptr_load_order_grp , ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_dependencies ", &(q_u->uni_dependencies ), q_u->ptr_dependencies , ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_service_start_name", &(q_u->uni_service_start_name), q_u->ptr_service_start_name, ps, depth);
+ prs_align(ps);
+ smb_io_unistr2("uni_display_name ", &(q_u->uni_display_name ), q_u->ptr_display_name , ps, depth);
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+makes an SVC_Q_ENUM_SVCS_STATUS structure.
+********************************************************************/
+BOOL make_svc_q_enum_svcs_status(SVC_Q_ENUM_SVCS_STATUS *q_c, POLICY_HND *hnd,
+ uint32 service_type, uint32 service_state,
+ uint32 buf_size, uint32 resume_hnd )
+{
+ if (q_c == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_svc_q_enum_svcs_status\n"));
+
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->service_type = service_type;
+ q_c->service_state = service_state;
+ q_c->buf_size = buf_size;
+ make_enum_hnd(&q_c->resume_hnd, resume_hnd);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_q_enum_svcs_status(char *desc, SVC_Q_ENUM_SVCS_STATUS *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_q_enum_svcs_status");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("service_type ", ps, depth, &(q_u->service_type ));
+ prs_uint32("service_state", ps, depth, &(q_u->service_state));
+ prs_uint32("buf_size ", ps, depth, &(q_u->buf_size ));
+ smb_io_enum_hnd("resume_hnd", &(q_u->resume_hnd), ps, depth);
+
+ return True;
+}
+
+/*******************************************************************
+makes an SVC_R_ENUM_SVCS_STATUS structure.
+********************************************************************/
+BOOL make_svc_r_enum_svcs_status(SVC_R_ENUM_SVCS_STATUS *r_c,
+ ENUM_SRVC_STATUS *svcs, uint32 more_buf_size,
+ uint32 num_svcs, ENUM_HND *resume_hnd,
+ uint32 dos_status)
+{
+ if (r_c == NULL) return False;
+
+ DEBUG(5,("make_svc_r_enum_svcs_status\n"));
+
+ r_c->svcs = svcs;
+ r_c->more_buf_size = more_buf_size;
+ r_c->num_svcs = num_svcs;
+ memcpy(&(r_c->resume_hnd), resume_hnd, sizeof(ENUM_HND));
+ r_c->dos_status = dos_status;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a SVC_R_ENUM_SVCS_STATUS structure.
+
+this is another wierd structure. WHY oh WHY can the microsoft teams
+not COMMUNICATE and get some CONSISTENCY TO THEIR DATA STRUCTURES!
+ARGH!
+
+********************************************************************/
+BOOL svc_io_r_enum_svcs_status(char *desc, SVC_R_ENUM_SVCS_STATUS *svc, prs_struct *ps, int depth)
+{
+ uint32 i;
+ if (svc == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_enum_svcs_status");
+ depth++;
+
+ prs_align(ps);
+
+ /*
+ * format is actually as laid out in SVC_R_ENUM_SVCS_STATUS.
+ * the reason for all the jumping about, which is horrible
+ * and can be avoided, is due to the use of offsets instead
+ * of pointers.
+ *
+ * if i ever find out that these offsets are in fact non-zero
+ * tokens just like pointer-tokens, i am going to go MAD.
+ */
+
+ if (ps->io)
+ {
+ /* reading */
+
+ uint32 buf_offset;
+ uint32 new_offset;
+
+ prs_uint32("buf_size", ps, depth, &(svc->buf_size));
+
+ buf_offset = ps->offset;
+ ps->offset = buf_offset + svc->buf_size;
+
+ prs_align(ps);
+
+ prs_uint32("more_buf_size", ps, depth, &(svc->more_buf_size));
+ prs_uint32("num_svcs", ps, depth, &(svc->num_svcs));
+ smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth);
+ prs_uint32("dos_status", ps, depth, &(svc->dos_status));
+
+ new_offset = ps->offset;
+ ps->offset = buf_offset;
+
+ svc->svcs = (ENUM_SRVC_STATUS*)Realloc(NULL,
+ svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
+
+ if (svc->svcs == NULL)
+ {
+ DEBUG(0,("svc_io_r_enum_svcs_status: Realloc failed\n"));
+ ps->offset = 0x7fffffff;
+ return False;
+ }
+
+ bzero(svc->svcs, svc->num_svcs * sizeof(ENUM_SRVC_STATUS));
+
+ for (i = 0; i < svc->num_svcs; i++)
+ {
+ fstring name;
+ uint32 old_offset;
+ uint32 srvc_offset;
+ uint32 disp_offset;
+
+ prs_uint32("srvc_offset", ps, depth, &srvc_offset);
+ prs_uint32("disp_offset", ps, depth, &disp_offset);
+ svc_io_svc_status("status", &svc->svcs[i].status, ps, depth);
+
+ old_offset = ps->offset;
+
+ ps->offset = buf_offset + srvc_offset;
+ slprintf(name, sizeof(name)-1, "srvc[%02d]", i);
+ smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps, depth);
+
+ ps->offset = buf_offset + disp_offset;
+ slprintf(name, sizeof(name)-1, "disp[%02d]", i);
+ smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps, depth);
+
+ ps->offset = old_offset;
+ }
+
+ ps->offset = new_offset;
+ }
+ else
+ {
+ /* writing */
+
+ uint32 buf_offset;
+ uint32 old_buf_offset;
+ uint32 srvc_offset = 9 * sizeof(uint32) * svc->num_svcs;
+
+ prs_uint32_pre("buf_size", ps, depth, &svc->buf_size, &buf_offset);
+ old_buf_offset = ps->offset;
+
+ srvc_offset += old_buf_offset;
+
+ if (svc->svcs == NULL)
+ {
+ return False;
+ }
+
+ for (i = 0; i < svc->num_svcs; i++)
+ {
+ fstring name;
+ uint32 old_offset;
+
+ /*
+ * store unicode string offset and unicode string
+ */
+
+ srvc_offset -= old_buf_offset;
+ prs_uint32("srvc_offset", ps, depth, &srvc_offset);
+ srvc_offset += old_buf_offset;
+
+ slprintf(name, sizeof(name)-1, "srvc[%02d]", i);
+
+ old_offset = ps->offset;
+ ps->offset = srvc_offset;
+ smb_io_unistr(name, &svc->svcs[i].uni_srvc_name, ps, depth);
+ srvc_offset = ps->offset;
+ ps->offset = old_offset;
+
+ /*
+ * store unicode string offset and unicode string
+ */
+
+ srvc_offset -= old_buf_offset;
+ prs_uint32("disp_offset", ps, depth, &srvc_offset);
+ srvc_offset += old_buf_offset;
+
+ slprintf(name, sizeof(name)-1, "disp[%02d]", i);
+
+ old_offset = ps->offset;
+ ps->offset = srvc_offset;
+ smb_io_unistr(name, &svc->svcs[i].uni_disp_name, ps, depth);
+ srvc_offset = ps->offset;
+ ps->offset = old_offset;
+
+ /*
+ * store status info
+ */
+
+ svc_io_svc_status("status", &svc->svcs[i].status, ps, depth);
+ }
+
+ prs_uint32_post("buf_size", ps, depth, &svc->buf_size, buf_offset, srvc_offset - buf_offset - sizeof(uint32));
+
+ ps->offset = srvc_offset;
+
+ prs_align(ps);
+
+ prs_uint32("more_buf_size", ps, depth, &(svc->more_buf_size));
+ prs_uint32("num_svcs", ps, depth, &(svc->num_svcs));
+ smb_io_enum_hnd("resume_hnd", &(svc->resume_hnd), ps, depth);
+ prs_uint32("dos_status", ps, depth, &(svc->dos_status));
+ }
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_svc_status(char *desc, SVC_STATUS *svc, prs_struct *ps, int depth)
+{
+ if (svc == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_svc_status");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("svc_type", ps, depth, &(svc->svc_type));
+ prs_uint32("current_state", ps, depth, &(svc->current_state));
+ prs_uint32("controls_accepted", ps, depth, &(svc->controls_accepted));
+ prs_uint32("win32_exit_code", ps, depth, &(svc->win32_exit_code));
+ prs_uint32("svc_specific_exit_code", ps, depth, &(svc->svc_specific_exit_code));
+ prs_uint32("check_point", ps, depth, &(svc->check_point));
+ prs_uint32("wait_hint", ps, depth, &(svc->wait_hint));
+
+ return True;
+}
+
+/*******************************************************************
+makes an SVC_Q_QUERY_SVC_CONFIG structure.
+********************************************************************/
+BOOL make_svc_q_query_svc_config(SVC_Q_QUERY_SVC_CONFIG *q_c, POLICY_HND *hnd,
+ uint32 buf_size)
+{
+ if (q_c == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_svc_q_query_svc_config\n"));
+
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+ q_c->buf_size = buf_size;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_q_query_svc_config(char *desc, SVC_Q_QUERY_SVC_CONFIG *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_q_query_svc_config");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ prs_align(ps);
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
+
+ return True;
+}
+
+/*******************************************************************
+makes an SVC_R_QUERY_SVC_CONFIG structure.
+********************************************************************/
+BOOL make_svc_r_query_svc_config(SVC_R_QUERY_SVC_CONFIG *r_c,
+ QUERY_SERVICE_CONFIG *cfg,
+ uint32 buf_size)
+{
+ if (r_c == NULL) return False;
+
+ DEBUG(5,("make_svc_r_query_svc_config\n"));
+
+ r_c->cfg = cfg;
+ r_c->buf_size = buf_size;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_r_query_svc_config(char *desc, SVC_R_QUERY_SVC_CONFIG *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_query_svc_config");
+ depth++;
+
+ prs_align(ps);
+
+ svc_io_query_svc_cfg("cfg", r_u->cfg, ps, depth);
+ prs_uint32("buf_size", ps, depth, &(r_u->buf_size));
+ prs_uint32("status ", ps, depth, &(r_u->status ));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_q_query_disp_name(char *desc, SVC_Q_QUERY_DISP_NAME *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_q_query_disp_name");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(q_u->scman_pol), ps, depth);
+ prs_align(ps);
+
+ smb_io_unistr2("uni_svc_name", &(q_u->uni_svc_name), 1, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("buf_size", ps, depth, &(q_u->buf_size));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_r_query_disp_name(char *desc, SVC_R_QUERY_DISP_NAME *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_query_disp_name");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_unistr2("uni_disp_name", &(r_u->uni_disp_name), 1, ps, depth);
+ prs_align(ps);
+
+ prs_uint32("buf_size", ps, depth, &(r_u->buf_size));
+ prs_uint32("status ", ps, depth, &(r_u->status ));
+
+ return True;
+}
+
+/*******************************************************************
+makes an SVC_Q_CLOSE structure.
+********************************************************************/
+BOOL make_svc_q_close(SVC_Q_CLOSE *q_c, POLICY_HND *hnd)
+{
+ if (q_c == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_svc_q_close\n"));
+
+ memcpy(&(q_c->pol), hnd, sizeof(q_c->pol));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_q_close(char *desc, SVC_Q_CLOSE *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_q_close");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_r_close(char *desc, SVC_R_CLOSE *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_close");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(r_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("status", ps, depth, &(r_u->status));
+
+ return True;
+}
+
+/*******************************************************************
+makes an SVC_Q_CHANGE_SVC_CONFIG structure.
+********************************************************************/
+BOOL make_svc_q_change_svc_config(SVC_Q_CHANGE_SVC_CONFIG *q_u, POLICY_HND *hnd,
+ uint32 service_type, uint32 start_type,
+ uint32 unknown_0,
+ uint32 error_control,
+ char* bin_path_name, char* load_order_grp,
+ uint32 tag_id,
+ char* dependencies, char* service_start_name,
+ char* password,
+ char* disp_name)
+{
+ if (q_u == NULL || hnd == NULL) return False;
+
+ DEBUG(5,("make_svc_q_change_svc_config\n"));
+
+ memcpy(&(q_u->pol), hnd, sizeof(q_u->pol));
+
+ q_u->service_type = service_type;
+ q_u->start_type = start_type;
+ q_u->unknown_0 = unknown_0;
+ q_u->error_control = error_control;
+ make_buf_unistr2(&(q_u->uni_bin_path_name ), &(q_u->ptr_bin_path_name ), bin_path_name );
+ make_buf_unistr2(&(q_u->uni_load_order_grp ), &(q_u->ptr_load_order_grp ), load_order_grp );
+ q_u->tag_id = tag_id;
+ make_buf_unistr2(&(q_u->uni_dependencies ), &(q_u->ptr_dependencies ), dependencies );
+ make_buf_unistr2(&(q_u->uni_service_start_name), &(q_u->ptr_service_start_name), service_start_name);
+ make_buf_string2(&(q_u->str_password ), &(q_u->ptr_password ), password );
+ make_buf_unistr2(&(q_u->uni_display_name ), &(q_u->ptr_display_name ), disp_name );
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_q_change_svc_config(char *desc, SVC_Q_CHANGE_SVC_CONFIG *q_u, prs_struct *ps, int depth)
+{
+ if (q_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_q_change_svc_config");
+ depth++;
+
+ prs_align(ps);
+
+ smb_io_pol_hnd("", &(q_u->pol), ps, depth);
+ prs_align(ps);
+
+ prs_uint32("service_type ", ps, depth, &(q_u->service_type ));
+ prs_uint32("start_type ", ps, depth, &(q_u->start_type ));
+ prs_uint32("unknown_0 ", ps, depth, &(q_u->unknown_0 ));
+ prs_uint32("error_control ", ps, depth, &(q_u->error_control ));
+ prs_uint32("ptr_bin_path_name ", ps, depth, &(q_u->ptr_bin_path_name ));
+ smb_io_unistr2("uni_bin_path_name ", &(q_u->uni_bin_path_name ), q_u->ptr_bin_path_name , ps, depth);
+ prs_align(ps);
+
+ prs_uint32("ptr_load_order_grp ", ps, depth, &(q_u->ptr_load_order_grp ));
+ smb_io_unistr2("uni_load_order_grp ", &(q_u->uni_load_order_grp ), q_u->ptr_load_order_grp , ps, depth);
+ prs_align(ps);
+ prs_uint32("tag_id ", ps, depth, &(q_u->tag_id ));
+ prs_uint32("ptr_dependencies ", ps, depth, &(q_u->ptr_dependencies ));
+ smb_io_unistr2("uni_dependencies ", &(q_u->uni_dependencies ), q_u->ptr_dependencies , ps, depth);
+ prs_align(ps);
+ prs_uint32("ptr_service_start_name", ps, depth, &(q_u->ptr_service_start_name));
+ smb_io_unistr2("uni_service_start_name", &(q_u->uni_service_start_name), q_u->ptr_service_start_name, ps, depth);
+ prs_align(ps);
+ prs_uint32("ptr_password ", ps, depth, &(q_u->ptr_password ));
+
+ smb_io_string2("str_password ", &(q_u->str_password ), q_u->ptr_display_name , ps, depth);
+ prs_align(ps);
+
+ prs_uint32("ptr_display_name ", ps, depth, &(q_u->ptr_display_name ));
+ smb_io_unistr2("uni_display_name ", &(q_u->uni_display_name ), q_u->ptr_display_name , ps, depth);
+ prs_align(ps);
+
+ return True;
+}
+
+/*******************************************************************
+makes an SVC_R_CHANGE_SVC_CONFIG structure.
+********************************************************************/
+BOOL make_svc_r_change_svc_config(SVC_R_CHANGE_SVC_CONFIG *r_c,
+ uint32 unknown_0, uint32 status)
+{
+ if (r_c == NULL) return False;
+
+ DEBUG(5,("make_svc_r_change_svc_config\n"));
+
+ r_c->unknown_0 = unknown_0;
+ r_c->status = status;
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL svc_io_r_change_svc_config(char *desc, SVC_R_CHANGE_SVC_CONFIG *r_u, prs_struct *ps, int depth)
+{
+ if (r_u == NULL) return False;
+
+ prs_debug(ps, depth, desc, "svc_io_r_change_svc_config");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("unknown_0", ps, depth, &(r_u->unknown_0));
+ prs_uint32("status ", ps, depth, &(r_u->status ));
+
+ return True;
+}
+
diff --git a/source/rpc_parse/parse_vuid.c b/source/rpc_parse/parse_vuid.c
new file mode 100644
index 00000000000..89c613a05f9
--- /dev/null
+++ b/source/rpc_parse/parse_vuid.c
@@ -0,0 +1,159 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tgroupsgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambgroupsge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL vuid_io_key(char *desc, vuser_key * r_u, prs_struct * ps, int depth)
+{
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "vuid_io_key");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("pid ", ps, 0, &r_u->pid);
+ prs_uint16("vuid", ps, 0, &r_u->vuid);
+
+ return True;
+}
+
+/*******************************************************************
+makes a vuser struct.
+********************************************************************/
+BOOL make_vuid_user_struct(user_struct * r_u,
+ uid_t uid, gid_t gid,
+ const char *name,
+ const char *requested_name,
+ const char *real_name,
+ BOOL guest,
+ uint32 n_groups, const gid_t * groups,
+ const NET_USER_INFO_3 * usr)
+{
+ int i;
+
+ if (r_u == NULL)
+ return False;
+
+ DEBUG(5, ("make_user_struct\n"));
+
+ r_u->uid = uid;
+ r_u->gid = gid;
+
+ fstrcpy(r_u->name, name);
+ fstrcpy(r_u->requested_name, requested_name);
+ fstrcpy(r_u->real_name, real_name);
+ r_u->guest = guest;
+
+ r_u->n_groups = n_groups;
+ r_u->groups = g_new(uint32, r_u->n_groups);
+ if (r_u->groups == NULL && n_groups != 0)
+ {
+ return False;
+ }
+ for (i = 0; i < n_groups; i++)
+ {
+ r_u->groups[i] = (gid_t) groups[i];
+ }
+
+ memcpy(&r_u->usr, usr, sizeof(r_u->usr));
+
+ return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+BOOL vuid_io_user_struct(char *desc, user_struct * r_u, prs_struct * ps,
+ int depth)
+{
+ int i;
+
+ if (r_u == NULL)
+ return False;
+
+ prs_debug(ps, depth, desc, "vuid_io_user_struct");
+ depth++;
+
+ prs_align(ps);
+
+ prs_uint32("uid", ps, depth, &(r_u->uid));
+ prs_uint32("gid", ps, depth, &(r_u->gid));
+
+ prs_align(ps);
+ prs_string("name", ps, depth, r_u->name, strlen(r_u->name),
+ sizeof(r_u->name));
+ prs_align(ps);
+ prs_string("requested_name", ps, depth, r_u->requested_name,
+ strlen(r_u->requested_name), sizeof(r_u->requested_name));
+ prs_align(ps);
+ prs_string("real_name", ps, depth, r_u->real_name,
+ strlen(r_u->real_name), sizeof(r_u->real_name));
+ prs_align(ps);
+ prs_uint32("guest", ps, depth, &(r_u->guest));
+
+ prs_uint32("n_groups", ps, depth, &(r_u->n_groups));
+ if (r_u->n_groups != 0)
+ {
+ if (ps->io)
+ {
+ /* reading */
+ r_u->groups = g_new(uint32, r_u->n_groups);
+ }
+ if (r_u->groups == NULL)
+ {
+ vuid_free_user_struct(r_u);
+ return False;
+ }
+ }
+ for (i = 0; i < r_u->n_groups; i++)
+ {
+ prs_uint32("", ps, depth, &(r_u->groups[i]));
+ }
+
+ net_io_user_info3("usr", &r_u->usr, ps, depth);
+
+ return True;
+}
+
+
+
+/*******************************************************************
+frees a structure.
+********************************************************************/
+void vuid_free_user_struct(user_struct * r_u)
+{
+ if (r_u != NULL && r_u->groups != NULL)
+ {
+ free(r_u->groups);
+ r_u->groups = NULL;
+ }
+ safe_free(r_u);
+}
diff --git a/source/rpc_parse/parse_wks.c b/source/rpc_parse/parse_wks.c
index 7357e3d2f3a..108cfca97c7 100644
--- a/source/rpc_parse/parse_wks.c
+++ b/source/rpc_parse/parse_wks.c
@@ -3,9 +3,9 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ * Copyright (C) Paul Ashton 1997-1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,48 +24,42 @@
#include "includes.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
/*******************************************************************
- Init
+ make_wks_q_query_info
********************************************************************/
-
-void init_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
+BOOL make_wks_q_query_info(WKS_Q_QUERY_INFO *q_u,
char *server, uint16 switch_value)
{
- DEBUG(5,("init_wks_q_query_info\n"));
+ DEBUG(5,("make_wks_q_query_info\n"));
- init_buf_unistr2(&q_u->uni_srv_name, &q_u->ptr_srv_name, server);
+ make_buf_unistr2(&(q_u->uni_srv_name), &(q_u->ptr_srv_name), server);
q_u->switch_value = switch_value;
+
+ return True;
}
/*******************************************************************
- Reads or writes a WKS_Q_QUERY_INFO structure.
+reads or writes a WKS_Q_QUERY_INFO structure.
********************************************************************/
-
BOOL wks_io_q_query_info(char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps, int depth)
{
- if (q_u == NULL)
- return False;
+ if (q_u == NULL) return False;
prs_debug(ps, depth, desc, "wks_io_q_query_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
- return False;
- if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint32("ptr_srv_name", ps, depth, &(q_u->ptr_srv_name));
+ smb_io_unistr2("", &(q_u->uni_srv_name), q_u->ptr_srv_name, ps, depth);
+ prs_align(ps);
- if(!prs_uint16("switch_value", ps, depth, &q_u->switch_value))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint16("switch_value", ps, depth, &(q_u->switch_value));
+ prs_align(ps);
return True;
}
@@ -73,72 +67,60 @@ BOOL wks_io_q_query_info(char *desc, WKS_Q_QUERY_INFO *q_u, prs_struct *ps, int
/*******************************************************************
wks_info_100
********************************************************************/
-
-void init_wks_info_100(WKS_INFO_100 *inf,
+BOOL make_wks_info_100(WKS_INFO_100 *inf,
uint32 platform_id, uint32 ver_major, uint32 ver_minor,
char *my_name, char *domain_name)
{
- DEBUG(5,("Init WKS_INFO_100: %d\n", __LINE__));
+ DEBUG(5,("WKS_INFO_100: %d\n", __LINE__));
inf->platform_id = platform_id; /* 0x0000 01f4 - unknown */
inf->ver_major = ver_major; /* os major version */
inf->ver_minor = ver_minor; /* os minor version */
- init_buf_unistr2(&inf->uni_compname, &inf->ptr_compname, my_name );
- init_buf_unistr2(&inf->uni_lan_grp, &inf->ptr_lan_grp, domain_name);
+ make_buf_unistr2(&(inf->uni_compname), &(inf->ptr_compname), my_name );
+ make_buf_unistr2(&(inf->uni_lan_grp ), &(inf->ptr_lan_grp ), domain_name);
+
+ return True;
}
/*******************************************************************
- Reads or writes a WKS_INFO_100 structure.
+reads or writes a WKS_INFO_100 structure.
********************************************************************/
-
static BOOL wks_io_wks_info_100(char *desc, WKS_INFO_100 *inf, prs_struct *ps, int depth)
{
- if (inf == NULL)
- return False;
+ if (inf == NULL) return False;
prs_debug(ps, depth, desc, "wks_io_wks_info_100");
depth++;
- if(!prs_align(ps))
- return False;
-
- if(!prs_uint32("platform_id ", ps, depth, &inf->platform_id)) /* 0x0000 01f4 - unknown */
- return False;
- if(!prs_uint32("ptr_compname", ps, depth, &inf->ptr_compname)) /* pointer to computer name */
- return False;
- if(!prs_uint32("ptr_lan_grp ", ps, depth, &inf->ptr_lan_grp)) /* pointer to LAN group name */
- return False;
- if(!prs_uint32("ver_major ", ps, depth, &inf->ver_major)) /* 4 - major os version */
- return False;
- if(!prs_uint32("ver_minor ", ps, depth, &inf->ver_minor)) /* 0 - minor os version */
- return False;
-
- if(!smb_io_unistr2("", &inf->uni_compname, inf->ptr_compname, ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
-
- if(!smb_io_unistr2("", &inf->uni_lan_grp, inf->ptr_lan_grp , ps, depth))
- return False;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
+
+ prs_uint32("platform_id ", ps, depth, &(inf->platform_id )); /* 0x0000 01f4 - unknown */
+ prs_uint32("ptr_compname", ps, depth, &(inf->ptr_compname)); /* pointer to computer name */
+ prs_uint32("ptr_lan_grp ", ps, depth, &(inf->ptr_lan_grp )); /* pointer to LAN group name */
+ prs_uint32("ver_major ", ps, depth, &(inf->ver_major )); /* 4 - major os version */
+ prs_uint32("ver_minor ", ps, depth, &(inf->ver_minor )); /* 0 - minor os version */
+
+ smb_io_unistr2("", &(inf->uni_compname), inf->ptr_compname, ps, depth);
+ prs_align(ps);
+
+ smb_io_unistr2("", &(inf->uni_lan_grp ), inf->ptr_lan_grp , ps, depth);
+ prs_align(ps);
return True;
}
/*******************************************************************
- Inits WKS_R_QUERY_INFO.
+ make_wks_r_query_info
only supports info level 100 at the moment.
********************************************************************/
-
-void init_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
+BOOL make_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
uint32 switch_value, WKS_INFO_100 *wks100,
int status)
{
- DEBUG(5,("init_wks_r_unknown_0: %d\n", __LINE__));
+ DEBUG(5,("make_wks_r_unknown_0: %d\n", __LINE__));
r_u->switch_value = switch_value; /* same as in request */
@@ -146,35 +128,30 @@ void init_wks_r_query_info(WKS_R_QUERY_INFO *r_u,
r_u->wks100 = wks100;
r_u->status = status;
+
+ return True;
}
/*******************************************************************
- Reads or writes a structure.
+reads or writes a structure.
********************************************************************/
-
-BOOL wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth)
+BOOL wks_io_r_query_info(char *desc, WKS_R_QUERY_INFO *r_u, prs_struct *ps, int depth)
{
- if (r_u == NULL)
- return False;
+ if (r_u == NULL) return False;
prs_debug(ps, depth, desc, "wks_io_r_query_info");
depth++;
- if(!prs_align(ps))
- return False;
+ prs_align(ps);
- if(!prs_uint16("switch_value", ps, depth, &r_u->switch_value)) /* level 100 (0x64) */
- return False;
- if(!prs_align(ps))
- return False;
+ prs_uint16("switch_value", ps, depth, &(r_u->switch_value)); /* level 100 (0x64) */
+ prs_align(ps);
- if(!prs_uint32("ptr_1 ", ps, depth, &r_u->ptr_1)) /* pointer 1 */
- return False;
- if(!wks_io_wks_info_100("inf", r_u->wks100, ps, depth))
- return False;
+ prs_uint32("ptr_1 ", ps, depth, &(r_u->ptr_1 )); /* pointer 1 */
+ wks_io_wks_info_100("inf", r_u->wks100, ps, depth);
- if(!prs_uint32("status ", ps, depth, &r_u->status))
- return False;
+ prs_uint32("status ", ps, depth, &(r_u->status));
return True;
}
+
diff --git a/source/rpc_server/.cvsignore b/source/rpc_server/.cvsignore
index e69de29bb2d..c8b522d6e79 100644
--- a/source/rpc_server/.cvsignore
+++ b/source/rpc_server/.cvsignore
@@ -0,0 +1 @@
+*.lo
diff --git a/source/rpc_server/srv_brs.c b/source/rpc_server/srv_brs.c
new file mode 100644
index 00000000000..9c249029ed2
--- /dev/null
+++ b/source/rpc_server/srv_brs.c
@@ -0,0 +1,76 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1999,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+extern pstring global_myname;
+
+
+/*******************************************************************
+ api_brs_query_info
+ ********************************************************************/
+static BOOL api_brs_query_info( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ BRS_Q_QUERY_INFO q_u;
+ BRS_R_QUERY_INFO r_u;
+ uint32 status;
+ BRS_INFO_100 brs100;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the net share enum */
+ if (!brs_io_q_query_info("", &q_u, data, 0))
+ {
+ return False;
+ }
+
+
+ status = _brs_query_info(&q_u.uni_srv_name, q_u.switch_value1, &brs100);
+ make_brs_r_query_info(&r_u, q_u.switch_value1, &brs100, status);
+ return brs_io_r_query_info("", &r_u, rdata, 0);
+}
+
+
+/*******************************************************************
+ \PIPE\brssvc commands
+ ********************************************************************/
+static const struct api_struct api_brs_cmds[] =
+{
+ { "BRS_Q_QUERY_INFO", BRS_QUERY_INFO, api_brs_query_info },
+ { NULL , 0 , NULL }
+};
+
+/*******************************************************************
+ receives a browser pipe and responds.
+ ********************************************************************/
+BOOL api_brs_rpc(rpcsrv_struct *p)
+{
+ return api_rpcTNP(p, "api_brs_rpc", api_brs_cmds);
+}
+
diff --git a/source/rpc_server/srv_lookup.c b/source/rpc_server/srv_lookup.c
index e6df9933bff..dcb4f614d6a 100644
--- a/source/rpc_server/srv_lookup.c
+++ b/source/rpc_server/srv_lookup.c
@@ -45,54 +45,14 @@
#include "includes.h"
#include "nterr.h"
+#include "sids.h"
extern int DEBUGLEVEL;
-extern fstring global_sam_name;
-extern DOM_SID global_sam_sid;
-extern DOM_SID global_sid_S_1_5_20;
-/*
- * A list of the rids of well known BUILTIN and Domain users
- * and groups.
- */
-
-rid_name builtin_alias_rids[] =
-{
- { BUILTIN_ALIAS_RID_ADMINS , "Administrators" },
- { BUILTIN_ALIAS_RID_USERS , "Users" },
- { BUILTIN_ALIAS_RID_GUESTS , "Guests" },
- { BUILTIN_ALIAS_RID_POWER_USERS , "Power Users" },
-
- { BUILTIN_ALIAS_RID_ACCOUNT_OPS , "Account Operators" },
- { BUILTIN_ALIAS_RID_SYSTEM_OPS , "System Operators" },
- { BUILTIN_ALIAS_RID_PRINT_OPS , "Print Operators" },
- { BUILTIN_ALIAS_RID_BACKUP_OPS , "Backup Operators" },
- { BUILTIN_ALIAS_RID_REPLICATOR , "Replicator" },
- { 0 , NULL }
-};
-
-/* array lookup of well-known Domain RID users. */
-rid_name domain_user_rids[] =
-{
- { DOMAIN_USER_RID_ADMIN , "Administrator" },
- { DOMAIN_USER_RID_GUEST , "Guest" },
- { 0 , NULL }
-};
-
-/* array lookup of well-known Domain RID groups. */
-rid_name domain_group_rids[] =
-{
- { DOMAIN_GROUP_RID_ADMINS , "Domain Admins" },
- { DOMAIN_GROUP_RID_USERS , "Domain Users" },
- { DOMAIN_GROUP_RID_GUESTS , "Domain Guests" },
- { 0 , NULL }
-};
-
-
-int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
+uint32 make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
{
- int count;
+ uint32 count;
int i;
DOM_GID *gids = NULL;
@@ -110,17 +70,25 @@ int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
uint32 status;
uint32 rid;
- uint8 type;
+ DOM_SID sid;
+ uint32 type;
uint8 attr = mem[count].attr;
char *name = mem[count].name;
- become_root(True);
- status = lookup_grp_rid(name, &rid, &type);
- unbecome_root(True);
+ status = lookup_lsa_name(global_sam_name, name, &sid, &type);
- if (status == 0x0)
+ if (status == 0x0 && !sid_front_equal(&global_sam_sid, &sid))
+ {
+ fstring sid_str;
+ sid_to_string(sid_str, &sid);
+ DEBUG(1,("make_dom_gids: unknown sid %s for groupname %s\n",
+ sid_str, name));
+ }
+ else if (status == 0x0)
{
+ sid_split_rid(&sid, &rid);
+
gids = (DOM_GID *)Realloc( gids, sizeof(DOM_GID) * (count+1) );
if (gids == NULL)
@@ -138,7 +106,7 @@ int make_dom_gids(DOMAIN_GRP *mem, int num_members, DOM_GID **ppgids)
}
else
{
- DEBUG(1,("make_dom_gids: unknown group name %s\n", name));
+ DEBUG(1,("make_dom_gids: unknown groupname %s\n", name));
}
}
@@ -168,370 +136,324 @@ int get_domain_user_groups(DOMAIN_GRP_MEMBER **grp_members, uint32 group_rid)
/*******************************************************************
- lookup_builtin_names
+ lookup_wk_group_sid
********************************************************************/
-uint32 lookup_builtin_names(uint32 rid, char *name, uint8 *type)
+static uint32 lookup_wk_group_sid(DOM_SID *sid, char *group_name, uint32 *type)
{
- uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-
- status = (status != 0x0) ? lookup_wk_user_name (rid, name, type) : status;
- status = (status != 0x0) ? lookup_wk_group_name(rid, name, type) : status;
- status = (status != 0x0) ? lookup_wk_alias_name(rid, name, type) : status;
-
- return status;
-}
+ uint32 rid;
+ DOM_SID tmp;
+ char *mapped;
+ sid_copy(&tmp, sid);
+ sid_split_rid(&tmp, &rid);
-/*******************************************************************
- lookup_added_name - names that have been added to the SAM database by admins.
- ********************************************************************/
-uint32 lookup_added_name(uint32 rid, char *name, uint8 *type)
-{
- uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ if (!sid_equal(&global_sid_S_1_5_20, &tmp))
+ {
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
- status = (status != 0x0) ? lookup_user_name (rid, name, type) : status;
- status = (status != 0x0) ? lookup_group_name(rid, name, type) : status;
- status = (status != 0x0) ? lookup_alias_name(rid, name, type) : status;
+ DEBUG(5,("lookup_wk_group_sid: rid: %d", rid));
- return status;
+ /* look up the well-known domain group rids first */
+ mapped = lookup_wk_group_rid(rid);
+ if(mapped == NULL)
+ {
+ DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
+ fstrcpy(group_name, mapped);
+ (*type) = SID_NAME_DOM_GRP;
+ DEBUG(5,(" = %s\n", group_name));
+ return 0x0;
}
-
/*******************************************************************
- lookup_name
+ lookup_group_sid
********************************************************************/
-uint32 lookup_name(uint32 rid, char *name, uint8 *type)
+static uint32 lookup_group_sid(DOM_SID *sid, char *group_name, uint32 *type)
{
+ pstring sid_str;
+ uint32 rid;
+ DOM_SID tmp;
+ DOMAIN_GRP *grp = NULL;
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- status = (status != 0x0) ? lookup_builtin_names(rid, name, type) : status;
- status = (status != 0x0) ? lookup_added_name (rid, name, type) : status;
-
- return status;
-}
-
-
-/*******************************************************************
- lookup_wk_group_name
- ********************************************************************/
-uint32 lookup_wk_group_name(uint32 rid, char *group_name, uint8 *type)
-{
- int i = 0;
- (*type) = SID_NAME_WKN_GRP;
+ sid_to_string(sid_str, sid);
+ DEBUG(5,("lookup_group_sid: sid: %s", sid_str));
- DEBUG(5,("lookup_wk_group_name: rid: %d", rid));
+ sid_copy(&tmp, sid);
+ sid_split_rid(&tmp, &rid);
- while (domain_group_rids[i].rid != rid && domain_group_rids[i].rid != 0)
+ if (!sid_equal(&global_sam_sid, &tmp))
{
- i++;
+ DEBUG(5,("not our SID\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
- if (domain_group_rids[i].rid != 0)
+ grp = getgrouprid(rid, NULL, NULL);
+
+ if (grp != NULL)
{
- fstrcpy(group_name, domain_group_rids[i].name);
+ fstrcpy(group_name, grp->name);
+ (*type) = SID_NAME_DOM_GRP;
DEBUG(5,(" = %s\n", group_name));
return 0x0;
}
DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ return status;
}
/*******************************************************************
- lookup_group_name
+ lookup_wk_alias_sid
********************************************************************/
-uint32 lookup_group_name(uint32 rid, char *group_name, uint8 *type)
+static uint32 lookup_wk_alias_sid(DOM_SID *sid, char *alias_name, uint32 *type)
{
- uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- DOM_SID sid;
-
- DEBUG(5,("lookup_group_name: rid: 0x%x", rid));
-
- sid_copy (&sid, &global_sam_sid);
- sid_append_rid(&sid, rid);
+ uint32 rid;
+ DOM_SID tmp;
+ char *mapped;
- (*type) = SID_NAME_DOM_GRP;
+ sid_copy(&tmp, sid);
+ sid_split_rid(&tmp, &rid);
- if (map_group_sid_to_name(&sid, group_name, NULL))
+ if (!sid_equal(&global_sid_S_1_5_20, &tmp))
{
- status = 0x0;
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
- if (status == 0x0)
- {
- DEBUG(5,(" = %s\n", group_name));
- }
- else
+ DEBUG(5,("lookup_wk_alias_sid: rid: %d", rid));
+
+ /* look up the well-known alias group rids first */
+ mapped = lookup_wk_alias_rid(rid);
+ if(mapped == NULL)
{
DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
-
- return status;
+ fstrcpy(alias_name, mapped);
+ (*type) = SID_NAME_ALIAS;
+ DEBUG(5,(" = %s\n", alias_name));
+ return 0x0;
}
/*******************************************************************
- lookup_wk_alias_name
+ lookup_alias_sid
********************************************************************/
-uint32 lookup_wk_alias_name(uint32 rid, char *alias_name, uint8 *type)
+static uint32 lookup_alias_sid(DOM_SID *sid, char *alias_name, uint32 *type)
{
- int i = 0;
- (*type) = SID_NAME_ALIAS;
+ pstring sid_str;
+ uint32 rid;
+ DOM_SID tmp;
+ LOCAL_GRP *als = NULL;
+ uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+
+ sid_to_string(sid_str, sid);
+ DEBUG(5,("lookup_alias_sid: sid: %s", sid_str));
- DEBUG(5,("lookup_wk_alias_name: rid: %d", rid));
+ sid_copy(&tmp, sid);
+ sid_split_rid(&tmp, &rid);
- while (builtin_alias_rids[i].rid != rid && builtin_alias_rids[i].rid != 0)
+ if (!sid_equal(&global_sam_sid, &tmp))
{
- i++;
+ DEBUG(5,("not our SID\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
- if (builtin_alias_rids[i].rid != 0)
+ als = getaliasrid(rid, NULL, NULL);
+
+ if (als != NULL)
{
- fstrcpy(alias_name, builtin_alias_rids[i].name);
+ fstrcpy(alias_name, als->name);
+ (*type) = SID_NAME_ALIAS;
DEBUG(5,(" = %s\n", alias_name));
return 0x0;
}
DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
-}
-
-/*******************************************************************
- lookup_alias_name
- ********************************************************************/
-uint32 lookup_alias_name(uint32 rid, char *alias_name, uint8 *type)
-{
- (*type) = SID_NAME_ALIAS;
-
- DEBUG(2,("lookup_alias_name: rid: %d\n", rid));
- DEBUG(2,(" NOT IMPLEMENTED\n"));
-
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ return status;
}
/*******************************************************************
lookup well-known user name
********************************************************************/
-uint32 lookup_wk_user_name(uint32 rid, char *user_name, uint8 *type)
+static uint32 lookup_wk_user_sid(DOM_SID *sid, char *user_name, uint32 *type)
{
- int i = 0;
- (*type) = SID_NAME_USER;
+ uint32 rid;
+ DOM_SID tmp;
+ char *mapped;
- DEBUG(5,("lookup_wk_user_name: rid: %d", rid));
+ sid_copy(&tmp, sid);
+ sid_split_rid(&tmp, &rid);
- /* look up the well-known domain user rids first */
- while (domain_user_rids[i].rid != rid && domain_user_rids[i].rid != 0)
+ if (!sid_equal(&global_sid_S_1_5_20, &tmp))
{
- i++;
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
- if (domain_user_rids[i].rid != 0)
+ DEBUG(5,("lookup_wk_user_sid: rid: %d", rid));
+
+ /* look up the well-known domain user rids first */
+ mapped = lookup_wk_user_rid(rid);
+ if(mapped == NULL)
{
- fstrcpy(user_name, domain_user_rids[i].name);
- DEBUG(5,(" = %s\n", user_name));
- return 0x0;
+ DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
-
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ fstrcpy(user_name, mapped);
+ (*type) = SID_NAME_USER;
+ DEBUG(5,(" = %s\n", user_name));
+ return 0x0;
}
/*******************************************************************
lookup user name
********************************************************************/
-uint32 lookup_user_name(uint32 rid, char *user_name, uint8 *type)
+static uint32 lookup_user_sid(DOM_SID *sid, char *user_name, uint32 *type)
{
struct sam_disp_info *disp_info;
- (*type) = SID_NAME_USER;
+ uint32 rid;
+ DOM_SID tmp;
- DEBUG(5,("lookup_user_name: rid: %d", rid));
+ sid_copy(&tmp, sid);
+ sid_split_rid(&tmp, &rid);
- /* find the user account */
- become_root(True);
- disp_info = getsamdisprid(rid);
- unbecome_root(True);
-
- if (disp_info != NULL)
+ if (sid_equal(&global_sam_sid, &tmp))
{
- fstrcpy(user_name, disp_info->smb_name);
- DEBUG(5,(" = %s\n", user_name));
- return 0x0;
- }
+ DEBUG(5,("lookup_user_sid in SAM %s: rid: %d",
+ global_sam_name, rid));
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
-}
-
-/*******************************************************************
- lookup_group_rid
- ********************************************************************/
-uint32 lookup_group_rid(char *group_name, uint32 *rid, uint8 *type)
-{
- DOM_SID sid;
-
- (*rid) = 0;
- (*type) = SID_NAME_DOM_GRP;
+ /* find the user account */
+ become_root(True);
+ disp_info = getsamdisprid(rid);
+ unbecome_root(True);
- DEBUG(5,("lookup_group_rid: name: %s", group_name));
+ if (disp_info != NULL)
+ {
+ fstrcpy(user_name, disp_info->nt_name);
+ (*type) = SID_NAME_USER;
+ DEBUG(5,(" = %s\n", user_name));
+ return 0x0;
+ }
- if (map_group_name_to_sid(group_name, &sid) &&
- sid_split_rid(&sid, rid) &&
- sid_equal(&sid, &global_sam_sid))
- {
- DEBUG(5,(" = 0x%x\n", (*rid)));
- return 0x0;
+ DEBUG(5,(" none mapped\n"));
}
- DEBUG(5,(" none mapped\n"));
return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
/*******************************************************************
- lookup_wk_group_rid
+ lookup_builtin_sid
********************************************************************/
-uint32 lookup_wk_group_rid(char *group_name, uint32 *rid, uint8 *type)
+static uint32 lookup_builtin_sid(DOM_SID *sid, char *name, uint32 *type)
{
- char *grp_name;
- int i = -1; /* start do loop at -1 */
- (*rid) = 0;
- (*type) = SID_NAME_WKN_GRP;
-
- do /* find, if it exists, a group rid for the group name */
- {
- i++;
- (*rid) = domain_group_rids[i].rid;
- grp_name = domain_group_rids[i].name;
+ uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- } while (grp_name != NULL && !strequal(grp_name, group_name));
+ status = (status != 0x0) ? lookup_wk_user_sid (sid, name, type) : status;
+ status = (status != 0x0) ? lookup_wk_group_sid(sid, name, type) : status;
+ status = (status != 0x0) ? lookup_wk_alias_sid(sid, name, type) : status;
- return (grp_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ return status;
}
/*******************************************************************
- lookup_alias_sid
+ lookup_added_sid - names that have been added to the SAM database by admins.
********************************************************************/
-uint32 lookup_alias_sid(char *alias_name, DOM_SID *sid, uint8 *type)
+static uint32 lookup_added_sid(DOM_SID *sid, char *name, uint32 *type)
{
- (*type) = SID_NAME_ALIAS;
+ uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- DEBUG(5,("lookup_alias_rid: name: %s", alias_name));
+ status = (status != 0x0) ? lookup_user_sid (sid, name, type) : status;
+ status = (status != 0x0) ? lookup_group_sid(sid, name, type) : status;
+ status = (status != 0x0) ? lookup_alias_sid(sid, name, type) : status;
- if (map_alias_name_to_sid(alias_name, sid))
- {
- fstring sid_str;
- sid_to_string(sid_str, sid);
- DEBUG(5,(" = %s\n", sid_str));
- return 0x0;
- }
-
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ return status;
}
+
/*******************************************************************
- lookup_alias_rid
+ lookup_sid
********************************************************************/
-uint32 lookup_alias_rid(char *alias_name, uint32 *rid, uint8 *type)
+uint32 lookup_sid(DOM_SID *sid, char *name, uint32 *type)
{
- DOM_SID sid;
-
- (*rid) = 0;
- (*type) = SID_NAME_ALIAS;
+ uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- DEBUG(5,("lookup_alias_rid: name: %s", alias_name));
+ status = (status != 0x0) ? lookup_builtin_sid(sid, name, type) : status;
+ status = (status != 0x0) ? lookup_added_sid (sid, name, type) : status;
- if (map_alias_name_to_sid(alias_name, &sid) &&
- sid_split_rid(&sid, rid) &&
- sid_equal(&sid, &global_sam_sid))
- {
- DEBUG(5,(" = 0x%x\n", (*rid)));
- return 0x0;
- }
-
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ return status;
}
+
/*******************************************************************
- lookup_wk_alias_sid
+ lookup_group_rid
********************************************************************/
-uint32 lookup_wk_alias_sid(char *alias_name, DOM_SID *sid, uint8 *type)
+static uint32 lookup_added_group_name(const char *grp_name,
+ const char *domain,
+ DOM_SID *sid, uint32 *type)
{
- char *als_name;
- int i = 0;
- uint32 rid;
- (*type) = SID_NAME_ALIAS;
+ DOMAIN_GRP *grp = NULL;
- do /* find, if it exists, a alias rid for the alias name*/
+ DEBUG(5,("lookup_added_group_name: name: %s", grp_name));
+
+ if (!strequal(domain, global_sam_name))
{
- rid = builtin_alias_rids[i].rid;
- als_name = builtin_alias_rids[i].name;
+ DEBUG(5,(" not our domain\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
- i++;
+ grp = getgroupntnam(grp_name, NULL, NULL);
- if (strequal(als_name, alias_name))
- {
- sid_copy(sid, &global_sid_S_1_5_20);
- sid_append_rid(sid, rid);
+ if (grp != NULL)
+ {
+ sid_copy(sid, &global_sam_sid);
+ sid_append_rid(sid, grp->rid);
+ (*type) = SID_NAME_DOM_GRP;
- return 0x0;
- }
-
- } while (als_name != NULL);
+ DEBUG(5,(" = 0x%x\n", grp->rid));
+ return 0x0;
+ }
+ DEBUG(5,(" none mapped\n"));
return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
/*******************************************************************
- lookup_wk_alias_rid
+ lookup_added_alias_name
********************************************************************/
-uint32 lookup_wk_alias_rid(char *alias_name, uint32 *rid, uint8 *type)
+static uint32 lookup_added_alias_name(const char *als_name,
+ const char *domain,
+ DOM_SID *sid, uint32 *type)
{
- char *als_name;
- int i = -1; /* start do loop at -1 */
- (*rid) = 0;
- (*type) = SID_NAME_ALIAS;
+ LOCAL_GRP *als = NULL;
- do /* find, if it exists, a alias rid for the alias name*/
- {
- i++;
- (*rid) = builtin_alias_rids[i].rid;
- als_name = builtin_alias_rids[i].name;
-
- } while (als_name != NULL && !strequal(als_name, alias_name));
-
- return (als_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
-}
-
-/*******************************************************************
- lookup_sid
- ********************************************************************/
-uint32 lookup_sid(char *name, DOM_SID *sid, uint8 *type)
-{
- uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- fstring domain;
- fstring user;
-
- split_domain_name(name, domain, user);
+ DEBUG(5,("lookup_added_alias_name: name: %s\\%s", domain, als_name));
if (!strequal(domain, global_sam_name))
{
- DEBUG(0,("lookup_sid: remote domain %s not supported\n", domain));
- return status;
+ DEBUG(5,(" not our domain\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
- status = (status != 0x0) ? lookup_wk_alias_sid(user, sid, type) : status;
- status = (status != 0x0) ? lookup_alias_sid (user, sid, type) : status;
-#if 0
- status = (status != 0x0) ? lookup_domain_sid (user, sid, type) : status;
-#endif
+ als = getaliasntnam(als_name, NULL, NULL);
- return status;
+ if (als != NULL)
+ {
+ sid_copy(sid, &global_sam_sid);
+ sid_append_rid(sid, als->rid);
+ (*type) = SID_NAME_ALIAS;
+
+ DEBUG(5,(" = 0x%x\n", als->rid));
+ return 0x0;
+ }
+
+ DEBUG(5,(" none mapped\n"));
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
}
/*******************************************************************
lookup_added_user_rid
********************************************************************/
-uint32 lookup_added_user_rids(char *user_name,
+uint32 lookup_added_user_rids(char *nt_name,
uint32 *usr_rid, uint32 *grp_rid)
{
struct sam_passwd *sam_pass;
@@ -540,7 +462,7 @@ uint32 lookup_added_user_rids(char *user_name,
/* find the user account */
become_root(True);
- sam_pass = getsam21pwnam(user_name);
+ sam_pass = getsam21pwntnam(nt_name);
unbecome_root(True);
if (sam_pass != NULL)
@@ -554,22 +476,31 @@ uint32 lookup_added_user_rids(char *user_name,
}
/*******************************************************************
- lookup_added_user_rid
+ lookup_added_user_name
********************************************************************/
-uint32 lookup_added_user_rid(char *user_name, uint32 *rid, uint8 *type)
+static uint32 lookup_added_user_name(const char *nt_name, const char *domain,
+ DOM_SID *sid, uint32 *type)
{
struct sam_passwd *sam_pass;
- (*rid) = 0;
- (*type) = SID_NAME_USER;
+
+ if (!strequal(domain, global_sam_name))
+ {
+ return 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ }
/* find the user account */
become_root(True);
- sam_pass = getsam21pwnam(user_name);
+ sam_pass = getsam21pwntnam(nt_name);
unbecome_root(True);
if (sam_pass != NULL)
{
- (*rid) = sam_pass->user_rid;
+ DEBUG(10,("lookup_added_user_name: nt name: %s rid: %x\n",
+ nt_name, sam_pass->user_rid));
+ sid_copy(sid, &global_sam_sid);
+ sid_append_rid(sid, sam_pass->user_rid);
+ (*type) = SID_NAME_USER;
+
return 0x0;
}
@@ -577,134 +508,51 @@ uint32 lookup_added_user_rid(char *user_name, uint32 *rid, uint8 *type)
}
/*******************************************************************
- lookup_wk_user_rid
- ********************************************************************/
-uint32 lookup_wk_user_rid(char *user_name, uint32 *rid, uint8 *type)
-{
- char *usr_name;
- int i = -1; /* start do loop at -1 */
- (*rid) = 0;
- (*type) = SID_NAME_USER;
-
- do /* find, if it exists, a alias rid for the alias name*/
- {
- i++;
- (*rid) = domain_user_rids[i].rid;
- usr_name = domain_user_rids[i].name;
-
- } while (usr_name != NULL && !strequal(usr_name, user_name));
-
- return (usr_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
-}
-
-/*******************************************************************
- lookup_added_grp_rid
- ********************************************************************/
-uint32 lookup_added_grp_rid(char *name, uint32 *rid, uint8 *type)
-{
- uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-
- status = (status != 0x0) ? lookup_group_rid(name, rid, type) : status;
- status = (status != 0x0) ? lookup_alias_rid(name, rid, type) : status;
-
- return status;
-}
-
-/*******************************************************************
- lookup_builtin_grp_rid
- ********************************************************************/
-uint32 lookup_builtin_grp_rid(char *name, uint32 *rid, uint8 *type)
-{
- uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-
- status = (status != 0x0) ? lookup_wk_group_rid(name, rid, type) : status;
- status = (status != 0x0) ? lookup_wk_alias_rid(name, rid, type) : status;
-
- return status;
-}
-
-/*******************************************************************
- lookup_grp_rid
+ lookup_grp_name
********************************************************************/
-uint32 lookup_grp_rid(char *name, uint32 *rid, uint8 *type)
+static uint32 lookup_grp_name(const char *name, const char *domain,
+ DOM_SID *sid, uint32 *type)
{
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- status = (status != 0x0) ? lookup_builtin_grp_rid(name, rid, type) : status;
- status = (status != 0x0) ? lookup_added_grp_rid (name, rid, type) : status;
+ status = (status != 0x0) ? lookup_wk_group_name (name, domain, sid, type) : status;
+ status = (status != 0x0) ? lookup_builtin_alias_name(name, domain, sid, type) : status;
+ status = (status != 0x0) ? lookup_added_group_name (name, domain, sid, type) : status;
+ status = (status != 0x0) ? lookup_added_alias_name (name, domain, sid, type) : status;
return status;
}
/*******************************************************************
- lookup_user_rid
+ lookup_user_name
********************************************************************/
-uint32 lookup_user_rid(char *name, uint32 *rid, uint8 *type)
+static uint32 lookup_user_name(const char *name, const char *domain,
+ DOM_SID *sid, uint32 *type)
{
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- status = (status != 0x0) ? lookup_wk_user_rid (name, rid, type) : status;
- status = (status != 0x0) ? lookup_added_user_rid(name, rid, type) : status;
+ status = (status != 0x0) ? lookup_wk_user_name (name, domain, sid, type) : status;
+ status = (status != 0x0) ? lookup_added_user_name(name, domain, sid, type) : status;
return status;
}
/*******************************************************************
- lookup_rid
- ********************************************************************/
-uint32 lookup_rid(char *name, uint32 *rid, uint8 *type)
-{
- uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
-
- status = (status != 0x0) ? lookup_user_rid(name, rid, type) : status;
- status = (status != 0x0) ? lookup_grp_rid (name, rid, type) : status;
-
- return status;
-}
-
-/*******************************************************************
- lookup_user_rids
+ lookup_name
********************************************************************/
-uint32 lookup_user_rids(char *name, uint32 *usr_rid, uint32 *grp_rid)
+uint32 lookup_name(const char *name, DOM_SID *sid, uint32 *type)
{
uint32 status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- uint8 type;
-
- /*
- * try an ordinary user lookup
- */
-
- status = lookup_added_user_rids(name, usr_rid, grp_rid);
- if (status == 0)
- {
- return status;
- }
-
- /*
- * hm. must be a well-known user, in a well-known group.
- */
-
- status = lookup_wk_user_rid(name, usr_rid, &type);
- if (status != 0 || type != SID_NAME_USER)
- {
- return status; /* ok, maybe not! */
- }
- if (type != SID_NAME_USER)
- {
- return 0xC0000000 | NT_STATUS_NONE_MAPPED; /* users only... */
- }
-
- /*
- * ok, got the user rid: now try the group rid
- */
+ fstring domain;
+ fstring user;
+
+ split_domain_name(name, domain, user);
- status = lookup_builtin_grp_rid(name, grp_rid, &type);
- if (type == SID_NAME_DOM_GRP ||
- type == SID_NAME_ALIAS ||
- type == SID_NAME_WKN_GRP)
- {
- status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- }
+ status = (status != 0x0) ? lookup_user_name (user, domain, sid, type) : status;
+ status = (status != 0x0) ? lookup_grp_name (user, domain, sid, type) : status;
+#if 0
+ status = (status != 0x0) ? lookup_domain_name (domain, sid, type) : status;
+#endif
return status;
}
diff --git a/source/rpc_server/srv_lsa.c b/source/rpc_server/srv_lsa.c
index 7094d842b41..915d00ee31e 100644
--- a/source/rpc_server/srv_lsa.c
+++ b/source/rpc_server/srv_lsa.c
@@ -1,651 +1 @@
-
-/*
- * Unix SMB/Netbios implementation.
- * Version 1.9.
- * RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jeremy Allison 1998.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "includes.h"
-#include "nterr.h"
-
-extern int DEBUGLEVEL;
-extern DOM_SID global_sam_sid;
-extern fstring global_myworkgroup;
-extern pstring global_myname;
-
-/***************************************************************************
- lsa_reply_open_policy2
- ***************************************************************************/
-
-static BOOL lsa_reply_open_policy2(prs_struct *rdata)
-{
- int i;
- LSA_R_OPEN_POL2 r_o;
-
- ZERO_STRUCT(r_o);
-
- /* set up the LSA QUERY INFO response */
-
- for (i = 4; i < POL_HND_SIZE; i++)
- r_o.pol.data[i] = i;
- r_o.status = 0x0;
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_open_pol2("", &r_o, rdata, 0)) {
- DEBUG(0,("lsa_reply_open_policy2: unable to marshall LSA_R_OPEN_POL2.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
-lsa_reply_open_policy
- ***************************************************************************/
-
-static BOOL lsa_reply_open_policy(prs_struct *rdata)
-{
- int i;
- LSA_R_OPEN_POL r_o;
-
- ZERO_STRUCT(r_o);
-
- /* set up the LSA QUERY INFO response */
-
- for (i = 4; i < POL_HND_SIZE; i++)
- r_o.pol.data[i] = i;
- r_o.status = 0x0;
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_open_pol("", &r_o, rdata, 0)) {
- DEBUG(0,("lsa_reply_open_policy: unable to marshall LSA_R_OPEN_POL.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
-Init dom_query
- ***************************************************************************/
-
-static void init_dom_query(DOM_QUERY *d_q, char *dom_name, DOM_SID *dom_sid)
-{
- fstring sid_str;
- int domlen = strlen(dom_name);
-
- d_q->uni_dom_max_len = domlen * 2;
- d_q->uni_dom_str_len = domlen * 2;
-
- d_q->buffer_dom_name = domlen != 0 ? 1 : 0; /* domain buffer pointer */
- d_q->buffer_dom_sid = dom_sid != NULL ? 1 : 0; /* domain sid pointer */
-
- /* this string is supposed to be character short */
- init_unistr2(&d_q->uni_domain_name, dom_name, domlen);
-
- sid_to_string(sid_str, dom_sid);
- init_dom_sid2(&d_q->dom_sid, dom_sid);
-}
-
-/***************************************************************************
- lsa_reply_enum_trust_dom
- ***************************************************************************/
-
-static void lsa_reply_enum_trust_dom(LSA_Q_ENUM_TRUST_DOM *q_e,
- prs_struct *rdata,
- uint32 enum_context, char *dom_name, DOM_SID *dom_sid)
-{
- LSA_R_ENUM_TRUST_DOM r_e;
-
- ZERO_STRUCT(r_e);
-
- /* set up the LSA QUERY INFO response */
- init_r_enum_trust_dom(&r_e, enum_context, dom_name, dom_sid,
- dom_name != NULL ? 0x0 : 0x80000000 | NT_STATUS_UNABLE_TO_FREE_VM);
-
- /* store the response in the SMB stream */
- lsa_io_r_enum_trust_dom("", &r_e, rdata, 0);
-}
-
-/***************************************************************************
-lsa_reply_query_info
- ***************************************************************************/
-
-static BOOL lsa_reply_query_info(LSA_Q_QUERY_INFO *q_q, prs_struct *rdata,
- char *dom_name, DOM_SID *dom_sid)
-{
- LSA_R_QUERY_INFO r_q;
-
- ZERO_STRUCT(r_q);
-
- /* set up the LSA QUERY INFO response */
-
- r_q.undoc_buffer = 0x22000000; /* bizarre */
- r_q.info_class = q_q->info_class;
-
- init_dom_query(&r_q.dom.id5, dom_name, dom_sid);
-
- r_q.status = 0x0;
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_query("", &r_q, rdata, 0)) {
- DEBUG(0,("lsa_reply_query_info: failed to marshall LSA_R_QUERY_INFO.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
- init_dom_ref - adds a domain if it's not already in, returns the index.
-***************************************************************************/
-
-static int init_dom_ref(DOM_R_REF *ref, char *dom_name, DOM_SID *dom_sid)
-{
- int num = 0;
- int len;
-
- if (dom_name != NULL) {
- for (num = 0; num < ref->num_ref_doms_1; num++) {
- fstring domname;
- fstrcpy(domname, dos_unistr2_to_str(&ref->ref_dom[num].uni_dom_name));
- if (strequal(domname, dom_name))
- return num;
- }
- } else {
- num = ref->num_ref_doms_1;
- }
-
- if (num >= MAX_REF_DOMAINS) {
- /* index not found, already at maximum domain limit */
- return -1;
- }
-
- ref->num_ref_doms_1 = num+1;
- ref->ptr_ref_dom = 1;
- ref->max_entries = MAX_REF_DOMAINS;
- ref->num_ref_doms_2 = num+1;
-
- len = (dom_name != NULL) ? strlen(dom_name) : 0;
- if(dom_name != NULL && len == 0)
- len = 1;
-
- init_uni_hdr(&ref->hdr_ref_dom[num].hdr_dom_name, len);
- ref->hdr_ref_dom[num].ptr_dom_sid = dom_sid != NULL ? 1 : 0;
-
- init_unistr2(&ref->ref_dom[num].uni_dom_name, dom_name, len);
- init_dom_sid2(&ref->ref_dom[num].ref_dom, dom_sid );
-
- return num;
-}
-
-/***************************************************************************
- init_lsa_rid2s
- ***************************************************************************/
-
-static void init_lsa_rid2s(DOM_R_REF *ref, DOM_RID2 *rid2,
- int num_entries, UNISTR2 name[MAX_LOOKUP_SIDS],
- uint32 *mapped_count)
-{
- int i;
- int total = 0;
- *mapped_count = 0;
-
- SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
-
- for (i = 0; i < num_entries; i++) {
- BOOL status = False;
- DOM_SID dom_sid;
- DOM_SID sid;
- uint32 rid = 0xffffffff;
- int dom_idx = -1;
- pstring full_name;
- fstring dom_name;
- fstring user;
- uint8 sid_name_use = SID_NAME_UNKNOWN;
-
- pstrcpy(full_name, dos_unistr2_to_str(&name[i]));
-
- /*
- * Try and split the name into a DOMAIN and
- * user component.
- */
-
- split_domain_name(full_name, dom_name, user);
-
- /*
- * We only do anything with this name if we
- * can map the Domain into a SID we know.
- */
-
- if (map_domain_name_to_sid(&dom_sid, dom_name)) {
- dom_idx = init_dom_ref(ref, dom_name, &dom_sid);
-
- if (lookup_local_name(dom_name, user, &sid, &sid_name_use) && sid_split_rid(&sid, &rid))
- status = True;
- }
-
- if (status)
- (*mapped_count)++;
- else {
- dom_idx = -1;
- rid = 0xffffffff;
- sid_name_use = SID_NAME_UNKNOWN;
- }
-
- init_dom_rid2(&rid2[total], rid, sid_name_use, dom_idx);
- total++;
- }
-}
-
-/***************************************************************************
- init_reply_lookup_names
- ***************************************************************************/
-
-static void init_reply_lookup_names(LSA_R_LOOKUP_NAMES *r_l,
- DOM_R_REF *ref, uint32 num_entries,
- DOM_RID2 *rid2, uint32 mapped_count)
-{
- r_l->ptr_dom_ref = 1;
- r_l->dom_ref = ref;
-
- r_l->num_entries = num_entries;
- r_l->ptr_entries = 1;
- r_l->num_entries2 = num_entries;
- r_l->dom_rid = rid2;
-
- r_l->mapped_count = mapped_count;
-
- if (mapped_count == 0)
- r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- else
- r_l->status = 0x0;
-}
-
-/***************************************************************************
- Init lsa_trans_names.
- ***************************************************************************/
-
-static void init_lsa_trans_names(DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *trn,
- int num_entries, DOM_SID2 sid[MAX_LOOKUP_SIDS], uint32 *mapped_count)
-{
- extern DOM_SID global_sid_S_1_5_0x20; /* BUILTIN sid. */
- int i;
- int total = 0;
- *mapped_count = 0;
-
- SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
-
- for (i = 0; i < num_entries; i++) {
- BOOL status = False;
- DOM_SID find_sid = sid[i].sid;
- uint32 rid = 0xffffffff;
- int dom_idx = -1;
- fstring name;
- fstring dom_name;
- uint8 sid_name_use = 0;
-
- memset(dom_name, '\0', sizeof(dom_name));
- memset(name, '\0', sizeof(name));
-
- /*
- * First, check to see if the SID is one of the well
- * known ones (this includes our own domain SID).
- * Next, check if the domain prefix is one of the
- * well known ones. If so and the domain prefix was
- * either BUILTIN or our own global sid, then lookup
- * the RID as a user or group id and translate to
- * a name.
- */
-
- if (map_domain_sid_to_name(&find_sid, dom_name)) {
- sid_name_use = SID_NAME_DOMAIN;
- } else if (sid_split_rid(&find_sid, &rid) && map_domain_sid_to_name(&find_sid, dom_name)) {
- if (sid_equal(&find_sid, &global_sam_sid) ||
- sid_equal(&find_sid, &global_sid_S_1_5_0x20)) {
- status = lookup_local_rid(rid, name, &sid_name_use);
- } else {
- status = lookup_known_rid(&find_sid, rid, name, &sid_name_use);
- }
- }
-
- DEBUG(10,("init_lsa_trans_names: adding domain '%s' sid %s to referenced list.\n",
- dom_name, name ));
-
- dom_idx = init_dom_ref(ref, dom_name, &find_sid);
-
- if(!status) {
- slprintf(name, sizeof(name)-1, "unix.%08x", rid);
- sid_name_use = SID_NAME_UNKNOWN;
- }
-
- DEBUG(10,("init_lsa_trans_names: added user '%s\\%s' to referenced list.\n", dom_name, name ));
-
- (*mapped_count)++;
-
- init_lsa_trans_name(&trn->name[total], &trn->uni_name[total],
- sid_name_use, name, dom_idx);
- total++;
- }
-
- trn->num_entries = total;
- trn->ptr_trans_names = 1;
- trn->num_entries2 = total;
-}
-
-/***************************************************************************
- Init_reply_lookup_sids.
- ***************************************************************************/
-
-static void init_reply_lookup_sids(LSA_R_LOOKUP_SIDS *r_l,
- DOM_R_REF *ref, LSA_TRANS_NAME_ENUM *names,
- uint32 mapped_count)
-{
- r_l->ptr_dom_ref = 1;
- r_l->dom_ref = ref;
- r_l->names = names;
- r_l->mapped_count = mapped_count;
-
- if (mapped_count == 0)
- r_l->status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
- else
- r_l->status = 0x0;
-}
-
-/***************************************************************************
-lsa_reply_lookup_sids
- ***************************************************************************/
-
-static BOOL lsa_reply_lookup_sids(prs_struct *rdata, DOM_SID2 *sid, int num_entries)
-{
- LSA_R_LOOKUP_SIDS r_l;
- DOM_R_REF ref;
- LSA_TRANS_NAME_ENUM names;
- uint32 mapped_count = 0;
-
- ZERO_STRUCT(r_l);
- ZERO_STRUCT(ref);
- ZERO_STRUCT(names);
-
- /* set up the LSA Lookup SIDs response */
- init_lsa_trans_names(&ref, &names, num_entries, sid, &mapped_count);
- init_reply_lookup_sids(&r_l, &ref, &names, mapped_count);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_lookup_sids("", &r_l, rdata, 0)) {
- DEBUG(0,("lsa_reply_lookup_sids: Failed to marshall LSA_R_LOOKUP_SIDS.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
-lsa_reply_lookup_names
- ***************************************************************************/
-
-static BOOL lsa_reply_lookup_names(prs_struct *rdata,
- UNISTR2 names[MAX_LOOKUP_SIDS], int num_entries)
-{
- LSA_R_LOOKUP_NAMES r_l;
- DOM_R_REF ref;
- DOM_RID2 rids[MAX_LOOKUP_SIDS];
- uint32 mapped_count = 0;
-
- ZERO_STRUCT(r_l);
- ZERO_STRUCT(ref);
- ZERO_ARRAY(rids);
-
- /* set up the LSA Lookup RIDs response */
- init_lsa_rid2s(&ref, rids, num_entries, names, &mapped_count);
- init_reply_lookup_names(&r_l, &ref, num_entries, rids, mapped_count);
-
- /* store the response in the SMB stream */
- if(!lsa_io_r_lookup_names("", &r_l, rdata, 0)) {
- DEBUG(0,("lsa_reply_lookup_names: Failed to marshall LSA_R_LOOKUP_NAMES.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
- api_lsa_open_policy2
- ***************************************************************************/
-
-static BOOL api_lsa_open_policy2( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- LSA_Q_OPEN_POL2 q_o;
-
- ZERO_STRUCT(q_o);
-
- /* grab the server, object attributes and desired access flag...*/
- if(!lsa_io_q_open_pol2("", &q_o, data, 0)) {
- DEBUG(0,("api_lsa_open_policy2: unable to unmarshall LSA_Q_OPEN_POL2.\n"));
- return False;
- }
-
- /* lkclXXXX having decoded it, ignore all fields in the open policy! */
-
- /* return a 20 byte policy handle */
- if(!lsa_reply_open_policy2(rdata))
- return False;
-
- return True;
-}
-
-/***************************************************************************
-api_lsa_open_policy
- ***************************************************************************/
-static BOOL api_lsa_open_policy( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- LSA_Q_OPEN_POL q_o;
-
- ZERO_STRUCT(q_o);
-
- /* grab the server, object attributes and desired access flag...*/
- if(!lsa_io_q_open_pol("", &q_o, data, 0)) {
- DEBUG(0,("api_lsa_open_policy: unable to unmarshall LSA_Q_OPEN_POL.\n"));
- return False;
- }
-
- /* lkclXXXX having decoded it, ignore all fields in the open policy! */
-
- /* return a 20 byte policy handle */
- if(!lsa_reply_open_policy(rdata))
- return False;
-
- return True;
-}
-
-/***************************************************************************
-api_lsa_enum_trust_dom
- ***************************************************************************/
-static BOOL api_lsa_enum_trust_dom( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- LSA_Q_ENUM_TRUST_DOM q_e;
-
- ZERO_STRUCT(q_e);
-
- /* grab the enum trust domain context etc. */
- lsa_io_q_enum_trust_dom("", &q_e, data, 0);
-
- /* construct reply. return status is always 0x0 */
- lsa_reply_enum_trust_dom(&q_e, rdata, 0, NULL, NULL);
-
- return True;
-}
-
-/***************************************************************************
-api_lsa_query_info
- ***************************************************************************/
-static BOOL api_lsa_query_info( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- LSA_Q_QUERY_INFO q_i;
- fstring name;
- DOM_SID *sid = NULL;
- memset(name, 0, sizeof(name));
-
- ZERO_STRUCT(q_i);
-
- /* grab the info class and policy handle */
- if(!lsa_io_q_query("", &q_i, data, 0)) {
- DEBUG(0,("api_lsa_query_info: failed to unmarshall LSA_Q_QUERY_INFO.\n"));
- return False;
- }
-
- switch (q_i.info_class) {
- case 0x03:
- fstrcpy(name, global_myworkgroup);
- sid = &global_sam_sid;
- break;
- case 0x05:
- fstrcpy(name, global_myname);
- sid = &global_sam_sid;
- break;
- default:
- DEBUG(0,("api_lsa_query_info: unknown info level in Lsa Query: %d\n", q_i.info_class));
- break;
- }
-
- /* construct reply. return status is always 0x0 */
- if(!lsa_reply_query_info(&q_i, rdata, name, sid))
- return False;
-
- return True;
-}
-
-/***************************************************************************
- api_lsa_lookup_sids
- ***************************************************************************/
-
-static BOOL api_lsa_lookup_sids( uint16 vuid, prs_struct *data, prs_struct *rdata )
-{
- LSA_Q_LOOKUP_SIDS q_l;
- ZERO_STRUCT(q_l);
-
- /* grab the info class and policy handle */
- if(!lsa_io_q_lookup_sids("", &q_l, data, 0)) {
- DEBUG(0,("api_lsa_lookup_sids: failed to unmarshall LSA_Q_LOOKUP_SIDS.\n"));
- return False;
- }
-
- /* construct reply. return status is always 0x0 */
- if(!lsa_reply_lookup_sids(rdata, q_l.sids.sid, q_l.sids.num_entries))
- return False;
-
- return True;
-}
-
-/***************************************************************************
- api_lsa_lookup_names
- ***************************************************************************/
-
-static BOOL api_lsa_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata )
-{
- LSA_Q_LOOKUP_NAMES q_l;
- ZERO_STRUCT(q_l);
-
- /* grab the info class and policy handle */
- if(!lsa_io_q_lookup_names("", &q_l, data, 0)) {
- DEBUG(0,("api_lsa_lookup_names: failed to unmarshall LSA_Q_LOOKUP_NAMES.\n"));
- return False;
- }
-
- SMB_ASSERT_ARRAY(q_l.uni_name, q_l.num_entries);
-
- return lsa_reply_lookup_names(rdata, q_l.uni_name, q_l.num_entries);
-}
-
-/***************************************************************************
- api_lsa_close
- ***************************************************************************/
-static BOOL api_lsa_close( uint16 vuid, prs_struct *data,
- prs_struct *rdata)
-{
- LSA_R_CLOSE r_c;
-
- ZERO_STRUCT(r_c);
-
- /* store the response in the SMB stream */
- if (!lsa_io_r_close("", &r_c, rdata, 0)) {
- DEBUG(0,("api_lsa_close: lsa_io_r_close failed.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
- api_lsa_open_secret
- ***************************************************************************/
-static BOOL api_lsa_open_secret( uint16 vuid, prs_struct *data,
- prs_struct *rdata)
-{
- /* XXXX this is NOT good */
- size_t i;
- uint32 dummy = 0;
-
- for(i =0; i < 4; i++) {
- if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
- DEBUG(0,("api_lsa_open_secret: prs_uint32 %d failed.\n",
- (int)i ));
- return False;
- }
- }
-
- dummy = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- if(!prs_uint32("api_lsa_close", rdata, 1, &dummy)) {
- DEBUG(0,("api_lsa_open_secret: prs_uint32 status failed.\n"));
- return False;
- }
-
- return True;
-}
-
-/***************************************************************************
- \PIPE\ntlsa commands
- ***************************************************************************/
-static struct api_struct api_lsa_cmds[] =
-{
- { "LSA_OPENPOLICY2" , LSA_OPENPOLICY2 , api_lsa_open_policy2 },
- { "LSA_OPENPOLICY" , LSA_OPENPOLICY , api_lsa_open_policy },
- { "LSA_QUERYINFOPOLICY" , LSA_QUERYINFOPOLICY , api_lsa_query_info },
- { "LSA_ENUMTRUSTDOM" , LSA_ENUMTRUSTDOM , api_lsa_enum_trust_dom },
- { "LSA_CLOSE" , LSA_CLOSE , api_lsa_close },
- { "LSA_OPENSECRET" , LSA_OPENSECRET , api_lsa_open_secret },
- { "LSA_LOOKUPSIDS" , LSA_LOOKUPSIDS , api_lsa_lookup_sids },
- { "LSA_LOOKUPNAMES" , LSA_LOOKUPNAMES , api_lsa_lookup_names },
- { NULL , 0 , NULL }
-};
-
-/***************************************************************************
- api_ntLsarpcTNP
- ***************************************************************************/
-BOOL api_ntlsa_rpc(pipes_struct *p, prs_struct *data)
-{
- return api_rpcTNP(p, "api_ntlsa_rpc", api_lsa_cmds, data);
-}
+/* retired - code is now in lsarpcd/ */
diff --git a/source/rpc_server/srv_lsa_hnd.c b/source/rpc_server/srv_lsa_hnd.c
index 24aec701f0b..8705e334f6e 100644
--- a/source/rpc_server/srv_lsa_hnd.c
+++ b/source/rpc_server/srv_lsa_hnd.c
@@ -1,309 +1,2 @@
-/*
- * Unix SMB/Netbios implementation.
- * Version 1.9.
- * RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
-#include "includes.h"
-
-
-extern int DEBUGLEVEL;
-
-#ifndef MAX_OPEN_POLS
-#define MAX_OPEN_POLS 64
-#endif
-
-struct reg_info
-{
- /* for use by \PIPE\winreg */
- fstring name; /* name of registry key */
-};
-
-struct samr_info
-{
- /* for use by the \PIPE\samr policy */
- DOM_SID sid;
- uint32 rid; /* relative id associated with the pol_hnd */
- uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
-};
-
-static struct policy
-{
- struct policy *next, *prev;
- int pnum;
- BOOL open;
- POLICY_HND pol_hnd;
-
- union {
- struct samr_info samr;
- struct reg_info reg;
- } dev;
-} *Policy;
-
-static struct bitmap *bmap;
-
-
-/****************************************************************************
- create a unique policy handle
-****************************************************************************/
-static void create_pol_hnd(POLICY_HND *hnd)
-{
- static uint32 pol_hnd_low = 0;
- static uint32 pol_hnd_high = 0;
-
- if (hnd == NULL) return;
-
- /* i severely doubt that pol_hnd_high will ever be non-zero... */
- pol_hnd_low++;
- if (pol_hnd_low == 0) pol_hnd_high++;
-
- SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */
- SIVAL(hnd->data, 4 , pol_hnd_low ); /* second bit is incrementing */
- SIVAL(hnd->data, 8 , pol_hnd_high); /* second bit is incrementing */
- SIVAL(hnd->data, 12, time(NULL)); /* something random */
- SIVAL(hnd->data, 16, getpid()); /* something more random */
-}
-
-/****************************************************************************
- initialise policy handle states...
-****************************************************************************/
-void init_lsa_policy_hnd(void)
-{
- bmap = bitmap_allocate(MAX_OPEN_POLS);
- if (!bmap) {
- exit_server("out of memory in init_lsa_policy_hnd\n");
- }
-}
-
-/****************************************************************************
- find first available policy slot. creates a policy handle for you.
-****************************************************************************/
-BOOL open_lsa_policy_hnd(POLICY_HND *hnd)
-{
- int i;
- struct policy *p;
-
- i = bitmap_find(bmap, 1);
-
- if (i == -1) {
- DEBUG(0,("ERROR: out of Policy Handles!\n"));
- return False;
- }
-
- p = (struct policy *)malloc(sizeof(*p));
- if (!p) {
- DEBUG(0,("ERROR: out of memory!\n"));
- return False;
- }
-
- ZERO_STRUCTP(p);
-
- p->open = True;
- p->pnum = i;
-
- create_pol_hnd(hnd);
- memcpy(&p->pol_hnd, hnd, sizeof(*hnd));
-
- bitmap_set(bmap, i);
-
- DLIST_ADD(Policy, p);
-
- DEBUG(4,("Opened policy hnd[%x] ", i));
- dump_data(4, (char *)hnd->data, sizeof(hnd->data));
-
- return True;
-}
-
-/****************************************************************************
- find policy by handle
-****************************************************************************/
-static struct policy *find_lsa_policy(POLICY_HND *hnd)
-{
- struct policy *p;
-
- for (p=Policy;p;p=p->next) {
- if (memcmp(&p->pol_hnd, hnd, sizeof(*hnd)) == 0) {
- DEBUG(4,("Found policy hnd[%x] ", p->pnum));
- dump_data(4, (char *)hnd->data, sizeof(hnd->data));
- return p;
- }
- }
-
- DEBUG(4,("Policy not found: "));
- dump_data(4, (char *)hnd->data, sizeof(hnd->data));
-
- return NULL;
-}
-
-/****************************************************************************
- find policy index by handle
-****************************************************************************/
-int find_lsa_policy_by_hnd(POLICY_HND *hnd)
-{
- struct policy *p = find_lsa_policy(hnd);
-
- return p?p->pnum:-1;
-}
-
-/****************************************************************************
- set samr rid
-****************************************************************************/
-BOOL set_lsa_policy_samr_rid(POLICY_HND *hnd, uint32 rid)
-{
- struct policy *p = find_lsa_policy(hnd);
-
- if (p && p->open) {
- DEBUG(3,("Setting policy device rid=%x pnum=%x\n",
- rid, p->pnum));
-
- p->dev.samr.rid = rid;
- return True;
- }
-
- DEBUG(3,("Error setting policy rid=%x\n",rid));
- return False;
-}
-
-
-/****************************************************************************
- set samr pol status. absolutely no idea what this is.
-****************************************************************************/
-BOOL set_lsa_policy_samr_pol_status(POLICY_HND *hnd, uint32 pol_status)
-{
- struct policy *p = find_lsa_policy(hnd);
-
- if (p && p->open) {
- DEBUG(3,("Setting policy status=%x pnum=%x\n",
- pol_status, p->pnum));
-
- p->dev.samr.status = pol_status;
- return True;
- }
-
- DEBUG(3,("Error setting policy status=%x\n",
- pol_status));
- return False;
-}
-
-/****************************************************************************
- set samr sid
-****************************************************************************/
-BOOL set_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
-{
- fstring sidstr;
- struct policy *p = find_lsa_policy(hnd);
-
- if (p && p->open) {
- DEBUG(3,("Setting policy sid=%s pnum=%x\n",
- sid_to_string(sidstr, sid), p->pnum));
-
- memcpy(&p->dev.samr.sid, sid, sizeof(*sid));
- return True;
- }
-
- DEBUG(3,("Error setting policy sid=%s\n",
- sid_to_string(sidstr, sid)));
- return False;
-}
-
-/****************************************************************************
- get samr sid
-****************************************************************************/
-BOOL get_lsa_policy_samr_sid(POLICY_HND *hnd, DOM_SID *sid)
-{
- struct policy *p = find_lsa_policy(hnd);
-
- if (p != NULL && p->open)
- {
- fstring sidstr;
- memcpy(sid, &p->dev.samr.sid, sizeof(*sid));
- DEBUG(3,("Getting policy sid=%s pnum=%x\n",
- sid_to_string(sidstr, sid), p->pnum));
-
- return True;
- }
-
- DEBUG(3,("Error getting policy\n"));
- return False;
-}
-
-/****************************************************************************
- get samr rid
-****************************************************************************/
-uint32 get_lsa_policy_samr_rid(POLICY_HND *hnd)
-{
- struct policy *p = find_lsa_policy(hnd);
-
- if (p && p->open) {
- uint32 rid = p->dev.samr.rid;
- DEBUG(3,("Getting policy device rid=%x pnum=%x\n",
- rid, p->pnum));
-
- return rid;
- }
-
- DEBUG(3,("Error getting policy\n"));
- return 0xffffffff;
-}
-
-/****************************************************************************
- set reg name
-****************************************************************************/
-BOOL set_lsa_policy_reg_name(POLICY_HND *hnd, fstring name)
-{
- struct policy *p = find_lsa_policy(hnd);
-
- if (p && p->open) {
- DEBUG(3,("Setting policy pnum=%x name=%s\n",
- p->pnum, name));
-
- fstrcpy(p->dev.reg.name, name);
- return True;
- }
-
- DEBUG(3,("Error setting policy name=%s\n", name));
- return False;
-}
-
-/****************************************************************************
- close an lsa policy
-****************************************************************************/
-BOOL close_lsa_policy_hnd(POLICY_HND *hnd)
-{
- struct policy *p = find_lsa_policy(hnd);
-
- if (!p) {
- DEBUG(3,("Error closing policy\n"));
- return False;
- }
-
- DEBUG(3,("Closed policy name pnum=%x\n", p->pnum));
-
- DLIST_REMOVE(Policy, p);
-
- bitmap_clear(bmap, p->pnum);
-
- ZERO_STRUCTP(p);
-
- free(p);
-
- return True;
-}
+/* this file moved to lib/util_hnd.c */
diff --git a/source/rpc_server/srv_netlog.c b/source/rpc_server/srv_netlog.c
index c0233d80c6e..7dd75336cf3 100644
--- a/source/rpc_server/srv_netlog.c
+++ b/source/rpc_server/srv_netlog.c
@@ -1,12 +1,12 @@
-
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
- * Copyright (C) Jeremy Allison 1998.
+ * Copyright (C) Paul Ashton 1997,
+ * Copyright (C) Jeremy Allison 1998,
+ * Copyright (C) Sander Striker 2000
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,911 +24,376 @@
*/
+/* strikerXXXX Luke, do I need all these? */
#include "includes.h"
#include "nterr.h"
+#include "sids.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
-extern BOOL sam_logon_in_ssb;
-extern pstring samlogon_user;
extern pstring global_myname;
-extern DOM_SID global_sam_sid;
-
-/*************************************************************************
- init_net_r_req_chal:
- *************************************************************************/
-
-static void init_net_r_req_chal(NET_R_REQ_CHAL *r_c,
- DOM_CHAL *srv_chal, int status)
-{
- DEBUG(6,("init_net_r_req_chal: %d\n", __LINE__));
- memcpy(r_c->srv_chal.data, srv_chal->data, sizeof(srv_chal->data));
- r_c->status = status;
-}
/*************************************************************************
- net_reply_req_chal:
+ api_net_req_chal
*************************************************************************/
-
-static BOOL net_reply_req_chal(NET_Q_REQ_CHAL *q_c, prs_struct *rdata,
- DOM_CHAL *srv_chal, uint32 srv_time)
+static BOOL api_net_req_chal( rpcsrv_struct *p,
+ prs_struct *data,
+ prs_struct *rdata)
{
+ NET_Q_REQ_CHAL q_r;
NET_R_REQ_CHAL r_c;
- DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
-
- /* set up the LSA REQUEST CHALLENGE response */
- init_net_r_req_chal(&r_c, srv_chal, srv_time);
+ ZERO_STRUCT(q_r);
+ ZERO_STRUCT(r_c);
- /* store the response in the SMB stream */
- if(!net_io_r_req_chal("", &r_c, rdata, 0)) {
- DEBUG(0,("net_reply_req_chal: Failed to marshall NET_R_REQ_CHAL.\n"));
+ /* grab the challenge... */
+ if (!net_io_q_req_chal("", &q_r, data, 0))
+ {
return False;
}
- DEBUG(6,("net_reply_req_chal: %d\n", __LINE__));
-
- return True;
-}
-
-/*************************************************************************
- net_reply_logon_ctrl2:
- *************************************************************************/
-
-static BOOL net_reply_logon_ctrl2(NET_Q_LOGON_CTRL2 *q_l, prs_struct *rdata,
- uint32 flags, uint32 pdc_status, uint32 logon_attempts,
- uint32 tc_status, char *trust_domain_name)
-{
- NET_R_LOGON_CTRL2 r_l;
-
- DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
-
- /* set up the Logon Control2 response */
- init_r_logon_ctrl2(&r_l, q_l->query_level,
- flags, pdc_status, logon_attempts,
- tc_status, trust_domain_name);
+ r_c.status = _net_req_chal(&q_r.uni_logon_srv, &q_r.uni_logon_clnt,
+ &q_r.clnt_chal, &r_c.srv_chal,
+ p->key.pid); /* strikerXXXX have to pass this parameter */
/* store the response in the SMB stream */
- if(!net_io_r_logon_ctrl2("", &r_l, rdata, 0)) {
- DEBUG(0,("net_reply_logon_ctrl2: Failed to marshall NET_R_LOGON_CTRL2.\n"));
- return False;
- }
-
- DEBUG(6,("net_reply_logon_ctrl2: %d\n", __LINE__));
-
- return True;
+ return net_io_r_req_chal("", &r_c, rdata, 0);
}
/*************************************************************************
- net_reply_trust_dom_list:
+ api_net_auth
*************************************************************************/
-
-static BOOL net_reply_trust_dom_list(NET_Q_TRUST_DOM_LIST *q_t, prs_struct *rdata,
- uint32 num_trust_domains, char *trust_domain_name)
+static BOOL api_net_auth( rpcsrv_struct *p,
+ prs_struct *data,
+ prs_struct *rdata)
{
- NET_R_TRUST_DOM_LIST r_t;
-
- DEBUG(6,("net_reply_trust_dom_list: %d\n", __LINE__));
+ NET_Q_AUTH q_a;
+ NET_R_AUTH r_a;
- /* set up the Trusted Domain List response */
- init_r_trust_dom(&r_t, num_trust_domains, trust_domain_name);
+ ZERO_STRUCT(q_a);
+ ZERO_STRUCT(r_a);
- /* store the response in the SMB stream */
- if(!net_io_r_trust_dom("", &r_t, rdata, 0)) {
- DEBUG(0,("net_reply_trust_dom_list: Failed to marshall NET_R_TRUST_DOM_LIST.\n"));
+ /* grab the challenge... */
+ if (!net_io_q_auth("", &q_a, data, 0))
+ {
return False;
}
- DEBUG(6,("net_reply_trust_dom_listlogon_ctrl2: %d\n", __LINE__));
+ r_a.status = _net_auth(&q_a.clnt_id,
+ &q_a.clnt_chal,
+ &r_a.srv_chal,
+ p->key.pid); /* strikerXXXX have to pass this parameter */
- return True;
+ /* store the response in the SMB stream */
+ return net_io_r_auth("", &r_a, rdata, 0);
}
/*************************************************************************
- init_net_r_auth_2:
+ api_net_auth_2
*************************************************************************/
-
-static void init_net_r_auth_2(NET_R_AUTH_2 *r_a,
- DOM_CHAL *resp_cred, NEG_FLAGS *flgs, int status)
-{
- memcpy(r_a->srv_chal.data, resp_cred->data, sizeof(resp_cred->data));
- memcpy(&r_a->srv_flgs, flgs, sizeof(r_a->srv_flgs));
- r_a->status = status;
-}
-
-/************************************************************************
- net_reply_auth_2:
- *************************************************************************/
-
-static BOOL net_reply_auth_2(NET_Q_AUTH_2 *q_a, prs_struct *rdata,
- DOM_CHAL *resp_cred, int status)
+static BOOL api_net_auth_2( rpcsrv_struct *p,
+ prs_struct *data,
+ prs_struct *rdata)
{
+ NET_Q_AUTH_2 q_a;
NET_R_AUTH_2 r_a;
- NEG_FLAGS srv_flgs;
-
- srv_flgs.neg_flags = 0x000001ff;
-
- /* set up the LSA AUTH 2 response */
- init_net_r_auth_2(&r_a, resp_cred, &srv_flgs, status);
+ ZERO_STRUCT(q_a);
+ ZERO_STRUCT(r_a);
- /* store the response in the SMB stream */
- if(!net_io_r_auth_2("", &r_a, rdata, 0)) {
- DEBUG(0,("net_reply_auth_2: Failed to marshall NET_R_AUTH_2.\n"));
+ /* grab the challenge... */
+ if (!net_io_q_auth_2("", &q_a, data, 0))
+ {
return False;
}
- return True;
-}
-
-/***********************************************************************************
- init_net_r_srv_pwset:
- ***********************************************************************************/
-
-static void init_net_r_srv_pwset(NET_R_SRV_PWSET *r_s,
- DOM_CRED *srv_cred, int status)
-{
- DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
+ r_a.status = _net_auth_2(&q_a.clnt_id,
+ &q_a.clnt_chal,
+ &q_a.clnt_flgs,
+ &r_a.srv_chal,
+ &r_a.srv_flgs,
+ p->key.pid); /* strikerXXXX have to pass this parameter */
- memcpy(&r_s->srv_cred, srv_cred, sizeof(r_s->srv_cred));
- r_s->status = status;
-
- DEBUG(5,("init_net_r_srv_pwset: %d\n", __LINE__));
+ /* store the response in the SMB stream */
+ return net_io_r_auth_2("", &r_a, rdata, 0);
}
/*************************************************************************
- net_reply_srv_pwset:
+ api_net_srv_pwset
*************************************************************************/
-
-static BOOL net_reply_srv_pwset(NET_Q_SRV_PWSET *q_s, prs_struct *rdata,
- DOM_CRED *srv_cred, int status)
+static BOOL api_net_srv_pwset( rpcsrv_struct *p,
+ prs_struct *data,
+ prs_struct *rdata)
{
+ NET_Q_SRV_PWSET q_a;
NET_R_SRV_PWSET r_s;
- DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
+ ZERO_STRUCT(q_a);
+ ZERO_STRUCT(r_s);
- /* set up the LSA Server Password Set response */
- init_net_r_srv_pwset(&r_s, srv_cred, status);
-
- /* store the response in the SMB stream */
- if(!net_io_r_srv_pwset("", &r_s, rdata, 0)) {
- DEBUG(0,("net_reply_srv_pwset: Failed to marshall NET_R_SRV_PWSET.\n"));
+ /* grab the challenge and encrypted password ... */
+ if (!net_io_q_srv_pwset("", &q_a, data, 0))
+ {
return False;
}
- DEBUG(5,("net_srv_pwset: %d\n", __LINE__));
-
- return True;
-}
-
-/*************************************************************************
- net_reply_sam_logon:
- *************************************************************************/
-
-static BOOL net_reply_sam_logon(NET_Q_SAM_LOGON *q_s, prs_struct *rdata,
- DOM_CRED *srv_cred, NET_USER_INFO_3 *user_info,
- uint32 status)
-{
- NET_R_SAM_LOGON r_s;
-
- /* XXXX maybe we want to say 'no', reject the client's credentials */
- r_s.buffer_creds = 1; /* yes, we have valid server credentials */
- memcpy(&r_s.srv_creds, srv_cred, sizeof(r_s.srv_creds));
-
- /* store the user information, if there is any. */
- r_s.user = user_info;
- if (status == 0x0 && user_info != NULL && user_info->ptr_user_info != 0)
- r_s.switch_value = 3; /* indicates type of validation user info */
- else
- r_s.switch_value = 0; /* indicates no info */
-
- r_s.status = status;
- r_s.auth_resp = 1; /* authoritative response */
+ r_s.status = _net_srv_pwset(&q_a.clnt_id,
+ q_a.pwd,
+ &r_s.srv_cred,
+ p->key.pid); /* strikerXXXX have to pass this parameter */
/* store the response in the SMB stream */
- if(!net_io_r_sam_logon("", &r_s, rdata, 0)) {
- DEBUG(0,("net_reply_sam_logon: Failed to marshall NET_R_SAM_LOGON.\n"));
- return False;
- }
-
- return True;
+ return net_io_r_srv_pwset("", &r_s, rdata, 0);
}
-
/*************************************************************************
- net_reply_sam_logoff:
+ api_net_sam_logoff
*************************************************************************/
-
-static BOOL net_reply_sam_logoff(NET_Q_SAM_LOGOFF *q_s, prs_struct *rdata,
- DOM_CRED *srv_cred,
- uint32 status)
+static BOOL api_net_sam_logoff( rpcsrv_struct *p,
+ prs_struct *data,
+ prs_struct *rdata)
{
+ NET_Q_SAM_LOGOFF q_l;
NET_R_SAM_LOGOFF r_s;
+ NET_ID_INFO_CTR ctr;
+ DOM_CRED srv_cred;
+ uint32 status;
- /* XXXX maybe we want to say 'no', reject the client's credentials */
- r_s.buffer_creds = 1; /* yes, we have valid server credentials */
- memcpy(&r_s.srv_creds, srv_cred, sizeof(r_s.srv_creds));
-
- r_s.status = status;
-
- /* store the response in the SMB stream */
- if(!net_io_r_sam_logoff("", &r_s, rdata, 0)) {
- DEBUG(0,("net_reply_sam_logoff: Failed to marshall NET_R_SAM_LOGOFF.\n"));
- return False;
- }
-
- return True;
-}
-
-/******************************************************************
- gets a machine password entry. checks access rights of the host.
- ******************************************************************/
-
-static BOOL get_md4pw(char *md4pw, char *mach_name, char *mach_acct)
-{
- struct smb_passwd *smb_pass;
-
-#if 0
- /*
- * Currently this code is redundent as we already have a filter
- * by hostname list. What this code really needs to do is to
- * get a hosts allowed/hosts denied list from the SAM database
- * on a per user basis, and make the access decision there.
- * I will leave this code here for now as a reminder to implement
- * this at a later date. JRA.
- */
-
- if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
- client_name(Client), client_addr(Client)))
- {
- DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
- return False;
- }
-#endif /* 0 */
-
- become_root(True);
- smb_pass = getsmbpwnam(mach_acct);
- unbecome_root(True);
-
- if ((smb_pass) != NULL && !(smb_pass->acct_ctrl & ACB_DISABLED) &&
- (smb_pass->smb_nt_passwd != NULL))
- {
- memcpy(md4pw, smb_pass->smb_nt_passwd, 16);
- dump_data(5, md4pw, 16);
-
- return True;
- }
- DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
- return False;
-}
-
-/*************************************************************************
- api_net_req_chal:
- *************************************************************************/
-
-static BOOL api_net_req_chal( uint16 vuid, prs_struct *data, prs_struct *rdata)
-{
- NET_Q_REQ_CHAL q_r;
- uint32 status = 0x0;
-
- fstring mach_acct;
- fstring mach_name;
-
- user_struct *vuser;
-
- DEBUG(5,("api_net_req_chal(%d): vuid %d\n", __LINE__, (int)vuid));
-
- if ((vuser = get_valid_user_struct(vuid)) == NULL)
- return False;
-
- /* grab the challenge... */
- if(!net_io_q_req_chal("", &q_r, data, 0)) {
- DEBUG(0,("api_net_req_chal: Failed to unmarshall NET_Q_REQ_CHAL.\n"));
- return False;
- }
-
- fstrcpy(mach_acct, dos_unistrn2(q_r.uni_logon_clnt.buffer,
- q_r.uni_logon_clnt.uni_str_len));
-
- fstrcpy(mach_name, mach_acct);
- strlower(mach_name);
-
- fstrcat(mach_acct, "$");
-
- if (get_md4pw((char *)vuser->dc.md4pw, mach_name, mach_acct)) {
- /* copy the client credentials */
- memcpy(vuser->dc.clnt_chal.data , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
- memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data));
-
- /* create a server challenge for the client */
- /* Set these to random values. */
- generate_random_buffer(vuser->dc.srv_chal.data, 8, False);
-
- memcpy(vuser->dc.srv_cred.challenge.data, vuser->dc.srv_chal.data, 8);
-
- memset((char *)vuser->dc.sess_key, '\0', sizeof(vuser->dc.sess_key));
-
- /* from client / server challenges and md4 password, generate sess key */
- cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal),
- (char *)vuser->dc.md4pw, vuser->dc.sess_key);
- } else {
- /* lkclXXXX take a guess at a good error message to return :-) */
- status = 0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;
- }
-
- /* construct reply. */
- if(!net_reply_req_chal(&q_r, rdata, &vuser->dc.srv_chal, status))
- return False;
-
- return True;
-}
-
-/*************************************************************************
- api_net_auth_2:
- *************************************************************************/
-
-static BOOL api_net_auth_2( uint16 vuid, prs_struct *data, prs_struct *rdata)
-{
- NET_Q_AUTH_2 q_a;
- uint32 status = 0x0;
-
- DOM_CHAL srv_cred;
- UTIME srv_time;
-
- user_struct *vuser;
-
- if ((vuser = get_valid_user_struct(vuid)) == NULL)
- return False;
+ ZERO_STRUCT(q_l);
+ ZERO_STRUCT(r_s);
- srv_time.time = 0;
+ /* the DOM_ID_INFO_1 structure is a bit big. plus we might want to
+ dynamically allocate it inside net_io_q_sam_logon, at some point */
+ q_l.sam_id.ctr = &ctr;
/* grab the challenge... */
- if(!net_io_q_auth_2("", &q_a, data, 0)) {
- DEBUG(0,("api_net_auth_2: Failed to unmarshall NET_Q_AUTH_2.\n"));
+ if (!net_io_q_sam_logoff("", &q_l, data, 0))
+ {
return False;
}
- /* check that the client credentials are valid */
- if (cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key,
- &(vuser->dc.clnt_cred.challenge), srv_time)) {
+ status = _net_sam_logoff(&q_l.sam_id,
+ &srv_cred,
+ p->key.pid); /* strikerXXXX have to pass this parameter */
+ make_r_sam_logoff(&r_s, &srv_cred, status);
- /* create server challenge for inclusion in the reply */
- cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred);
-
- /* copy the received client credentials for use next time */
- memcpy(vuser->dc.clnt_cred.challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
- memcpy(vuser->dc.srv_cred .challenge.data, q_a.clnt_chal.data, sizeof(q_a.clnt_chal.data));
- } else {
- status = NT_STATUS_ACCESS_DENIED | 0xC0000000;
- }
-
- /* construct reply. */
- if(!net_reply_auth_2(&q_a, rdata, &srv_cred, status))
- return False;
-
- return True;
+ /* store the response in the SMB stream */
+ return net_io_r_sam_logoff("", &r_s, rdata, 0);
}
-
-/*************************************************************************
- api_net_srv_pwset:
- *************************************************************************/
-
-static BOOL api_net_srv_pwset( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static uint32 net_update_creds(uint32 remote_pid, struct dcinfo *dc,
+ const UNISTR2 *uni_cli_name,
+ const DOM_CRED *cli_creds,
+ const DOM_CRED *ret_creds,
+ DOM_CRED *srv_creds)
{
- NET_Q_SRV_PWSET q_a;
- uint32 status = NT_STATUS_WRONG_PASSWORD|0xC0000000;
- DOM_CRED srv_cred;
- pstring mach_acct;
- struct smb_passwd *smb_pass;
- BOOL ret;
- user_struct *vuser;
+ fstring trust_name;
- if ((vuser = get_valid_user_struct(vuid)) == NULL)
- return False;
+ unistr2_to_ascii(trust_name, uni_cli_name, sizeof(trust_name)-1);
- /* grab the challenge and encrypted password ... */
- if(!net_io_q_srv_pwset("", &q_a, data, 0)) {
- DEBUG(0,("api_net_srv_pwset: Failed to unmarshall NET_Q_SRV_PWSET.\n"));
- return False;
+ if (!cred_get(remote_pid, global_sam_name, trust_name, dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
}
/* checks and updates credentials. creates reply credentials */
- if (deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
- &(q_a.clnt_id.cred), &srv_cred))
+ if (!deal_with_creds(dc->sess_key, &dc->clnt_cred, cli_creds, srv_creds))
{
- memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
-
- DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
-
- pstrcpy(mach_acct, dos_unistrn2(q_a.clnt_id.login.uni_acct_name.buffer,
- q_a.clnt_id.login.uni_acct_name.uni_str_len));
-
- DEBUG(3,("Server Password Set Wksta:[%s]\n", mach_acct));
-
- become_root(True);
- smb_pass = getsmbpwnam(mach_acct);
- unbecome_root(True);
-
- if (smb_pass != NULL) {
- unsigned char pwd[16];
- int i;
-
- DEBUG(100,("Server password set : new given value was :\n"));
- for(i = 0; i < 16; i++)
- DEBUG(100,("%02X ", q_a.pwd[i]));
- DEBUG(100,("\n"));
-
- cred_hash3( pwd, q_a.pwd, vuser->dc.sess_key, 0);
-
- /* lies! nt and lm passwords are _not_ the same: don't care */
- smb_pass->smb_passwd = pwd;
- smb_pass->smb_nt_passwd = pwd;
- smb_pass->acct_ctrl = ACB_WSTRUST;
-
- become_root(True);
- ret = mod_smbpwd_entry(smb_pass,False);
- unbecome_root(True);
-
- if (ret) {
- /* hooray! */
- status = 0x0;
- }
- }
+ return NT_STATUS_ACCESS_DENIED;
+ }
- DEBUG(5,("api_net_srv_pwset: %d\n", __LINE__));
+ memcpy(&dc->srv_cred, &dc->clnt_cred, sizeof(dc->clnt_cred));
- } else {
- /* lkclXXXX take a guess at a sensible error code to return... */
- status = 0xC0000000 | NT_STATUS_NETWORK_CREDENTIAL_CONFLICT;
+ if (!cred_store(remote_pid, global_sam_name, trust_name, dc))
+ {
+ return NT_STATUS_INVALID_HANDLE;
}
- /* Construct reply. */
- if(!net_reply_srv_pwset(&q_a, rdata, &srv_cred, status))
- return False;
-
- return True;
+ return NT_STATUS_NOPROBLEMO;
}
-
/*************************************************************************
- api_net_sam_logoff:
+ api_net_sam_sync
*************************************************************************/
-
-static BOOL api_net_sam_logoff( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_net_sam_sync( rpcsrv_struct *p,
+ prs_struct *data,
+ prs_struct *rdata)
{
- NET_Q_SAM_LOGOFF q_l;
- NET_ID_INFO_CTR ctr;
-
- DOM_CRED srv_cred;
-
- user_struct *vuser;
-
- if ((vuser = get_valid_user_struct(vuid)) == NULL)
- return False;
-
- /* the DOM_ID_INFO_1 structure is a bit big. plus we might want to
- dynamically allocate it inside net_io_q_sam_logon, at some point */
- q_l.sam_id.ctr = &ctr;
-
+ NET_Q_SAM_SYNC q_s;
+ NET_R_SAM_SYNC r_s;
+ DOM_CRED srv_creds;
+ uint32 num_deltas;
+ uint32 num_deltas2;
+ SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS];
+ SAM_DELTA_CTR deltas[MAX_SAM_DELTAS];
+ uint32 status;
+
+ struct dcinfo dc;
+ ZERO_STRUCT(dc);
+ ZERO_STRUCT(srv_creds);
+
/* grab the challenge... */
- if(!net_io_q_sam_logoff("", &q_l, data, 0)) {
- DEBUG(0,("api_net_sam_logoff: Failed to unmarshall NET_Q_SAM_LOGOFF.\n"));
+ if (!net_io_q_sam_sync("", &q_s, data, 0))
+ {
return False;
}
- /* checks and updates credentials. creates reply credentials */
- deal_with_creds(vuser->dc.sess_key, &vuser->dc.clnt_cred,
- &q_l.sam_id.client.cred, &srv_cred);
- memcpy(&vuser->dc.srv_cred, &vuser->dc.clnt_cred, sizeof(vuser->dc.clnt_cred));
-
- /* construct reply. always indicate success */
- if(!net_reply_sam_logoff(&q_l, rdata, &srv_cred, 0x0))
- return False;
-
- return True;
-}
-
-/*************************************************************************
- net_login_interactive:
- *************************************************************************/
-
-static uint32 net_login_interactive(NET_ID_INFO_1 *id1, struct smb_passwd *smb_pass,
- user_struct *vuser)
-{
- uint32 status = 0x0;
-
- char nt_pwd[16];
- char lm_pwd[16];
- unsigned char key[16];
-
- memset(key, 0, 16);
- memcpy(key, vuser->dc.sess_key, 8);
-
- memcpy(lm_pwd, id1->lm_owf.data, 16);
- memcpy(nt_pwd, id1->nt_owf.data, 16);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("key:"));
- dump_data(100, (char *)key, 16);
-
- DEBUG(100,("lm owf password:"));
- dump_data(100, lm_pwd, 16);
- DEBUG(100,("nt owf password:"));
- dump_data(100, nt_pwd, 16);
-#endif
+ status = net_update_creds(p->key.pid,
+ &dc, &q_s.uni_cli_name,
+ &q_s.cli_creds,
+ &q_s.ret_creds,
+ &srv_creds);
- SamOEMhash((uchar *)lm_pwd, key, False);
- SamOEMhash((uchar *)nt_pwd, key, False);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("decrypt of lm owf password:"));
- dump_data(100, lm_pwd, 16);
-
- DEBUG(100,("decrypt of nt owf password:"));
- dump_data(100, nt_pwd, 16);
-#endif
-
- if (memcmp(smb_pass->smb_passwd , lm_pwd, 16) != 0 ||
- memcmp(smb_pass->smb_nt_passwd, nt_pwd, 16) != 0)
+ if (status == 0x0)
{
- status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
+ status = _net_sam_sync(&q_s.uni_srv_name,
+ &q_s.uni_cli_name,
+ q_s.database_id,
+ q_s.restart_state,
+ &q_s.sync_context,
+ q_s.max_size,
+ &num_deltas,
+ &num_deltas2,
+ hdr_deltas,
+ deltas);
}
- return status;
+ make_r_sam_sync(&r_s, &srv_creds,
+ q_s.sync_context,
+ num_deltas,
+ num_deltas2,
+ hdr_deltas,
+ deltas,
+ status);
+
+ /* store the response in the SMB stream */
+ return net_io_r_sam_sync("", dc.sess_key, &r_s, rdata, 0);
}
/*************************************************************************
- net_login_network:
+ api_net_sam_logon
*************************************************************************/
-
-static uint32 net_login_network(NET_ID_INFO_2 *id2, struct smb_passwd *smb_pass)
+static BOOL api_net_sam_logon( rpcsrv_struct *p,
+ prs_struct *data,
+ prs_struct *rdata)
{
- DEBUG(5,("net_login_network: lm_len: %d nt_len: %d\n",
- id2->hdr_lm_chal_resp.str_str_len,
- id2->hdr_nt_chal_resp.str_str_len));
-
- /* JRA. Check the NT password first if it exists - this is a higher quality
- password, if it exists and it doesn't match - fail. */
-
- if (id2->hdr_nt_chal_resp.str_str_len == 24 &&
- smb_pass->smb_nt_passwd != NULL)
- {
- if(smb_password_check((char *)id2->nt_chal_resp.buffer,
- smb_pass->smb_nt_passwd,
- id2->lm_chal))
- return 0x0;
- else
- return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
- }
-
- /* lkclXXXX this is not a good place to put disabling of LM hashes in.
- if that is to be done, first move this entire function into a
- library routine that calls the two smb_password_check() functions.
- if disabling LM hashes (which nt can do for security reasons) then
- an attempt should be made to disable them everywhere (which nt does
- not do, for various security-hole reasons).
- */
-
- if (id2->hdr_lm_chal_resp.str_str_len == 24 &&
- smb_password_check((char *)id2->lm_chal_resp.buffer,
- smb_pass->smb_passwd,
- id2->lm_chal))
+ NET_Q_SAM_LOGON q_l;
+ NET_R_SAM_LOGON r_s;
+ NET_ID_INFO_CTR ctr;
+ DOM_CRED srv_creds;
+ uint16 switch_value;
+ NET_USER_INFO_3 info_3;
+ uint32 status;
+
+ ZERO_STRUCT(info_3);
+ ZERO_STRUCT(q_l);
+ ZERO_STRUCT(r_s);
+
+ q_l.sam_id.ctr = &ctr; /* strikerXXXX don't really get this */
+ if (!net_io_q_sam_logon("", &q_l, data, 0))
{
- return 0x0;
+ return False;
}
+ status = _net_sam_logon(&q_l.sam_id,
+ q_l.validation_level,
+ &srv_creds,
+ &switch_value,
+ &info_3,
+ p->key.pid);
+ make_r_sam_logon(&r_s, &srv_creds, switch_value,
+ status == NT_STATUS_NOPROBLEMO ? &info_3 : NULL,
+ status);
- /* oops! neither password check succeeded */
-
- return 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
-}
-
-/*************************************************************************
- api_net_sam_logon:
- *************************************************************************/
-
-static BOOL api_net_sam_logon( uint16 vuid, prs_struct *data, prs_struct *rdata)
-{
- NET_Q_SAM_LOGON q_l;
- NET_ID_INFO_CTR ctr;
- NET_USER_INFO_3 usr_info;
- uint32 status = 0x0;
- DOM_CRED srv_cred;
- struct smb_passwd *smb_pass = NULL;
- UNISTR2 *uni_samlogon_user = NULL;
- fstring nt_username;
-
- user_struct *vuser = NULL;
-
- if ((vuser = get_valid_user_struct(vuid)) == NULL)
- return False;
-
- memset(&q_l, '\0', sizeof(q_l));
- memset(&ctr, '\0', sizeof(ctr));
- memset(&usr_info, '\0', sizeof(usr_info));
-
- q_l.sam_id.ctr = &ctr;
-
- if(!net_io_q_sam_logon("", &q_l, data, 0)) {
- DEBUG(0,("api_net_sam_logon: Failed to unmarshall NET_Q_SAM_LOGON.\n"));
- return False;
- }
-
- /* checks and updates credentials. creates reply credentials */
- if (!deal_with_creds(vuser->dc.sess_key, &(vuser->dc.clnt_cred),
- &(q_l.sam_id.client.cred), &srv_cred))
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- else
- memcpy(&(vuser->dc.srv_cred), &(vuser->dc.clnt_cred), sizeof(vuser->dc.clnt_cred));
-
- /* find the username */
-
- if (status == 0) {
- switch (q_l.sam_id.logon_level) {
- case INTERACTIVE_LOGON_TYPE:
- uni_samlogon_user = &q_l.sam_id.ctr->auth.id1.uni_user_name;
-
- DEBUG(3,("SAM Logon (Interactive). Domain:[%s]. ", lp_workgroup()));
- break;
- case NET_LOGON_TYPE:
- uni_samlogon_user = &q_l.sam_id.ctr->auth.id2.uni_user_name;
-
- DEBUG(3,("SAM Logon (Network). Domain:[%s]. ", lp_workgroup()));
- break;
- default:
- DEBUG(2,("SAM Logon: unsupported switch value\n"));
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- break;
- } /* end switch */
- } /* end if status == 0 */
-
- /* check username exists */
-
- if (status == 0) {
- pstrcpy(nt_username, dos_unistrn2(uni_samlogon_user->buffer,
- uni_samlogon_user->uni_str_len));
-
- DEBUG(3,("User:[%s]\n", nt_username));
-
- /*
- * Convert to a UNIX username.
- */
- map_username(nt_username);
-
- /*
- * Do any case conversions.
- */
- (void)Get_Pwnam(nt_username, True);
-
- become_root(True);
- smb_pass = getsmbpwnam(nt_username);
- unbecome_root(True);
-
- if (smb_pass == NULL)
- status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
- else if (smb_pass->acct_ctrl & ACB_PWNOTREQ)
- status = 0;
- else if (smb_pass->acct_ctrl & ACB_DISABLED)
- status = 0xC0000000 | NT_STATUS_ACCOUNT_DISABLED;
- }
-
- /* Validate password - if required. */
-
- if ((status == 0) && !(smb_pass->acct_ctrl & ACB_PWNOTREQ)) {
- switch (q_l.sam_id.logon_level) {
- case INTERACTIVE_LOGON_TYPE:
- /* interactive login. */
- status = net_login_interactive(&q_l.sam_id.ctr->auth.id1, smb_pass, vuser);
- break;
- case NET_LOGON_TYPE:
- /* network login. lm challenge and 24 byte responses */
- status = net_login_network(&q_l.sam_id.ctr->auth.id2, smb_pass);
- break;
- }
- }
-
- /* lkclXXXX this is the point at which, if the login was
- successful, that the SAM Local Security Authority should
- record that the user is logged in to the domain.
- */
-
- /* return the profile plus other bits :-) */
-
- if (status == 0) {
- DOM_GID *gids = NULL;
- int num_gids = 0;
- NTTIME dummy_time;
- pstring logon_script;
- pstring profile_path;
- pstring home_dir;
- pstring home_drive;
- pstring my_name;
- pstring my_workgroup;
- pstring domain_groups;
- uint32 r_uid;
- uint32 r_gid;
-
- /* set up pointer indicating user/password failed to be found */
- usr_info.ptr_user_info = 0;
-
- dummy_time.low = 0xffffffff;
- dummy_time.high = 0x7fffffff;
-
- /* XXXX hack to get standard_sub_basic() to use sam logon username */
- /* possibly a better way would be to do a become_user() call */
- sam_logon_in_ssb = True;
- pstrcpy(samlogon_user, nt_username);
-
- pstrcpy(logon_script, lp_logon_script());
- pstrcpy(profile_path, lp_logon_path());
-
- pstrcpy(my_workgroup, lp_workgroup());
-
- pstrcpy(home_drive, lp_logon_drive());
- pstrcpy(home_dir, lp_logon_home());
-
- pstrcpy(my_name, global_myname);
- strupper(my_name);
-
- /*
- * This is the point at which we get the group
- * database - we should be getting the gid_t list
- * from /etc/group and then turning the uids into
- * rids and then into machine sids for this user.
- * JRA.
- */
-
- get_domain_user_groups(domain_groups, nt_username);
-
- /*
- * make_dom_gids allocates the gids array. JRA.
- */
- gids = NULL;
- num_gids = make_dom_gids(domain_groups, &gids);
-
- sam_logon_in_ssb = False;
-
- if (pdb_name_to_rid(nt_username, &r_uid, &r_gid))
- init_net_user_info3(&usr_info,
- &dummy_time, /* logon_time */
- &dummy_time, /* logoff_time */
- &dummy_time, /* kickoff_time */
- &dummy_time, /* pass_last_set_time */
- &dummy_time, /* pass_can_change_time */
- &dummy_time, /* pass_must_change_time */
-
- nt_username , /* user_name */
- vuser->real_name, /* full_name */
- logon_script , /* logon_script */
- profile_path , /* profile_path */
- home_dir , /* home_dir */
- home_drive , /* dir_drive */
-
- 0, /* logon_count */
- 0, /* bad_pw_count */
-
- r_uid , /* RID user_id */
- r_gid , /* RID group_id */
- num_gids, /* uint32 num_groups */
- gids , /* DOM_GID *gids */
- 0x20 , /* uint32 user_flgs (?) */
-
- NULL, /* char sess_key[16] */
-
- my_name , /* char *logon_srv */
- my_workgroup, /* char *logon_dom */
-
- &global_sam_sid, /* DOM_SID *dom_sid */
- NULL); /* char *other_sids */
- else
- status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
-
- /* Free any allocated groups array. */
- if(gids)
- free((char *)gids);
- }
-
- if(!net_reply_sam_logon(&q_l, rdata, &srv_cred, &usr_info, status))
- return False;
-
- return True;
+ /* store the response in the SMB stream */
+ return net_io_r_sam_logon("", &r_s, rdata, 0);
}
-
/*************************************************************************
- api_net_trust_dom_list:
+ api_net_trust_dom_list
*************************************************************************/
-
-static BOOL api_net_trust_dom_list( uint16 vuid,
- prs_struct *data,
- prs_struct *rdata)
+static BOOL api_net_trust_dom_list( rpcsrv_struct *p,
+ prs_struct *data,
+ prs_struct *rdata)
{
NET_Q_TRUST_DOM_LIST q_t;
+ NET_R_TRUST_DOM_LIST r_t;
- char *trusted_domain = "test_domain";
-
- DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
+ ZERO_STRUCT(q_t);
+ ZERO_STRUCT(r_t);
/* grab the lsa trusted domain list query... */
- if(!net_io_q_trust_dom("", &q_t, data, 0)) {
- DEBUG(0,("api_net_trust_dom_list: Failed to unmarshall NET_Q_TRUST_DOM_LIST.\n"));
+ if (!net_io_q_trust_dom("", &q_t, data, 0))
+ {
return False;
}
- /* construct reply. */
- if(!net_reply_trust_dom_list(&q_t, rdata, 1, trusted_domain))
- return False;
-
- DEBUG(6,("api_net_trust_dom_list: %d\n", __LINE__));
-
- return True;
+ r_t.status = _net_trust_dom_list(&q_t.uni_server_name,
+ q_t.function_code,
+ &r_t.uni_trust_dom_name);
+
+ /* store the response in the SMB stream */
+ return net_io_r_trust_dom("", &r_t, rdata, 0);
}
-
-/*************************************************************************
- error messages cropping up when using nltest.exe...
- *************************************************************************/
-#define ERROR_NO_SUCH_DOMAIN 0x54b
-#define ERROR_NO_LOGON_SERVERS 0x51f
-
/*************************************************************************
- api_net_logon_ctrl2:
+ api_net_logon_ctrl2
*************************************************************************/
-
-static BOOL api_net_logon_ctrl2( uint16 vuid,
+static BOOL api_net_logon_ctrl2( rpcsrv_struct *p,
prs_struct *data,
prs_struct *rdata)
{
NET_Q_LOGON_CTRL2 q_l;
+ NET_R_LOGON_CTRL2 r_l;
- /* lkclXXXX - guess what - absolutely no idea what these are! */
- uint32 flags = 0x0;
- uint32 pdc_connection_status = 0x0;
- uint32 logon_attempts = 0x0;
- uint32 tc_status = ERROR_NO_LOGON_SERVERS;
- char *trusted_domain = "test_domain";
+ NETLOGON_INFO logon_info;
+ uint32 switch_value;
+ uint32 status;
- DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
+ ZERO_STRUCT(q_l);
+ ZERO_STRUCT(r_l);
/* grab the lsa netlogon ctrl2 query... */
- if(!net_io_q_logon_ctrl2("", &q_l, data, 0)) {
- DEBUG(0,("api_net_logon_ctrl2: Failed to unmarshall NET_Q_LOGON_CTRL2.\n"));
+ if (!net_io_q_logon_ctrl2("", &q_l, data, 0))
+ {
return False;
}
- /* construct reply. */
- if(!net_reply_logon_ctrl2(&q_l, rdata,
- flags, pdc_connection_status, logon_attempts,
- tc_status, trusted_domain))
- return False;
+ status = _net_logon_ctrl2(&q_l.uni_server_name,
+ q_l.function_code,
+ q_l.query_level,
+ q_l.switch_value,
+ &switch_value,
+ &logon_info);
+ make_r_logon_ctrl2(&r_l, switch_value, &logon_info, status);
- DEBUG(6,("api_net_logon_ctrl2: %d\n", __LINE__));
-
- return True;
+ /* store the response in the SMB stream */
+ return net_io_r_logon_ctrl2("", &r_l, rdata, 0);
}
/*******************************************************************
array of \PIPE\NETLOGON operations
********************************************************************/
-static struct api_struct api_net_cmds [] =
+static const struct api_struct api_net_cmds [] =
{
{ "NET_REQCHAL" , NET_REQCHAL , api_net_req_chal },
+ { "NET_AUTH" , NET_AUTH , api_net_auth },
{ "NET_AUTH2" , NET_AUTH2 , api_net_auth_2 },
{ "NET_SRVPWSET" , NET_SRVPWSET , api_net_srv_pwset },
{ "NET_SAMLOGON" , NET_SAMLOGON , api_net_sam_logon },
{ "NET_SAMLOGOFF" , NET_SAMLOGOFF , api_net_sam_logoff },
{ "NET_LOGON_CTRL2" , NET_LOGON_CTRL2 , api_net_logon_ctrl2 },
{ "NET_TRUST_DOM_LIST", NET_TRUST_DOM_LIST, api_net_trust_dom_list },
- { NULL , 0 , NULL }
+ { "NET_SAM_SYNC" , NET_SAM_SYNC , api_net_sam_sync },
+ { NULL , 0 , NULL }
};
/*******************************************************************
receives a netlogon pipe and responds.
********************************************************************/
-
-BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data)
+BOOL api_netlog_rpc(rpcsrv_struct *p)
{
- return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds, data);
+ return api_rpcTNP(p, "api_netlog_rpc", api_net_cmds);
}
diff --git a/source/rpc_server/srv_pipe.c b/source/rpc_server/srv_pipe.c
index f8439de9a77..58367660f25 100644
--- a/source/rpc_server/srv_pipe.c
+++ b/source/rpc_server/srv_pipe.c
@@ -22,22 +22,6 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* this module apparently provides an implementation of DCE/RPC over a
- * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
- * documentation are available (in on-line form) from the X-Open group.
- *
- * this module should provide a level of abstraction between SMB
- * and DCE/RPC, while minimising the amount of mallocs, unnecessary
- * data copies, and network traffic.
- *
- * in this version, which takes a "let's learn what's going on and
- * get something running" approach, there is additional network
- * traffic generated, but the code should be easier to understand...
- *
- * ... if you read the docs. or stare at packets for weeks on end.
- *
- */
-
#include "includes.h"
#include "nterr.h"
@@ -49,8 +33,13 @@ extern int DEBUGLEVEL;
case of the RPC_BINDCONT pdu).
********************************************************************/
BOOL readwrite_pipe(pipes_struct *p, char *data, int len,
- char **rdata, int *rlen)
+ char **rdata, int *rlen,
+ BOOL *pipe_outstanding)
{
+ fd_set fds;
+ int selrtn;
+ struct timeval timeout;
+
DEBUG(10,("rpc_to_smb_readwrite: len %d\n", len));
if (write(p->m->fd, data, len) != len)
@@ -69,10 +58,9 @@ BOOL readwrite_pipe(pipes_struct *p, char *data, int len,
return False;
}
- /* read a minimum of an rpc header, then wait for up to 10 seconds
- * to read up to a maximum of the SMBtrans max data size
- */
- (*rlen) = read_with_timeout(p->m->fd, (*rdata), 16, (*rlen), 10000);
+ /* compromise. MUST read a minimum of an rpc header.
+ * timeout waiting for the rest for 10 seconds */
+ (*rlen) = read_with_timeout(p->m->fd, (*rdata), 16,(*rlen), 10000);
if ((*rlen) < 0)
{
return False;
@@ -82,17 +70,42 @@ BOOL readwrite_pipe(pipes_struct *p, char *data, int len,
{
return False;
}
+
+ /* now check whether there is outstanding data on the pipe.
+ * this is needed to as to report a STATUS message back to
+ * the NT client. yes, NT clients fail to operate if you
+ * don't set a STATUS_BUFFER_OVERFLOW warning on the SMBtrans
+ * response. *dur*! what's msrpc got to do with smb, ANYWAY!!
+ */
+
+ FD_ZERO(&fds);
+ FD_SET(p->m->fd,&fds);
+
+ /* Set initial timeout to zero */
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ selrtn = sys_select(p->m->fd+1,&fds,NULL, &timeout);
+
+ /* Check if error */
+ if (selrtn == -1)
+ {
+ /* something is wrong. Maybe the socket is dead? */
+ return -1;
+ }
+
+ *pipe_outstanding = FD_ISSET(p->m->fd, &fds);
+
return True;
}
/****************************************************************************
- writes data to a pipe.
- ****************************************************************************/
+writes data to a pipe.
+****************************************************************************/
ssize_t write_pipe(pipes_struct *p, char *data, size_t n)
{
DEBUG(6,("write_pipe: %x", p->pnum));
- DEBUG(6,("name: %s open: %s len: %d",
- p->name, BOOLSTR(p->open), n));
+ DEBUG(6,("name: %s len: %d", p->name, n));
dump_data(50, data, n);
@@ -110,15 +123,15 @@ ssize_t write_pipe(pipes_struct *p, char *data, size_t n)
****************************************************************************/
int read_pipe(pipes_struct *p, char *data, int n)
{
- DEBUG(6,("read_pipe: %x name: %s open: %s len: %d",
- p->pnum, p->name, BOOLSTR(p->open), n));
+ DEBUG(6,("read_pipe: %x name: %s len: %d", p->pnum, p->name, n));
- if (!p || !p->open)
+ if (!p)
{
DEBUG(6,("pipe not open\n"));
return -1;
}
- return read_data(p->m->fd, data, n);
+ /* read a minimum of 1 byte! :-) */
+ return read_with_timeout(p->m->fd, data, 1, n, 10000);
}
diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c
index 32a804d5d58..db1f1676157 100644
--- a/source/rpc_server/srv_pipe_hnd.c
+++ b/source/rpc_server/srv_pipe_hnd.c
@@ -5,7 +5,6 @@
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Jeremy Allison 1999.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,6 +23,7 @@
#include "includes.h"
+#include "rpc_parse.h"
#define PIPE "\\PIPE\\"
@@ -49,14 +49,14 @@ static int pipe_handle_offset;
void set_pipe_handle_offset(int max_open_files)
{
- if(max_open_files < 0x7000)
- pipe_handle_offset = 0x7000;
- else
- pipe_handle_offset = max_open_files + 10; /* For safety. :-) */
+ if (max_open_files < 0x7000)
+ pipe_handle_offset = 0x7000;
+ else
+ pipe_handle_offset = max_open_files + 10; /* For safety. :-) */
}
/****************************************************************************
- Reset pipe chain handle number.
+ reset pipe chain handle number
****************************************************************************/
void reset_chain_p(void)
{
@@ -64,132 +64,79 @@ void reset_chain_p(void)
}
/****************************************************************************
- Initialise pipe handle states.
+ initialise pipe handle states...
****************************************************************************/
-
void init_rpc_pipe_hnd(void)
{
bmap = bitmap_allocate(MAX_OPEN_PIPES);
if (!bmap)
+ {
exit_server("out of memory in init_rpc_pipe_hnd\n");
-}
-
-/****************************************************************************
- Initialise an outgoing packet.
-****************************************************************************/
-
-BOOL pipe_init_outgoing_data(output_data *out_data)
-{
-
- memset(out_data->current_pdu, '\0', sizeof(out_data->current_pdu));
-
- /* Free any memory in the current return data buffer. */
- prs_mem_free(&out_data->rdata);
-
- /*
- * Initialize the outgoing RPC data buffer.
- * we will use this as the raw data area for replying to rpc requests.
- */
- if(!prs_init(&out_data->rdata, 1024, 4, MARSHALL)) {
- DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
- return False;
}
-
- /* Reset the offset counters. */
- out_data->data_sent_length = 0;
- out_data->current_pdu_len = 0;
- out_data->current_pdu_sent = 0;
-
- return True;
}
+
/****************************************************************************
- Find first available pipe slot.
+ find first available file slot
****************************************************************************/
-
-pipes_struct *open_rpc_pipe_p(char *pipe_name,
- connection_struct *conn, uint16 vuid)
+pipes_struct *open_rpc_pipe_p(char *pipe_name, const vuser_key * key,
+ rpcsrv_struct * l)
{
int i;
pipes_struct *p;
static int next_pipe;
- struct msrpc_state *m = NULL;
- user_struct *vuser = get_valid_user_struct(vuid);
- struct user_creds usr;
+ struct msrpc_local *m = NULL;
- ZERO_STRUCT(usr);
+ DEBUG(4, ("Open pipe requested %s by [%d,%x] (pipes_open=%d)\n",
+ pipe_name, key->pid, key->vuid, pipes_open));
- DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
- pipe_name, pipes_open));
-
- if (vuser == NULL)
+ if (!is_valid_user_struct(key))
{
- DEBUG(4,("invalid vuid %d\n", vuid));
+ DEBUG(4, ("invalid vuid\n"));
return NULL;
}
- /* set up unix credentials from the smb side, to feed over the pipe */
- make_creds_unix(&usr.uxc, vuser->name, vuser->requested_name,
- vuser->real_name, vuser->guest);
- usr.ptr_uxc = 1;
- make_creds_unix_sec(&usr.uxs, vuser->uid, vuser->gid,
- vuser->n_groups, vuser->groups);
- usr.ptr_uxs = 1;
-
- usr.ptr_ssk = 1;
- DEBUG(0,("user session key not available (yet).\n"));
- DEBUG(0,("password-change operations may fail.\n"));
-
-#if USER_SESSION_KEY_DEFINED_IN_VUSER_STRUCT
- memcpy(usr.usr_sess_key, vuser->usr_sess_key, sizeof(usr.usr_sess_key));
-#else
- memset(usr.usr_sess_key, 0, sizeof(usr.usr_sess_key));
-#endif
-
- /* set up nt credentials from the smb side, to feed over the pipe */
- /* lkclXXXX todo!
- make_creds_nt(&usr.ntc);
- make_creds_nt_sec(&usr.nts);
- */
-
- become_root(False); /* to connect to pipe */
- m = msrpc_use_add(pipe_name, getpid(), &usr, False);
- unbecome_root(False);
-
- if (m == NULL)
- {
- DEBUG(10,("open pipes: msrpc redirect failed - go local.\n"));
- }
-
/* not repeating pipe numbers makes it easier to track things in
log files and prevents client bugs where pipe numbers are reused
over connection restarts */
if (next_pipe == 0)
- next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
+ {
+ next_pipe = (key->pid ^ time(NULL)) % MAX_OPEN_PIPES;
+ }
i = bitmap_find(bmap, next_pipe);
- if (i == -1) {
- DEBUG(0,("ERROR! Out of pipe structures\n"));
+ if (i == -1)
+ {
+ DEBUG(0, ("ERROR! Out of pipe structures\n"));
return NULL;
}
- next_pipe = (i+1) % MAX_OPEN_PIPES;
+ next_pipe = (i + 1) % MAX_OPEN_PIPES;
for (p = Pipes; p; p = p->next)
- DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
+ {
+ DEBUG(5, ("open pipes: name %s pnum=%x\n", p->name, p->pnum));
+ }
- p = (pipes_struct *)malloc(sizeof(*p));
+ if (l == NULL)
+ {
+ BOOL is_new;
+ become_root(False); /* to make pipe connection */
+ m = ncalrpc_l_use_add(pipe_name, key, True, True, &is_new);
+ unbecome_root(False);
+ if (m == NULL)
+ {
+ DEBUG(5, ("open pipes: msrpc redirect failed\n"));
+ return NULL;
+ }
+ }
+
+ p = (pipes_struct *) malloc(sizeof(*p));
if (!p)
return NULL;
ZERO_STRUCTP(p);
-
- /*
- * Initialize the RPC and PDU data buffers with no memory.
- */
- prs_init(&p->out_data.rdata, 0, 4, MARSHALL);
-
DLIST_ADD(Pipes, p);
bitmap_set(bmap, i);
@@ -198,255 +145,101 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
pipes_open++;
p->pnum = i;
+ p->m = m;
+ p->l = l;
- p->open = True;
p->device_state = 0;
p->priority = 0;
- p->conn = conn;
- p->vuid = vuid;
-
- p->m = m;
+ p->key = *key;
- p->max_trans_reply = 0;
-
- p->ntlmssp_chal_flags = 0;
- p->ntlmssp_auth_validated = False;
- p->ntlmssp_auth_requested = False;
+ fstrcpy(p->name, pipe_name);
- p->out_data.current_pdu_len = 0;
- p->out_data.current_pdu_sent = 0;
- p->out_data.data_sent_length = 0;
+ DEBUG(4, ("Opened pipe %s with handle %x (pipes_open=%d)\n",
+ pipe_name, i, pipes_open));
- p->uid = (uid_t)-1;
- p->gid = (gid_t)-1;
-
- fstrcpy(p->name, pipe_name);
-
- DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
- pipe_name, i, pipes_open));
-
chain_p = p;
-
- /* OVERWRITE p as a temp variable, to display all open pipes */
+
+ /* OVERWRITE p as a temp variable, to display all open pipes */
for (p = Pipes; p; p = p->next)
- DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
+ {
+ DEBUG(5, ("open pipes: name %s pnum=%x\n", p->name, p->pnum));
+ }
return chain_p;
}
-/****************************************************************************
- Accepts incoming data on an rpc pipe.
-
- This code is probably incorrect at the moment. The problem is
- that the rpc request shouldn't really be executed until all the
- data needed for it is received. This currently assumes that each
- SMBwrite or SMBwriteX contains all the data needed for an rpc
- request. JRA.
- ****************************************************************************/
-
-ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
-{
- DEBUG(6,("write_to_pipe: %x", p->pnum));
-
- DEBUG(6,("name: %s open: %s len: %d",
- p->name, BOOLSTR(p->open), (int)n));
-
- dump_data(50, data, n);
-
- return rpc_command(p, data, (int)n) ? ((ssize_t)n) : -1;
-}
-
-
-/****************************************************************************
- Replyies to a request to read data from a pipe.
-
- Headers are interspersed with the data at PDU intervals. By the time
- this function is called, the start of the data could possibly have been
- read by an SMBtrans (file_offset != 0).
-
- Calling create_rpc_reply() here is a hack. The data should already
- have been prepared into arrays of headers + data stream sections.
-
- ****************************************************************************/
-
-int read_from_pipe(pipes_struct *p, char *data, int n)
-{
- uint32 pdu_remaining = 0;
- int data_returned = 0;
-
- if (!p || !p->open) {
- DEBUG(0,("read_from_pipe: pipe not open\n"));
- return -1;
- }
-
- DEBUG(6,("read_from_pipe: %x", p->pnum));
-
- DEBUG(6,("name: %s len: %d\n", p->name, n));
-
- /*
- * We cannot return more than one PDU length per
- * read request.
- */
-
- if(n > MAX_PDU_FRAG_LEN) {
- DEBUG(0,("read_from_pipe: loo large read (%d) requested on pipe %s. We can \
-only service %d sized reads.\n", n, p->name, MAX_PDU_FRAG_LEN ));
- return -1;
- }
-
- /*
- * Determine if there is still data to send in the
- * pipe PDU buffer. Always send this first. Never
- * send more than is left in the current PDU. The
- * client should send a new read request for a new
- * PDU.
- */
-
- if((pdu_remaining = p->out_data.current_pdu_len - p->out_data.current_pdu_sent) > 0) {
- data_returned = MIN(n, pdu_remaining);
-
- DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, current_pdu_sent = %u \
-returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
- (unsigned int)p->out_data.current_pdu_sent, (int)data_returned));
-
- memcpy( data, &p->out_data.current_pdu[p->out_data.current_pdu_sent], (size_t)data_returned);
- p->out_data.current_pdu_sent += (uint32)data_returned;
- return data_returned;
- }
-
- /*
- * At this point p->current_pdu_len == p->current_pdu_sent (which
- * may of course be zero if this is the first return fragment.
- */
-
- DEBUG(10,("read_from_pipe: %s: data_sent_length = %u, prs_offset(&p->out_data.rdata) = %u.\n",
- p->name, (unsigned int)p->out_data.data_sent_length, (unsigned int)prs_offset(&p->out_data.rdata) ));
-
- if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
- /*
- * We have sent all possible data. Return 0.
- */
- return 0;
- }
-
- /*
- * We need to create a new PDU from the data left in p->rdata.
- * Create the header/data/footers. This also sets up the fields
- * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
- * and stores the outgoing PDU in p->current_pdu.
- */
-
- if(!create_next_pdu(p)) {
- DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
- p->name));
- return -1;
- }
-
- data_returned = MIN(n, p->out_data.current_pdu_len);
-
- memcpy( data, p->out_data.current_pdu, (size_t)data_returned);
- p->out_data.current_pdu_sent += (uint32)data_returned;
- return data_returned;
-}
/****************************************************************************
- Wait device state on a pipe. Exactly what this is for is unknown...
+ wait device state on a pipe. exactly what this is for is unknown...
****************************************************************************/
-
-BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
+BOOL wait_rpc_pipe_hnd_state(pipes_struct * p, uint16 priority)
{
if (p == NULL)
return False;
- if (p->open) {
- DEBUG(3,("wait_rpc_pipe_hnd_state: Setting pipe wait state priority=%x on pipe (name=%s)\n",
- priority, p->name));
-
- p->priority = priority;
-
- return True;
- }
+ DEBUG(3,
+ ("%s Setting pipe wait state priority=%x on pipe (name=%s)\n",
+ timestring(), priority, p->name));
- DEBUG(3,("wait_rpc_pipe_hnd_state: Error setting pipe wait state priority=%x (name=%s)\n",
- priority, p->name));
- return False;
+ p->priority = priority;
+ return True;
}
/****************************************************************************
- Set device state on a pipe. Exactly what this is for is unknown...
+ set device state on a pipe. exactly what this is for is unknown...
****************************************************************************/
-
-BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
+BOOL set_rpc_pipe_hnd_state(pipes_struct * p, uint16 device_state)
{
if (p == NULL)
return False;
- if (p->open) {
- DEBUG(3,("set_rpc_pipe_hnd_state: Setting pipe device state=%x on pipe (name=%s)\n",
- device_state, p->name));
+ DEBUG(3, ("%s Setting pipe device state=%x on pipe (name=%s)\n",
+ timestring(), device_state, p->name));
- p->device_state = device_state;
-
- return True;
- }
-
- DEBUG(3,("set_rpc_pipe_hnd_state: Error setting pipe device state=%x (name=%s)\n",
- device_state, p->name));
- return False;
+ p->device_state = device_state;
+ return True;
}
-
/****************************************************************************
- Close an rpc pipe.
+ close an rpc pipe
****************************************************************************/
-
-BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
+BOOL close_rpc_pipe_hnd(pipes_struct * p)
{
- if (!p) {
- DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
+ if (!p)
+ {
+ DEBUG(0, ("Invalid pipe in close_rpc_pipe_hnd\n"));
return False;
}
- prs_mem_free(&p->out_data.rdata);
-
bitmap_clear(bmap, p->pnum - pipe_handle_offset);
pipes_open--;
- DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
- p->name, p->pnum, pipes_open));
+ DEBUG(4, ("closed pipe name %s pnum=%x (pipes_open=%d)\n",
+ p->name, p->pnum, pipes_open));
+
+ DLIST_REMOVE(Pipes, p);
if (p->m != NULL)
{
- DEBUG(4,("closed msrpc redirect: "));
- if (msrpc_use_del(p->m->pipe_name, &p->m->usr, False, NULL))
- {
- DEBUG(4,("OK\n"));
- }
- else
- {
- DEBUG(4,("FAILED\n"));
- }
+ DEBUG(4, ("closing msrpc redirect"));
+ ncalrpc_l_use_del(p->name, &p->key, False, NULL);
}
- DLIST_REMOVE(Pipes, p);
-
ZERO_STRUCTP(p);
-
free(p);
-
+
return True;
}
/****************************************************************************
- Find an rpc pipe given a pipe handle in a buffer and an offset.
+ get an rpc pipe
****************************************************************************/
-
pipes_struct *get_rpc_pipe_p(char *buf, int where)
{
- int pnum = SVAL(buf,where);
+ int pnum = SVAL(buf, where);
if (chain_p)
return chain_p;
@@ -455,21 +248,50 @@ pipes_struct *get_rpc_pipe_p(char *buf, int where)
}
/****************************************************************************
- Find an rpc pipe given a pipe handle.
+ get an rpc pipe
****************************************************************************/
+pipes_struct *get_rpc_vuser(const vuser_key * key)
+{
+ pipes_struct *p;
+ DEBUG(4, ("search for pipe vuser [%d,%x]\n", key->pid, key->vuid));
+
+ for (p = Pipes; p; p = p->next)
+ {
+ DEBUG(5, ("pipe name %s [%d,%x] (pipes_open=%d)\n",
+ p->name, p->key.pid, p->key.vuid, pipes_open));
+ }
+
+ for (p = Pipes; p; p = p->next)
+ {
+ if (p->key.pid == key->pid && p->key.vuid == key->vuid)
+ {
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+ close an rpc pipe
+****************************************************************************/
pipes_struct *get_rpc_pipe(int pnum)
{
pipes_struct *p;
- DEBUG(4,("search for pipe pnum=%x\n", pnum));
+ DEBUG(4, ("search for pipe pnum=%x\n", pnum));
- for (p=Pipes;p;p=p->next)
- DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
- p->name, p->pnum, pipes_open));
+ for (p = Pipes; p; p = p->next)
+ {
+ DEBUG(5, ("pipe name %s pnum=%x (pipes_open=%d)\n",
+ p->name, p->pnum, pipes_open));
+ }
- for (p=Pipes;p;p=p->next) {
- if (p->pnum == pnum) {
+ for (p = Pipes; p; p = p->next)
+ {
+ if (p->pnum == pnum)
+ {
chain_p = p;
return p;
}
diff --git a/source/rpc_server/srv_pipe_netsec.c b/source/rpc_server/srv_pipe_netsec.c
new file mode 100644
index 00000000000..33534502236
--- /dev/null
+++ b/source/rpc_server/srv_pipe_netsec.c
@@ -0,0 +1,391 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe server routines
+ * Copyright (C) Andrew Tridgell 1992-2000
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "rpc_parse.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+turns a DCE/RPC request into a DCE/RPC reply
+
+this is where the data really should be split up into an array of
+headers and data sections.
+
+********************************************************************/
+static BOOL api_netsec_create_pdu(rpcsrv_struct *l, uint32 data_start,
+ prs_struct *resp)
+{
+ netsec_auth_struct *a = (netsec_auth_struct *)l->auth_info;
+
+ BOOL ret;
+ uint32 data_len;
+ uint32 frag_len;
+ uint32 auth_len;
+ uint32 data_end = l->rdata.offset + 8 + 0x20;
+ char *data;
+
+ prs_struct rhdr;
+ prs_struct rdata_i;
+ prs_struct rauth;
+ prs_struct rverf;
+
+ RPC_HDR_RESP hdr_resp;
+ RPC_HDR_AUTH auth_info;
+ RPC_AUTH_NETSEC_CHK verf;
+ uchar sign[8];
+ static const uchar netsec_sig[8] = NETSEC_SIGNATURE;
+
+ DEBUG(5,("api_netsec_create_pdu: data_start: %d data_end: %d max_tsize: %d\n",
+ data_start, data_end, l->hdr_ba.bba.max_tsize));
+
+ auth_len = l->hdr.auth_len;
+
+ DEBUG(10,("api_netsec_create_pdu: auth\n"));
+
+ if (auth_len != 0x20)
+ {
+ return False;
+ }
+
+ prs_init(&rhdr , 0, 4, False);
+
+ l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
+
+ /* set up rpc header (fragmentation issues) */
+ if (data_start == 0)
+ {
+ l->hdr.flags = RPC_FLG_FIRST;
+ }
+ else
+ {
+ l->hdr.flags = 0;
+ }
+
+ hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
+ hdr_resp.cancel_count = 0x0;
+ hdr_resp.context_id = 0x0;
+ hdr_resp.reserved = 0x0;
+
+ DEBUG(10,("alloc_hint: %d\n", hdr_resp.alloc_hint));
+
+ if (hdr_resp.alloc_hint + 0x18 <= l->hdr_ba.bba.max_tsize)
+ {
+ l->hdr.flags |= RPC_FLG_LAST;
+ l->hdr.frag_len = hdr_resp.alloc_hint + 0x18;
+ }
+ else
+ {
+ l->hdr.frag_len = l->hdr_ba.bba.max_tsize;
+ }
+
+ hdr_resp.alloc_hint -= auth_len + 8;
+
+ data_len = l->hdr.frag_len - auth_len - 8 - 0x18;
+
+ rhdr.start = 0;
+ rhdr.end = 0x18;
+
+ DEBUG(10,("hdr flags: %x\n", l->hdr.flags));
+
+ /* store the header in the data stream */
+ smb_io_rpc_hdr ("rhdr", &(l->hdr ), &rhdr, 0);
+ smb_io_rpc_hdr_resp("resp", &(hdr_resp), &rhdr, 0);
+
+ /* don't use rdata: use rdata_i instead, which moves... */
+ /* make a pointer to the rdata data, NOT A COPY */
+ data = prs_data(&l->rdata, data_start);
+ prs_create(&rdata_i, data, data_len, l->rdata.align, rdata_i.io);
+ rdata_i.offset = data_len;
+ l->rdata_offset += data_len;
+
+ prs_debug_out(&rdata_i, "rdata_i", 200);
+ prs_debug_out(&l->rdata, "rdata", 200);
+
+ /* happen to know that NETSEC authentication verifier is 32 bytes */
+ frag_len = data_len + auth_len + 8 + 0x18;
+
+ prs_init(&rauth , 8 , 4, False);
+ prs_init(&rverf, auth_len, 4, False);
+
+ make_rpc_hdr_auth(&auth_info, 0x44, 0x06, 0x0, 1);
+ smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &rauth, 0);
+
+ memset(sign, 0, sizeof(sign));
+ sign[3] = 0x01;
+
+ make_rpc_auth_netsec_chk(&verf, netsec_sig, NULL, sign, NULL);
+ ret = netsec_encode(a, &verf, data, data_len);
+
+ if (ret)
+ {
+ smb_io_rpc_auth_netsec_chk("auth_sign", &verf, &rverf, 0);
+ a->seq_num++;
+ }
+
+ if (ret)
+ {
+ prs_link(NULL , &rhdr , &rdata_i );
+ prs_link(&rhdr , &rdata_i , &rauth );
+ prs_link(&rdata_i , &rauth , &rverf);
+ prs_link(&rauth, &rverf, NULL );
+
+ prs_init(resp, 0, 4, False);
+ ret = prs_copy(resp, &rhdr);
+ }
+
+ prs_free_data(&rauth);
+ prs_free_data(&rverf);
+ prs_free_data(&rhdr );
+
+ if (IS_BITS_SET_ALL(l->hdr.flags, RPC_FLG_LAST) ||
+ l->hdr.pkt_type == RPC_BINDACK)
+ {
+ DEBUG(10,("create_netsec_reply: finished sending\n"));
+ prs_free_data(&l->rdata);
+ }
+
+ return ret;
+}
+
+static BOOL api_netsec_verify(rpcsrv_struct *l)
+{
+ netsec_auth_struct *a = (netsec_auth_struct *)l->auth_info;
+ struct dcinfo dc;
+
+ DEBUG(5,("api_netsec_verify: checking credential details\n"));
+
+ /*
+ * obtain the session key
+ */
+ if (!cred_get(l->key.pid,
+ a->netsec_neg.domain, a->netsec_neg.myname, &dc))
+ {
+ return False;
+ }
+
+ l->auth_validated = True;
+
+ memset(a->sess_key, 0, sizeof(a->sess_key));
+ memcpy(a->sess_key, dc.sess_key, sizeof(dc.sess_key));
+
+ dump_data_pw("sess_key:\n", a->sess_key, sizeof(a->sess_key));
+
+ if (l->auth_validated)
+ {
+ a->seq_num = 0;
+ }
+ else
+ {
+ l->auth_validated = False;
+ }
+
+ return l->auth_validated;
+}
+
+static BOOL api_netsec(rpcsrv_struct *l, uint32 msg_type)
+{
+ switch (msg_type)
+ {
+ case 0x3:
+ case 0x13:
+ {
+ netsec_auth_struct *a;
+ a = (netsec_auth_struct *)l->auth_info;
+
+ smb_io_rpc_auth_netsec_neg("", &a->netsec_neg, &l->data_i, 0);
+ if (l->data_i.offset == 0) return False;
+
+ return api_netsec_verify(l);
+ }
+ default:
+ {
+ /* NEGSEC expected: unexpected message type */
+ DEBUG(3,("unexpected message type in NEGSEC %d\n",
+ msg_type));
+ return False;
+ }
+ }
+
+ return False;
+}
+
+static BOOL api_netsec_auth_chk(rpcsrv_struct *l,
+ enum RPC_PKT_TYPE pkt_type)
+{
+ switch (pkt_type)
+ {
+ case RPC_BINDACK:
+ {
+ RPC_AUTH_VERIFIER auth_verifier;
+ smb_io_rpc_auth_verifier("", &auth_verifier, &l->data_i, 0);
+ if (l->data_i.offset == 0) return False;
+
+ if (strequal(auth_verifier.signature, ""))
+ {
+ return api_netsec(l, auth_verifier.msg_type);
+ }
+ break;
+ }
+ default:
+ {
+ DEBUG(10,("api_netsec_auth_chk: unknown pkt_type %x\n",
+ pkt_type));
+ return False;
+ }
+ }
+ return False;
+}
+
+static BOOL api_netsec_auth_gen(rpcsrv_struct *l, prs_struct *resp,
+ enum RPC_PKT_TYPE pkt_type)
+{
+ BOOL ret;
+ RPC_HDR_AUTH auth_info;
+ RPC_AUTH_VERIFIER auth_verifier;
+ RPC_AUTH_NETSEC_RESP auth_resp;
+ prs_struct rhdr;
+ prs_struct rauth;
+ prs_struct rverf;
+ prs_struct rresp;
+
+ prs_init(&(rhdr ), 0, 4, False);
+ prs_init(&(rauth), 0, 4, False);
+ prs_init(&(rverf), 0, 4, False);
+ prs_init(&(rresp), 0, 4, False);
+
+ /*** authentication info ***/
+
+ make_rpc_hdr_auth(&auth_info, 0x44, 0x06, 0, 1);
+ smb_io_rpc_hdr_auth("", &auth_info, &rverf, 0);
+ prs_realloc_data(&rverf, rverf.offset);
+
+ /*** NETSEC verifier ***/
+
+ make_rpc_auth_verifier(&auth_verifier, "\001", 0x0);
+ smb_io_rpc_auth_verifier("", &auth_verifier, &rauth, 0);
+ prs_realloc_data(&rauth, rauth.offset);
+
+ /* NETSEC challenge ***/
+
+ make_rpc_auth_netsec_resp(&auth_resp, 0x05);
+ smb_io_rpc_auth_netsec_resp("", &auth_resp, &rresp, 0);
+ prs_realloc_data(&rresp, rresp.offset);
+
+ /***/
+ /*** then do the header, now we know the length ***/
+ /***/
+
+ make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
+ l->hdr.call_id,
+ l->rdata.offset + rverf.offset + rauth.offset + rresp.offset + 0x10,
+ rauth.offset + rresp.offset);
+
+ smb_io_rpc_hdr("", &l->hdr, &rhdr, 0);
+ prs_realloc_data(&rhdr, l->rdata.offset);
+
+ /***/
+ /*** link rpc header, bind ack and auth responses ***/
+ /***/
+
+ prs_link(NULL , &rhdr , &l->rdata);
+ prs_link(&rhdr , &l->rdata, &rverf );
+ prs_link(&l->rdata, &rverf , &rauth );
+ prs_link(&rverf , &rauth , &rresp );
+ prs_link(&rauth , &rresp , NULL );
+
+ prs_init(resp, 0, 4, False);
+ ret = prs_copy(resp, &rhdr);
+
+ prs_free_data(&l->rdata);
+ prs_free_data(&rhdr );
+ prs_free_data(&rauth );
+ prs_free_data(&rverf );
+ prs_free_data(&rresp );
+
+ return ret;
+}
+
+static BOOL api_netsec_decode_pdu(rpcsrv_struct *l)
+{
+ netsec_auth_struct *a = (netsec_auth_struct *)l->auth_info;
+ int data_len;
+ int auth_len;
+ uint32 old_offset;
+ RPC_HDR_AUTH auth_info;
+ RPC_AUTH_NETSEC_CHK netsec_chk;
+
+ auth_len = l->hdr.auth_len;
+
+ if (auth_len != 0x20 )
+ {
+ return False;
+ }
+
+ data_len = l->hdr.frag_len - auth_len - 8 - 0x18;
+
+ DEBUG(5,("api_pipe_auth_process: data %d auth %d\n",
+ data_len, auth_len));
+
+ /*** skip the data, record the offset so we can restore it again */
+ old_offset = l->data_i.offset;
+
+ l->data_i.offset += data_len;
+ smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &l->data_i, 0);
+ if (!rpc_hdr_netsec_auth_chk(&(auth_info))) return False;
+
+ smb_io_rpc_auth_netsec_chk("auth_sign", &netsec_chk, &l->data_i, 0);
+
+ if (!netsec_decode(a, &netsec_chk,
+ prs_data(&l->data_i, old_offset),
+ data_len))
+ {
+ return False;
+ }
+
+ /* restore the [data, now decoded] offset */
+ l->data_i.offset = old_offset;
+
+ return True;
+}
+
+static BOOL api_netsec_hdr_chk(RPC_HDR_AUTH *auth_info, void **auth_struct)
+{
+ DEBUG(10,("api_netsec_hdr_chk:\n"));
+ if (!rpc_hdr_netsec_auth_chk(auth_info))
+ {
+ return False;
+ }
+ (*auth_struct) = (void*)malloc(sizeof(netsec_auth_struct));
+ return (*auth_struct) != NULL;
+}
+
+srv_auth_fns netsec_fns =
+{
+ api_netsec_hdr_chk,
+ api_netsec_auth_chk,
+ api_netsec_auth_gen,
+ api_netsec_decode_pdu,
+ api_netsec_create_pdu,
+};
+
diff --git a/source/rpc_server/srv_pipe_noauth.c b/source/rpc_server/srv_pipe_noauth.c
new file mode 100644
index 00000000000..d486ffb452f
--- /dev/null
+++ b/source/rpc_server/srv_pipe_noauth.c
@@ -0,0 +1,174 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1998
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+ * Copyright (C) Paul Ashton 1997-1998.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+
+/*******************************************************************
+turns a DCE/RPC request into a DCE/RPC reply
+********************************************************************/
+static BOOL api_noauth_create_pdu(rpcsrv_struct *l, uint32 data_start,
+ prs_struct *resp)
+{
+ BOOL ret;
+ uint32 data_len;
+ uint32 auth_len;
+ uint32 data_end = l->rdata.offset;
+ prs_struct rhdr;
+ prs_struct rdata_i;
+ RPC_HDR_RESP hdr_resp;
+
+ DEBUG(5,("create_noauth_reply: data_start: %d data_end: %d max_tsize: %d\n",
+ data_start, data_end, l->hdr_ba.bba.max_tsize));
+
+ auth_len = l->hdr.auth_len;
+
+ if (auth_len != 0)
+ {
+ return False;
+ }
+
+ prs_init(&rhdr , 0, 4, False);
+
+ l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
+
+ /* set up rpc header (fragmentation issues) */
+ if (data_start == 0)
+ {
+ l->hdr.flags = RPC_FLG_FIRST;
+ }
+ else
+ {
+ l->hdr.flags = 0;
+ }
+
+ hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
+ hdr_resp.cancel_count = 0x0;
+ hdr_resp.context_id = 0x0;
+ hdr_resp.reserved = 0x0;
+
+ DEBUG(10,("alloc_hint: %d\n", hdr_resp.alloc_hint));
+
+ if (hdr_resp.alloc_hint + 0x18 <= l->hdr_ba.bba.max_tsize)
+ {
+ l->hdr.flags |= RPC_FLG_LAST;
+ l->hdr.frag_len = hdr_resp.alloc_hint + 0x18;
+ }
+ else
+ {
+ l->hdr.frag_len = l->hdr_ba.bba.max_tsize;
+ }
+
+ data_len = l->hdr.frag_len - 0x18;
+
+ rhdr.start = 0;
+ rhdr.end = 0x18;
+
+ DEBUG(10,("hdr flags: %x\n", l->hdr.flags));
+
+ /* store the header in the data stream */
+ smb_io_rpc_hdr ("rhdr", &(l->hdr ), &(rhdr), 0);
+ smb_io_rpc_hdr_resp("resp", &(hdr_resp), &(rhdr), 0);
+
+ /* don't use rdata: use rdata_i instead, which moves... */
+ /* make a pointer to the rdata data, NOT A COPY */
+
+ prs_create(&rdata_i, prs_data(&l->rdata, data_start),
+ data_len, l->rdata.align, rdata_i.io);
+ rdata_i.offset = data_len;
+ l->rdata_offset += data_len;
+
+ prs_debug_out(&rdata_i, "rdata_i", 200);
+ prs_debug_out(&l->rdata, "rdata", 200);
+
+ prs_link(NULL , &rhdr , &rdata_i);
+ prs_link(&rhdr, &rdata_i, NULL );
+
+ prs_init(resp, 0, 4, False);
+ ret = prs_copy(resp, &rhdr);
+
+ prs_free_data(&rhdr );
+
+ return ret;
+}
+
+static BOOL api_noauth_auth_gen(rpcsrv_struct *l, prs_struct *resp,
+ enum RPC_PKT_TYPE pkt_type)
+{
+ prs_struct rhdr;
+ BOOL ret;
+
+ DEBUG(10,("api_noauth_auth_gen\n"));
+
+ prs_init(&rhdr, 0, 4, False);
+
+ make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
+ l->hdr.call_id,
+ l->rdata.offset + 0x10, 0);
+
+ smb_io_rpc_hdr("", &l->hdr, &rhdr, 0);
+ prs_realloc_data(&rhdr, l->rdata.offset);
+
+ /***/
+ /*** link rpc header and bind acknowledgment ***/
+ /***/
+
+ prs_link(NULL , &rhdr , &l->rdata);
+ prs_link(&rhdr, &l->rdata, NULL );
+
+ prs_init(resp, 0, 4, False);
+ ret = prs_copy(resp, &rhdr);
+
+ prs_free_data(&l->rdata);
+ prs_free_data(&rhdr );
+
+ return ret;
+}
+
+static BOOL api_noauth_auth_chk(rpcsrv_struct *l, enum RPC_PKT_TYPE pkt_type)
+{
+ l->auth_validated = True;
+
+ return True;
+}
+
+static BOOL api_noauth_decode_pdu(rpcsrv_struct *l)
+{
+ return True;
+}
+
+srv_auth_fns noauth_fns =
+{
+ NULL,
+ api_noauth_auth_chk,
+ api_noauth_auth_gen,
+ api_noauth_decode_pdu,
+ api_noauth_create_pdu,
+};
+
diff --git a/source/rpc_server/srv_pipe_ntlmssp.c b/source/rpc_server/srv_pipe_ntlmssp.c
new file mode 100644
index 00000000000..19fa70aef73
--- /dev/null
+++ b/source/rpc_server/srv_pipe_ntlmssp.c
@@ -0,0 +1,657 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe server routines
+ * Copyright (C) Andrew Tridgell 1992-1999
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+static void NTLMSSPcalc_p(ntlmssp_auth_struct * a, uchar * data, int len)
+{
+ uchar *hash = a->ntlmssp_hash;
+ uchar index_i = hash[256];
+ uchar index_j = hash[257];
+ int ind;
+
+ for (ind = 0; ind < len; ind++)
+ {
+ uchar tc;
+ uchar t;
+
+ index_i++;
+ index_j += hash[index_i];
+
+ tc = hash[index_i];
+ hash[index_i] = hash[index_j];
+ hash[index_j] = tc;
+
+ t = hash[index_i] + hash[index_j];
+ data[ind] = data[ind] ^ hash[t];
+ }
+
+ hash[256] = index_i;
+ hash[257] = index_j;
+}
+
+/*******************************************************************
+turns a DCE/RPC request into a DCE/RPC reply
+
+this is where the data really should be split up into an array of
+headers and data sections.
+
+********************************************************************/
+static BOOL api_ntlmssp_create_pdu(rpcsrv_struct * l, uint32 data_start,
+ prs_struct * resp)
+{
+ ntlmssp_auth_struct *a = (ntlmssp_auth_struct *) l->auth_info;
+
+ BOOL ret;
+ BOOL auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SIGN);
+ BOOL auth_seal = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SEAL);
+ uint32 data_len;
+ uint32 auth_len;
+ uint32 data_end = l->rdata.offset + (l->auth ? (8 + 16) : 0);
+ uint32 crc32 = 0;
+ char *data;
+
+ prs_struct rhdr;
+ prs_struct rdata_i;
+ prs_struct rauth;
+ prs_struct rverf;
+
+ RPC_HDR_RESP hdr_resp;
+
+ DEBUG(5,
+ ("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
+ data_start, data_end, l->hdr_ba.bba.max_tsize));
+
+ auth_len = l->hdr.auth_len;
+
+ DEBUG(10, ("create_rpc_reply: auth\n"));
+
+ if (auth_len != 16)
+ {
+ return False;
+ }
+
+ prs_init(&rhdr, 0, 4, False);
+
+ l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
+
+ /* set up rpc header (fragmentation issues) */
+ if (data_start == 0)
+ {
+ l->hdr.flags = RPC_FLG_FIRST;
+ }
+ else
+ {
+ l->hdr.flags = 0;
+ }
+
+ hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
+ hdr_resp.cancel_count = 0x0;
+ hdr_resp.context_id = 0x0;
+ hdr_resp.reserved = 0x0;
+
+ DEBUG(10, ("alloc_hint: %d\n", hdr_resp.alloc_hint));
+
+ if (hdr_resp.alloc_hint + 0x18 <= l->hdr_ba.bba.max_tsize)
+ {
+ l->hdr.flags |= RPC_FLG_LAST;
+ l->hdr.frag_len = hdr_resp.alloc_hint + 0x18;
+ }
+ else
+ {
+ l->hdr.frag_len = l->hdr_ba.bba.max_tsize;
+ }
+
+ hdr_resp.alloc_hint -= auth_len + 8;
+
+ data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
+
+ rhdr.start = 0;
+ rhdr.end = 0x18;
+
+ DEBUG(10, ("hdr flags: %x\n", l->hdr.flags));
+
+ /* store the header in the data stream */
+ smb_io_rpc_hdr("rhdr", &(l->hdr), &(rhdr), 0);
+ smb_io_rpc_hdr_resp("resp", &(hdr_resp), &(rhdr), 0);
+
+ /* don't use rdata: use rdata_i instead, which moves... */
+ /* make a pointer to the rdata data, NOT A COPY */
+
+ data = prs_data(&l->rdata, data_start);
+ prs_create(&rdata_i, data, data_len, l->rdata.align, rdata_i.io);
+ rdata_i.offset = data_len;
+ l->rdata_offset += data_len;
+
+ prs_debug_out(&rdata_i, "rdata_i", 200);
+ prs_debug_out(&l->rdata, "rdata", 200);
+
+ prs_init(&rauth, 0, 4, False);
+ prs_init(&rverf, 0, 4, False);
+
+ DEBUG(5, ("create_ntlmssp_reply: sign: %s seal: %s data %d auth %d\n",
+ BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len,
+ auth_len));
+
+ if (auth_seal)
+ {
+ crc32 = crc32_calc_buffer(data_len, data);
+ NTLMSSPcalc_p(a, (uchar *) data, data_len);
+ }
+
+ if (auth_seal || auth_verify)
+ {
+ RPC_HDR_AUTH auth_info;
+ make_rpc_hdr_auth(&auth_info, 0x0a, 0x06, 0x08,
+ (auth_verify ? 1 : 0));
+ smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &rauth, 0);
+ }
+
+ if (auth_verify)
+ {
+ RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
+ a->ntlmssp_seq_num++;
+ make_rpc_auth_ntlmssp_chk(&ntlmssp_chk,
+ NTLMSSP_SIGN_VERSION, crc32,
+ a->ntlmssp_seq_num++);
+ smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &rverf,
+ 0);
+ NTLMSSPcalc_p(a, (uchar *) prs_data(&rverf, 4), 12);
+ }
+ prs_link(NULL, &rhdr, &rdata_i);
+ prs_link(&rhdr, &rdata_i, &rauth);
+ prs_link(&rdata_i, &rauth, &rverf);
+ prs_link(&rauth, &rverf, NULL);
+
+ prs_init(resp, 0, 4, False);
+ ret = prs_copy(resp, &rhdr);
+
+ prs_free_data(&rauth);
+ prs_free_data(&rverf);
+ prs_free_data(&rhdr);
+
+ if (IS_BITS_SET_ALL(l->hdr.flags, RPC_FLG_LAST) ||
+ l->hdr.pkt_type == RPC_BINDACK)
+ {
+ DEBUG(10, ("create_ntlmssp_reply: finished sending\n"));
+ prs_free_data(&l->rdata);
+ }
+
+ return ret;
+}
+
+static BOOL api_ntlmssp_verify(rpcsrv_struct * l,
+ RPC_AUTH_NTLMSSP_RESP * ntlmssp_resp)
+{
+ ntlmssp_auth_struct *a = (ntlmssp_auth_struct *) l->auth_info;
+ uchar lm_owf[24];
+ uchar nt_owf[128];
+ size_t lm_owf_len;
+ size_t nt_owf_len;
+ size_t usr_len;
+ size_t dom_len;
+ size_t wks_len;
+ BOOL anonymous = False;
+ fstring user_name;
+ fstring domain;
+ fstring wks;
+ const struct passwd *pw = NULL;
+ fstring unix_user;
+ fstring nt_user;
+ NET_USER_INFO_3 info3;
+ BOOL guest = False;
+
+ ZERO_STRUCT(info3);
+
+ DEBUG(5, ("api_ntlmssp_verify: checking user details\n"));
+
+ lm_owf_len = ntlmssp_resp->hdr_lm_resp.str_str_len;
+ nt_owf_len = ntlmssp_resp->hdr_nt_resp.str_str_len;
+ usr_len = ntlmssp_resp->hdr_usr.str_str_len;
+ dom_len = ntlmssp_resp->hdr_domain.str_str_len;
+ wks_len = ntlmssp_resp->hdr_wks.str_str_len;
+
+ if (lm_owf_len <= 1 && nt_owf_len == 0 &&
+ usr_len == 0 && dom_len == 0)
+ {
+ anonymous = True;
+ }
+ else
+ {
+ if (lm_owf_len == 0)
+ return False;
+ if (nt_owf_len == 0)
+ return False;
+ if (ntlmssp_resp->hdr_usr.str_str_len == 0)
+ return False;
+ if (ntlmssp_resp->hdr_wks.str_str_len == 0)
+ return False;
+ }
+
+ if (lm_owf_len > sizeof(lm_owf))
+ return False;
+ if (nt_owf_len > sizeof(nt_owf))
+ return False;
+
+ memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
+ memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf));
+
+ dump_data_pw("lm_owf:", lm_owf, sizeof(lm_owf));
+ dump_data_pw("nt_owf:", nt_owf, sizeof(nt_owf));
+ dump_data_pw("chal:", a->ntlmssp_chal.challenge, 8);
+
+ memset(user_name, 0, sizeof(user_name));
+ memset(domain, 0, sizeof(domain));
+ memset(wks, 0, sizeof(wks));
+
+ if (IS_BITS_SET_ALL
+ (a->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE))
+ {
+ unibuf_to_ascii(user_name, ntlmssp_resp->user,
+ MIN(ntlmssp_resp->hdr_usr.str_str_len / 2,
+ sizeof(user_name) - 1));
+ unibuf_to_ascii(domain, ntlmssp_resp->domain,
+ MIN(ntlmssp_resp->hdr_domain.str_str_len / 2,
+ sizeof(domain) - 1));
+ unibuf_to_ascii(wks, ntlmssp_resp->wks,
+ MIN(ntlmssp_resp->hdr_wks.str_str_len / 2,
+ sizeof(wks) - 1));
+ }
+ else
+ {
+ fstrcpy(user_name, ntlmssp_resp->user);
+ fstrcpy(domain, ntlmssp_resp->domain);
+ fstrcpy(wks, ntlmssp_resp->wks);
+ }
+
+ if (anonymous)
+ {
+ DEBUG(5, ("anonymous user session\n"));
+ guest = True;
+ safe_strcpy(unix_user, lp_guestaccount(-1),
+ sizeof(unix_user) - 1);
+ nt_user[0] = 0;
+ pw = Get_Pwnam(unix_user, True);
+ }
+ DEBUG(5, ("user: %s domain: %s wks: %s\n", user_name, domain, wks));
+
+ l->auth_validated = check_domain_security(user_name, domain,
+ (const uchar *)a->
+ ntlmssp_chal.challenge,
+ lm_owf, lm_owf_len, nt_owf,
+ nt_owf_len, &info3) == 0x0;
+
+ if (!anonymous && l->auth_validated)
+ {
+ pw = map_nt_and_unix_username(domain, user_name,
+ unix_user, nt_user);
+ l->auth_validated = pw != NULL;
+ }
+
+ if (l->auth_validated)
+ {
+ become_root(False);
+ l->key.pid = getpid();
+ l->key.vuid =
+ register_vuid(l->key.pid, pw->pw_uid, pw->pw_gid,
+ unix_user, nt_user, guest, &info3);
+ unbecome_root(False);
+ l->auth_validated = l->key.vuid != UID_FIELD_INVALID;
+ }
+
+ if (l->auth_validated)
+ {
+ l->auth_validated = become_vuser(&l->key);
+ }
+
+ if (l->auth_validated)
+ {
+ /************************************************************/
+ /****************** lkclXXXX - NTLMv1 ONLY! *****************/
+ /************************************************************/
+
+ uchar p24[24];
+ uchar j = 0;
+ int ind;
+ uchar password[16];
+ uchar k2[16];
+ int len;
+
+ ZERO_STRUCT(password);
+ memcpy(password, info3.padding, 8);
+
+ NTLMSSPOWFencrypt(password, lm_owf, p24);
+
+ if (True)
+ {
+ len = 8;
+ memcpy(k2, p24, 5);
+ k2[5] = 0xe5;
+ k2[6] = 0x38;
+ k2[7] = 0xb0;
+ }
+ else
+ {
+ len = 16;
+ memcpy(k2, p24, 16);
+ }
+
+ for (ind = 0; ind < 256; ind++)
+ {
+ a->ntlmssp_hash[ind] = (uchar) ind;
+ }
+
+ for (ind = 0; ind < 256; ind++)
+ {
+ uchar tc;
+
+ j += (a->ntlmssp_hash[ind] + k2[ind % len]);
+ tc = a->ntlmssp_hash[ind];
+ a->ntlmssp_hash[ind] = a->ntlmssp_hash[j];
+ a->ntlmssp_hash[j] = tc;
+ }
+
+ a->ntlmssp_hash[256] = 0;
+ a->ntlmssp_hash[257] = 0;
+ a->ntlmssp_seq_num = 0;
+ }
+ else
+ {
+ l->auth_validated = False;
+ }
+
+ return l->auth_validated;
+}
+
+static BOOL api_ntlmssp(rpcsrv_struct * l, uint32 msg_type)
+{
+ /* receive a negotiate; send a challenge; receive a response */
+ switch (msg_type)
+ {
+ case NTLMSSP_NEGOTIATE:
+ {
+ RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
+ if (!smb_io_rpc_auth_ntlmssp_neg
+ ("", &ntlmssp_neg, &l->data_i, 0))
+ {
+ return False;
+ }
+ if (strlen(ntlmssp_neg.myname) == 0 ||
+ strlen(ntlmssp_neg.domain) == 0)
+ {
+ return False;
+ }
+ DEBUG(10, ("ntlmssp neg: myname %s domain %s\n",
+ ntlmssp_neg.myname, ntlmssp_neg.domain));
+ break;
+ }
+ case NTLMSSP_AUTH:
+ {
+ RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+ smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp,
+ &l->data_i, 0);
+ if (!api_ntlmssp_verify(l, &ntlmssp_resp))
+ {
+ l->data_i.offset = 0;
+ }
+ break;
+ }
+ default:
+ {
+ /* NTLMSSP expected: unexpected message type */
+ DEBUG(3, ("unexpected message type in NTLMSSP %d\n",
+ msg_type));
+ return False;
+ }
+ }
+
+ return (l->data_i.offset != 0);
+}
+
+static BOOL api_ntlmssp_bind_auth_resp(rpcsrv_struct * l)
+{
+ RPC_HDR_AUTHA autha_info;
+ RPC_AUTH_VERIFIER auth_verifier;
+
+ DEBUG(5, ("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
+
+ if (l->hdr.auth_len == 0)
+ return False;
+
+ /* decode the authentication verifier response */
+ smb_io_rpc_hdr_autha("", &autha_info, &l->data_i, 0);
+ if (l->data_i.offset == 0)
+ return False;
+
+ smb_io_rpc_auth_verifier("", &auth_verifier, &l->data_i, 0);
+ if (l->data_i.offset == 0)
+ return False;
+
+ if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH))
+ {
+ return False;
+ }
+
+ return api_ntlmssp(l, auth_verifier.msg_type);
+}
+
+static BOOL api_ntlmssp_auth_chk(rpcsrv_struct * l,
+ enum RPC_PKT_TYPE pkt_type)
+{
+ switch (pkt_type)
+ {
+ case RPC_BINDRESP:
+ {
+ return api_ntlmssp_bind_auth_resp(l);
+ }
+ case RPC_BINDACK:
+ case RPC_ALTCONTRESP:
+ {
+ RPC_AUTH_VERIFIER auth_verifier;
+ if (!smb_io_rpc_auth_verifier("", &auth_verifier,
+ &l->data_i, 0))
+ {
+ return False;
+ }
+ if (l->data_i.offset == 0)
+ return False;
+
+ if (strequal(auth_verifier.signature, "NTLMSSP"))
+ {
+ return api_ntlmssp(l, auth_verifier.msg_type);
+ }
+ break;
+ }
+ default:
+ {
+ return False;
+ }
+ }
+ return False;
+}
+
+static BOOL api_ntlmssp_auth_gen(rpcsrv_struct * l, prs_struct * resp,
+ enum RPC_PKT_TYPE pkt_type)
+{
+ BOOL ret;
+ uint8 challenge[8];
+ RPC_HDR_AUTH auth_info;
+ RPC_AUTH_VERIFIER auth_verifier;
+ prs_struct rhdr;
+ prs_struct rauth;
+ prs_struct rverf;
+ prs_struct rntlm;
+
+ ntlmssp_auth_struct *a = (ntlmssp_auth_struct *) l->auth_info;
+
+ prs_init(&(rhdr), 0, 4, False);
+ prs_init(&(rauth), 0, 4, False);
+ prs_init(&(rverf), 0, 4, False);
+ prs_init(&(rntlm), 0, 4, False);
+
+ generate_random_buffer(challenge, 8, False);
+
+ /*** authentication info ***/
+
+ make_rpc_hdr_auth(&auth_info, 0x0a, 0x06, 0, 1);
+ smb_io_rpc_hdr_auth("", &auth_info, &rverf, 0);
+ prs_realloc_data(&rverf, rverf.offset);
+
+ /*** NTLMSSP verifier ***/
+
+ make_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE);
+ smb_io_rpc_auth_verifier("", &auth_verifier, &rauth, 0);
+ prs_realloc_data(&rauth, rauth.offset);
+
+ /* NTLMSSP challenge ** */
+
+ make_rpc_auth_ntlmssp_chal(&a->ntlmssp_chal, 0x000082b1, challenge);
+ smb_io_rpc_auth_ntlmssp_chal("", &a->ntlmssp_chal, &rntlm, 0);
+ prs_realloc_data(&rntlm, rntlm.offset);
+
+ /***/
+ /*** then do the header, now we know the length ***/
+ /***/
+
+ make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
+ l->hdr.call_id,
+ l->rdata.offset + rverf.offset + rauth.offset +
+ rntlm.offset + 0x10, rauth.offset + rntlm.offset);
+
+ smb_io_rpc_hdr("", &l->hdr, &rhdr, 0);
+ prs_realloc_data(&rhdr, l->rdata.offset);
+
+ /***/
+ /*** link rpc header, bind ack and auth responses ***/
+ /***/
+
+ prs_link(NULL, &rhdr, &l->rdata);
+ prs_link(&rhdr, &l->rdata, &rverf);
+ prs_link(&l->rdata, &rverf, &rauth);
+ prs_link(&rverf, &rauth, &rntlm);
+ prs_link(&rauth, &rntlm, NULL);
+
+ prs_init(resp, 0, 4, False);
+ ret = prs_copy(resp, &rhdr);
+
+ prs_free_data(&l->rdata);
+ prs_free_data(&rhdr);
+ prs_free_data(&rauth);
+ prs_free_data(&rverf);
+ prs_free_data(&rntlm);
+
+ return ret;
+}
+
+static BOOL api_ntlmssp_decode_pdu(rpcsrv_struct * l)
+{
+ ntlmssp_auth_struct *a = (ntlmssp_auth_struct *) l->auth_info;
+ BOOL auth_verify = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SIGN);
+ BOOL auth_seal = IS_BITS_SET_ALL(a->ntlmssp_chal.neg_flags,
+ NTLMSSP_NEGOTIATE_SEAL);
+ int data_len;
+ int auth_len;
+ uint32 old_offset;
+ uint32 crc32 = 0;
+
+ auth_len = l->hdr.auth_len;
+
+ if (auth_len != 16 && auth_verify)
+ {
+ return False;
+ }
+
+ data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
+
+ DEBUG(5,
+ ("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
+ BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
+
+ if (auth_seal)
+ {
+ char *data = prs_data(&l->data_i, l->data_i.offset);
+ DEBUG(5,
+ ("api_pipe_auth_process: data %d\n", l->data_i.offset));
+ NTLMSSPcalc_p(a, (uchar *) data, data_len);
+ crc32 = crc32_calc_buffer(data_len, data);
+ }
+
+ /*** skip the data, record the offset so we can restore it again */
+ old_offset = l->data_i.offset;
+
+ if (auth_seal || auth_verify)
+ {
+ RPC_HDR_AUTH auth_info;
+ l->data_i.offset += data_len;
+ smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &l->data_i, 0);
+ if (!rpc_hdr_ntlmssp_auth_chk(&(auth_info)))
+ return False;
+ }
+
+ if (auth_verify)
+ {
+ RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
+ DEBUG(5, ("api_pipe_auth_process: auth %d\n",
+ l->data_i.offset + 4));
+ NTLMSSPcalc_p(a, (uchar *) prs_data(&l->data_i,
+ l->data_i.offset + 4),
+ 12);
+ smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk,
+ &l->data_i, 0);
+
+ if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32,
+ a->ntlmssp_seq_num))
+ {
+ return False;
+ }
+ }
+
+ l->data_i.offset = old_offset;
+
+ return True;
+}
+
+static BOOL api_ntlmssp_hdr_chk(RPC_HDR_AUTH * auth_info, void **auth_struct)
+{
+ DEBUG(10, ("api_ntlmssp_hdr_chk:\n"));
+ if (!rpc_hdr_ntlmssp_auth_chk(auth_info))
+ {
+ return False;
+ }
+ (*auth_struct) = (void *)malloc(sizeof(ntlmssp_auth_struct));
+ return (*auth_struct) != NULL;
+}
+
+srv_auth_fns ntlmssp_fns = {
+ api_ntlmssp_hdr_chk,
+ api_ntlmssp_auth_chk,
+ api_ntlmssp_auth_gen,
+ api_ntlmssp_decode_pdu,
+ api_ntlmssp_create_pdu,
+};
diff --git a/source/rpc_server/srv_pipe_srv.c b/source/rpc_server/srv_pipe_srv.c
index 86cc9e47e64..a2340e5c04d 100644
--- a/source/rpc_server/srv_pipe_srv.c
+++ b/source/rpc_server/srv_pipe_srv.c
@@ -1,11 +1,11 @@
+
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1998
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
- * Copyright (C) Paul Ashton 1997-1998.
- * Copyright (C) Jeremy Allison 1999.
+ * Copyright (C) Andrew Tridgell 1992-2000
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Paul Ashton 1997-2000.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,1095 +22,731 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* this module apparently provides an implementation of DCE/RPC over a
- * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
- * documentation are available (in on-line form) from the X-Open group.
- *
- * this module should provide a level of abstraction between SMB
- * and DCE/RPC, while minimising the amount of mallocs, unnecessary
- * data copies, and network traffic.
- *
- * in this version, which takes a "let's learn what's going on and
- * get something running" approach, there is additional network
- * traffic generated, but the code should be easier to understand...
- *
- * ... if you read the docs. or stare at packets for weeks on end.
- *
- */
-
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
-static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len)
-{
- unsigned char *hash = p->ntlmssp_hash;
- unsigned char index_i = hash[256];
- unsigned char index_j = hash[257];
- int ind;
-
- for( ind = 0; ind < len; ind++) {
- unsigned char tc;
- unsigned char t;
-
- index_i++;
- index_j += hash[index_i];
-
- tc = hash[index_i];
- hash[index_i] = hash[index_j];
- hash[index_j] = tc;
-
- t = hash[index_i] + hash[index_j];
- data[ind] = data[ind] ^ hash[t];
- }
-
- hash[256] = index_i;
- hash[257] = index_j;
-}
-
/*******************************************************************
- Generate the next PDU to be returned from the data in p->rdata.
- We cheat here as this function doesn't handle the special auth
- footers of the authenticated bind response reply.
- ********************************************************************/
-
-BOOL create_next_pdu(pipes_struct *p)
+turns a DCE/RPC response stream into a DCE/RPC reply
+********************************************************************/
+static BOOL create_rpc_reply(rpcsrv_struct * l, uint32 data_start,
+ prs_struct * resp)
{
- RPC_HDR_RESP hdr_resp;
- BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN);
- BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL);
- uint32 data_len;
- uint32 data_space_available;
- uint32 data_len_left;
- prs_struct outgoing_pdu;
- char *data;
- char *data_from;
- uint32 data_pos;
-
- memset((char *)&hdr_resp, '\0', sizeof(hdr_resp));
-
- /* Change the incoming request header to a response. */
- p->hdr.pkt_type = RPC_RESPONSE;
-
- /* Set up rpc header flags. */
- if (p->out_data.data_sent_length == 0)
- p->hdr.flags = RPC_FLG_FIRST;
- else
- p->hdr.flags = 0;
+ BOOL ret;
- /*
- * Work out how much we can fit in a sigle PDU.
- */
-
- data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
- if(p->ntlmssp_auth_validated)
- data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN);
-
- /*
- * The amount we send is the minimum of the available
- * space and the amount left to send.
- */
-
- data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;
-
- /*
- * Ensure there really is data left to send.
- */
-
- if(!data_len_left) {
- DEBUG(0,("create_next_pdu: no data left to send !\n"));
- return False;
+ if (l->auth != NULL)
+ {
+ ret = l->auth->api_create_pdu(l, data_start, resp);
}
-
- data_len = MIN(data_len_left, data_space_available);
-
- /*
- * Set up the alloc hint. This should be the data left to
- * send.
- */
-
- hdr_resp.alloc_hint = data_len_left;
-
- /*
- * Set up the header lengths.
- */
-
- if (p->ntlmssp_auth_validated) {
- p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len +
- RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN;
- p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN;
- } else {
- p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len;
- p->hdr.auth_len = 0;
+ else
+ {
+ ret = False;
}
-
- /*
- * Work out if this PDU will be the last.
- */
-
- if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata))
- p->hdr.flags |= RPC_FLG_LAST;
-
- /*
- * Init the parse struct to point at the outgoing
- * data.
- */
-
- prs_init( &outgoing_pdu, 0, 4, MARSHALL);
- prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
-
- /* Store the header in the data stream. */
- if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) {
- DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n"));
- return False;
+ if ((!ret) || IS_BITS_SET_ALL(l->hdr.flags, RPC_FLG_LAST))
+ {
+ DEBUG(10, ("create_rpc_reply: finished sending\n"));
+ prs_free_data(&l->rdata);
}
+ return ret;
+}
- if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) {
- DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n"));
- return False;
- }
- /* Store the current offset. */
- data_pos = prs_offset(&outgoing_pdu);
+struct api_cmd
+{
+ char *pipe_clnt_name;
+ char *pipe_srv_name;
+ BOOL (*fn) (rpcsrv_struct *);
+};
- /* Copy the data into the PDU. */
- data_from = prs_data_p(&p->out_data.rdata) + p->out_data.data_sent_length;
+static struct api_cmd **api_fd_commands = NULL;
+uint32 num_cmds = 0;
- if(!prs_append_data(&outgoing_pdu, data_from, data_len)) {
- DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len));
- return False;
+static void api_cmd_free(struct api_cmd *item)
+{
+ if (item != NULL)
+ {
+ if (item->pipe_clnt_name != NULL)
+ {
+ free(item->pipe_clnt_name);
+ }
+ if (item->pipe_srv_name != NULL)
+ {
+ free(item->pipe_srv_name);
+ }
+ free(item);
}
+}
- /*
- * Set data to point to where we copied the data into.
- */
-
- data = prs_data_p(&outgoing_pdu) + data_pos;
-
- if (p->hdr.auth_len > 0) {
- uint32 crc32 = 0;
-
- DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n",
- BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, p->hdr.auth_len));
-
- if (auth_seal) {
- crc32 = crc32_calc_buffer(data, data_len);
- NTLMSSPcalc_p(p, (uchar*)data, data_len);
+static struct api_cmd *api_cmd_dup(const struct api_cmd *from)
+{
+ struct api_cmd *copy = NULL;
+ if (from == NULL)
+ {
+ return NULL;
+ }
+ copy = (struct api_cmd *)malloc(sizeof(struct api_cmd));
+ if (copy != NULL)
+ {
+ ZERO_STRUCTP(copy);
+ if (from->pipe_clnt_name != NULL)
+ {
+ copy->pipe_clnt_name = strdup(from->pipe_clnt_name);
}
-
- if (auth_seal || auth_verify) {
- RPC_HDR_AUTH auth_info;
-
- init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL,
- (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0));
- if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) {
- DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n"));
- return False;
- }
+ if (from->pipe_srv_name != NULL)
+ {
+ copy->pipe_srv_name = strdup(from->pipe_srv_name);
}
-
- if (auth_verify) {
- RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
- char *auth_data = prs_data_p(&outgoing_pdu);
-
- p->ntlmssp_seq_num++;
- init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION,
- crc32, p->ntlmssp_seq_num++);
- auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4;
- if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) {
- DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n"));
- return False;
- }
- NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
+ if (from->fn != NULL)
+ {
+ copy->fn = from->fn;
}
}
-
- /*
- * Setup the counts for this PDU.
- */
-
- p->out_data.data_sent_length += data_len;
- p->out_data.current_pdu_len = p->hdr.frag_len;
- p->out_data.current_pdu_sent = 0;
-
- return True;
+ return copy;
}
-/*******************************************************************
- Process an NTLMSSP authentication response.
- If this function succeeds, the user has been authenticated
- and their domain, name and calling workstation stored in
- the pipe struct.
- The initial challenge is stored in p->challenge.
- *******************************************************************/
-
-static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
+static void free_api_cmd_array(uint32 num_entries, struct api_cmd **entries)
{
- uchar lm_owf[24];
- uchar nt_owf[24];
- fstring user_name;
- fstring unix_user_name;
- fstring domain;
- fstring wks;
- BOOL guest_user = False;
- struct smb_passwd *smb_pass = NULL;
- struct passwd *pass = NULL;
- uchar null_smb_passwd[16];
- uchar *smb_passwd_ptr = NULL;
-
- DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));
-
- memset(p->user_name, '\0', sizeof(p->user_name));
- memset(p->unix_user_name, '\0', sizeof(p->unix_user_name));
- memset(p->domain, '\0', sizeof(p->domain));
- memset(p->wks, '\0', sizeof(p->wks));
-
- /*
- * Setup an empty password for a guest user.
- */
-
- memset(null_smb_passwd,0,16);
-
- /*
- * We always negotiate UNICODE.
- */
-
- if (IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_UNICODE)) {
- fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2));
- fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2));
- fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2));
- } else {
- fstrcpy(user_name, ntlmssp_resp->user);
- fstrcpy(domain, ntlmssp_resp->domain);
- fstrcpy(wks, ntlmssp_resp->wks);
- }
-
- DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks));
-
- memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
- memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf));
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("lm, nt owfs, chal\n"));
- dump_data(100, (char *)lm_owf, sizeof(lm_owf));
- dump_data(100, (char *)nt_owf, sizeof(nt_owf));
- dump_data(100, (char *)p->challenge, 8);
-#endif
-
- /*
- * Allow guest access. Patch from Shirish Kalele <kalele@veritas.com>.
- */
-
- if((strlen(user_name) == 0) && (ntlmssp_resp->hdr_lm_resp.str_str_len==0) &&
- (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) {
+ void (*fn) (void *) = (void (*)(void *))&api_cmd_free;
+ free_void_array(num_entries, (void **)entries, *fn);
+}
- guest_user = True;
+static struct api_cmd *add_api_cmd_to_array(uint32 * len,
+ struct api_cmd ***array,
+ const struct api_cmd *name)
+{
+ void *(*fn) (const void *) = (void *(*)(const void *))&api_cmd_dup;
+ return (struct api_cmd *)add_copy_to_array(len,
+ (void ***)array,
+ (const void *)name, *fn,
+ False);
+}
- fstrcpy(unix_user_name, lp_guestaccount(-1));
- DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", unix_user_name));
- smb_passwd_ptr = null_smb_passwd;
+void close_msrpc_command_processor(void)
+{
+ free_api_cmd_array(num_cmds, api_fd_commands);
+}
- } else {
+void add_msrpc_command_processor(char *pipe_name,
+ char *process_name,
+ BOOL (*fn) (rpcsrv_struct *))
+{
+ struct api_cmd cmd;
+ cmd.pipe_clnt_name = pipe_name;
+ cmd.pipe_srv_name = process_name;
+ cmd.fn = fn;
- /*
- * Pass the user through the NT -> unix user mapping
- * function.
- */
+ add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd);
+}
- fstrcpy(unix_user_name, user_name);
- (void)map_username(unix_user_name);
+static BOOL api_pipe_nack_resp(rpcsrv_struct * l, uint16 rej_code,
+ prs_struct * resp)
+{
+ prs_struct rhdr;
+ prs_struct rnack;
+ RPC_HDR_NACK hdr_nack;
- /*
- * Do the length checking only if user is not NULL.
- */
+ DEBUG(5, ("api_pipe_nack_resp: make response\n"));
- if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0)
- return False;
- if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0)
- return False;
- if (ntlmssp_resp->hdr_usr.str_str_len == 0)
- return False;
- if (ntlmssp_resp->hdr_domain.str_str_len == 0)
- return False;
- if (ntlmssp_resp->hdr_wks.str_str_len == 0)
- return False;
+ l->faulted_once_before = True;
- }
+ prs_init(&(rhdr), 0, 4, False);
+ prs_init(&(rnack), 0, 4, False);
- /*
- * Find the user in the unix password db.
- */
+ /***/
+ /*** set up the header and nack status ***/
+ /***/
- if(!(pass = Get_Pwnam(unix_user_name,True))) {
- DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",unix_user_name));
- return(False);
- }
+ hdr_nack.rej_code = rej_code;
- if(!guest_user) {
+ make_rpc_hdr(&l->hdr, RPC_BINDNACK,
+ RPC_FLG_FIRST | RPC_FLG_LAST,
+ l->hdr.call_id, 0x12, 0);
- become_root(True);
+ smb_io_rpc_hdr("hdr", &l->hdr, &rhdr, 0);
+ smb_io_rpc_hdr_nack("nack", &hdr_nack, &rnack, 0);
+ prs_realloc_data(&rhdr, rhdr.offset);
+ prs_realloc_data(&rnack, rnack.offset);
- if(!(p->ntlmssp_auth_validated = pass_check_smb(unix_user_name, domain,
- (uchar*)p->challenge, lm_owf, nt_owf, NULL))) {
- DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \
-failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name ));
- unbecome_root(True);
- return False;
- }
+ /***/
+ /*** link rpc header and nack together ***/
+ /***/
- if(!(smb_pass = getsmbpwnam(unix_user_name))) {
- DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n",
- unix_user_name));
- unbecome_root(True);
- return False;
- }
+ prs_link(NULL, &rhdr, &rnack);
+ prs_link(&rhdr, &rnack, NULL);
- unbecome_root(True);
-
- if (smb_pass == NULL) {
- DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n",
- unix_user_name));
- return(False);
- }
-
- /* Quit if the account was disabled. */
- if((smb_pass->acct_ctrl & ACB_DISABLED) || !smb_pass->smb_passwd) {
- DEBUG(1,("Account for user '%s' was disabled.\n", unix_user_name));
- return(False);
- }
+ prs_init(resp, 0, 4, False);
+ if (!prs_copy(resp, &rhdr))
+ return False;
+ prs_free_data(&rnack);
+ prs_free_data(&rhdr);
- if(!smb_pass->smb_nt_passwd) {
- DEBUG(1,("Account for user '%s' has no NT password hash.\n", unix_user_name));
- return(False);
- }
+ return True;
+}
- smb_passwd_ptr = smb_pass->smb_passwd;
- }
+static BOOL api_pipe_fault_resp(rpcsrv_struct * l, uint32 status,
+ prs_struct * resp)
+{
+ prs_struct rhdr;
+ prs_struct rfault;
+ RPC_HDR_FAULT hdr_fault;
+ RPC_HDR_RESP hdr_resp;
- /*
- * Set up the sign/seal data.
- */
+ DEBUG(5, ("api_pipe_fault_resp: make response\n"));
+ if (l->auth_validated == False)
{
- uchar p24[24];
- NTLMSSPOWFencrypt(smb_passwd_ptr, lm_owf, p24);
- {
- unsigned char j = 0;
- int ind;
-
- unsigned char k2[8];
+ l->faulted_once_before = True;
+ }
- memcpy(k2, p24, 5);
- k2[5] = 0xe5;
- k2[6] = 0x38;
- k2[7] = 0xb0;
+ prs_init(&(rhdr), 0, 4, False);
+ prs_init(&(rfault), 0, 4, False);
- for (ind = 0; ind < 256; ind++)
- p->ntlmssp_hash[ind] = (unsigned char)ind;
+ /***/
+ /*** set up the header, response header and fault status ***/
+ /***/
- for( ind = 0; ind < 256; ind++) {
- unsigned char tc;
+ hdr_fault.status = status;
+ hdr_fault.reserved = 0x0;
- j += (p->ntlmssp_hash[ind] + k2[ind%8]);
+ hdr_resp.alloc_hint = 0x0;
+ hdr_resp.cancel_count = 0x0;
+ hdr_resp.context_id = 0x0;
+ hdr_resp.reserved = 0x0;
- tc = p->ntlmssp_hash[ind];
- p->ntlmssp_hash[ind] = p->ntlmssp_hash[j];
- p->ntlmssp_hash[j] = tc;
- }
+ make_rpc_hdr(&l->hdr, RPC_FAULT,
+ RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST,
+ l->hdr.call_id, 0x20, 0);
- p->ntlmssp_hash[256] = 0;
- p->ntlmssp_hash[257] = 0;
- }
-/* NTLMSSPhash(p->ntlmssp_hash, p24); */
- p->ntlmssp_seq_num = 0;
+ smb_io_rpc_hdr("hdr", &(l->hdr), &(rhdr), 0);
+ smb_io_rpc_hdr_resp("resp", &(hdr_resp), &(rhdr), 0);
+ smb_io_rpc_hdr_fault("fault", &(hdr_fault), &(rfault), 0);
+ prs_realloc_data(&rhdr, rhdr.offset);
+ prs_realloc_data(&rfault, rfault.offset);
- }
+ /***/
+ /*** link rpc header and fault together ***/
+ /***/
- fstrcpy(p->user_name, user_name);
- fstrcpy(p->unix_user_name, unix_user_name);
- fstrcpy(p->domain, domain);
- fstrcpy(p->wks, wks);
+ prs_link(NULL, &rhdr, &rfault);
+ prs_link(&rhdr, &rfault, NULL);
- /*
- * Store the UNIX credential data (uid/gid pair) in the pipe structure.
- */
-
- p->uid = pass->pw_uid;
- p->gid = pass->pw_gid;
+ prs_init(resp, 0, 4, False);
+ if (!prs_copy(resp, &rhdr))
+ return False;
+ prs_free_data(&rfault);
+ prs_free_data(&rhdr);
- p->ntlmssp_auth_validated = True;
return True;
}
-/*******************************************************************
- The switch table for the pipe names and the functions to handle them.
- *******************************************************************/
-
-struct api_cmd
+static BOOL srv_pipe_bind_and_alt_req(rpcsrv_struct * l,
+ const char *ack_pipe_name,
+ prs_struct * resp,
+ enum RPC_PKT_TYPE pkt_type)
{
- char * pipe_clnt_name;
- char * pipe_srv_name;
- BOOL (*fn) (pipes_struct *, prs_struct *);
-};
-
-static struct api_cmd api_fd_commands[] =
-{
- { "lsarpc", "lsass", api_ntlsa_rpc },
- { "samr", "lsass", api_samr_rpc },
- { "srvsvc", "ntsvcs", api_srvsvc_rpc },
- { "wkssvc", "ntsvcs", api_wkssvc_rpc },
- { "NETLOGON", "lsass", api_netlog_rpc },
-#if DISABLED_IN_2_0
- { "winreg", "winreg", api_reg_rpc },
-#endif
- { "spoolss", "spoolss", api_spoolss_rpc },
- { NULL, NULL, NULL }
-};
+ BOOL ret;
-/*******************************************************************
- This is the client reply to our challenge for an authenticated
- bind request. The challenge we sent is in p->challenge.
-*******************************************************************/
+ prs_struct rhdr;
+ uint32 assoc_gid = l->key.pid;
-static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd)
-{
- RPC_HDR_AUTHA autha_info;
- RPC_AUTH_VERIFIER auth_verifier;
- RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+ l->auth = NULL;
- DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__));
+ /* decode the bind request */
+ smb_io_rpc_hdr_rb("", &l->hdr_rb, &l->data_i, 0);
- if (p->hdr.auth_len == 0) {
- DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n"));
+ if (l->data_i.offset == 0)
return False;
- }
- /*
- * Decode the authentication verifier response.
- */
+ assoc_gid = l->hdr_rb.bba.assoc_gid;
- if(!smb_io_rpc_hdr_autha("", &autha_info, pd, 0)) {
- DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_HDR_AUTHA failed.\n"));
- return False;
+ if (assoc_gid != 0)
+ {
+ l->key.pid = assoc_gid;
}
- if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != NTLMSSP_AUTH_LEVEL) {
- DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n",
- (int)autha_info.auth_type, (int)autha_info.auth_level ));
- return False;
- }
+ if (l->hdr.auth_len != 0)
+ {
+ RPC_HDR_AUTH auth_info;
+ BOOL found = False;
+ int i;
- if(!smb_io_rpc_auth_verifier("", &auth_verifier, pd, 0)) {
- DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_AUTH_VERIFIER failed.\n"));
- return False;
+ /* decode the authentication verifier */
+ smb_io_rpc_hdr_auth("", &auth_info, &l->data_i, 0);
+ if (l->data_i.offset == 0)
+ return False;
+
+ for (i = 0; i < l->num_auths && !found; i++)
+ {
+ if (l->auth_fns[i]->api_is_auth(&auth_info,
+ &l->auth_info))
+ {
+ l->auth = l->auth_fns[i];
+ found = True;
+ }
+ }
+ if (!found)
+ {
+ return False;
+ }
}
+ else
+ {
+ extern srv_auth_fns noauth_fns;
- /*
- * Ensure this is a NTLMSSP_AUTH packet type.
- */
+ l->auth = &noauth_fns;
+ l->auth_info = NULL;
- if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH)) {
- DEBUG(0,("api_pipe_bind_auth_resp: rpc_auth_verifier_chk failed.\n"));
- return False;
+ assoc_gid = l->hdr_rb.bba.assoc_gid;
+ if (assoc_gid != 0)
+ {
+ l->key.pid = assoc_gid;
+ }
}
- if(!smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp, pd, 0)) {
- DEBUG(0,("api_pipe_bind_auth_resp: Failed to unmarshall RPC_AUTH_NTLMSSP_RESP.\n"));
- return False;
+ if (l->auth != NULL)
+ {
+ if (!l->auth->api_auth_chk(l, pkt_type))
+ {
+ if (l->auth_info != NULL)
+ {
+ free(l->auth_info);
+ }
+ l->auth_info = NULL;
+ return False;
+ }
}
+ DEBUG(5, ("api_pipe_bind_req: make response. %d\n", __LINE__));
- /*
- * The following call actually checks the challenge/response data.
- * for correctness against the given DOMAIN\user name.
- */
-
- if (!api_pipe_ntlmssp_verify(p, &ntlmssp_resp))
- return False;
-
- return True;
-}
-
-/*******************************************************************
- Marshall a bind_nak pdu.
-*******************************************************************/
-
-static BOOL setup_bind_nak(pipes_struct *p, prs_struct *pd)
-{
- prs_struct outgoing_rpc;
- RPC_HDR nak_hdr;
- uint16 zero = 0;
-
- /*
- * Marshall directly into the outgoing PDU space. We
- * must do this as we need to set to the bind response
- * header and are never sending more than one PDU here.
- */
+ prs_init(&(l->rdata), 0, 4, False);
+ prs_init(&(rhdr), 0, 4, False);
- prs_init( &outgoing_rpc, 0, 4, MARSHALL);
- prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
+ /***/
+ /*** do the bind ack first ***/
+ /***/
+ make_rpc_hdr_ba(&l->hdr_ba,
+ l->hdr_rb.bba.max_tsize,
+ l->hdr_rb.bba.max_rsize,
+ assoc_gid,
+ ack_pipe_name, 0x1, 0x0, 0x0, &(l->hdr_rb.transfer));
- /*
- * Initialize a bind_nak header.
- */
+ smb_io_rpc_hdr_ba("", &l->hdr_ba, &l->rdata, 0);
+ prs_realloc_data(&l->rdata, l->rdata.offset);
- init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST,
- p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0);
+ if (l->auth != NULL)
+ {
+ /***/
+ /*** now the authentication ***/
+ /***/
- /*
- * Marshall the header into the outgoing PDU.
- */
+ ret = l->auth->api_auth_gen(l, resp, pkt_type);
- if(!smb_io_rpc_hdr("", &nak_hdr, &outgoing_rpc, 0)) {
- DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n"));
+ if (!ret)
+ {
+ free(l->auth_info);
+ l->auth_info = NULL;
+ prs_free_data(&l->rdata);
+ return False;
+ }
+ }
+ else
+ {
return False;
}
- /*
- * Now add the reject reason.
- */
-
- if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero))
- return False;
-
- p->out_data.data_sent_length = 0;
- p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
- p->out_data.current_pdu_sent = 0;
-
- return True;
+ return ret;
}
-/*******************************************************************
- Respond to a pipe bind request.
-*******************************************************************/
-
-static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_PKT_TYPE pkt_type)
+static BOOL api_pipe_bind_and_alt_req(rpcsrv_struct * l,
+ const char *name,
+ prs_struct * resp,
+ enum RPC_PKT_TYPE pkt_type)
{
- RPC_HDR_BA hdr_ba;
- RPC_HDR_RB hdr_rb;
- RPC_HDR_AUTH auth_info;
- uint16 assoc_gid;
fstring ack_pipe_name;
- prs_struct out_hdr_ba;
- prs_struct out_auth;
- prs_struct outgoing_rpc;
+ fstring pipe_srv_name;
int i = 0;
- int auth_len = 0;
-
- p->ntlmssp_auth_requested = False;
- DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__));
+ DEBUG(5, ("api_pipe_bind_req: decode request. %d\n", __LINE__));
- /*
- * Try and find the correct pipe name to ensure
- * that this is a pipe name we support.
- */
-
- for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
- if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
- api_fd_commands[i].fn != NULL) {
- DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
- api_fd_commands[i].pipe_clnt_name,
- api_fd_commands[i].pipe_srv_name));
- fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name);
+ for (i = 0; i < num_cmds; i++)
+ {
+ if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
+ api_fd_commands[i]->fn != NULL)
+ {
+ DEBUG(3,
+ ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n",
+ api_fd_commands[i]->pipe_clnt_name,
+ api_fd_commands[i]->pipe_srv_name));
+ fstrcpy(pipe_srv_name,
+ api_fd_commands[i]->pipe_srv_name);
break;
}
}
- if (api_fd_commands[i].fn == NULL) {
- DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n",
- p->name ));
- if(!setup_bind_nak(p, pd))
- return False;
- return True;
- }
-
- /* decode the bind request */
- if(!smb_io_rpc_hdr_rb("", &hdr_rb, pd, 0)) {
- DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n"));
+ if (api_fd_commands[i]->fn == NULL)
return False;
- }
- /*
- * Check if this is an authenticated request.
- */
-
- if (p->hdr.auth_len != 0) {
- RPC_AUTH_VERIFIER auth_verifier;
- RPC_AUTH_NTLMSSP_NEG ntlmssp_neg;
-
- /*
- * Decode the authentication verifier.
- */
-
- if(!smb_io_rpc_hdr_auth("", &auth_info, pd, 0)) {
- DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
- return False;
- }
-
- /*
- * We only support NTLMSSP_AUTH_TYPE requests.
- */
-
- if(auth_info.auth_type != NTLMSSP_AUTH_TYPE) {
- DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n",
- auth_info.auth_type ));
- return False;
- }
-
- if(!smb_io_rpc_auth_verifier("", &auth_verifier, pd, 0)) {
- DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n"));
- return False;
- }
-
- if(!strequal(auth_verifier.signature, "NTLMSSP")) {
- DEBUG(0,("api_pipe_bind_req: auth_verifier.signature != NTLMSSP\n"));
- return False;
- }
-
- if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) {
- DEBUG(0,("api_pipe_bind_req: auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n",
- auth_verifier.msg_type));
- return False;
- }
-
- if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, pd, 0)) {
- DEBUG(0,("api_pipe_bind_req: Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n"));
- return False;
- }
-
- p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS;
- p->ntlmssp_auth_requested = True;
- }
-
- switch (pkt_type) {
+ switch (pkt_type)
+ {
case RPC_BINDACK:
+ {
/* name has to be \PIPE\xxxxx */
fstrcpy(ack_pipe_name, "\\PIPE\\");
- fstrcat(ack_pipe_name, p->pipe_srv_name);
+ fstrcat(ack_pipe_name, pipe_srv_name);
+ break;
+ }
case RPC_ALTCONTRESP:
+ {
/* secondary address CAN be NULL
* as the specs says it's ignored.
* It MUST NULL to have the spoolss working.
*/
fstrcpy(ack_pipe_name, "");
break;
+ }
default:
+ {
return False;
+ }
}
+ return srv_pipe_bind_and_alt_req(l, ack_pipe_name, resp, pkt_type);
+}
- DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
-
- /*
- * Marshall directly into the outgoing PDU space. We
- * must do this as we need to set to the bind response
- * header and are never sending more than one PDU here.
- */
-
- prs_init( &outgoing_rpc, 0, 4, MARSHALL);
- prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False);
-
- /*
- * Setup the memory to marshall the ba header, and the
- * auth footers.
- */
-
- if(!prs_init(&out_hdr_ba, 1024, 4, MARSHALL)) {
- DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n"));
- return False;
- }
-
- if(!prs_init(&out_auth, 1024, 4, MARSHALL)) {
- DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n"));
- prs_mem_free(&out_hdr_ba);
- return False;
- }
-
- if (p->ntlmssp_auth_requested)
- assoc_gid = 0x7a77;
- else
- assoc_gid = hdr_rb.bba.assoc_gid;
-
- /*
- * Create the bind response struct.
- */
+/*
+ * The RPC Alter-Context call is used only by the spoolss pipe
+ * simply because there is a bug (?) in the MS unmarshalling code
+ * or in the marshalling code. If it's in the later, then Samba
+ * have the same bug.
+ */
+static BOOL api_pipe_bind_req(rpcsrv_struct * l, const char *name,
+ prs_struct * resp)
+{
+ return api_pipe_bind_and_alt_req(l, name, resp, RPC_BINDACK);
+}
- init_rpc_hdr_ba(&hdr_ba,
- hdr_rb.bba.max_tsize,
- hdr_rb.bba.max_rsize,
- assoc_gid,
- ack_pipe_name,
- 0x1, 0x0, 0x0,
- &hdr_rb.transfer);
+static BOOL api_pipe_alt_req(rpcsrv_struct * l, const char *name,
+ prs_struct * resp)
+{
+ return api_pipe_bind_and_alt_req(l, name, resp, RPC_ALTCONTRESP);
+}
- /*
- * and marshall it.
- */
+static BOOL api_pipe_request(rpcsrv_struct * l, const char *name,
+ prs_struct * resp)
+{
+ int i = 0;
- if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n"));
- goto err_exit;
+ if (l->auth != NULL && l->auth_validated)
+ {
+ DEBUG(10, ("api_pipe_request: validated auth\n"));
+ if (!l->auth->api_decode_pdu(l))
+ return False;
}
- /*
- * Now the authentication.
- */
-
- if (p->ntlmssp_auth_requested) {
- RPC_AUTH_VERIFIER auth_verifier;
- RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal;
-
- generate_random_buffer(p->challenge, 8, False);
-
- /*** Authentication info ***/
-
- init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1);
- if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n"));
- goto err_exit;
- }
+ for (i = 0; i < num_cmds; i++)
+ {
+ if (strequal(api_fd_commands[i]->pipe_clnt_name, name) &&
+ api_fd_commands[i]->fn != NULL)
+ {
+ DEBUG(3,
+ ("Doing \\PIPE\\%s\n",
+ api_fd_commands[i]->pipe_clnt_name));
+ if (!api_fd_commands[i]->fn(l))
+ {
+ return False;
+ }
+ l->rdata_offset = 0;
- /*** NTLMSSP verifier ***/
+ /* create the rpc pdu */
+ return create_rpc_reply(l, 0, resp);
- init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE);
- if(!smb_io_rpc_auth_verifier("", &auth_verifier, &out_auth, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n"));
- goto err_exit;
}
+ }
+ return False;
+}
- /* NTLMSSP challenge ***/
+static BOOL rpc_redir_local(rpcsrv_struct * l, prs_struct * req,
+ prs_struct * resp, const char *name)
+{
+ BOOL reply = False;
+ BOOL last;
+ BOOL first;
- init_rpc_auth_ntlmssp_chal(&ntlmssp_chal, p->ntlmssp_chal_flags, p->challenge);
- if(!smb_io_rpc_auth_ntlmssp_chal("", &ntlmssp_chal, &out_auth, 0)) {
- DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_NTLMSSP_CHAL failed.\n"));
- goto err_exit;
+ if (req->data == NULL || req->data_size == 0)
+ {
+ if (l->rdata.data == NULL)
+ {
+ return False;
}
+ /* hmm, must need some more data.
+ * create, flatten and return data in a single pdu
+ */
+ if (!create_rpc_reply(l, l->rdata_offset, resp))
+ return False;
- /* Auth len in the rpc header doesn't include auth_header. */
- auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN;
+ return True;
}
- /*
- * Create the header, now we know the length.
- */
-
- init_rpc_hdr(&p->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST,
- p->hdr.call_id,
- RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth),
- auth_len);
+ if (req->data == NULL)
+ return False;
- /*
- * Marshall the header into the outgoing PDU.
+ /* lkclXXXX still assume that the first complete PDU is always
+ in a single request!!!
*/
+ /* process the rpc header */
+ req->offset = 0x0;
+ req->io = True;
+ smb_io_rpc_hdr("hdr", &l->hdr, req, 0);
- if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) {
- DEBUG(0,("pi_pipe_bind_req: marshalling of RPC_HDR failed.\n"));
- goto err_exit;
- }
+ if (req->offset == 0)
+ return False;
- /*
- * Now add the RPC_HDR_BA and any auth needed.
- */
+ last = IS_BITS_SET_ALL(l->hdr.flags, RPC_FLG_LAST);
+ first = IS_BITS_SET_ALL(l->hdr.flags, RPC_FLG_FIRST);
- if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) {
- DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n"));
- goto err_exit;
+ if (l->hdr.pkt_type == RPC_BIND || l->hdr.pkt_type == RPC_BINDRESP)
+ {
+ last = True;
+ first = True;
}
- if(p->ntlmssp_auth_requested && !prs_append_prs_data( &outgoing_rpc, &out_auth)) {
- DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n"));
- goto err_exit;
+ if (first)
+ {
+ prs_init(&l->data_i, 0, 4, True);
+ prs_set_packtype(&l->data_i, l->hdr.pack_type);
}
-
- /*
- * Setup the lengths for the initial reply.
- */
-
- p->out_data.data_sent_length = 0;
- p->out_data.current_pdu_len = prs_offset(&outgoing_rpc);
- p->out_data.current_pdu_sent = 0;
-
- prs_mem_free(&out_hdr_ba);
- prs_mem_free(&out_auth);
-
- return True;
-
- err_exit:
-
- prs_mem_free(&out_hdr_ba);
- prs_mem_free(&out_auth);
- return False;
-}
-
-/*******************************************************************
- Respond to a pipe bind request.
-*******************************************************************/
-
-static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
-{
- return api_pipe_bind_and_alt_req(p, pd, RPC_BINDACK);
-}
-
-/*******************************************************************
- Respond to a pipe alter request.
-
- The RPC Alter-Context call is used only by the spoolss pipe
- simply because there is a bug (?) in the MS unmarshalling code
- or in the marshalling code. If it's in the later, then Samba
- have the same bug.
-*******************************************************************/
-
-static BOOL api_pipe_altercontext_req(pipes_struct *p, prs_struct *pd)
-{
- return api_pipe_bind_and_alt_req(p, pd, RPC_ALTCONTRESP);
-}
-
-/****************************************************************************
- Deal with sign & seal processing on an RPC request.
-****************************************************************************/
-
-static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in)
-{
- /*
- * We always negotiate the following two bits....
- */
- BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN);
- BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL);
- int data_len;
- int auth_len;
- uint32 old_offset;
- uint32 crc32 = 0;
-
- auth_len = p->hdr.auth_len;
-
- if ((auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) && auth_verify) {
- DEBUG(0,("api_pipe_auth_process: Incorrect auth_len %d.\n", auth_len ));
- return False;
+ if (last)
+ {
+ prs_append_data(&l->data_i,
+ prs_data(req, req->offset),
+ req->data_size - req->offset);
+ }
+ else
+ {
+ prs_init(resp, 0, 4, False);
+ return True;
}
- /*
- * The following is that length of the data we must verify or unseal.
- * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN
- * preceeding the auth_data.
+ /* previous authentication failure. don't give a monkey's what
+ * is sent to us, we reject it, outright
*/
- data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
- (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len;
-
- DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n",
- BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
-
- if (auth_seal) {
- char *data = prs_data_p(rpc_in) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN;
- NTLMSSPcalc_p(p, (uchar*)data, data_len);
- crc32 = crc32_calc_buffer(data, data_len);
+ if (l->faulted_once_before)
+ {
+ DEBUG(10,
+ ("rpc_redir_local: faulted before (so do it again)\n"));
+ prs_free_data(&l->data_i);
+ return api_pipe_fault_resp(l, 0x1c010002, resp);
}
- old_offset = prs_offset(rpc_in);
-
- if (auth_seal || auth_verify) {
- RPC_HDR_AUTH auth_info;
-
- if(!prs_set_offset(rpc_in, old_offset + data_len)) {
- DEBUG(0,("api_pipe_auth_process: cannot move offset to %u.\n",
- (unsigned int)old_offset + data_len ));
- return False;
+ switch (l->hdr.pkt_type)
+ {
+ case RPC_BIND:
+ {
+ reply = api_pipe_bind_req(l, name, resp);
+ if (!reply)
+ {
+ reply = api_pipe_nack_resp(l, 0x0, resp);
+ }
+ break;
}
-
- if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) {
- DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_HDR_AUTH.\n"));
- return False;
+ case RPC_ALTCONT:
+ {
+ reply = api_pipe_alt_req(l, name, resp);
+ break;
}
- }
-
- if (auth_verify) {
- RPC_AUTH_NTLMSSP_CHK ntlmssp_chk;
- char *req_data = prs_data_p(rpc_in) + prs_offset(rpc_in) + 4;
-
- DEBUG(5,("api_pipe_auth_process: auth %d\n", prs_offset(rpc_in) + 4));
-
- /*
- * Ensure we have RPC_AUTH_NTLMSSP_CHK_LEN - 4 more bytes in the
- * incoming buffer.
- */
- if(prs_mem_get(rpc_in, RPC_AUTH_NTLMSSP_CHK_LEN - 4) == NULL) {
- DEBUG(0,("api_pipe_auth_process: missing %d bytes in buffer.\n",
- RPC_AUTH_NTLMSSP_CHK_LEN - 4 ));
- return False;
+ case RPC_REQUEST:
+ {
+ if (l->auth != NULL && !l->auth_validated)
+ {
+ /* authentication _was_ requested
+ and it failed. sorry, no deal!
+ */
+ reply = False;
+ }
+ else
+ {
+ vuser_key key = l->key;
+ /* read the rpc header */
+ reply =
+ smb_io_rpc_hdr_req("req",
+ &(l->hdr_req),
+ &l->data_i, 0);
+ if (reply)
+ {
+ if (l->hdr_req.context_id != 0)
+ {
+ key.vuid =
+ l->hdr_req.context_id;
+ }
+ reply = become_vuser(&key) ||
+ become_guest();
+
+ }
+ if (reply)
+ {
+ reply =
+ api_pipe_request(l, name,
+ resp);
+ }
+ }
+ break;
}
-
- NTLMSSPcalc_p(p, (uchar*)req_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4);
- if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, rpc_in, 0)) {
- DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_AUTH_NTLMSSP_CHK.\n"));
- return False;
+ case RPC_BINDRESP: /* not the real name! */
+ {
+ if (l->auth != NULL)
+ {
+ reply = l->auth->api_auth_chk(l,
+ l->hdr.
+ pkt_type);
+ }
+ if (!reply)
+ {
+ l->auth = NULL;
+ if (l->auth_info != NULL)
+ {
+ free(l->auth_info);
+ l->auth_info = NULL;
+ }
+ l->auth_validated = False;
+ }
+ break;
}
+ }
- if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32, p->ntlmssp_seq_num)) {
- DEBUG(0,("api_pipe_auth_process: NTLMSSP check failed.\n"));
- return False;
- }
+ if (!reply)
+ {
+ reply = api_pipe_fault_resp(l, 0x1c010002, resp);
}
- /*
- * Return the current pointer to the data offset.
- */
+ if (reply)
+ {
+ /* flatten the data into a single pdu */
+ DEBUG(200, ("rpc_redir_local: %d\n", __LINE__));
+ prs_debug_out(resp, "redir_local resp", 200);
- if(!prs_set_offset(rpc_in, old_offset)) {
- DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n",
- (unsigned int)old_offset ));
- return False;
+ prs_free_data(&l->data_i);
+ return True;
}
- return True;
-}
+ /* delete intermediate data used to set up the pdu. leave
+ rdata alone because that's got the rest of the data in it */
+ prs_free_data(&l->data_i);
-/****************************************************************************
- Find the correct RPC function to call for this request.
- If the pipe is authenticated then become the correct UNIX user
- before doing the call.
-****************************************************************************/
+ return reply;
+}
-static BOOL api_pipe_request(pipes_struct *p, prs_struct *rpc_in)
+/*******************************************************************
+ receives a netlogon pipe and responds.
+ ********************************************************************/
+static BOOL api_rpc_command(rpcsrv_struct * l, const char *rpc_name,
+ const struct api_struct *api_rpc_cmds)
{
- int i = 0;
- BOOL ret = False;
- BOOL changed_user_id = False;
-
- if (p->ntlmssp_auth_validated) {
- if (!api_pipe_auth_process(p, rpc_in))
- return False;
-
- if(!become_authenticated_pipe_user(p))
- return False;
-
- changed_user_id = True;
- }
+ int fn_num;
+ DEBUG(4,
+ ("api_rpc_command: %s op 0x%x - ", rpc_name, l->hdr_req.opnum));
- for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) {
- if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) &&
- api_fd_commands[i].fn != NULL) {
- DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name));
- ret = api_fd_commands[i].fn(p, rpc_in);
+ for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++)
+ {
+ if (api_rpc_cmds[fn_num].opnum == l->hdr_req.opnum
+ && api_rpc_cmds[fn_num].fn != NULL)
+ {
+ DEBUG(3,
+ ("api_rpc_command: %s\n",
+ api_rpc_cmds[fn_num].name));
+ break;
}
}
- if(changed_user_id)
- unbecome_authenticated_pipe_user(p);
+ if (api_rpc_cmds[fn_num].name == NULL)
+ {
+ DEBUG(4, ("unknown\n"));
+ return False;
+ }
- return ret;
-}
+ prs_init(&l->rdata, 0, 4, False);
-/****************************************************************************
- This function is the entry point to processing a DCE/RPC request.
- All the data for the request (including RPC headers and authentication
- verifiers) must be linearized in the input_data buffer, with a length
- of data_len.
+ /* do the actual command */
+ api_rpc_cmds[fn_num].fn(l, &l->data_i, &(l->rdata));
- The output is placed into the pipes_struct, and handed back to the
- client on demand.
-****************************************************************************/
+ if (l->rdata.data == NULL || l->rdata.offset == 0)
+ {
+ prs_free_data(&l->rdata);
+ return False;
+ }
-BOOL rpc_command(pipes_struct *p, char *input_data, int data_len)
-{
- prs_struct rpc_in;
- BOOL reply = False;
+ prs_realloc_data(&l->rdata, l->rdata.offset);
- if (input_data == NULL)
- return False;
+ DEBUG(10, ("called %s\n", rpc_name));
- prs_init(&rpc_in, 0, 4, UNMARSHALL);
+ return True;
+}
- /*
- * Hand the data to the prs_struct, but don't let
- * it own it.
- */
- prs_give_memory( &rpc_in, input_data, (uint32)data_len, False);
- /* Unmarshall the rpc header */
- if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
- DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n"));
+/*******************************************************************
+ receives a netlogon pipe and responds.
+ ********************************************************************/
+BOOL api_rpcTNP(rpcsrv_struct * l, const char *rpc_name,
+ const struct api_struct *api_rpc_cmds)
+{
+ if (l == NULL)
+ {
+ DEBUG(1, ("NULL rpcsrv_struct\n"));
return False;
}
-
- /*
- * Create the response data buffer.
- */
-
- if(!pipe_init_outgoing_data(&p->out_data)) {
- DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n"));
+ if (l->data_i.data == NULL)
+ {
+ DEBUG(2, ("%s: NULL data received\n", rpc_name));
return False;
}
- switch (p->hdr.pkt_type) {
- case RPC_BIND:
- reply = api_pipe_bind_req(p, &rpc_in);
- break;
- case RPC_ALTCONT:
- reply = api_pipe_altercontext_req(p, &rpc_in);
- break;
- case RPC_REQUEST:
- if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) {
- /* authentication _was_ requested
- and it failed. sorry, no deal!
- */
- DEBUG(0,("rpc_command: RPC request received on pipe %s where \
-authentication failed. Denying the request.\n", p->name));
- reply = False;
- } else {
- /* read the RPC request header */
- if(!smb_io_rpc_hdr_req("req", &p->hdr_req, &rpc_in, 0)) {
- DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR_REQ.\n"));
- return False;
- }
- reply = api_pipe_request(p, &rpc_in);
- }
- break;
- case RPC_BINDRESP: /* not the real name! */
- reply = api_pipe_bind_auth_resp(p, &rpc_in);
- break;
+ /* interpret the command */
+ if (!api_rpc_command(l, rpc_name, api_rpc_cmds))
+ {
+ return False;
}
- if (!reply)
- DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n"));
-
- return reply;
+ return True;
}
-
/*******************************************************************
- Calls the underlying RPC function for a named pipe.
+ entry point from msrpc to smb. adds data received to pdu; checks
+ pdu; hands pdu off to msrpc, which gets a pdu back (except in the
+ case of the RPC_BINDCONT pdu).
********************************************************************/
-
-BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds,
- prs_struct *rpc_in)
+BOOL rpc_local(rpcsrv_struct * l, char *data, int len, const char *name)
{
- int fn_num;
+ BOOL reply = False;
- /* interpret the command */
- DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum));
+ DEBUG(10, ("rpc_local: len %d\n", len));
- for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) {
- if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) {
- DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name));
- break;
- }
- }
+ if (len != 0)
+ {
+ reply = prs_add_data(&l->smb_pdu, data, len);
- if (api_rpc_cmds[fn_num].name == NULL) {
- DEBUG(4, ("unknown\n"));
- return False;
+ if (reply && is_complete_pdu(&l->smb_pdu))
+ {
+ l->smb_pdu.offset = l->smb_pdu.data_size;
+ prs_link(NULL, &l->smb_pdu, NULL);
+ reply =
+ rpc_redir_local(l, &l->smb_pdu, &l->rsmb_pdu,
+ name);
+ prs_free_data(&l->smb_pdu);
+ prs_init(&l->smb_pdu, 0, 4, True);
+ }
}
-
- /* do the actual command */
- if(!api_rpc_cmds[fn_num].fn(p->vuid, rpc_in, &p->out_data.rdata)) {
- DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name));
- prs_mem_free(&p->out_data.rdata);
- return False;
+ else
+ {
+ if (l->rdata.data == NULL || l->rdata.data_size == 0)
+ {
+ DEBUG(10, ("rpc_local: no data to send\n"));
+ return True;
+ }
+ prs_free_data(&l->smb_pdu);
+ prs_init(&l->smb_pdu, 0, 4, True);
+ reply = rpc_redir_local(l, &l->smb_pdu, &l->rsmb_pdu, name);
}
-
- DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name));
-
- return True;
+ return reply;
}
diff --git a/source/rpc_server/srv_reg.c b/source/rpc_server/srv_reg.c
index f2083fa22f5..0e1d3b5581a 100644
--- a/source/rpc_server/srv_reg.c
+++ b/source/rpc_server/srv_reg.c
@@ -1,11 +1,12 @@
+
/*
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
- * Copyright (C) Hewlett-Packard Company 1999.
+ * Copyright (C) Paul Ashton 1997,
+ * Copyright (C) Lars Kneschke 2000.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,219 +25,172 @@
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
-
-/*******************************************************************
- reg_reply_unknown_1
- ********************************************************************/
-static void reg_reply_close(REG_Q_CLOSE *q_r,
- prs_struct *rdata)
+#if 0
+/****************************************************************************
+ set reg name
+****************************************************************************/
+static BOOL set_policy_reg_name(struct policy_cache *cache, POLICY_HND *hnd,
+ fstring name)
{
- REG_R_CLOSE r_u;
-
- /* set up the REG unknown_1 response */
- memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
-
- /* close the policy handle */
- if (close_lsa_policy_hnd(&(q_r->pol)))
+ char *dev = strdup(name);
+ if (dev != NULL)
{
- r_u.status = 0;
- }
- else
- {
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
+ if (set_policy_state(cache, hnd, NULL, (void*)dev))
+ {
+ DEBUG(3,("Registry setting policy name=%s\n", name));
+ return True;
+ }
+ free(dev);
}
- DEBUG(5,("reg_unknown_1: %d\n", __LINE__));
-
- /* store the response in the SMB stream */
- reg_io_r_close("", &r_u, rdata, 0);
-
- DEBUG(5,("reg_unknown_1: %d\n", __LINE__));
+ DEBUG(3,("Error setting policy name=%s\n", name));
+ return False;
}
-
-/*******************************************************************
- api_reg_close
- ********************************************************************/
-static BOOL api_reg_close( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
+#endif
+/****************************************************************************
+ get reg name
+****************************************************************************/
+static BOOL get_policy_reg_name(struct policy_cache *cache, POLICY_HND *hnd,
+ fstring name)
{
- REG_Q_CLOSE q_r;
-
- /* grab the reg unknown 1 */
- reg_io_q_close("", &q_r, data, 0);
+ char *dev = (char*)get_policy_state_info(cache, hnd);
- /* construct reply. always indicate success */
- reg_reply_close(&q_r, rdata);
+ if (dev != NULL)
+ {
+ fstrcpy(name, dev);
+ DEBUG(5,("getting policy reg name=%s\n", name));
+ return True;
+ }
- return True;
+ DEBUG(3,("Error getting policy reg name\n"));
+ return False;
}
-
/*******************************************************************
- reg_reply_open
+ api_reg_close
********************************************************************/
-static void reg_reply_open(REG_Q_OPEN_HKLM *q_r,
- prs_struct *rdata)
+static BOOL api_reg_close( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
{
- REG_R_OPEN_HKLM r_u;
-
- r_u.status = 0x0;
- /* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !open_lsa_policy_hnd(&(r_u.pol)))
+ REG_Q_CLOSE q_r;
+ REG_R_CLOSE r_u;
+ ZERO_STRUCT(q_r);
+ ZERO_STRUCT(r_u);
+
+ /* grab the reg unknown 1 */
+ if (!reg_io_q_close("", &q_r, data, 0))
{
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ return False;
}
- DEBUG(5,("reg_open: %d\n", __LINE__));
-
- /* store the response in the SMB stream */
- reg_io_r_open_hklm("", &r_u, rdata, 0);
-
- DEBUG(5,("reg_open: %d\n", __LINE__));
-}
+
+ memcpy(&r_u.pol, &q_r.pol, sizeof(POLICY_HND));
+
+ /* construct reply. always indicate success */
+ r_u.status = _reg_close(&r_u.pol);
+
+ /* store the response in the SMB stream */
+ return reg_io_r_close("", &r_u, rdata, 0);
+}
/*******************************************************************
api_reg_open
********************************************************************/
-static BOOL api_reg_open( uint16 vuid, prs_struct *data,
+static BOOL api_reg_open( rpcsrv_struct *p, prs_struct *data,
prs_struct *rdata )
{
- REG_Q_OPEN_HKLM q_u;
-
- /* grab the reg open */
- reg_io_q_open_hklm("", &q_u, data, 0);
-
- /* construct reply. always indicate success */
- reg_reply_open(&q_u, rdata);
-
- return True;
-}
-
-
-/*******************************************************************
- reg_reply_open_entry
- ********************************************************************/
-static void reg_reply_open_entry(REG_Q_OPEN_ENTRY *q_u,
- prs_struct *rdata)
-{
- uint32 status = 0;
- POLICY_HND pol;
- REG_R_OPEN_ENTRY r_u;
- fstring name;
-
- DEBUG(5,("reg_open_entry: %d\n", __LINE__));
-
- if (status == 0 && find_lsa_policy_by_hnd(&(q_u->pol)) == -1)
+ REG_Q_OPEN_HKLM q_u;
+ REG_R_OPEN_HKLM r_u;
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ /* grab the reg open */
+ if (!reg_io_q_open_hklm("", &q_u, data, 0))
{
- status = 0xC000000 | NT_STATUS_INVALID_HANDLE;
+ return False;
}
- if (status == 0x0 && !open_lsa_policy_hnd(&pol))
- {
- status = 0xC000000 | NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
- }
-
- fstrcpy(name, dos_unistrn2(q_u->uni_name.buffer, q_u->uni_name.uni_str_len));
-
- if (status == 0x0)
- {
- DEBUG(5,("reg_open_entry: %s\n", name));
- /* lkcl XXXX do a check on the name, here */
- if (!strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions"))
- {
- status = 0xC000000 | NT_STATUS_ACCESS_DENIED;
- }
- }
-
- if (status == 0x0 && !set_lsa_policy_reg_name(&pol, name))
- {
- status = 0xC000000 | NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
- }
-
- init_reg_r_open_entry(&r_u, &pol, status);
-
- /* store the response in the SMB stream */
- reg_io_r_open_entry("", &r_u, rdata, 0);
-
- DEBUG(5,("reg_open_entry: %d\n", __LINE__));
+
+ r_u.status = _reg_open(&r_u.pol, q_u.access_mask);
+
+ /* store the response in the SMB stream */
+ return reg_io_r_open_hklm("", &r_u, rdata, 0);
}
/*******************************************************************
api_reg_open_entry
********************************************************************/
-static BOOL api_reg_open_entry( uint16 vuid, prs_struct *data,
+static BOOL api_reg_open_entry( rpcsrv_struct *p, prs_struct *data,
prs_struct *rdata )
{
+ uint32 status;
+
+ POLICY_HND entry_pol;
REG_Q_OPEN_ENTRY q_u;
+ REG_R_OPEN_ENTRY r_u;
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
/* grab the reg open entry */
- reg_io_q_open_entry("", &q_u, data, 0);
+ if (!reg_io_q_open_entry("", &q_u, data, 0))
+ {
+ return False;
+ }
/* construct reply. */
- reg_reply_open_entry(&q_u, rdata);
+ status = _reg_open_entry(&q_u.pol,&q_u.uni_name,q_u.unknown_0,q_u.access_mask,&entry_pol);
+
+ make_reg_r_open_entry(&r_u, &entry_pol, status);
- return True;
+ /* store the response in the SMB stream */
+ return reg_io_r_open_entry("", &r_u, rdata, 0);
}
/*******************************************************************
- reg_reply_info
+ api_reg_info
********************************************************************/
-static void reg_reply_info(REG_Q_INFO *q_u,
- prs_struct *rdata)
+static BOOL api_reg_info( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
{
- uint32 status = 0;
-
REG_R_INFO r_u;
+ REG_Q_INFO q_u;
+ BUFFER2 buf;
- DEBUG(5,("reg_info: %d\n", __LINE__));
+ uint32 status;
+ uint32 type = 0xcafeface;
- if (status == 0 && find_lsa_policy_by_hnd(&(q_u->pol)) == -1)
- {
- status = 0xC000000 | NT_STATUS_INVALID_HANDLE;
- }
+ ZERO_STRUCT(r_u);
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(buf);
- if (status == 0)
+
+ /* grab the reg unknown 0x11*/
+ if (!reg_io_q_info("", &q_u, data, 0))
{
+ return False;
}
- /* This makes the server look like a member server to clients */
- /* which tells clients that we have our own local user and */
- /* group databases and helps with ACL support. */
- init_reg_r_info(&r_u, 1, "ServerNT", 0x12, 0x12, status);
-
- /* store the response in the SMB stream */
- reg_io_r_info("", &r_u, rdata, 0);
-
- DEBUG(5,("reg_open_entry: %d\n", __LINE__));
-}
-
-/*******************************************************************
- api_reg_info
- ********************************************************************/
-static BOOL api_reg_info( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- REG_Q_INFO q_u;
-
- /* grab the reg unknown 0x11*/
- reg_io_q_info("", &q_u, data, 0);
/* construct reply. always indicate success */
- reg_reply_info(&q_u, rdata);
+ status = _reg_info(&q_u.pol, &buf, &type);
- return True;
+ make_reg_r_info(&r_u, &type, &buf, status);
+
+ /* store the response in the SMB stream */
+ return reg_io_r_info("", &r_u, rdata, 0);
}
/*******************************************************************
array of \PIPE\reg operations
********************************************************************/
-static struct api_struct api_reg_cmds[] =
+static const struct api_struct api_reg_cmds[] =
{
{ "REG_CLOSE" , REG_CLOSE , api_reg_close },
{ "REG_OPEN_ENTRY" , REG_OPEN_ENTRY , api_reg_open_entry },
@@ -248,8 +202,8 @@ static struct api_struct api_reg_cmds[] =
/*******************************************************************
receives a reg pipe and responds.
********************************************************************/
-BOOL api_reg_rpc(pipes_struct *p, prs_struct *data)
+BOOL api_reg_rpc(rpcsrv_struct *p)
{
- return api_rpcTNP(p, "api_reg_rpc", api_reg_cmds, data);
+ return api_rpcTNP(p, "api_reg_rpc", api_reg_cmds);
}
diff --git a/source/rpc_server/srv_samr.c b/source/rpc_server/srv_samr.c
index 169dc2169ed..d92e299cb50 100644
--- a/source/rpc_server/srv_samr.c
+++ b/source/rpc_server/srv_samr.c
@@ -3,9 +3,8 @@
* Unix SMB/Netbios implementation.
* Version 1.9.
* RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-1997,
- * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
- * Copyright (C) Paul Ashton 1997.
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,1698 +23,1150 @@
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
-extern fstring global_myworkgroup;
+extern fstring global_sam_name;
extern pstring global_myname;
extern DOM_SID global_sam_sid;
-
-extern rid_name domain_group_rids[];
-extern rid_name domain_alias_rids[];
-extern rid_name builtin_alias_rids[];
+extern DOM_SID global_sid_S_1_1;
+extern DOM_SID global_sid_S_1_5_20;
/*******************************************************************
- This next function should be replaced with something that
- dynamically returns the correct user info..... JRA.
+ api_samr_close_hnd
********************************************************************/
-
-static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
- int start_idx,
- int *total_entries, int *num_entries,
- int max_num_entries,
- uint16 acb_mask)
+static BOOL api_samr_close_hnd( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- void *vp = NULL;
- struct sam_passwd *pwd = NULL;
-
- (*num_entries) = 0;
- (*total_entries) = 0;
-
- if (pw_buf == NULL) return False;
-
- vp = startsmbpwent(False);
- if (!vp)
+ SAMR_Q_CLOSE_HND q_u;
+ SAMR_R_CLOSE_HND r_u;
+ if (!samr_io_q_close_hnd("", &q_u, data, 0))
{
- DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
return False;
}
-
- while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries)
- {
- int user_name_len;
-
- if (start_idx > 0)
- {
- /* skip the requested number of entries.
- not very efficient, but hey...
- */
- start_idx--;
- continue;
- }
-
- user_name_len = strlen(pwd->smb_name);
- init_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->smb_name, user_name_len);
- init_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
- pw_buf[(*num_entries)].user_rid = pwd->user_rid;
- memset((char *)pw_buf[(*num_entries)].nt_pwd, '\0', 16);
-
- /* Now check if the NT compatible password is available. */
- if (pwd->smb_nt_passwd != NULL)
- {
- memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
- }
-
- pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
-
- DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
- (*num_entries), pwd->smb_name,
- pwd->user_rid, pwd->acct_ctrl));
-
- if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
- {
- DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
- (*num_entries)++;
- }
- else
- {
- DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
- }
-
- (*total_entries)++;
- }
-
- endsmbpwent(vp);
-
- return (*num_entries) > 0;
+ r_u.status = _samr_close(&q_u.pol);
+ memcpy(&r_u.pol, &q_u.pol, sizeof(q_u.pol));
+ return samr_io_r_close_hnd("", &r_u, rdata, 0);
}
+
/*******************************************************************
- samr_reply_unknown_1
+ api_samr_unknown_2d
********************************************************************/
-static void samr_reply_close_hnd(SAMR_Q_CLOSE_HND *q_u,
- prs_struct *rdata)
+static BOOL api_samr_unknown_2d( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_CLOSE_HND r_u;
-
- /* set up the SAMR unknown_1 response */
- memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
-
- /* close the policy handle */
- if (close_lsa_policy_hnd(&(q_u->pol)))
- {
- r_u.status = 0;
- }
- else
+ SAMR_Q_UNKNOWN_2D q_u;
+ SAMR_R_UNKNOWN_2D r_u;
+ if (!samr_io_q_unknown_2d("", &q_u, data, 0))
{
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_INVALID;
+ return False;
}
-
- DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
-
- /* store the response in the SMB stream */
- samr_io_r_close_hnd("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_reply_close_hnd: %d\n", __LINE__));
-
+ r_u.status = _samr_unknown_2d(&q_u.dom_pol, &q_u.sid.sid);
+ return samr_io_r_unknown_2d("", &r_u, rdata, 0);
}
/*******************************************************************
- api_samr_close_hnd
+ api_samr_open_domain
********************************************************************/
-static BOOL api_samr_close_hnd( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_CLOSE_HND q_u;
+ SAMR_Q_OPEN_DOMAIN q_u;
+ SAMR_R_OPEN_DOMAIN r_u;
+ if (!samr_io_q_open_domain("", &q_u, data, 0))
+ {
+ return False;
+ }
- /* grab the samr unknown 1 */
- samr_io_q_close_hnd("", &q_u, data, 0);
- /* construct reply. always indicate success */
- samr_reply_close_hnd(&q_u, rdata);
+ r_u.status = _samr_open_domain(&q_u.connect_pol, q_u.flags,
+ &q_u.dom_sid.sid,
+ &r_u.domain_pol);
- return True;
+ return samr_io_r_open_domain("", &r_u, rdata, 0);
}
-
/*******************************************************************
- samr_reply_open_domain
+ api_samr_usrdom_pwinfo
********************************************************************/
-static void samr_reply_open_domain(SAMR_Q_OPEN_DOMAIN *q_u,
- prs_struct *rdata)
+static BOOL api_samr_get_usrdom_pwinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_OPEN_DOMAIN r_u;
- BOOL pol_open = False;
-
- r_u.status = 0x0;
-
- /* find the connection policy handle. */
- if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->connect_pol)) == -1))
- {
- r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
-
- /* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.domain_pol))))
- {
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- /* associate the domain SID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_lsa_policy_samr_sid(&(r_u.domain_pol), &(q_u->dom_sid.sid)))
+ SAMR_Q_GET_USRDOM_PWINFO q_u;
+ SAMR_R_GET_USRDOM_PWINFO r_u;
+ if (!samr_io_q_get_usrdom_pwinfo("", &q_u, data, 0))
{
- /* oh, whoops. don't know what error message to return, here */
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- if (r_u.status != 0 && pol_open)
- {
- close_lsa_policy_hnd(&(r_u.domain_pol));
+ return False;
}
- DEBUG(5,("samr_open_domain: %d\n", __LINE__));
- /* store the response in the SMB stream */
- samr_io_r_open_domain("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_open_domain: %d\n", __LINE__));
+ r_u.status = _samr_get_usrdom_pwinfo(&q_u.user_pol,
+ &r_u.unknown_0, &r_u.unknown_1);
+ return samr_io_r_get_usrdom_pwinfo("", &r_u, rdata, 0);
}
+
/*******************************************************************
- api_samr_open_domain
+ api_samr_query_sec_obj
********************************************************************/
-static BOOL api_samr_open_domain( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_sec_obj( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_OPEN_DOMAIN q_u;
+ SAMR_Q_QUERY_SEC_OBJ q_u;
+ SAMR_R_QUERY_SEC_OBJ r_u;
- /* grab the samr open */
- samr_io_q_open_domain("", &q_u, data, 0);
+ ZERO_STRUCT(r_u);
+ ZERO_STRUCT(q_u);
- /* construct reply. always indicate success */
- samr_reply_open_domain(&q_u, rdata);
+ if (!samr_io_q_query_sec_obj("", &q_u, data, 0))
+ {
+ return False;
+ }
- return True;
+ r_u.status = _samr_query_sec_obj(&q_u.user_pol, &r_u.buf);
+ r_u.ptr = 1; /* man, we don't have any choice! NT bombs otherwise! */
+ return samr_io_r_query_sec_obj("", &r_u, rdata, 0);
}
/*******************************************************************
- samr_reply_unknown_2c
+ api_samr_enum_dom_users
********************************************************************/
-static void samr_reply_unknown_2c(SAMR_Q_UNKNOWN_2C *q_u,
- prs_struct *rdata)
+static BOOL api_samr_enum_dom_users( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_UNKNOWN_2C r_u;
- uint32 status = 0x0;
+ SAMR_Q_ENUM_DOM_USERS q_e;
+ SAMR_R_ENUM_DOM_USERS r_e;
+ uint32 num_entries = 0;
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
+ BOOL ret;
- /* find the user's rid */
- if ((status == 0x0) && (get_lsa_policy_samr_rid(&(q_u->user_pol)) == 0xffffffff))
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_e);
+
+ if (!samr_io_q_enum_dom_users("", &q_e, data, 0))
{
- status = NT_STATUS_OBJECT_TYPE_MISMATCH;
+ return False;
}
- init_samr_r_unknown_2c(&r_u, status);
-
- DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
-
- /* store the response in the SMB stream */
- samr_io_r_unknown_2c("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_unknown_2c: %d\n", __LINE__));
-}
+ r_e.status = _samr_enum_dom_users(&q_e.pol, &q_e.start_idx,
+ q_e.acb_mask, q_e.unknown_1, q_e.max_size,
+ &r_e.sam, &r_e.uni_acct_name,
+ &num_entries);
-/*******************************************************************
- api_samr_unknown_2c
- ********************************************************************/
-static BOOL api_samr_unknown_2c( uint16 vuid, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_UNKNOWN_2C q_u;
+ make_samr_r_enum_dom_users(&r_e, q_e.start_idx, num_entries);
- /* grab the samr open */
- samr_io_q_unknown_2c("", &q_u, data, 0);
+ ret = samr_io_r_enum_dom_users("", &r_e, rdata, 0);
- /* construct reply. always indicate success */
- samr_reply_unknown_2c(&q_u, rdata);
+ safe_free(r_e.sam);
+ safe_free(r_e.uni_acct_name);
- return True;
+ return ret;
}
-
/*******************************************************************
- samr_reply_unknown_3
+ api_samr_add_groupmem
********************************************************************/
-static void samr_reply_unknown_3(SAMR_Q_UNKNOWN_3 *q_u,
- prs_struct *rdata)
+static BOOL api_samr_add_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_UNKNOWN_3 r_u;
- DOM_SID3 sid[MAX_SAM_SIDS];
- uint32 rid;
- uint32 status;
-
- status = 0x0;
-
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->user_pol)) == -1))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
+ SAMR_Q_ADD_GROUPMEM q_e;
+ SAMR_R_ADD_GROUPMEM r_e;
- /* find the user's rid */
- if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->user_pol))) == 0xffffffff)
- {
- status = NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_e);
- if (status == 0x0)
+ if (!samr_io_q_add_groupmem("", &q_e, data, 0))
{
- DOM_SID user_sid;
- DOM_SID everyone_sid;
-
- user_sid = global_sam_sid;
-
- SMB_ASSERT_ARRAY(user_sid.sub_auths, user_sid.num_auths+1);
-
- /*
- * Add the user RID.
- */
- user_sid.sub_auths[user_sid.num_auths++] = rid;
-
- string_to_sid(&everyone_sid, "S-1-1");
-
- /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
- /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
- init_dom_sid3(&(sid[0]), 0x035b, 0x0002, &everyone_sid);
- init_dom_sid3(&(sid[1]), 0x0044, 0x0002, &user_sid);
+ return False;
}
- init_samr_r_unknown_3(&r_u,
- 0x0001, 0x8004,
- 0x00000014, 0x0002, 0x0070,
- 2, sid, status);
- DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
-
- /* store the response in the SMB stream */
- samr_io_r_unknown_3("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_unknown_3: %d\n", __LINE__));
+ r_e.status = _samr_add_groupmem(&q_e.pol, q_e.rid, q_e.unknown);
+ return samr_io_r_add_groupmem("", &r_e, rdata, 0);
}
/*******************************************************************
- api_samr_unknown_3
+ api_samr_del_groupmem
********************************************************************/
-static BOOL api_samr_unknown_3( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_del_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_UNKNOWN_3 q_u;
+ SAMR_Q_DEL_GROUPMEM q_e;
+ SAMR_R_DEL_GROUPMEM r_e;
- /* grab the samr open */
- samr_io_q_unknown_3("", &q_u, data, 0);
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_e);
- /* construct reply. always indicate success */
- samr_reply_unknown_3(&q_u, rdata);
+ if (!samr_io_q_del_groupmem("", &q_e, data, 0))
+ {
+ return False;
+ }
- return True;
-}
+ r_e.status = _samr_del_groupmem(&q_e.pol, q_e.rid);
+
+ return samr_io_r_del_groupmem("", &r_e, rdata, 0);
+}
/*******************************************************************
- samr_reply_enum_dom_users
+ api_samr_add_aliasmem
********************************************************************/
-static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
- prs_struct *rdata)
+static BOOL api_samr_add_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_ENUM_DOM_USERS r_e;
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
- int num_entries;
- int total_entries;
+ SAMR_Q_ADD_ALIASMEM q_e;
+ SAMR_R_ADD_ALIASMEM r_e;
- r_e.status = 0x0;
- r_e.total_num_entries = 0;
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_e);
- /* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ if (!samr_io_q_add_aliasmem("", &q_e, data, 0))
{
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ return False;
}
- DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
-
- become_root(True);
- get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
- unbecome_root(True);
-
- init_samr_r_enum_dom_users(&r_e, total_entries,
- q_u->unknown_0, num_entries,
- pass, r_e.status);
-
- /* store the response in the SMB stream */
- samr_io_r_enum_dom_users("", &r_e, rdata, 0);
- DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
+ r_e.status = _samr_add_aliasmem(&q_e.alias_pol, &q_e.sid.sid);
+ return samr_io_r_add_aliasmem("", &r_e, rdata, 0);
}
/*******************************************************************
- api_samr_enum_dom_users
+ api_samr_del_aliasmem
********************************************************************/
-static BOOL api_samr_enum_dom_users( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_del_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_ENUM_DOM_USERS q_e;
+ SAMR_Q_DEL_ALIASMEM q_e;
+ SAMR_R_DEL_ALIASMEM r_e;
+ if (!samr_io_q_del_aliasmem("", &q_e, data, 0))
+ {
+ return False;
+ }
- /* grab the samr open */
- samr_io_q_enum_dom_users("", &q_e, data, 0);
- /* construct reply. */
- samr_reply_enum_dom_users(&q_e, rdata);
+ r_e.status = _samr_del_aliasmem(&q_e.alias_pol, &q_e.sid.sid);
- return True;
+ return samr_io_r_del_aliasmem("", &r_e, rdata, 0);
}
-
/*******************************************************************
- samr_reply_enum_dom_groups
+ api_samr_enum_domains
********************************************************************/
-static void samr_reply_enum_dom_groups(SAMR_Q_ENUM_DOM_GROUPS *q_u,
- prs_struct *rdata)
+static BOOL api_samr_enum_domains( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_ENUM_DOM_GROUPS r_e;
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
- int num_entries;
- BOOL got_grps;
- char *dummy_group = "Domain Admins";
+ SAMR_Q_ENUM_DOMAINS q_e;
+ SAMR_R_ENUM_DOMAINS r_e;
+ uint32 num_entries = 0;
- r_e.status = 0x0;
- r_e.num_entries = 0;
+ BOOL ret;
- /* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_e);
+
+ if (!samr_io_q_enum_domains("", &q_e, data, 0))
{
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ return False;
}
- DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
- got_grps = True;
- num_entries = 1;
- init_unistr2(&(pass[0].uni_user_name), dummy_group, strlen(dummy_group));
- pass[0].user_rid = DOMAIN_GROUP_RID_ADMINS;
+ r_e.status = _samr_enum_domains(&q_e.pol, &q_e.start_idx,
+ q_e.max_size,
+ &r_e.sam, &r_e.uni_dom_name,
+ &num_entries);
- if (r_e.status == 0 && got_grps)
- {
- init_samr_r_enum_dom_groups(&r_e, q_u->start_idx, num_entries, pass, r_e.status);
- }
+ make_samr_r_enum_domains(&r_e, q_e.start_idx, num_entries);
- /* store the response in the SMB stream */
- samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
+ ret = samr_io_r_enum_domains("", &r_e, rdata, 0);
- DEBUG(5,("samr_enum_dom_groups: %d\n", __LINE__));
+ safe_free(r_e.sam);
+ safe_free(r_e.uni_dom_name);
+ return ret;
}
/*******************************************************************
api_samr_enum_dom_groups
********************************************************************/
-static BOOL api_samr_enum_dom_groups( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_groups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_ENUM_DOM_GROUPS q_e;
+ SAMR_R_ENUM_DOM_GROUPS r_e;
- /* grab the samr open */
- samr_io_q_enum_dom_groups("", &q_e, data, 0);
-
- /* construct reply. */
- samr_reply_enum_dom_groups(&q_e, rdata);
-
- return True;
-}
-
+ uint32 num_entries = 0;
-/*******************************************************************
- samr_reply_enum_dom_aliases
- ********************************************************************/
-static void samr_reply_enum_dom_aliases(SAMR_Q_ENUM_DOM_ALIASES *q_u,
- prs_struct *rdata)
-{
- SAMR_R_ENUM_DOM_ALIASES r_e;
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
- int num_entries = 0;
- DOM_SID sid;
- fstring sid_str;
- fstring sam_sid_str;
+ BOOL ret;
- r_e.status = 0x0;
- r_e.num_entries = 0;
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_e);
- /* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && !get_lsa_policy_samr_sid(&q_u->pol, &sid))
+ if (!samr_io_q_enum_dom_groups("", &q_e, data, 0))
{
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ return False;
}
- sid_to_string(sid_str, &sid);
- sid_to_string(sam_sid_str, &global_sam_sid);
- DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
+ r_e.status = _samr_enum_dom_groups(&q_e.pol, &q_e.start_idx,
+ q_e.max_size,
+ &r_e.sam, &r_e.uni_grp_name,
+ &num_entries);
- /* well-known aliases */
- if (strequal(sid_str, "S-1-5-32"))
- {
- char *name;
- while (num_entries < MAX_SAM_ENTRIES && ((name = builtin_alias_rids[num_entries].name) != NULL))
- {
- init_unistr2(&(pass[num_entries].uni_user_name), name, strlen(name));
- pass[num_entries].user_rid = builtin_alias_rids[num_entries].rid;
- num_entries++;
- }
- }
- else if (strequal(sid_str, sam_sid_str))
- {
- /* local aliases */
- /* oops! there's no code to deal with this */
- DEBUG(3,("samr_reply_enum_dom_aliases: enum of aliases in our domain not supported yet\n"));
- num_entries = 0;
- }
-
- init_samr_r_enum_dom_aliases(&r_e, num_entries, pass, r_e.status);
+ make_samr_r_enum_dom_groups(&r_e, q_e.start_idx, num_entries);
- /* store the response in the SMB stream */
- samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
+ ret = samr_io_r_enum_dom_groups("", &r_e, rdata, 0);
- DEBUG(5,("samr_enum_dom_aliases: %d\n", __LINE__));
+ safe_free(r_e.sam);
+ safe_free(r_e.uni_grp_name);
+ return ret;
}
/*******************************************************************
api_samr_enum_dom_aliases
********************************************************************/
-static BOOL api_samr_enum_dom_aliases( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_enum_dom_aliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_ENUM_DOM_ALIASES q_e;
+ SAMR_R_ENUM_DOM_ALIASES r_e;
- /* grab the samr open */
- samr_io_q_enum_dom_aliases("", &q_e, data, 0);
-
- /* construct reply. */
- samr_reply_enum_dom_aliases(&q_e, rdata);
-
- return True;
-}
-
+ uint32 num_entries = 0;
-/*******************************************************************
- samr_reply_query_dispinfo
- ********************************************************************/
-static void samr_reply_query_dispinfo(SAMR_Q_QUERY_DISPINFO *q_u,
- prs_struct *rdata)
-{
- SAMR_R_QUERY_DISPINFO r_e;
- SAM_INFO_CTR ctr;
- SAM_INFO_1 info1;
- SAM_INFO_2 info2;
- SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
- int num_entries = 0;
- int total_entries = 0;
- BOOL got_pwds;
- uint16 switch_level = 0x0;
+ BOOL ret;
+ ZERO_STRUCT(q_e);
ZERO_STRUCT(r_e);
- r_e.status = 0x0;
-
- DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
-
- /* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ if (!samr_io_q_enum_dom_aliases("", &q_e, data, 0))
{
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
+ return False;
}
- if (r_e.status == 0x0)
- {
- become_root(True);
- got_pwds = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, 0);
- unbecome_root(True);
-
- switch (q_u->switch_level)
- {
- case 0x1:
- {
-
- /* query disp info is for users */
- switch_level = 0x1;
- init_sam_info_1(&info1, ACB_NORMAL,
- q_u->start_idx, num_entries, pass);
-
- ctr.sam.info1 = &info1;
-
- break;
- }
- case 0x2:
- {
- /* query disp info is for servers */
- switch_level = 0x2;
- init_sam_info_2(&info2, ACB_WSTRUST,
- q_u->start_idx, num_entries, pass);
-
- ctr.sam.info2 = &info2;
-
- break;
- }
- }
- }
- if (r_e.status == 0 && got_pwds)
- {
- init_samr_r_query_dispinfo(&r_e, switch_level, &ctr, r_e.status);
- }
+ r_e.status = _samr_enum_dom_aliases(&q_e.pol, &q_e.start_idx,
+ q_e.max_size,
+ &r_e.sam, &r_e.uni_grp_name,
+ &num_entries);
- /* store the response in the SMB stream */
- samr_io_r_query_dispinfo("", &r_e, rdata, 0);
+ make_samr_r_enum_dom_aliases(&r_e, q_e.start_idx, num_entries);
- DEBUG(5,("samr_query_dispinfo: %d\n", __LINE__));
+ ret = samr_io_r_enum_dom_aliases("", &r_e, rdata, 0);
+ safe_free(r_e.sam);
+ safe_free(r_e.uni_grp_name);
+
+ return ret;
}
/*******************************************************************
api_samr_query_dispinfo
********************************************************************/
-static BOOL api_samr_query_dispinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_dispinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_QUERY_DISPINFO q_e;
+ SAMR_R_QUERY_DISPINFO r_e;
+ SAM_DISPINFO_CTR ctr;
+ uint32 data_size = 0;
+ uint32 num_entries = 0;
+ uint32 status = 0;
+ BOOL ret;
- /* grab the samr open */
- samr_io_q_query_dispinfo("", &q_e, data, 0);
-
- /* construct reply. */
- samr_reply_query_dispinfo(&q_e, rdata);
-
- return True;
-}
-
-
-/*******************************************************************
- samr_reply_query_aliasinfo
- ********************************************************************/
-static void samr_reply_query_aliasinfo(SAMR_Q_QUERY_ALIASINFO *q_u,
- prs_struct *rdata)
-{
- SAMR_R_QUERY_ALIASINFO r_e;
-
- r_e.status = 0x0;
- r_e.ptr = 0;
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_e);
+ ZERO_STRUCT(ctr);
- /* find the policy handle. open a policy on it. */
- if (r_e.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ if (!samr_io_q_query_dispinfo("", &q_e, data, 0))
{
- r_e.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ return False;
}
- DEBUG(5,("samr_reply_query_aliasinfo: %d\n", __LINE__));
+ status = _samr_query_dispinfo(&q_e.domain_pol,
+ q_e.switch_level,
+ q_e.start_idx,
+ q_e.max_entries,
+ q_e.max_size,
+ &data_size,
+ &num_entries,
+ &ctr);
- if (r_e.status == 0x0)
- {
- if (q_u->switch_level != 3)
- {
- r_e.status = NT_STATUS_INVALID_INFO_CLASS;
- }
- }
-
- init_samr_r_query_aliasinfo(&r_e, q_u->switch_level,
- "<account description>",
- r_e.status);
+ make_samr_r_query_dispinfo(&r_e, num_entries, data_size,
+ q_e.switch_level, &ctr, status);
/* store the response in the SMB stream */
- samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
-
- DEBUG(5,("samr_query_aliasinfo: %d\n", __LINE__));
+ ret = samr_io_r_query_dispinfo("", &r_e, rdata, 0);
+ safe_free(ctr.sam.info);
+ return ret;
}
/*******************************************************************
- api_samr_query_aliasinfo
+ api_samr_delete_dom_user
********************************************************************/
-static BOOL api_samr_query_aliasinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_delete_dom_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_QUERY_ALIASINFO q_e;
+ SAMR_Q_DELETE_DOM_USER q_u;
+ SAMR_R_DELETE_DOM_USER r_u;
- /* grab the samr open */
- samr_io_q_query_aliasinfo("", &q_e, data, 0);
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- /* construct reply. */
- samr_reply_query_aliasinfo(&q_e, rdata);
+ if (!samr_io_q_delete_dom_user("", &q_u, data, 0))
+ {
+ return False;
+ }
- return True;
+ r_u.status = _samr_delete_dom_user(&q_u.user_pol);
+ memcpy(&r_u.pol, &q_u.user_pol, sizeof(q_u.user_pol));
+ return samr_io_r_delete_dom_user("", &r_u, rdata, 0);
}
-
/*******************************************************************
- samr_reply_lookup_ids
+ api_samr_delete_dom_group
********************************************************************/
-static void samr_reply_lookup_ids(SAMR_Q_LOOKUP_IDS *q_u,
- prs_struct *rdata)
+static BOOL api_samr_delete_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- uint32 rid[MAX_SAM_ENTRIES];
- uint32 status = 0;
- int num_rids = q_u->num_sids1;
+ SAMR_Q_DELETE_DOM_GROUP q_u;
+ SAMR_R_DELETE_DOM_GROUP r_u;
- SAMR_R_LOOKUP_IDS r_u;
-
- DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
-
- if (num_rids > MAX_SAM_ENTRIES)
- {
- num_rids = MAX_SAM_ENTRIES;
- DEBUG(5,("samr_lookup_ids: truncating entries to %d\n", num_rids));
- }
-
-#if 0
- int i;
- SMB_ASSERT_ARRAY(q_u->uni_user_name, num_rids);
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- for (i = 0; i < num_rids && status == 0; i++)
+ if (!samr_io_q_delete_dom_group("", &q_u, data, 0))
{
- struct sam_passwd *sam_pass;
- fstring user_name;
-
-
- fstrcpy(user_name, unistrn2(q_u->uni_user_name[i].buffer,
- q_u->uni_user_name[i].uni_str_len));
-
- /* find the user account */
- become_root(True);
- sam_pass = get_smb21pwd_entry(user_name, 0);
- unbecome_root(True);
-
- if (sam_pass == NULL)
- {
- status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
- rid[i] = 0;
- }
- else
- {
- rid[i] = sam_pass->user_rid;
- }
+ return False;
}
-#endif
-
- num_rids = 1;
- rid[0] = BUILTIN_ALIAS_RID_USERS;
-
- init_samr_r_lookup_ids(&r_u, num_rids, rid, status);
-
- /* store the response in the SMB stream */
- samr_io_r_lookup_ids("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_lookup_ids: %d\n", __LINE__));
+ r_u.status = _samr_delete_dom_group(&q_u.group_pol);
+ memcpy(&r_u.pol, &q_u.group_pol, sizeof(q_u.group_pol));
+ return samr_io_r_delete_dom_group("", &r_u, rdata, 0);
}
-/*******************************************************************
- api_samr_lookup_ids
- ********************************************************************/
-static BOOL api_samr_lookup_ids( uint16 vuid, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_LOOKUP_IDS q_u;
-
- /* grab the samr 0x10 */
- samr_io_q_lookup_ids("", &q_u, data, 0);
-
- /* construct reply. always indicate success */
- samr_reply_lookup_ids(&q_u, rdata);
-
- return True;
-}
/*******************************************************************
- samr_reply_lookup_names
+ api_samr_query_groupmem
********************************************************************/
-
-static BOOL samr_reply_lookup_names(SAMR_Q_LOOKUP_NAMES *q_u,
- prs_struct *rdata)
+static BOOL api_samr_query_groupmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- uint32 rid[MAX_SAM_ENTRIES];
- uint8 type[MAX_SAM_ENTRIES];
- uint32 status = 0;
- int i;
- int num_rids = q_u->num_names1;
- DOM_SID pol_sid;
-
- SAMR_R_LOOKUP_NAMES r_u;
-
- DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
-
- ZERO_ARRAY(rid);
- ZERO_ARRAY(type);
-
- if (!get_lsa_policy_samr_sid(&q_u->pol, &pol_sid)) {
- status = 0xC0000000 | NT_STATUS_OBJECT_TYPE_MISMATCH;
- init_samr_r_lookup_names(&r_u, 0, rid, type, status);
- if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
- DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
- return False;
- }
- return True;
- }
-
- if (num_rids > MAX_SAM_ENTRIES) {
- num_rids = MAX_SAM_ENTRIES;
- DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
- }
-
- SMB_ASSERT_ARRAY(q_u->uni_name, num_rids);
-
- for (i = 0; i < num_rids; i++) {
- fstring name;
-
- status = 0xC0000000 | NT_STATUS_NONE_MAPPED;
+ SAMR_Q_QUERY_GROUPMEM q_u;
+ SAMR_R_QUERY_GROUPMEM r_u;
- rid [i] = 0xffffffff;
- type[i] = SID_NAME_UNKNOWN;
-
- fstrcpy(name, dos_unistrn2(q_u->uni_name[i].buffer,
- q_u->uni_name[i].uni_str_len));
-
- if(sid_equal(&pol_sid, &global_sam_sid)) {
- DOM_SID sid;
-
- if(lookup_local_name(global_myname, name, &sid, &type[i])) {
- sid_split_rid( &sid, &rid[i]);
- status = 0;
- }
- }
- }
+ uint32 *rid = NULL;
+ uint32 *attr = NULL;
+ int num_rids = 0;
+ uint32 status = 0;
+ BOOL ret;
- init_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- /* store the response in the SMB stream */
- if(!samr_io_r_lookup_names("", &r_u, rdata, 0)) {
- DEBUG(0,("samr_reply_lookup_names: failed to marshall SAMR_R_LOOKUP_NAMES.\n"));
+ if (!samr_io_q_query_groupmem("", &q_u, data, 0))
+ {
return False;
}
- DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
-
- return True;
+ status = _samr_query_groupmem(&q_u.group_pol,
+ &num_rids, &rid, &attr);
+ make_samr_r_query_groupmem(&r_u, num_rids, rid, attr, status);
+ ret = samr_io_r_query_groupmem("", &r_u, rdata, 0);
+ samr_free_r_query_groupmem(&r_u);
+ return ret;
}
+
/*******************************************************************
- api_samr_lookup_names
+ api_samr_query_groupinfo
********************************************************************/
-
-static BOOL api_samr_lookup_names( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_set_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_LOOKUP_NAMES q_u;
+ SAMR_Q_SET_GROUPINFO q_e;
+ SAMR_R_SET_GROUPINFO r_e;
+ GROUP_INFO_CTR ctr;
- memset(&q_u, '\0', sizeof(q_u));
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_e);
+ ZERO_STRUCT(ctr);
- /* grab the samr lookup names */
- if(!samr_io_q_lookup_names("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_lookup_names: failed to unmarshall SAMR_Q_LOOKUP_NAMES.\n"));
+ q_e.ctr = &ctr;
+ if (!samr_io_q_set_groupinfo("", &q_e, data, 0))
+ {
return False;
}
- /* construct reply. always indicate success */
- if(!samr_reply_lookup_names(&q_u, rdata))
- return False;
-
- return True;
+ r_e.status = _samr_set_groupinfo(&q_e.pol, ctr.switch_value1, &ctr);
+ return samr_io_r_set_groupinfo("", &r_e, rdata, 0);
}
+
/*******************************************************************
- samr_reply_chgpasswd_user
+ api_samr_query_groupinfo
********************************************************************/
-
-static BOOL samr_reply_chgpasswd_user(SAMR_Q_CHGPASSWD_USER *q_u,
- prs_struct *rdata)
+static BOOL api_samr_query_groupinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_CHGPASSWD_USER r_u;
- uint32 status = 0x0;
- fstring user_name;
- fstring wks;
-
- fstrcpy(user_name, dos_unistrn2(q_u->uni_user_name.buffer, q_u->uni_user_name.uni_str_len));
- fstrcpy(wks , dos_unistrn2(q_u->uni_dest_host.buffer, q_u->uni_dest_host.uni_str_len));
-
- DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
+ SAMR_Q_QUERY_GROUPINFO q_e;
+ SAMR_R_QUERY_GROUPINFO r_e;
+ GROUP_INFO_CTR ctr;
+ uint32 status;
- if (!pass_oem_change(user_name,
- q_u->lm_newpass.pass, q_u->lm_oldhash.hash,
- q_u->nt_newpass.pass, q_u->nt_oldhash.hash))
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_e);
+ ZERO_STRUCT(ctr);
+
+ if (!samr_io_q_query_groupinfo("", &q_e, data, 0))
{
- status = 0xC0000000 | NT_STATUS_WRONG_PASSWORD;
+ return False;
}
- init_samr_r_chgpasswd_user(&r_u, status);
- /* store the response in the SMB stream */
- if(!samr_io_r_chgpasswd_user("", &r_u, rdata, 0)) {
- DEBUG(0,("samr_reply_chgpasswd_user: Failed to marshall SAMR_R_CHGPASSWD_USER struct.\n" ));
- return False;
- }
+ status = _samr_query_groupinfo(&q_e.pol, q_e.switch_level, &ctr);
- DEBUG(5,("samr_chgpasswd_user: %d\n", __LINE__));
- return True;
+ make_samr_r_query_groupinfo(&r_e, status == 0 ? &ctr : NULL, status);
+ return samr_io_r_query_groupinfo("", &r_e, rdata, 0);
}
+
/*******************************************************************
- api_samr_chgpasswd_user
+ api_samr_query_aliasinfo
********************************************************************/
-
-static BOOL api_samr_chgpasswd_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_aliasinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_CHGPASSWD_USER q_u;
+ SAMR_Q_QUERY_ALIASINFO q_e;
+ SAMR_R_QUERY_ALIASINFO r_e;
+ ALIAS_INFO_CTR ctr;
+ uint32 status;
- /* unknown 38 command */
- if (!samr_io_q_chgpasswd_user("", &q_u, data, 0)) {
- DEBUG(0,("api_samr_chgpasswd_user: samr_io_q_chgpasswd_user failed to parse RPC packet.\n"));
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_e);
+ ZERO_STRUCT(ctr);
+
+ if (!samr_io_q_query_aliasinfo("", &q_e, data, 0))
+ {
return False;
}
- /* construct reply. */
- if(!samr_reply_chgpasswd_user(&q_u, rdata)) {
- DEBUG(0,("api_samr_chgpasswd_user: samr_reply_chgpasswd_user failed to create reply packet.\n"));
- return False;
- }
- return True;
+ status = _samr_query_aliasinfo(&q_e.pol, q_e.switch_level, &ctr);
+
+ make_samr_r_query_aliasinfo(&r_e, status == 0 ? &ctr : NULL, status);
+ return samr_io_r_query_aliasinfo("", &r_e, rdata, 0);
}
/*******************************************************************
- samr_reply_unknown_38
+ api_samr_query_useraliases
********************************************************************/
-static void samr_reply_unknown_38(SAMR_Q_UNKNOWN_38 *q_u,
- prs_struct *rdata)
+static BOOL api_samr_query_useraliases( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_UNKNOWN_38 r_u;
+ SAMR_Q_QUERY_USERALIASES q_u;
+ SAMR_R_QUERY_USERALIASES r_u;
- DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
+ uint32 status = 0;
+ uint32 *rid = NULL;
+ int num_rids = 0;
- init_samr_r_unknown_38(&r_u);
+ ZERO_STRUCT(r_u);
+ ZERO_STRUCT(q_u);
- /* store the response in the SMB stream */
- samr_io_r_unknown_38("", &r_u, rdata, 0);
+ if (!samr_io_q_query_useraliases("", &q_u, data, 0))
+ {
+ return False;
+ }
- DEBUG(5,("samr_unknown_38: %d\n", __LINE__));
+ status = _samr_query_useraliases(&q_u.pol, q_u.ptr_sid, q_u.sid,
+ &num_rids, &rid);
+ samr_free_q_query_useraliases(&q_u);
+ make_samr_r_query_useraliases(&r_u, num_rids, rid, status);
+ return samr_io_r_query_useraliases("", &r_u, rdata, 0);
}
+
/*******************************************************************
- api_samr_unknown_38
+ api_samr_delete_dom_alias
********************************************************************/
-static BOOL api_samr_unknown_38( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_delete_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_UNKNOWN_38 q_u;
+ SAMR_Q_DELETE_DOM_ALIAS q_u;
+ SAMR_R_DELETE_DOM_ALIAS r_u;
- /* unknown 38 command */
- samr_io_q_unknown_38("", &q_u, data, 0);
+ ZERO_STRUCT(r_u);
+ ZERO_STRUCT(q_u);
- /* construct reply. always indicate success */
- samr_reply_unknown_38(&q_u, rdata);
+ if (!samr_io_q_delete_dom_alias("", &q_u, data, 0))
+ {
+ return False;
+ }
- return True;
+ r_u.status = _samr_delete_dom_alias(&q_u.alias_pol);
+ return samr_io_r_delete_dom_alias("", &r_u, rdata, 0);
}
/*******************************************************************
- samr_reply_unknown_12
+ api_samr_query_aliasmem
********************************************************************/
-static void samr_reply_unknown_12(SAMR_Q_UNKNOWN_12 *q_u,
- prs_struct *rdata)
+static BOOL api_samr_query_aliasmem( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- fstring group_names[MAX_SAM_ENTRIES];
- uint32 group_attrs[MAX_SAM_ENTRIES];
- uint32 status = 0;
- int num_gids = q_u->num_gids1;
-
- SAMR_R_UNKNOWN_12 r_u;
-
- DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
+ SAMR_Q_QUERY_ALIASMEM q_u;
+ SAMR_R_QUERY_ALIASMEM r_u;
+ uint32 status = 0;
+ DOM_SID2 *sid = NULL;
+ int num_sids = 0;
+ BOOL ret;
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
- {
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- }
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- if (status == 0x0)
+ if (!samr_io_q_query_aliasmem("", &q_u, data, 0))
{
- int i;
- if (num_gids > MAX_SAM_ENTRIES)
- {
- num_gids = MAX_SAM_ENTRIES;
- DEBUG(5,("samr_unknown_12: truncating entries to %d\n", num_gids));
- }
-
- for (i = 0; i < num_gids && status == 0; i++)
- {
- fstrcpy(group_names[i], "dummy group");
- group_attrs[i] = 0x2;
- }
+ return False;
}
- init_samr_r_unknown_12(&r_u, num_gids, group_names, group_attrs, status);
+ status = _samr_query_aliasmem(&q_u.alias_pol, &num_sids, &sid);
+ make_samr_r_query_aliasmem(&r_u, num_sids, sid, status);
/* store the response in the SMB stream */
- samr_io_r_unknown_12("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_unknown_12: %d\n", __LINE__));
+ ret = samr_io_r_query_aliasmem("", &r_u, rdata, 0);
+ if (sid != NULL)
+ {
+ safe_free(sid);
+ }
+ return ret;
}
/*******************************************************************
- api_samr_unknown_12
+ api_samr_lookup_names
********************************************************************/
-static BOOL api_samr_unknown_12( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_lookup_names( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_UNKNOWN_12 q_u;
+ SAMR_Q_LOOKUP_NAMES q_u;
+ SAMR_R_LOOKUP_NAMES r_u;
- /* grab the samr lookup names */
- samr_io_q_unknown_12("", &q_u, data, 0);
+ uint32 rid [MAX_SAM_ENTRIES];
+ uint32 type[MAX_SAM_ENTRIES];
+ uint32 num_rids = 0;
+ uint32 num_types = 0;
- /* construct reply. always indicate success */
- samr_reply_unknown_12(&q_u, rdata);
+ uint32 status = 0;
- return True;
-}
+ if (!samr_io_q_lookup_names("", &q_u, data, 0))
+ {
+ return False;
+ }
+ status = _samr_lookup_names(&q_u.pol, q_u.num_names1,
+ q_u.flags, q_u.ptr, q_u.uni_name,
+ &num_rids, rid, &num_types, type);
+ samr_free_q_lookup_names(&q_u);
+ make_samr_r_lookup_names(&r_u, num_rids, rid, type, status);
+ return samr_io_r_lookup_names("", &r_u, rdata, 0);
+}
/*******************************************************************
- samr_reply_open_user
+ api_samr_chgpasswd_user
********************************************************************/
-static void samr_reply_open_user(SAMR_Q_OPEN_USER *q_u,
- prs_struct *rdata,
- int status)
+static BOOL api_samr_chgpasswd_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_OPEN_USER r_u;
- struct sam_passwd *sam_pass;
- BOOL pol_open = False;
-
- /* set up the SAMR open_user response */
- memset((char *)r_u.user_pol.data, '\0', POL_HND_SIZE);
+ SAMR_Q_CHGPASSWD_USER q_u;
+ SAMR_R_CHGPASSWD_USER r_u;
+ uchar *lm_newpass = NULL;
+ uchar *nt_newpass = NULL;
+ uchar *lm_oldhash = NULL;
+ uchar *nt_oldhash = NULL;
- r_u.status = 0x0;
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- /* find the policy handle. open a policy on it. */
- if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
+ if (!samr_io_q_chgpasswd_user("", &q_u, data, 0))
{
- r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ return False;
}
- /* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.user_pol))))
+ if (q_u.lm_newpass.ptr)
{
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ lm_newpass = q_u.lm_newpass.pass;
}
-
- become_root(True);
- sam_pass = getsam21pwrid(q_u->user_rid);
- unbecome_root(True);
-
- /* check that the RID exists in our domain. */
- if (r_u.status == 0x0 && sam_pass == NULL)
+ if (q_u.lm_oldhash.ptr)
{
- r_u.status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
+ lm_oldhash = q_u.lm_oldhash.hash;
}
-
- /* associate the RID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.user_pol), q_u->user_rid))
+ if (q_u.nt_newpass.ptr)
{
- /* oh, whoops. don't know what error message to return, here */
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ nt_newpass = q_u.nt_newpass.pass;
}
-
- if (r_u.status != 0 && pol_open)
+ if (q_u.nt_oldhash.ptr)
{
- close_lsa_policy_hnd(&(r_u.user_pol));
- }
-
- DEBUG(5,("samr_open_user: %d\n", __LINE__));
-
- /* store the response in the SMB stream */
- samr_io_r_open_user("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_open_user: %d\n", __LINE__));
-
+ nt_oldhash = q_u.nt_oldhash.hash;
+ }
+ r_u.status = _samr_chgpasswd_user(&q_u.uni_dest_host,
+ &q_u.uni_user_name,
+ lm_newpass, nt_newpass,
+ lm_oldhash, nt_oldhash);
+ return samr_io_r_chgpasswd_user("", &r_u, rdata, 0);
}
+
/*******************************************************************
- api_samr_open_user
+ api_samr_get_dom_pwinfo
********************************************************************/
-static BOOL api_samr_open_user( uint16 vuid, prs_struct *data, prs_struct *rdata)
-{
- SAMR_Q_OPEN_USER q_u;
-
- /* grab the samr unknown 22 */
- samr_io_q_open_user("", &q_u, data, 0);
-
- /* construct reply. always indicate success */
- samr_reply_open_user(&q_u, rdata, 0x0);
-
- return True;
-}
-
-
-/*************************************************************************
- get_user_info_10
- *************************************************************************/
-static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
+static BOOL api_samr_get_dom_pwinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- struct smb_passwd *smb_pass;
+ SAMR_Q_GET_DOM_PWINFO q_u;
+ SAMR_R_GET_DOM_PWINFO r_u;
- if (!pdb_rid_is_user(user_rid))
+ if (!samr_io_q_get_dom_pwinfo("", &q_u, data, 0))
{
- DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
return False;
}
- become_root(True);
- smb_pass = getsmbpwrid(user_rid);
- unbecome_root(True);
-
- if (smb_pass == NULL)
- {
- DEBUG(4,("User 0x%x not found\n", user_rid));
- return False;
- }
-
- DEBUG(3,("User:[%s]\n", smb_pass->smb_name));
-
- init_sam_user_info10(id10, smb_pass->acct_ctrl);
-
- return True;
+ r_u.status = _samr_get_dom_pwinfo(&q_u.uni_srv_name,
+ &r_u.unk_0,
+ &r_u.unk_1,
+ &r_u.unk_2);
+ return samr_io_r_get_dom_pwinfo("", &r_u, rdata, 0);
}
-/*************************************************************************
- get_user_info_21
- *************************************************************************/
-static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
-{
- NTTIME dummy_time;
- struct sam_passwd *sam_pass;
- LOGON_HRS hrs;
- int i;
- if (!pdb_rid_is_user(user_rid))
- {
- DEBUG(4,("RID 0x%x is not a user RID\n", user_rid));
- return False;
- }
+/*******************************************************************
+ api_samr_lookup_rids
+ ********************************************************************/
+static BOOL api_samr_lookup_rids( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_LOOKUP_RIDS q_u;
+ SAMR_R_LOOKUP_RIDS r_u;
+ uint32 status = 0;
+ UNIHDR *hdr_names = NULL;
+ UNISTR2 *uni_names = NULL;
+ uint32 *types = NULL;
+ uint32 num_names = 0;
- become_root(True);
- sam_pass = getsam21pwrid(user_rid);
- unbecome_root(True);
+ ZERO_STRUCT(r_u);
+ ZERO_STRUCT(q_u);
- if (sam_pass == NULL)
+ if (!samr_io_q_lookup_rids("", &q_u, data, 0))
{
- DEBUG(4,("User 0x%x not found\n", user_rid));
return False;
}
- DEBUG(3,("User:[%s]\n", sam_pass->smb_name));
-
- dummy_time.low = 0xffffffff;
- dummy_time.high = 0x7fffffff;
+ status = _samr_lookup_rids(&q_u.pol, q_u.num_rids1,
+ q_u.flags, q_u.rid,
+ &num_names,
+ &hdr_names, &uni_names, &types);
+ samr_free_q_lookup_rids(&q_u);
+ make_samr_r_lookup_rids(&r_u, num_names, hdr_names, uni_names, types);
+ return samr_io_r_lookup_rids("", &r_u, rdata, 0);
+}
- DEBUG(5,("get_user_info_21 - TODO: convert unix times to NTTIMEs\n"));
- /* create a LOGON_HRS structure */
- hrs.len = sam_pass->hours_len;
- SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
- for (i = 0; i < hrs.len; i++)
+/*******************************************************************
+ api_samr_open_user
+ ********************************************************************/
+static BOOL api_samr_open_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+{
+ SAMR_Q_OPEN_USER q_u;
+ SAMR_R_OPEN_USER r_u;
+ if (!samr_io_q_open_user("", &q_u, data, 0))
{
- hrs.hours[i] = sam_pass->hours[i];
+ return False;
}
- init_sam_user_info21(id21,
-
- &dummy_time, /* logon_time */
- &dummy_time, /* logoff_time */
- &dummy_time, /* kickoff_time */
- &dummy_time, /* pass_last_set_time */
- &dummy_time, /* pass_can_change_time */
- &dummy_time, /* pass_must_change_time */
-
- sam_pass->smb_name, /* user_name */
- sam_pass->full_name, /* full_name */
- sam_pass->home_dir, /* home_dir */
- sam_pass->dir_drive, /* dir_drive */
- sam_pass->logon_script, /* logon_script */
- sam_pass->profile_path, /* profile_path */
- sam_pass->acct_desc, /* description */
- sam_pass->workstations, /* workstations user can log in from */
- sam_pass->unknown_str, /* don't know, yet */
- sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
-
- sam_pass->user_rid, /* RID user_id */
- sam_pass->group_rid, /* RID group_id */
- sam_pass->acct_ctrl,
-
- sam_pass->unknown_3, /* unknown_3 */
- sam_pass->logon_divs, /* divisions per week */
- &hrs, /* logon hours */
- sam_pass->unknown_5,
- sam_pass->unknown_6);
-
- return True;
+ r_u.status = _samr_open_user(&q_u.domain_pol,
+ q_u.access_mask, q_u.user_rid,
+ &r_u.user_pol);
+ return samr_io_r_open_user("", &r_u, rdata, 0);
}
+
/*******************************************************************
- samr_reply_query_userinfo
+ api_samr_query_userinfo
********************************************************************/
-static void samr_reply_query_userinfo(SAMR_Q_QUERY_USERINFO *q_u,
- prs_struct *rdata)
+static BOOL api_samr_query_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
+ SAMR_Q_QUERY_USERINFO q_u;
SAMR_R_QUERY_USERINFO r_u;
-#if 0
- SAM_USER_INFO_11 id11;
-#endif
- SAM_USER_INFO_10 id10;
- SAM_USER_INFO_21 id21;
- void *info = NULL;
-
+ SAM_USERINFO_CTR ctr;
uint32 status = 0x0;
- uint32 rid = 0x0;
- DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+ ZERO_STRUCT(ctr);
- /* search for the handle */
- if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ if (!samr_io_q_query_userinfo("", &q_u, data, 0))
{
- status = NT_STATUS_INVALID_HANDLE;
+ return False;
}
- /* find the user's rid */
- if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
- {
- status = NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
- DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
+ if (q_u.switch_value == 0x12)
+ {
+ DEBUG(0,("api_samr_query_userinfo: possible password attack (info level 0x12)\n"));
- /* ok! user info levels (there are lots: see MSDEV help), off we go... */
- if (status == 0x0)
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ else
{
- switch (q_u->switch_value)
- {
- case 0x10:
- {
- info = (void*)&id10;
- status = get_user_info_10(&id10, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
- break;
- }
-#if 0
-/* whoops - got this wrong. i think. or don't understand what's happening. */
- case 0x11:
- {
- NTTIME expire;
- info = (void*)&id11;
-
- expire.low = 0xffffffff;
- expire.high = 0x7fffffff;
-
- make_sam_user_info11(&id11, &expire, "BROOKFIELDS$", 0x03ef, 0x201, 0x0080);
-
- break;
- }
-#endif
- case 21:
- {
- info = (void*)&id21;
- status = get_user_info_21(&id21, rid) ? 0 : NT_STATUS_NO_SUCH_USER;
- break;
- }
-
- default:
- {
- status = NT_STATUS_INVALID_INFO_CLASS;
-
- break;
- }
- }
+ status = _samr_query_userinfo(&q_u.pol, q_u.switch_value, &ctr);
}
-
- init_samr_r_query_userinfo(&r_u, q_u->switch_value, info, status);
-
- /* store the response in the SMB stream */
- samr_io_r_query_userinfo("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_reply_query_userinfo: %d\n", __LINE__));
-
+ make_samr_r_query_userinfo(&r_u, &ctr, status);
+ return samr_io_r_query_userinfo("", &r_u, rdata, 0);
}
+
/*******************************************************************
- api_samr_query_userinfo
+ api_samr_set_userinfo2
********************************************************************/
-static BOOL api_samr_query_userinfo( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_set_userinfo2( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_QUERY_USERINFO q_u;
+ SAMR_Q_SET_USERINFO2 q_u;
+ SAMR_R_SET_USERINFO2 r_u;
+ SAM_USERINFO_CTR ctr;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ q_u.ctr = &ctr;
- /* grab the samr unknown 24 */
- samr_io_q_query_userinfo("", &q_u, data, 0);
+ if (!samr_io_q_set_userinfo2("", &q_u, data, 0))
+ {
+ return False;
+ }
- /* construct reply. always indicate success */
- samr_reply_query_userinfo(&q_u, rdata);
+ r_u.status = _samr_set_userinfo2(&q_u.pol, q_u.switch_value, &ctr);
- return True;
+ free_samr_q_set_userinfo2(&q_u);
+ return samr_io_r_set_userinfo2("", &r_u, rdata, 0);
}
/*******************************************************************
- samr_reply_query_usergroups
+ api_samr_set_userinfo
********************************************************************/
-static void samr_reply_query_usergroups(SAMR_Q_QUERY_USERGROUPS *q_u,
- prs_struct *rdata)
+static BOOL api_samr_set_userinfo( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_QUERY_USERGROUPS r_u;
- uint32 status = 0x0;
+ SAMR_Q_SET_USERINFO q_u;
+ SAMR_R_SET_USERINFO r_u;
+ SAM_USERINFO_CTR ctr;
- struct sam_passwd *sam_pass;
- DOM_GID *gids = NULL;
- int num_groups = 0;
- uint32 rid;
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
+ q_u.ctr = &ctr;
- /* find the policy handle. open a policy on it. */
- if (status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->pol)) == -1))
+ if (!samr_io_q_set_userinfo("", &q_u, data, 0))
{
- status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
+ return False;
}
- /* find the user's rid */
- if (status == 0x0 && (rid = get_lsa_policy_samr_rid(&(q_u->pol))) == 0xffffffff)
+ if (q_u.switch_value == 0x12)
{
- status = NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
+ DEBUG(0,("api_samr_set_userinfo: possible password attack (info level 0x12)\n"));
- if (status == 0x0)
- {
- become_root(True);
- sam_pass = getsam21pwrid(rid);
- unbecome_root(True);
-
- if (sam_pass == NULL)
- {
- status = 0xC0000000 | NT_STATUS_NO_SUCH_USER;
- }
+ r_u.status = NT_STATUS_INVALID_INFO_CLASS;
}
-
- if (status == 0x0)
- {
- pstring groups;
- get_domain_user_groups(groups, sam_pass->smb_name);
- gids = NULL;
- num_groups = make_dom_gids(groups, &gids);
- }
-
- /* construct the response. lkclXXXX: gids are not copied! */
- init_samr_r_query_usergroups(&r_u, num_groups, gids, status);
-
- /* store the response in the SMB stream */
- samr_io_r_query_usergroups("", &r_u, rdata, 0);
-
- if (gids)
+ else
{
- free((char *)gids);
+ r_u.status = _samr_set_userinfo(&q_u.pol, q_u.switch_value, &ctr);
}
- DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
-
+ free_samr_q_set_userinfo(&q_u);
+ return samr_io_r_set_userinfo("", &r_u, rdata, 0);
}
+
/*******************************************************************
api_samr_query_usergroups
********************************************************************/
-static BOOL api_samr_query_usergroups( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_usergroups( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_QUERY_USERGROUPS q_u;
- /* grab the samr unknown 32 */
- samr_io_q_query_usergroups("", &q_u, data, 0);
-
- /* construct reply. */
- samr_reply_query_usergroups(&q_u, rdata);
-
- return True;
-}
-
+ SAMR_R_QUERY_USERGROUPS r_u;
-/*******************************************************************
- samr_reply_query_dom_info
- ********************************************************************/
-static void samr_reply_query_dom_info(SAMR_Q_QUERY_DOMAIN_INFO *q_u,
- prs_struct *rdata)
-{
- SAMR_R_QUERY_DOMAIN_INFO r_u;
- SAM_UNK_CTR ctr;
- uint16 switch_value = 0x0;
uint32 status = 0x0;
+ DOM_GID *gids = NULL;
+ int num_groups = 0;
+ ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- ZERO_STRUCT(ctr);
-
- r_u.ctr = &ctr;
- DEBUG(5,("samr_reply_query_dom_info: %d\n", __LINE__));
-
- /* find the policy handle. open a policy on it. */
- if (r_u.status == 0x0 && (find_lsa_policy_by_hnd(&(q_u->domain_pol)) == -1))
- {
- r_u.status = 0xC0000000 | NT_STATUS_INVALID_HANDLE;
- DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
- }
-
- if (status == 0x0)
+ if (!samr_io_q_query_usergroups("", &q_u, data, 0))
{
- switch (q_u->switch_value)
- {
- case 0x02:
- {
- switch_value = 0x2;
- init_unk_info2(&ctr.info.inf2, global_myworkgroup, global_myname);
-
- break;
- }
- default:
- {
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
- }
+ return False;
}
- init_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
-
- /* store the response in the SMB stream */
- samr_io_r_query_dom_info("", &r_u, rdata, 0);
- DEBUG(5,("samr_query_dom_info: %d\n", __LINE__));
+ status = _samr_query_usergroups(&q_u.pol, &num_groups, &gids);
+ make_samr_r_query_usergroups(&r_u, num_groups, gids, status);
+ return samr_io_r_query_usergroups("", &r_u, rdata, 0);
}
/*******************************************************************
- api_samr_query_dom_info
+ api_samr_create_dom_alias
********************************************************************/
-static BOOL api_samr_query_dom_info( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_create_dom_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_QUERY_DOMAIN_INFO q_e;
+ SAMR_Q_CREATE_DOM_ALIAS q_u;
+ SAMR_R_CREATE_DOM_ALIAS r_u;
- /* grab the samr unknown 8 command */
- samr_io_q_query_dom_info("", &q_e, data, 0);
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- /* construct reply. */
- samr_reply_query_dom_info(&q_e, rdata);
+ if (!samr_io_q_create_dom_alias("", &q_u, data, 0))
+ {
+ return False;
+ }
- return True;
+ r_u.status = _samr_create_dom_alias(&q_u.dom_pol, &q_u.uni_acct_desc,
+ q_u.access_mask,
+ &r_u.alias_pol, &r_u.rid);
+ return samr_io_r_create_dom_alias("", &r_u, rdata, 0);
}
-
-
/*******************************************************************
- samr_reply_unknown_32
+ api_samr_create_dom_group
********************************************************************/
-static void samr_reply_unknown_32(SAMR_Q_UNKNOWN_32 *q_u,
- prs_struct *rdata,
- int status)
+static BOOL api_samr_create_dom_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- int i;
- SAMR_R_UNKNOWN_32 r_u;
+ SAMR_Q_CREATE_DOM_GROUP q_u;
+ SAMR_R_CREATE_DOM_GROUP r_u;
- /* set up the SAMR unknown_32 response */
- memset((char *)r_u.pol.data, '\0', POL_HND_SIZE);
- if (status == 0)
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!samr_io_q_create_dom_group("", &q_u, data, 0))
{
- for (i = 4; i < POL_HND_SIZE; i++)
- {
- r_u.pol.data[i] = i+1;
- }
+ return False;
}
- init_dom_rid4(&(r_u.rid4), 0x0030, 0, 0);
- r_u.status = status;
-
- DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
+ r_u.status = _samr_create_dom_group(&q_u.pol,
+ &q_u.uni_acct_desc,
+ q_u.access_mask,
+ &r_u.pol, &r_u.rid);
/* store the response in the SMB stream */
- samr_io_r_unknown_32("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_unknown_32: %d\n", __LINE__));
-
+ return samr_io_r_create_dom_group("", &r_u, rdata, 0);
}
/*******************************************************************
- api_samr_unknown_32
+ api_samr_query_dom_info
********************************************************************/
-static BOOL api_samr_unknown_32( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_query_dom_info( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- uint32 status = 0;
- struct sam_passwd *sam_pass;
- fstring mach_acct;
-
- SAMR_Q_UNKNOWN_32 q_u;
-
- /* grab the samr unknown 32 */
- samr_io_q_unknown_32("", &q_u, data, 0);
-
- /* find the machine account: tell the caller if it exists.
- lkclXXXX i have *no* idea if this is a problem or not
- or even if you are supposed to construct a different
- reply if the account already exists...
- */
-
- fstrcpy(mach_acct, dos_unistrn2(q_u.uni_mach_acct.buffer,
- q_u.uni_mach_acct.uni_str_len));
+ SAMR_Q_QUERY_DOMAIN_INFO q_e;
+ SAMR_R_QUERY_DOMAIN_INFO r_u;
+ SAM_UNK_CTR ctr;
+ uint16 switch_value;
+ uint32 status;
- become_root(True);
- sam_pass = getsam21pwnam(mach_acct);
- unbecome_root(True);
+ ZERO_STRUCT(q_e);
+ ZERO_STRUCT(r_u);
+ ZERO_STRUCT(ctr);
- if (sam_pass != NULL)
- {
- /* machine account exists: say so */
- status = 0xC0000000 | NT_STATUS_USER_EXISTS;
- }
- else
+ if (!samr_io_q_query_dom_info("", &q_e, data, 0))
{
- /* this could cause trouble... */
- DEBUG(0,("trouble!\n"));
- status = 0;
+ return False;
}
- /* construct reply. */
- samr_reply_unknown_32(&q_u, rdata, status);
- return True;
-}
+ switch_value = q_e.switch_value;
+ status = _samr_query_dom_info(&q_e.domain_pol, q_e.switch_value, &ctr);
+ make_samr_r_query_dom_info(&r_u, switch_value, &ctr, status);
+ /* store the response in the SMB stream */
+ return samr_io_r_query_dom_info("", &r_u, rdata, 0);
+}
/*******************************************************************
- samr_reply_connect_anon
+ api_samr_create_user
********************************************************************/
-static void samr_reply_connect_anon(SAMR_Q_CONNECT_ANON *q_u,
- prs_struct *rdata)
+static BOOL api_samr_create_user( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_R_CONNECT_ANON r_u;
- BOOL pol_open = False;
-
- /* set up the SAMR connect_anon response */
+ SAMR_Q_CREATE_USER q_u;
+ SAMR_R_CREATE_USER r_u;
- r_u.status = 0x0;
- /* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
- {
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- /* associate the domain SID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
- {
- /* oh, whoops. don't know what error message to return, here */
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- if (r_u.status != 0 && pol_open)
+ if (!samr_io_q_create_user("", &q_u, data, 0))
{
- close_lsa_policy_hnd(&(r_u.connect_pol));
+ return False;
}
- DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
-
- /* store the response in the SMB stream */
- samr_io_r_connect_anon("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_connect_anon: %d\n", __LINE__));
-
+ r_u.status = _samr_create_user(&q_u.domain_pol,
+ &q_u.uni_name, q_u.acb_info,
+ q_u.access_mask,
+ &r_u.user_pol,
+ &r_u.unknown_0,
+ &r_u.user_rid);
+ return samr_io_r_create_user("", &r_u, rdata, 0);
}
/*******************************************************************
api_samr_connect_anon
********************************************************************/
-static BOOL api_samr_connect_anon( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_connect_anon( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
SAMR_Q_CONNECT_ANON q_u;
+ SAMR_R_CONNECT_ANON r_u;
- /* grab the samr open policy */
- samr_io_q_connect_anon("", &q_u, data, 0);
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- /* construct reply. always indicate success */
- samr_reply_connect_anon(&q_u, rdata);
+ if (!samr_io_q_connect_anon("", &q_u, data, 0))
+ {
+ return False;
+ }
- return True;
+ r_u.status = _samr_connect_anon(NULL,
+ q_u.access_mask,
+ &r_u.connect_pol);
+ return samr_io_r_connect_anon("", &r_u, rdata, 0);
}
/*******************************************************************
- samr_reply_connect
+ api_samr_connect
********************************************************************/
-static void samr_reply_connect(SAMR_Q_CONNECT *q_u,
- prs_struct *rdata)
+static BOOL api_samr_connect( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
+ SAMR_Q_CONNECT q_u;
SAMR_R_CONNECT r_u;
- BOOL pol_open = False;
-
- /* set up the SAMR connect response */
-
- r_u.status = 0x0;
- /* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.connect_pol))))
- {
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
- /* associate the domain SID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_lsa_policy_samr_pol_status(&(r_u.connect_pol), q_u->unknown_0))
- {
- /* oh, whoops. don't know what error message to return, here */
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- if (r_u.status != 0 && pol_open)
+ if (!samr_io_q_connect("", &q_u, data, 0))
{
- close_lsa_policy_hnd(&(r_u.connect_pol));
+ return False;
}
- DEBUG(5,("samr_connect: %d\n", __LINE__));
-
- /* store the response in the SMB stream */
- samr_io_r_connect("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_connect: %d\n", __LINE__));
-
+ r_u.status = _samr_connect(&q_u.uni_srv_name,
+ q_u.access_mask,
+ &r_u.connect_pol);
+ return samr_io_r_connect("", &r_u, rdata, 0);
}
/*******************************************************************
- api_samr_connect
+ api_samr_open_alias
********************************************************************/
-static BOOL api_samr_connect( uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_samr_open_alias( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+
{
- SAMR_Q_CONNECT q_u;
+ SAMR_Q_OPEN_ALIAS q_u;
+ SAMR_R_OPEN_ALIAS r_u;
- /* grab the samr open policy */
- samr_io_q_connect("", &q_u, data, 0);
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!samr_io_q_open_alias("", &q_u, data, 0))
+ {
+ return False;
+ }
- /* construct reply. always indicate success */
- samr_reply_connect(&q_u, rdata);
- return True;
+ r_u.status = _samr_open_alias(&q_u.dom_pol, q_u.unknown_0, q_u.rid_alias, &r_u.pol);
+
+ /* store the response in the SMB stream */
+ return samr_io_r_open_alias("", &r_u, rdata, 0);
}
/*******************************************************************
- samr_reply_open_alias
+ api_samr_open_group
********************************************************************/
-static void samr_reply_open_alias(SAMR_Q_OPEN_ALIAS *q_u,
- prs_struct *rdata)
+static BOOL api_samr_open_group( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
+
{
- SAMR_R_OPEN_ALIAS r_u;
- BOOL pol_open = False;
+ SAMR_Q_OPEN_GROUP q_u;
+ SAMR_R_OPEN_GROUP r_u;
- /* set up the SAMR open_alias response */
-
- r_u.status = 0x0;
- /* get a (unique) handle. open a policy on it. */
- if (r_u.status == 0x0 && !(pol_open = open_lsa_policy_hnd(&(r_u.pol))))
- {
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- /* associate a RID with the (unique) handle. */
- if (r_u.status == 0x0 && !set_lsa_policy_samr_rid(&(r_u.pol), q_u->rid_alias))
- {
- /* oh, whoops. don't know what error message to return, here */
- r_u.status = 0xC0000000 | NT_STATUS_OBJECT_NAME_NOT_FOUND;
- }
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- if (r_u.status != 0 && pol_open)
+ if (!samr_io_q_open_group("", &q_u, data, 0))
{
- close_lsa_policy_hnd(&(r_u.pol));
+ return False;
}
- DEBUG(5,("samr_open_alias: %d\n", __LINE__));
-
- /* store the response in the SMB stream */
- samr_io_r_open_alias("", &r_u, rdata, 0);
-
- DEBUG(5,("samr_open_alias: %d\n", __LINE__));
-
+ r_u.status = _samr_open_group(&q_u.domain_pol, q_u.access_mask,
+ q_u.rid_group, &r_u.pol);
+ return samr_io_r_open_group("", &r_u, rdata, 0);
}
/*******************************************************************
- api_samr_open_alias
+ api_samr_lookup_domain
********************************************************************/
-static BOOL api_samr_open_alias( uint16 vuid, prs_struct *data, prs_struct *rdata)
-
+static BOOL api_samr_lookup_domain( rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
- SAMR_Q_OPEN_ALIAS q_u;
+ SAMR_Q_LOOKUP_DOMAIN q_u;
+ SAMR_R_LOOKUP_DOMAIN r_u;
+ DOM_SID dom_sid;
+ uint32 status;
- /* grab the samr open policy */
- samr_io_q_open_alias("", &q_u, data, 0);
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- /* construct reply. always indicate success */
- samr_reply_open_alias(&q_u, rdata);
+ if (!samr_io_q_lookup_domain("", &q_u, data, 0))
+ {
+ return False;
+ }
- return True;
+ status = _samr_lookup_domain(&q_u.connect_pol, &q_u.uni_domain, &dom_sid);
+ make_samr_r_lookup_domain(&r_u, &dom_sid, status);
+
+ /* store the response in the SMB stream */
+ return samr_io_r_lookup_domain("", &r_u, rdata, 0);
}
/*******************************************************************
array of \PIPE\samr operations
********************************************************************/
-static struct api_struct api_samr_cmds [] =
+static const struct api_struct api_samr_cmds [] =
{
{ "SAMR_CLOSE_HND" , SAMR_CLOSE_HND , api_samr_close_hnd },
{ "SAMR_CONNECT" , SAMR_CONNECT , api_samr_connect },
{ "SAMR_CONNECT_ANON" , SAMR_CONNECT_ANON , api_samr_connect_anon },
+ { "SAMR_ENUM_DOMAINS" , SAMR_ENUM_DOMAINS , api_samr_enum_domains },
{ "SAMR_ENUM_DOM_USERS" , SAMR_ENUM_DOM_USERS , api_samr_enum_dom_users },
{ "SAMR_ENUM_DOM_GROUPS" , SAMR_ENUM_DOM_GROUPS , api_samr_enum_dom_groups },
{ "SAMR_ENUM_DOM_ALIASES" , SAMR_ENUM_DOM_ALIASES , api_samr_enum_dom_aliases },
- { "SAMR_LOOKUP_IDS" , SAMR_LOOKUP_IDS , api_samr_lookup_ids },
+ { "SAMR_QUERY_USERALIASES", SAMR_QUERY_USERALIASES, api_samr_query_useraliases},
+ { "SAMR_QUERY_ALIASMEM" , SAMR_QUERY_ALIASMEM , api_samr_query_aliasmem },
+ { "SAMR_QUERY_GROUPMEM" , SAMR_QUERY_GROUPMEM , api_samr_query_groupmem },
+ { "SAMR_ADD_ALIASMEM" , SAMR_ADD_ALIASMEM , api_samr_add_aliasmem },
+ { "SAMR_DEL_ALIASMEM" , SAMR_DEL_ALIASMEM , api_samr_del_aliasmem },
+ { "SAMR_ADD_GROUPMEM" , SAMR_ADD_GROUPMEM , api_samr_add_groupmem },
+ { "SAMR_DEL_GROUPMEM" , SAMR_DEL_GROUPMEM , api_samr_del_groupmem },
+ { "SAMR_DELETE_DOM_USER" , SAMR_DELETE_DOM_USER , api_samr_delete_dom_user },
+ { "SAMR_DELETE_DOM_GROUP" , SAMR_DELETE_DOM_GROUP , api_samr_delete_dom_group },
+ { "SAMR_DELETE_DOM_ALIAS" , SAMR_DELETE_DOM_ALIAS , api_samr_delete_dom_alias },
+ { "SAMR_CREATE_DOM_GROUP" , SAMR_CREATE_DOM_GROUP , api_samr_create_dom_group },
+ { "SAMR_CREATE_DOM_ALIAS" , SAMR_CREATE_DOM_ALIAS , api_samr_create_dom_alias },
{ "SAMR_LOOKUP_NAMES" , SAMR_LOOKUP_NAMES , api_samr_lookup_names },
{ "SAMR_OPEN_USER" , SAMR_OPEN_USER , api_samr_open_user },
{ "SAMR_QUERY_USERINFO" , SAMR_QUERY_USERINFO , api_samr_query_userinfo },
- { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
+ { "SAMR_SET_USERINFO" , SAMR_SET_USERINFO , api_samr_set_userinfo },
+ { "SAMR_SET_USERINFO2" , SAMR_SET_USERINFO2 , api_samr_set_userinfo2 },
+ { "SAMR_QUERY_DOMAIN_INFO", SAMR_QUERY_DOMAIN_INFO, api_samr_query_dom_info },
{ "SAMR_QUERY_USERGROUPS" , SAMR_QUERY_USERGROUPS , api_samr_query_usergroups },
{ "SAMR_QUERY_DISPINFO" , SAMR_QUERY_DISPINFO , api_samr_query_dispinfo },
+ { "SAMR_QUERY_DISPINFO3" , SAMR_QUERY_DISPINFO3 , api_samr_query_dispinfo },
+ { "SAMR_QUERY_DISPINFO4" , SAMR_QUERY_DISPINFO4 , api_samr_query_dispinfo },
{ "SAMR_QUERY_ALIASINFO" , SAMR_QUERY_ALIASINFO , api_samr_query_aliasinfo },
- { "SAMR_0x32" , 0x32 , api_samr_unknown_32 },
- { "SAMR_UNKNOWN_12" , SAMR_UNKNOWN_12 , api_samr_unknown_12 },
- { "SAMR_UNKNOWN_38" , SAMR_UNKNOWN_38 , api_samr_unknown_38 },
+ { "SAMR_QUERY_GROUPINFO" , SAMR_QUERY_GROUPINFO , api_samr_query_groupinfo },
+ { "SAMR_SET_GROUPINFO" , SAMR_SET_GROUPINFO , api_samr_set_groupinfo },
+ { "SAMR_CREATE_USER" , SAMR_CREATE_USER , api_samr_create_user },
+ { "SAMR_LOOKUP_RIDS" , SAMR_LOOKUP_RIDS , api_samr_lookup_rids },
+ { "SAMR_GET_DOM_PWINFO" , SAMR_GET_DOM_PWINFO , api_samr_get_dom_pwinfo },
{ "SAMR_CHGPASSWD_USER" , SAMR_CHGPASSWD_USER , api_samr_chgpasswd_user },
{ "SAMR_OPEN_ALIAS" , SAMR_OPEN_ALIAS , api_samr_open_alias },
+ { "SAMR_OPEN_GROUP" , SAMR_OPEN_GROUP , api_samr_open_group },
{ "SAMR_OPEN_DOMAIN" , SAMR_OPEN_DOMAIN , api_samr_open_domain },
- { "SAMR_UNKNOWN_3" , SAMR_UNKNOWN_3 , api_samr_unknown_3 },
- { "SAMR_UNKNOWN_2C" , SAMR_UNKNOWN_2C , api_samr_unknown_2c },
+ { "SAMR_UNKNOWN_2D" , SAMR_UNKNOWN_2D , api_samr_unknown_2d },
+ { "SAMR_LOOKUP_DOMAIN" , SAMR_LOOKUP_DOMAIN , api_samr_lookup_domain },
+ { "SAMR_QUERY_SEC_OBJECT" , SAMR_QUERY_SEC_OBJECT , api_samr_query_sec_obj },
+ { "SAMR_GET_USRDOM_PWINFO", SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo},
{ NULL , 0 , NULL }
};
/*******************************************************************
receives a samr pipe and responds.
********************************************************************/
-BOOL api_samr_rpc(pipes_struct *p, prs_struct *data)
+BOOL api_samr_rpc(rpcsrv_struct *p)
{
- return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds, data);
+ return api_rpcTNP(p, "api_samr_rpc", api_samr_cmds);
}
+
diff --git a/source/rpc_server/srv_sid.c b/source/rpc_server/srv_sid.c
new file mode 100644
index 00000000000..6552e0963bf
--- /dev/null
+++ b/source/rpc_server/srv_sid.c
@@ -0,0 +1,22 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* this module is retired, is is called lib/sids.c */
diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c
index 75493b7a303..5f3f56988a7 100755
--- a/source/rpc_server/srv_spoolss.c
+++ b/source/rpc_server/srv_spoolss.c
@@ -21,75 +21,86 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
+
/********************************************************************
- * api_spoolss_open_printer_ex
+ * api_spoolss_open_printer
+ *
+ * called from the spoolss dispatcher
********************************************************************/
-static BOOL api_spoolss_open_printer_ex(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_open_printer_ex(rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
SPOOL_Q_OPEN_PRINTER_EX q_u;
SPOOL_R_OPEN_PRINTER_EX r_u;
UNISTR2 *printername = NULL;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if (!spoolss_io_q_open_printer_ex("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_open_printer_ex: unable to unmarshall SPOOL_Q_OPEN_PRINTER_EX.\n"));
+ if (!spoolss_io_q_open_printer_ex("", &q_u, data, 0))
+ {
return False;
}
- if (q_u.printername_ptr != 0)
+ if (q_u.ptr != 0)
+ {
printername = &q_u.printername;
-
+ }
r_u.status = _spoolss_open_printer_ex( printername,
- &q_u.printer_default,
- q_u.user_switch, q_u.user_ctr,
+ q_u.unknown0, q_u.cbbuf,
+ q_u.devmod, q_u.access_required,
+ q_u.unknown1, q_u.unknown2,
+ q_u.unknown3, q_u.unknown4,
+ q_u.unknown5, q_u.unknown6,
+ q_u.unknown7, q_u.unknown8,
+ q_u.unknown9, q_u.unknown10,
+ &q_u.station, &q_u.username,
&r_u.handle);
-
- if (!spoolss_io_r_open_printer_ex("",&r_u,rdata,0)){
- DEBUG(0,("spoolss_io_r_open_printer_ex: unable to marshall SPOOL_R_OPEN_PRINTER_EX.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_open_printer_ex("",&r_u,rdata,0);
+ return ret;
}
+
/********************************************************************
* api_spoolss_getprinterdata
*
* called from the spoolss dispatcher
********************************************************************/
-static BOOL api_spoolss_getprinterdata(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_getprinterdata(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_GETPRINTERDATA q_u;
SPOOL_R_GETPRINTERDATA r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
/* read the stream and fill the struct */
- if (!spoolss_io_q_getprinterdata("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_getprinterdata: unable to unmarshall SPOOL_Q_GETPRINTERDATA.\n"));
+ if (!spoolss_io_q_getprinterdata("", &q_u, data, 0))
+ {
return False;
}
-
- r_u.status = _spoolss_getprinterdata( &q_u.handle, &q_u.valuename,
- q_u.size, &r_u.type, &r_u.size,
- &r_u.data, &r_u.needed);
- if (!spoolss_io_r_getprinterdata("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_getprinterdata: unable to marshall SPOOL_R_GETPRINTERDATA.\n"));
- return False;
- }
- safe_free(r_u.data);
+ r_u.size = q_u.size;
+ r_u.status = _spoolss_getprinterdata( &q_u.handle, &q_u.valuename,
+ &r_u.type, &r_u.size,
+ &r_u.data, &r_u.numeric_data,
+ &r_u.needed);
- return True;
+ ret = spoolss_io_r_getprinterdata("", &r_u, rdata, 0);
+ safe_free(r_u.data);
+ return ret;
}
/********************************************************************
@@ -97,57 +108,54 @@ static BOOL api_spoolss_getprinterdata(uint16 vuid, prs_struct *data, prs_struct
*
* called from the spoolss dispatcher
********************************************************************/
-static BOOL api_spoolss_closeprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_closeprinter(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_CLOSEPRINTER q_u;
SPOOL_R_CLOSEPRINTER r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if (!spoolss_io_q_closeprinter("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_closeprinter: unable to unmarshall SPOOL_Q_CLOSEPRINTER.\n"));
+ if (!spoolss_io_q_closeprinter("", &q_u, data, 0))
+ {
return False;
}
r_u.status = _spoolss_closeprinter(&q_u.handle);
memcpy(&r_u.handle, &q_u.handle, sizeof(r_u.handle));
-
- if (!spoolss_io_r_closeprinter("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_closeprinter: unable to marshall SPOOL_R_CLOSEPRINTER.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_closeprinter("",&r_u,rdata,0);
+ return ret;
}
/********************************************************************
* api_spoolss_rffpcnex
* ReplyFindFirstPrinterChangeNotifyEx
********************************************************************/
-static BOOL api_spoolss_rffpcnex(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_rffpcnex(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_RFFPCNEX q_u;
SPOOL_R_RFFPCNEX r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if (!spoolss_io_q_rffpcnex("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_rffpcnex: unable to unmarshall SPOOL_Q_RFFPCNEX.\n"));
+ if (!spoolss_io_q_rffpcnex("", &q_u, data, 0))
+ {
return False;
}
+
r_u.status = _spoolss_rffpcnex(&q_u.handle, q_u.flags,
q_u.options, &q_u.localmachine,
- q_u.printerlocal, q_u.option);
-
- if (!spoolss_io_r_rffpcnex("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_rffpcnex: unable to marshall SPOOL_R_RFFPCNEX.\n"));
- return False;
- }
-
- return True;
+ q_u.printerlocal, &q_u.option);
+ ret = spoolss_io_r_rffpcnex("",&r_u,rdata,0);
+ return ret;
}
@@ -157,33 +165,27 @@ static BOOL api_spoolss_rffpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat
* called from the spoolss dispatcher
*
********************************************************************/
-static BOOL api_spoolss_rfnpcnex(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_rfnpcnex(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_RFNPCNEX q_u;
SPOOL_R_RFNPCNEX r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if (!spoolss_io_q_rfnpcnex("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_rfnpcnex: unable to unmarshall SPOOL_Q_RFNPCNEX.\n"));
+ if (!spoolss_io_q_rfnpcnex("", &q_u, data, 0))
+ {
return False;
}
- r_u.status = _spoolss_rfnpcnex(&q_u.handle, q_u.change,
- q_u.option, &r_u.info);
-
- /* we always have a NOTIFY_INFO struct */
- r_u.info_ptr=0x1;
-
- if (!spoolss_io_r_rfnpcnex("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_rfnpcnex: unable to marshall SPOOL_R_RFNPCNEX.\n"));
- return False;
- }
- safe_free(r_u.info.data);
-
- return True;
+ r_u.status = _spoolss_rfnpcnex(&q_u.handle, q_u.change,
+ &q_u.option, &r_u.count, &r_u.info);
+ ret = spoolss_io_r_rfnpcnex("", &r_u, rdata, 0);
+ return ret;
}
@@ -192,74 +194,80 @@ static BOOL api_spoolss_rfnpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat
* called from the spoolss dispatcher
*
********************************************************************/
-static BOOL api_spoolss_enumprinters(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_enumprinters(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ENUMPRINTERS q_u;
SPOOL_R_ENUMPRINTERS r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if (!spoolss_io_q_enumprinters("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_enumprinters: unable to unmarshall SPOOL_Q_ENUMPRINTERS.\n"));
+ if (!spoolss_io_q_enumprinters("", &q_u, data, 0))
+ {
return False;
}
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-
- r_u.status = _spoolss_enumprinters( q_u.flags, &q_u.servername, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed, &r_u.returned);
- if (!new_spoolss_io_r_enumprinters("", &r_u, rdata, 0)) {
- DEBUG(0,("new_spoolss_io_r_enumprinters: unable to marshall SPOOL_R_ENUMPRINTERS.\n"));
- new_spoolss_free_buffer(q_u.buffer);
- return False;
- }
-
- new_spoolss_free_buffer(q_u.buffer);
+ /* lkclXXX DAMN DAMN DAMN! MICROSOFT @#$%S IT UP, AGAIN, AND WE
+ HAVE TO DEAL WITH IT! AGH!
+ */
+ r_u.level = q_u.level;
+ r_u.status = _spoolss_enumprinters(
+ q_u.flags,
+ &q_u.servername,
+ q_u.level,
+ &q_u.buffer,
+ q_u.buf_size,
+ &r_u.offered,
+ &r_u.needed,
+ &r_u.ctr,
+ &r_u.returned);
+
+ memcpy(r_u.servername.buffer,q_u.servername.buffer,
+ 2*q_u.servername.uni_str_len);
+ r_u.servername.buffer[q_u.servername.uni_str_len] = 0;
- return True;
+ spoolss_io_free_buffer(&(q_u.buffer));
+ ret = spoolss_io_r_enumprinters("",&r_u,rdata,0);
+ return ret;
}
+
/********************************************************************
* api_spoolss_getprinter
* called from the spoolss dispatcher
*
********************************************************************/
-static BOOL api_spoolss_getprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_getprinter(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_GETPRINTER q_u;
SPOOL_R_GETPRINTER r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if(!spoolss_io_q_getprinter("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_getprinter: unable to unmarshall SPOOL_Q_GETPRINTER.\n"));
+ if (!spoolss_io_q_getprinter("", &q_u, data, 0))
+ {
return False;
}
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
r_u.status = _spoolss_getprinter(&q_u.handle, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed);
+ &r_u.ctr, &q_u.offered, &r_u.needed);
- if(!spoolss_io_r_getprinter("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_getprinter: unable to marshall SPOOL_R_GETPRINTER.\n"));
- new_spoolss_free_buffer(q_u.buffer);
- return False;
- }
+ memcpy(&r_u.handle, &q_u.handle, sizeof(&r_u.handle));
+ r_u.offered = q_u.offered;
+ r_u.level = q_u.level;
+ safe_free(q_u.buffer);
- new_spoolss_free_buffer(q_u.buffer);
- return True;
+ ret = spoolss_io_r_getprinter("",&r_u,rdata,0);
+ return ret;
}
@@ -268,36 +276,34 @@ static BOOL api_spoolss_getprinter(uint16 vuid, prs_struct *data, prs_struct *rd
* called from the spoolss dispatcher
*
********************************************************************/
-static BOOL api_spoolss_getprinterdriver2(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_getprinterdriver2(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_GETPRINTERDRIVER2 q_u;
SPOOL_R_GETPRINTERDRIVER2 r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if(!spoolss_io_q_getprinterdriver2("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_getprinterdriver2: unable to unmarshall SPOOL_Q_GETPRINTERDRIVER2.\n"));
+
+ if (!spoolss_io_q_getprinterdriver2("", &q_u, data, 0))
+ {
return False;
}
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-
- r_u.status = _spoolss_getprinterdriver2(&q_u.handle, &q_u.architecture, q_u.level, q_u.unknown,
- r_u.buffer, q_u.offered,
- &r_u.needed, &r_u.unknown0, &r_u.unknown1);
- if(!spoolss_io_r_getprinterdriver2("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_getprinterdriver2: unable to marshall SPOOL_R_GETPRINTERDRIVER2.\n"));
- new_spoolss_free_buffer(q_u.buffer);
- return False;
- }
+ r_u.status = _spoolss_getprinterdriver2(&q_u.handle,
+ &q_u.architecture, q_u.level,
+ &r_u.ctr, &q_u.buf_size,
+ &r_u.needed);
- new_spoolss_free_buffer(q_u.buffer);
- return True;
+ r_u.offered = q_u.buf_size;
+ r_u.level = q_u.level;
+ spoolss_io_free_buffer(&(q_u.buffer));
+
+ ret = spoolss_io_r_getprinterdriver2("",&r_u,rdata,0);
+ return ret;
}
/********************************************************************
@@ -305,27 +311,25 @@ static BOOL api_spoolss_getprinterdriver2(uint16 vuid, prs_struct *data, prs_str
* called from the spoolss dispatcher
*
********************************************************************/
-static BOOL api_spoolss_startpageprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_startpageprinter(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_STARTPAGEPRINTER q_u;
SPOOL_R_STARTPAGEPRINTER r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_startpageprinter("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_startpageprinter: unable to unmarshall SPOOL_Q_STARTPAGEPRINTER.\n"));
+
+ if (!spoolss_io_q_startpageprinter("", &q_u, data, 0))
+ {
return False;
}
r_u.status = _spoolss_startpageprinter(&q_u.handle);
-
- if(!spoolss_io_r_startpageprinter("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_startpageprinter: unable to marshall SPOOL_R_STARTPAGEPRINTER.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_startpageprinter("",&r_u,rdata,0);
+ return ret;
}
@@ -334,41 +338,45 @@ static BOOL api_spoolss_startpageprinter(uint16 vuid, prs_struct *data, prs_stru
* called from the spoolss dispatcher
*
********************************************************************/
-static BOOL api_spoolss_endpageprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_endpageprinter(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ENDPAGEPRINTER q_u;
SPOOL_R_ENDPAGEPRINTER r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_endpageprinter("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_endpageprinter: unable to unmarshall SPOOL_Q_ENDPAGEPRINTER.\n"));
+
+ if (!spoolss_io_q_endpageprinter("", &q_u, data, 0))
+ {
return False;
}
r_u.status = _spoolss_endpageprinter(&q_u.handle);
-
- if(!spoolss_io_r_endpageprinter("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_endpageprinter: unable to marshall SPOOL_R_ENDPAGEPRINTER.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_endpageprinter("",&r_u,rdata,0);
+ return ret;
}
/********************************************************************
-********************************************************************/
-static BOOL api_spoolss_startdocprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
+ * api_spoolss_getprinter
+ * called from the spoolss dispatcher
+ *
+ ********************************************************************/
+static BOOL api_spoolss_startdocprinter(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_STARTDOCPRINTER q_u;
SPOOL_R_STARTDOCPRINTER r_u;
-
+
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_startdocprinter("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_startdocprinter: unable to unmarshall SPOOL_Q_STARTDOCPRINTER.\n"));
+
+ if (!spoolss_io_q_startdocprinter("", &q_u, data, 0))
+ {
return False;
}
@@ -376,54 +384,55 @@ static BOOL api_spoolss_startdocprinter(uint16 vuid, prs_struct *data, prs_struc
q_u.doc_info_container.level,
&q_u.doc_info_container.docinfo,
&r_u.jobid);
-
- if(!spoolss_io_r_startdocprinter("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_startdocprinter: unable to marshall SPOOL_R_STARTDOCPRINTER.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_startdocprinter("",&r_u,rdata,0);
+ return ret;
}
-
/********************************************************************
-********************************************************************/
-static BOOL api_spoolss_enddocprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
+ * api_spoolss_getprinter
+ * called from the spoolss dispatcher
+ *
+ ********************************************************************/
+static BOOL api_spoolss_enddocprinter(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ENDDOCPRINTER q_u;
SPOOL_R_ENDDOCPRINTER r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_enddocprinter("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_enddocprinter: unable to unmarshall SPOOL_Q_ENDDOCPRINTER.\n"));
+
+ if (!spoolss_io_q_enddocprinter("", &q_u, data, 0))
+ {
return False;
}
r_u.status = _spoolss_enddocprinter(&q_u.handle);
-
- if(!spoolss_io_r_enddocprinter("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_enddocprinter: unable to marshall SPOOL_R_ENDDOCPRINTER.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_enddocprinter("",&r_u,rdata,0);
+ return ret;
}
/********************************************************************
-********************************************************************/
-static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
+ * api_spoolss_getprinter
+ * called from the spoolss dispatcher
+ *
+ ********************************************************************/
+static BOOL api_spoolss_writeprinter(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_WRITEPRINTER q_u;
SPOOL_R_WRITEPRINTER r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_writeprinter("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_writeprinter: unable to unmarshall SPOOL_Q_WRITEPRINTER.\n"));
+
+ if (!spoolss_io_q_writeprinter("", &q_u, data, 0))
+ {
return False;
}
@@ -433,644 +442,555 @@ static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct *
&q_u.buffer_size2);
r_u.buffer_written = q_u.buffer_size2;
safe_free(q_u.buffer);
-
- if(!spoolss_io_r_writeprinter("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_writeprinter: unable to marshall SPOOL_R_WRITEPRINTER.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_writeprinter("",&r_u,rdata,0);
+ return ret;
}
/****************************************************************************
-
****************************************************************************/
-static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_setprinter(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_SETPRINTER q_u;
SPOOL_R_SETPRINTER r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!spoolss_io_q_setprinter("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_setprinter: unable to unmarshall SPOOL_Q_SETPRINTER.\n"));
- return False;
- }
-
- r_u.status = _spoolss_setprinter(&q_u.handle, q_u.level, &q_u.info,
- q_u.devmode_ctr, q_u.command);
-
- /* now, we can free the memory */
- if (q_u.info.level==2 && q_u.info.info_ptr!=0)
- safe_free(q_u.info.info_2);
-
- if (q_u.devmode_ctr.devmode_ptr!=0)
- safe_free(q_u.devmode_ctr.devmode);
-
- if(!spoolss_io_r_setprinter("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_setprinter: unable to marshall SPOOL_R_SETPRINTER.\n"));
+ if (!spoolss_io_q_setprinter("", &q_u, data, 0))
+ {
return False;
}
- return True;
+ DEBUG(0,("api_spoolss_setprinter: typecast sec_des to uint8*!\n"));
+ r_u.status = _spoolss_setprinter(&q_u.handle,
+ q_u.level, &q_u.info,
+ q_u.devmode,
+ q_u.security.size_of_buffer,
+ (const uint8*)q_u.security.data,
+ q_u.command);
+ ret = spoolss_io_r_setprinter("",&r_u,rdata,0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_fcpn(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_fcpn(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_FCPN q_u;
SPOOL_R_FCPN r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!spoolss_io_q_fcpn("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_fcpn: unable to unmarshall SPOOL_Q_FCPN.\n"));
+ if (!spoolss_io_q_fcpn("", &q_u, data, 0))
+ {
return False;
}
r_u.status = _spoolss_fcpn(&q_u.handle);
-
- if(!spoolss_io_r_fcpn("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_fcpn: unable to marshall SPOOL_R_FCPN.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_fcpn("",&r_u,rdata,0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_addjob(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_addjob(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ADDJOB q_u;
SPOOL_R_ADDJOB r_u;
-
+
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if(!spoolss_io_q_addjob("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_addjob: unable to unmarshall SPOOL_Q_ADDJOB.\n"));
+
+ if (!spoolss_io_q_addjob("", &q_u, data, 0))
+ {
return False;
}
- /* that's only an [in] buffer ! */
r_u.status = _spoolss_addjob(&q_u.handle, q_u.level,
- q_u.buffer, q_u.offered);
-
- if(!spoolss_io_r_addjob("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_addjob: unable to marshall SPOOL_R_ADDJOB.\n"));
- new_spoolss_free_buffer(q_u.buffer);
- return False;
- }
-
- new_spoolss_free_buffer(q_u.buffer);
-
- return True;
+ &q_u.buffer, q_u.buf_size);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
+ ret = spoolss_io_r_addjob("",&r_u,rdata,0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_enumjobs(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_enumjobs(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ENUMJOBS q_u;
SPOOL_R_ENUMJOBS r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if (!spoolss_io_q_enumjobs("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_enumjobs: unable to unmarshall SPOOL_Q_ENUMJOBS.\n"));
- return False;
- }
-
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-
- r_u.status = _spoolss_enumjobs(&q_u.handle, q_u.firstjob, q_u.numofjobs, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed, &r_u.returned);
-
- if (!spoolss_io_r_enumjobs("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_enumjobs: unable to marshall SPOOL_R_ENUMJOBS.\n"));
- new_spoolss_free_buffer(q_u.buffer);
+
+ if (!spoolss_io_q_enumjobs("", &q_u, data, 0))
+ {
return False;
}
- new_spoolss_free_buffer(q_u.buffer);
-
- return True;
+ r_u.offered = q_u.buf_size;
+ r_u.level = q_u.level;
+ r_u.status = _spoolss_enumjobs(&q_u.handle,
+ q_u.firstjob, q_u.numofjobs, q_u.level,
+ &r_u.ctr, &r_u.offered, &r_u.numofjobs);
+ ret = spoolss_io_free_buffer(&(q_u.buffer));
+ spoolss_io_r_enumjobs("",&r_u,rdata,0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_schedulejob(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_schedulejob(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_SCHEDULEJOB q_u;
SPOOL_R_SCHEDULEJOB r_u;
-
+
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_schedulejob("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_schedulejob: unable to unmarshall SPOOL_Q_SCHEDULEJOB.\n"));
+
+ if (!spoolss_io_q_schedulejob("", &q_u, data, 0))
+ {
return False;
}
r_u.status = _spoolss_schedulejob(&q_u.handle, q_u.jobid);
-
- if(!spoolss_io_r_schedulejob("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_schedulejob: unable to marshall SPOOL_R_SCHEDULEJOB.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_schedulejob("",&r_u,rdata,0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_setjob(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_setjob(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_SETJOB q_u;
SPOOL_R_SETJOB r_u;
-
+
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- if(!spoolss_io_q_setjob("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_setjob: unable to unmarshall SPOOL_Q_SETJOB.\n"));
+
+ if (!spoolss_io_q_setjob("", &q_u, data, 0))
+ {
return False;
}
r_u.status = _spoolss_setjob(&q_u.handle, q_u.jobid,
q_u.level, &q_u.ctr, q_u.command);
-
- if(!spoolss_io_r_setjob("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_setjob: unable to marshall SPOOL_R_SETJOB.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_setjob("",&r_u,rdata,0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_enumprinterdrivers(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_enumprinterdrivers(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ENUMPRINTERDRIVERS q_u;
SPOOL_R_ENUMPRINTERDRIVERS r_u;
-
+
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if (!spoolss_io_q_enumprinterdrivers("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_enumprinterdrivers: unable to unmarshall SPOOL_Q_ENUMPRINTERDRIVERS.\n"));
+
+ if (!spoolss_io_q_enumprinterdrivers("", &q_u, data, 0))
+ {
return False;
}
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-
- r_u.status = _spoolss_enumprinterdrivers(&q_u.name, &q_u.environment, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed, &r_u.returned);
-
- if (!new_spoolss_io_r_enumprinterdrivers("",&r_u,rdata,0)) {
- DEBUG(0,("new_spoolss_io_r_enumprinterdrivers: unable to marshall SPOOL_R_ENUMPRINTERDRIVERS.\n"));
- new_spoolss_free_buffer(q_u.buffer);
- return False;
- }
- new_spoolss_free_buffer(q_u.buffer);
+ r_u.offered = q_u.buf_size;
+ r_u.level = q_u.level;
+ r_u.status = _spoolss_enumprinterdrivers(&q_u.name,
+ &q_u.environment, q_u. level,
+ &r_u.ctr, &r_u.offered, &r_u.numofdrivers);
- return True;
+ spoolss_io_free_buffer(&q_u.buffer);
+ ret = spoolss_io_r_enumdrivers("",&r_u,rdata,0);
+ free_spoolss_r_enumdrivers(&r_u);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_enumforms(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ENUMFORMS q_u;
SPOOL_R_ENUMFORMS r_u;
-
+
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if (!spoolss_io_q_enumforms("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_enumforms: unable to unmarshall SPOOL_Q_ENUMFORMS.\n"));
- return False;
- }
-
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-
- r_u.status = _new_spoolss_enumforms(&q_u.handle, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed, &r_u.numofforms);
-
- if (!new_spoolss_io_r_enumforms("",&r_u,rdata,0)) {
- DEBUG(0,("new_spoolss_io_r_enumforms: unable to marshall SPOOL_R_ENUMFORMS.\n"));
- new_spoolss_free_buffer(q_u.buffer);
+
+ if (!spoolss_io_q_enumforms("", &q_u, data, 0))
+ {
return False;
}
- new_spoolss_free_buffer(q_u.buffer);
- return True;
+ r_u.offered = q_u.buf_size;
+ r_u.level = q_u.level;
+ r_u.status = _spoolss_enumforms(&q_u.handle,
+ q_u.level,
+ &r_u.forms_1,
+ &r_u.offered,
+ &r_u.numofforms);
+ spoolss_io_free_buffer(&q_u.buffer);
+ ret = spoolss_io_r_enumforms("",&r_u,rdata,0);
+ spoolss_free_r_enumforms(&r_u);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_enumports(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_enumports(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ENUMPORTS q_u;
SPOOL_R_ENUMPORTS r_u;
-
+
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if(!spoolss_io_q_enumports("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_enumports: unable to unmarshall SPOOL_Q_ENUMPORTS.\n"));
- return False;
- }
-
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-
- r_u.status = _spoolss_enumports(&q_u.name, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed, &r_u.returned);
-
- if (!new_spoolss_io_r_enumports("",&r_u,rdata,0)) {
- DEBUG(0,("new_spoolss_io_r_enumports: unable to marshall SPOOL_R_ENUMPORTS.\n"));
- new_spoolss_free_buffer(q_u.buffer);
+
+ if (!spoolss_io_q_enumports("", &q_u, data, 0))
+ {
return False;
}
- new_spoolss_free_buffer(q_u.buffer);
- return True;
+ r_u.offered = q_u.buf_size;
+ r_u.level = q_u.level;
+ r_u.status = _spoolss_enumports(&q_u.name,
+ q_u.level,
+ &r_u.ctr,
+ &r_u.offered,
+ &r_u.numofports);
+
+ spoolss_io_free_buffer(&(q_u.buffer));
+ ret = spoolss_io_r_enumports("",&r_u,rdata,0);
+ spoolss_free_r_enumports(&r_u);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_addprinterex(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_addprinterex(rpcsrv_struct *p, prs_struct *data, prs_struct *rdata)
{
SPOOL_Q_ADDPRINTEREX q_u;
SPOOL_R_ADDPRINTEREX r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!spoolss_io_q_addprinterex("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_addprinterex: unable to unmarshall SPOOL_Q_ADDPRINTEREX.\n"));
+ if (!spoolss_io_q_addprinterex("", &q_u, data, 0))
+ {
return False;
}
-
+
r_u.status = _spoolss_addprinterex(&q_u.server_name,
q_u.level, &q_u.info,
q_u.unk0, q_u.unk1, q_u.unk2, q_u.unk3,
- q_u.user_switch, &q_u.user_ctr,
+ q_u.user_level, &q_u.user,
&r_u.handle);
-
- if(!spoolss_io_r_addprinterex("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_addprinterex: unable to marshall SPOOL_R_ADDPRINTEREX.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_addprinterex("", &r_u, rdata, 0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_addprinterdriver(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_addprinterdriver(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ADDPRINTERDRIVER q_u;
SPOOL_R_ADDPRINTERDRIVER r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!spoolss_io_q_addprinterdriver("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_addprinterdriver: unable to unmarshall SPOOL_Q_ADDPRINTERDRIVER.\n"));
+ if (!spoolss_io_q_addprinterdriver("", &q_u, data, 0))
+ {
return False;
}
-
- r_u.status = _spoolss_addprinterdriver(&q_u.server_name, q_u.level, &q_u.info);
-
- if(!spoolss_io_r_addprinterdriver("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_addprinterdriver: unable to marshall SPOOL_R_ADDPRINTERDRIVER.\n"));
- return False;
- }
-
- return True;
+
+ r_u.status = _spoolss_addprinterdriver(&q_u.server_name,
+ q_u.level, &q_u.info);
+ ret = spoolss_io_r_addprinterdriver("", &r_u, rdata, 0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_getprinterdriverdirectory(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_getprinterdriverdirectory(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_GETPRINTERDRIVERDIR q_u;
SPOOL_R_GETPRINTERDRIVERDIR r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
-
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if(!spoolss_io_q_getprinterdriverdir("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_getprinterdriverdir: unable to unmarshall SPOOL_Q_GETPRINTERDRIVERDIR.\n"));
- return False;
- }
-
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-
- r_u.status = _spoolss_getprinterdriverdirectory(&q_u.name, &q_u.environment, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed);
-
- if(!spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_getprinterdriverdir: unable to marshall SPOOL_R_GETPRINTERDRIVERDIR.\n"));
- new_spoolss_free_buffer(q_u.buffer);
+
+ if (!spoolss_io_q_getprinterdriverdir("", &q_u, data, 0))
+ {
return False;
}
- new_spoolss_free_buffer(q_u.buffer);
-
- return True;
+
+ r_u.offered = q_u.buf_size;
+ r_u.level = q_u.level;
+ r_u.status = _spoolss_getprinterdriverdirectory(&q_u.name,
+ &q_u.environment,
+ q_u.level,
+ &r_u.ctr,
+ &r_u.offered);
+ ret = spoolss_io_free_buffer(&q_u.buffer);
+ spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_enumprinterdata(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_enumprinterdata(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ENUMPRINTERDATA q_u;
SPOOL_R_ENUMPRINTERDATA r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!spoolss_io_q_enumprinterdata("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_enumprinterdata: unable to unmarshall SPOOL_Q_ENUMPRINTERDATA.\n"));
- return False;
- }
-
- r_u.status = _spoolss_enumprinterdata(&q_u.handle, q_u.index, q_u.valuesize, q_u.datasize,
- &r_u.valuesize, &r_u.value, &r_u.realvaluesize,
- &r_u.type,
- &r_u.datasize, &r_u.data, &r_u.realdatasize);
-
- if(!spoolss_io_r_enumprinterdata("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_enumprinterdata: unable to marshall SPOOL_R_ENUMPRINTERDATA.\n"));
- safe_free(r_u.value);
- safe_free(r_u.data);
+ if (!spoolss_io_q_enumprinterdata("", &q_u, data, 0))
+ {
return False;
}
- safe_free(r_u.value);
- safe_free(r_u.data);
+ r_u.valuesize = q_u.valuesize;
+ r_u.datasize = q_u.datasize;
- return True;
+ r_u.status = _spoolss_enumprinterdata(&q_u.handle,
+ q_u.index,/* in */
+ &r_u.valuesize,/* in out */
+ &r_u.value,/* out */
+ &r_u.realvaluesize,/* out */
+ &r_u.type,/* out */
+ &r_u.datasize,/* in out */
+ &r_u.data,/* out */
+ &r_u.realdatasize);/* out */
+ ret = spoolss_io_r_enumprinterdata("", &r_u, rdata, 0);
+ safe_free(r_u.data);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_setprinterdata(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_setprinterdata(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_SETPRINTERDATA q_u;
SPOOL_R_SETPRINTERDATA r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!spoolss_io_q_setprinterdata("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_setprinterdata: unable to unmarshall SPOOL_Q_SETPRINTERDATA.\n"));
+ if (!spoolss_io_q_setprinterdata("", &q_u, data, 0))
+ {
return False;
}
-
+
r_u.status = _spoolss_setprinterdata(&q_u.handle,
&q_u.value, q_u.type, q_u.max_len,
q_u.data, q_u.real_len, q_u.numeric_data);
-
- if(!spoolss_io_r_setprinterdata("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_setprinterdata: unable to marshall SPOOL_R_SETPRINTERDATA.\n"));
- return False;
- }
-
- return True;
+ ret = spoolss_io_r_setprinterdata("", &r_u, rdata, 0);
+ safe_free(q_u.data);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_addform(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_addform(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ADDFORM q_u;
SPOOL_R_ADDFORM r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!spoolss_io_q_addform("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_addform: unable to unmarshall SPOOL_Q_ADDFORM.\n"));
- return False;
- }
-
- r_u.status = _spoolss_addform(&q_u.handle, q_u.level, &q_u.form);
-
- if(!spoolss_io_r_addform("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_addform: unable to marshall SPOOL_R_ADDFORM.\n"));
+ if (!spoolss_io_q_addform("", &q_u, data, 0))
+ {
return False;
}
- return True;
+ r_u.status = _spoolss_addform(&q_u.handle, q_u.level, &q_u.form);
+ ret = spoolss_io_r_addform("", &r_u, rdata, 0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_setform(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_setform(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_SETFORM q_u;
SPOOL_R_SETFORM r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- if(!spoolss_io_q_setform("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_setform: unable to unmarshall SPOOL_Q_SETFORM.\n"));
- return False;
- }
-
- r_u.status = _spoolss_setform(&q_u.handle, &q_u.name, q_u.level, &q_u.form);
-
- if(!spoolss_io_r_setform("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_setform: unable to marshall SPOOL_R_SETFORM.\n"));
+ if (!spoolss_io_q_setform("", &q_u, data, 0))
+ {
return False;
}
- return True;
+ r_u.status = _spoolss_setform(&q_u.handle,
+ &q_u.name, q_u.level, &q_u.form);
+ ret = spoolss_io_r_setform("", &r_u, rdata, 0);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_enumprintprocessors(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_enumprintprocessors(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ENUMPRINTPROCESSORS q_u;
SPOOL_R_ENUMPRINTPROCESSORS r_u;
- ZERO_STRUCT(q_u);
- ZERO_STRUCT(r_u);
-
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if(!spoolss_io_q_enumprintprocessors("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_enumprintprocessors: unable to unmarshall SPOOL_Q_ENUMPRINTPROCESSORS.\n"));
- return False;
- }
-
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-
- r_u.status = _spoolss_enumprintprocessors(&q_u.name, &q_u.environment, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed, &r_u.returned);
-
- if(!spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_enumprintprocessors: unable to marshall SPOOL_R_ENUMPRINTPROCESSORS.\n"));
- new_spoolss_free_buffer(q_u.buffer);
- return False;
- }
-
- new_spoolss_free_buffer(q_u.buffer);
+ BOOL ret;
- return True;
-}
-
-/****************************************************************************
-****************************************************************************/
-static BOOL api_spoolss_enumprintprocdatatypes(uint16 vuid, prs_struct *data, prs_struct *rdata)
-{
- SPOOL_Q_ENUMPRINTPROCDATATYPES q_u;
- SPOOL_R_ENUMPRINTPROCDATATYPES r_u;
-
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if(!spoolss_io_q_enumprintprocdatatypes("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_enumprintprocdatatypes: unable to unmarshall SPOOL_Q_ENUMPRINTPROCDATATYPES.\n"));
- return False;
- }
-
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-
- r_u.status = _spoolss_enumprintprocdatatypes(&q_u.name, &q_u.processor, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed, &r_u.returned);
-
- if(!spoolss_io_r_enumprintprocdatatypes("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_enumprintprocdatatypes: unable to marshall SPOOL_R_ENUMPRINTPROCDATATYPES.\n"));
- new_spoolss_free_buffer(q_u.buffer);
- return False;
- }
-
- new_spoolss_free_buffer(q_u.buffer);
-
- return True;
+ if (!spoolss_io_q_enumprintprocessors("", &q_u, data, 0))
+ {
+ return False;
+ }
+
+ r_u.offered = q_u.buf_size;
+ r_u.level = q_u.level;
+ r_u.status = _spoolss_enumprintprocessors(&q_u.name,
+ &q_u.environment,
+ q_u.level,
+ &r_u.info_1,
+ &r_u.offered,
+ &r_u.numofprintprocessors);
+ spoolss_io_free_buffer(&q_u.buffer);
+ ret = spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0);
+ safe_free(r_u.info_1);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_enumprintmonitors(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_enumprintmonitors(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_ENUMPRINTMONITORS q_u;
SPOOL_R_ENUMPRINTMONITORS r_u;
+ BOOL ret;
+
ZERO_STRUCT(q_u);
ZERO_STRUCT(r_u);
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if (!spoolss_io_q_enumprintmonitors("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_enumprintmonitors: unable to unmarshall SPOOL_Q_ENUMPRINTMONITORS.\n"));
- return False;
- }
-
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
-
- r_u.status = _spoolss_enumprintmonitors(&q_u.name, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed, &r_u.returned);
-
- if (!spoolss_io_r_enumprintmonitors("", &r_u, rdata, 0)) {
- DEBUG(0,("spoolss_io_r_enumprintmonitors: unable to marshall SPOOL_R_ENUMPRINTMONITORS.\n"));
- new_spoolss_free_buffer(q_u.buffer);
- return False;
- }
-
- new_spoolss_free_buffer(q_u.buffer);
-
- return True;
+ if (!spoolss_io_q_enumprintmonitors("", &q_u, data, 0))
+ {
+ return False;
+ }
+
+ r_u.offered = q_u.buf_size;
+ r_u.level = q_u.level;
+ r_u.status = _spoolss_enumprintmonitors(&q_u.name,
+ q_u.level,
+ &r_u.info_1,
+ &r_u.offered,
+ &r_u.numofprintmonitors);
+ spoolss_io_free_buffer(&q_u.buffer);
+ ret = spoolss_io_r_enumprintmonitors("", &r_u, rdata, 0);
+ safe_free(r_u.info_1);
+ return ret;
}
/****************************************************************************
****************************************************************************/
-static BOOL api_spoolss_getjob(uint16 vuid, prs_struct *data, prs_struct *rdata)
+static BOOL api_spoolss_getjob(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata)
{
SPOOL_Q_GETJOB q_u;
SPOOL_R_GETJOB r_u;
-
- new_spoolss_allocate_buffer(&q_u.buffer);
-
- if(!spoolss_io_q_getjob("", &q_u, data, 0)) {
- DEBUG(0,("spoolss_io_q_getjob: unable to unmarshall SPOOL_Q_GETJOB.\n"));
- return False;
- }
- /* that's an [in out] buffer */
- new_spoolss_move_buffer(q_u.buffer, &r_u.buffer);
+ BOOL ret;
- r_u.status = _spoolss_getjob(&q_u.handle, q_u.jobid, q_u.level,
- r_u.buffer, q_u.offered,
- &r_u.needed);
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
- if(!spoolss_io_r_getjob("",&r_u,rdata,0)) {
- DEBUG(0,("spoolss_io_r_getjob: unable to marshall SPOOL_R_GETJOB.\n"));
- new_spoolss_free_buffer(q_u.buffer);
+ if (!spoolss_io_q_getjob("", &q_u, data, 0))
+ {
return False;
}
-
- new_spoolss_free_buffer(q_u.buffer);
- return True;
+
+
+ r_u.offered = q_u.buf_size;
+ r_u.level = q_u.level;
+ r_u.status = _spoolss_getjob(&q_u.handle,
+ q_u.jobid,
+ q_u.level,
+ &r_u.ctr,
+ &r_u.offered);
+ spoolss_io_free_buffer(&(q_u.buffer));
+ ret = spoolss_io_r_getjob("",&r_u,rdata,0);
+ free_spoolss_r_getjob(&r_u);
+ return ret;
}
/*******************************************************************
\pipe\spoolss commands
********************************************************************/
-struct api_struct api_spoolss_cmds[] =
+static const struct api_struct api_spoolss_cmds[] =
{
{"SPOOLSS_OPENPRINTEREX", SPOOLSS_OPENPRINTEREX, api_spoolss_open_printer_ex },
{"SPOOLSS_GETPRINTERDATA", SPOOLSS_GETPRINTERDATA, api_spoolss_getprinterdata },
@@ -1104,15 +1024,14 @@ struct api_struct api_spoolss_cmds[] =
{"SPOOLSS_ENUMPRINTPROCESSORS", SPOOLSS_ENUMPRINTPROCESSORS, api_spoolss_enumprintprocessors },
{"SPOOLSS_ENUMMONITORS", SPOOLSS_ENUMMONITORS, api_spoolss_enumprintmonitors },
{"SPOOLSS_GETJOB", SPOOLSS_GETJOB, api_spoolss_getjob },
- {"SPOOLSS_ENUMPRINTPROCDATATYPES", SPOOLSS_ENUMPRINTPROCDATATYPES, api_spoolss_enumprintprocdatatypes },
{ NULL, 0, NULL }
};
/*******************************************************************
receives a spoolss pipe and responds.
********************************************************************/
-BOOL api_spoolss_rpc(pipes_struct *p, prs_struct *data)
+BOOL api_spoolss_rpc(rpcsrv_struct *p)
{
- return api_rpcTNP(p, "api_spoolss_rpc", api_spoolss_cmds, data);
+ return api_rpcTNP(p, "api_spoolss_rpc", api_spoolss_cmds);
}
diff --git a/source/rpc_server/srv_srvsvc.c b/source/rpc_server/srv_srvsvc.c
index f42b94832b0..b87d2cbf9e7 100644
--- a/source/rpc_server/srv_srvsvc.c
+++ b/source/rpc_server/srv_srvsvc.c
@@ -24,1093 +24,274 @@
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
extern pstring global_myname;
/*******************************************************************
- Fill in a share info level 1 structure.
- ********************************************************************/
-
-static void init_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, int snum)
-{
- int len_net_name;
- pstring net_name;
- pstring remark;
- uint32 type;
-
- pstrcpy(net_name, lp_servicename(snum));
- pstrcpy(remark, lp_comment(snum));
- pstring_sub(remark,"%S",lp_servicename(snum));
- len_net_name = strlen(net_name);
-
- /* work out the share type */
- type = STYPE_DISKTREE;
-
- if (lp_print_ok(snum))
- type = STYPE_PRINTQ;
- if (strequal("IPC$", net_name))
- type = STYPE_IPC;
- if (net_name[len_net_name] == '$')
- type |= STYPE_HIDDEN;
-
- init_srv_share_info1(&sh1->info_1, net_name, type, remark);
- init_srv_share_info1_str(&sh1->info_1_str, net_name, remark);
-}
-
-/*******************************************************************
- Fill in a share info level 2 structure.
- ********************************************************************/
-
-static void init_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, int snum)
-{
- int len_net_name;
- pstring net_name;
- pstring remark;
- pstring path;
- pstring passwd;
- uint32 type;
-
- pstrcpy(net_name, lp_servicename(snum));
- pstrcpy(remark, lp_comment(snum));
- pstring_sub(remark,"%S",lp_servicename(snum));
- pstrcpy(path, lp_pathname(snum));
- pstrcpy(passwd, "");
- len_net_name = strlen(net_name);
-
- /* work out the share type */
- type = STYPE_DISKTREE;
-
- if (lp_print_ok(snum))
- type = STYPE_PRINTQ;
- if (strequal("IPC$", net_name))
- type = STYPE_IPC;
- if (net_name[len_net_name] == '$')
- type |= STYPE_HIDDEN;
-
- init_srv_share_info2(&sh2->info_2, net_name, type, remark, 0, 0xffffffff, 1, path, passwd);
- init_srv_share_info2_str(&sh2->info_2_str, net_name, remark, path, passwd);
-}
-
-/*******************************************************************
- Fill in a share info structure.
- ********************************************************************/
-
-static BOOL init_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr,
- uint32 info_level, uint32 *resume_hnd, uint32 *total_entries)
+********************************************************************/
+static BOOL api_srv_net_srv_get_info( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
{
- int num_entries = 0;
- int num_services = lp_numservices();
- int snum;
-
- DEBUG(5,("init_srv_share_info_ctr\n"));
-
- ZERO_STRUCTPN(ctr);
-
- ctr->info_level = ctr->switch_value = info_level;
- *resume_hnd = 0;
-
- /* Count the number of entries. */
- for (snum = 0; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum))
- num_entries++;
- }
-
- *total_entries = num_entries;
- ctr->num_entries2 = ctr->num_entries = num_entries;
- ctr->ptr_share_info = ctr->ptr_entries = 1;
-
- if (!num_entries)
- return True;
-
- switch (info_level) {
- case 1:
- {
- SRV_SHARE_INFO_1 *info1;
- int i = 0;
-
- info1 = malloc(num_entries * sizeof(SRV_SHARE_INFO_1));
-
- for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum)) {
- init_srv_share_info_1(&info1[i++], snum);
- }
- }
+ SRV_Q_NET_SRV_GET_INFO q_n;
+ SRV_R_NET_SRV_GET_INFO r_n;
+ SRV_INFO_CTR ctr;
+ uint32 status;
- ctr->share.info1 = info1;
- break;
- }
+ ZERO_STRUCT(q_n);
+ ZERO_STRUCT(r_n);
- case 2:
+ /* grab the net server get info */
+ if (!srv_io_q_net_srv_get_info("", &q_n, data, 0))
{
- SRV_SHARE_INFO_2 *info2;
- int i = 0;
-
- info2 = malloc(num_entries * sizeof(SRV_SHARE_INFO_2));
-
- for (snum = *resume_hnd; snum < num_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum)) {
- init_srv_share_info_2(&info2[i++], snum);
- }
- }
-
- ctr->share.info2 = info2;
- break;
- }
-
- default:
- DEBUG(5,("init_srv_share_info_ctr: unsupported switch value %d\n", info_level));
return False;
}
- return True;
-}
-
-/*******************************************************************
- Inits a SRV_R_NET_SHARE_ENUM structure.
-********************************************************************/
-static void init_srv_r_net_share_enum(SRV_R_NET_SHARE_ENUM *r_n,
- uint32 info_level, uint32 resume_hnd)
-{
- DEBUG(5,("init_srv_r_net_share_enum: %d\n", __LINE__));
+ status = _srv_net_srv_get_info( &q_n.uni_srv_name, q_n.switch_value,
+ &ctr );
- if (init_srv_share_info_ctr(&r_n->ctr, info_level,
- &resume_hnd, &r_n->total_entries)) {
- r_n->status = 0x0;
- } else {
- r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- }
+ /* set up the net server get info structure */
+ make_srv_r_net_srv_get_info(&r_n, q_n.switch_value, &ctr, status);
- init_enum_hnd(&r_n->enum_hnd, resume_hnd);
+ /* store the response in the SMB stream */
+ return srv_io_r_net_srv_get_info("", &r_n, rdata, 0);
}
/*******************************************************************
- Net share enum.
********************************************************************/
-
-static BOOL srv_reply_net_share_enum(SRV_Q_NET_SHARE_ENUM *q_n,
- prs_struct *rdata)
+static BOOL api_srv_net_file_enum( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
{
- SRV_R_NET_SHARE_ENUM r_n;
+ SRV_Q_NET_FILE_ENUM q_n;
+ SRV_R_NET_FILE_ENUM r_n;
+ SRV_FILE_INFO_CTR ctr;
BOOL ret;
- DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
-
- /* Create the list of shares for the response. */
- init_srv_r_net_share_enum(&r_n,
- q_n->ctr.info_level,
- get_enum_hnd(&q_n->enum_hnd));
-
- /* store the response in the SMB stream */
- ret = srv_io_r_net_share_enum("", &r_n, rdata, 0);
-
- /* Free the memory used by the response. */
- free_srv_r_net_share_enum(&r_n);
+ ZERO_STRUCT(q_n);
+ ZERO_STRUCT(r_n);
+ ZERO_STRUCT(ctr);
- DEBUG(5,("srv_net_share_enum: %d\n", __LINE__));
-
- return ret;
-}
-
-/*******************************************************************
- Inits a SRV_R_NET_SHARE_GET_INFO structure.
-********************************************************************/
+ q_n.ctr = &ctr;
+ r_n.ctr = &ctr;
-static void init_srv_r_net_share_get_info(SRV_R_NET_SHARE_GET_INFO *r_n,
- char *share_name, uint32 info_level)
-{
- uint32 status = 0x0;
- int snum;
-
- DEBUG(5,("init_srv_r_net_share_get_info: %d\n", __LINE__));
-
- r_n->switch_value = info_level;
-
- snum = find_service(share_name);
-
- if (snum >= 0) {
- switch (info_level) {
- case 1:
- init_srv_share_info_1(&r_n->share.info1, snum);
- break;
- case 2:
- init_srv_share_info_2(&r_n->share.info2, snum);
- break;
- default:
- DEBUG(5,("init_srv_net_share_get_info: unsupported switch value %d\n", info_level));
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
- } else {
- status = 0xC0000000 | NT_STATUS_BAD_NETWORK_NAME;
+ /* grab the net server get enum */
+ if (!srv_io_q_net_file_enum("", &q_n, data, 0))
+ {
+ return False;
}
- r_n->ptr_share_ctr = (status == 0x0) ? 1 : 0;
- r_n->status = status;
-}
+ r_n.file_level = q_n.file_level;
-/*******************************************************************
- Net share get info.
-********************************************************************/
+ r_n.status = _srv_net_file_enum(&q_n.uni_srv_name,
+ ctr.switch_value, &ctr,
+ q_n.preferred_len, &q_n.enum_hnd,
+ &(r_n.total_entries),
+ q_n.file_level);
-static BOOL srv_reply_net_share_get_info(SRV_Q_NET_SHARE_GET_INFO *q_n,
- prs_struct *rdata)
-{
- SRV_R_NET_SHARE_GET_INFO r_n;
- char *share_name;
- BOOL ret;
-
- DEBUG(5,("srv_net_share_get_info: %d\n", __LINE__));
-
- /* Create the list of shares for the response. */
- share_name = dos_unistr2_to_str(&q_n->uni_share_name);
- init_srv_r_net_share_get_info(&r_n, share_name, q_n->info_level);
+ memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
/* store the response in the SMB stream */
- ret = srv_io_r_net_share_get_info("", &r_n, rdata, 0);
-
- /* Free the memory used by the response. */
- free_srv_r_net_share_get_info(&r_n);
+ ret = srv_io_r_net_file_enum("", &r_n, rdata, 0);
- DEBUG(5,("srv_net_share_get_info: %d\n", __LINE__));
+ srv_free_srv_file_ctr(&ctr);
return ret;
}
/*******************************************************************
- fill in a sess info level 1 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
-
- ********************************************************************/
-static void init_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0,
- char *name)
-{
- init_srv_sess_info0 (se0 , name);
- init_srv_sess_info0_str(str0, name);
-}
-
-/*******************************************************************
- fill in a sess info level 0 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
-
- ********************************************************************/
-static void init_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
-{
- uint32 num_entries = 0;
- (*stot) = 1;
-
- if (ss0 == NULL)
- {
- (*snum) = 0;
- return;
- }
-
- DEBUG(5,("init_srv_sess_0_ss0\n"));
-
- if (snum)
- {
- for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
- {
- init_srv_sess_0_info(&(ss0->info_0 [num_entries]),
- &(ss0->info_0_str[num_entries]), "MACHINE");
-
- /* move on to creating next session */
- /* move on to creating next sess */
- num_entries++;
- }
-
- ss0->num_entries_read = num_entries;
- ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
- ss0->num_entries_read2 = num_entries;
-
- if ((*snum) >= (*stot))
- {
- (*snum) = 0;
- }
- }
- else
- {
- ss0->num_entries_read = 0;
- ss0->ptr_sess_info = 0;
- ss0->num_entries_read2 = 0;
- }
-}
-
-/*******************************************************************
- fill in a sess info level 1 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
-
- ********************************************************************/
-static void init_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
- char *name, char *user,
- uint32 num_opens,
- uint32 open_time, uint32 idle_time,
- uint32 usr_flgs)
-{
- init_srv_sess_info1 (se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
- init_srv_sess_info1_str(str1, name, user);
-}
-
-/*******************************************************************
- fill in a sess info level 1 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
-
- ********************************************************************/
-static void init_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
-{
- uint32 num_entries = 0;
- (*stot) = 1;
-
- if (ss1 == NULL)
- {
- (*snum) = 0;
- return;
- }
-
- DEBUG(5,("init_srv_sess_1_ss1\n"));
-
- if (snum)
- {
- for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
- {
- init_srv_sess_1_info(&(ss1->info_1 [num_entries]),
- &(ss1->info_1_str[num_entries]),
- "MACHINE", "dummy_user", 1, 10, 5, 0);
-
- /* move on to creating next session */
- /* move on to creating next sess */
- num_entries++;
- }
-
- ss1->num_entries_read = num_entries;
- ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
- ss1->num_entries_read2 = num_entries;
-
- if ((*snum) >= (*stot))
- {
- (*snum) = 0;
- }
- }
- else
- {
- ss1->num_entries_read = 0;
- ss1->ptr_sess_info = 0;
- ss1->num_entries_read2 = 0;
-
- (*stot) = 0;
- }
-}
-
-/*******************************************************************
- makes a SRV_R_NET_SESS_ENUM structure.
********************************************************************/
-static uint32 init_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
- int switch_value, uint32 *resume_hnd, uint32 *total_entries)
-{
- uint32 status = 0x0;
- DEBUG(5,("init_srv_sess_info_ctr: %d\n", __LINE__));
-
- ctr->switch_value = switch_value;
-
- switch (switch_value)
- {
- case 0:
- {
- init_srv_sess_info_0(&(ctr->sess.info0), resume_hnd, total_entries);
- ctr->ptr_sess_ctr = 1;
- break;
- }
- case 1:
- {
- init_srv_sess_info_1(&(ctr->sess.info1), resume_hnd, total_entries);
- ctr->ptr_sess_ctr = 1;
- break;
- }
- default:
- {
- DEBUG(5,("init_srv_sess_info_ctr: unsupported switch value %d\n",
- switch_value));
- (*resume_hnd) = 0;
- (*total_entries) = 0;
- ctr->ptr_sess_ctr = 0;
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
- }
-
- return status;
-}
-
-/*******************************************************************
- makes a SRV_R_NET_SESS_ENUM structure.
-********************************************************************/
-static void init_srv_r_net_sess_enum(SRV_R_NET_SESS_ENUM *r_n,
- uint32 resume_hnd, int sess_level, int switch_value)
+static BOOL api_srv_net_conn_enum( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
{
- DEBUG(5,("init_srv_r_net_sess_enum: %d\n", __LINE__));
-
- r_n->sess_level = sess_level;
- if (sess_level == -1)
- {
- r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- }
- else
- {
- r_n->status = init_srv_sess_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
- }
- if (r_n->status != 0x0)
- {
- resume_hnd = 0;
- }
- init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
-}
+ SRV_Q_NET_CONN_ENUM q_n;
+ SRV_R_NET_CONN_ENUM r_n;
+ SRV_CONN_INFO_CTR ctr;
-/*******************************************************************
-net sess enum
-********************************************************************/
-static void srv_reply_net_sess_enum(SRV_Q_NET_SESS_ENUM *q_n,
- prs_struct *rdata)
-{
- SRV_R_NET_SESS_ENUM r_n;
- SRV_SESS_INFO_CTR ctr;
+ ZERO_STRUCT(q_n);
+ ZERO_STRUCT(r_n);
+ q_n.ctr = &ctr;
r_n.ctr = &ctr;
- DEBUG(5,("srv_net_sess_enum: %d\n", __LINE__));
+ r_n.conn_level = q_n.conn_level;
- /* set up the */
- init_srv_r_net_sess_enum(&r_n,
- get_enum_hnd(&q_n->enum_hnd),
- q_n->sess_level,
- q_n->ctr->switch_value);
-
- /* store the response in the SMB stream */
- srv_io_r_net_sess_enum("", &r_n, rdata, 0);
-
- DEBUG(5,("srv_net_sess_enum: %d\n", __LINE__));
-}
-
-/*******************************************************************
- fill in a conn info level 0 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
-
- ********************************************************************/
-static void init_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
-{
- uint32 num_entries = 0;
- (*stot) = 1;
-
- if (ss0 == NULL)
- {
- (*snum) = 0;
- return;
- }
-
- DEBUG(5,("init_srv_conn_0_ss0\n"));
-
- if (snum)
- {
- for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
- {
- init_srv_conn_info0(&(ss0->info_0 [num_entries]), (*stot));
-
- /* move on to creating next connection */
- /* move on to creating next conn */
- num_entries++;
- }
-
- ss0->num_entries_read = num_entries;
- ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
- ss0->num_entries_read2 = num_entries;
-
-
-
- if ((*snum) >= (*stot))
- {
- (*snum) = 0;
- }
- }
- else
- {
- ss0->num_entries_read = 0;
- ss0->ptr_conn_info = 0;
- ss0->num_entries_read2 = 0;
-
- (*stot) = 0;
- }
-}
-
-/*******************************************************************
- fill in a conn info level 1 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
-
- ********************************************************************/
-static void init_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
- uint32 id, uint32 type,
- uint32 num_opens, uint32 num_users, uint32 open_time,
- char *usr_name, char *net_name)
-{
- init_srv_conn_info1 (se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
- init_srv_conn_info1_str(str1, usr_name, net_name);
-}
-
-/*******************************************************************
- fill in a conn info level 1 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
-
- ********************************************************************/
-static void init_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
-{
- uint32 num_entries = 0;
- (*stot) = 1;
-
- if (ss1 == NULL)
- {
- (*snum) = 0;
- return;
- }
-
- DEBUG(5,("init_srv_conn_1_ss1\n"));
-
- if (snum)
- {
- for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
- {
- init_srv_conn_1_info(&(ss1->info_1 [num_entries]),
- &(ss1->info_1_str[num_entries]),
- (*stot), 0x3, 1, 1, 3,"dummy_user", "IPC$");
-
- /* move on to creating next connection */
- /* move on to creating next conn */
- num_entries++;
- }
-
- ss1->num_entries_read = num_entries;
- ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
- ss1->num_entries_read2 = num_entries;
-
-
- if ((*snum) >= (*stot))
- {
- (*snum) = 0;
- }
- }
- else
+ /* grab the net server get enum */
+ if (!srv_io_q_net_conn_enum("", &q_n, data, 0))
{
- ss1->num_entries_read = 0;
- ss1->ptr_conn_info = 0;
- ss1->num_entries_read2 = 0;
-
- (*stot) = 0;
+ return False;
}
-}
-/*******************************************************************
- makes a SRV_R_NET_CONN_ENUM structure.
-********************************************************************/
-static uint32 init_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
- int switch_value, uint32 *resume_hnd, uint32 *total_entries)
-{
- uint32 status = 0x0;
- DEBUG(5,("init_srv_conn_info_ctr: %d\n", __LINE__));
- ctr->switch_value = switch_value;
+ r_n.status = _srv_net_conn_enum( &q_n.uni_srv_name,
+ ctr.switch_value, &ctr,
+ q_n.preferred_len, &q_n.enum_hnd,
+ &(r_n.total_entries),
+ q_n.conn_level );
- switch (switch_value)
- {
- case 0:
- {
- init_srv_conn_info_0(&(ctr->conn.info0), resume_hnd, total_entries);
- ctr->ptr_conn_ctr = 1;
- break;
- }
- case 1:
- {
- init_srv_conn_info_1(&(ctr->conn.info1), resume_hnd, total_entries);
- ctr->ptr_conn_ctr = 1;
- break;
- }
- default:
- {
- DEBUG(5,("init_srv_conn_info_ctr: unsupported switch value %d\n",
- switch_value));
- (*resume_hnd = 0);
- (*total_entries) = 0;
- ctr->ptr_conn_ctr = 0;
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
- }
+ memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
- return status;
+ /* store the response in the SMB stream */
+ return srv_io_r_net_conn_enum("", &r_n, rdata, 0);
}
/*******************************************************************
- makes a SRV_R_NET_CONN_ENUM structure.
********************************************************************/
-static void init_srv_r_net_conn_enum(SRV_R_NET_CONN_ENUM *r_n,
- uint32 resume_hnd, int conn_level, int switch_value)
+static BOOL api_srv_net_sess_enum( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
{
- DEBUG(5,("init_srv_r_net_conn_enum: %d\n", __LINE__));
+ SRV_Q_NET_SESS_ENUM q_n;
+ SRV_R_NET_SESS_ENUM r_n;
+ SRV_SESS_INFO_CTR ctr;
- r_n->conn_level = conn_level;
- if (conn_level == -1)
- {
- r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- }
- else
- {
- r_n->status = init_srv_conn_info_ctr(r_n->ctr, switch_value, &resume_hnd, &r_n->total_entries);
- }
- if (r_n->status != 0x0)
- {
- resume_hnd = 0;
- }
- init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
-}
-
-/*******************************************************************
-net conn enum
-********************************************************************/
-static void srv_reply_net_conn_enum(SRV_Q_NET_CONN_ENUM *q_n,
- prs_struct *rdata)
-{
- SRV_R_NET_CONN_ENUM r_n;
- SRV_CONN_INFO_CTR ctr;
+ ZERO_STRUCT(q_n);
+ ZERO_STRUCT(r_n);
+ q_n.ctr = &ctr;
r_n.ctr = &ctr;
- DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
-
- /* set up the */
- init_srv_r_net_conn_enum(&r_n,
- get_enum_hnd(&q_n->enum_hnd),
- q_n->conn_level,
- q_n->ctr->switch_value);
-
- /* store the response in the SMB stream */
- srv_io_r_net_conn_enum("", &r_n, rdata, 0);
-
- DEBUG(5,("srv_net_conn_enum: %d\n", __LINE__));
-}
-
-/*******************************************************************
- fill in a file info level 3 structure.
- ********************************************************************/
-static void init_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3,
- uint32 fnum, uint32 perms, uint32 num_locks,
- char *path_name, char *user_name)
-{
- init_srv_file_info3 (fl3 , fnum, perms, num_locks, path_name, user_name);
- init_srv_file_info3_str(str3, path_name, user_name);
-}
-
-/*******************************************************************
- fill in a file info level 3 structure.
-
- this function breaks the rule that i'd like to be in place, namely
- it doesn't receive its data as arguments: it has to call lp_xxxx()
- functions itself. yuck.
-
- ********************************************************************/
-static void init_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
-{
- uint32 num_entries = 0;
- (*ftot) = 1;
-
- if (fl3 == NULL)
+ /* grab the net server get enum */
+ if (!srv_io_q_net_sess_enum("", &q_n, data, 0))
{
- (*fnum) = 0;
- return;
+ return False;
}
- DEBUG(5,("init_srv_file_3_fl3\n"));
+ r_n.sess_level = q_n.sess_level;
- for (; (*fnum) < (*ftot) && num_entries < MAX_FILE_ENTRIES; (*fnum)++)
- {
- init_srv_file_3_info(&(fl3->info_3 [num_entries]),
- &(fl3->info_3_str[num_entries]),
- (*fnum), 0x35, 0, "\\PIPE\\samr", "dummy user");
+ r_n.status = _srv_net_sess_enum( &q_n.uni_srv_name,
+ ctr.switch_value, &ctr,
+ q_n.preferred_len, &q_n.enum_hnd,
+ &(r_n.total_entries),
+ q_n.sess_level );
- /* move on to creating next file */
- num_entries++;
- }
+ memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
- fl3->num_entries_read = num_entries;
- fl3->ptr_file_info = num_entries > 0 ? 1 : 0;
- fl3->num_entries_read2 = num_entries;
-
- if ((*fnum) >= (*ftot))
- {
- (*fnum) = 0;
- }
+ /* store the response in the SMB stream */
+ return srv_io_r_net_sess_enum("", &r_n, rdata, 0);
}
/*******************************************************************
- makes a SRV_R_NET_FILE_ENUM structure.
********************************************************************/
-static uint32 init_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
- int switch_value, uint32 *resume_hnd, uint32 *total_entries)
+static BOOL api_srv_net_share_enum(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
{
- uint32 status = 0x0;
- DEBUG(5,("init_srv_file_info_ctr: %d\n", __LINE__));
-
- ctr->switch_value = switch_value;
+ SRV_Q_NET_SHARE_ENUM q_n;
+ SRV_R_NET_SHARE_ENUM r_n;
+ SRV_SHARE_INFO_CTR ctr;
- switch (switch_value)
- {
- case 3:
- {
- init_srv_file_info_3(&(ctr->file.info3), resume_hnd, total_entries);
- ctr->ptr_file_ctr = 1;
- break;
- }
- default:
- {
- DEBUG(5,("init_srv_file_info_ctr: unsupported switch value %d\n",
- switch_value));
- (*resume_hnd = 0);
- (*total_entries) = 0;
- ctr->ptr_file_ctr = 0;
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
- }
+ BOOL ret;
- return status;
-}
+ ZERO_STRUCT(q_n);
+ ZERO_STRUCT(r_n);
+ ZERO_STRUCT(ctr);
-/*******************************************************************
- makes a SRV_R_NET_FILE_ENUM structure.
-********************************************************************/
-static void init_srv_r_net_file_enum(SRV_R_NET_FILE_ENUM *r_n,
- uint32 resume_hnd, int file_level, int switch_value)
-{
- DEBUG(5,("init_srv_r_net_file_enum: %d\n", __LINE__));
+ q_n.ctr = &ctr;
+ r_n.ctr = &ctr;
- r_n->file_level = file_level;
- if (file_level == 0)
- {
- r_n->status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- }
- else
- {
- r_n->status = init_srv_file_info_ctr(r_n->ctr, switch_value, &resume_hnd, &(r_n->total_entries));
- }
- if (r_n->status != 0x0)
+ /* grab the net server get enum */
+ if (!srv_io_q_net_share_enum("", &q_n, data, 0))
{
- resume_hnd = 0;
+ return False;
}
- init_enum_hnd(&(r_n->enum_hnd), resume_hnd);
-}
-/*******************************************************************
-net file enum
-********************************************************************/
-static void srv_reply_net_file_enum(SRV_Q_NET_FILE_ENUM *q_n,
- prs_struct *rdata)
-{
- SRV_R_NET_FILE_ENUM r_n;
- SRV_FILE_INFO_CTR ctr;
-
- r_n.ctr = &ctr;
+ r_n.share_level = q_n.share_level;
- DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
+ r_n.status = _srv_net_share_enum( &q_n.uni_srv_name,
+ ctr.switch_value, &ctr,
+ q_n.preferred_len, &q_n.enum_hnd,
+ &(r_n.total_entries),
+ q_n.share_level );
- /* set up the */
- init_srv_r_net_file_enum(&r_n,
- get_enum_hnd(&q_n->enum_hnd),
- q_n->file_level,
- q_n->ctr->switch_value);
+ memcpy(&r_n.enum_hnd, &q_n.enum_hnd, sizeof(r_n.enum_hnd));
/* store the response in the SMB stream */
- srv_io_r_net_file_enum("", &r_n, rdata, 0);
-
- DEBUG(5,("srv_net_file_enum: %d\n", __LINE__));
+ ret = srv_io_r_net_share_enum("", &r_n, rdata, 0);
+ srv_free_srv_share_ctr(&ctr);
+ return ret;
}
/*******************************************************************
-net server get info
********************************************************************/
-
-static void srv_reply_net_srv_get_info(SRV_Q_NET_SRV_GET_INFO *q_n,
- prs_struct *rdata)
+static BOOL api_srv_net_share_get_info(rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
{
- SRV_R_NET_SRV_GET_INFO r_n;
- uint32 status = 0x0;
- SRV_INFO_CTR ctr;
-
+ SRV_Q_NET_SHARE_GET_INFO q_n;
+ SRV_R_NET_SHARE_GET_INFO r_n;
+ uint32 status;
+ BOOL ret;
- DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
+ ZERO_STRUCT(q_n);
+ ZERO_STRUCT(r_n);
- switch (q_n->switch_value)
+ /* grab the request */
+ if (!srv_io_q_net_share_get_info("", &q_n, data, 0))
{
- case 102:
- {
- init_srv_info_102(&ctr.srv.sv102,
- 500, global_myname,
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH),
- lp_major_announce_version(), lp_minor_announce_version(),
- lp_default_server_announce(),
- 0xffffffff, /* users */
- 0xf, /* disc */
- 0, /* hidden */
- 240, /* announce */
- 3000, /* announce delta */
- 100000, /* licenses */
- "c:\\"); /* user path */
- break;
- }
- case 101:
- {
- init_srv_info_101(&ctr.srv.sv101,
- 500, global_myname,
- lp_major_announce_version(), lp_minor_announce_version(),
- lp_default_server_announce(),
- string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
- break;
- }
- default:
- {
- status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
+ return False;
}
- /* set up the net server get info structure */
- init_srv_r_net_srv_get_info(&r_n, q_n->switch_value, &ctr, status);
-
- /* store the response in the SMB stream */
- srv_io_r_net_srv_get_info("", &r_n, rdata, 0);
-
- DEBUG(5,("srv_net_srv_get_info: %d\n", __LINE__));
-}
-
-/*******************************************************************
-********************************************************************/
-static BOOL api_srv_net_srv_get_info( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- SRV_Q_NET_SRV_GET_INFO q_n;
-
- /* grab the net server get info */
- srv_io_q_net_srv_get_info("", &q_n, data, 0);
-
- /* construct reply. always indicate success */
- srv_reply_net_srv_get_info(&q_n, rdata);
-
- return True;
-}
-
+ status = NT_STATUS_ACCESS_DENIED;
-/*******************************************************************
-********************************************************************/
-static BOOL api_srv_net_file_enum( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- SRV_Q_NET_FILE_ENUM q_n;
- SRV_FILE_INFO_CTR ctr;
-
- q_n.ctr = &ctr;
-
- /* grab the net file enum */
- srv_io_q_net_file_enum("", &q_n, data, 0);
-
- /* construct reply. always indicate success */
- srv_reply_net_file_enum(&q_n, rdata);
-
- return True;
-}
+ make_srv_r_net_share_get_info(&r_n, q_n.info_level, NULL, status);
+ ret = srv_io_r_net_share_get_info("", &r_n, rdata, 0);
-/*******************************************************************
-********************************************************************/
-static BOOL api_srv_net_conn_enum( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- SRV_Q_NET_CONN_ENUM q_n;
- SRV_CONN_INFO_CTR ctr;
-
- q_n.ctr = &ctr;
-
- /* grab the net server get enum */
- srv_io_q_net_conn_enum("", &q_n, data, 0);
-
- /* construct reply. always indicate success */
- srv_reply_net_conn_enum(&q_n, rdata);
-
- return True;
+ return ret;
}
-
/*******************************************************************
********************************************************************/
-static BOOL api_srv_net_sess_enum( uint16 vuid, prs_struct *data,
+static BOOL api_srv_net_remote_tod( rpcsrv_struct *p, prs_struct *data,
prs_struct *rdata )
{
- SRV_Q_NET_SESS_ENUM q_n;
- SRV_SESS_INFO_CTR ctr;
+ SRV_Q_NET_REMOTE_TOD q_n;
+ SRV_R_NET_REMOTE_TOD r_n;
+ TIME_OF_DAY_INFO tod;
+ uint32 status;
- q_n.ctr = &ctr;
+ ZERO_STRUCT(q_n);
+ ZERO_STRUCT(r_n);
/* grab the net server get enum */
- srv_io_q_net_sess_enum("", &q_n, data, 0);
-
- /* construct reply. always indicate success */
- srv_reply_net_sess_enum(&q_n, rdata);
-
- return True;
-}
-
-
-/*******************************************************************
- RPC to enumerate shares.
-********************************************************************/
-
-static BOOL api_srv_net_share_enum( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- SRV_Q_NET_SHARE_ENUM q_n;
- BOOL ret;
-
- /* Unmarshall the net server get enum. */
- if(!srv_io_q_net_share_enum("", &q_n, data, 0)) {
- DEBUG(0,("api_srv_net_share_enum: Failed to unmarshall SRV_Q_NET_SHARE_ENUM.\n"));
- return False;
- }
-
- ret = srv_reply_net_share_enum(&q_n, rdata);
-
- /* Free any data allocated in the unmarshalling. */
- free_srv_q_net_share_enum(&q_n);
-
- return ret;
-}
-
-/*******************************************************************
- RPC to return share information.
-********************************************************************/
-
-static BOOL api_srv_net_share_get_info( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- SRV_Q_NET_SHARE_GET_INFO q_n;
- BOOL ret;
-
- /* Unmarshall the net server get info. */
- if(!srv_io_q_net_share_get_info("", &q_n, data, 0)) {
- DEBUG(0,("api_srv_net_share_get_info: Failed to unmarshall SRV_Q_NET_SHARE_GET_INFO.\n"));
+ if (!srv_io_q_net_remote_tod("", &q_n, data, 0))
+ {
return False;
}
- ret = srv_reply_net_share_get_info(&q_n, rdata);
-
- /* Free any data allocated in the unmarshalling. */
- free_srv_q_net_share_get_info(&q_n);
- return ret;
-}
-
-/*******************************************************************
-time of day
-********************************************************************/
-static BOOL srv_reply_net_remote_tod(SRV_Q_NET_REMOTE_TOD *q_n,
- prs_struct *rdata)
-{
- SRV_R_NET_REMOTE_TOD r_n;
- TIME_OF_DAY_INFO tod;
- struct tm *t;
- time_t unixdate = time(NULL);
+ status = _srv_net_remote_tod( &q_n.uni_srv_name, &tod );
r_n.tod = &tod;
r_n.ptr_srv_tod = 0x1;
- r_n.status = 0x0;
-
- DEBUG(5,("srv_reply_net_remote_tod: %d\n", __LINE__));
-
- t = gmtime(&unixdate);
-
- /* set up the */
- init_time_of_day_info(&tod,
- unixdate,
- 0,
- t->tm_hour,
- t->tm_min,
- t->tm_sec,
- 0,
- TimeDiff(unixdate)/60,
- 10000,
- t->tm_mday,
- t->tm_mon + 1,
- 1900+t->tm_year,
- t->tm_wday);
-
- /* store the response in the SMB stream */
- srv_io_r_net_remote_tod("", &r_n, rdata, 0);
-
- DEBUG(5,("srv_reply_net_remote_tod: %d\n", __LINE__));
-
- return True;
-}
-/*******************************************************************
-********************************************************************/
-static BOOL api_srv_net_remote_tod( uint16 vuid, prs_struct *data,
- prs_struct *rdata )
-{
- SRV_Q_NET_REMOTE_TOD q_n;
+ r_n.status = status;
- /* grab the net server get enum */
- srv_io_q_net_remote_tod("", &q_n, data, 0);
-
- /* construct reply. always indicate success */
- srv_reply_net_remote_tod(&q_n, rdata);
-
- return True;
+ /* store the response in the SMB stream */
+ return srv_io_r_net_remote_tod("", &r_n, rdata, 0);
}
/*******************************************************************
\PIPE\srvsvc commands
********************************************************************/
-struct api_struct api_srv_cmds[] =
-{
- { "SRV_NETCONNENUM" , SRV_NETCONNENUM , api_srv_net_conn_enum },
- { "SRV_NETSESSENUM" , SRV_NETSESSENUM , api_srv_net_sess_enum },
- { "SRV_NETSHAREENUM" , SRV_NETSHAREENUM , api_srv_net_share_enum },
- { "SRV_NET_SHARE_GET_INFO", SRV_NET_SHARE_GET_INFO, api_srv_net_share_get_info },
- { "SRV_NETFILEENUM" , SRV_NETFILEENUM , api_srv_net_file_enum },
- { "SRV_NET_SRV_GET_INFO" , SRV_NET_SRV_GET_INFO , api_srv_net_srv_get_info },
- { "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod },
- { NULL , 0 , NULL }
+static const struct api_struct api_srv_cmds[] =
+{
+ { "SRV_NETCONNENUM" , SRV_NETCONNENUM , api_srv_net_conn_enum },
+ { "SRV_NETSESSENUM" , SRV_NETSESSENUM , api_srv_net_sess_enum },
+ { "SRV_NETSHAREENUM" , SRV_NETSHAREENUM , api_srv_net_share_enum },
+ { "SRV_NETSHAREENUM2" , SRV_NETSHAREENUM2 , api_srv_net_share_enum },
+ { "SRV_NETSHAREGETINFO" , SRV_NETSHAREGETINFO , api_srv_net_share_get_info},
+ { "SRV_NETFILEENUM" , SRV_NETFILEENUM , api_srv_net_file_enum },
+ { "SRV_NET_SRV_GET_INFO", SRV_NET_SRV_GET_INFO, api_srv_net_srv_get_info },
+ { "SRV_NET_REMOTE_TOD" , SRV_NET_REMOTE_TOD , api_srv_net_remote_tod },
+ { NULL , 0 , NULL }
};
/*******************************************************************
receives a srvsvc pipe and responds.
********************************************************************/
-BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data)
+BOOL api_srvsvc_rpc(rpcsrv_struct *p)
{
- return api_rpcTNP(p, "api_srvsvc_rpc", api_srv_cmds, data);
+ return api_rpcTNP(p, "api_srvsvc_rpc", api_srv_cmds);
}
+
diff --git a/source/rpc_server/srv_svcctl.c b/source/rpc_server/srv_svcctl.c
new file mode 100644
index 00000000000..17cf5ff86ee
--- /dev/null
+++ b/source/rpc_server/srv_svcctl.c
@@ -0,0 +1,252 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ api_svc_close
+ ********************************************************************/
+static BOOL api_svc_close( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ SVC_Q_CLOSE q_r;
+ SVC_R_CLOSE r_u;
+
+ ZERO_STRUCT(q_r);
+ ZERO_STRUCT(r_u);
+
+ if (!svc_io_q_close("", &q_r, data, 0))
+ {
+ return False;
+ }
+
+ memcpy(&r_u.pol, &q_r.pol, sizeof(POLICY_HND));
+ r_u.status = _svc_close(&r_u.pol);
+
+ /* store the response in the SMB stream */
+ return svc_io_r_close("", &r_u, rdata, 0);
+}
+
+/*******************************************************************
+ api_svc_open_service
+ ********************************************************************/
+static BOOL api_svc_open_service( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ SVC_Q_OPEN_SERVICE q_u;
+ SVC_R_OPEN_SERVICE r_u;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!svc_io_q_open_service("", &q_u, data, 0))
+ {
+ return False;
+ }
+
+ r_u.status = _svc_open_service(&q_u.scman_pol,
+ &q_u.uni_svc_name,
+ q_u.des_access,
+ &r_u.pol);
+
+ /* store the response in the SMB stream */
+ return svc_io_r_open_service("", &r_u, rdata, 0);
+}
+
+/*******************************************************************
+ api_svc_stop_service
+ ********************************************************************/
+static BOOL api_svc_stop_service( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ SVC_Q_STOP_SERVICE q_u;
+ SVC_R_STOP_SERVICE r_s;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_s);
+
+ if (!svc_io_q_stop_service("", &q_u, data, 0))
+ {
+ return False;
+ }
+
+ r_s.status = _svc_stop_service(&q_u.pol,
+ q_u.unknown,
+ &r_s.unknown0,
+ &r_s.unknown1,
+ &r_s.unknown2,
+ &r_s.unknown3,
+ &r_s.unknown4,
+ &r_s.unknown5,
+ &r_s.unknown6);
+
+ /* store the response in the SMB stream */
+ return svc_io_r_stop_service("", &r_s, rdata, 0);
+}
+
+/*******************************************************************
+ api_svc_start_service
+ ********************************************************************/
+static BOOL api_svc_start_service( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ SVC_Q_START_SERVICE q_u;
+ SVC_R_START_SERVICE r_s;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_s);
+
+ if (!svc_io_q_start_service("", &q_u, data, 0))
+ {
+ return False;
+ }
+
+ r_s.status = _svc_start_service(&q_u.pol,
+ q_u.argc,
+ q_u.argc2,
+ q_u.argv);
+
+ /* store the response in the SMB stream */
+ return svc_io_r_start_service("", &r_s, rdata, 0);
+}
+
+/*******************************************************************
+ api_svc_open_sc_man
+ ********************************************************************/
+static BOOL api_svc_open_sc_man( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ SVC_Q_OPEN_SC_MAN q_u;
+ SVC_R_OPEN_SC_MAN r_u;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!svc_io_q_open_sc_man("", &q_u, data, 0))
+ {
+ return False;
+ }
+
+ r_u.status = _svc_open_sc_man(&q_u.uni_srv_name,
+ &q_u.uni_db_name,
+ q_u.des_access,
+ &r_u.pol);
+
+ /* store the response in the SMB stream */
+ return svc_io_r_open_sc_man("", &r_u, rdata, 0);
+}
+
+/*******************************************************************
+ api_svc_enum_svcs_status
+ ********************************************************************/
+static BOOL api_svc_enum_svcs_status( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ SVC_Q_ENUM_SVCS_STATUS q_u;
+ SVC_R_ENUM_SVCS_STATUS r_u;
+ uint32 buf_size;
+ ENUM_SRVC_STATUS svcs[MAX_SERVICES];
+ uint32 more_buf_size;
+ uint32 num_svcs;
+ ENUM_HND resume_hnd;
+ uint32 status;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!svc_io_q_enum_svcs_status("", &q_u, data, 0))
+ {
+ return False;
+ }
+
+ buf_size = q_u.buf_size;
+ memcpy(&resume_hnd, &q_u.resume_hnd, sizeof(ENUM_HND));
+ status = _svc_enum_svcs_status(&q_u.pol,
+ q_u.service_type,
+ q_u.service_state,
+ &buf_size,
+ &resume_hnd,
+ svcs,
+ &more_buf_size,
+ &num_svcs);
+ make_svc_r_enum_svcs_status(&r_u, svcs, more_buf_size, num_svcs, &resume_hnd, status);
+
+ /* store the response in the SMB stream */
+ return svc_io_r_enum_svcs_status("", &r_u, rdata, 0);
+}
+
+/*******************************************************************
+ api_svc_query_disp_name
+ ********************************************************************/
+static BOOL api_svc_query_disp_name( rpcsrv_struct *p, prs_struct *data,
+ prs_struct *rdata )
+{
+ SVC_Q_QUERY_DISP_NAME q_u;
+ SVC_R_QUERY_DISP_NAME r_u;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
+
+ if (!svc_io_q_query_disp_name("", &q_u, data, 0))
+ {
+ return False;
+ }
+
+ r_u.status = _svc_query_disp_name(&q_u.scman_pol,
+ &q_u.uni_svc_name,
+ q_u.buf_size,
+ &r_u.uni_disp_name,
+ &r_u.buf_size);
+
+ /* store the response in the SMB stream */
+ return svc_io_r_query_disp_name("", &r_u, rdata, 0);
+}
+
+/*******************************************************************
+ array of \PIPE\svcctl operations
+ ********************************************************************/
+static const struct api_struct api_svc_cmds[] =
+{
+ { "SVC_CLOSE" , SVC_CLOSE , api_svc_close },
+ { "SVC_OPEN_SC_MAN" , SVC_OPEN_SC_MAN , api_svc_open_sc_man },
+ { "SVC_OPEN_SERVICE" , SVC_OPEN_SERVICE , api_svc_open_service },
+ { "SVC_ENUM_SVCS_STATUS", SVC_ENUM_SVCS_STATUS, api_svc_enum_svcs_status },
+ { "SVC_QUERY_DISP_NAME" , SVC_QUERY_DISP_NAME , api_svc_query_disp_name },
+ { "SVC_START_SERVICE" , SVC_START_SERVICE , api_svc_start_service },
+ { "SVC_STOP_SERVICE" , SVC_STOP_SERVICE , api_svc_stop_service },
+ { NULL , 0 , NULL }
+};
+
+/*******************************************************************
+ receives a svcctl pipe and responds.
+ ********************************************************************/
+BOOL api_svcctl_rpc(rpcsrv_struct *p)
+{
+ return api_rpcTNP(p, "api_svc_rpc", api_svc_cmds);
+}
+
diff --git a/source/rpc_server/srv_util.c b/source/rpc_server/srv_util.c
index 097ab92d76a..25dceb41a0d 100644
--- a/source/rpc_server/srv_util.c
+++ b/source/rpc_server/srv_util.c
@@ -22,325 +22,4 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* this module apparently provides an implementation of DCE/RPC over a
- * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC
- * documentation are available (in on-line form) from the X-Open group.
- *
- * this module should provide a level of abstraction between SMB
- * and DCE/RPC, while minimising the amount of mallocs, unnecessary
- * data copies, and network traffic.
- *
- * in this version, which takes a "let's learn what's going on and
- * get something running" approach, there is additional network
- * traffic generated, but the code should be easier to understand...
- *
- * ... if you read the docs. or stare at packets for weeks on end.
- *
- */
-
-#include "includes.h"
-#include "nterr.h"
-
-extern int DEBUGLEVEL;
-
-/*
- * A list of the rids of well known BUILTIN and Domain users
- * and groups.
- */
-
-rid_name builtin_alias_rids[] =
-{
- { BUILTIN_ALIAS_RID_ADMINS , "Administrators" },
- { BUILTIN_ALIAS_RID_USERS , "Users" },
- { BUILTIN_ALIAS_RID_GUESTS , "Guests" },
- { BUILTIN_ALIAS_RID_POWER_USERS , "Power Users" },
-
- { BUILTIN_ALIAS_RID_ACCOUNT_OPS , "Account Operators" },
- { BUILTIN_ALIAS_RID_SYSTEM_OPS , "System Operators" },
- { BUILTIN_ALIAS_RID_PRINT_OPS , "Print Operators" },
- { BUILTIN_ALIAS_RID_BACKUP_OPS , "Backup Operators" },
- { BUILTIN_ALIAS_RID_REPLICATOR , "Replicator" },
- { 0 , NULL }
-};
-
-/* array lookup of well-known Domain RID users. */
-rid_name domain_user_rids[] =
-{
- { DOMAIN_USER_RID_ADMIN , "Administrator" },
- { DOMAIN_USER_RID_GUEST , "Guest" },
- { 0 , NULL }
-};
-
-/* array lookup of well-known Domain RID groups. */
-rid_name domain_group_rids[] =
-{
- { DOMAIN_GROUP_RID_ADMINS , "Domain Admins" },
- { DOMAIN_GROUP_RID_USERS , "Domain Users" },
- { DOMAIN_GROUP_RID_GUESTS , "Domain Guests" },
- { 0 , NULL }
-};
-
-int make_dom_gids(char *gids_str, DOM_GID **ppgids)
-{
- char *ptr;
- pstring s2;
- int count;
- DOM_GID *gids;
-
- *ppgids = NULL;
-
- DEBUG(4,("make_dom_gids: %s\n", gids_str));
-
- if (gids_str == NULL || *gids_str == 0)
- return 0;
-
- for (count = 0, ptr = gids_str;
- next_token(&ptr, s2, NULL, sizeof(s2));
- count++)
- ;
-
- gids = (DOM_GID *)malloc( sizeof(DOM_GID) * count );
- if(!gids)
- {
- DEBUG(0,("make_dom_gids: malloc fail !\n"));
- return 0;
- }
-
- for (count = 0, ptr = gids_str;
- next_token(&ptr, s2, NULL, sizeof(s2)) &&
- count < LSA_MAX_GROUPS;
- count++)
- {
- /* the entries are of the form GID/ATTR, ATTR being optional.*/
- char *attr;
- uint32 rid = 0;
- int i;
-
- attr = strchr(s2,'/');
- if (attr)
- *attr++ = 0;
-
- if (!attr || !*attr)
- attr = "7"; /* default value for attribute is 7 */
-
- /* look up the RID string and see if we can turn it into a rid number */
- for (i = 0; builtin_alias_rids[i].name != NULL; i++)
- {
- if (strequal(builtin_alias_rids[i].name, s2))
- {
- rid = builtin_alias_rids[i].rid;
- break;
- }
- }
-
- if (rid == 0)
- rid = atoi(s2);
-
- if (rid == 0)
- {
- DEBUG(1,("make_dom_gids: unknown well-known alias RID %s/%s\n", s2, attr));
- count--;
- }
- else
- {
- gids[count].g_rid = rid;
- gids[count].attr = atoi(attr);
-
- DEBUG(5,("group id: %d attr: %d\n", gids[count].g_rid, gids[count].attr));
- }
- }
-
- *ppgids = gids;
- return count;
-}
-
-
-/*******************************************************************
- gets a domain user's groups
- ********************************************************************/
-void get_domain_user_groups(char *domain_groups, char *user)
-{
- pstring tmp;
-
- if (domain_groups == NULL || user == NULL) return;
-
- /* any additional groups this user is in. e.g power users */
- pstrcpy(domain_groups, lp_domain_groups());
-
- /* can only be a user or a guest. cannot be guest _and_ admin */
- if (user_in_list(user, lp_domain_guest_group()))
- {
- slprintf(tmp, sizeof(tmp) - 1, " %ld/7 ", DOMAIN_GROUP_RID_GUESTS);
- pstrcat(domain_groups, tmp);
-
- DEBUG(3,("domain guest group access %s granted\n", tmp));
- }
- else
- {
- slprintf(tmp, sizeof(tmp) -1, " %ld/7 ", DOMAIN_GROUP_RID_USERS);
- pstrcat(domain_groups, tmp);
-
- DEBUG(3,("domain group access %s granted\n", tmp));
-
- if (user_in_list(user, lp_domain_admin_group()))
- {
- slprintf(tmp, sizeof(tmp) - 1, " %ld/7 ", DOMAIN_GROUP_RID_ADMINS);
- pstrcat(domain_groups, tmp);
-
- DEBUG(3,("domain admin group access %s granted\n", tmp));
- }
- }
-}
-
-
-/*******************************************************************
- lookup_group_name
- ********************************************************************/
-uint32 lookup_group_name(uint32 rid, char *group_name, uint32 *type)
-{
- int i = 0;
- (*type) = SID_NAME_DOM_GRP;
-
- DEBUG(5,("lookup_group_name: rid: %d", rid));
-
- while (domain_group_rids[i].rid != rid && domain_group_rids[i].rid != 0)
- {
- i++;
- }
-
- if (domain_group_rids[i].rid != 0)
- {
- fstrcpy(group_name, domain_group_rids[i].name);
- DEBUG(5,(" = %s\n", group_name));
- return 0x0;
- }
-
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
-}
-
-/*******************************************************************
- lookup_alias_name
- ********************************************************************/
-uint32 lookup_alias_name(uint32 rid, char *alias_name, uint32 *type)
-{
- int i = 0;
- (*type) = SID_NAME_WKN_GRP;
-
- DEBUG(5,("lookup_alias_name: rid: %d", rid));
-
- while (builtin_alias_rids[i].rid != rid && builtin_alias_rids[i].rid != 0)
- {
- i++;
- }
-
- if (builtin_alias_rids[i].rid != 0)
- {
- fstrcpy(alias_name, builtin_alias_rids[i].name);
- DEBUG(5,(" = %s\n", alias_name));
- return 0x0;
- }
-
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
-}
-
-/*******************************************************************
- lookup_user_name
- ********************************************************************/
-uint32 lookup_user_name(uint32 rid, char *user_name, uint32 *type)
-{
- struct sam_disp_info *disp_info;
- int i = 0;
- (*type) = SID_NAME_USER;
-
- DEBUG(5,("lookup_user_name: rid: %d", rid));
-
- /* look up the well-known domain user rids first */
- while (domain_user_rids[i].rid != rid && domain_user_rids[i].rid != 0)
- {
- i++;
- }
-
- if (domain_user_rids[i].rid != 0)
- {
- fstrcpy(user_name, domain_user_rids[i].name);
- DEBUG(5,(" = %s\n", user_name));
- return 0x0;
- }
-
- /* ok, it's a user. find the user account */
- become_root(True);
- disp_info = getsamdisprid(rid);
- unbecome_root(True);
-
- if (disp_info != NULL)
- {
- fstrcpy(user_name, disp_info->smb_name);
- DEBUG(5,(" = %s\n", user_name));
- return 0x0;
- }
-
- DEBUG(5,(" none mapped\n"));
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
-}
-
-/*******************************************************************
- lookup_group_rid
- ********************************************************************/
-uint32 lookup_group_rid(char *group_name, uint32 *rid)
-{
- char *grp_name;
- int i = -1; /* start do loop at -1 */
-
- do /* find, if it exists, a group rid for the group name*/
- {
- i++;
- (*rid) = domain_group_rids[i].rid;
- grp_name = domain_group_rids[i].name;
-
- } while (grp_name != NULL && !strequal(grp_name, group_name));
-
- return (grp_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
-}
-
-/*******************************************************************
- lookup_alias_rid
- ********************************************************************/
-uint32 lookup_alias_rid(char *alias_name, uint32 *rid)
-{
- char *als_name;
- int i = -1; /* start do loop at -1 */
-
- do /* find, if it exists, a alias rid for the alias name*/
- {
- i++;
- (*rid) = builtin_alias_rids[i].rid;
- als_name = builtin_alias_rids[i].name;
-
- } while (als_name != NULL && !strequal(als_name, alias_name));
-
- return (als_name != NULL) ? 0 : 0xC0000000 | NT_STATUS_NONE_MAPPED;
-}
-
-/*******************************************************************
- lookup_user_rid
- ********************************************************************/
-uint32 lookup_user_rid(char *user_name, uint32 *rid)
-{
- struct sam_passwd *sam_pass;
- (*rid) = 0;
-
- /* find the user account */
- become_root(True);
- sam_pass = getsam21pwnam(user_name);
- unbecome_root(True);
-
- if (sam_pass != NULL)
- {
- (*rid) = sam_pass->user_rid;
- return 0x0;
- }
-
- return 0xC0000000 | NT_STATUS_NONE_MAPPED;
-}
+/* retired module */
diff --git a/source/rpc_server/srv_wkssvc.c b/source/rpc_server/srv_wkssvc.c
index 658cadc6257..c708e54f5f7 100644
--- a/source/rpc_server/srv_wkssvc.c
+++ b/source/rpc_server/srv_wkssvc.c
@@ -24,6 +24,7 @@
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
@@ -31,74 +32,38 @@ extern pstring global_myname;
/*******************************************************************
- create_wks_info_100
- ********************************************************************/
-static void create_wks_info_100(WKS_INFO_100 *inf)
-{
- pstring my_name;
- pstring domain;
-
- DEBUG(5,("create_wks_info_100: %d\n", __LINE__));
-
- pstrcpy (my_name, global_myname);
- strupper(my_name);
-
- pstrcpy (domain , lp_workgroup());
- strupper(domain);
-
- init_wks_info_100(inf,
- 0x000001f4, /* platform id info */
- lp_major_announce_version(),
- lp_minor_announce_version(),
- my_name, domain);
-}
-
-/*******************************************************************
- wks_reply_query_info
-
- only supports info level 100 at the moment.
-
- ********************************************************************/
-static void wks_reply_query_info(WKS_Q_QUERY_INFO *q_u,
- prs_struct *rdata,
- int status)
-{
- WKS_R_QUERY_INFO r_u;
- WKS_INFO_100 wks100;
-
- DEBUG(5,("wks_query_info: %d\n", __LINE__));
-
- create_wks_info_100(&wks100);
- init_wks_r_query_info(&r_u, q_u->switch_value, &wks100, status);
-
- /* store the response in the SMB stream */
- wks_io_r_query_info("", &r_u, rdata, 0);
-
- DEBUG(5,("wks_query_info: %d\n", __LINE__));
-}
-
-/*******************************************************************
api_wks_query_info
********************************************************************/
-static BOOL api_wks_query_info( uint16 vuid, prs_struct *data,
+static BOOL api_wks_query_info( rpcsrv_struct *p, prs_struct *data,
prs_struct *rdata )
{
WKS_Q_QUERY_INFO q_u;
+ WKS_R_QUERY_INFO r_u;
+ WKS_INFO_100 wks100;
+ uint32 status;
+
+ ZERO_STRUCT(q_u);
+ ZERO_STRUCT(r_u);
/* grab the net share enum */
- wks_io_q_query_info("", &q_u, data, 0);
+ if (!wks_io_q_query_info("", &q_u, data, 0))
+ {
+ return False;
+ }
+
- /* construct reply. always indicate success */
- wks_reply_query_info(&q_u, rdata, 0x0);
+ status = _wks_query_info(&q_u.uni_srv_name, q_u.switch_value, &wks100);
+ make_wks_r_query_info(&r_u, q_u.switch_value, &wks100, status);
- return True;
+ /* store the response in the SMB stream */
+ return wks_io_r_query_info("", &r_u, rdata, 0);
}
/*******************************************************************
\PIPE\wkssvc commands
********************************************************************/
-struct api_struct api_wks_cmds[] =
+static const struct api_struct api_wks_cmds[] =
{
{ "WKS_Q_QUERY_INFO", WKS_QUERY_INFO, api_wks_query_info },
{ NULL , 0 , NULL }
@@ -107,8 +72,8 @@ struct api_struct api_wks_cmds[] =
/*******************************************************************
receives a wkssvc pipe and responds.
********************************************************************/
-BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data)
+BOOL api_wkssvc_rpc(rpcsrv_struct *p)
{
- return api_rpcTNP(p, "api_wkssvc_rpc", api_wks_cmds, data);
+ return api_rpcTNP(p, "api_wkssvc_rpc", api_wks_cmds);
}
diff --git a/source/rpcclient/cmd_atsvc.c b/source/rpcclient/cmd_atsvc.c
new file mode 100644
index 00000000000..ea86246543d
--- /dev/null
+++ b/source/rpcclient/cmd_atsvc.c
@@ -0,0 +1,353 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.1.
+ MSRPC client: scheduler service
+ Copyright (C) Matthew Chapman 1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+ Copyright (C) Andrew Tridgell 1994-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern FILE* out_hnd;
+
+
+/****************************************************************************
+checks for a /OPTION:param style option
+****************************************************************************/
+static BOOL checkopt(char *input, char *optname, char **params)
+{
+ char *inend;
+
+ if (*input++ != '/')
+ return False;
+
+ for (inend = input; *inend != 0 && *inend != ':'; inend++);
+
+ if (params != NULL)
+ {
+ *inend = 0;
+ *params = inend;
+ }
+
+ while(input < inend)
+ {
+ if (toupper(*input++) != *optname++)
+ return False;
+ }
+
+ return True;
+}
+
+extern char *daynames_short[];
+extern char *daynames[];
+
+/****************************************************************************
+parses a list of days of the week and month
+****************************************************************************/
+static BOOL at_parse_days(char *str, uint32 *monthdays, uint8 *weekdays)
+{
+ char *tok;
+ char *nexttok = str;
+ int day;
+
+ do {
+ tok = nexttok;
+
+ if ((nexttok = strchr(tok, ',')) != NULL)
+ {
+ *nexttok++ = 0;
+ }
+
+ if (isdigit((int)*tok))
+ {
+ day = strtol(tok, NULL, 10);
+ if (day == 0 || day > 31)
+ {
+ printf("\tInvalid day of month.\n\n");
+ return False;
+ }
+
+ *monthdays |= (1 << (day-1));
+ }
+ else
+ {
+ if (strlen(tok) < 3)
+ {
+ for (day = 0; day < 7; day++)
+ {
+ if (!strcasecmp(tok, daynames_short[day]))
+ break;
+ }
+ }
+ else
+ {
+ for (day = 0; day < 7; day++)
+ {
+ if (!strncasecmp(tok, daynames[day], 3))
+ break;
+ }
+ }
+
+ if (day < 7)
+ {
+ *weekdays |= (1 << day);
+ }
+ else
+ {
+ printf("\tInvalid day of week\n\n");
+ return False;
+ }
+ }
+
+ } while (nexttok != NULL);
+
+ return True;
+}
+
+#define SOON_OFFSET 2 /* seconds */
+
+/****************************************************************************
+schedule the job 'soon'
+****************************************************************************/
+static BOOL at_soon(char *dest_srv, uint32 *hours, uint32 *minutes, uint32 *seconds)
+{
+ TIME_OF_DAY_INFO tod;
+ BOOL res = True;
+
+ /* enumerate files on server */
+ res = res ? srv_net_remote_tod(dest_srv, &tod) : False;
+
+ if (res)
+ {
+ *hours = (tod.hours - ((int)tod.zone/60)) % 24;
+ *minutes = tod.mins;
+ *seconds = (tod.secs + SOON_OFFSET) % 60;
+ return True;
+ }
+
+ return False;
+}
+
+
+/****************************************************************************
+scheduler add job
+****************************************************************************/
+void cmd_at(struct client_info *info, int argc, char *argv[])
+{
+ fstring dest_wks;
+ BOOL add = False;
+ BOOL del = False;
+ char *p;
+
+ uint32 jobid = -1;
+ unsigned int hours, minutes, seconds = 0;
+ uint32 monthdays = 0;
+ uint8 weekdays = 0;
+ uint8 flags = JOB_NONINTERACTIVE;
+ pstring command;
+
+ safe_strcpy(dest_wks, "\\\\", sizeof(dest_wks));
+ safe_strcat(dest_wks, info->dest_host, sizeof(dest_wks));
+ strupper(dest_wks);
+
+ while (argc > 1)
+ {
+ argc--;
+ argv++;
+
+ if (checkopt(argv[0], "DELETE", NULL))
+ {
+ del = True;
+ continue;
+ }
+ else if (checkopt(argv[0], "YES", NULL))
+ {
+ /* Compatibility */
+ continue;
+ }
+
+ jobid = strtol(argv[0], &p, 10);
+ if (*p == 0) /* Entirely numeric field */
+ continue;
+
+ if (!strcasecmp(argv[0], "NOW"))
+ {
+ if (!at_soon(dest_wks, &hours, &minutes, &seconds))
+ {
+ return;
+ }
+ }
+ else if (sscanf(argv[0], "%d:%d:%d", &hours, &minutes, &seconds) >= 2)
+ {
+ p = strchr(argv[0], 0);
+
+ if (!strcasecmp(p-2, "AM"))
+ {
+ hours = (hours == 12) ? 0 : hours;
+ }
+
+ if (!strcasecmp(p-2, "PM"))
+ {
+ hours = (hours == 12) ? 12 : hours + 12;
+ }
+
+ if (hours > 23 || minutes > 59 || seconds > 59)
+ {
+ printf("\tInvalid time.\n\n");
+ return;
+ }
+ }
+ else
+ {
+ printf("at { {time | NOW} [/INTERACTIVE] [{/EVERY|/NEXT}:5,Sun,...] command\n\t| [/DEL] [jobid] }\n\n");
+ return;
+ }
+
+ add = True;
+ command[0] = 0;
+ p = NULL;
+
+ if (argc <= 1) break;
+ argc--;
+ argv++;
+
+ if (checkopt(argv[0], "INTERACTIVE", NULL))
+ {
+ flags &= ~JOB_NONINTERACTIVE;
+
+ if (argc <= 1) break;
+ argc--;
+ argv++;
+ }
+
+ if (checkopt(argv[0], "EVERY", &p))
+ {
+ flags |= JOB_PERIODIC;
+ }
+ else
+ {
+ checkopt(argv[0], "NEXT", &p);
+ }
+
+ if (p != NULL)
+ {
+ if (*p == ':')
+ {
+ if (!at_parse_days(p, &monthdays, &weekdays))
+ return;
+ }
+ else
+ {
+ weekdays = 0x7F;
+ }
+
+ if (argc <= 1) break;
+ argc--;
+ argv++;
+ }
+
+ while (True)
+ {
+ safe_strcat(command, argv[0], sizeof(command));
+
+ if (argc <= 1) break;
+ argc--;
+ argv++;
+
+ safe_strcat(command, " ", sizeof(command));
+ }
+
+ break;
+ }
+
+ if (add && !command[0])
+ {
+ printf("\tNo command specified.\n\n");
+ return;
+ }
+
+ if (add) /* add job */
+ {
+ AT_JOB_INFO job;
+
+ job.time = ((((hours * 60) + minutes) * 60) + seconds) * 1000;
+ job.monthdays = monthdays;
+ job.weekdays = weekdays;
+ job.flags = flags;
+ job.ptr_command = 1;
+
+ display_at_job_info(out_hnd, ACTION_HEADER , &job, command);
+ display_at_job_info(out_hnd, ACTION_ENUMERATE, &job, command);
+ display_at_job_info(out_hnd, ACTION_FOOTER , &job, command);
+
+ if (at_add_job(dest_wks, &job, command, &jobid))
+ {
+ fprintf(out_hnd, "\tJob ID: %d\n\n", jobid);
+ }
+ }
+ else if (del) /* delete */
+ {
+ if (jobid == -1)
+ {
+ fprintf(out_hnd, "\tDeleting all jobs.\n\n");
+ at_del_job(dest_wks, 0, 0xffffffff);
+ }
+ else
+ {
+ fprintf(out_hnd, "\tDeleting job %d.\n\n", jobid);
+ at_del_job(dest_wks, jobid, jobid);
+ }
+
+ }
+ else if (jobid == -1) /* enumerate */
+ {
+ AT_ENUM_INFO jobs[AT_MAX_JOBS];
+ char **commands = NULL;
+ uint32 num_jobs = 0;
+
+ if (at_enum_jobs(dest_wks, &num_jobs, jobs, &commands))
+ {
+ display_at_enum_info(out_hnd, ACTION_HEADER , num_jobs, jobs, commands);
+ display_at_enum_info(out_hnd, ACTION_ENUMERATE, num_jobs, jobs, commands);
+ display_at_enum_info(out_hnd, ACTION_FOOTER , num_jobs, jobs, commands);
+ }
+
+ free_char_array(num_jobs, commands);
+ }
+ else /* job info */
+ {
+ AT_JOB_INFO job;
+
+ if (at_query_job(dest_wks, jobid, &job, command))
+ {
+ display_at_job_info(out_hnd, ACTION_HEADER , &job, command);
+ display_at_job_info(out_hnd, ACTION_ENUMERATE, &job, command);
+ display_at_job_info(out_hnd, ACTION_FOOTER , &job, command);
+ }
+ }
+}
diff --git a/source/rpcclient/cmd_brs.c b/source/rpcclient/cmd_brs.c
new file mode 100644
index 00000000000..886d8e7ced0
--- /dev/null
+++ b/source/rpcclient/cmd_brs.c
@@ -0,0 +1,84 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "rpc_brs.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern FILE* out_hnd;
+
+
+/****************************************************************************
+Browser get info query
+****************************************************************************/
+void cmd_brs_query_info(struct client_info *info, int argc, char *argv[])
+{
+ fstring dest_brs;
+ BRS_INFO_100 ctr;
+ uint32 info_level = 100;
+
+ BOOL res = True;
+
+ bzero(&ctr, sizeof(ctr));
+
+ fstrcpy(dest_brs, "\\\\");
+ fstrcat(dest_brs, info->dest_host);
+ strupper(dest_brs);
+
+ if (argc > 1)
+ {
+ info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
+ }
+
+ DEBUG(4,("cmd_brs_query_info: server:%s info level: %d\n",
+ dest_brs, info_level));
+
+ /* send info level: receive requested info. hopefully. */
+ res = res ? brs_query_info( dest_brs, info_level, &ctr) : False;
+
+ if (res)
+ {
+ DEBUG(5,("cmd_brs_query_info: query succeeded\n"));
+
+#if 0
+ display_brs_info_100(out_hnd, ACTION_HEADER , &ctr);
+ display_brs_info_100(out_hnd, ACTION_ENUMERATE, &ctr);
+ display_brs_info_100(out_hnd, ACTION_FOOTER , &ctr);
+#endif
+
+ }
+ else
+ {
+ DEBUG(5,("cmd_brs_query_info: query failed\n"));
+ }
+}
+
diff --git a/source/rpcclient/cmd_eventlog.c b/source/rpcclient/cmd_eventlog.c
new file mode 100644
index 00000000000..3e86f5bb28b
--- /dev/null
+++ b/source/rpcclient/cmd_eventlog.c
@@ -0,0 +1,92 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2.1.
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999,
+ Copyright (C) Andrew Tridgell 1994-1999,
+ Copyright (C) Jean Francois Micouleau 1998-1999.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern FILE* out_hnd;
+
+
+/****************************************************************************
+****************************************************************************/
+void cmd_eventlog(struct client_info *info, int argc, char *argv[])
+{
+ BOOL res1 = True;
+ BOOL res = True;
+ POLICY_HND hnd;
+ uint32 number = 0;
+ uint32 flags;
+ uint32 offset;
+ uint32 num_of_bytes;
+ EVENTLOGRECORD ev;
+
+ char *journal = NULL;
+
+ fstring srv_name;
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ flags = EVENTLOG_READ_SEQUENTIAL|EVENTLOG_READ_BACKWARD;
+
+ if (argc > 1)
+ {
+ journal = argv[1];
+ }
+
+ res = res ? event_open(srv_name, journal, &hnd) : False;
+ res1 = res ? event_numofeventlogrec(&hnd, &number) : False;
+
+ fprintf(out_hnd, "Number of events: %d\n", number);
+
+ display_eventlog_eventrecord(out_hnd, ACTION_HEADER, &ev);
+
+ for (offset = 0; offset < number && res1; offset++)
+ {
+ num_of_bytes=0;
+
+ /* try once with a empty buffer */
+ res1 = res1 ? event_readeventlog(&hnd, number,
+ flags, offset,
+ &num_of_bytes, &ev) : False;
+
+ /* and try again with the correct size */
+ res1 = res1 ? event_readeventlog(&hnd, number,
+ flags, offset,
+ &num_of_bytes, &ev) : False;
+
+ display_eventlog_eventrecord(out_hnd, ACTION_ENUMERATE, &ev);
+ }
+
+ display_eventlog_eventrecord(out_hnd, ACTION_FOOTER, &ev);
+
+ res = res ? event_close(&hnd): False;
+}
diff --git a/source/rpcclient/cmd_lsarpc.c b/source/rpcclient/cmd_lsarpc.c
index 731eda4437d..77fdcfeb266 100644
--- a/source/rpcclient/cmd_lsarpc.c
+++ b/source/rpcclient/cmd_lsarpc.c
@@ -2,8 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1994-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,7 +21,6 @@
*/
-
#ifdef SYSLOG
#undef SYSLOG
#endif
@@ -33,18 +32,73 @@ extern int DEBUGLEVEL;
#define DEBUG_TESTING
-extern struct cli_state *smb_cli;
-extern int smb_tidx;
-
extern FILE* out_hnd;
+/****************************************************************************
+nt enumerate trusted domains
+****************************************************************************/
+void cmd_lsa_enum_trust_dom(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ uint32 num_doms = 0;
+ char **domains = NULL;
+ DOM_SID **sids = NULL;
+ uint32 enum_ctx = 0;
+ POLICY_HND lsa_pol;
+
+ BOOL res = True;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ DEBUG(4,("cmd_lsa_enum_trust_dom: server:%s\n", srv_name));
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? lsa_open_policy( srv_name,
+ &lsa_pol, False, 0x02000000) : False;
+
+ do
+ {
+ /* send enum trusted domains query */
+ res = res ? lsa_enum_trust_dom( &lsa_pol,
+ &enum_ctx,
+ &num_doms, &domains, &sids) : False;
+
+ } while (res && enum_ctx != 0);
+
+ res = res ? lsa_close(&lsa_pol) : False;
+
+ if (res)
+ {
+ uint32 i;
+ DEBUG(5,("cmd_lsa_enum_trust_dom: query succeeded\n"));
+
+ report(out_hnd, "LSA Enumerate Trusted Domains\n");
+ for (i = 0; i < num_doms; i++)
+ {
+ fstring sid;
+ sid_to_string(sid, sids[i]);
+ report(out_hnd, "Domain:\t%s\tSID:\t%s\n",
+ domains[i], sid);
+ }
+ }
+ else
+ {
+ DEBUG(5,("cmd_lsa_enum_trust_dom: query failed\n"));
+ }
+
+ free_char_array(num_doms, domains);
+ free_sid_array(num_doms, sids);
+}
/****************************************************************************
nt lsa query
****************************************************************************/
-void cmd_lsa_query_info(struct client_info *info)
+void cmd_lsa_query_info(struct client_info *info, int argc, char *argv[])
{
fstring srv_name;
+ POLICY_HND lsa_pol;
BOOL res = True;
@@ -54,37 +108,26 @@ void cmd_lsa_query_info(struct client_info *info)
ZERO_STRUCT(info->dom.level5_sid);
fstrcpy(srv_name, "\\\\");
- fstrcat(srv_name, info->myhostname);
+ fstrcat(srv_name, info->dest_host);
strupper(srv_name);
DEBUG(4,("cmd_lsa_query_info: server:%s\n", srv_name));
- DEBUG(5, ("cmd_lsa_query_info: smb_cli->fd:%d\n", smb_cli->fd));
-
- /* open LSARPC session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_LSARPC) : False;
-
/* lookup domain controller; receive a policy handle */
- res = res ? do_lsa_open_policy(smb_cli,
- srv_name,
- &info->dom.lsa_info_pol, False) : False;
+ res = res ? lsa_open_policy( srv_name,
+ &lsa_pol, False, 0x02000000) : False;
/* send client info query, level 3. receive domain name and sid */
- res = res ? do_lsa_query_info_pol(smb_cli,
- &info->dom.lsa_info_pol, 0x03,
+ res = res ? lsa_query_info_pol( &lsa_pol, 0x03,
info->dom.level3_dom,
&info->dom.level3_sid) : False;
/* send client info query, level 5. receive domain name and sid */
- res = res ? do_lsa_query_info_pol(smb_cli,
- &info->dom.lsa_info_pol, 0x05,
+ res = res ? lsa_query_info_pol( &lsa_pol, 0x05,
info->dom.level5_dom,
&info->dom.level5_sid) : False;
- res = res ? do_lsa_close(smb_cli, &info->dom.lsa_info_pol) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? lsa_close(&lsa_pol) : False;
if (res)
{
@@ -92,25 +135,25 @@ void cmd_lsa_query_info(struct client_info *info)
fstring sid;
DEBUG(5,("cmd_lsa_query_info: query succeeded\n"));
- fprintf(out_hnd, "LSA Query Info Policy\n");
+ report(out_hnd, "LSA Query Info Policy\n");
if (info->dom.level3_dom[0] != 0)
{
sid_to_string(sid, &info->dom.level3_sid);
- fprintf(out_hnd, "Domain Member - Domain: %s SID: %s\n",
+ report(out_hnd, "Domain Member - Domain: %s SID: %s\n",
info->dom.level3_dom, sid);
domain_something = True;
}
if (info->dom.level5_dom[0] != 0)
{
sid_to_string(sid, &info->dom.level5_sid);
- fprintf(out_hnd, "Domain Controller - Domain: %s SID: %s\n",
+ report(out_hnd, "Domain Controller - Domain: %s SID: %s\n",
info->dom.level5_dom, sid);
domain_something = True;
}
if (!domain_something)
{
- fprintf(out_hnd, "%s is not a Domain Member or Controller\n",
+ report(out_hnd, "%s is not a Domain Member or Controller\n",
info->dest_host);
}
}
@@ -121,33 +164,102 @@ void cmd_lsa_query_info(struct client_info *info)
}
/****************************************************************************
-nt lsa query
+lookup names
****************************************************************************/
-void cmd_lsa_lookup_sids(struct client_info *info)
+void cmd_lsa_lookup_names(struct client_info *info, int argc, char *argv[])
{
- fstring temp;
- int i;
- fstring sid_name;
fstring srv_name;
- DOM_SID sid[10];
- DOM_SID *sids[10];
+ int num_names = 0;
+ char **names;
+ uint32 *types = NULL;
+ DOM_SID *sids = NULL;
int num_sids = 0;
+ uint32 ret;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ DEBUG(4,("cmd_lsa_lookup_names: server: %s\n", srv_name));
+
+ argc--;
+ argv++;
+
+ num_names = argc;
+ names = argv;
+
+ if (num_names <= 0)
+ {
+ report(out_hnd, "lookupnames <name> [<name> ...]\n");
+ return;
+ }
+
+ ret = lookup_lsa_names(srv_name,
+ num_names, names,
+ &num_sids, &sids, &types);
+
+ if (ret != 0x0)
+ {
+ report(out_hnd, "cmd_lsa_lookup_names: FAILED: %s\n",
+ get_nt_error_msg(ret));
+ }
+
+ if (sids != NULL)
+ {
+ int i;
+ fstring temp;
+
+ report(out_hnd, "Lookup Names:\n");
+ for (i = 0; i < num_sids; i++)
+ {
+ sid_to_string(temp, &sids[i]);
+ report(out_hnd, "SID: %s -> %s (%d: %s)\n",
+ names[i], temp, types[i],
+ get_sid_name_use_str(types[i]));
+#if 0
+ if (sids[i] != NULL)
+ {
+ free(sids[i]);
+ }
+#endif
+ }
+ free(sids);
+ }
+ safe_free(types);
+}
+
+/****************************************************************************
+lookup sids
+****************************************************************************/
+void cmd_lsa_lookup_sids(struct client_info *info, int argc, char *argv[])
+{
+ POLICY_HND lsa_pol;
+ int i;
+ pstring sid_name;
+ fstring srv_name;
+ DOM_SID **sids = NULL;
+ uint32 num_sids = 0;
char **names = NULL;
+ uint32 *types = NULL;
int num_names = 0;
BOOL res = True;
fstrcpy(srv_name, "\\\\");
- fstrcat(srv_name, info->myhostname);
+ fstrcat(srv_name, info->dest_host);
strupper(srv_name);
DEBUG(4,("cmd_lsa_lookup_sids: server: %s\n", srv_name));
- while (num_sids < 10 && next_token(NULL, temp, NULL, sizeof(temp)))
+ argv++;
+ argc--;
+
+ while (argc > 0)
{
- if (strnequal("S-", temp, 2))
+ DOM_SID sid;
+ if (strnequal("S-", argv[0], 2))
{
- fstrcpy(sid_name, temp);
+ fstrcpy(sid_name, argv[0]);
}
else
{
@@ -155,42 +267,37 @@ void cmd_lsa_lookup_sids(struct client_info *info)
if (sid_name[0] == 0)
{
- fprintf(out_hnd, "please use lsaquery first or specify a complete SID\n");
+ report(out_hnd, "please use lsaquery first or specify a complete SID\n");
return;
}
fstrcat(sid_name, "-");
- fstrcat(sid_name, temp);
+ fstrcat(sid_name, argv[0]);
}
- init_dom_sid(&sid[num_sids], sid_name);
- sids[num_sids] = &sid[num_sids];
- num_sids++;
+ string_to_sid(&sid, sid_name);
+
+ add_sid_to_array(&num_sids, &sids, &sid);
+
+ argc--;
+ argv++;
}
if (num_sids == 0)
{
- fprintf(out_hnd, "lookupsid RID or SID\n");
+ report(out_hnd, "lookupsid RID or SID\n");
return;
}
- /* open LSARPC session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_LSARPC) : False;
-
/* lookup domain controller; receive a policy handle */
- res = res ? do_lsa_open_policy(smb_cli,
- srv_name,
- &info->dom.lsa_info_pol, True) : False;
+ res = res ? lsa_open_policy( srv_name,
+ &lsa_pol, True, 0x02000000) : False;
/* send lsa lookup sids call */
- res = res ? do_lsa_lookup_sids(smb_cli,
- &info->dom.lsa_info_pol,
+ res = res ? lsa_lookup_sids( &lsa_pol,
num_sids, sids,
- &names, &num_names) : False;
+ &names, &types, &num_names) : False;
- res = res ? do_lsa_close(smb_cli, &info->dom.lsa_info_pol) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? lsa_close(&lsa_pol) : False;
if (res)
{
@@ -202,11 +309,14 @@ void cmd_lsa_lookup_sids(struct client_info *info)
}
if (names != NULL)
{
- fprintf(out_hnd,"Lookup SIDS:\n");
+ report(out_hnd, "Lookup SIDS:\n");
for (i = 0; i < num_names; i++)
{
+ fstring temp;
sid_to_string(temp, sids[i]);
- fprintf(out_hnd, "SID: %s -> %s\n", temp, names[i]);
+ report(out_hnd, "SID: %s -> %s (%d: %s)\n",
+ temp, names[i], types[i],
+ get_sid_name_use_str(types[i]));
if (names[i] != NULL)
{
free(names[i]);
@@ -214,5 +324,183 @@ void cmd_lsa_lookup_sids(struct client_info *info)
}
free(names);
}
+
+ if (types)
+ {
+ free(types);
+ }
+
+ free_sid_array(num_sids, sids);
+}
+
+/****************************************************************************
+nt lsa query
+****************************************************************************/
+void cmd_lsa_set_secret(struct client_info *info, int argc, char *argv[])
+{
+ char *secret_name;
+ fstring srv_name;
+ char *data;
+ int len;
+ UNISTR2 uni_data;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (argc != 3)
+ {
+ report(out_hnd, "setsecret <secret name> <secret value>\n");
+ return;
+ }
+
+ secret_name = argv[1];
+ data = argv[2];
+ len = strlen(argv[2]);
+
+ make_unistr2(&uni_data, data, len);
+
+ if (msrpc_lsa_set_secret(srv_name, secret_name,
+ (const char*)uni_data.buffer, uni_data.uni_str_len * 2))
+ {
+ report(out_hnd, "LSA Set Secret: OK\n");
+ }
+ else
+ {
+ report(out_hnd, "LSA Set Secret: failed\n");
+ }
+}
+
+/****************************************************************************
+nt lsa query
+****************************************************************************/
+void cmd_lsa_create_secret(struct client_info *info, int argc, char *argv[])
+{
+ char *secret_name;
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (argc > 2)
+ {
+ report(out_hnd, "createsecret <secret name>\n");
+ return;
+ }
+
+ secret_name = argv[1];
+
+ if (msrpc_lsa_create_secret(srv_name, secret_name, 0x020003))
+ {
+ report(out_hnd, "LSA Create Secret: OK\n");
+ }
+ else
+ {
+ report(out_hnd, "LSA Query Secret: failed\n");
+ }
+}
+
+/****************************************************************************
+nt lsa query
+****************************************************************************/
+void cmd_lsa_query_secret_secobj(struct client_info *info, int argc, char *argv[])
+{
+ char *secret_name;
+ fstring srv_name;
+
+ BOOL res = True;
+ BOOL res1;
+ BOOL res2;
+
+ POLICY_HND pol_sec;
+ POLICY_HND lsa_pol;
+ SEC_DESC_BUF buf;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ ZERO_STRUCT(buf);
+
+ if (argc > 2)
+ {
+ report(out_hnd, "querysecretsecdes <secret name>\n");
+ return;
+ }
+
+ secret_name = argv[1];
+
+ /* lookup domain controller; receive a policy handle */
+ res = res ? lsa_open_policy(srv_name,
+ &lsa_pol, False, 0x02000000) : False;
+
+ /* lookup domain controller; receive a policy handle */
+ res1 = res ? lsa_open_secret(&lsa_pol,
+ secret_name, 0x02000000,
+ &pol_sec) : False;
+
+ res2 = res1 ? lsa_query_sec_obj(&pol_sec, 0x07, &buf) : False;
+
+ if (buf.sec != NULL)
+ {
+ display_sec_desc(out_hnd, ACTION_HEADER , buf.sec);
+ display_sec_desc(out_hnd, ACTION_ENUMERATE, buf.sec);
+ display_sec_desc(out_hnd, ACTION_FOOTER , buf.sec);
+ }
+ else
+ {
+ report(out_hnd, "LSA Query Secret: failed\n");
+ }
+
+ free_sec_desc_buf(&buf);
+
+ res1 = res1 ? lsa_close(&pol_sec) : False;
+ res = res ? lsa_close(&lsa_pol) : False;
+
+
+}
+
+/****************************************************************************
+nt lsa query
+****************************************************************************/
+void cmd_lsa_query_secret(struct client_info *info, int argc, char *argv[])
+{
+ char *secret_name;
+ STRING2 secret;
+ NTTIME last_update;
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ ZERO_STRUCT(secret);
+
+ if (argc > 2)
+ {
+ report(out_hnd, "querysecret <secret name>\n");
+ return;
+ }
+
+ secret_name = argv[1];
+
+ if (msrpc_lsa_query_secret(srv_name, secret_name, &secret,
+ &last_update))
+ {
+ int i;
+ report(out_hnd, "\tValue : ");
+ for (i = 0; i < secret.str_str_len; i++)
+ {
+ report(out_hnd, "%02X", secret.buffer[i]);
+ }
+
+ report(out_hnd, "\n\tLast Updated: %s\n\n",
+ http_timestring(nt_time_to_unix(&last_update)));
+ }
+ else
+ {
+ report(out_hnd, "LSA Query Secret: failed\n");
+ }
}
diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c
index 2c8514b43e8..3a57bb034ed 100644
--- a/source/rpcclient/cmd_netlogon.c
+++ b/source/rpcclient/cmd_netlogon.c
@@ -33,101 +33,291 @@ extern int DEBUGLEVEL;
#define DEBUG_TESTING
-extern struct cli_state *smb_cli;
+extern struct user_creds *usr_creds;
-extern FILE* out_hnd;
+extern FILE *out_hnd;
/****************************************************************************
experimental nt login.
****************************************************************************/
-void cmd_netlogon_login_test(struct client_info *info)
+void cmd_netlogon_login_test(struct client_info *info, int argc, char *argv[])
{
- extern BOOL global_machine_password_needs_changing;
-
fstring nt_user_name;
- fstring password;
BOOL res = True;
char *nt_password;
- unsigned char trust_passwd[16];
+ uchar trust_passwd[16];
+ uchar nt_pw[16];
+ uchar lm_pw[16];
+ fstring trust_acct;
+ fstring domain;
+ char *p;
+
+ fstring wks_name;
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fstrcpy(wks_name, "\\\\");
+ if (strequal(srv_name, "\\\\.") &&
+ strequal(info->dest_host, info->myhostname))
+ {
+ fstrcat(wks_name, ".");
+ }
+ else
+ {
+ fstrcat(wks_name, info->dest_host);
+ }
+ strupper(wks_name);
+
+ domain[0] = 0;
+ if (usr_creds != NULL)
+ {
+ fstrcpy(domain, usr_creds->ntc.domain);
+ }
+ if (domain[0] == 0)
+ {
+ fstrcpy(domain, info->dom.level3_dom);
+ }
#if 0
- /* machine account passwords */
+ /* trust account passwords */
pstring new_mach_pwd;
/* initialisation */
new_mach_pwd[0] = 0;
#endif
- if (!next_token(NULL, nt_user_name, NULL, sizeof(nt_user_name)))
+ argc--;
+ argv++;
+
+ if (argc < 1)
{
- fstrcpy(nt_user_name, smb_cli->user_name);
+ nt_user_name[0] = 0;
+ if (usr_creds != NULL)
+ {
+ fstrcpy(nt_user_name, usr_creds->ntc.user_name);
+ }
if (nt_user_name[0] == 0)
{
- fprintf(out_hnd,"ntlogin: must specify username with anonymous connection\n");
+ report(out_hnd,
+ "ntlogin: must specify username with anonymous connection\n");
+ report(out_hnd,
+ "ntlogin [[DOMAIN\\]user] [password]\n");
return;
}
}
+ else
+ {
+ fstrcpy(nt_user_name, argv[0]);
+ }
- if (next_token(NULL, password, NULL, sizeof(password)))
+ p = strchr(nt_user_name, '\\');
+ if (p != NULL)
{
- nt_password = password;
+ fstrcpy(domain, nt_user_name);
+ p = strchr(domain, '\\');
+ if (p != NULL)
+ {
+ *p = 0;
+ fstrcpy(nt_user_name, p + 1);
+ }
+
+ }
+
+ if (domain[0] == 0)
+ {
+ report(out_hnd, "no domain specified.\n");
+ }
+
+ argc--;
+ argv++;
+
+ if (argc > 0)
+ {
+ nt_password = argv[0];
}
else
{
nt_password = getpass("Enter NT Login password:");
}
- DEBUG(5,("do_nt_login_test: username %s\n", nt_user_name));
+ nt_lm_owf_gen(nt_password, nt_pw, lm_pw);
+
+ DEBUG(5, ("do_nt_login_test: username %s from: %s\n",
+ nt_user_name, info->myhostname));
+
+ fstrcpy(trust_acct, info->myhostname);
+ fstrcat(trust_acct, "$");
+
+ res = res ? msrpc_lsa_query_trust_passwd(wks_name, "$MACHINE.ACC",
+ trust_passwd, NULL) : False;
+
+ res = res ? cli_nt_setup_creds(srv_name, domain, info->myhostname,
+ trust_acct,
+ trust_passwd,
+ SEC_CHAN_WKSTA) == 0x0 : False;
+
+
+ memset(trust_passwd, 0, 16);
+
+ /* do an NT login */
+ res = res ? (cli_nt_login_interactive(srv_name, info->myhostname,
+ domain, nt_user_name,
+ getuid(), lm_pw, nt_pw,
+ &info->dom.ctr,
+ &info->dom.user_info3) ==
+ 0x0) : False;
- res = res ? trust_get_passwd(trust_passwd, smb_cli->domain, info->myhostname) : False;
#if 0
- /* check whether the user wants to change their machine password */
- res = res ? trust_account_check(info->dest_ip, info->dest_host,
- info->myhostname, smb_cli->domain,
- info->mach_acct, new_mach_pwd) : False;
+ /* ok! you're logged in! do anything you like, then... */
+
+ /* do an NT logout */
+ res =
+ res ? cli_nt_logoff(srv_name, info->myhostname,
+ &info->dom.ctr) : False;
#endif
- /* open NETLOGON session. negotiate credentials */
- res = res ? cli_nt_session_open(smb_cli, PIPE_NETLOGON) : False;
- res = res ? cli_nt_setup_creds(smb_cli, trust_passwd) : False;
+ report(out_hnd, "cmd_nt_login: login (%s) test succeeded: %s\n",
+ nt_user_name, BOOLSTR(res));
+}
- /* change the machine password? */
- if (global_machine_password_needs_changing)
+/****************************************************************************
+experimental nt login.
+****************************************************************************/
+void cmd_netlogon_domain_test(struct client_info *info, int argc,
+ char *argv[])
+{
+ char *nt_trust_dom;
+ BOOL res = True;
+ uchar trust_passwd[16];
+ fstring inter_dom_acct;
+ fstring trust_sec_name;
+ fstring domain;
+
+ fstring wks_name;
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fstrcpy(wks_name, "\\\\");
+ if (strequal(srv_name, "\\\\.") &&
+ strequal(info->dest_host, info->myhostname))
+ {
+ fstrcat(wks_name, ".");
+ }
+ else
{
- unsigned char new_trust_passwd[16];
- generate_random_buffer(new_trust_passwd, 16, True);
- res = res ? cli_nt_srv_pwset(smb_cli, new_trust_passwd) : False;
+ fstrcat(wks_name, info->dest_host);
+ }
+ strupper(wks_name);
- if (res)
- {
- global_machine_password_needs_changing = !set_trust_account_password(new_trust_passwd);
- }
+ domain[0] = 0;
+ if (usr_creds != NULL)
+ {
+ fstrcpy(domain, usr_creds->ntc.domain);
+ }
- memset(new_trust_passwd, 0, 16);
+ if (domain[0] == 0)
+ {
+ fstrcpy(domain, info->dom.level3_dom);
}
- memset(trust_passwd, 0, 16);
+ if (argc < 2)
+ {
+ report(out_hnd, "domtest: must specify domain name\n");
+ return;
+ }
- /* do an NT login */
- res = res ? cli_nt_login_interactive(smb_cli,
- smb_cli->domain, nt_user_name,
- getuid(), nt_password,
- &info->dom.ctr, &info->dom.user_info3) : False;
+ nt_trust_dom = argv[1];
- /*** clear out the password ***/
- memset(password, 0, sizeof(password));
+ DEBUG(5, ("do_nt_login_test: domain %s\n", nt_trust_dom));
- /* ok! you're logged in! do anything you like, then... */
+ fstrcpy(trust_sec_name, "G$$");
+ fstrcat(trust_sec_name, nt_trust_dom);
+ strupper(inter_dom_acct);
- /* do an NT logout */
- res = res ? cli_nt_logoff(smb_cli, &info->dom.ctr) : False;
+ fstrcpy(inter_dom_acct, nt_trust_dom);
+ fstrcat(inter_dom_acct, "$");
+
+ res = res ? msrpc_lsa_query_trust_passwd(wks_name, trust_sec_name,
+ trust_passwd, NULL) : False;
+ res = res ? cli_nt_setup_creds(srv_name, domain,
+ info->myhostname, inter_dom_acct,
+ trust_passwd,
+ SEC_CHAN_DOMAIN) == 0x0 : False;
- /* close the session */
- cli_nt_session_close(smb_cli);
+ memset(trust_passwd, 0, 16);
- fprintf(out_hnd,"cmd_nt_login: login (%s) test succeeded: %s\n",
- nt_user_name, BOOLSTR(res));
+ report(out_hnd, "cmd_nt_login: credentials (%s) test succeeded: %s\n",
+ nt_trust_dom, BOOLSTR(res));
}
+/****************************************************************************
+experimental SAM synchronisation.
+****************************************************************************/
+void cmd_sam_sync(struct client_info *info, int argc, char *argv[])
+{
+ SAM_DELTA_HDR hdr_deltas[MAX_SAM_DELTAS];
+ SAM_DELTA_CTR deltas[MAX_SAM_DELTAS];
+ uint32 num;
+ uchar trust_passwd[16];
+ fstring trust_acct;
+ fstring domain;
+
+ fstring wks_name;
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fstrcpy(wks_name, "\\\\");
+ if (strequal(srv_name, "\\\\.") &&
+ strequal(info->dest_host, info->myhostname))
+ {
+ fstrcat(wks_name, ".");
+ }
+ else
+ {
+ fstrcat(wks_name, info->dest_host);
+ }
+ strupper(wks_name);
+
+ fstrcpy(trust_acct, info->myhostname);
+ fstrcat(trust_acct, "$");
+
+ domain[0] = 0;
+ if (usr_creds != NULL)
+ {
+ fstrcpy(domain, usr_creds->ntc.domain);
+ }
+
+ if (domain[0] == 0)
+ {
+ fstrcpy(domain, info->dom.level3_dom);
+ }
+
+ if (!msrpc_lsa_query_trust_passwd(wks_name, "$MACHINE.ACC",
+ trust_passwd, NULL))
+ {
+ report(out_hnd, "cmd_sam_sync: no trust account password\n");
+ return;
+ }
+
+ if (net_sam_sync(srv_name, domain, info->myhostname,
+ trust_acct, trust_passwd, hdr_deltas, deltas, &num))
+ {
+ display_sam_sync(out_hnd, ACTION_HEADER, hdr_deltas, deltas,
+ num);
+ display_sam_sync(out_hnd, ACTION_ENUMERATE, hdr_deltas,
+ deltas, num);
+ display_sam_sync(out_hnd, ACTION_FOOTER, hdr_deltas, deltas,
+ num);
+ }
+}
diff --git a/source/rpcclient/cmd_reg.c b/source/rpcclient/cmd_reg.c
index fcc12c530cc..1462fd78586 100644
--- a/source/rpcclient/cmd_reg.c
+++ b/source/rpcclient/cmd_reg.c
@@ -2,8 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1994-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,38 +27,101 @@
#endif
#include "includes.h"
-#include "nterr.h"
+#include "rpc_parse.h"
extern int DEBUGLEVEL;
-extern struct cli_state *smb_cli;
-extern int smb_tidx;
-
extern FILE* out_hnd;
/*
* keys. of the form:
* ----
*
- * [HKLM]|[HKU]\[parent_keyname_components]\[subkey]|[value]
+ * [HKLM]|[HKU]|[HKCR]\[parent_keyname]\[subkey]|[value]
*
* reg_getsubkey() splits this down into:
- * [HKLM]|[HKU]\[parent_keyname_components] and [subkey]|[value]
+ * [HKLM]|[HKU]|[HKCR]\[parent_keyname_components] and [subkey]|[value]
*
- * do_reg_connect() splits the left side down further into:
- * [HKLM]|[HKU] and [parent_keyname_components].
+ * reg_connect() splits the left side down further into:
+ * [HKLM]|[HKU]|[HKCR] and [parent_keyname_components].
*
* HKLM is short for HKEY_LOCAL_MACHINE
+ * HKCR is short for HKEY_CLASSES_ROOT
* HKU is short for HKEY_USERS
*
* oh, and HKEY stands for "Hive Key".
*
*/
+static void reg_display_key(int val, const char *full_keyname, int num)
+{
+ switch (val)
+ {
+ case 0:
+ {
+ /* initialsation */
+ report(out_hnd, "Key Name:\t%s\n", full_keyname);
+ break;
+ }
+ case 1:
+ {
+ /* subkeys initialisation */
+ if (num > 0)
+ {
+ report(out_hnd,"Subkeys\n");
+ report(out_hnd,"-------\n");
+ }
+ break;
+ }
+ case 2:
+ {
+ /* values initialisation */
+ if (num > 0)
+ {
+ report(out_hnd,"Key Values\n");
+ report(out_hnd,"----------\n");
+ }
+ break;
+ }
+ case 3:
+ {
+ /* clean-up */
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+void split_server_keyname(char *srv_name, char *key, const char* arg)
+{
+ pstrcpy(key, arg);
+
+ if (strnequal("\\\\", key, 2))
+ {
+ char *p = strchr(&key[2], '\\');
+ if (p == NULL)
+ {
+ key[0] = 0;
+ return;
+ }
+
+ *p = 0;
+
+ fstrcpy(srv_name, key);
+ pstrcpy(key, &arg[strlen(srv_name)+1]);
+ }
+}
+
/****************************************************************************
nt registry enum
****************************************************************************/
-void cmd_reg_enum(struct client_info *info)
+BOOL msrpc_reg_enum_key(const char* srv_name, const char* full_keyname,
+ REG_FN(reg_fn),
+ REG_KEY_FN(reg_key_fn),
+ REG_VAL_FN(reg_val_fn))
{
BOOL res = True;
BOOL res1 = True;
@@ -66,7 +129,7 @@ void cmd_reg_enum(struct client_info *info)
int i;
POLICY_HND key_pol;
- fstring full_keyname;
+ POLICY_HND pol_con;
fstring key_name;
/*
@@ -90,46 +153,36 @@ void cmd_reg_enum(struct client_info *info)
uint32 unk_1a_response;
- DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli->fd));
-
- if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
- {
- fprintf(out_hnd, "regenum <key_name>\n");
- return;
- }
-
- /* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
+ DEBUG(5, ("reg_enum_key: %s\n", full_keyname));
/* open registry receive a policy handle */
- res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
- &info->dom.reg_pol_connect) : False;
+ res = res ? reg_connect(srv_name, full_keyname, key_name, 0x02000000,
+ &pol_con) : False;
if ((*key_name) != 0)
{
/* open an entry */
- res1 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ res1 = res ? reg_open_entry(&pol_con,
key_name, 0x02000000, &key_pol) : False;
}
else
{
- memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
+ memcpy(&key_pol, &pol_con, sizeof(key_pol));
}
- res1 = res1 ? do_reg_query_key(smb_cli,
- &key_pol,
+ res1 = res1 ? reg_query_key(&key_pol,
key_class, &max_class_len,
&num_subkeys, &max_subkeylen, &max_subkeysize,
&num_values, &max_valnamelen, &max_valbufsize,
&sec_desc, &mod_time) : False;
- if (res1 && num_subkeys > 0)
+ if (res1 && reg_fn != NULL)
{
- fprintf(out_hnd,"Subkeys\n");
- fprintf(out_hnd,"-------\n");
+ reg_fn(0, full_keyname, 0);
+ reg_fn(1, full_keyname, num_subkeys);
}
- for (i = 0; i < num_subkeys; i++)
+ for (i = 0; i < num_subkeys && reg_key_fn != NULL; i++)
{
/*
* enumerate key
@@ -141,36 +194,33 @@ void cmd_reg_enum(struct client_info *info)
time_t key_mod_time;
/* unknown 1a it */
- res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
+ res2 = res1 ? reg_unknown_1a(&key_pol,
&unk_1a_response) : False;
if (res2 && unk_1a_response != 5)
{
- fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
+ report(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
}
/* enum key */
- res2 = res2 ? do_reg_enum_key(smb_cli, &key_pol,
+ res2 = res2 ? reg_enum_key(&key_pol,
i, enum_name,
&enum_unk1, &enum_unk2,
&key_mod_time) : False;
if (res2)
{
- display_reg_key_info(out_hnd, ACTION_HEADER , enum_name, key_mod_time);
- display_reg_key_info(out_hnd, ACTION_ENUMERATE, enum_name, key_mod_time);
- display_reg_key_info(out_hnd, ACTION_FOOTER , enum_name, key_mod_time);
+ reg_key_fn(full_keyname, enum_name, key_mod_time);
}
}
- if (num_values > 0)
+ if (reg_fn != NULL)
{
- fprintf(out_hnd,"Key Values\n");
- fprintf(out_hnd,"----------\n");
+ reg_fn(2, full_keyname, num_values);
}
- for (i = 0; i < num_values; i++)
+ for (i = 0; i < num_values && reg_val_fn != NULL; i++)
{
/*
* enumerate key
@@ -181,57 +231,191 @@ void cmd_reg_enum(struct client_info *info)
fstring val_name;
/* unknown 1a it */
- res2 = res1 ? do_reg_unknown_1a(smb_cli, &key_pol,
+ res2 = res1 ? reg_unknown_1a(&key_pol,
&unk_1a_response) : False;
if (res2 && unk_1a_response != 5)
{
- fprintf(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
+ report(out_hnd,"Unknown 1a response: %x\n", unk_1a_response);
}
/* enum key */
- res2 = res2 ? do_reg_enum_val(smb_cli, &key_pol,
+ res2 = res2 ? reg_enum_val(&key_pol,
i, max_valnamelen, max_valbufsize,
val_name, &val_type, &value) : False;
if (res2)
{
- display_reg_value_info(out_hnd, ACTION_HEADER , val_name, val_type, &value);
- display_reg_value_info(out_hnd, ACTION_ENUMERATE, val_name, val_type, &value);
- display_reg_value_info(out_hnd, ACTION_FOOTER , val_name, val_type, &value);
+ reg_val_fn(full_keyname, val_name, val_type, &value);
}
}
+ if (res1 && reg_fn != NULL)
+ {
+ reg_fn(3, full_keyname, 0);
+ }
+
/* close the handles */
if ((*key_name) != 0)
{
- res1 = res1 ? do_reg_close(smb_cli, &key_pol) : False;
+ res1 = res1 ? reg_close(&key_pol) : False;
}
- res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? reg_close(&pol_con) : False;
if (res && res1 && res2)
{
- DEBUG(5,("cmd_reg_enum: query succeeded\n"));
+ DEBUG(5,("msrpc_reg_enum_key: query succeeded\n"));
}
else
{
- DEBUG(5,("cmd_reg_enum: query failed\n"));
+ DEBUG(5,("msrpc_reg_enum_key: query failed\n"));
+ }
+
+ return res1;
+}
+
+static void reg_display_key_info(const char *full_name,
+ const char *name, time_t key_mod_time)
+{
+ display_reg_key_info(out_hnd, ACTION_HEADER , name, key_mod_time);
+ display_reg_key_info(out_hnd, ACTION_ENUMERATE, name, key_mod_time);
+ display_reg_key_info(out_hnd, ACTION_FOOTER , name, key_mod_time);
+}
+
+static void reg_display_val_info(const char *full_name,
+ const char* name,
+ uint32 type,
+ const BUFFER2 *const value)
+{
+ display_reg_value_info(out_hnd, ACTION_HEADER , name, type, value);
+ display_reg_value_info(out_hnd, ACTION_ENUMERATE, name, type, value);
+ display_reg_value_info(out_hnd, ACTION_FOOTER , name, type, value);
+}
+
+/****************************************************************************
+nt registry enum
+****************************************************************************/
+void cmd_reg_enum(struct client_info *info, int argc, char *argv[])
+{
+ pstring full_keyname;
+
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (argc < 2)
+ {
+ report(out_hnd, "regenum <key_name>\n");
+ return;
+ }
+
+ split_server_keyname(srv_name, full_keyname, argv[1]);
+
+ (void)(msrpc_reg_enum_key(srv_name, full_keyname,
+ reg_display_key,
+ reg_display_key_info,
+ reg_display_val_info));
+}
+
+/****************************************************************************
+nt registry query value info
+****************************************************************************/
+void cmd_reg_query_info(struct client_info *info, int argc, char *argv[])
+{
+ BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+
+ POLICY_HND key_pol;
+ POLICY_HND pol_con;
+ pstring full_keyname;
+ fstring key_name;
+ fstring keyname;
+ fstring val_name;
+
+ /*
+ * query value info
+ */
+
+ BUFFER2 buf;
+ uint32 type;
+
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (argc < 2)
+ {
+ report(out_hnd, "regvalinfo value_name\n");
+ return;
+ }
+
+ split_server_keyname(srv_name, full_keyname, argv[1]);
+
+ reg_get_subkey(full_keyname, keyname, val_name);
+
+ if (keyname[0] == 0 || val_name[0] == 0)
+ {
+ report(out_hnd, "invalid value name\n");
+ return;
+ }
+
+ /* open registry receive a policy handle */
+ res = res ? reg_connect(srv_name, keyname, key_name, 0x02000000,
+ &pol_con) : False;
+
+ if ((*key_name) != 0)
+ {
+ /* open an entry */
+ res1 = res ? reg_open_entry(&pol_con,
+ key_name, 0x02000000, &key_pol) : False;
+ }
+ else
+ {
+ memcpy(&key_pol, &pol_con, sizeof(key_pol));
+ }
+
+ /* query it */
+ res2 = res1 ? reg_query_info(&key_pol,
+ val_name, &type, &buf) : False;
+
+ if (res2)
+ {
+ reg_display_val_info(full_keyname, val_name, type, &buf);
+ }
+
+ /* close the handles */
+ if ((*key_name) != 0)
+ {
+ res1 = res1 ? reg_close(&key_pol) : False;
+ }
+ res = res ? reg_close(&pol_con) : False;
+
+ if (res2)
+ {
+ DEBUG(5,("cmd_reg_query: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_reg_query: query failed\n"));
}
}
/****************************************************************************
nt registry query key
****************************************************************************/
-void cmd_reg_query_key(struct client_info *info)
+void cmd_reg_query_key(struct client_info *info, int argc, char *argv[])
{
BOOL res = True;
BOOL res1 = True;
POLICY_HND key_pol;
- fstring full_keyname;
+ POLICY_HND pol_con;
+ pstring full_keyname;
fstring key_name;
/*
@@ -249,34 +433,36 @@ void cmd_reg_query_key(struct client_info *info)
uint32 sec_desc;
NTTIME mod_time;
- DEBUG(5, ("cmd_reg_enum: smb_cli->fd:%d\n", smb_cli->fd));
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
- if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ if (argc < 2)
{
- fprintf(out_hnd, "regquery key_name\n");
+ report(out_hnd, "regquery key_name\n");
return;
}
- /* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
+ split_server_keyname(srv_name, full_keyname, argv[1]);
/* open registry receive a policy handle */
- res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
- &info->dom.reg_pol_connect) : False;
+ res = res ? reg_connect(srv_name, full_keyname, key_name, 0x02000000,
+ &pol_con) : False;
if ((*key_name) != 0)
{
/* open an entry */
- res1 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ res1 = res ? reg_open_entry(&pol_con,
key_name, 0x02000000, &key_pol) : False;
}
else
{
- memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
+ memcpy(&key_pol, &pol_con, sizeof(key_pol));
}
- res1 = res1 ? do_reg_query_key(smb_cli,
- &key_pol,
+ res1 = res1 ? reg_query_key(&key_pol,
key_class, &key_class_len,
&num_subkeys, &max_subkeylen, &max_subkeysize,
&num_values, &max_valnamelen, &max_valbufsize,
@@ -284,8 +470,7 @@ void cmd_reg_query_key(struct client_info *info)
if (res1 && key_class_len != 0)
{
- res1 = res1 ? do_reg_query_key(smb_cli,
- &key_pol,
+ res1 = res1 ? reg_query_key(&key_pol,
key_class, &key_class_len,
&num_subkeys, &max_subkeylen, &max_subkeysize,
&num_values, &max_valnamelen, &max_valbufsize,
@@ -294,23 +479,20 @@ void cmd_reg_query_key(struct client_info *info)
if (res1)
{
- fprintf(out_hnd,"Registry Query Info Key\n");
- fprintf(out_hnd,"key class: %s\n", key_class);
- fprintf(out_hnd,"subkeys, max_len, max_size: %d %d %d\n", num_subkeys, max_subkeylen, max_subkeysize);
- fprintf(out_hnd,"vals, max_len, max_size: 0x%x 0x%x 0x%x\n", num_values, max_valnamelen, max_valbufsize);
- fprintf(out_hnd,"sec desc: 0x%x\n", sec_desc);
- fprintf(out_hnd,"mod time: %s\n", http_timestring(nt_time_to_unix(&mod_time)));
+ report(out_hnd,"Registry Query Info Key\n");
+ report(out_hnd,"key class: %s\n", key_class);
+ report(out_hnd,"subkeys, max_len, max_size: %d %d %d\n", num_subkeys, max_subkeylen, max_subkeysize);
+ report(out_hnd,"vals, max_len, max_size: 0x%x 0x%x 0x%x\n", num_values, max_valnamelen, max_valbufsize);
+ report(out_hnd,"sec desc: 0x%x\n", sec_desc);
+ report(out_hnd,"mod time: %s\n", http_timestring(nt_time_to_unix(&mod_time)));
}
/* close the handles */
if ((*key_name) != 0)
{
- res1 = res1 ? do_reg_close(smb_cli, &key_pol) : False;
+ res1 = res1 ? reg_close(&key_pol) : False;
}
- res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? reg_close(&pol_con) : False;
if (res && res1)
{
@@ -325,18 +507,18 @@ void cmd_reg_query_key(struct client_info *info)
/****************************************************************************
nt registry create value
****************************************************************************/
-void cmd_reg_create_val(struct client_info *info)
+void cmd_reg_create_val(struct client_info *info, int argc, char *argv[])
{
BOOL res = True;
BOOL res3 = True;
BOOL res4 = True;
POLICY_HND parent_pol;
- fstring full_keyname;
+ POLICY_HND pol_con;
+ pstring full_keyname;
fstring keyname;
fstring parent_name;
fstring val_name;
- fstring tmp;
uint32 val_type;
BUFFER3 value;
@@ -344,75 +526,75 @@ void cmd_reg_create_val(struct client_info *info)
uint32 unk_0;
uint32 unk_1;
/* query it */
- res1 = res1 ? do_reg_query_info(smb_cli, &val_pol,
+ res1 = res1 ? reg_query_info(&val_pol,
type, &unk_0, &unk_1) : False;
#endif
- DEBUG(5, ("cmd_reg_create_val: smb_cli->fd:%d\n", smb_cli->fd));
+ fstring srv_name;
- if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (argc < 4)
{
- fprintf(out_hnd, "regcreate <val_name> <val_type> <val>\n");
+ report(out_hnd, "regcreate <val_name> <val_type (1|3|4)> <val>\n");
+ report(out_hnd, "(val_type 1=UNISTR, 3=BYTES, 4=DWORD supported\n");
return;
}
+ split_server_keyname(srv_name, full_keyname, argv[1]);
+
reg_get_subkey(full_keyname, keyname, val_name);
+ argc--;
+ argv++;
+
if (keyname[0] == 0 || val_name[0] == 0)
{
- fprintf(out_hnd, "invalid key name\n");
+ report(out_hnd, "invalid key name\n");
return;
}
- if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
+ if (argc < 2)
{
- fprintf(out_hnd, "regcreate <val_name> <val_type (1|4)> <val>\n");
return;
}
- val_type = atoi(tmp);
+ argc--;
+ argv++;
+
+ val_type = atoi(argv[0]);
if (val_type != 1 && val_type != 3 && val_type != 4)
{
- fprintf(out_hnd, "val_type 1=UNISTR, 3=BYTES, 4=DWORD supported\n");
+ report(out_hnd, "val_type 1=UNISTR, 3=BYTES, 4=DWORD supported\n");
return;
}
- if (!next_token(NULL, tmp, NULL, sizeof(tmp)))
- {
- fprintf(out_hnd, "regcreate <val_name> <val_type (1|4)> <val>\n");
- return;
- }
+ argc--;
+ argv++;
switch (val_type)
{
case 0x01: /* UNISTR */
{
- init_buffer3_str(&value, tmp, strlen(tmp)+1);
+ make_buffer3_str(&value, argv[0], strlen(argv[0])+1);
break;
}
case 0x03: /* BYTES */
{
- init_buffer3_hex(&value, tmp);
+ make_buffer3_hex(&value, argv[0]);
break;
}
case 0x04: /* DWORD */
{
- uint32 tmp_val;
- if (strnequal(tmp, "0x", 2))
- {
- tmp_val = strtol(tmp, (char**)NULL, 16);
- }
- else
- {
- tmp_val = strtol(tmp, (char**)NULL, 10);
- }
- init_buffer3_uint32(&value, tmp_val);
+ make_buffer3_uint32(&value, get_number(argv[0]));
break;
}
default:
{
- fprintf(out_hnd, "i told you i only deal with UNISTR, DWORD and BYTES!\n");
+ report(out_hnd, "i told you i only deal with UNISTR, DWORD and BYTES!\n");
return;
}
}
@@ -420,47 +602,41 @@ void cmd_reg_create_val(struct client_info *info)
DEBUG(10,("key data:\n"));
dump_data(10, (char *)value.buffer, value.buf_len);
- /* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
-
/* open registry receive a policy handle */
- res = res ? do_reg_connect(smb_cli, keyname, parent_name,
- &info->dom.reg_pol_connect) : False;
+ res = res ? reg_connect(srv_name, keyname, parent_name, 0x02000000,
+ &pol_con) : False;
if ((*val_name) != 0)
{
/* open an entry */
- res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ res3 = res ? reg_open_entry(&pol_con,
parent_name, 0x02000000, &parent_pol) : False;
}
else
{
- memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
+ memcpy(&parent_pol, &pol_con, sizeof(parent_pol));
}
/* create an entry */
- res4 = res3 ? do_reg_create_val(smb_cli, &parent_pol,
+ res4 = res3 ? reg_create_val(&parent_pol,
val_name, val_type, &value) : False;
/* flush the modified key */
- res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
+ res4 = res4 ? reg_flush_key(&parent_pol) : False;
/* close the val handle */
if ((*val_name) != 0)
{
- res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
+ res3 = res3 ? reg_close(&parent_pol) : False;
}
/* close the registry handles */
- res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? reg_close(&pol_con) : False;
if (res && res3 && res4)
{
DEBUG(5,("cmd_reg_create_val: query succeeded\n"));
- fprintf(out_hnd,"OK\n");
+ report(out_hnd,"OK\n");
}
else
{
@@ -471,71 +647,72 @@ void cmd_reg_create_val(struct client_info *info)
/****************************************************************************
nt registry delete value
****************************************************************************/
-void cmd_reg_delete_val(struct client_info *info)
+void cmd_reg_delete_val(struct client_info *info, int argc, char *argv[])
{
BOOL res = True;
BOOL res3 = True;
BOOL res4 = True;
POLICY_HND parent_pol;
- fstring full_keyname;
+ POLICY_HND pol_con;
+ pstring full_keyname;
fstring keyname;
fstring parent_name;
fstring val_name;
- DEBUG(5, ("cmd_reg_delete_val: smb_cli->fd:%d\n", smb_cli->fd));
+ fstring srv_name;
- if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (argc < 2)
{
- fprintf(out_hnd, "regdelete <val_name>\n");
+ report(out_hnd, "regdelete <val_name>\n");
return;
}
+ split_server_keyname(srv_name, full_keyname, argv[1]);
+
reg_get_subkey(full_keyname, keyname, val_name);
if (keyname[0] == 0 || val_name[0] == 0)
{
- fprintf(out_hnd, "invalid key name\n");
+ report(out_hnd, "invalid key name\n");
return;
}
- /* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
-
/* open registry receive a policy handle */
- res = res ? do_reg_connect(smb_cli, keyname, parent_name,
- &info->dom.reg_pol_connect) : False;
+ res = res ? reg_connect(srv_name, keyname, parent_name, 0x02000000,
+ &pol_con) : False;
if ((*val_name) != 0)
{
/* open an entry */
- res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ res3 = res ? reg_open_entry(&pol_con,
parent_name, 0x02000000, &parent_pol) : False;
}
else
{
- memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
+ memcpy(&parent_pol, &pol_con, sizeof(parent_pol));
}
/* delete an entry */
- res4 = res3 ? do_reg_delete_val(smb_cli, &parent_pol, val_name) : False;
+ res4 = res3 ? reg_delete_val(&parent_pol, val_name) : False;
/* flush the modified key */
- res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
+ res4 = res4 ? reg_flush_key(&parent_pol) : False;
/* close the key handle */
- res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
+ res3 = res3 ? reg_close(&parent_pol) : False;
/* close the registry handles */
- res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? reg_close(&pol_con) : False;
if (res && res3 && res4)
{
DEBUG(5,("cmd_reg_delete_val: query succeeded\n"));
- fprintf(out_hnd,"OK\n");
+ report(out_hnd,"OK\n");
}
else
{
@@ -546,74 +723,75 @@ void cmd_reg_delete_val(struct client_info *info)
/****************************************************************************
nt registry delete key
****************************************************************************/
-void cmd_reg_delete_key(struct client_info *info)
+void cmd_reg_delete_key(struct client_info *info, int argc, char *argv[])
{
BOOL res = True;
BOOL res3 = True;
BOOL res4 = True;
POLICY_HND parent_pol;
- fstring full_keyname;
+ POLICY_HND pol_con;
+ pstring full_keyname;
fstring parent_name;
fstring key_name;
fstring subkey_name;
- DEBUG(5, ("cmd_reg_delete_key: smb_cli->fd:%d\n", smb_cli->fd));
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
- if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ if (argc < 2)
{
- fprintf(out_hnd, "regdeletekey <key_name>\n");
+ report(out_hnd, "regdeletekey <key_name>\n");
return;
}
+ split_server_keyname(srv_name, full_keyname, argv[1]);
+
reg_get_subkey(full_keyname, parent_name, subkey_name);
if (parent_name[0] == 0 || subkey_name[0] == 0)
{
- fprintf(out_hnd, "invalid key name\n");
+ report(out_hnd, "invalid key name\n");
return;
}
- /* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
-
/* open registry receive a policy handle */
- res = res ? do_reg_connect(smb_cli, parent_name, key_name,
- &info->dom.reg_pol_connect) : False;
+ res = res ? reg_connect(srv_name, parent_name, key_name, 0x02000000,
+ &pol_con) : False;
if ((*key_name) != 0)
{
/* open an entry */
- res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ res3 = res ? reg_open_entry(&pol_con,
key_name, 0x02000000, &parent_pol) : False;
}
else
{
- memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
+ memcpy(&parent_pol, &pol_con, sizeof(parent_pol));
}
/* create an entry */
- res4 = res3 ? do_reg_delete_key(smb_cli, &parent_pol, subkey_name) : False;
+ res4 = res3 ? reg_delete_key(&parent_pol, subkey_name) : False;
/* flush the modified key */
- res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
+ res4 = res4 ? reg_flush_key(&parent_pol) : False;
/* close the key handle */
if ((*key_name) != 0)
{
- res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
+ res3 = res3 ? reg_close(&parent_pol) : False;
}
/* close the registry handles */
- res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? reg_close(&pol_con) : False;
if (res && res3 && res4)
{
DEBUG(5,("cmd_reg_delete_key: query succeeded\n"));
- fprintf(out_hnd,"OK\n");
+ report(out_hnd,"OK\n");
}
else
{
@@ -624,7 +802,7 @@ void cmd_reg_delete_key(struct client_info *info)
/****************************************************************************
nt registry create key
****************************************************************************/
-void cmd_reg_create_key(struct client_info *info)
+void cmd_reg_create_key(struct client_info *info, int argc, char *argv[])
{
BOOL res = True;
BOOL res3 = True;
@@ -632,30 +810,41 @@ void cmd_reg_create_key(struct client_info *info)
POLICY_HND parent_pol;
POLICY_HND key_pol;
- fstring full_keyname;
+ POLICY_HND pol_con;
+ pstring full_keyname;
fstring parent_key;
fstring parent_name;
fstring key_name;
fstring key_class;
SEC_ACCESS sam_access;
- DEBUG(5, ("cmd_reg_create_key: smb_cli->fd:%d\n", smb_cli->fd));
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
- if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ if (argc < 2)
{
- fprintf(out_hnd, "regcreate <key_name> [key_class]\n");
+ report(out_hnd, "regcreate <key_name> [key_class]\n");
return;
}
+ split_server_keyname(srv_name, full_keyname, argv[1]);
+
reg_get_subkey(full_keyname, parent_key, key_name);
if (parent_key[0] == 0 || key_name[0] == 0)
{
- fprintf(out_hnd, "invalid key name\n");
+ report(out_hnd, "invalid key name\n");
return;
}
- if (!next_token(NULL, key_class, NULL, sizeof(key_class)))
+ if (argc > 2)
+ {
+ fstrcpy(key_class, argv[2]);
+ }
+ else
{
memset(key_class, 0, sizeof(key_class));
}
@@ -663,50 +852,44 @@ void cmd_reg_create_key(struct client_info *info)
/* set access permissions */
sam_access.mask = SEC_RIGHTS_READ;
- /* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
-
/* open registry receive a policy handle */
- res = res ? do_reg_connect(smb_cli, parent_key, parent_name,
- &info->dom.reg_pol_connect) : False;
+ res = res ? reg_connect(srv_name, parent_key, parent_name, 0x02000000,
+ &pol_con) : False;
if ((*parent_name) != 0)
{
/* open an entry */
- res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ res3 = res ? reg_open_entry(&pol_con,
parent_name, 0x02000000, &parent_pol) : False;
}
else
{
- memcpy(&parent_pol, &info->dom.reg_pol_connect, sizeof(parent_pol));
+ memcpy(&parent_pol, &pol_con, sizeof(parent_pol));
}
/* create an entry */
- res4 = res3 ? do_reg_create_key(smb_cli, &parent_pol,
+ res4 = res3 ? reg_create_key(&parent_pol,
key_name, key_class, &sam_access, &key_pol) : False;
/* flush the modified key */
- res4 = res4 ? do_reg_flush_key(smb_cli, &parent_pol) : False;
+ res4 = res4 ? reg_flush_key(&parent_pol) : False;
/* close the key handle */
- res4 = res4 ? do_reg_close(smb_cli, &key_pol) : False;
+ res4 = res4 ? reg_close(&key_pol) : False;
/* close the key handle */
if ((*parent_name) != 0)
{
- res3 = res3 ? do_reg_close(smb_cli, &parent_pol) : False;
+ res3 = res3 ? reg_close(&parent_pol) : False;
}
/* close the registry handles */
- res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? reg_close(&pol_con) : False;
if (res && res3 && res4)
{
DEBUG(5,("cmd_reg_create_key: query succeeded\n"));
- fprintf(out_hnd,"OK\n");
+ report(out_hnd,"OK\n");
}
else
{
@@ -717,14 +900,15 @@ void cmd_reg_create_key(struct client_info *info)
/****************************************************************************
nt registry security info
****************************************************************************/
-void cmd_reg_test_key_sec(struct client_info *info)
+void cmd_reg_test_key_sec(struct client_info *info, int argc, char *argv[])
{
BOOL res = True;
BOOL res3 = True;
BOOL res4 = True;
POLICY_HND key_pol;
- fstring full_keyname;
+ POLICY_HND pol_con;
+ pstring full_keyname;
fstring key_name;
/*
@@ -732,76 +916,84 @@ void cmd_reg_test_key_sec(struct client_info *info)
*/
uint32 sec_buf_size;
- SEC_DESC_BUF *psdb;
+ SEC_DESC_BUF sec_buf;
+ uint32 sec_info = 0x7;
+
+ fstring srv_name;
- DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli->fd));
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
- if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ if (argc < 2)
{
- fprintf(out_hnd, "reggetsec <key_name>\n");
+ report(out_hnd, "regtestkeysec <key_name>\n");
return;
}
- /* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
+ split_server_keyname(srv_name, full_keyname, argv[1]);
/* open registry receive a policy handle */
- res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
- &info->dom.reg_pol_connect) : False;
+ res = res ? reg_connect(srv_name, full_keyname, key_name, 0x02000000,
+ &pol_con) : False;
if ((*key_name) != 0)
{
/* open an entry */
- res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ res3 = res ? reg_open_entry(&pol_con,
key_name, 0x02000000, &key_pol) : False;
}
else
{
- memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
+ memcpy(&key_pol, &pol_con, sizeof(key_pol));
}
/* open an entry */
- res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ res3 = res ? reg_open_entry(&pol_con,
key_name, 0x02000000, &key_pol) : False;
/* query key sec info. first call sets sec_buf_size. */
-
sec_buf_size = 0;
- res4 = res3 ? do_reg_get_key_sec(smb_cli, &key_pol,
- &sec_buf_size, &psdb) : False;
+ ZERO_STRUCT(sec_buf);
+
+ res4 = res3 ? reg_get_key_sec(&key_pol,
+ sec_info,
+ &sec_buf_size, &sec_buf) : False;
- free_sec_desc_buf(&psdb);
+ if (res4)
+ {
+ free_sec_desc_buf(&sec_buf);
+ }
- res4 = res4 ? do_reg_get_key_sec(smb_cli, &key_pol,
- &sec_buf_size, &psdb) : False;
+ res4 = res4 ? reg_get_key_sec(&key_pol,
+ sec_info,
+ &sec_buf_size, &sec_buf) : False;
- if (res4 && psdb->len > 0 && psdb->sec != NULL)
+ if (res4 && sec_buf.len > 0 && sec_buf.sec != NULL)
{
- display_sec_desc(out_hnd, ACTION_HEADER , psdb->sec);
- display_sec_desc(out_hnd, ACTION_ENUMERATE, psdb->sec);
- display_sec_desc(out_hnd, ACTION_FOOTER , psdb->sec);
+ display_sec_desc(out_hnd, ACTION_HEADER , sec_buf.sec);
+ display_sec_desc(out_hnd, ACTION_ENUMERATE, sec_buf.sec);
+ display_sec_desc(out_hnd, ACTION_FOOTER , sec_buf.sec);
- res4 = res4 ? do_reg_set_key_sec(smb_cli, &key_pol, psdb) : False;
- }
+ res4 = res4 ? reg_set_key_sec(&key_pol,
+ sec_info, sec_buf_size, sec_buf.sec) : False;
- free_sec_desc_buf(&psdb);
+ free_sec_desc_buf(&sec_buf);
+ }
/* close the key handle */
if ((*key_name) != 0)
{
- res3 = res3 ? do_reg_close(smb_cli, &key_pol) : False;
+ res3 = res3 ? reg_close(&key_pol) : False;
}
/* close the registry handles */
- res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? reg_close(&pol_con) : False;
if (res && res3 && res4)
{
DEBUG(5,("cmd_reg_test2: query succeeded\n"));
- fprintf(out_hnd,"Registry Test2\n");
+ report(out_hnd,"Registry Test2\n");
}
else
{
@@ -812,14 +1004,15 @@ void cmd_reg_test_key_sec(struct client_info *info)
/****************************************************************************
nt registry security info
****************************************************************************/
-void cmd_reg_get_key_sec(struct client_info *info)
+void cmd_reg_get_key_sec(struct client_info *info, int argc, char *argv[])
{
BOOL res = True;
BOOL res3 = True;
BOOL res4 = True;
POLICY_HND key_pol;
- fstring full_keyname;
+ POLICY_HND pol_con;
+ pstring full_keyname;
fstring key_name;
/*
@@ -827,68 +1020,76 @@ void cmd_reg_get_key_sec(struct client_info *info)
*/
uint32 sec_buf_size;
- SEC_DESC_BUF *psdb;
+ SEC_DESC_BUF sec_buf;
+ uint32 sec_info = 0x7;
+
+ fstring srv_name;
- DEBUG(5, ("cmd_reg_get_key_sec: smb_cli->fd:%d\n", smb_cli->fd));
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
- if (!next_token(NULL, full_keyname, NULL, sizeof(full_keyname)))
+ if (argc < 2)
{
- fprintf(out_hnd, "reggetsec <key_name>\n");
+ report(out_hnd, "reggetsec <key_name>\n");
return;
}
- /* open WINREG session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_WINREG) : False;
+ split_server_keyname(srv_name, full_keyname, argv[1]);
/* open registry receive a policy handle */
- res = res ? do_reg_connect(smb_cli, full_keyname, key_name,
- &info->dom.reg_pol_connect) : False;
+ res = res ? reg_connect(srv_name, full_keyname, key_name, 0x02000000,
+ &pol_con) : False;
if ((*key_name) != 0)
{
/* open an entry */
- res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ res3 = res ? reg_open_entry(&pol_con,
key_name, 0x02000000, &key_pol) : False;
}
else
{
- memcpy(&key_pol, &info->dom.reg_pol_connect, sizeof(key_pol));
+ memcpy(&key_pol, &pol_con, sizeof(key_pol));
}
/* open an entry */
- res3 = res ? do_reg_open_entry(smb_cli, &info->dom.reg_pol_connect,
+ res3 = res ? reg_open_entry(&pol_con,
key_name, 0x02000000, &key_pol) : False;
- /* Get the size. */
+ /* query key sec info. first call sets sec_buf_size. */
sec_buf_size = 0;
- res4 = res3 ? do_reg_get_key_sec(smb_cli, &key_pol,
- &sec_buf_size, &psdb) : False;
+ ZERO_STRUCT(sec_buf);
+
+ res4 = res3 ? reg_get_key_sec(&key_pol,
+ sec_info,
+ &sec_buf_size, &sec_buf) : False;
- free_sec_desc_buf(&psdb);
+ if (res4)
+ {
+ free_sec_desc_buf(&sec_buf);
+ }
- res4 = res4 ? do_reg_get_key_sec(smb_cli, &key_pol,
- &sec_buf_size, &psdb) : False;
+ res4 = res4 ? reg_get_key_sec(&key_pol,
+ sec_info,
+ &sec_buf_size, &sec_buf) : False;
- if (res4 && psdb->len > 0 && psdb->sec != NULL)
+ if (res4 && sec_buf.len > 0 && sec_buf.sec != NULL)
{
- display_sec_desc(out_hnd, ACTION_HEADER , psdb->sec);
- display_sec_desc(out_hnd, ACTION_ENUMERATE, psdb->sec);
- display_sec_desc(out_hnd, ACTION_FOOTER , psdb->sec);
- }
+ display_sec_desc(out_hnd, ACTION_HEADER , sec_buf.sec);
+ display_sec_desc(out_hnd, ACTION_ENUMERATE, sec_buf.sec);
+ display_sec_desc(out_hnd, ACTION_FOOTER , sec_buf.sec);
- free_sec_desc_buf(&psdb);
+ free(sec_buf.sec);
+ }
/* close the key handle */
if ((*key_name) != 0)
{
- res3 = res3 ? do_reg_close(smb_cli, &key_pol) : False;
+ res3 = res3 ? reg_close(&key_pol) : False;
}
/* close the registry handles */
- res = res ? do_reg_close(smb_cli, &info->dom.reg_pol_connect) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? reg_close(&pol_con) : False;
if (res && res3 && res4)
{
@@ -899,3 +1100,75 @@ void cmd_reg_get_key_sec(struct client_info *info)
DEBUG(5,("cmd_reg_get_key_sec: query failed\n"));
}
}
+
+/****************************************************************************
+nt registry shutdown
+****************************************************************************/
+void cmd_reg_shutdown(struct client_info *info, int argc, char *argv[])
+{
+ BOOL res = True;
+
+ fstring msg;
+ uint32 timeout = 20;
+ uint16 flgs = 0;
+ int opt;
+
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ while ((opt = getopt(argc, argv,"fim:t:r-")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'm':
+ {
+ safe_strcpy(msg, optarg, sizeof(msg)-1);
+ break;
+ }
+ case 't':
+ {
+ timeout = atoi(optarg);
+ break;
+ }
+ case 'r':
+ {
+ flgs |= 0x100;
+ break;
+ }
+ case 'f':
+ {
+ flgs |= 0x100;
+ break;
+ }
+ case '-':
+ {
+ if (strequal(optarg, "-reboot"))
+ {
+ flgs |= 0x100;
+ }
+ if (strequal(optarg, "-force-close"))
+ {
+ flgs |= 0x001;
+ }
+ break;
+ }
+ }
+ }
+
+ /* create an entry */
+ res = res ? reg_shutdown(srv_name, msg, timeout, flgs) : False;
+
+ if (res)
+ {
+ DEBUG(5,("cmd_reg_shutdown: query succeeded\n"));
+ report(out_hnd,"OK\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_reg_shutdown: query failed\n"));
+ report(out_hnd,"Failed\n");
+ }
+}
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index 023bf512e8a..874761644b8 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -2,8 +2,9 @@
Unix SMB/Netbios implementation.
Version 1.9.
NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1994-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Andrew Tridgell 1994-2000,
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ Copyright (C) Elrond 2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,35 +28,178 @@
#endif
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
+#include "rpcclient.h"
extern int DEBUGLEVEL;
#define DEBUG_TESTING
-extern struct cli_state *smb_cli;
+extern struct user_creds *usr_creds;
extern FILE* out_hnd;
+static void sam_display_domain(const char *domain)
+{
+ report(out_hnd, "Domain Name: %s\n", domain);
+}
+
+static void sam_display_dom_info(const char* domain, const DOM_SID *sid,
+ uint32 switch_value,
+ SAM_UNK_CTR *ctr)
+{
+ fstring sidstr;
+ sid_to_string(sidstr, sid);
+ report(out_hnd, "Domain Name:\t%s\tSID:\t%s\n", domain, sidstr);
+ display_sam_unk_ctr(out_hnd, ACTION_HEADER , switch_value, ctr);
+ display_sam_unk_ctr(out_hnd, ACTION_ENUMERATE, switch_value, ctr);
+ display_sam_unk_ctr(out_hnd, ACTION_FOOTER , switch_value, ctr);
+}
+
+static void sam_display_alias_info(const char *domain, const DOM_SID *sid,
+ uint32 alias_rid,
+ ALIAS_INFO_CTR *const ctr)
+{
+ display_alias_info_ctr(out_hnd, ACTION_HEADER , ctr);
+ display_alias_info_ctr(out_hnd, ACTION_ENUMERATE, ctr);
+ display_alias_info_ctr(out_hnd, ACTION_FOOTER , ctr);
+}
+
+static void sam_display_alias(const char *domain, const DOM_SID *sid,
+ uint32 alias_rid, const char *alias_name)
+{
+ report(out_hnd, "Alias RID: %8x Alias Name: %s\n",
+ alias_rid, alias_name);
+}
+
+static void sam_display_alias_members(const char *domain, const DOM_SID *sid,
+ uint32 alias_rid, const char *alias_name,
+ uint32 num_names,
+ DOM_SID *const *const sids,
+ char *const *const name,
+ uint32 *const type)
+{
+ display_alias_members(out_hnd, ACTION_HEADER , num_names, name, type);
+ display_alias_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
+ display_alias_members(out_hnd, ACTION_FOOTER , num_names, name, type);
+}
+
+static void sam_display_group_info(const char *domain, const DOM_SID *sid,
+ uint32 group_rid,
+ GROUP_INFO_CTR *const ctr)
+{
+ display_group_info_ctr(out_hnd, ACTION_HEADER , ctr);
+ display_group_info_ctr(out_hnd, ACTION_ENUMERATE, ctr);
+ display_group_info_ctr(out_hnd, ACTION_FOOTER , ctr);
+}
+
+static void sam_display_group(const char *domain, const DOM_SID *sid,
+ uint32 group_rid, const char *group_name)
+{
+ report(out_hnd, "Group RID: %8x Group Name: %s\n",
+ group_rid, group_name);
+}
+
+static void sam_display_group_members(const char *domain, const DOM_SID *sid,
+ uint32 group_rid, const char *group_name,
+ uint32 num_names,
+ const uint32 *rid_mem,
+ char *const *const name,
+ uint32 *const type)
+{
+ display_group_members(out_hnd, ACTION_HEADER , num_names, name, type);
+ display_group_members(out_hnd, ACTION_ENUMERATE, num_names, name, type);
+ display_group_members(out_hnd, ACTION_FOOTER , num_names, name, type);
+}
+
+static void sam_display_user_info(const char *domain, const DOM_SID *sid,
+ uint32 user_rid,
+ SAM_USERINFO_CTR *const ctr)
+{
+ if (ctr->switch_value == 21)
+ {
+ SAM_USER_INFO_21 *const usr = ctr->info.id21;
+ display_sam_user_info_21(out_hnd, ACTION_HEADER , usr);
+ display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, usr);
+ display_sam_user_info_21(out_hnd, ACTION_FOOTER , usr);
+ }
+}
+
+static void sam_display_user(const char *domain, const DOM_SID *sid,
+ uint32 user_rid, const char *user_name)
+{
+ report(out_hnd, "User RID: %8x User Name: %s\n",
+ user_rid, user_name);
+}
+
/****************************************************************************
SAM password change
****************************************************************************/
-void cmd_sam_ntchange_pwd(struct client_info *info)
+void cmd_sam_ntchange_pwd(struct client_info *info, int argc, char *argv[])
{
fstring srv_name;
- fstring domain;
- fstring sid;
char *new_passwd;
- BOOL res = True;
- char nt_newpass[516];
- uchar nt_hshhash[16];
- uchar nt_newhash[16];
+ char *new_passwd2;
uchar nt_oldhash[16];
- char lm_newpass[516];
- uchar lm_newhash[16];
- uchar lm_hshhash[16];
uchar lm_oldhash[16];
+ fstring acct_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ report(out_hnd, "SAM NT Password Change\n");
+
+ if (argc >= 2)
+ {
+ struct pwd_info old_pwd;
+ safe_strcpy(acct_name, argv[1], sizeof(acct_name));
+ pwd_read(&old_pwd, "Old Password:", True);
+ pwd_get_lm_nt_16(&old_pwd, lm_oldhash, nt_oldhash );
+ }
+ else
+ {
+ safe_strcpy(acct_name, usr_creds->ntc.user_name, sizeof(acct_name));
+ pwd_get_lm_nt_16(&(usr_creds->ntc.pwd), lm_oldhash, nt_oldhash );
+ }
+
+ new_passwd = (char*)getpass("New Password: ");
+ new_passwd2 = (char*)getpass("retype: ");
+
+ if ((new_passwd != NULL && new_passwd2 != NULL &&
+ !strequal(new_passwd, new_passwd2)) ||
+ (new_passwd != new_passwd2))
+ {
+ report(out_hnd, "New passwords differ!\n");
+ return;
+ }
+
+ /* establish a connection. */
+ if (msrpc_sam_ntchange_pwd( srv_name, NULL, acct_name,
+ lm_oldhash, nt_oldhash,
+ new_passwd))
+ {
+ report(out_hnd, "NT Password changed OK\n");
+ }
+ else
+ {
+ report(out_hnd, "NT Password change FAILED\n");
+ }
+}
+
+
+/****************************************************************************
+experimental SAM encryted rpc test connection
+****************************************************************************/
+void cmd_sam_test(struct client_info *info, int argc, char *argv[])
+{
+ struct cli_connection *con = NULL;
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ BOOL res = True;
sid_to_string(sid, &info->dom.level5_sid);
fstrcpy(domain, info->dom.level5_dom);
@@ -64,23 +208,9 @@ void cmd_sam_ntchange_pwd(struct client_info *info)
fstrcat(srv_name, info->dest_host);
strupper(srv_name);
- fprintf(out_hnd, "SAM NT Password Change\n");
+ report(out_hnd, "SAM Encryption Test\n");
-#if 0
- struct pwd_info new_pwd;
- pwd_read(&new_pwd, "New Password (ONCE: this is test code!):", True);
-#endif
- new_passwd = (char*)getpass("New Password (ONCE ONLY - get it right :-)");
-
- nt_lm_owf_gen(new_passwd, lm_newhash, nt_newhash);
- pwd_get_lm_nt_16(&(smb_cli->pwd), lm_oldhash, nt_oldhash );
- make_oem_passwd_hash(nt_newpass, new_passwd, nt_oldhash, True);
- make_oem_passwd_hash(lm_newpass, new_passwd, lm_oldhash, True);
- E_old_pw_hash(lm_newhash, lm_oldhash, lm_hshhash);
- E_old_pw_hash(lm_newhash, nt_oldhash, nt_hshhash);
-
- cli_nt_set_ntlmssp_flgs(smb_cli,
- NTLMSSP_NEGOTIATE_UNICODE |
+ usr_creds->ntc.ntlmssp_flags = NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_OEM |
NTLMSSP_NEGOTIATE_SIGN |
NTLMSSP_NEGOTIATE_SEAL |
@@ -88,593 +218,2970 @@ void cmd_sam_ntchange_pwd(struct client_info *info)
NTLMSSP_NEGOTIATE_NTLM |
NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
NTLMSSP_NEGOTIATE_00001000 |
- NTLMSSP_NEGOTIATE_00002000);
+ NTLMSSP_NEGOTIATE_00002000;
/* open SAMR session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+ res = res ? cli_connection_init(srv_name, PIPE_SAMR, &con) : False;
- /* establish a connection. */
- res = res ? do_samr_unknown_38(smb_cli, srv_name) : False;
+ /* close the session */
+ cli_connection_unlink(con);
+
+ if (res)
+ {
+ DEBUG(5,("cmd_sam_test: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_test: failed\n"));
+ }
+}
+
+/****************************************************************************
+Lookup domain in SAM server.
+****************************************************************************/
+void cmd_sam_lookup_domain(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ char *domain;
+ fstring str_sid;
+ DOM_SID dom_sid;
+ BOOL res = True;
+ POLICY_HND sam_pol;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (argc < 2)
+ {
+ report(out_hnd, "lookupdomain: <name>\n");
+ return;
+ }
+
+ domain = argv[1];
+ strupper(domain);
+
+ report(out_hnd, "Lookup Domain %s in SAM Server\n", domain);
/* establish a connection. */
- res = res ? do_samr_chgpasswd_user(smb_cli,
- srv_name, smb_cli->user_name,
- nt_newpass, nt_hshhash,
- lm_newpass, lm_hshhash) : False;
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? samr_connect( srv_name, 0x02000000, &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_query_lookup_domain( &sam_pol, domain, &dom_sid) : False;
+
+ res = res ? samr_close(&sam_pol) : False;
if (res)
{
- fprintf(out_hnd, "NT Password changed OK\n");
+ DEBUG(5,("cmd_sam_lookup_domain: succeeded\n"));
+
+ sid_to_string(str_sid, &dom_sid);
+ report(out_hnd, "Domain:\t%s\tSID:\t%s\n", domain, str_sid);
}
else
{
- fprintf(out_hnd, "NT Password change FAILED\n");
+ DEBUG(5,("cmd_sam_lookup_domain: failed\n"));
+ report(out_hnd, "Lookup Domain: FAILED\n");
}
}
+/****************************************************************************
+Lookup names in SAM server.
+****************************************************************************/
+static void fill_domain_sid(const char *srv_name,
+ const char *new_domain, char *domain,
+ DOM_SID *sid)
+{
+ uint32 ret;
+ DOM_SID new_sid;
+ fstring temp;
+
+ ret = lookup_sam_domainname(srv_name, new_domain,
+ &new_sid);
+
+ if (ret != 0x0)
+ {
+ report(out_hnd, "Domain %s: %s\n",
+ new_domain, get_nt_error_msg(ret));
+ }
+ else
+ {
+ sid_copy(sid, &new_sid);
+ fstrcpy(domain, new_domain);
+ }
+
+ sid_to_string(temp, sid);
+ DEBUG(3, ("Using Domain-SID: %s\n", temp));
+}
/****************************************************************************
-experimental SAM encryted rpc test connection
+Lookup names in SAM server.
****************************************************************************/
-void cmd_sam_test(struct client_info *info)
+void cmd_sam_lookup_names(struct client_info *info, int argc, char *argv[])
+{
+ int opt;
+ fstring srv_name;
+ fstring domain;
+ DOM_SID sid_dom;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ BOOL res = True, res1 = True;
+ POLICY_HND pol_sam;
+ POLICY_HND pol_dom;
+ int num_names;
+ char **names;
+ uint32 num_rids, i;
+ uint32 *rids = NULL;
+ uint32 *types = NULL;
+
+ sid_copy(&sid_dom, &info->dom.level5_sid);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (argc < 2)
+ {
+ report(out_hnd, "samlookupnames [-d <domain>] <name> [<name> ...]\n");
+ return;
+ }
+
+ while ((opt = getopt(argc, argv, "d:")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'd':
+ {
+ fill_domain_sid(srv_name, optarg,
+ domain, &sid_dom);
+ break;
+ }
+ }
+ }
+
+ if (sid_dom.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid_dom) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ report(out_hnd, "SAM Lookup Names\n");
+
+ argc -= optind;
+ argv += optind;
+
+ num_names = argc;
+ names = (char **) argv;
+
+ if (num_names <= 0)
+ {
+ report(out_hnd, "samlookupnames [-d <domain>] <name> [<name> ...]\n");
+ return;
+ }
+
+ /* establish a connection. */
+ res = res ? samr_connect(srv_name, 0x02000000, &pol_sam) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain(&pol_sam, ace_perms, &sid_dom,
+ &pol_dom) : False;
+
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x000003e8,
+ num_names, names,
+ &num_rids, &rids, &types) : False;
+
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&pol_sam) : False;
+
+ if (res1)
+ {
+ DEBUG(5,("cmd_sam_lookup_names: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_lookup_names: query failed\n"));
+ }
+
+ if (res1)
+ {
+ for (i = 0; i < num_rids; i++)
+ {
+ report(out_hnd, "RID: %s -> %d (%d: %s)\n",
+ names[i], rids[i], types[i],
+ get_sid_name_use_str(types[i]));
+ }
+ }
+
+ safe_free(rids);
+ safe_free(types);
+}
+
+/****************************************************************************
+Lookup rids in SAM server.
+****************************************************************************/
+void cmd_sam_lookup_rids(struct client_info *info, int argc, char *argv[])
+{
+ int opt;
+ fstring srv_name;
+ fstring domain;
+ DOM_SID sid_dom;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ BOOL res = True, res1 = True;
+ POLICY_HND pol_sam;
+ POLICY_HND pol_dom;
+ int num_names = 0;
+ char **names = NULL;
+ uint32 num_rids, i;
+ uint32 *rids = NULL;
+ uint32 *types = NULL;
+
+ sid_copy(&sid_dom, &info->dom.level5_sid);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (argc < 2)
+ {
+ report(out_hnd, "samlookupnames [-d <domain>] <name> [<name> ...]\n");
+ return;
+ }
+
+ while ((opt = getopt(argc, argv, "d:")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'd':
+ {
+ fill_domain_sid(srv_name, optarg,
+ domain, &sid_dom);
+ break;
+ }
+ }
+ }
+
+ if (sid_dom.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid_dom) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ report(out_hnd, "SAM Lookup Rids\n");
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc <= 0)
+ {
+ report(out_hnd, "samlookuprids [-d <domain>] <rid> [<rid> ...]\n");
+ return;
+ }
+
+ num_rids = 0;
+
+ while (num_rids < argc)
+ {
+ rids = Realloc(rids, sizeof(rids[0]) * (num_rids+1));
+ if (rids == NULL)
+ {
+ return;
+ }
+ rids[num_rids] = get_number(argv[num_rids]);
+ num_rids++;
+ }
+
+ /* establish a connection. */
+ res = res ? samr_connect(srv_name, 0x02000000, &pol_sam) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain(&pol_sam, ace_perms, &sid_dom,
+ &pol_dom) : False;
+
+ res1 = res ? samr_query_lookup_rids( &pol_dom, 0x000003e8,
+ num_rids, rids,
+ &num_names, &names, &types) : False;
+
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&pol_sam) : False;
+
+ if (res1)
+ {
+ DEBUG(5,("cmd_sam_lookup_rids: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_lookup_rids: query failed\n"));
+ }
+
+ if (res1)
+ {
+ for (i = 0; i < num_names; i++)
+ {
+ report(out_hnd, "Name: %s -> %d (%d: %s)\n",
+ names[i], rids[i], types[i],
+ get_sid_name_use_str(types[i]));
+ }
+ }
+
+ safe_free(rids);
+ safe_free(types);
+
+ free_char_array(num_names, names);
+}
+
+/****************************************************************************
+SAM delete alias member.
+****************************************************************************/
+void cmd_sam_del_aliasmem(struct client_info *info, int argc, char *argv[])
{
fstring srv_name;
fstring domain;
fstring sid;
+ DOM_SID sid1;
+ POLICY_HND alias_pol;
BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ DOM_SID member_sid;
+ uint32 alias_rid;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
- sid_to_string(sid, &info->dom.level5_sid);
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
fstrcpy(domain, info->dom.level5_dom);
-/*
- if (strlen(sid) == 0)
+ if (sid1.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
{
- fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ report(out_hnd, "delaliasmem: <alias rid> [member sid1] [member sid2] ...\n");
return;
}
-*/
+
+ argc--;
+ argv++;
+
+ alias_rid = get_number(argv[0]);
+
+ report(out_hnd, "SAM Domain Alias Member\n");
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
+ &pol_dom) : False;
+
+ /* connect to the domain */
+ res1 = res ? samr_open_alias( &pol_dom,
+ 0x000f001f, alias_rid, &alias_pol) : False;
+
+ while (argc > 0 && res2 && res1)
+ {
+ argc--;
+ argv++;
+ /* get a sid, delete a member from the alias */
+ res2 = res2 ? string_to_sid(&member_sid, argv[0]) : False;
+ res2 = res2 ? samr_del_aliasmem(&alias_pol, &member_sid) : False;
+
+ if (res2)
+ {
+ report(out_hnd, "SID deleted from Alias 0x%x: %s\n", alias_rid, argv[0]);
+ }
+ }
+
+ res1 = res1 ? samr_close(&alias_pol) : False;
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (res && res1 && res2)
+ {
+ DEBUG(5,("cmd_sam_del_aliasmem: succeeded\n"));
+ report(out_hnd, "Delete Domain Alias Member: OK\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_del_aliasmem: failed\n"));
+ report(out_hnd, "Delete Domain Alias Member: FAILED\n");
+ }
+}
+
+/****************************************************************************
+SAM delete alias.
+****************************************************************************/
+void cmd_sam_delete_dom_alias(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ char *name;
+ fstring sid;
+ DOM_SID sid1;
+ POLICY_HND alias_pol;
+ BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ uint32 alias_rid = 0;
+ char *names[1];
+ uint32 *rids;
+ uint32 *types;
+ uint32 num_rids;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
fstrcpy(srv_name, "\\\\");
fstrcat(srv_name, info->dest_host);
strupper(srv_name);
- fprintf(out_hnd, "SAM Encryption Test\n");
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, info->dom.level5_dom);
- cli_nt_set_ntlmssp_flgs(smb_cli,
- NTLMSSP_NEGOTIATE_UNICODE |
- NTLMSSP_NEGOTIATE_OEM |
- NTLMSSP_NEGOTIATE_SIGN |
- NTLMSSP_NEGOTIATE_SEAL |
- NTLMSSP_NEGOTIATE_LM_KEY |
- NTLMSSP_NEGOTIATE_NTLM |
- NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
- NTLMSSP_NEGOTIATE_00001000 |
- NTLMSSP_NEGOTIATE_00002000);
+ if (sid1.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
- /* open SAMR session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+ if (argc < 2)
+ {
+ report(out_hnd, "delalias <alias name>\n");
+ return;
+ }
+
+ name = argv[1];
+
+ report(out_hnd, "SAM Delete Domain Alias\n");
/* establish a connection. */
- res = res ? do_samr_unknown_38(smb_cli, srv_name) : False;
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
- /* close the session */
- cli_nt_session_close(smb_cli);
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
+ &pol_dom) : False;
- if (res)
+ names[0] = name;
+
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x000003e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+
+ if (res1 && num_rids == 1 && rids)
{
- DEBUG(5,("cmd_sam_test: succeeded\n"));
+ alias_rid = rids[0];
+ }
+ if (rids)
+ {
+ free(rids);
+ }
+ if (types)
+ {
+ free(types);
+ }
+
+ /* connect to the domain */
+ res1 = res1 ? samr_open_alias( &pol_dom,
+ 0x00f001f, alias_rid, &alias_pol) : False;
+
+ res2 = res1 ? samr_delete_dom_alias(&alias_pol) : False;
+
+ res1 = res1 ? samr_close(&alias_pol) : False;
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (res && res1 && res2)
+ {
+ DEBUG(5,("cmd_sam_delete_dom_alias: succeeded\n"));
+ report(out_hnd, "Delete Domain Alias: OK\n");
}
else
{
- DEBUG(5,("cmd_sam_test: failed\n"));
+ DEBUG(5,("cmd_sam_delete_dom_alias: failed\n"));
+ report(out_hnd, "Delete Domain Alias: FAILED\n");
}
}
-
/****************************************************************************
-experimental SAM users enum.
+SAM add alias member.
****************************************************************************/
-void cmd_sam_enum_users(struct client_info *info)
+void cmd_sam_add_aliasmem(struct client_info *info, int argc, char *argv[])
{
fstring srv_name;
fstring domain;
+ fstring tmp;
fstring sid;
DOM_SID sid1;
- int user_idx;
+ POLICY_HND alias_pol;
BOOL res = True;
- BOOL request_user_info = False;
- BOOL request_group_info = False;
- uint16 num_entries = 0;
- uint16 unk_0 = 0x0;
- uint16 acb_mask = 0;
- uint16 unk_1 = 0x0;
- uint32 admin_rid = 0x304; /* absolutely no idea. */
- fstring tmp;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ BOOL res3 = True;
+ BOOL res4 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ uint32 alias_rid;
+ char **names = NULL;
+ int num_names = 0;
+ DOM_SID *sids = NULL;
+ int num_sids = 0;
+ int i;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ POLICY_HND lsa_pol;
- sid_to_string(sid, &info->dom.level5_sid);
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
fstrcpy(domain, info->dom.level5_dom);
- if (strlen(sid) == 0)
+ if (sid1.num_auths == 0)
{
- fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
+ {
+ report(out_hnd, "addaliasmem <group name> [member name1] [member name2] ...\n");
return;
}
+
+ num_names = argc+1;
+ names = argv+1;
- init_dom_sid(&sid1, sid);
+ report(out_hnd, "SAM Domain Alias Member\n");
+
+ /* lookup domain controller; receive a policy handle */
+ res3 = res3 ? lsa_open_policy(srv_name,
+ &lsa_pol, True, 0x02000000) : False;
+
+ /* send lsa lookup sids call */
+ res4 = res3 ? lsa_lookup_names(&lsa_pol,
+ num_names, names,
+ &sids, NULL, &num_sids) : False;
+
+ res3 = res3 ? lsa_close(&lsa_pol) : False;
+
+ res4 = num_sids < 2 ? False : res4;
+
+ if (res4)
+ {
+ /*
+ * accept domain sid or builtin sid
+ */
+
+ DOM_SID sid_1_5_20;
+ string_to_sid(&sid_1_5_20, "S-1-5-32");
+ sid_split_rid(&sids[0], &alias_rid);
+
+ if (sid_equal(&sids[0], &sid_1_5_20))
+ {
+ sid_copy(&sid1, &sid_1_5_20);
+ }
+ else if (!sid_equal(&sids[0], &sid1))
+ {
+ res4 = False;
+ }
+ }
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
+ &pol_dom) : False;
+
+ /* connect to the domain */
+ res1 = res ? samr_open_alias( &pol_dom,
+ 0x000f001f, alias_rid, &alias_pol) : False;
+
+ for (i = 1; i < num_sids && res2 && res1; i++)
+ {
+ /* add a member to the alias */
+ res2 = res2 ? samr_add_aliasmem(&alias_pol, &sids[i]) : False;
+
+ if (res2)
+ {
+ sid_to_string(tmp, &sids[i]);
+ report(out_hnd, "SID added to Alias 0x%x: %s\n", alias_rid, tmp);
+ }
+ }
+
+ res1 = res1 ? samr_close(&alias_pol) : False;
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (sids != NULL)
+ {
+ free(sids);
+ }
+
+ free_char_array(num_names, names);
+
+ if (res && res1 && res2)
+ {
+ DEBUG(5,("cmd_sam_add_aliasmem: succeeded\n"));
+ report(out_hnd, "Add Domain Alias Member: OK\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_add_aliasmem: failed\n"));
+ report(out_hnd, "Add Domain Alias Member: FAILED\n");
+ }
+}
+
+
+#if 0
+/****************************************************************************
+SAM create domain user.
+****************************************************************************/
+void cmd_sam_create_dom_trusting(struct client_info *info, int argc, char *argv[])
+{
+ fstring local_domain;
+ fstring local_pdc;
+
+ char *trusting_domain;
+ char *trusting_pdc;
+ fstring password;
+
+ fstring sid;
+ DOM_SID sid1;
+ uint32 user_rid;
fstrcpy(srv_name, "\\\\");
fstrcat(srv_name, info->dest_host);
strupper(srv_name);
- /* a bad way to do token parsing... */
- if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (sid1.num_auths == 0)
{
- request_user_info |= strequal(tmp, "-u");
- request_group_info |= strequal(tmp, "-g");
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
}
- if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ if (argc < 3)
{
- request_user_info |= strequal(tmp, "-u");
- request_group_info |= strequal(tmp, "-g");
+ report(out_hnd, "createtrusting: <Domain Name> <PDC Name> [password]\n");
+ return;
}
-#ifdef DEBUG_TESTING
- if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ argc--;
+ argv++;
+
+ trusting_domain = argv[0];
+
+ argc--;
+ argv++;
+
+ trusting_pdc = argv[0];
+
+ argc--;
+ argv++;
+
+ if (argc > 0)
{
- num_entries = (uint16)strtol(tmp, (char**)NULL, 16);
+ safe_strcpy(password, argv[0], sizeof(password)-1);
}
+ else
+ {
+ fstring pass_str;
+ char *pass;
+ slprintf(pass_str, sizeof(pass_str)-1, "Enter %s's Password:",
+ user_name);
+ pass = (char*)getpass(pass_str);
- if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ if (pass != NULL)
+ {
+ safe_strcpy(password, pass, sizeof(password)-1);
+ set_passwd = True;
+ }
+ }
+ report(out_hnd, "SAM Create Domain Trusting Account\n");
+
+ if (msrpc_sam_create_dom_user(srv_name,
+ acct_name, ACB_WSTRUST, &user_rid))
+ {
+ report(out_hnd, "Create Domain User: OK\n");
+ }
+ else
{
- unk_0 = (uint16)strtol(tmp, (char**)NULL, 16);
+ report(out_hnd, "Create Domain User: FAILED\n");
}
+}
+#endif
- if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+/****************************************************************************
+SAM create domain user.
+****************************************************************************/
+void cmd_sam_create_dom_user(struct client_info *info, int argc, char *argv[])
+{
+ fstring domain;
+ fstring acct_name;
+ fstring name;
+ fstring sid;
+ DOM_SID sid1;
+ uint32 user_rid;
+ uint16 acb_info = ACB_NORMAL;
+ BOOL join_domain = False;
+ int opt;
+ char *password = NULL;
+ int plen = 0;
+ int len = 0;
+ UNISTR2 upw;
+
+ BOOL res = True;
+ POLICY_HND lsa_pol;
+
+ fstring wks_name;
+
+ fstring srv_name;
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (sid1.num_auths == 0)
{
- acb_mask = (uint16)strtol(tmp, (char**)NULL, 16);
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
}
- if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ if (argc < 2)
{
- unk_1 = (uint16)strtol(tmp, (char**)NULL, 16);
+ report(out_hnd, "createuser: <acct name> [-i] [-s] [-j] [-p password]\n");
+ return;
}
-#endif
- fprintf(out_hnd, "SAM Enumerate Users\n");
- fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
- info->myhostname, srv_name, domain, sid);
+ argc--;
+ argv++;
-#ifdef DEBUG_TESTING
- DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
- num_entries, unk_0, acb_mask, unk_1));
-#endif
+ safe_strcpy(acct_name, argv[0], sizeof(acct_name));
+ len = strlen(acct_name)-1;
+ if (acct_name[len] == '$')
+ {
+ safe_strcpy(name, argv[0], sizeof(name));
+ name[len] = 0;
+ acb_info = ACB_WSTRUST;
+ }
- /* open SAMR session. negotiate credentials */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+ while ((opt = getopt(argc, argv,"isjp:w:")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'i':
+ {
+ acb_info = ACB_DOMTRUST;
+ break;
+ }
+ case 's':
+ {
+ acb_info = ACB_SVRTRUST;
+ break;
+ }
+ case 'j':
+ {
+ join_domain = True;
+ break;
+ }
+ case 'p':
+ {
+ fstring pwd;
+ safe_strcpy(pwd, optarg, sizeof(pwd)-1);
+ make_unistr2(&upw, pwd, strlen(pwd));
+ password = (char*)upw.buffer;
+ plen = upw.uni_str_len * 2;
+ memset(pwd, 0, sizeof(pwd));
+ break;
+ }
+ }
+ }
- /* establish a connection. */
- res = res ? do_samr_connect(smb_cli,
- srv_name, 0x00000020,
- &info->dom.samr_pol_connect) : False;
+ /*
+ * sort out the workstation name. if it's ourselves, and we're
+ * on MSRPC local loopback, must _also_ connect to workstation
+ * local-loopback.
+ */
- /* connect to the domain */
- res = res ? do_samr_open_domain(smb_cli,
- &info->dom.samr_pol_connect, admin_rid, &sid1,
- &info->dom.samr_pol_open_domain) : False;
+ DEBUG(10,("create_dom_user: myhostname: %s server: %s\n",
+ info->myhostname, name));
- /* read some users */
- res = res ? do_samr_enum_dom_users(smb_cli,
- &info->dom.samr_pol_open_domain,
- num_entries, unk_0, acb_mask, unk_1, 0xffff,
- &info->dom.sam, &info->dom.num_sam_entries) : False;
+ fstrcpy(wks_name, "\\\\");
+ if (strequal(srv_name, "\\\\.") && strequal(name, info->myhostname))
+ {
+ fstrcat(wks_name, ".");
+ }
+ else
+ {
+ fstrcat(wks_name, name);
+ }
+ strupper(wks_name);
- if (res && info->dom.num_sam_entries == 0)
+ if (join_domain && acb_info == ACB_NORMAL)
{
- fprintf(out_hnd, "No users\n");
+ report(out_hnd, "can only join trust accounts to a domain\n");
+ return;
}
- if (request_user_info || request_group_info)
+ report(out_hnd, "SAM Create Domain User\n");
+ report(out_hnd, "Domain: %s Name: %s ACB: %s\n",
+ domain, acct_name,
+ pwdb_encode_acct_ctrl(acb_info, NEW_PW_FORMAT_SPACE_PADDED_LEN));
+
+ if (acb_info == ACB_WSTRUST || acb_info == ACB_SVRTRUST)
{
- /* query all the users */
- user_idx = 0;
+#if 0
+ uint8 rnd_data[512];
+ int i, j;
+#endif
- while (res && user_idx < info->dom.num_sam_entries)
+ if (password != NULL)
{
- uint32 user_rid = info->dom.sam[user_idx].smb_userid;
- SAM_USER_INFO_21 usr;
+ report(out_hnd,("Workstation and Server Trust Accounts are randomly auto-generated\n"));
+ memset(&upw, 0, sizeof(upw));
+ return;
+ }
- fprintf(out_hnd, "User RID: %8x User Name: %s\n",
- user_rid,
- info->dom.sam[user_idx].acct_name);
+ upw.uni_str_len = 0xc;
+ upw.uni_max_len = 0xc;
+#if 0
+ upw.uni_str_len = 0x78;
+ upw.uni_max_len = 0x78;
+ generate_random_buffer(rnd_data, sizeof(rnd_data), True);
+ for (j = 0, i = 0; i < 0x78 && j < sizeof(rnd_data); j++,i++)
+ {
+ for (; j < sizeof(rnd_data) && rnd_data[j] == 0; j++)
+ {
+ }
+
+ upw.buffer[i] = rnd_data[j];
+ }
+#endif
+ password = (char*)upw.buffer;
+ plen = upw.uni_str_len * 2;
+ generate_random_buffer(password, plen, True);
+ }
+
+ if (join_domain)
+ {
+ /*
+ * ok. this looks really weird, but if you don't open
+ * the connection to the workstation first, then the
+ * set trust account on the SAM database may get the
+ * local copy-of trust account out-of-sync with the
+ * remote one, and you're stuffed!
+ */
+ res = lsa_open_policy( wks_name, &lsa_pol, True, 0x02000000);
+
+ if (!res)
+ {
+ report(out_hnd, "Connection to %s FAILED\n", wks_name);
+ report(out_hnd, "(Do a \"use \\\\%s -U localadmin\")\n",
+ wks_name);
+ }
+ }
- if (request_user_info)
+ if (res && msrpc_sam_create_dom_user(srv_name, &sid1,
+ acct_name, acb_info, password, plen,
+ &user_rid))
+ {
+ report(out_hnd, "Create Domain User: OK\n");
+
+ if (join_domain)
+ {
+ POLICY_HND pol_sec;
+ BOOL res1;
+ BOOL res2 = False;
+
+ uchar ntpw[16];
+
+ nt_owf_genW(&upw, ntpw);
+
+ strupper(domain);
+ strupper(name);
+
+ report(out_hnd, "Join %s to Domain %s\n", name, domain);
+
+ /* attempt to create, and if already exist, open */
+ res1 = lsa_create_secret( &lsa_pol, "$MACHINE.ACC",
+ 0x020003, &pol_sec);
+
+ if (res1)
{
- /* send user info query, level 0x15 */
- if (get_samr_query_userinfo(smb_cli,
- &info->dom.samr_pol_open_domain,
- 0x15, user_rid, &usr))
- {
- display_sam_user_info_21(out_hnd, ACTION_HEADER , &usr);
- display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
- display_sam_user_info_21(out_hnd, ACTION_FOOTER , &usr);
- }
+ report(out_hnd, "Create $MACHINE.ACC: OK\n");
}
+ else
+ {
+ res1 = lsa_open_secret( &lsa_pol,
+ "$MACHINE.ACC",
+ 0x020003, &pol_sec);
- if (request_group_info)
+ }
+
+ /* valid pol_sec on $MACHINE.ACC, set trust passwd */
+ if (res1)
{
- uint32 num_groups;
- DOM_GID gid[LSA_MAX_GROUPS];
+ STRING2 secret;
+ secret_store_data(&secret, password, plen);
- /* send user group query */
- if (get_samr_query_usergroups(smb_cli,
- &info->dom.samr_pol_open_domain,
- user_rid, &num_groups, gid))
- {
- display_group_rid_info(out_hnd, ACTION_HEADER , num_groups, gid);
- display_group_rid_info(out_hnd, ACTION_ENUMERATE, num_groups, gid);
- display_group_rid_info(out_hnd, ACTION_FOOTER , num_groups, gid);
- }
+ res2 = lsa_set_secret(&pol_sec, &secret) ==
+ NT_STATUS_NOPROBLEMO;
+
+ }
+
+ if (res2)
+ {
+ report(out_hnd, "Set $MACHINE.ACC: OK\n");
}
+ else
+ {
+ report(out_hnd, "Set $MACHINE.ACC: FAILED\n");
+ }
+
+ res1 = res1 ? lsa_close(&pol_sec) : False;
- user_idx++;
+ memset(ntpw, 0, sizeof(ntpw));
}
}
+ else
+ {
+ report(out_hnd, "Create Domain User: FAILED\n");
+ }
- res = res ? do_samr_close(smb_cli,
- &info->dom.samr_pol_open_domain) : False;
+ res = res ? lsa_close(&lsa_pol) : False;
- res = res ? do_samr_close(smb_cli,
- &info->dom.samr_pol_connect) : False;
+ memset(&upw, 0, sizeof(upw));
+}
- /* close the session */
- cli_nt_session_close(smb_cli);
- if (info->dom.sam != NULL)
+/****************************************************************************
+SAM create domain alias.
+****************************************************************************/
+void cmd_sam_create_dom_alias(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ char *acct_name;
+ fstring acct_desc;
+ fstring sid;
+ DOM_SID sid1;
+ BOOL res = True;
+ BOOL res1 = True;
+ uint32 ace_perms = 0x02000000; /* permissions */
+ uint32 alias_rid;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (sid1.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+
+ if (argc < 2)
{
- free(info->dom.sam);
+ report(out_hnd, "createalias: <acct name> [acct description]\n");
}
- if (res)
+ acct_name = argv[1];
+
+ if (argc < 3)
{
- DEBUG(5,("cmd_sam_enum_users: succeeded\n"));
+ acct_desc[0] = 0;
}
else
{
- DEBUG(5,("cmd_sam_enum_users: failed\n"));
+ safe_strcpy(acct_desc, argv[2], sizeof(acct_desc)-1);
+ }
+
+ report(out_hnd, "SAM Create Domain Alias\n");
+ report(out_hnd, "Domain: %s Name: %s Description: %s\n",
+ domain, acct_name, acct_desc);
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
+ &pol_dom) : False;
+
+ /* create a domain alias */
+ res1 = res ? create_samr_domain_alias( &pol_dom,
+ acct_name, acct_desc, &alias_rid) : False;
+
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ if (res && res1)
+ {
+ DEBUG(5,("cmd_sam_create_dom_alias: succeeded\n"));
+ report(out_hnd, "Create Domain Alias: OK\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_create_dom_alias: failed\n"));
+ report(out_hnd, "Create Domain Alias: FAILED\n");
}
}
/****************************************************************************
-experimental SAM user query.
+SAM delete group member.
****************************************************************************/
-void cmd_sam_query_user(struct client_info *info)
+void cmd_sam_del_groupmem(struct client_info *info, int argc, char *argv[])
{
fstring srv_name;
fstring domain;
fstring sid;
DOM_SID sid1;
- int user_idx = 0; /* FIXME maybe ... */
+ POLICY_HND pol_grp;
BOOL res = True;
- uint32 admin_rid = 0x304; /* absolutely no idea. */
- fstring rid_str ;
- fstring info_str;
- uint32 user_rid = 0;
- uint32 info_level = 0x15;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ uint32 member_rid;
+ uint32 group_rid;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
- SAM_USER_INFO_21 usr;
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
- sid_to_string(sid, &info->dom.level5_sid);
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
fstrcpy(domain, info->dom.level5_dom);
- if (strlen(sid) == 0)
+ if (sid1.num_auths == 0)
{
- fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
+ {
+ report(out_hnd, "delgroupmem: <group rid> [member rid1] [member rid2] ...\n");
return;
}
- init_dom_sid(&sid1, sid);
+ argc--;
+ argv++;
+
+ group_rid = get_number(argv[0]);
+
+ report(out_hnd, "SAM Add Domain Group member\n");
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
+ &pol_dom) : False;
+
+ /* connect to the domain */
+ res1 = res ? samr_open_group( &pol_dom,
+ 0x0000001f, group_rid, &pol_grp) : False;
+
+ while (argc > 0 && res2 && res1)
+ {
+ argc--;
+ argv++;
+
+ /* get a rid, delete a member from the group */
+ member_rid = get_number(argv[0]);
+ res2 = res2 ? samr_del_groupmem(&pol_grp, member_rid) : False;
+
+ if (res2)
+ {
+ report(out_hnd, "RID deleted from Group 0x%x: 0x%x\n", group_rid, member_rid);
+ }
+ }
+
+ res1 = res1 ? samr_close(&pol_grp) : False;
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (res && res1 && res2)
+ {
+ DEBUG(5,("cmd_sam_del_groupmem: succeeded\n"));
+ report(out_hnd, "Add Domain Group Member: OK\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_del_groupmem: failed\n"));
+ report(out_hnd, "Add Domain Group Member: FAILED\n");
+ }
+}
+
+
+/****************************************************************************
+SAM delete user.
+****************************************************************************/
+void cmd_sam_delete_dom_user(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ char *name;
+ fstring sid;
+ DOM_SID sid1;
+ DOM_SID sid_usr;
+ POLICY_HND pol_usr;
+ BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ uint32 user_rid = 0;
+ char *names[1];
+ uint32 *rids;
+ uint32 *types;
+ uint32 num_rids;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
fstrcpy(srv_name, "\\\\");
fstrcat(srv_name, info->dest_host);
strupper(srv_name);
- if (next_token(NULL, rid_str , NULL, sizeof(rid_str )) &&
- next_token(NULL, info_str, NULL, sizeof(info_str)))
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (sid1.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
{
- user_rid = (uint32)strtol(rid_str , (char**)NULL, 16);
- info_level = (uint32)strtol(info_str, (char**)NULL, 10);
+ report(out_hnd, "deluser <user name>\n");
+ return;
}
- fprintf(out_hnd, "SAM Query User: rid %x info level %d\n",
- user_rid, info_level);
- fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
- info->myhostname, srv_name, domain, sid);
+ name = argv[1];
- /* open SAMR session. negotiate credentials */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+ report(out_hnd, "SAM Delete Domain User\n");
/* establish a connection. */
- res = res ? do_samr_connect(smb_cli,
- srv_name, 0x00000020,
- &info->dom.samr_pol_connect) : False;
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
/* connect to the domain */
- res = res ? do_samr_open_domain(smb_cli,
- &info->dom.samr_pol_connect, admin_rid, &sid1,
- &info->dom.samr_pol_open_domain) : False;
+ res = res ? samr_open_domain( &sam_pol, 0x0200, &sid1,
+ &pol_dom) : False;
+
+ names[0] = name;
- fprintf(out_hnd, "User RID: %8x User Name: %s\n",
- user_rid,
- info->dom.sam[user_idx].acct_name);
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x000003e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
- /* send user info query, level */
- if (get_samr_query_userinfo(smb_cli,
- &info->dom.samr_pol_open_domain,
- info_level, user_rid, &usr))
+ if (res1 && num_rids == 1 && rids)
{
- if (info_level == 0x15)
+ user_rid = rids[0];
+ sid_copy(&sid_usr, &sid1);
+ if (!sid_append_rid(&sid_usr, user_rid))
{
- display_sam_user_info_21(out_hnd, ACTION_HEADER , &usr);
- display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
- display_sam_user_info_21(out_hnd, ACTION_FOOTER , &usr);
+ res1 = False;
}
+
}
+ else
+ {
+ res1 = False;
+ }
+ safe_free(rids);
+ safe_free(types);
- res = res ? do_samr_close(smb_cli,
- &info->dom.samr_pol_connect) : False;
+ /* connect to the domain */
+ res1 = res1 ? samr_open_user( &pol_dom,
+ 0x010000, user_rid, &pol_usr) : False;
- res = res ? do_samr_close(smb_cli,
- &info->dom.samr_pol_open_domain) : False;
+ res2 = res1 ? samr_unknown_2d(&pol_dom, &sid_usr) : False;
+ res2 = res2 ? samr_delete_dom_user(&pol_usr) : False;
+ res2 = res2 ? samr_unknown_2d(&pol_dom, &sid_usr) : False;
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
- if (res)
+ if (res && res1 && res2)
{
- DEBUG(5,("cmd_sam_query_user: succeeded\n"));
+ DEBUG(5,("cmd_sam_delete_dom_user: succeeded\n"));
+ report(out_hnd, "Delete Domain User: OK\n");
}
else
{
- DEBUG(5,("cmd_sam_query_user: failed\n"));
+ DEBUG(5,("cmd_sam_delete_dom_user: failed\n"));
+ report(out_hnd, "Delete Domain User: FAILED\n");
}
}
/****************************************************************************
-experimental SAM groups query.
+SAM delete group.
****************************************************************************/
-void cmd_sam_query_groups(struct client_info *info)
+void cmd_sam_delete_dom_group(struct client_info *info, int argc, char *argv[])
{
fstring srv_name;
fstring domain;
+ char *name;
fstring sid;
DOM_SID sid1;
+ POLICY_HND pol_grp;
BOOL res = True;
- fstring info_str;
- uint32 switch_value = 2;
- uint32 admin_rid = 0x304; /* absolutely no idea. */
+ BOOL res1 = True;
+ BOOL res2 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ uint32 group_rid = 0;
+ char *names[1];
+ uint32 *rids;
+ uint32 *types;
+ uint32 num_rids;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
- sid_to_string(sid, &info->dom.level5_sid);
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
fstrcpy(domain, info->dom.level5_dom);
- if (strlen(sid) == 0)
+ if (sid1.num_auths == 0)
{
- fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
+ {
+ report(out_hnd, "delgroup <group name>\n");
return;
}
- init_dom_sid(&sid1, sid);
+ name = argv[1];
+
+ report(out_hnd, "SAM Delete Domain Group\n");
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
+ &pol_dom) : False;
+
+ names[0] = name;
+
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x000003e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+
+ if (res1 && num_rids == 1 && rids)
+ {
+ group_rid = rids[0];
+ }
+ if (rids)
+ {
+ free(rids);
+ }
+ if (types)
+ {
+ free(types);
+ }
+
+ /* connect to the domain */
+ res1 = res1 ? samr_open_group( &pol_dom,
+ 0x0000001f, group_rid, &pol_grp) : False;
+
+ res2 = res1 ? samr_delete_dom_group(&pol_grp) : False;
+
+ res1 = res1 ? samr_close(&pol_grp) : False;
+ res = res ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+ if (res && res1 && res2)
+ {
+ DEBUG(5,("cmd_sam_delete_dom_group: succeeded\n"));
+ report(out_hnd, "Delete Domain Group: OK\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_delete_dom_group: failed\n"));
+ report(out_hnd, "Delete Domain Group: FAILED\n");
+ }
+}
+
+
+/****************************************************************************
+SAM add group member.
+****************************************************************************/
+void cmd_sam_add_groupmem(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+ POLICY_HND pol_grp;
+ BOOL res = True;
+ BOOL res1 = True;
+ BOOL res2 = True;
+ BOOL res3 = True;
+ BOOL res4 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ uint32 *group_rids;
+ uint32 *group_types;
+ char **names = NULL;
+ uint32 num_names = 0;
+ fstring group_name;
+ char *group_names[1];
+ uint32 *rids;
+ uint32 *types;
+ uint32 num_rids;
+ uint32 num_group_rids;
+ uint32 i;
+ DOM_SID sid_1_5_20;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ POLICY_HND pol_blt;
+
+ string_to_sid(&sid_1_5_20, "S-1-5-32");
fstrcpy(srv_name, "\\\\");
fstrcat(srv_name, info->dest_host);
strupper(srv_name);
- if (next_token(NULL, info_str, NULL, sizeof(info_str)))
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (sid1.num_auths == 0)
{
- switch_value = (uint32)strtol(info_str, (char**)NULL, 10);
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 3)
+ {
+ report(out_hnd, "addgroupmem <group name> [member name1] [member name2] ...\n");
+ return;
}
+
+ argc--;
+ argv++;
- fprintf(out_hnd, "SAM Query Groups: info level %d\n", switch_value);
- fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
- info->myhostname, srv_name, domain, sid);
+ group_names[0] = argv[0];
- /* open SAMR session. negotiate credentials */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+ argc--;
+ argv++;
+
+ num_names = argc;
+ names = (char **) argv;
+
+ report(out_hnd, "SAM Add Domain Group member\n");
/* establish a connection. */
- res = res ? do_samr_connect(smb_cli,
- srv_name, 0x00000020,
- &info->dom.samr_pol_connect) : False;
+ res = res ? samr_connect( srv_name, 0x02000000, &sam_pol) : False;
/* connect to the domain */
- res = res ? do_samr_open_domain(smb_cli,
- &info->dom.samr_pol_connect, admin_rid, &sid1,
- &info->dom.samr_pol_open_domain) : False;
+ res4 = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
+ &pol_dom) : False;
- /* send a samr 0x8 command */
- res = res ? do_samr_query_dom_info(smb_cli,
- &info->dom.samr_pol_open_domain, switch_value) : False;
+ /* connect to the domain */
+ res3 = res ? samr_open_domain( &sam_pol, ace_perms, &sid_1_5_20,
+ &pol_blt) : False;
- res = res ? do_samr_close(smb_cli,
- &info->dom.samr_pol_connect) : False;
+ res2 = res4 ? samr_query_lookup_names( &pol_dom, 0x000003e8,
+ 1, group_names,
+ &num_group_rids, &group_rids, &group_types) : False;
- res = res ? do_samr_close(smb_cli,
- &info->dom.samr_pol_open_domain) : False;
+ /* open the group */
+ res2 = res2 ? samr_open_group( &pol_dom,
+ 0x0000001f, group_rids[0], &pol_grp) : False;
- /* close the session */
- cli_nt_session_close(smb_cli);
+ if (!res2 || (group_types != NULL && group_types[0] == SID_NAME_UNKNOWN))
+ {
+ if (group_rids != NULL)
+ {
+ free(group_rids);
+ }
+ if (group_types != NULL)
+ {
+ free(group_types);
+ }
- if (res)
+ res2 = res3 ? samr_query_lookup_names( &pol_blt, 0x000003e8,
+ 1, group_names,
+ &num_group_rids, &group_rids, &group_types) : False;
+
+ /* open the group */
+ res2 = res2 ? samr_open_group( &pol_blt,
+ 0x0000001f, group_rids[0], &pol_grp) : False;
+ }
+
+ if (res2 && group_types[0] == SID_NAME_ALIAS)
+ {
+ report(out_hnd, "%s is a local alias, not a group. Use addaliasmem command instead\n",
+ group_name);
+ if (group_rids != NULL)
+ {
+ free(group_rids);
+ }
+ if (group_types != NULL)
+ {
+ free(group_types);
+ }
+ return;
+ }
+ res1 = res2 ? samr_query_lookup_names( &pol_dom, 0x000003e8,
+ num_names, names,
+ &num_rids, &rids, &types) : False;
+
+ if (num_rids == 0)
+ {
+ report(out_hnd, "Member names not known\n");
+ }
+ for (i = 0; i < num_rids && res2 && res1; i++)
+ {
+ if (types[i] == SID_NAME_UNKNOWN)
+ {
+ report(out_hnd, "Name %s unknown\n", names[i]);
+ }
+ else
+ {
+ if (samr_add_groupmem(&pol_grp, rids[i]))
+ {
+ report(out_hnd, "RID added to Group 0x%x: 0x%x\n",
+ group_rids[0], rids[i]);
+ }
+ }
+ }
+
+ res1 = res ? samr_close(&pol_grp) : False;
+ res1 = res3 ? samr_close(&pol_blt) : False;
+ res1 = res4 ? samr_close(&pol_dom) : False;
+ res = res ? samr_close(&sam_pol) : False;
+
+#if 0
+ free_char_array(num_names, names);
+#endif
+
+ if (res && res1 && res2)
{
- DEBUG(5,("cmd_sam_query_groups: succeeded\n"));
+ DEBUG(5,("cmd_sam_add_groupmem: succeeded\n"));
+ report(out_hnd, "Add Domain Group Member: OK\n");
}
else
{
- DEBUG(5,("cmd_sam_query_groups: failed\n"));
+ DEBUG(5,("cmd_sam_add_groupmem: failed\n"));
+ report(out_hnd, "Add Domain Group Member: FAILED\n");
+ }
+ if (group_rids != NULL)
+ {
+ free(group_rids);
+ }
+ if (group_types != NULL)
+ {
+ free(group_types);
+ }
+ if (rids != NULL)
+ {
+ free(rids);
+ }
+ if (types != NULL)
+ {
+ free(types);
}
}
/****************************************************************************
-experimental SAM aliases query.
+SAM create domain group.
****************************************************************************/
-void cmd_sam_enum_aliases(struct client_info *info)
+void cmd_sam_create_dom_group(struct client_info *info, int argc, char *argv[])
{
fstring srv_name;
fstring domain;
+ char *acct_name;
+ fstring acct_desc;
fstring sid;
DOM_SID sid1;
BOOL res = True;
+ BOOL res1 = True;
+ uint32 ace_perms = 0x02000000; /* absolutely no idea. */
+ uint32 group_rid;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (sid1.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+
+ if (argc < 2)
+ {
+ report(out_hnd, "creategroup: <acct name> [acct description]\n");
+ }
+
+ acct_name = argv[1];
+
+ if (argc < 3)
+ {
+ acct_desc[0] = 0;
+ }
+ else
+ {
+ safe_strcpy(acct_desc, argv[2], sizeof(acct_desc)-1);
+ }
+
+
+ report(out_hnd, "SAM Create Domain Group\n");
+ report(out_hnd, "Domain: %s Name: %s Description: %s\n",
+ domain, acct_name, acct_desc);
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, ace_perms, &sid1,
+ &pol_dom) : False;
+
+ /* read some users */
+ res1 = res ? create_samr_domain_group( &pol_dom,
+ acct_name, acct_desc, &group_rid) : False;
+
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ if (res && res1)
+ {
+ DEBUG(5,("cmd_sam_create_dom_group: succeeded\n"));
+ report(out_hnd, "Create Domain Group: OK\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_create_dom_group: failed\n"));
+ report(out_hnd, "Create Domain Group: FAILED\n");
+ }
+}
+
+/****************************************************************************
+experimental SAM users enum.
+****************************************************************************/
+void cmd_sam_enum_users(struct client_info *info, int argc, char *argv[])
+{
BOOL request_user_info = False;
+ BOOL request_group_info = False;
BOOL request_alias_info = False;
- uint32 admin_rid = 0x304; /* absolutely no idea. */
- fstring tmp;
+ struct acct_info *sam = NULL;
+ uint32 num_sam_entries = 0;
+ int opt;
- uint32 num_aliases = 3;
- uint32 alias_rid[3] = { DOMAIN_GROUP_RID_ADMINS, DOMAIN_GROUP_RID_USERS, DOMAIN_GROUP_RID_GUESTS };
- fstring alias_names [3];
- uint32 num_als_usrs[3];
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
- sid_to_string(sid, &info->dom.level3_sid);
- fstrcpy(domain, info->dom.level3_dom);
-#if 0
- fstrcpy(sid , "S-1-5-20");
-#endif
- if (strlen(sid) == 0)
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (sid1.num_auths == 0)
{
- fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ while ((opt = getopt(argc, argv, "uga")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'u':
+ {
+ request_user_info = True;
+ break;
+ }
+ case 'g':
+ {
+ request_group_info = True;
+ break;
+ }
+ case 'a':
+ {
+ request_alias_info = True;
+ break;
+ }
+ }
+ }
+
+ report(out_hnd, "SAM Enumerate Users\n");
+
+ msrpc_sam_enum_users(srv_name, domain, &sid1,
+ &sam, &num_sam_entries,
+ sam_display_user,
+ request_user_info ? sam_display_user_info : NULL,
+ request_group_info ? sam_display_group_members : NULL,
+ request_alias_info ? sam_display_group_members : NULL);
+
+ if (sam != NULL)
+ {
+ free(sam);
+ }
+}
+
+
+/****************************************************************************
+experimental SAM group query members.
+****************************************************************************/
+void cmd_sam_query_groupmem(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid_str;
+ DOM_SID sid;
+ BOOL res = True;
+ BOOL res1 = True;
+
+ char *group_name;
+ char *names[1];
+ uint32 num_rids;
+ uint32 *rids;
+ uint32 *types;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fstrcpy(domain, info->dom.level5_dom);
+ sid_copy(&sid, &info->dom.level5_sid);
+
+ if (sid.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
+ {
+ report(out_hnd, "samgroupmem <name>\n");
return;
}
- init_dom_sid(&sid1, sid);
+ group_name = argv[1];
+
+ sid_to_string(sid_str, &sid);
+
+ report(out_hnd, "SAM Query Group: %s\n", group_name);
+ report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+ info->myhostname, srv_name, domain, sid_str);
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, 0x304, &sid,
+ &pol_dom) : False;
+
+ /* look up group rid */
+ names[0] = group_name;
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+
+ if (res1 && num_rids == 1)
+ {
+ res1 = req_groupmem_info( &pol_dom,
+ domain,
+ &sid,
+ rids[0],
+ group_name,
+ sam_display_group_members);
+ }
+
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ if (res1)
+ {
+ DEBUG(5,("cmd_sam_query_group: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_query_group: failed\n"));
+ }
+ if (rids != NULL)
+ {
+ free(rids);
+ }
+ if (types != NULL)
+ {
+ free(types);
+ }
+}
+
+
+/****************************************************************************
+experimental SAM group query.
+****************************************************************************/
+void cmd_sam_query_group(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid_str;
+ DOM_SID sid;
+ BOOL res = True;
+ BOOL res1 = True;
+
+ char *group_name;
+ char *names[1];
+ uint32 num_rids;
+ uint32 *rids;
+ uint32 *types;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
fstrcpy(srv_name, "\\\\");
fstrcat(srv_name, info->dest_host);
strupper(srv_name);
- /* a bad way to do token parsing... */
- if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ fstrcpy(domain, info->dom.level5_dom);
+ sid_copy(&sid, &info->dom.level5_sid);
+
+ if (sid.num_auths == 0)
{
- request_user_info |= strequal(tmp, "-u");
- request_alias_info |= strequal(tmp, "-g");
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
}
- if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ if (argc < 2)
{
- request_user_info |= strequal(tmp, "-u");
- request_alias_info |= strequal(tmp, "-g");
+ report(out_hnd, "samgroup <name>\n");
+ return;
}
- fprintf(out_hnd, "SAM Enumerate Aliases\n");
- fprintf(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
- info->myhostname, srv_name, domain, sid);
+ group_name = argv[1];
+
+ sid_to_string(sid_str, &sid);
- /* open SAMR session. negotiate credentials */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SAMR) : False;
+ report(out_hnd, "SAM Query Group: %s\n", group_name);
+ report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+ info->myhostname, srv_name, domain, sid_str);
/* establish a connection. */
- res = res ? do_samr_connect(smb_cli,
- srv_name, 0x00000020,
- &info->dom.samr_pol_connect) : False;
+ res = res ? samr_connect( srv_name, 0x02000000, &sam_pol) : False;
/* connect to the domain */
- res = res ? do_samr_open_domain(smb_cli,
- &info->dom.samr_pol_connect, admin_rid, &sid1,
- &info->dom.samr_pol_open_domain) : False;
+ res = res ? samr_open_domain( &sam_pol, 0x304, &sid, &pol_dom) : False;
- /* send a query on the aliase */
- res = res ? do_samr_query_unknown_12(smb_cli,
- &info->dom.samr_pol_open_domain, admin_rid, num_aliases, alias_rid,
- &num_aliases, alias_names, num_als_usrs) : False;
+ /* look up group rid */
+ names[0] = group_name;
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
- if (res)
+ if (res1 && num_rids == 1)
{
- display_alias_name_info(out_hnd, ACTION_HEADER , num_aliases, alias_names, num_als_usrs);
- display_alias_name_info(out_hnd, ACTION_ENUMERATE, num_aliases, alias_names, num_als_usrs);
- display_alias_name_info(out_hnd, ACTION_FOOTER , num_aliases, alias_names, num_als_usrs);
+ res1 = query_groupinfo( &pol_dom,
+ domain,
+ &sid,
+ rids[0],
+ sam_display_group_info);
}
-#if 0
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
- /* read some users */
- res = res ? do_samr_enum_dom_users(smb_cli,
- &info->dom.samr_pol_open_domain,
- num_entries, unk_0, acb_mask, unk_1, 0xffff,
- info->dom.sam, &info->dom.num_sam_entries) : False;
+ if (res1)
+ {
+ DEBUG(5,("cmd_sam_query_group: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_query_group: failed\n"));
+ }
+ if (rids != NULL)
+ {
+ free(rids);
+ }
+ if (types != NULL)
+ {
+ free(types);
+ }
+
+}
- if (res && info->dom.num_sam_entries == 0)
+
+/****************************************************************************
+experimental SAM query security object.
+****************************************************************************/
+void cmd_sam_query_sec_obj(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid_str;
+ DOM_SID sid;
+ BOOL res = True;
+ BOOL res1 = True;
+
+ char *user_name;
+ char *names[1];
+ uint32 num_rids;
+ uint32 *rids;
+ uint32 *types;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fstrcpy(domain, info->dom.level5_dom);
+ sid_copy(&sid, &info->dom.level5_sid);
+
+ if (sid.num_auths == 0)
{
- fprintf(out_hnd, "No users\n");
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
+ {
+ report(out_hnd, "samsecquery <name>\n");
+ return;
}
- if (request_user_info || request_alias_info)
+ user_name = argv[1];
+
+ argc--;
+ argv++;
+
+ sid_to_string(sid_str, &sid);
+
+ report(out_hnd, "SAM Query User: %s\n", user_name);
+ report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+ info->myhostname, srv_name, domain, sid_str);
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, 0x304, &sid,
+ &pol_dom) : False;
+
+ /* look up user rid */
+ names[0] = user_name;
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+
+ /* send user info query */
+ if (res1 && num_rids == 1)
{
- /* query all the users */
- user_idx = 0;
+ POLICY_HND pol_usr;
+ BOOL ret = True;
+ SEC_DESC_BUF buf;
+
+ /* send open domain (on user sid) */
+ ret = samr_open_user( &pol_dom, 0x02011b, rids[0], &pol_usr);
+ res1 = ret ? samr_query_sec_obj(&pol_usr, 0x04, &buf) : False;
+ ret = ret ? samr_close (&pol_usr) : False;
- while (res && user_idx < info->dom.num_sam_entries)
+ if (buf.sec != NULL)
{
- uint32 user_rid = info->dom.sam[user_idx].smb_userid;
- SAM_USER_INFO_21 usr;
+ display_sec_desc(out_hnd, ACTION_HEADER , buf.sec);
+ display_sec_desc(out_hnd, ACTION_ENUMERATE, buf.sec);
+ display_sec_desc(out_hnd, ACTION_FOOTER , buf.sec);
+ }
+
+ free_sec_desc_buf(&buf);
+ }
+ else
+ {
+ res1 = False;
+ }
- fprintf(out_hnd, "User RID: %8x User Name: %s\n",
- user_rid,
- info->dom.sam[user_idx].acct_name);
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
- if (request_user_info)
+ if (res1)
+ {
+ DEBUG(5,("cmd_sam_query_sec_obj: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_query_sec_obj: failed\n"));
+ }
+ if (rids != NULL)
+ {
+ free(rids);
+ }
+ if (types != NULL)
+ {
+ free(types);
+ }
+}
+
+/****************************************************************************
+experimental SAM user query.
+****************************************************************************/
+void cmd_sam_query_user(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid_str;
+ DOM_SID sid;
+ BOOL res = True;
+ BOOL res1 = True;
+ int opt;
+
+ char *user_name;
+ char *names[1];
+ uint32 num_rids;
+ uint32 *rids;
+ uint32 *types;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ uint16 info_level = 0x15;
+
+ BOOL request_user_info = False;
+ BOOL request_group_info = False;
+ BOOL request_alias_info = False;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fstrcpy(domain, info->dom.level5_dom);
+ sid_copy(&sid, &info->dom.level5_sid);
+
+ if (sid.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
+ {
+ report(out_hnd, "samuser <name> [-u] [-g] [-a]\n");
+ return;
+ }
+
+ user_name = argv[1];
+
+ argc--;
+ argv++;
+
+ while ((opt = getopt(argc, argv, "ugai:")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'u':
{
- /* send user info query, level 0x15 */
- if (get_samr_query_userinfo(smb_cli,
- &info->dom.samr_pol_open_domain,
- 0x15, user_rid, &usr))
- {
- display_sam_user_info_21(out_hnd, ACTION_HEADER , &usr);
- display_sam_user_info_21(out_hnd, ACTION_ENUMERATE, &usr);
- display_sam_user_info_21(out_hnd, ACTION_FOOTER , &usr);
- }
+ request_user_info = True;
+ break;
+ }
+ case 'g':
+ {
+ request_group_info = True;
+ break;
+ }
+ case 'a':
+ {
+ request_alias_info = True;
+ break;
+ }
+ case 'i':
+ {
+ info_level = get_number(optarg);
+ break;
+ }
+ }
+ }
+
+ sid_to_string(sid_str, &sid);
+
+ report(out_hnd, "SAM Query User: %s\n", user_name);
+ report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+ info->myhostname, srv_name, domain, sid_str);
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, 0x304, &sid,
+ &pol_dom) : False;
+
+ /* look up user rid */
+ names[0] = user_name;
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+
+ /* send user info query */
+ if (res1 && num_rids == 1)
+ {
+ msrpc_sam_user( &pol_dom, NULL,
+ domain,
+ &sid, NULL,
+ rids[0], info_level, user_name,
+ sam_display_user,
+ request_user_info ? sam_display_user_info : NULL,
+ request_group_info ? sam_display_group_members : NULL,
+ request_alias_info ? sam_display_group_members : NULL);
+ }
+ else
+ {
+ res1 = False;
+ }
+
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ if (res1)
+ {
+ DEBUG(5,("cmd_sam_query_user: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_query_user: failed\n"));
+ }
+ if (rids != NULL)
+ {
+ free(rids);
+ }
+ if (types != NULL)
+ {
+ free(types);
+ }
+}
+
+
+/****************************************************************************
+experimental SAM user set.
+****************************************************************************/
+void cmd_sam_set_userinfo2(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid_str;
+ DOM_SID sid;
+ BOOL res = True;
+ BOOL res1 = True;
+ int opt;
+ BOOL set_acb_bits = False;
+ BOOL clr_acb_bits = False;
+
+ fstring user_name;
+
+ char *names[1];
+ uint32 num_rids;
+ uint32 *rids;
+ uint32 *types;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ SAM_USERINFO_CTR ctr;
+ uint16 acb_set = 0x0;
+ uint16 acb_clr = 0x0;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fstrcpy(domain, info->dom.level5_dom);
+ sid_copy(&sid, &info->dom.level5_sid);
+
+ if (sid.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
+ {
+ report(out_hnd, "samuserset2 <name> [-s <acb_bits>] [-c <acb_bits]\n");
+ return;
+ }
+
+ argc--;
+ argv++;
+
+ safe_strcpy(user_name, argv[0], sizeof(user_name));
+
+ while ((opt = getopt(argc, argv,"s:c:")) != EOF)
+ {
+ switch (opt)
+ {
+ case 's':
+ {
+ set_acb_bits = True;
+ acb_set = get_number(optarg);
+ break;
}
+ case 'c':
+ {
+ clr_acb_bits = True;
+ acb_clr = get_number(optarg);
+ break;
+ }
+ }
+ }
+
+ sid_to_string(sid_str, &sid);
- if (request_alias_info)
+ report(out_hnd, "SAM Set User Info: %s\n", user_name);
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, 0x02000000, &sid,
+ &pol_dom) : False;
+
+ /* look up user rid */
+ names[0] = user_name;
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+
+ /* send set user info */
+ if (res1 && num_rids == 1 && get_samr_query_userinfo( &pol_dom,
+ 0x10, rids[0],
+ &ctr))
+ {
+ void *usr = NULL;
+ uint32 switch_value = 0;
+
+ if (True)
+ {
+ SAM_USER_INFO_10 *p = (SAM_USER_INFO_10 *)malloc(sizeof(SAM_USER_INFO_10));
+ p->acb_info = ctr.info.id10->acb_info;
+ DEBUG(10,("acb_info: %x\n", p->acb_info));
+ if (set_acb_bits)
+ {
+ p->acb_info |= acb_set;
+ }
+
+ if (clr_acb_bits)
{
- uint32 num_aliases;
- DOM_GID gid[LSA_MAX_GROUPS];
+ p->acb_info &= (~acb_clr);
+ }
+
+ DEBUG(10,("acb_info: %x\n", p->acb_info));
+
+ usr = (void*)p;
+ switch_value = 16;
+ }
+
+ if (usr != NULL)
+ {
+ res1 = set_samr_set_userinfo2( &pol_dom,
+ switch_value, rids[0], usr);
+ }
+ }
+
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
- /* send user aliase query */
- if (get_samr_query_useraliases(smb_cli,
- &info->dom.samr_pol_open_domain,
- user_rid, &num_aliases, gid))
+ if (res1)
+ {
+ report(out_hnd, "Set User Info: OK\n");
+ DEBUG(5,("cmd_sam_query_user: succeeded\n"));
+ }
+ else
+ {
+ report(out_hnd, "Set User Info: Failed\n");
+ DEBUG(5,("cmd_sam_query_user: failed\n"));
+ }
+ if (rids != NULL)
+ {
+ free(rids);
+ }
+ if (types != NULL)
+ {
+ free(types);
+ }
+ free_samr_userinfo_ctr(&ctr);
+}
+
+/****************************************************************************
+experimental SAM user set.
+****************************************************************************/
+void cmd_sam_set_userinfo(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid_str;
+ DOM_SID sid;
+ BOOL res = True;
+ BOOL res1 = True;
+ int opt;
+ BOOL set_passwd = False;
+
+ fstring user_name;
+ fstring password;
+
+ char *names[1];
+ uint32 num_rids;
+ uint32 *rids;
+ uint32 *types;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+ SAM_USERINFO_CTR ctr;
+
+ ZERO_STRUCT(ctr);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fstrcpy(domain, info->dom.level5_dom);
+ sid_copy(&sid, &info->dom.level5_sid);
+
+ if (sid.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ argc--;
+ argv++;
+
+ if (argc == 0)
+ {
+ report(out_hnd, "samuserset <name> [-p password]\n");
+ return;
+ }
+
+ safe_strcpy(user_name, argv[0], sizeof(user_name));
+
+ if (argc == 1)
+ {
+ fstring pass_str;
+ char *pass;
+ slprintf(pass_str, sizeof(pass_str)-1, "Enter %s's Password:",
+ user_name);
+ pass = (char*)getpass(pass_str);
+
+ if (pass != NULL)
+ {
+ safe_strcpy(password, pass,
+ sizeof(password)-1);
+ set_passwd = True;
+ }
+ }
+ else
+ {
+ while ((opt = getopt(argc, argv,"p:")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'p':
{
- display_alias_info(out_hnd, ACTION_HEADER , num_aliases, gid);
- display_alias_info(out_hnd, ACTION_ENUMERATE, num_aliases, gid);
- display_alias_info(out_hnd, ACTION_FOOTER , num_aliases, gid);
+ set_passwd = True;
+ safe_strcpy(password, optarg,
+ sizeof(password)-1);
+ break;
}
}
-
- user_idx++;
}
}
+
+ sid_to_string(sid_str, &sid);
+
+ report(out_hnd, "SAM Set User Info: %s\n", user_name);
+ report(out_hnd, "Password: %s\n", password);
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, 0x02000000, &sid,
+ &pol_dom) : False;
+
+ /* look up user rid */
+ names[0] = user_name;
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+
+ /* send set user info */
+ if (res1 && num_rids == 1 && get_samr_query_userinfo( &pol_dom,
+ 0x15, rids[0], &ctr))
+ {
+ void *usr = NULL;
+ uint32 switch_value = 0;
+ char pwbuf[516];
+
+ if (set_passwd)
+ {
+ encode_pw_buffer(pwbuf, password,
+ strlen(password), True);
+ }
+
+ if (True)
+ {
+ SAM_USER_INFO_24 *p = (SAM_USER_INFO_24*)malloc(sizeof(SAM_USER_INFO_24));
+ make_sam_user_info24(p, pwbuf, strlen(password));
+
+ usr = p;
+ switch_value = 24;
+ }
+
+ if (False)
+ {
+ SAM_USER_INFO_21 *usr21 = ctr.info.id21;
+ SAM_USER_INFO_23 *p = (SAM_USER_INFO_23*)malloc(sizeof(SAM_USER_INFO_23));
+ /* send user info query, level 0x15 */
+ make_sam_user_info23W(p,
+ &usr21->logon_time,
+ &usr21->logoff_time,
+ &usr21->kickoff_time,
+ &usr21->pass_last_set_time,
+ &usr21->pass_can_change_time,
+ &usr21->pass_must_change_time,
+
+ &usr21->uni_user_name,
+ &usr21->uni_full_name,
+ &usr21->uni_home_dir,
+ &usr21->uni_dir_drive,
+ &usr21->uni_logon_script,
+ &usr21->uni_profile_path,
+ &usr21->uni_acct_desc,
+ &usr21->uni_workstations,
+ &usr21->uni_unknown_str,
+ &usr21->uni_munged_dial,
+
+ 0x0,
+ usr21->group_rid,
+ usr21->acb_info,
+
+ 0x09f827fa,
+ usr21->logon_divs,
+ &usr21->logon_hrs,
+ usr21->unknown_5,
+ pwbuf
+#if 0
+ , usr21->unknown_6
#endif
+ );
- res = res ? do_samr_close(smb_cli,
- &info->dom.samr_pol_connect) : False;
+ usr = p;
+ switch_value = 23;
+ }
+ if (usr != NULL)
+ {
+ res1 = set_samr_set_userinfo( &pol_dom,
+ switch_value, rids[0], usr);
+ }
+ }
- res = res ? do_samr_close(smb_cli,
- &info->dom.samr_pol_open_domain) : False;
+ free_samr_userinfo_ctr(&ctr);
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
- if (res)
+ if (res1)
+ {
+ report(out_hnd, "Set User Info: OK\n");
+ DEBUG(5,("cmd_sam_query_user: succeeded\n"));
+ }
+ else
+ {
+ report(out_hnd, "Set User Info: Failed\n");
+ DEBUG(5,("cmd_sam_query_user: failed\n"));
+ }
+ if (rids != NULL)
+ {
+ free(rids);
+ }
+ if (types != NULL)
+ {
+ free(types);
+ }
+ free_samr_userinfo_ctr(&ctr);
+}
+
+static void sam_display_disp_info(const char* domain, const DOM_SID *sid,
+ uint16 info, uint32 num,
+ SAM_DISPINFO_CTR *ctr)
+
+{
+ report(out_hnd, "SAM Display Info for Domain %s\n", domain);
+
+ display_sam_disp_info_ctr(out_hnd, ACTION_HEADER , info, num, ctr);
+ display_sam_disp_info_ctr(out_hnd, ACTION_ENUMERATE, info, num, ctr);
+ display_sam_disp_info_ctr(out_hnd, ACTION_FOOTER , info, num, ctr);
+}
+
+/****************************************************************************
+experimental SAM query display info.
+****************************************************************************/
+void cmd_sam_query_dispinfo(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+ uint16 switch_value = 1;
+ SAM_DISPINFO_CTR ctr;
+ SAM_DISPINFO_1 inf1;
+ uint32 num_entries;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_to_string(sid, &info->dom.level5_sid);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ string_to_sid(&sid1, sid);
+
+ if (sid1.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ fprintf(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc > 1)
+ {
+ switch_value = strtoul(argv[1], (char**)NULL, 10);
+ }
+
+ ctr.sam.info1 = &inf1;
+
+ if (msrpc_sam_query_dispinfo( srv_name, domain, &sid1,
+ switch_value,
+ &num_entries, &ctr, sam_display_disp_info))
+ {
+
+ DEBUG(5,("cmd_sam_query_dispinfo: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_query_dispinfo: failed\n"));
+ }
+}
+
+/****************************************************************************
+experimental SAM domain info query.
+****************************************************************************/
+void cmd_sam_query_dominfo(struct client_info *info, int argc, char *argv[])
+{
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+ uint32 switch_value = 2;
+ SAM_UNK_CTR ctr;
+ fstring srv_name;
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_to_string(sid, &info->dom.level5_sid);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ string_to_sid(&sid1, sid);
+
+ if (sid1.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc > 1)
+ {
+ switch_value = strtoul(argv[1], (char**)NULL, 10);
+ }
+
+ if (sam_query_dominfo(srv_name, &sid1, switch_value, &ctr))
+ {
+ DEBUG(5,("cmd_sam_query_dominfo: succeeded\n"));
+ sam_display_dom_info(domain, &sid1, switch_value, &ctr);
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_query_dominfo: failed\n"));
+ }
+}
+
+/****************************************************************************
+experimental SAM alias query members.
+****************************************************************************/
+void cmd_sam_query_aliasmem(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid_str;
+ DOM_SID sid;
+ BOOL res = True;
+ BOOL res1 = True;
+
+ char *alias_name;
+ char *names[1];
+ uint32 num_rids;
+ uint32 *rids;
+ uint32 *types;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fstrcpy(domain, info->dom.level5_dom);
+ sid_copy(&sid, &info->dom.level5_sid);
+
+ if (sid.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
{
- DEBUG(5,("cmd_sam_enum_users: succeeded\n"));
+ report(out_hnd, "samaliasmem <name>\n");
+ return;
+ }
+
+ alias_name = argv[1];
+
+ sid_to_string(sid_str, &sid);
+
+ report(out_hnd, "SAM Query Alias: %s\n", alias_name);
+ report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+ info->myhostname, srv_name, domain, sid_str);
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, 0x304, &sid,
+ &pol_dom) : False;
+
+ /* look up alias rid */
+ names[0] = alias_name;
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+
+ if (res1 && num_rids == 1)
+ {
+ res1 = req_aliasmem_info(srv_name,
+ &pol_dom,
+ domain,
+ &sid,
+ rids[0],
+ alias_name,
+ sam_display_alias_members);
+ }
+
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ if (res1)
+ {
+ DEBUG(5,("cmd_sam_query_alias: succeeded\n"));
}
else
{
- DEBUG(5,("cmd_sam_enum_users: failed\n"));
+ DEBUG(5,("cmd_sam_query_alias: failed\n"));
+ }
+ if (rids != NULL)
+ {
+ free(rids);
+ }
+ if (types != NULL)
+ {
+ free(types);
+ }
+}
+
+
+/****************************************************************************
+experimental SAM alias query.
+****************************************************************************/
+void cmd_sam_query_alias(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring domain;
+ fstring sid_str;
+ DOM_SID sid;
+ BOOL res = True;
+ BOOL res1 = True;
+
+ char *alias_name;
+ char *names[1];
+ uint32 num_rids;
+ uint32 *rids;
+ uint32 *types;
+ POLICY_HND sam_pol;
+ POLICY_HND pol_dom;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ fstrcpy(domain, info->dom.level5_dom);
+ sid_copy(&sid, &info->dom.level5_sid);
+
+ if (sid.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ if (argc < 2)
+ {
+ report(out_hnd, "samalias <name>\n");
+ return;
+ }
+
+ alias_name = argv[1];
+
+ sid_to_string(sid_str, &sid);
+
+ report(out_hnd, "SAM Query Alias: %s\n", alias_name);
+ report(out_hnd, "From: %s To: %s Domain: %s SID: %s\n",
+ info->myhostname, srv_name, domain, sid_str);
+
+ /* establish a connection. */
+ res = res ? samr_connect( srv_name, 0x02000000,
+ &sam_pol) : False;
+
+ /* connect to the domain */
+ res = res ? samr_open_domain( &sam_pol, 0x304, &sid,
+ &pol_dom) : False;
+
+ /* look up alias rid */
+ names[0] = alias_name;
+ res1 = res ? samr_query_lookup_names( &pol_dom, 0x3e8,
+ 1, names,
+ &num_rids, &rids, &types) : False;
+
+ if (res1 && num_rids == 1)
+ {
+ res1 = query_aliasinfo( &pol_dom,
+ domain,
+ &sid,
+ rids[0],
+ sam_display_alias_info);
+ }
+
+ res = res ? samr_close( &pol_dom) : False;
+ res = res ? samr_close( &sam_pol) : False;
+
+ if (res1)
+ {
+ DEBUG(5,("cmd_sam_query_alias: succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_sam_query_alias: failed\n"));
+ }
+ if (rids != NULL)
+ {
+ free(rids);
+ }
+ if (types != NULL)
+ {
+ free(types);
+ }
+}
+
+
+/****************************************************************************
+SAM aliases query.
+****************************************************************************/
+void cmd_sam_enum_aliases(struct client_info *info, int argc, char *argv[])
+{
+ BOOL request_member_info = False;
+ BOOL request_alias_info = False;
+ struct acct_info *sam = NULL;
+ uint32 num_sam_entries = 0;
+ int opt;
+
+ fstring domain;
+ fstring srv_name;
+ fstring sid;
+ DOM_SID sid1;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (sid1.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ while ((opt = getopt(argc, argv, "ma")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'm':
+ {
+ request_member_info = True;
+ break;
+ }
+ case 'a':
+ {
+ request_alias_info = True;
+ break;
+ }
+ }
+ }
+
+ report(out_hnd, "SAM Enumerate Aliases\n");
+
+ msrpc_sam_enum_aliases(srv_name, domain, &sid1,
+ &sam, &num_sam_entries,
+ sam_display_alias,
+ request_alias_info ? sam_display_alias_info : NULL,
+ request_member_info ? sam_display_alias_members : NULL);
+
+ if (sam != NULL)
+ {
+ free(sam);
}
}
+/****************************************************************************
+experimental SAM groups enum.
+****************************************************************************/
+void cmd_sam_enum_groups(struct client_info *info, int argc, char *argv[])
+{
+ BOOL request_member_info = False;
+ BOOL request_group_info = False;
+ struct acct_info *sam = NULL;
+ uint32 num_sam_entries = 0;
+ int opt;
+
+ fstring srv_name;
+ fstring domain;
+ fstring sid;
+ DOM_SID sid1;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ sid_copy(&sid1, &info->dom.level5_sid);
+ sid_to_string(sid, &sid1);
+ fstrcpy(domain, info->dom.level5_dom);
+
+ if (sid1.num_auths == 0)
+ {
+ if (msrpc_sam_get_first_domain(srv_name, domain, &sid1) != 0x0)
+ {
+ report(out_hnd, "please use 'lsaquery' first, to ascertain the SID\n");
+ return;
+ }
+ }
+
+ while ((opt = getopt(argc, argv, "mg")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'm':
+ {
+ request_member_info = True;
+ break;
+ }
+ case 'g':
+ {
+ request_group_info = True;
+ break;
+ }
+ }
+ }
+
+ report(out_hnd, "SAM Enumerate Groups\n");
+
+ msrpc_sam_enum_groups(srv_name, domain, &sid1,
+ &sam, &num_sam_entries,
+ sam_display_group,
+ request_group_info ? sam_display_group_info : NULL,
+ request_member_info ? sam_display_group_members : NULL);
+
+ if (sam != NULL)
+ {
+ free(sam);
+ }
+}
+
+/****************************************************************************
+experimental SAM domains enum.
+****************************************************************************/
+void cmd_sam_enum_domains(struct client_info *info, int argc, char *argv[])
+{
+ BOOL request_domain_info = False;
+ struct acct_info *sam = NULL;
+ uint32 num_sam_entries = 0;
+ int opt;
+
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ while ((opt = getopt(argc, argv, "i")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'i':
+ {
+ request_domain_info= True;
+ break;
+ }
+ }
+ }
+
+ report(out_hnd, "SAM Enumerate Domains\n");
+
+ msrpc_sam_enum_domains(srv_name,
+ &sam, &num_sam_entries,
+ request_domain_info ? NULL : sam_display_domain,
+ request_domain_info ? sam_display_dom_info : NULL);
+
+ if (sam != NULL)
+ {
+ free(sam);
+ }
+}
diff --git a/source/rpcclient/cmd_spoolss.c b/source/rpcclient/cmd_spoolss.c
new file mode 100644
index 00000000000..e9003c8c6a8
--- /dev/null
+++ b/source/rpcclient/cmd_spoolss.c
@@ -0,0 +1,264 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+#define DEBUG_TESTING
+
+extern FILE* out_hnd;
+
+extern struct user_creds *usr_creds;
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_printers( const char* srv_name,
+ uint32 level,
+ uint32 *num,
+ void ***ctr,
+ PRINT_INFO_FN(fn))
+{
+ BOOL res = True;
+
+ if (spoolss_enum_printers( 0x40, srv_name, level, num, ctr) &&
+ fn != NULL)
+ {
+ fn(srv_name, level, *num, *ctr);
+ }
+
+ return res;
+}
+
+static void spool_print_info_ctr(const char* srv_name, uint32 level,
+ uint32 num, void *const *const ctr)
+{
+ display_printer_info_ctr(out_hnd, ACTION_HEADER , level, num, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, num, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_FOOTER , level, num, ctr);
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+void cmd_spoolss_enum_printers(struct client_info *info, int argc, char *argv[])
+{
+ void **ctr = NULL;
+ uint32 num = 0;
+ uint32 level = 1;
+
+ fstring srv_name;
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (msrpc_spoolss_enum_printers(srv_name, level, &num, &ctr,
+ spool_print_info_ctr))
+ {
+ DEBUG(5,("cmd_spoolss_enum_printer: query succeeded\n"));
+ }
+ else
+ {
+ report(out_hnd, "FAILED\n");
+ }
+
+ free_void_array(num, ctr, free);
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+void cmd_spoolss_open_printer_ex(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring station;
+ char *printer_name;
+ POLICY_HND hnd;
+
+ BOOL res = True;
+
+ if (argc < 2)
+ {
+ report(out_hnd, "spoolopen <printer name>\n");
+ return;
+ }
+
+ printer_name = argv[1];
+
+ fstrcpy(station, "\\\\");
+ fstrcat(station, info->myhostname);
+ strupper(station);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (!strnequal("\\\\", printer_name, 2))
+ {
+ fstrcat(srv_name, "\\");
+ fstrcat(srv_name, printer_name);
+ printer_name = srv_name;
+ }
+
+ DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n",
+ printer_name, station, usr_creds->ntc.user_name));
+
+ res = res ? spoolss_open_printer_ex( printer_name,
+ 0, 0, 0,
+ station, usr_creds->ntc.user_name,
+ &hnd) : False;
+
+ res = res ? spoolss_closeprinter(&hnd) : False;
+
+ if (res)
+ {
+ DEBUG(5,("cmd_spoolss_open_printer_ex: query succeeded\n"));
+ report(out_hnd, "OK\n");
+ }
+ else
+ {
+ DEBUG(5,("cmd_spoolss_open_printer_ex: query failed\n"));
+ }
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_jobs( const char* printer_name,
+ const char* station, const char* user_name,
+ uint32 level,
+ uint32 *num,
+ void ***ctr,
+ JOB_INFO_FN(fn))
+{
+ POLICY_HND hnd;
+ uint32 buf_size = 0x0;
+ uint32 status = 0x0;
+
+ BOOL res = True;
+ BOOL res1 = True;
+
+ DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n",
+ printer_name, station, user_name));
+
+ res = res ? spoolss_open_printer_ex( printer_name,
+ 0, 0, 0,
+ station, user_name,
+ &hnd) : False;
+
+ if (status == 0x0)
+ {
+ status = spoolss_enum_jobs( &hnd,
+ 0, 1000, level, &buf_size,
+ num, ctr);
+ }
+
+ if (status == ERROR_INSUFFICIENT_BUFFER)
+ {
+ status = spoolss_enum_jobs( &hnd,
+ 0, 1000, level, &buf_size,
+ num, ctr);
+ }
+
+ res1 = (status == 0x0);
+
+ res = res ? spoolss_closeprinter(&hnd) : False;
+
+ if (res1 && fn != NULL)
+ {
+ fn(printer_name, station, level, *num, *ctr);
+ }
+
+ return res1;
+}
+
+static void spool_job_info_ctr( const char* printer_name,
+ const char* station,
+ uint32 level,
+ uint32 num, void *const *const ctr)
+{
+ display_job_info_ctr(out_hnd, ACTION_HEADER , level, num, ctr);
+ display_job_info_ctr(out_hnd, ACTION_ENUMERATE, level, num, ctr);
+ display_job_info_ctr(out_hnd, ACTION_FOOTER , level, num, ctr);
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+void cmd_spoolss_enum_jobs(struct client_info *info, int argc, char *argv[])
+{
+ fstring srv_name;
+ fstring station;
+ char *printer_name;
+
+ void **ctr = NULL;
+ uint32 num = 0;
+ uint32 level = 1;
+
+ if (argc < 2)
+ {
+ report(out_hnd, "spooljobs <printer name>\n");
+ return;
+ }
+
+ printer_name = argv[1];
+
+ fstrcpy(station, "\\\\");
+ fstrcat(station, info->myhostname);
+ strupper(station);
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ if (!strnequal("\\\\", printer_name, 2))
+ {
+ fstrcat(srv_name, "\\");
+ fstrcat(srv_name, printer_name);
+ printer_name = srv_name;
+ }
+
+ DEBUG(4,("spoolopen - printer: %s station: %s user: %s\n",
+ printer_name, station, usr_creds->ntc.user_name));
+
+ if (msrpc_spoolss_enum_jobs( printer_name, station,
+ usr_creds->ntc.user_name,
+ level, &num, &ctr,
+ spool_job_info_ctr))
+ {
+ DEBUG(5,("cmd_spoolss_enum_jobs: query succeeded\n"));
+ }
+ else
+ {
+ report(out_hnd, "FAILED\n");
+ }
+
+ free_void_array(num, ctr, free);
+}
+
diff --git a/source/rpcclient/cmd_srvsvc.c b/source/rpcclient/cmd_srvsvc.c
index 9deb9e801c6..c5e1e699723 100644
--- a/source/rpcclient/cmd_srvsvc.c
+++ b/source/rpcclient/cmd_srvsvc.c
@@ -2,8 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
NT Domain Authentication SMB / MSRPC client
- Copyright (C) Andrew Tridgell 1994-1997
- Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Andrew Tridgell 1994-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1999
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,56 +27,56 @@
#endif
#include "includes.h"
-#include "nterr.h"
+#include "rpc_parse.h"
+#include "rpcclient.h"
extern int DEBUGLEVEL;
#define DEBUG_TESTING
-extern struct cli_state *smb_cli;
-
extern FILE* out_hnd;
/****************************************************************************
server get info query
****************************************************************************/
-void cmd_srv_query_info(struct client_info *info)
+BOOL net_srv_get_info(struct client_info *info,
+ uint32 info_level,
+ SRV_INFO_CTR *ctr)
{
fstring dest_srv;
- fstring tmp;
- SRV_INFO_CTR ctr;
- uint32 info_level = 101;
BOOL res = True;
- memset((char *)&ctr, '\0', sizeof(ctr));
-
fstrcpy(dest_srv, "\\\\");
fstrcat(dest_srv, info->dest_host);
strupper(dest_srv);
- if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
- {
- info_level = (uint32)strtol(tmp, (char**)NULL, 10);
- }
-
- DEBUG(4,("cmd_srv_query_info: server:%s info level: %d\n",
+ DEBUG(4,("net_srv_get_info: server:%s info level: %d\n",
dest_srv, (int)info_level));
- DEBUG(5, ("cmd_srv_query_info: smb_cli->fd:%d\n", smb_cli->fd));
+ /* send info level: receive requested info. hopefully. */
+ res = res ? srv_net_srv_get_info(dest_srv, info_level, ctr) : False;
- /* open LSARPC session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
+ return res;
+}
- /* send info level: receive requested info. hopefully. */
- res = res ? do_srv_net_srv_get_info(smb_cli,
- dest_srv, info_level, &ctr) : False;
+/****************************************************************************
+server get info query
+****************************************************************************/
+void cmd_srv_query_info(struct client_info *info, int argc, char *argv[])
+{
+ uint32 info_level = 101;
+ SRV_INFO_CTR ctr;
- /* close the session */
- cli_nt_session_close(smb_cli);
+ ZERO_STRUCT(ctr);
- if (res)
+ if (argc > 1)
+ {
+ info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
+ }
+
+ if (net_srv_get_info(info, info_level, &ctr))
{
DEBUG(5,("cmd_srv_query_info: query succeeded\n"));
@@ -91,20 +91,82 @@ void cmd_srv_query_info(struct client_info *info)
}
/****************************************************************************
+server enum transports
+****************************************************************************/
+BOOL msrpc_srv_enum_tprt( const char* dest_srv,
+ uint32 info_level,
+ SRV_TPRT_INFO_CTR *ctr,
+ TPRT_INFO_FN(tprt_fn))
+{
+ BOOL res = True;
+ BOOL res1 = True;
+
+ ENUM_HND hnd;
+
+ hnd.ptr_hnd = 1;
+ hnd.handle = 0;
+
+ /* enumerate transports on server */
+ res1 = res ? srv_net_srv_tprt_enum(dest_srv,
+ info_level, ctr, 0xffffffff, &hnd) : False;
+
+ tprt_fn(ctr);
+
+ free_srv_tprt_ctr(ctr);
+
+ return res1;
+}
+
+static void srv_display_tprt_ctr(const SRV_TPRT_INFO_CTR *ctr)
+{
+ display_srv_tprt_info_ctr(out_hnd, ACTION_HEADER , ctr);
+ display_srv_tprt_info_ctr(out_hnd, ACTION_ENUMERATE, ctr);
+ display_srv_tprt_info_ctr(out_hnd, ACTION_FOOTER , ctr);
+}
+
+/****************************************************************************
+server enum transports
+****************************************************************************/
+void cmd_srv_enum_tprt(struct client_info *info, int argc, char *argv[])
+{
+ fstring dest_srv;
+ SRV_TPRT_INFO_CTR ctr;
+ uint32 info_level = 0;
+
+ ZERO_STRUCT(ctr);
+
+ fstrcpy(dest_srv, "\\\\");
+ fstrcat(dest_srv, info->dest_host);
+ strupper(dest_srv);
+
+ if (argc > 1)
+ {
+ info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
+ }
+
+ DEBUG(4,("cmd_srv_enum_tprt: server:%s info level: %d\n",
+ dest_srv, (int)info_level));
+
+ /* enumerate transports on server */
+ msrpc_srv_enum_tprt(dest_srv,
+ info_level, &ctr,
+ srv_display_tprt_ctr);
+}
+
+/****************************************************************************
server enum connections
****************************************************************************/
-void cmd_srv_enum_conn(struct client_info *info)
+void cmd_srv_enum_conn(struct client_info *info, int argc, char *argv[])
{
fstring dest_srv;
fstring qual_srv;
- fstring tmp;
SRV_CONN_INFO_CTR ctr;
ENUM_HND hnd;
uint32 info_level = 0;
BOOL res = True;
- memset((char *)&ctr, '\0', sizeof(ctr));
+ ZERO_STRUCT(ctr);
fstrcpy(qual_srv, "\\\\");
fstrcat(qual_srv, info->myhostname);
@@ -114,25 +176,19 @@ void cmd_srv_enum_conn(struct client_info *info)
fstrcat(dest_srv, info->dest_host);
strupper(dest_srv);
- if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
+ if (argc > 1)
{
- info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
}
DEBUG(4,("cmd_srv_enum_conn: server:%s info level: %d\n",
dest_srv, (int)info_level));
- DEBUG(5, ("cmd_srv_enum_conn: smb_cli->fd:%d\n", smb_cli->fd));
-
- /* open srvsvc session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
-
hnd.ptr_hnd = 1;
hnd.handle = 0;
/* enumerate connections on server */
- res = res ? do_srv_net_srv_conn_enum(smb_cli,
- dest_srv, qual_srv,
+ res = res ? srv_net_srv_conn_enum(dest_srv, qual_srv,
info_level, &ctr, 0xffffffff, &hnd) : False;
if (res)
@@ -142,9 +198,6 @@ void cmd_srv_enum_conn(struct client_info *info)
display_srv_conn_info_ctr(out_hnd, ACTION_FOOTER , &ctr);
}
- /* close the session */
- cli_nt_session_close(smb_cli);
-
if (res)
{
DEBUG(5,("cmd_srv_enum_conn: query succeeded\n"));
@@ -158,51 +211,44 @@ void cmd_srv_enum_conn(struct client_info *info)
/****************************************************************************
server enum shares
****************************************************************************/
-void cmd_srv_enum_shares(struct client_info *info)
+void cmd_srv_enum_shares(struct client_info *info, int argc, char *argv[])
{
fstring dest_srv;
- fstring tmp;
- SRV_R_NET_SHARE_ENUM r_o;
+ SRV_SHARE_INFO_CTR ctr;
ENUM_HND hnd;
uint32 info_level = 1;
BOOL res = True;
+ ZERO_STRUCT(ctr);
+
fstrcpy(dest_srv, "\\\\");
fstrcat(dest_srv, info->dest_host);
strupper(dest_srv);
- if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
+ if (argc > 1)
{
- info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
}
DEBUG(4,("cmd_srv_enum_shares: server:%s info level: %d\n",
dest_srv, (int)info_level));
- DEBUG(5, ("cmd_srv_enum_shares: smb_cli->fd:%d\n", smb_cli->fd));
-
- /* open srvsvc session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
-
hnd.ptr_hnd = 0;
hnd.handle = 0;
/* enumerate shares_files on server */
- res = res ? do_srv_net_srv_share_enum(smb_cli,
- dest_srv,
- info_level, &r_o, 0xffffffff, &hnd) : False;
+ res = res ? srv_net_srv_share_enum(dest_srv,
+ info_level, &ctr, 0xffffffff, &hnd) : False;
if (res)
{
- display_srv_share_info_ctr(out_hnd, ACTION_HEADER , &r_o.ctr);
- display_srv_share_info_ctr(out_hnd, ACTION_ENUMERATE, &r_o.ctr);
- display_srv_share_info_ctr(out_hnd, ACTION_FOOTER , &r_o.ctr);
- free_srv_r_net_share_enum(&r_o);
+ display_srv_share_info_ctr(out_hnd, ACTION_HEADER , &ctr);
+ display_srv_share_info_ctr(out_hnd, ACTION_ENUMERATE, &ctr);
+ display_srv_share_info_ctr(out_hnd, ACTION_FOOTER , &ctr);
}
- /* close the session */
- cli_nt_session_close(smb_cli);
+ srv_free_srv_share_ctr(&ctr);
if (res)
{
@@ -215,46 +261,91 @@ void cmd_srv_enum_shares(struct client_info *info)
}
/****************************************************************************
+share get info
+****************************************************************************/
+void cmd_srv_share_get_info(struct client_info *info, int argc, char *argv[])
+{
+ fstring dest_srv;
+ const char *share_name;
+ uint32 info_level = 502;
+
+ BOOL res = True;
+
+ fstrcpy(dest_srv, "\\\\");
+ fstrcat(dest_srv, info->dest_host);
+ strupper(dest_srv);
+
+ if (argc < 2)
+ {
+ report(out_hnd, "srvshareinfo SHARE [502|1|2]\n");
+ return;
+ }
+
+ share_name = argv[1];
+
+ if (argc > 2)
+ {
+ info_level = (uint32)strtol(argv[2], (char**)NULL, 10);
+ }
+
+ DEBUG(4,
+ ("cmd_srv_share_get_info: server:%s, share:%s, info level:%d\n",
+ dest_srv, share_name, (int)info_level));
+
+ /* enumerate shares_files on server */
+ res = res
+ ? srv_net_srv_share_get_info(dest_srv, share_name, info_level)
+ : False;
+
+ if (res)
+ {
+ DEBUG(5,("cmd_srv_share_get_info: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_srv_share_get_info: query failed\n"));
+ }
+}
+
+/****************************************************************************
server enum sessions
****************************************************************************/
-void cmd_srv_enum_sess(struct client_info *info)
+void cmd_srv_enum_sess(struct client_info *info, int argc, char *argv[])
{
fstring dest_srv;
- fstring tmp;
SRV_SESS_INFO_CTR ctr;
ENUM_HND hnd;
uint32 info_level = 0;
BOOL res = True;
- memset((char *)&ctr, '\0', sizeof(ctr));
+ ZERO_STRUCT(ctr);
fstrcpy(dest_srv, "\\\\");
fstrcat(dest_srv, info->dest_host);
strupper(dest_srv);
- if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
+ if (argc > 1)
{
- info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
}
DEBUG(4,("cmd_srv_enum_sess: server:%s info level: %d\n",
dest_srv, (int)info_level));
- DEBUG(5, ("cmd_srv_enum_sess: smb_cli->fd:%d\n", smb_cli->fd));
-
- /* open srvsvc session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
-
hnd.ptr_hnd = 1;
hnd.handle = 0;
/* enumerate sessions on server */
- res = res ? do_srv_net_srv_sess_enum(smb_cli,
- dest_srv, NULL, info_level, &ctr, 0x1000, &hnd) : False;
+ res = res ? srv_net_srv_sess_enum(dest_srv, NULL, NULL,
+ info_level, &ctr, 0x1000, &hnd) : False;
- /* close the session */
- cli_nt_session_close(smb_cli);
+ if (res)
+ {
+ display_srv_sess_info_ctr(out_hnd, ACTION_HEADER , &ctr);
+ display_srv_sess_info_ctr(out_hnd, ACTION_ENUMERATE, &ctr);
+ display_srv_sess_info_ctr(out_hnd, ACTION_FOOTER , &ctr);
+ }
if (res)
{
@@ -269,42 +360,35 @@ void cmd_srv_enum_sess(struct client_info *info)
/****************************************************************************
server enum files
****************************************************************************/
-void cmd_srv_enum_files(struct client_info *info)
+void cmd_srv_enum_files(struct client_info *info, int argc, char *argv[])
{
fstring dest_srv;
- fstring tmp;
SRV_FILE_INFO_CTR ctr;
ENUM_HND hnd;
uint32 info_level = 3;
BOOL res = True;
- memset((char *)&ctr, '\0', sizeof(ctr));
+ ZERO_STRUCT(ctr);
fstrcpy(dest_srv, "\\\\");
fstrcat(dest_srv, info->dest_host);
strupper(dest_srv);
- if (next_token(NULL, tmp, NULL, sizeof(tmp)-1))
+ if (argc > 1)
{
- info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
}
DEBUG(4,("cmd_srv_enum_files: server:%s info level: %d\n",
dest_srv, (int)info_level));
- DEBUG(5, ("cmd_srv_enum_files: smb_cli->fd:%d\n", smb_cli->fd));
-
- /* open srvsvc session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_SRVSVC) : False;
-
hnd.ptr_hnd = 1;
hnd.handle = 0;
/* enumerate files on server */
- res = res ? do_srv_net_srv_file_enum(smb_cli,
- dest_srv, NULL, info_level, &ctr, 0x1000, &hnd) : False;
-
+ res = res ? srv_net_srv_file_enum(dest_srv, NULL, 0,
+ info_level, &ctr, 0x1000, &hnd) : False;
if (res)
{
@@ -313,8 +397,7 @@ void cmd_srv_enum_files(struct client_info *info)
display_srv_file_info_ctr(out_hnd, ACTION_FOOTER , &ctr);
}
- /* close the session */
- cli_nt_session_close(smb_cli);
+ srv_free_srv_file_ctr(&ctr);
if (res)
{
@@ -326,3 +409,36 @@ void cmd_srv_enum_files(struct client_info *info)
}
}
+/****************************************************************************
+display remote time
+****************************************************************************/
+void cmd_time(struct client_info *info, int argc, char *argv[])
+{
+ fstring dest_srv;
+ TIME_OF_DAY_INFO tod;
+ BOOL res = True;
+
+ fstrcpy(dest_srv, "\\\\");
+ fstrcat(dest_srv, info->dest_host);
+ strupper(dest_srv);
+
+ DEBUG(4,("cmd_time: server:%s\n", dest_srv));
+
+ /* enumerate files on server */
+ res = res ? srv_net_remote_tod(dest_srv, &tod) : False;
+
+ if (res)
+ {
+ fprintf(out_hnd, "\tRemote Time:\t%s\n\n",
+ http_timestring(tod.elapsedt));
+ }
+
+ if (res)
+ {
+ DEBUG(5,("cmd_srv_enum_files: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_srv_enum_files: query failed\n"));
+ }
+}
diff --git a/source/rpcclient/cmd_svcctl.c b/source/rpcclient/cmd_svcctl.c
new file mode 100644
index 00000000000..d118a7d15db
--- /dev/null
+++ b/source/rpcclient/cmd_svcctl.c
@@ -0,0 +1,407 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+
+#ifdef SYSLOG
+#undef SYSLOG
+#endif
+
+#include "includes.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+extern FILE* out_hnd;
+
+void svc_display_query_svc_cfg(const QUERY_SERVICE_CONFIG *cfg)
+{
+ display_query_svc_cfg(out_hnd, ACTION_HEADER , cfg);
+ display_query_svc_cfg(out_hnd, ACTION_ENUMERATE, cfg);
+ display_query_svc_cfg(out_hnd, ACTION_FOOTER , cfg);
+}
+
+BOOL svc_query_service( POLICY_HND *pol_scm,
+ const char *svc_name,
+ SVC_QUERY_FN(svc_query_fn))
+{
+ BOOL res2 = True;
+ BOOL res3;
+ POLICY_HND pol_svc;
+ QUERY_SERVICE_CONFIG cfg;
+ uint32 svc_buf_size = 0x8000;
+
+ res2 = res2 ? svc_open_service( pol_scm,
+ svc_name, 0x80000001,
+ &pol_svc) : False;
+ res3 = res2 ? svc_query_svc_cfg( &pol_svc, &cfg,
+ &svc_buf_size) : False;
+
+ if (res3 && svc_query_fn != NULL)
+ {
+ svc_query_fn(&cfg);
+ }
+
+ res2 = res2 ? svc_close(&pol_svc) : False;
+
+ return res3;
+}
+
+/****************************************************************************
+nt service info
+****************************************************************************/
+void cmd_svc_info(struct client_info *info, int argc, char *argv[])
+{
+ BOOL res = True;
+ BOOL res1 = True;
+ char *svc_name;
+
+ POLICY_HND pol_scm;
+
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ DEBUG(4,("cmd_svc_info: server:%s\n", srv_name));
+
+ if (argc < 2)
+ {
+ report(out_hnd,"svcinfo <service name>\n");
+ return;
+ }
+
+ svc_name = argv[1];
+
+ /* open service control manager receive a policy handle */
+ res = res ? svc_open_sc_man( srv_name, NULL, 0x80000004,
+ &pol_scm) : False;
+
+ res1 = svc_query_service(&pol_scm, svc_name,
+ svc_display_query_svc_cfg);
+
+ res = res ? svc_close(&pol_scm) : False;
+
+ if (res && res1)
+ {
+ DEBUG(5,("cmd_svc_info: query succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_svc_info: query failed\n"));
+ }
+}
+
+static void svc_display_svc_info(const ENUM_SRVC_STATUS *svc)
+{
+ display_svc_info(out_hnd, ACTION_HEADER , svc);
+ display_svc_info(out_hnd, ACTION_ENUMERATE, svc);
+ display_svc_info(out_hnd, ACTION_FOOTER , svc);
+}
+
+/****************************************************************************
+nt service enum
+****************************************************************************/
+BOOL msrpc_svc_enum(const char* srv_name,
+ ENUM_SRVC_STATUS **svcs,
+ uint32 *num_svcs,
+ SVC_INFO_FN(info_fn),
+ SVC_QUERY_FN(query_fn))
+{
+ BOOL res = True;
+ BOOL res1 = False;
+ int i;
+ uint32 resume_hnd = 0;
+ uint32 buf_size = 0;
+ uint32 dos_error = 0;
+
+ POLICY_HND pol_scm;
+
+ (*svcs) = NULL;
+ (*num_svcs) = 0;
+
+ /* open service control manager receive a policy handle */
+ res = res ? svc_open_sc_man( srv_name, NULL, 0x80000004,
+ &pol_scm) : False;
+
+ do
+ {
+ if ((*svcs) != NULL)
+ {
+ free(*svcs);
+ (*svcs) = NULL;
+ (*num_svcs) = 0;
+ }
+
+ buf_size += 0x800;
+
+ /* enumerate services */
+ res1 = res ? svc_enum_svcs( &pol_scm,
+ 0x00000030, 0x00000003,
+ &buf_size, &resume_hnd, &dos_error,
+ svcs, num_svcs) : False;
+
+ } while (res1 && dos_error == ERRmoredata);
+
+ for (i = 0; i < (*num_svcs) && (*svcs) != NULL && res1; i++)
+ {
+ fstring svc_name;
+
+ unistr_to_ascii(svc_name, (*svcs)[i].uni_srvc_name.buffer,
+ sizeof(svc_name)-1);
+
+ if (query_fn != NULL)
+ {
+ res1 = svc_query_service(&pol_scm,
+ svc_name, query_fn);
+ }
+ else if (info_fn != NULL)
+ {
+ info_fn(&(*svcs)[i]);
+ }
+ }
+
+ res = res ? svc_close(&pol_scm) : False;
+
+ return res1;
+}
+
+/****************************************************************************
+nt service enum
+****************************************************************************/
+void cmd_svc_enum(struct client_info *info, int argc, char *argv[])
+{
+ ENUM_SRVC_STATUS *svcs = NULL;
+ uint32 num_svcs = 0;
+ BOOL request_info = False;
+ int opt;
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ while ((opt = getopt(argc, argv,"i")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'i':
+ {
+ request_info = True;
+ break;
+ }
+ }
+ }
+
+ report(out_hnd,"Services\n");
+ report(out_hnd,"--------\n");
+
+ msrpc_svc_enum(srv_name, &svcs, &num_svcs,
+ request_info ? NULL : svc_display_svc_info,
+ request_info ? svc_display_query_svc_cfg : NULL);
+
+ if (svcs != NULL)
+ {
+ free(svcs);
+ }
+}
+
+/****************************************************************************
+nt stop service
+****************************************************************************/
+void cmd_svc_stop(struct client_info *info, int argc, char *argv[])
+{
+ BOOL res = True;
+ BOOL res1 = True;
+ char *svc_name;
+ BOOL res2 = True;
+ POLICY_HND pol_svc;
+ POLICY_HND pol_scm;
+
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ DEBUG(4,("cmd_svc_stop: server:%s\n", srv_name));
+
+ if (argc < 2)
+ {
+ report(out_hnd,"svcstop <service name>\n");
+ return;
+ }
+
+ svc_name = argv[1];
+
+ /* open service control manager receive a policy handle */
+ res = res ? svc_open_sc_man( srv_name, NULL, 0x80000000,
+ &pol_scm) : False;
+
+ res1 = res ? svc_open_service( &pol_scm,
+ svc_name, 0x00000020,
+ &pol_svc) : False;
+ res2 = res1 ? svc_stop_service(&pol_svc, 0x1) : False;
+
+ res1 = res1 ? svc_close(&pol_svc) : False;
+ res = res ? svc_close(&pol_scm) : False;
+
+ if (res2)
+ {
+ report(out_hnd,"Stopped Service %s\n", svc_name);
+ DEBUG(5,("cmd_svc_stop: succeeded\n"));
+ }
+ else
+ report(out_hnd,"Failed Service Stopped (%s)\n", svc_name);
+ {
+ DEBUG(5,("cmd_svc_stop: failed\n"));
+ }
+}
+
+/****************************************************************************
+nt start service
+****************************************************************************/
+void cmd_svc_start(struct client_info *info, int argc, char *argv[])
+{
+ BOOL res = True;
+ BOOL res1 = True;
+ char *svc_name;
+ BOOL res2 = True;
+ POLICY_HND pol_svc;
+ POLICY_HND pol_scm;
+
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ DEBUG(4,("cmd_svc_start: server:%s\n", srv_name));
+
+ if (argc < 2)
+ {
+ report(out_hnd,"svcstart <service name> [arg 0] [arg 1]...]\n");
+ return;
+ }
+
+ argv++;
+ argc--;
+
+ svc_name = argv[0];
+
+ argv++;
+ argc--;
+
+ /* open service control manager receive a policy handle */
+ res = res ? svc_open_sc_man( srv_name, NULL, 0x80000000,
+ &pol_scm) : False;
+
+ res1 = res ? svc_open_service( &pol_scm,
+ svc_name, 0x80000010,
+ &pol_svc) : False;
+ res2 = res1 ? svc_start_service( &pol_svc, argc, argv) : False;
+
+ res1 = res1 ? svc_close(&pol_svc) : False;
+ res = res ? svc_close(&pol_scm) : False;
+
+ if (res2)
+ {
+ report(out_hnd,"Started Service %s\n", svc_name);
+ DEBUG(5,("cmd_svc_start: succeeded\n"));
+ }
+ else
+ report(out_hnd,"Failed Service Startup (%s)\n", svc_name);
+ {
+ DEBUG(5,("cmd_svc_start: failed\n"));
+ }
+}
+
+/****************************************************************************
+nt service set
+****************************************************************************/
+void cmd_svc_set(struct client_info *info, int argc, char *argv[])
+{
+ BOOL res = True;
+ BOOL res2 = True;
+ BOOL res3;
+ POLICY_HND pol_svc;
+ QUERY_SERVICE_CONFIG cfg;
+ uint32 svc_buf_size = 0x8000;
+
+ char *svc_name;
+
+ POLICY_HND pol_scm;
+
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
+
+ DEBUG(4,("cmd_svc_set: server:%s\n", srv_name));
+
+ if (argc < 2)
+ {
+ report(out_hnd,"svcset <service name>\n");
+ return;
+ }
+
+ svc_name = argv[1];
+
+ /* open service control manager receive a policy handle */
+ res = res ? svc_open_sc_man( srv_name, NULL, 0x80000004,
+ &pol_scm) : False;
+
+ res2 = res ? svc_open_service( &pol_scm,
+ svc_name, 0x80000001,
+ &pol_svc) : False;
+ res3 = res2 ? svc_query_svc_cfg( &pol_svc, &cfg,
+ &svc_buf_size) : False;
+
+ if (res3)
+ {
+ res3 = svc_change_svc_cfg(&pol_svc,
+ cfg.service_type,
+ cfg.start_type,
+ 0xffffffff,
+ 0,
+ NULL, NULL,
+ cfg.tag_id,
+ NULL, "administrator", NULL, NULL);
+
+ }
+
+ res2 = res2 ? svc_close(&pol_svc) : False;
+
+ res = res ? svc_close(&pol_scm) : False;
+
+ if (res3)
+ {
+ DEBUG(5,("cmd_svc_set: change succeeded\n"));
+ }
+ else
+ {
+ DEBUG(5,("cmd_svc_set: change failed\n"));
+ }
+}
+
diff --git a/source/rpcclient/cmd_wkssvc.c b/source/rpcclient/cmd_wkssvc.c
index 0b8f469af37..474c53f347e 100644
--- a/source/rpcclient/cmd_wkssvc.c
+++ b/source/rpcclient/cmd_wkssvc.c
@@ -33,48 +33,36 @@ extern int DEBUGLEVEL;
#define DEBUG_TESTING
-extern struct cli_state *smb_cli;
-
extern FILE* out_hnd;
/****************************************************************************
workstation get info query
****************************************************************************/
-void cmd_wks_query_info(struct client_info *info)
+void cmd_wks_query_info(struct client_info *info, int argc, char *argv[])
{
fstring dest_wks;
- fstring tmp;
WKS_INFO_100 ctr;
uint32 info_level = 100;
BOOL res = True;
- memset((char *)&ctr, '\0', sizeof(ctr));
+ bzero(&ctr, sizeof(ctr));
fstrcpy(dest_wks, "\\\\");
fstrcat(dest_wks, info->dest_host);
strupper(dest_wks);
- if (next_token(NULL, tmp, NULL, sizeof(tmp)))
+ if (argc > 1)
{
- info_level = (uint32)strtol(tmp, (char**)NULL, 10);
+ info_level = (uint32)strtol(argv[1], (char**)NULL, 10);
}
DEBUG(4,("cmd_wks_query_info: server:%s info level: %d\n",
dest_wks, info_level));
- DEBUG(5, ("cmd_wks_query_info: smb_cli->fd:%d\n", smb_cli->fd));
-
- /* open LSARPC session. */
- res = res ? cli_nt_session_open(smb_cli, PIPE_WKSSVC) : False;
-
/* send info level: receive requested info. hopefully. */
- res = res ? do_wks_query_info(smb_cli,
- dest_wks, info_level, &ctr) : False;
-
- /* close the session */
- cli_nt_session_close(smb_cli);
+ res = res ? wks_query_info( dest_wks, info_level, &ctr) : False;
if (res)
{
diff --git a/source/rpcclient/cmdat.c b/source/rpcclient/cmdat.c
new file mode 100644
index 00000000000..efdd9237239
--- /dev/null
+++ b/source/rpcclient/cmdat.c
@@ -0,0 +1,35 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+
+ int main(int argc, char *argv[])
+{
+ add_at_commands();
+
+ return command_main(argc, argv);
+}
diff --git a/source/rpcclient/cmdat_cmds.c b/source/rpcclient/cmdat_cmds.c
new file mode 100644
index 00000000000..80d858453c9
--- /dev/null
+++ b/source/rpcclient/cmdat_cmds.c
@@ -0,0 +1,57 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "ntdomain.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+static const struct command_set at_commands[] =
+{
+ /*
+ * scheduler
+ */
+
+ {
+ "at",
+ cmd_at,
+ "Scheduler control (at /? for syntax)",
+ {NULL, NULL}
+ },
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
+ }
+};
+
+void add_at_commands(void)
+{
+ add_command_set(at_commands);
+}
diff --git a/source/rpcclient/display.c b/source/rpcclient/display.c
deleted file mode 100644
index ddbe435d757..00000000000
--- a/source/rpcclient/display.c
+++ /dev/null
@@ -1,1325 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- Samba utility functions
- Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Luke Kenneth Casson Leighton 1996 - 1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "includes.h"
-
-
-/****************************************************************************
-convert a share mode to a string
-****************************************************************************/
-char *get_file_mode_str(uint32 share_mode)
-{
- static fstring mode;
-
- switch (GET_DENY_MODE(share_mode))
- {
- case DENY_NONE : fstrcpy(mode, "DENY_NONE "); break;
- case DENY_ALL : fstrcpy(mode, "DENY_ALL "); break;
- case DENY_DOS : fstrcpy(mode, "DENY_DOS "); break;
- case DENY_READ : fstrcpy(mode, "DENY_READ "); break;
- case DENY_WRITE: fstrcpy(mode, "DENY_WRITE "); break;
- case DENY_FCB: fstrcpy(mode, "DENY_FCB "); break;
- default : fstrcpy(mode, "DENY_???? "); break;
- }
-
- switch (share_mode & 0xF)
- {
- case 0 : fstrcat(mode, "RDONLY"); break;
- case 1 : fstrcat(mode, "WRONLY"); break;
- case 2 : fstrcat(mode, "RDWR "); break;
- default: fstrcat(mode, "R??W??"); break;
- }
-
- return mode;
-}
-
-/****************************************************************************
-convert an oplock mode to a string
-****************************************************************************/
-char *get_file_oplock_str(uint32 op_type)
-{
- static fstring oplock;
- BOOL excl = IS_BITS_SET_ALL(op_type, EXCLUSIVE_OPLOCK);
- BOOL batch = IS_BITS_SET_ALL(op_type, BATCH_OPLOCK );
-
- oplock[0] = 0;
-
- if (excl ) fstrcat(oplock, "EXCLUSIVE");
- if (excl && batch) fstrcat(oplock, "+");
- if ( batch) fstrcat(oplock, "BATCH");
- if (!excl && !batch) fstrcat(oplock, "NONE");
-
- return oplock;
-}
-
-/****************************************************************************
-convert a share type enum to a string
-****************************************************************************/
-char *get_share_type_str(uint32 type)
-{
- static fstring typestr;
-
- switch (type)
- {
- case STYPE_DISKTREE: fstrcpy(typestr, "Disk" ); break;
- case STYPE_PRINTQ : fstrcpy(typestr, "Printer"); break;
- case STYPE_DEVICE : fstrcpy(typestr, "Device" ); break;
- case STYPE_IPC : fstrcpy(typestr, "IPC" ); break;
- default : fstrcpy(typestr, "????" ); break;
- }
- return typestr;
-}
-
-/****************************************************************************
-convert a server type enum to a string
-****************************************************************************/
-char *get_server_type_str(uint32 type)
-{
- static fstring typestr;
-
- if (type == SV_TYPE_ALL)
- {
- fstrcpy(typestr, "All");
- }
- else
- {
- int i;
- typestr[0] = 0;
- for (i = 0; i < 32; i++)
- {
- if (IS_BITS_SET_ALL(type, 1 << i))
- {
- switch (((unsigned)1) << i)
- {
- case SV_TYPE_WORKSTATION : fstrcat(typestr, "Wk " ); break;
- case SV_TYPE_SERVER : fstrcat(typestr, "Sv " ); break;
- case SV_TYPE_SQLSERVER : fstrcat(typestr, "Sql "); break;
- case SV_TYPE_DOMAIN_CTRL : fstrcat(typestr, "PDC "); break;
- case SV_TYPE_DOMAIN_BAKCTRL : fstrcat(typestr, "BDC "); break;
- case SV_TYPE_TIME_SOURCE : fstrcat(typestr, "Tim "); break;
- case SV_TYPE_AFP : fstrcat(typestr, "AFP "); break;
- case SV_TYPE_NOVELL : fstrcat(typestr, "Nov "); break;
- case SV_TYPE_DOMAIN_MEMBER : fstrcat(typestr, "Dom "); break;
- case SV_TYPE_PRINTQ_SERVER : fstrcat(typestr, "PrQ "); break;
- case SV_TYPE_DIALIN_SERVER : fstrcat(typestr, "Din "); break;
- case SV_TYPE_SERVER_UNIX : fstrcat(typestr, "Unx "); break;
- case SV_TYPE_NT : fstrcat(typestr, "NT " ); break;
- case SV_TYPE_WFW : fstrcat(typestr, "Wfw "); break;
- case SV_TYPE_SERVER_MFPN : fstrcat(typestr, "Mfp "); break;
- case SV_TYPE_SERVER_NT : fstrcat(typestr, "SNT "); break;
- case SV_TYPE_POTENTIAL_BROWSER: fstrcat(typestr, "PtB "); break;
- case SV_TYPE_BACKUP_BROWSER : fstrcat(typestr, "BMB "); break;
- case SV_TYPE_MASTER_BROWSER : fstrcat(typestr, "LMB "); break;
- case SV_TYPE_DOMAIN_MASTER : fstrcat(typestr, "DMB "); break;
- case SV_TYPE_SERVER_OSF : fstrcat(typestr, "OSF "); break;
- case SV_TYPE_SERVER_VMS : fstrcat(typestr, "VMS "); break;
- case SV_TYPE_WIN95_PLUS : fstrcat(typestr, "W95 "); break;
- case SV_TYPE_ALTERNATE_XPORT : fstrcat(typestr, "Xpt "); break;
- case SV_TYPE_LOCAL_LIST_ONLY : fstrcat(typestr, "Dom "); break;
- case SV_TYPE_DOMAIN_ENUM : fstrcat(typestr, "Loc "); break;
- }
- }
- }
- i = strlen(typestr)-1;
- if (typestr[i] == ' ') typestr[i] = 0;
-
- }
- return typestr;
-}
-
-/****************************************************************************
-server info level 101 display function
-****************************************************************************/
-void display_srv_info_101(FILE *out_hnd, enum action_type action,
- SRV_INFO_101 *sv101)
-{
- if (sv101 == NULL)
- {
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "Server Info Level 101:\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- fstring name;
- fstring comment;
-
- fstrcpy(name , dos_unistrn2(sv101->uni_name .buffer, sv101->uni_name .uni_str_len));
- fstrcpy(comment , dos_unistrn2(sv101->uni_comment .buffer, sv101->uni_comment .uni_str_len));
-
- display_server(out_hnd, action, name, sv101->srv_type, comment);
-
- fprintf(out_hnd, "\tplatform_id : %d\n" , sv101->platform_id);
- fprintf(out_hnd, "\tos version : %d.%d\n" , sv101->ver_major, sv101->ver_minor);
-
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-
-}
-
-/****************************************************************************
-server info level 102 display function
-****************************************************************************/
-void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102)
-{
- if (sv102 == NULL)
- {
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "Server Info Level 102:\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- fstring name;
- fstring comment;
- fstring usr_path;
-
- fstrcpy(name , dos_unistrn2(sv102->uni_name .buffer, sv102->uni_name .uni_str_len));
- fstrcpy(comment , dos_unistrn2(sv102->uni_comment .buffer, sv102->uni_comment .uni_str_len));
- fstrcpy(usr_path, dos_unistrn2(sv102->uni_usr_path.buffer, sv102->uni_usr_path.uni_str_len));
-
- display_server(out_hnd, action, name, sv102->srv_type, comment);
-
- fprintf(out_hnd, "\tplatform_id : %d\n" , sv102->platform_id);
- fprintf(out_hnd, "\tos version : %d.%d\n" , sv102->ver_major, sv102->ver_minor);
-
- fprintf(out_hnd, "\tusers : %x\n" , sv102->users );
- fprintf(out_hnd, "\tdisc, hidden : %x,%x\n" , sv102->disc , sv102->hidden );
- fprintf(out_hnd, "\tannounce, delta : %d, %d\n", sv102->announce , sv102->ann_delta);
- fprintf(out_hnd, "\tlicenses : %d\n" , sv102->licenses );
- fprintf(out_hnd, "\tuser path : %s\n" , usr_path);
-
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-/****************************************************************************
-server info container display function
-****************************************************************************/
-void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr)
-{
- if (ctr == NULL || ctr->ptr_srv_ctr == 0)
- {
- fprintf(out_hnd, "Server Information: unavailable due to an error\n");
- return;
- }
-
- switch (ctr->switch_value)
- {
- case 101:
- {
- display_srv_info_101(out_hnd, action, &(ctr->srv.sv101));
- break;
- }
- case 102:
- {
- display_srv_info_102(out_hnd, action, &(ctr->srv.sv102));
- break;
- }
- default:
- {
- fprintf(out_hnd, "Server Information: Unknown Info Level\n");
- break;
- }
- }
-}
-
-/****************************************************************************
-connection info level 0 display function
-****************************************************************************/
-void display_conn_info_0(FILE *out_hnd, enum action_type action,
- CONN_INFO_0 *info0)
-{
- if (info0 == NULL)
- {
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "Connection Info Level 0:\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- fprintf(out_hnd, "\tid: %d\n", info0->id);
-
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-
-}
-
-/****************************************************************************
-connection info level 1 display function
-****************************************************************************/
-void display_conn_info_1(FILE *out_hnd, enum action_type action,
- CONN_INFO_1 *info1, CONN_INFO_1_STR *str1)
-{
- if (info1 == NULL || str1 == NULL)
- {
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "Connection Info Level 1:\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- fstring usr_name;
- fstring net_name;
-
- fstrcpy(usr_name, dos_unistrn2(str1->uni_usr_name.buffer, str1->uni_usr_name.uni_str_len));
- fstrcpy(net_name, dos_unistrn2(str1->uni_net_name.buffer, str1->uni_net_name.uni_str_len));
-
- fprintf(out_hnd, "\tid : %d\n", info1->id);
- fprintf(out_hnd, "\ttype : %s\n", get_share_type_str(info1->type));
- fprintf(out_hnd, "\tnum_opens: %d\n", info1->num_opens);
- fprintf(out_hnd, "\tnum_users: %d\n", info1->num_users);
- fprintf(out_hnd, "\topen_time: %d\n", info1->open_time);
-
- fprintf(out_hnd, "\tuser name: %s\n", usr_name);
- fprintf(out_hnd, "\tnet name: %s\n", net_name);
-
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-
-}
-
-/****************************************************************************
-connection info level 0 container display function
-****************************************************************************/
-void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action,
- SRV_CONN_INFO_0 *ctr)
-{
- if (ctr == NULL)
- {
- fprintf(out_hnd, "display_srv_conn_info_0_ctr: unavailable due to an internal error\n");
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- int i;
-
- for (i = 0; i < ctr->num_entries_read; i++)
- {
- display_conn_info_0(out_hnd, ACTION_HEADER , &(ctr->info_0[i]));
- display_conn_info_0(out_hnd, ACTION_ENUMERATE, &(ctr->info_0[i]));
- display_conn_info_0(out_hnd, ACTION_FOOTER , &(ctr->info_0[i]));
- }
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-/****************************************************************************
-connection info level 1 container display function
-****************************************************************************/
-void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action,
- SRV_CONN_INFO_1 *ctr)
-{
- if (ctr == NULL)
- {
- fprintf(out_hnd, "display_srv_conn_info_1_ctr: unavailable due to an internal error\n");
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- int i;
-
- for (i = 0; i < ctr->num_entries_read; i++)
- {
- display_conn_info_1(out_hnd, ACTION_HEADER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
- display_conn_info_1(out_hnd, ACTION_ENUMERATE, &(ctr->info_1[i]), &(ctr->info_1_str[i]));
- display_conn_info_1(out_hnd, ACTION_FOOTER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
- }
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-/****************************************************************************
-connection info container display function
-****************************************************************************/
-void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action,
- SRV_CONN_INFO_CTR *ctr)
-{
- if (ctr == NULL || ctr->ptr_conn_ctr == 0)
- {
- fprintf(out_hnd, "display_srv_conn_info_ctr: unavailable due to an internal error\n");
- return;
- }
-
- switch (ctr->switch_value)
- {
- case 0:
- {
- display_srv_conn_info_0_ctr(out_hnd, action,
- &(ctr->conn.info0));
- break;
- }
- case 1:
- {
- display_srv_conn_info_1_ctr(out_hnd, action,
- &(ctr->conn.info1));
- break;
- }
- default:
- {
- fprintf(out_hnd, "display_srv_conn_info_ctr: Unknown Info Level\n");
- break;
- }
- }
-}
-
-
-/****************************************************************************
-share info level 1 display function
-****************************************************************************/
-void display_share_info_1(FILE *out_hnd, enum action_type action,
- SRV_SHARE_INFO_1 *info1)
-{
- if (info1 == NULL)
- {
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "Share Info Level 1:\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- fstring remark ;
- fstring net_name;
-
- fstrcpy(net_name, dos_unistrn2(info1->info_1_str.uni_netname.buffer, info1->info_1_str.uni_netname.uni_str_len));
- fstrcpy(remark , dos_unistrn2(info1->info_1_str.uni_remark .buffer, info1->info_1_str.uni_remark .uni_str_len));
-
- display_share(out_hnd, action, net_name, info1->info_1.type, remark);
-
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-
-}
-
-/****************************************************************************
-share info level 2 display function
-****************************************************************************/
-void display_share_info_2(FILE *out_hnd, enum action_type action,
- SRV_SHARE_INFO_2 *info2)
-{
- if (info2 == NULL)
- {
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "Share Info Level 2:\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- fstring remark ;
- fstring net_name;
- fstring path ;
- fstring passwd ;
-
- fstrcpy(net_name, dos_unistrn2(info2->info_2_str.uni_netname.buffer, info2->info_2_str.uni_netname.uni_str_len));
- fstrcpy(remark , dos_unistrn2(info2->info_2_str.uni_remark .buffer, info2->info_2_str.uni_remark .uni_str_len));
- fstrcpy(path , dos_unistrn2(info2->info_2_str.uni_path .buffer, info2->info_2_str.uni_path .uni_str_len));
- fstrcpy(passwd , dos_unistrn2(info2->info_2_str.uni_passwd .buffer, info2->info_2_str.uni_passwd .uni_str_len));
-
- display_share2(out_hnd, action, net_name,
- info2->info_2.type, remark, info2->info_2.perms,
- info2->info_2.max_uses, info2->info_2.num_uses,
- path, passwd);
-
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-
-}
-
-/****************************************************************************
-share info container display function
-****************************************************************************/
-void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action,
- SRV_SHARE_INFO_CTR *ctr)
-{
- if (ctr == NULL)
- {
- fprintf(out_hnd, "display_srv_share_info_ctr: unavailable due to an internal error\n");
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- int i;
-
- for (i = 0; i < ctr->num_entries; i++)
- {
- switch (ctr->info_level) {
- case 1:
- display_share_info_1(out_hnd, ACTION_HEADER , &(ctr->share.info1[i]));
- display_share_info_1(out_hnd, ACTION_ENUMERATE, &(ctr->share.info1[i]));
- display_share_info_1(out_hnd, ACTION_FOOTER , &(ctr->share.info1[i]));
- break;
- case 2:
- display_share_info_2(out_hnd, ACTION_HEADER , &(ctr->share.info2[i]));
- display_share_info_2(out_hnd, ACTION_ENUMERATE, &(ctr->share.info2[i]));
- display_share_info_2(out_hnd, ACTION_FOOTER , &(ctr->share.info2[i]));
- break;
- default:
- fprintf(out_hnd, "display_srv_share_info_ctr: Unknown Info Level\n");
- break;
- }
- }
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-/****************************************************************************
-file info level 3 display function
-****************************************************************************/
-void display_file_info_3(FILE *out_hnd, enum action_type action,
- FILE_INFO_3 *info3, FILE_INFO_3_STR *str3)
-{
- if (info3 == NULL || str3 == NULL)
- {
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "File Info Level 3:\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- fstring path_name;
- fstring user_name;
-
- fstrcpy(path_name, dos_unistrn2(str3->uni_path_name.buffer, str3->uni_path_name.uni_str_len));
- fstrcpy(user_name, dos_unistrn2(str3->uni_user_name.buffer, str3->uni_user_name.uni_str_len));
-
- fprintf(out_hnd, "\tid : %d\n", info3->id);
- fprintf(out_hnd, "\tperms : %s\n", get_file_mode_str(info3->perms));
- fprintf(out_hnd, "\tnum_locks: %d\n", info3->num_locks);
-
- fprintf(out_hnd, "\tpath name: %s\n", path_name);
- fprintf(out_hnd, "\tuser name: %s\n", user_name);
-
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-
-}
-
-/****************************************************************************
-file info level 3 container display function
-****************************************************************************/
-void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action,
- SRV_FILE_INFO_3 *ctr)
-{
- if (ctr == NULL)
- {
- fprintf(out_hnd, "display_srv_file_info_3_ctr: unavailable due to an internal error\n");
- return;
- }
-
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- int i;
-
- for (i = 0; i < ctr->num_entries_read; i++)
- {
- display_file_info_3(out_hnd, ACTION_HEADER , &(ctr->info_3[i]), &(ctr->info_3_str[i]));
- display_file_info_3(out_hnd, ACTION_ENUMERATE, &(ctr->info_3[i]), &(ctr->info_3_str[i]));
- display_file_info_3(out_hnd, ACTION_FOOTER , &(ctr->info_3[i]), &(ctr->info_3_str[i]));
- }
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-/****************************************************************************
-file info container display function
-****************************************************************************/
-void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action,
- SRV_FILE_INFO_CTR *ctr)
-{
- if (ctr == NULL || ctr->ptr_file_ctr == 0)
- {
- fprintf(out_hnd, "display_srv_file_info_ctr: unavailable due to an internal error\n");
- return;
- }
-
- switch (ctr->switch_value)
- {
- case 3:
- {
- display_srv_file_info_3_ctr(out_hnd, action,
- &(ctr->file.info3));
- break;
- }
- default:
- {
- fprintf(out_hnd, "display_srv_file_info_ctr: Unknown Info Level\n");
- break;
- }
- }
-}
-
-/****************************************************************************
- print browse connection on a host
- ****************************************************************************/
-void display_server(FILE *out_hnd, enum action_type action,
- char *sname, uint32 type, char *comment)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- fprintf(out_hnd, "\t%-15.15s%-20s %s\n",
- sname, get_server_type_str(type), comment);
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-/****************************************************************************
-print shares on a host
-****************************************************************************/
-void display_share(FILE *out_hnd, enum action_type action,
- char *sname, uint32 type, char *comment)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- fprintf(out_hnd, "\t%-15.15s%-10.10s%s\n",
- sname, get_share_type_str(type), comment);
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-
-/****************************************************************************
-print shares on a host, level 2
-****************************************************************************/
-void display_share2(FILE *out_hnd, enum action_type action,
- char *sname, uint32 type, char *comment,
- uint32 perms, uint32 max_uses, uint32 num_uses,
- char *path, char *passwd)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- fprintf(out_hnd, "\t%-15.15s%-10.10s%s %x %x %x %s %s\n",
- sname, get_share_type_str(type), comment,
- perms, max_uses, num_uses, path, passwd);
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-
-/****************************************************************************
-print name info
-****************************************************************************/
-void display_name(FILE *out_hnd, enum action_type action,
- char *sname)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- fprintf(out_hnd, "\t%-21.21s\n", sname);
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-
-/****************************************************************************
- display group rid info
- ****************************************************************************/
-void display_group_rid_info(FILE *out_hnd, enum action_type action,
- uint32 num_gids, DOM_GID *gid)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- if (num_gids == 0)
- {
- fprintf(out_hnd, "\tNo Groups\n");
- }
- else
- {
- fprintf(out_hnd, "\tGroup Info\n");
- fprintf(out_hnd, "\t----------\n");
- }
- break;
- }
- case ACTION_ENUMERATE:
- {
- int i;
-
- for (i = 0; i < num_gids; i++)
- {
- fprintf(out_hnd, "\tGroup RID: %8x attr: %x\n",
- gid[i].g_rid, gid[i].attr);
- }
-
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-}
-
-
-/****************************************************************************
- display alias name info
- ****************************************************************************/
-void display_alias_name_info(FILE *out_hnd, enum action_type action,
- uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- if (num_aliases == 0)
- {
- fprintf(out_hnd, "\tNo Aliases\n");
- }
- else
- {
- fprintf(out_hnd, "\tAlias Names\n");
- fprintf(out_hnd, "\t----------- \n");
- }
- break;
- }
- case ACTION_ENUMERATE:
- {
- int i;
-
- for (i = 0; i < num_aliases; i++)
- {
- fprintf(out_hnd, "\tAlias Name: %s Attributes: %3d\n",
- alias_name[i], num_als_usrs[i]);
- }
-
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-}
-
-
-/****************************************************************************
- display sam_user_info_21 structure
- ****************************************************************************/
-void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "\tUser Info, Level 0x15\n");
- fprintf(out_hnd, "\t---------------------\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- fprintf(out_hnd, "\t\tUser Name : %s\n", dos_unistrn2(usr->uni_user_name .buffer, usr->uni_user_name .uni_str_len)); /* username unicode string */
- fprintf(out_hnd, "\t\tFull Name : %s\n", dos_unistrn2(usr->uni_full_name .buffer, usr->uni_full_name .uni_str_len)); /* user's full name unicode string */
- fprintf(out_hnd, "\t\tHome Drive : %s\n", dos_unistrn2(usr->uni_home_dir .buffer, usr->uni_home_dir .uni_str_len)); /* home directory unicode string */
- fprintf(out_hnd, "\t\tDir Drive : %s\n", dos_unistrn2(usr->uni_dir_drive .buffer, usr->uni_dir_drive .uni_str_len)); /* home directory drive unicode string */
- fprintf(out_hnd, "\t\tProfile Path: %s\n", dos_unistrn2(usr->uni_profile_path.buffer, usr->uni_profile_path.uni_str_len)); /* profile path unicode string */
- fprintf(out_hnd, "\t\tLogon Script: %s\n", dos_unistrn2(usr->uni_logon_script.buffer, usr->uni_logon_script.uni_str_len)); /* logon script unicode string */
- fprintf(out_hnd, "\t\tDescription : %s\n", dos_unistrn2(usr->uni_acct_desc .buffer, usr->uni_acct_desc .uni_str_len)); /* user description unicode string */
- fprintf(out_hnd, "\t\tWorkstations: %s\n", dos_unistrn2(usr->uni_workstations.buffer, usr->uni_workstations.uni_str_len)); /* workstaions unicode string */
- fprintf(out_hnd, "\t\tUnknown Str : %s\n", dos_unistrn2(usr->uni_unknown_str .buffer, usr->uni_unknown_str .uni_str_len)); /* unknown string unicode string */
- fprintf(out_hnd, "\t\tRemote Dial : %s\n", dos_unistrn2(usr->uni_munged_dial .buffer, usr->uni_munged_dial .uni_str_len)); /* munged remote access unicode string */
-
- fprintf(out_hnd, "\t\tLogon Time : %s\n", http_timestring(nt_time_to_unix(&(usr->logon_time ))));
- fprintf(out_hnd, "\t\tLogoff Time : %s\n", http_timestring(nt_time_to_unix(&(usr->logoff_time ))));
- fprintf(out_hnd, "\t\tKickoff Time : %s\n", http_timestring(nt_time_to_unix(&(usr->kickoff_time ))));
- fprintf(out_hnd, "\t\tPassword last set Time : %s\n", http_timestring(nt_time_to_unix(&(usr->pass_last_set_time ))));
- fprintf(out_hnd, "\t\tPassword can change Time : %s\n", http_timestring(nt_time_to_unix(&(usr->pass_can_change_time ))));
- fprintf(out_hnd, "\t\tPassword must change Time: %s\n", http_timestring(nt_time_to_unix(&(usr->pass_must_change_time))));
-
- fprintf(out_hnd, "\t\tunknown_2[0..31]...\n"); /* user passwords? */
-
- fprintf(out_hnd, "\t\tuser_rid : %x\n" , usr->user_rid ); /* User ID */
- fprintf(out_hnd, "\t\tgroup_rid: %x\n" , usr->group_rid); /* Group ID */
- fprintf(out_hnd, "\t\tacb_info : %04x\n", usr->acb_info ); /* Account Control Info */
-
- fprintf(out_hnd, "\t\tunknown_3: %08x\n", usr->unknown_3); /* 0x00ff ffff */
- fprintf(out_hnd, "\t\tlogon_divs: %d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
- fprintf(out_hnd, "\t\tunknown_5: %08x\n", usr->unknown_5); /* 0x0002 0000 */
-
- fprintf(out_hnd, "\t\tpadding1[0..7]...\n");
-
- if (usr->ptr_logon_hrs)
- {
- fprintf(out_hnd, "\t\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len);
- }
-
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-}
-
-
-/****************************************************************************
-convert a security permissions into a string
-****************************************************************************/
-char *get_sec_mask_str(uint32 type)
-{
- static fstring typestr;
- int i;
-
- switch (type)
- {
- case SEC_RIGHTS_FULL_CONTROL:
- {
- fstrcpy(typestr, "Full Control");
- return typestr;
- }
-
- case SEC_RIGHTS_READ:
- {
- fstrcpy(typestr, "Read");
- return typestr;
- }
- default:
- {
- break;
- }
- }
-
- typestr[0] = 0;
- for (i = 0; i < 32; i++)
- {
- if (IS_BITS_SET_ALL(type, 1 << i))
- {
- switch (((unsigned)1) << i)
- {
- case SEC_RIGHTS_QUERY_VALUE : fstrcat(typestr, "Query " ); break;
- case SEC_RIGHTS_SET_VALUE : fstrcat(typestr, "Set " ); break;
- case SEC_RIGHTS_CREATE_SUBKEY : fstrcat(typestr, "Create "); break;
- case SEC_RIGHTS_ENUM_SUBKEYS : fstrcat(typestr, "Enum "); break;
- case SEC_RIGHTS_NOTIFY : fstrcat(typestr, "Notify "); break;
- case SEC_RIGHTS_CREATE_LINK : fstrcat(typestr, "CreateLink "); break;
- case SEC_RIGHTS_DELETE : fstrcat(typestr, "Delete "); break;
- case SEC_RIGHTS_READ_CONTROL : fstrcat(typestr, "ReadControl "); break;
- case SEC_RIGHTS_WRITE_DAC : fstrcat(typestr, "WriteDAC "); break;
- case SEC_RIGHTS_WRITE_OWNER : fstrcat(typestr, "WriteOwner "); break;
- }
- type &= ~(1 << i);
- }
- }
-
- /* remaining bits get added on as-is */
- if (type != 0)
- {
- fstring tmp;
- slprintf(tmp, sizeof(tmp)-1, "[%08x]", type);
- fstrcat(typestr, tmp);
- }
-
- /* remove last space */
- i = strlen(typestr)-1;
- if (typestr[i] == ' ') typestr[i] = 0;
-
- return typestr;
-}
-
-/****************************************************************************
- display sec_access structure
- ****************************************************************************/
-void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- fprintf(out_hnd, "\t\tPermissions: %s\n",
- get_sec_mask_str(info->mask));
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-/****************************************************************************
- display sec_ace structure
- ****************************************************************************/
-void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "\tACE\n");
- break;
- }
- case ACTION_ENUMERATE:
- {
- fstring sid_str;
-
- display_sec_access(out_hnd, ACTION_HEADER , &ace->info);
- display_sec_access(out_hnd, ACTION_ENUMERATE, &ace->info);
- display_sec_access(out_hnd, ACTION_FOOTER , &ace->info);
-
- sid_to_string(sid_str, &ace->sid);
- fprintf(out_hnd, "\t\tSID: %s\n", sid_str);
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-/****************************************************************************
- display sec_acl structure
- ****************************************************************************/
-void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "\tACL\tNum ACEs:\t%d\trevision:\t%x\n",
- sec_acl->num_aces, sec_acl->revision);
- fprintf(out_hnd, "\t---\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- if (sec_acl->size != 0 && sec_acl->num_aces != 0)
- {
- int i;
- for (i = 0; i < sec_acl->num_aces; i++)
- {
- display_sec_ace(out_hnd, ACTION_HEADER , &sec_acl->ace_list[i]);
- display_sec_ace(out_hnd, ACTION_ENUMERATE, &sec_acl->ace_list[i]);
- display_sec_ace(out_hnd, ACTION_FOOTER , &sec_acl->ace_list[i]);
- }
- }
-
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-}
-
-/****************************************************************************
- display sec_desc structure
- ****************************************************************************/
-void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "\tSecurity Descriptor\trevision:\t%x\ttype:\t%x\n",
- sec->revision, sec->type);
- fprintf(out_hnd, "\t-------------------\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- fstring sid_str;
-
- if (sec->off_sacl != 0)
- {
- display_sec_acl(out_hnd, ACTION_HEADER , sec->sacl);
- display_sec_acl(out_hnd, ACTION_ENUMERATE, sec->sacl);
- display_sec_acl(out_hnd, ACTION_FOOTER , sec->sacl);
- }
- if (sec->off_dacl != 0)
- {
- display_sec_acl(out_hnd, ACTION_HEADER , sec->dacl);
- display_sec_acl(out_hnd, ACTION_ENUMERATE, sec->dacl);
- display_sec_acl(out_hnd, ACTION_FOOTER , sec->dacl);
- }
- if (sec->off_owner_sid != 0)
- {
- sid_to_string(sid_str, sec->owner_sid);
- fprintf(out_hnd, "\tOwner SID:\t%s\n", sid_str);
- }
- if (sec->off_grp_sid != 0)
- {
- sid_to_string(sid_str, sec->grp_sid);
- fprintf(out_hnd, "\tParent SID:\t%s\n", sid_str);
- }
-
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-}
-
-/****************************************************************************
-convert a security permissions into a string
-****************************************************************************/
-char *get_reg_val_type_str(uint32 type)
-{
- static fstring typestr;
-
- switch (type)
- {
- case 0x01:
- {
- fstrcpy(typestr, "string");
- return typestr;
- }
-
- case 0x03:
- {
- fstrcpy(typestr, "bytes");
- return typestr;
- }
-
- case 0x04:
- {
- fstrcpy(typestr, "uint32");
- return typestr;
- }
-
- case 0x07:
- {
- fstrcpy(typestr, "multi");
- return typestr;
- }
- default:
- {
- break;
- }
- }
- slprintf(typestr, sizeof(typestr)-1, "[%d]", type);
- return typestr;
-}
-
-
-static void print_reg_value(FILE *out_hnd, char *val_name, uint32 val_type, BUFFER2 *value)
-{
- fstring type;
- fstrcpy(type, get_reg_val_type_str(val_type));
-
- switch (val_type)
- {
- case 0x01: /* unistr */
- {
- fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, dos_buffer2_to_str(value));
- break;
- }
-
- default: /* unknown */
- case 0x03: /* bytes */
- {
- if (value->buf_len <= 8)
- {
- fprintf(out_hnd,"\t%s:\t%s:\t", val_name, type);
- out_data(out_hnd, (char*)value->buffer, value->buf_len, 8);
- }
- else
- {
- fprintf(out_hnd,"\t%s:\t%s:\n", val_name, type);
- out_data(out_hnd, (char*)value->buffer, value->buf_len, 16);
- }
- break;
- }
-
- case 0x04: /* uint32 */
- {
- fprintf(out_hnd,"\t%s:\t%s: 0x%08x\n", val_name, type, buffer2_to_uint32(value));
- break;
- }
-
- case 0x07: /* multiunistr */
- {
- fprintf(out_hnd,"\t%s:\t%s:\t%s\n", val_name, type, dos_buffer2_to_multistr(value));
- break;
- }
- }
-}
-
-/****************************************************************************
- display structure
- ****************************************************************************/
-void display_reg_value_info(FILE *out_hnd, enum action_type action,
- char *val_name, uint32 val_type, BUFFER2 *value)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- print_reg_value(out_hnd, val_name, val_type, value);
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-/****************************************************************************
- display structure
- ****************************************************************************/
-void display_reg_key_info(FILE *out_hnd, enum action_type action,
- char *key_name, time_t key_mod_time)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- break;
- }
- case ACTION_ENUMERATE:
- {
- fprintf(out_hnd, "\t%s\t(%s)\n",
- key_name, http_timestring(key_mod_time));
- break;
- }
- case ACTION_FOOTER:
- {
- break;
- }
- }
-}
-
-#if COPY_THIS_TEMPLATE
-/****************************************************************************
- display structure
- ****************************************************************************/
- void display_(FILE *out_hnd, enum action_type action, *)
-{
- switch (action)
- {
- case ACTION_HEADER:
- {
- fprintf(out_hnd, "\t\n");
- fprintf(out_hnd, "\t-------------------\n");
-
- break;
- }
- case ACTION_ENUMERATE:
- {
- break;
- }
- case ACTION_FOOTER:
- {
- fprintf(out_hnd, "\n");
- break;
- }
- }
-}
-
-#endif
diff --git a/source/rpcclient/display_at.c b/source/rpcclient/display_at.c
new file mode 100644
index 00000000000..29daf9f3336
--- /dev/null
+++ b/source/rpcclient/display_at.c
@@ -0,0 +1,190 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+static char *get_at_time_str(uint32 t)
+{
+ static fstring timestr;
+ unsigned int hours, minutes, seconds;
+
+ hours = t / 1000;
+ seconds = hours % 60;
+ hours /= 60;
+ minutes = hours % 60;
+ hours /= 60;
+
+ slprintf(timestr, sizeof(timestr)-1, "%2d:%02d:%02d",
+ hours, minutes, seconds);
+
+ return timestr;
+}
+
+extern char *daynames_short[];
+
+static char *get_at_days_str(uint32 monthdays, uint8 weekdays, uint8 flags)
+{
+ static fstring days;
+ fstring numstr;
+ int day, bit;
+ BOOL first = True;
+
+ if (monthdays == 0 && weekdays == 0)
+ return "Once";
+
+ if (flags & JOB_PERIODIC)
+ {
+ if (IS_BITS_SET_ALL(weekdays, 0x7F))
+ return "Every Day";
+
+ fstrcpy(days, "Every ");
+ }
+ else
+ {
+ fstrcpy(days, "Next ");
+ }
+
+ for (day = 1, bit = 1; day < 32; day++, bit <<= 1)
+ {
+ if (monthdays & bit)
+ {
+ if (first)
+ first = False;
+ else
+ fstrcat(days, ", ");
+
+ slprintf(numstr, sizeof(numstr)-1, "%d", day);
+ fstrcat(days, numstr);
+ }
+ }
+
+ for (day = 0, bit = 1; day < 7; day++, bit <<= 1)
+ {
+ if (weekdays & bit)
+ {
+ if (first)
+ first = False;
+ else
+ fstrcat(days, ", ");
+
+ fstrcat(days, daynames_short[day]);
+ }
+ }
+
+ return days;
+}
+
+/****************************************************************************
+ display scheduled jobs
+ ****************************************************************************/
+void display_at_enum_info(FILE *out_hnd, enum action_type action,
+ uint32 num_jobs, const AT_ENUM_INFO *const jobs,
+ char *const *const commands)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ if (num_jobs == 0)
+ {
+ report(out_hnd, "\tNo Jobs.\n");
+ }
+ else
+ {
+ report(out_hnd, "\tJobs:\n");
+ report(out_hnd, "\t-----\n");
+ }
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < num_jobs; i++)
+ {
+ const AT_JOB_INFO *const job = &jobs[i].info;
+
+ report(out_hnd, "\t%d\t%s\t%s\t%s\n",
+ jobs[i].jobid,
+ get_at_time_str(job->time),
+ get_at_days_str(job->monthdays,
+ job->weekdays,
+ job->flags),
+ commands[i]);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display information about a scheduled job
+ ****************************************************************************/
+void display_at_job_info(FILE *out_hnd, enum action_type action,
+ AT_JOB_INFO *const job, fstring command)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "\tJob Information:\n");
+ report(out_hnd, "\t----------------\n");
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ report(out_hnd, "\tTime: %s\n",
+ get_at_time_str(job->time));
+
+ report(out_hnd, "\tSchedule: %s\n",
+ get_at_days_str(job->monthdays, job->weekdays,
+ job->flags));
+
+ report(out_hnd, "\tStatus: %s",
+ (job->flags & JOB_EXEC_ERR) ? "Failed" : "OK");
+
+ if (job->flags & JOB_RUNS_TODAY)
+ {
+ report(out_hnd, ", Runs Today");
+ }
+
+ report(out_hnd, "\n\tInteractive: %s\n",
+ (job->flags & JOB_NONINTERACTIVE) ? "No"
+ : "Yes");
+
+ report(out_hnd, "\tCommand: %s\n", command);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
diff --git a/source/rpcclient/display_event.c b/source/rpcclient/display_event.c
new file mode 100644
index 00000000000..cd941851ac5
--- /dev/null
+++ b/source/rpcclient/display_event.c
@@ -0,0 +1,101 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+/****************************************************************************
+ display structure
+ ****************************************************************************/
+void display_eventlog_eventrecord(FILE *out_hnd, enum action_type action, EVENTLOGRECORD *const ev)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "\tevent log records\n");
+ report(out_hnd, "\t-----------------\n");
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring temp;
+ report(out_hnd, "\t\trecord n.:\t%d\n", ev->recordnumber);
+
+ report(out_hnd, "\t\tsource\teventnumber\teventtype\tcategory\n");
+ unistr_to_ascii(temp, ev->sourcename.buffer, sizeof(temp)-1);
+
+ report(out_hnd, "\t\t%s", temp);
+
+ report(out_hnd, "\t%d\t\t", ev->eventnumber&0x0000FFFF);
+
+ switch (ev->eventtype)
+ {
+ case EVENTLOG_OK:
+ report(out_hnd, "Normal");
+ break;
+
+ case EVENTLOG_ERROR:
+ report(out_hnd, "Error");
+ break;
+
+ case EVENTLOG_WARNING:
+ report(out_hnd, "Warning");
+ break;
+
+ case EVENTLOG_INFORMATION:
+ report(out_hnd, "Information");
+ break;
+
+ case EVENTLOG_AUDIT_OK:
+ report(out_hnd, "Audit Normal");
+ break;
+
+ case EVENTLOG_AUDIT_ERROR:
+ report(out_hnd, "Audit Error\n");
+ break;
+ }
+
+ report(out_hnd, "\t%d\n", ev->category);
+ report(out_hnd, "\t\tcreationtime:\t%s\n", http_timestring(ev->creationtime));
+ report(out_hnd, "\t\twritetime:\t%s\n", http_timestring(ev->writetime));
+
+ unistr_to_ascii(temp, ev->computername.buffer, sizeof(temp)-1);
+ report(out_hnd, "\t\tcomputer:\t%s\n", temp);
+
+ if (ev->num_of_strings!=0)
+ {
+ unistr_to_ascii(temp, ev->strings.buffer, sizeof(temp)-1);
+ report(out_hnd, "\t\tdescription:\t%s\n", temp);
+ }
+
+ report(out_hnd, "\n");
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
diff --git a/source/rpcclient/display_reg.c b/source/rpcclient/display_reg.c
new file mode 100644
index 00000000000..d832d1bffb2
--- /dev/null
+++ b/source/rpcclient/display_reg.c
@@ -0,0 +1,168 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+/****************************************************************************
+convert a security permissions into a string
+****************************************************************************/
+char *get_reg_val_type_str(uint32 type)
+{
+ static fstring typestr;
+
+ switch (type)
+ {
+ case 0x01:
+ {
+ fstrcpy(typestr, "string");
+ return typestr;
+ }
+
+ case 0x03:
+ {
+ fstrcpy(typestr, "bytes");
+ return typestr;
+ }
+
+ case 0x04:
+ {
+ fstrcpy(typestr, "uint32");
+ return typestr;
+ }
+
+ case 0x07:
+ {
+ fstrcpy(typestr, "multi");
+ return typestr;
+ }
+ default:
+ {
+ break;
+ }
+ }
+ slprintf(typestr, sizeof(typestr)-1, "[%d]", type);
+ return typestr;
+}
+
+
+static void print_reg_value(FILE *out_hnd, const char *val_name,
+ uint32 val_type, const BUFFER2 *value)
+{
+ fstring type;
+ fstring valstr;
+
+ fstrcpy(type, get_reg_val_type_str(val_type));
+
+ switch (val_type)
+ {
+ case 0x01: /* unistr */
+ {
+ unibuf_to_ascii(valstr, value->buffer,
+ MIN(value->buf_len, sizeof(valstr)-1));
+ report(out_hnd, "\t%s:\t%s:\t%s\n", val_name, type, valstr);
+ break;
+ }
+
+ default: /* unknown */
+ case 0x03: /* bytes */
+ {
+ if (value->buf_len <= 8)
+ {
+ report(out_hnd, "\t%s:\t%s:\t", val_name, type);
+ out_data(out_hnd, (const char*)value->buffer,
+ value->buf_len, 8);
+ }
+ else
+ {
+ report(out_hnd, "\t%s:\t%s:\n", val_name, type);
+ out_data(out_hnd, (const char*)value->buffer,
+ value->buf_len, 16);
+ }
+ break;
+ }
+
+ case 0x04: /* uint32 */
+ {
+ report(out_hnd, "\t%s:\t%s:\t0x%08x\n", val_name, type, buffer2_to_uint32(value));
+ break;
+ }
+
+ case 0x07: /* multiunistr */
+ {
+ buffer2_to_multistr(valstr, value, sizeof(valstr)-1);
+ report(out_hnd, "\t%s:\t%s:\t%s\n", val_name, type, valstr);
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display structure
+ ****************************************************************************/
+void display_reg_value_info(FILE *out_hnd, enum action_type action,
+ const char *val_name,
+ uint32 val_type, const BUFFER2 *value)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ print_reg_value(out_hnd, val_name, val_type, value);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display structure
+ ****************************************************************************/
+void display_reg_key_info(FILE *out_hnd, enum action_type action,
+ const char *key_name, time_t key_mod_time)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ report(out_hnd, "\t%s\t(%s)\n",
+ key_name, http_timestring(key_mod_time));
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
diff --git a/source/rpcclient/display_sam.c b/source/rpcclient/display_sam.c
new file mode 100644
index 00000000000..4da8ab6adc7
--- /dev/null
+++ b/source/rpcclient/display_sam.c
@@ -0,0 +1,685 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/****************************************************************************
+ display alias members
+ ****************************************************************************/
+void display_alias_members(FILE *out_hnd, enum action_type action,
+ uint32 num_mem, char *const *const sid_mem,
+ uint32 *const type)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ if (num_mem == 0)
+ {
+ report(out_hnd, "\tNo Alias Members\n");
+ }
+ else
+ {
+ report(out_hnd, "\tAlias Members:\n");
+ report(out_hnd, "\t-------------\n");
+ }
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < num_mem; i++)
+ {
+ if (sid_mem[i] != NULL)
+ {
+ report(out_hnd, "\tMember Name:\t%s\tType:\t%s\n",
+ sid_mem[i],
+ get_sid_name_use_str(type[i]));
+ }
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display alias rid info
+ ****************************************************************************/
+void display_alias_rid_info(FILE *out_hnd, enum action_type action,
+ DOM_SID *const sid,
+ uint32 num_rids, uint32 *const rid)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fstring sid_str;
+ sid_to_string(sid_str, sid);
+ if (num_rids == 0)
+ {
+ report(out_hnd, "\tNo Aliases:\tSid %s\n", sid_str);
+ }
+ else
+ {
+ report(out_hnd, "\tAlias Info:\tSid %s\n", sid_str);
+ report(out_hnd, "\t----------\n");
+ }
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < num_rids; i++)
+ {
+ report(out_hnd, "\tAlias RID:\t%8x\n", rid[i]);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display group members
+ ****************************************************************************/
+void display_group_members(FILE *out_hnd, enum action_type action,
+ uint32 num_mem, char *const *const name, uint32 *const type)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ if (num_mem == 0)
+ {
+ report(out_hnd, "\tNo Members\n");
+ }
+ else
+ {
+ report(out_hnd, "\tMembers:\n");
+ report(out_hnd, "\t-------\n");
+ }
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < num_mem; i++)
+ {
+ report(out_hnd, "\tMember Name:\t%s\tType:\t%s\n",
+ name[i], get_sid_name_use_str(type[i]));
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display group info
+ ****************************************************************************/
+void display_group_info1(FILE *out_hnd, enum action_type action, GROUP_INFO1 *const info1)
+
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring temp;
+
+ unistr2_to_ascii(temp, &info1->uni_acct_name, sizeof(temp)-1);
+ report(out_hnd, "\tGroup Name:\t%s\n", temp);
+ unistr2_to_ascii(temp, &info1->uni_acct_desc, sizeof(temp)-1);
+ report(out_hnd, "\tDescription:\t%s\n", temp);
+ report(out_hnd, "\tunk1:%d\n", info1->unknown_1);
+ report(out_hnd, "\tNum Members:%d\n", info1->num_members);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display group info
+ ****************************************************************************/
+void display_group_info4(FILE *out_hnd, enum action_type action, GROUP_INFO4 *const info4)
+
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring desc;
+
+ unistr2_to_ascii(desc, &info4->uni_acct_desc, sizeof(desc)-1);
+ report(out_hnd, "\tGroup Description:%s\n",
+ desc);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display sam sync structure
+ ****************************************************************************/
+void display_group_info_ctr(FILE *out_hnd, enum action_type action,
+ GROUP_INFO_CTR *const ctr)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "\tSAM Group Info\n");
+ report(out_hnd, "\t--------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ switch (ctr->switch_value1)
+ {
+ case 1:
+ {
+ display_group_info1(out_hnd, ACTION_HEADER , &ctr->group.info1);
+ display_group_info1(out_hnd, ACTION_ENUMERATE, &ctr->group.info1);
+ display_group_info1(out_hnd, ACTION_FOOTER , &ctr->group.info1);
+ break;
+ }
+ case 4:
+ {
+ display_group_info4(out_hnd, ACTION_HEADER , &ctr->group.info4);
+ display_group_info4(out_hnd, ACTION_ENUMERATE, &ctr->group.info4);
+ display_group_info4(out_hnd, ACTION_FOOTER , &ctr->group.info4);
+ break;
+ }
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display group rid info
+ ****************************************************************************/
+void display_group_rid_info(FILE *out_hnd, enum action_type action,
+ uint32 num_gids, DOM_GID *const gid)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ if (num_gids == 0)
+ {
+ report(out_hnd, "\tNo Groups\n");
+ }
+ else
+ {
+ report(out_hnd, "\tGroup Info\n");
+ report(out_hnd, "\t----------\n");
+ }
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < num_gids; i++)
+ {
+ report(out_hnd, "\tGroup RID:\t%8x attr:\t%x\n",
+ gid[i].g_rid, gid[i].attr);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display alias name info
+ ****************************************************************************/
+void display_alias_name_info(FILE *out_hnd, enum action_type action,
+ uint32 num_aliases, fstring *const alias_name, const uint32 *const num_als_usrs)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ if (num_aliases == 0)
+ {
+ report(out_hnd, "\tNo Aliases\n");
+ }
+ else
+ {
+ report(out_hnd, "\tAlias Names\n");
+ report(out_hnd, "\t----------- \n");
+ }
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < num_aliases; i++)
+ {
+ report(out_hnd, "\tAlias Name:\t%s Attributes:\t%3d\n",
+ alias_name[i], num_als_usrs[i]);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display alias info
+ ****************************************************************************/
+void display_alias_info3(FILE *out_hnd, enum action_type action, ALIAS_INFO3 *const info3)
+
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring temp;
+
+ unistr2_to_ascii(temp, &info3->uni_acct_desc, sizeof(temp)-1);
+ report(out_hnd, "\tDescription:\t%s\n", temp);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display sam sync structure
+ ****************************************************************************/
+void display_alias_info_ctr(FILE *out_hnd, enum action_type action,
+ ALIAS_INFO_CTR *const ctr)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "\tSAM Group Info\n");
+ report(out_hnd, "\t--------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ switch (ctr->switch_value1)
+ {
+ case 3:
+ {
+ display_alias_info3(out_hnd, ACTION_HEADER , &ctr->alias.info3);
+ display_alias_info3(out_hnd, ACTION_ENUMERATE, &ctr->alias.info3);
+ display_alias_info3(out_hnd, ACTION_FOOTER , &ctr->alias.info3);
+ break;
+ }
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display sam_user_info_21 structure
+ ****************************************************************************/
+void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *const usr)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "\tUser Info, Level 0x15\n");
+ report(out_hnd, "\t---------------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring temp;
+
+ unistr2_to_ascii(temp, &usr->uni_user_name, sizeof(temp)-1);
+ report(out_hnd, "\t\tUser Name :\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &usr->uni_full_name, sizeof(temp)-1);
+ report(out_hnd, "\t\tFull Name :\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &usr->uni_home_dir, sizeof(temp)-1);
+ report(out_hnd, "\t\tHome Drive :\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &usr->uni_dir_drive, sizeof(temp)-1);
+ report(out_hnd, "\t\tDir Drive :\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &usr->uni_profile_path, sizeof(temp)-1);
+ report(out_hnd, "\t\tProfile Path:\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &usr->uni_logon_script, sizeof(temp)-1);
+ report(out_hnd, "\t\tLogon Script:\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &usr->uni_acct_desc, sizeof(temp)-1);
+ report(out_hnd, "\t\tDescription :\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &usr->uni_workstations, sizeof(temp)-1);
+ report(out_hnd, "\t\tWorkstations:\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &usr->uni_unknown_str, sizeof(temp)-1);
+ report(out_hnd, "\t\tUnknown Str :\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &usr->uni_munged_dial, sizeof(temp)-1);
+ report(out_hnd, "\t\tRemote Dial :\t%s\n", temp);
+
+ report(out_hnd, "\t\tLogon Time :\t%s\n", http_timestring(nt_time_to_unix(&(usr->logon_time ))));
+ report(out_hnd, "\t\tLogoff Time :\t%s\n", http_timestring(nt_time_to_unix(&(usr->logoff_time ))));
+ report(out_hnd, "\t\tKickoff Time :\t%s\n", http_timestring(nt_time_to_unix(&(usr->kickoff_time ))));
+ report(out_hnd, "\t\tPassword last set Time :\t%s\n", http_timestring(nt_time_to_unix(&(usr->pass_last_set_time ))));
+ report(out_hnd, "\t\tPassword can change Time :\t%s\n", http_timestring(nt_time_to_unix(&(usr->pass_can_change_time ))));
+ report(out_hnd, "\t\tPassword must change Time:\t%s\n", http_timestring(nt_time_to_unix(&(usr->pass_must_change_time))));
+
+ report(out_hnd, "\t\tunknown_2[0..31]...\n"); /* user passwords? */
+
+ report(out_hnd, "\t\tuser_rid :\t%x\n" , usr->user_rid ); /* User ID */
+ report(out_hnd, "\t\tgroup_rid:\t%x\n" , usr->group_rid); /* Group ID */
+ report(out_hnd, "\t\tacb_info :\t%04x\n", usr->acb_info ); /* Account Control Info */
+
+ report(out_hnd, "\t\tunknown_3:\t%08x\n", usr->unknown_3); /* 0x00ff ffff */
+ report(out_hnd, "\t\tlogon_divs:\t%d\n", usr->logon_divs); /* 0x0000 00a8 which is 168 which is num hrs in a week */
+ report(out_hnd, "\t\tunknown_5:\t%08x\n", usr->unknown_5); /* 0x0002 0000 */
+
+ report(out_hnd, "\t\tpadding1[0..7]...\n");
+
+ if (usr->ptr_logon_hrs)
+ {
+ report(out_hnd, "\t\tlogon_hrs[0..%d]...\n", usr->logon_hrs.len);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+ display sam sync structure
+ ****************************************************************************/
+void display_sam_unk_info_2(FILE *out_hnd, enum action_type action,
+ SAM_UNK_INFO_2 *const info2)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+ unistr2_to_ascii(name, &(info2->uni_domain), sizeof(name)-1);
+ report(out_hnd, "Domain:\t%s\n", name);
+
+ unistr2_to_ascii(name, &(info2->uni_server), sizeof(name)-1);
+ report(out_hnd, "Server:\t%s\n", name);
+
+ report(out_hnd, "Total Users:\t%d\n", info2->num_domain_usrs);
+ report(out_hnd, "Total Groups:\t%d\n", info2->num_domain_grps);
+ report(out_hnd, "Total Aliases:\t%d\n", info2->num_local_grps);
+
+ report(out_hnd, "Sequence No:\t%d\n", info2->seq_num);
+
+ report(out_hnd, "Unknown 0:\t0x%x\n", info2->unknown_0);
+ report(out_hnd, "Unknown 1:\t0x%x\n", info2->unknown_1);
+ report(out_hnd, "Unknown 2:\t0x%x\n", info2->unknown_2);
+ report(out_hnd, "Unknown 3:\t0x%x\n", info2->unknown_3);
+ report(out_hnd, "Unknown 4:\t0x%x\n", info2->unknown_4);
+ report(out_hnd, "Unknown 5:\t0x%x\n", info2->unknown_5);
+ report(out_hnd, "Unknown 6:\t0x%x\n", info2->unknown_6);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display sam sync structure
+ ****************************************************************************/
+void display_sam_unk_ctr(FILE *out_hnd, enum action_type action,
+ uint32 switch_value, SAM_UNK_CTR *const ctr)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "\tSAM Domain Info\n");
+ report(out_hnd, "\t---------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ switch (switch_value)
+ {
+ case 2:
+ {
+ display_sam_unk_info_2(out_hnd, ACTION_HEADER , &ctr->info.inf2);
+ display_sam_unk_info_2(out_hnd, ACTION_ENUMERATE, &ctr->info.inf2);
+ display_sam_unk_info_2(out_hnd, ACTION_FOOTER , &ctr->info.inf2);
+ break;
+ }
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+sam info level 1 display function
+****************************************************************************/
+void display_sam_info_1(FILE *out_hnd, enum action_type action,
+ SAM_ENTRY1 *const e1, SAM_STR1 *const s1)
+{
+ if (e1 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Sam Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring tmp;
+
+ report(out_hnd, "\tIndex:\t%d\n", e1->user_idx);
+ report(out_hnd, "\tRID:\t0x%x\n", e1->rid_user);
+ report(out_hnd, "\tACB:\t%s\n",
+ pwdb_encode_acct_ctrl(e1->acb_info,
+ NEW_PW_FORMAT_SPACE_PADDED_LEN));
+
+ unistr2_to_ascii(tmp, &s1->uni_acct_name, sizeof(tmp)-1);
+ report(out_hnd, "\tAccount Name:\t%s\n", tmp);
+ unistr2_to_ascii(tmp, &s1->uni_full_name, sizeof(tmp)-1);
+ report(out_hnd, "\tFull Name:\t%s\n", tmp);
+ unistr2_to_ascii(tmp, &s1->uni_acct_desc, sizeof(tmp)-1);
+ report(out_hnd, "\tUser Description:\t%s\n", tmp);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+connection info level 1 container display function
+****************************************************************************/
+void display_sam_info_1_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, SAM_DISPINFO_1 *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_sam_info_1_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ display_sam_info_1(out_hnd, ACTION_HEADER , &ctr->sam[i], &ctr->str[i]);
+ display_sam_info_1(out_hnd, ACTION_ENUMERATE, &ctr->sam[i], &ctr->str[i]);
+ display_sam_info_1(out_hnd, ACTION_FOOTER , &ctr->sam[i], &ctr->str[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_sam_disp_info_ctr(FILE *out_hnd, enum action_type action,
+ uint16 level, uint32 count,
+ SAM_DISPINFO_CTR *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_sam_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (level)
+ {
+ case 1:
+ {
+ display_sam_info_1_ctr(out_hnd, action,
+ count, ctr->sam.info1);
+ break;
+ }
+ default:
+ {
+ report(out_hnd, "display_sam_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
diff --git a/source/rpcclient/display_sec.c b/source/rpcclient/display_sec.c
new file mode 100644
index 00000000000..1916bdcb88d
--- /dev/null
+++ b/source/rpcclient/display_sec.c
@@ -0,0 +1,236 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+/****************************************************************************
+convert a security permissions into a string
+****************************************************************************/
+char *get_sec_mask_str(uint32 type)
+{
+ static fstring typestr;
+ int i;
+
+ switch (type)
+ {
+ case SEC_RIGHTS_FULL_CONTROL:
+ {
+ fstrcpy(typestr, "Full Control");
+ return typestr;
+ }
+
+ case SEC_RIGHTS_READ:
+ {
+ fstrcpy(typestr, "Read");
+ return typestr;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ typestr[0] = 0;
+ for (i = 0; i < 32; i++)
+ {
+ if (IS_BITS_SET_ALL(type, 1 << i))
+ {
+ switch (1 << i)
+ {
+ case SEC_RIGHTS_QUERY_VALUE : fstrcat(typestr, "Query " ); break;
+ case SEC_RIGHTS_SET_VALUE : fstrcat(typestr, "Set " ); break;
+ case SEC_RIGHTS_CREATE_SUBKEY : fstrcat(typestr, "Create "); break;
+ case SEC_RIGHTS_ENUM_SUBKEYS : fstrcat(typestr, "Enum "); break;
+ case SEC_RIGHTS_NOTIFY : fstrcat(typestr, "Notify "); break;
+ case SEC_RIGHTS_CREATE_LINK : fstrcat(typestr, "CreateLink "); break;
+ case SEC_RIGHTS_DELETE : fstrcat(typestr, "Delete "); break;
+ case SEC_RIGHTS_READ_CONTROL : fstrcat(typestr, "ReadControl "); break;
+ case SEC_RIGHTS_WRITE_DAC : fstrcat(typestr, "WriteDAC "); break;
+ case SEC_RIGHTS_WRITE_OWNER : fstrcat(typestr, "WriteOwner "); break;
+ }
+ type &= ~(1 << i);
+ }
+ }
+
+ /* remaining bits get added on as-is */
+ if (type != 0)
+ {
+ fstring tmp;
+ slprintf(tmp, sizeof(tmp)-1, "[%08x]", type);
+ fstrcat(typestr, tmp);
+ }
+
+ /* remove last space */
+ i = strlen(typestr)-1;
+ if (typestr[i] == ' ') typestr[i] = 0;
+
+ return typestr;
+}
+
+/****************************************************************************
+ display sec_access structure
+ ****************************************************************************/
+void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *const info)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ report(out_hnd, "\t\tPermissions:\t%s\n",
+ get_sec_mask_str(info->mask));
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display sec_ace structure
+ ****************************************************************************/
+void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *const ace)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "\tACE\n");
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring sid_str;
+
+ display_sec_access(out_hnd, ACTION_HEADER , &ace->info);
+ display_sec_access(out_hnd, ACTION_ENUMERATE, &ace->info);
+ display_sec_access(out_hnd, ACTION_FOOTER , &ace->info);
+
+ sid_to_string(sid_str, &ace->sid);
+ report(out_hnd, "\t\tSID:\t%s\n", sid_str);
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display sec_acl structure
+ ****************************************************************************/
+void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *const sec_acl)
+{
+ if (sec_acl == NULL)
+ {
+ return;
+ }
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "\tACL\tNum ACEs:\t%d\trevision:\t%x\n",
+ sec_acl->num_aces, sec_acl->revision);
+ report(out_hnd, "\t---\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ if (sec_acl->size != 0 && sec_acl->num_aces != 0)
+ {
+ int i;
+ for (i = 0; i < sec_acl->num_aces; i++)
+ {
+ display_sec_ace(out_hnd, ACTION_HEADER , &sec_acl->ace[i]);
+ display_sec_ace(out_hnd, ACTION_ENUMERATE, &sec_acl->ace[i]);
+ display_sec_ace(out_hnd, ACTION_FOOTER , &sec_acl->ace[i]);
+ }
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display sec_desc structure
+ ****************************************************************************/
+void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *const sec)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "\tSecurity Descriptor\trevision:\t%x\ttype:\t%x\n",
+ sec->revision, sec->type);
+ report(out_hnd, "\t-------------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring sid_str;
+
+ if (sec->off_sacl != 0)
+ {
+ display_sec_acl(out_hnd, ACTION_HEADER , sec->sacl);
+ display_sec_acl(out_hnd, ACTION_ENUMERATE, sec->sacl);
+ display_sec_acl(out_hnd, ACTION_FOOTER , sec->sacl);
+ }
+ if (sec->off_dacl != 0)
+ {
+ display_sec_acl(out_hnd, ACTION_HEADER , sec->dacl);
+ display_sec_acl(out_hnd, ACTION_ENUMERATE, sec->dacl);
+ display_sec_acl(out_hnd, ACTION_FOOTER , sec->dacl);
+ }
+ if (sec->off_owner_sid != 0)
+ {
+ sid_to_string(sid_str, sec->owner_sid);
+ report(out_hnd, "\tOwner SID:\t%s\n", sid_str);
+ }
+ if (sec->off_grp_sid != 0)
+ {
+ sid_to_string(sid_str, sec->grp_sid);
+ report(out_hnd, "\tParent SID:\t%s\n", sid_str);
+ }
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
diff --git a/source/rpcclient/display_spool.c b/source/rpcclient/display_spool.c
new file mode 100644
index 00000000000..252fc881568
--- /dev/null
+++ b/source/rpcclient/display_spool.c
@@ -0,0 +1,457 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/****************************************************************************
+printer info level 0 display function
+****************************************************************************/
+void display_print_info_0(FILE *out_hnd, enum action_type action,
+ PRINTER_INFO_0 *const i0)
+{
+ if (i0 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Printer Info Level 0:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+ fstring serv;
+
+ unistr_to_ascii(name, i0->printername.buffer, sizeof(name)-1);
+ unistr_to_ascii(serv, i0->servername .buffer, sizeof(serv)-1);
+
+ report(out_hnd, "\tprinter name:\t%s\n", name);
+ report(out_hnd, "\tserver name:\t%s\n", serv);
+ report(out_hnd, "\t[Other info not displayed]\n");
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+printer info level 1 display function
+****************************************************************************/
+void display_print_info_1(FILE *out_hnd, enum action_type action,
+ PRINTER_INFO_1 *const i1)
+{
+ if (i1 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Printer Info Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring desc;
+ fstring name;
+ fstring comm;
+
+ unistr_to_ascii(desc, i1->description.buffer, sizeof(desc)-1);
+ unistr_to_ascii(name, i1->name .buffer, sizeof(name)-1);
+ unistr_to_ascii(comm, i1->comment .buffer, sizeof(comm)-1);
+
+ report(out_hnd, "\tflags:\t%d\n", i1->flags);
+ report(out_hnd, "\tname:\t%s\n", name);
+ report(out_hnd, "\tdescription:\t%s\n", desc);
+ report(out_hnd, "\tcomment:\t%s\n", comm);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+connection info level 0 container display function
+****************************************************************************/
+void display_printer_info_0_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, PRINTER_INFO_0 *const *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_printer_info_0_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ display_print_info_0(out_hnd, ACTION_HEADER , ctr[i]);
+ display_print_info_0(out_hnd, ACTION_ENUMERATE, ctr[i]);
+ display_print_info_0(out_hnd, ACTION_FOOTER , ctr[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info level 1 container display function
+****************************************************************************/
+void display_printer_info_1_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, PRINTER_INFO_1 *const *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_printer_info_1_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ display_print_info_1(out_hnd, ACTION_HEADER , ctr[i]);
+ display_print_info_1(out_hnd, ACTION_ENUMERATE, ctr[i]);
+ display_print_info_1(out_hnd, ACTION_FOOTER , ctr[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_printer_info_ctr(FILE *out_hnd, enum action_type action,
+ uint32 level, uint32 count,
+ void *const *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_printer_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (level)
+ {
+ case 0:
+ {
+ display_printer_info_0_ctr(out_hnd, action,
+ count, (PRINTER_INFO_0*const*const)ctr);
+ break;
+ }
+ case 1:
+ {
+ display_printer_info_1_ctr(out_hnd, action,
+ count, (PRINTER_INFO_1*const*const)ctr);
+ break;
+ }
+ default:
+ {
+ report(out_hnd, "display_printer_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+job info level 2 display function
+****************************************************************************/
+void display_job_info_2(FILE *out_hnd, enum action_type action,
+ JOB_INFO_2 *const i2)
+{
+ if (i2 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Job Info Level 2:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring tmp;
+
+ report(out_hnd, "\tjob id:\t%d\n", i2->jobid);
+ unistr_to_ascii(tmp, i2->printername.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tprinter name:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i2->machinename.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tmachine name:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i2->username.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tusername:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i2->document.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tdocument:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i2->notifyname.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tnotify name:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i2->datatype.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tdata type:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i2->printprocessor.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tprint processor:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i2->parameters.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tparameters:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i2->drivername.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tdriver name:\t%s\n", tmp);
+ report(out_hnd, "\tDevice Mode:\tNOT DISPLAYED YET\n");
+/*
+ DEVICEMODE *devmode;
+*/
+ unistr_to_ascii(tmp, i2->text_status.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\ttext status:\t%s\n", tmp);
+ /* SEC_DESC sec_desc;*/
+ report(out_hnd, "\tstatus:\t%d\n", i2->status);
+ report(out_hnd, "\tpriority:\t%d\n", i2->priority);
+ report(out_hnd, "\tposition:\t%d\n", i2->position);
+ report(out_hnd, "\tstarttime:\t%d\n", i2->starttime);
+ report(out_hnd, "\tuntiltime:\t%d\n", i2->untiltime);
+ report(out_hnd, "\ttotalpages:\t%d\n", i2->totalpages);
+ report(out_hnd, "\tsize:\t%d\n", i2->size);
+/*
+ SYSTEMTIME submitted;
+*/
+ report(out_hnd, "\tsubmitted:\tNOT DISPLAYED YET\n");
+ report(out_hnd, "\ttimeelapsed:\t%d\n", i2->timeelapsed);
+ report(out_hnd, "\tpagesprinted:\t%d\n", i2->pagesprinted);
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+job info level 1 display function
+****************************************************************************/
+void display_job_info_1(FILE *out_hnd, enum action_type action,
+ JOB_INFO_1 *const i1)
+{
+ if (i1 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Job Info Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring tmp;
+
+ report(out_hnd, "\tjob id:\t%d\n", i1->jobid);
+ unistr_to_ascii(tmp, i1->printername.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tprinter name:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i1->machinename.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tmachine name:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i1->username.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tusername:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i1->document.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tdocument:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i1->datatype.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\tdata type:\t%s\n", tmp);
+ unistr_to_ascii(tmp, i1->text_status.buffer, sizeof(tmp)-1);
+ report(out_hnd, "\ttext status:\t%s\n", tmp);
+ report(out_hnd, "\tstatus:\t%d\n", i1->status);
+ report(out_hnd, "\tpriority:\t%d\n", i1->priority);
+ report(out_hnd, "\tposition:\t%d\n", i1->position);
+ report(out_hnd, "\ttotalpages:\t%d\n", i1->totalpages);
+/*
+ SYSTEMTIME submitted;
+*/
+ report(out_hnd, "\tsubmitted:\tNOT DISPLAYED YET\n");
+ report(out_hnd, "\tpagesprinted:\t%d\n", i1->pagesprinted);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+connection info level 2 container display function
+****************************************************************************/
+void display_job_info_2_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, JOB_INFO_2 *const *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_job_info_2_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ display_job_info_2(out_hnd, ACTION_HEADER , ctr[i]);
+ display_job_info_2(out_hnd, ACTION_ENUMERATE, ctr[i]);
+ display_job_info_2(out_hnd, ACTION_FOOTER , ctr[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info level 1 container display function
+****************************************************************************/
+void display_job_info_1_ctr(FILE *out_hnd, enum action_type action,
+ uint32 count, JOB_INFO_1 *const *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_job_info_1_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ display_job_info_1(out_hnd, ACTION_HEADER , ctr[i]);
+ display_job_info_1(out_hnd, ACTION_ENUMERATE, ctr[i]);
+ display_job_info_1(out_hnd, ACTION_FOOTER , ctr[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_job_info_ctr(FILE *out_hnd, enum action_type action,
+ uint32 level, uint32 count,
+ void *const *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_job_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (level)
+ {
+ case 1:
+ {
+ display_job_info_1_ctr(out_hnd, action,
+ count, (JOB_INFO_1*const*const)ctr);
+ break;
+ }
+ case 2:
+ {
+ display_job_info_2_ctr(out_hnd, action,
+ count, (JOB_INFO_2*const*const)ctr);
+ break;
+ }
+ default:
+ {
+ report(out_hnd, "display_job_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
diff --git a/source/rpcclient/display_srv.c b/source/rpcclient/display_srv.c
new file mode 100644
index 00000000000..d14c8f713dd
--- /dev/null
+++ b/source/rpcclient/display_srv.c
@@ -0,0 +1,1184 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+convert a share mode to a string
+****************************************************************************/
+char *get_file_mode_str(uint32 share_mode)
+{
+ static fstring mode;
+
+ switch (GET_DENY_MODE(share_mode))
+ {
+ case DENY_NONE : fstrcpy(mode, "DENY_NONE "); break;
+ case DENY_ALL : fstrcpy(mode, "DENY_ALL "); break;
+ case DENY_DOS : fstrcpy(mode, "DENY_DOS "); break;
+ case DENY_READ : fstrcpy(mode, "DENY_READ "); break;
+ case DENY_WRITE: fstrcpy(mode, "DENY_WRITE "); break;
+ case DENY_FCB: fstrcpy(mode, "DENY_FCB "); break;
+ default : fstrcpy(mode, "DENY_???? "); break;
+ }
+
+ switch (share_mode & 0xF)
+ {
+ case 0 : fstrcat(mode, "RDONLY"); break;
+ case 1 : fstrcat(mode, "WRONLY"); break;
+ case 2 : fstrcat(mode, "RDWR "); break;
+ default: fstrcat(mode, "R??W??"); break;
+ }
+
+ return mode;
+}
+/****************************************************************************
+convert an oplock mode to a string
+****************************************************************************/
+char *get_file_oplock_str(uint32 op_type)
+{
+ static fstring oplock;
+ BOOL excl = IS_BITS_SET_ALL(op_type, EXCLUSIVE_OPLOCK);
+ BOOL batch = IS_BITS_SET_ALL(op_type, BATCH_OPLOCK );
+
+ oplock[0] = 0;
+
+ if (excl ) fstrcat(oplock, "EXCLUSIVE");
+ if (excl && batch) fstrcat(oplock, "+");
+ if ( batch) fstrcat(oplock, "BATCH");
+ if (!excl && !batch) fstrcat(oplock, "NONE");
+
+ return oplock;
+}
+
+/****************************************************************************
+convert a share type enum to a string
+****************************************************************************/
+static const char *get_share_type_str(uint32 type)
+{
+ switch (type)
+ {
+ case STYPE_DISKTREE: return "Disk" ; break;
+ case STYPE_PRINTQ : return "Printer"; break;
+ case STYPE_DEVICE : return "Device" ; break;
+ case STYPE_IPC : return "IPC" ; break;
+ default : return "????" ; break;
+ }
+}
+
+/****************************************************************************
+convert a server type enum to a string
+****************************************************************************/
+char *get_server_type_str(uint32 type)
+{
+ static fstring typestr;
+
+ if (type == SV_TYPE_ALL)
+ {
+ fstrcpy(typestr, "All");
+ }
+ else
+ {
+ int i;
+ typestr[0] = 0;
+ for (i = 0; i < 32; i++)
+ {
+ if (IS_BITS_SET_ALL(type, 1 << i))
+ {
+ switch (1 << i)
+ {
+ case SV_TYPE_WORKSTATION : fstrcat(typestr, "Wk " ); break;
+ case SV_TYPE_SERVER : fstrcat(typestr, "Sv " ); break;
+ case SV_TYPE_SQLSERVER : fstrcat(typestr, "Sql "); break;
+ case SV_TYPE_DOMAIN_CTRL : fstrcat(typestr, "PDC "); break;
+ case SV_TYPE_DOMAIN_BAKCTRL : fstrcat(typestr, "BDC "); break;
+ case SV_TYPE_TIME_SOURCE : fstrcat(typestr, "Tim "); break;
+ case SV_TYPE_AFP : fstrcat(typestr, "AFP "); break;
+ case SV_TYPE_NOVELL : fstrcat(typestr, "Nov "); break;
+ case SV_TYPE_DOMAIN_MEMBER : fstrcat(typestr, "Dom "); break;
+ case SV_TYPE_PRINTQ_SERVER : fstrcat(typestr, "PrQ "); break;
+ case SV_TYPE_DIALIN_SERVER : fstrcat(typestr, "Din "); break;
+ case SV_TYPE_SERVER_UNIX : fstrcat(typestr, "Unx "); break;
+ case SV_TYPE_NT : fstrcat(typestr, "NT " ); break;
+ case SV_TYPE_WFW : fstrcat(typestr, "Wfw "); break;
+ case SV_TYPE_SERVER_MFPN : fstrcat(typestr, "Mfp "); break;
+ case SV_TYPE_SERVER_NT : fstrcat(typestr, "SNT "); break;
+ case SV_TYPE_POTENTIAL_BROWSER: fstrcat(typestr, "PtB "); break;
+ case SV_TYPE_BACKUP_BROWSER : fstrcat(typestr, "BMB "); break;
+ case SV_TYPE_MASTER_BROWSER : fstrcat(typestr, "LMB "); break;
+ case SV_TYPE_DOMAIN_MASTER : fstrcat(typestr, "DMB "); break;
+ case SV_TYPE_SERVER_OSF : fstrcat(typestr, "OSF "); break;
+ case SV_TYPE_SERVER_VMS : fstrcat(typestr, "VMS "); break;
+ case SV_TYPE_WIN95_PLUS : fstrcat(typestr, "W95 "); break;
+ case SV_TYPE_ALTERNATE_XPORT : fstrcat(typestr, "Xpt "); break;
+ case SV_TYPE_LOCAL_LIST_ONLY : fstrcat(typestr, "Dom "); break;
+ case SV_TYPE_DOMAIN_ENUM : fstrcat(typestr, "Loc "); break;
+ }
+ }
+ }
+ i = strlen(typestr)-1;
+ if (typestr[i] == ' ') typestr[i] = 0;
+
+ }
+ return typestr;
+}
+
+/****************************************************************************
+server info level 101 display function
+****************************************************************************/
+static void display_srv_info_101(FILE *out_hnd, enum action_type action,
+ const SRV_INFO_101 *sv101)
+{
+ if (sv101 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Server Info Level 101:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+ fstring comment;
+
+ unistr2_to_ascii(name, &sv101->uni_name, sizeof(name)-1);
+ unistr2_to_ascii(comment, &sv101->uni_comment, sizeof(comment)-1);
+
+ display_server(out_hnd, action, name, sv101->srv_type, comment);
+
+ report(out_hnd, "\tplatform_id :\t%d\n" , sv101->platform_id);
+ report(out_hnd, "\tos version :\t%d.%d\n" , sv101->ver_major, sv101->ver_minor);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+server info level 102 display function
+****************************************************************************/
+static void display_srv_info_102(FILE *out_hnd, enum action_type action,
+ const SRV_INFO_102 *sv102)
+{
+ if (sv102 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Server Info Level 102:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+ fstring comment;
+ fstring usr_path;
+
+ unistr2_to_ascii(name, &sv102->uni_name, sizeof(name)-1);
+ unistr2_to_ascii(comment, &sv102->uni_comment, sizeof(comment)-1);
+ unistr2_to_ascii(usr_path, &sv102->uni_usr_path,
+ sizeof(usr_path)-1);
+
+ display_server(out_hnd, action, name, sv102->srv_type, comment);
+
+ report(out_hnd, "\tplatform_id :\t%d\n" , sv102->platform_id);
+ report(out_hnd, "\tos version :\t%d.%d\n" , sv102->ver_major, sv102->ver_minor);
+
+ report(out_hnd, "\tusers :\t%x\n" , sv102->users );
+ report(out_hnd, "\tdisc, hidden :\t%x, %x\n" , sv102->disc , sv102->hidden );
+ report(out_hnd, "\tannounce, delta :\t%d, %d\n", sv102->announce , sv102->ann_delta);
+ report(out_hnd, "\tlicenses :\t%d\n" , sv102->licenses );
+ report(out_hnd, "\tuser path :\t%s\n" , usr_path);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+server info container display function
+****************************************************************************/
+void display_srv_info_ctr(FILE *out_hnd, enum action_type action,
+ const SRV_INFO_CTR *ctr)
+{
+ if (ctr == NULL || ctr->ptr_srv_ctr == 0)
+ {
+ report(out_hnd, "Server Information: unavailable due to an error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 101:
+ {
+ display_srv_info_101(out_hnd, action, &(ctr->srv.sv101));
+ break;
+ }
+ case 102:
+ {
+ display_srv_info_102(out_hnd, action, &(ctr->srv.sv102));
+ break;
+ }
+ default:
+ {
+ report(out_hnd, "Server Information: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info level 0 display function
+****************************************************************************/
+void display_conn_info_0(FILE *out_hnd, enum action_type action,
+ CONN_INFO_0 *const info0)
+{
+ if (info0 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Connection Info Level 0:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ report(out_hnd, "\tid:\t%d\n", info0->id);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+connection info level 1 display function
+****************************************************************************/
+void display_conn_info_1(FILE *out_hnd, enum action_type action,
+ CONN_INFO_1 *const info1, CONN_INFO_1_STR *const str1)
+{
+ if (info1 == NULL || str1 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Connection Info Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring usr_name;
+ fstring net_name;
+
+ unistr2_to_ascii(usr_name, &str1->uni_usr_name, sizeof(usr_name)-1);
+ unistr2_to_ascii(net_name, &str1->uni_net_name, sizeof(net_name)-1);
+
+ report(out_hnd, "\tid :\t%d\n", info1->id);
+ report(out_hnd, "\ttype :\t%s\n", get_share_type_str(info1->type));
+ report(out_hnd, "\tnum_opens:\t%d\n", info1->num_opens);
+ report(out_hnd, "\tnum_users:\t%d\n", info1->num_users);
+ report(out_hnd, "\topen_time:\t%d\n", info1->open_time);
+
+ report(out_hnd, "\tuser name:\t%s\n", usr_name);
+ report(out_hnd, "\tnet name:\t%s\n", net_name);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+connection info level 0 container display function
+****************************************************************************/
+void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_0 *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_srv_conn_info_0_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_conn_info_0(out_hnd, ACTION_HEADER , &(ctr->info_0[i]));
+ display_conn_info_0(out_hnd, ACTION_ENUMERATE, &(ctr->info_0[i]));
+ display_conn_info_0(out_hnd, ACTION_FOOTER , &(ctr->info_0[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info level 1 container display function
+****************************************************************************/
+void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_1 *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_srv_conn_info_1_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_conn_info_1(out_hnd, ACTION_HEADER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ display_conn_info_1(out_hnd, ACTION_ENUMERATE, &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ display_conn_info_1(out_hnd, ACTION_FOOTER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+connection info container display function
+****************************************************************************/
+void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_CONN_INFO_CTR *const ctr)
+{
+ if (ctr == NULL || ctr->ptr_conn_ctr == 0)
+ {
+ report(out_hnd, "display_srv_conn_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ display_srv_conn_info_0_ctr(out_hnd, action,
+ &(ctr->conn.info0));
+ break;
+ }
+ case 1:
+ {
+ display_srv_conn_info_1_ctr(out_hnd, action,
+ &(ctr->conn.info1));
+ break;
+ }
+ default:
+ {
+ report(out_hnd, "display_srv_conn_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+transport info level 0 display function
+****************************************************************************/
+void display_tprt_info_0(FILE *out_hnd, enum action_type action,
+ TPRT_INFO_0 *const info0, TPRT_INFO_0_STR *const str0)
+{
+ if (info0 == NULL || str0 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Transport Info Level 0:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring trans_name;
+ fstring trans_addr;
+ fstring addr_name;
+
+ unistr2_to_ascii(trans_name, &str0->uni_trans_name, sizeof(trans_name)-1);
+ buffer4_to_str(trans_addr, &str0->buf_trans_addr, sizeof(trans_addr)-1);
+ unistr2_to_ascii(addr_name, &str0->uni_addr_name, sizeof(addr_name)-1);
+
+ report(out_hnd, "\tnum_vcs :\t%d\n", info0->num_vcs);
+ report(out_hnd, "\ttransport name:\t%s\n", trans_name);
+ report(out_hnd, "\ttransport addr:\t%s\n", trans_addr);
+ report(out_hnd, "\taddress name:\t%s\n", addr_name);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+transport info level 0 container display function
+****************************************************************************/
+void display_srv_tprt_info_0_ctr(FILE *out_hnd, enum action_type action,
+ const SRV_TPRT_INFO_0 *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_srv_tprt_info_0_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_tprt_info_0(out_hnd, ACTION_HEADER , &(ctr->info_0[i]), &(ctr->info_0_str[i]));
+ display_tprt_info_0(out_hnd, ACTION_ENUMERATE, &(ctr->info_0[i]), &(ctr->info_0_str[i]));
+ display_tprt_info_0(out_hnd, ACTION_FOOTER , &(ctr->info_0[i]), &(ctr->info_0_str[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+transport info container display function
+****************************************************************************/
+void display_srv_tprt_info_ctr(FILE *out_hnd, enum action_type action,
+ const SRV_TPRT_INFO_CTR *const ctr)
+{
+ if (ctr == NULL || ctr->ptr_tprt_ctr == 0)
+ {
+ report(out_hnd, "display_srv_tprt_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ display_srv_tprt_info_0_ctr(out_hnd, action,
+ &(ctr->tprt.info0));
+ break;
+ }
+ default:
+ {
+ report(out_hnd, "display_srv_tprt_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+share info level 1 display function
+****************************************************************************/
+static void display_share_info_1(FILE *out_hnd, enum action_type action,
+ SH_INFO_1 *const info1, SH_INFO_1_STR *const str1)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Share Info Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring remark ;
+ fstring net_name;
+
+ if (info1 == NULL || str1 == NULL)
+ {
+ return;
+ }
+
+ unistr2_to_ascii(net_name, &str1->uni_netname, sizeof(net_name)-1);
+ unistr2_to_ascii(remark, &str1->uni_remark, sizeof(remark)-1);
+
+ display_share(out_hnd, action, net_name, info1->type, remark);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+share info level 2 display function
+****************************************************************************/
+static void display_share_info_2(FILE *out_hnd, enum action_type action,
+ SH_INFO_2 *const info2, SH_INFO_2_STR *const str2)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Share Info Level 2:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring remark ;
+ fstring net_name;
+ fstring path ;
+ fstring password;
+
+ if (info2 == NULL || str2 == NULL)
+ {
+ return;
+ }
+
+ unistr2_to_ascii(net_name, &str2->uni_netname, sizeof(net_name)-1);
+ unistr2_to_ascii(remark, &str2->uni_remark, sizeof(remark)-1);
+ unistr2_to_ascii(path, &str2->uni_path, sizeof(path)-1);
+ unistr2_to_ascii(password, &str2->uni_passwd, sizeof(password)-1);
+
+ display_share2(out_hnd, action, net_name, info2->type, remark,
+ info2->perms, info2->max_uses, info2->num_uses,
+ path, password);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+share info level 1 container display function
+****************************************************************************/
+static void display_srv_share_info_1_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_1 *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_srv_share_info_1_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ display_share_info_1(out_hnd, ACTION_HEADER, NULL, NULL);
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_share_info_1(out_hnd, ACTION_ENUMERATE, ctr->info_1[i], ctr->info_1_str[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ display_share_info_1(out_hnd, ACTION_FOOTER, NULL, NULL);
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+share info level 2 container display function
+****************************************************************************/
+static void display_srv_share_info_2_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_2 *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_srv_share_info_2_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ display_share_info_2(out_hnd, ACTION_HEADER, NULL, NULL);
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_share_info_2(out_hnd, ACTION_ENUMERATE, ctr->info_2[i], ctr->info_2_str[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ display_share_info_2(out_hnd, ACTION_FOOTER, NULL, NULL);
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+share info container display function
+****************************************************************************/
+void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SHARE_INFO_CTR *const ctr)
+{
+ if (ctr == NULL || ctr->ptr_share_ctr == 0)
+ {
+ report(out_hnd, "display_srv_share_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 1:
+ {
+ display_srv_share_info_1_ctr(out_hnd, action,
+ &(ctr->share.info1));
+ break;
+ }
+ case 2:
+ {
+ display_srv_share_info_2_ctr(out_hnd, action,
+ &(ctr->share.info2));
+ break;
+ }
+ default:
+ {
+ report(out_hnd, "display_srv_share_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+file info level 3 display function
+****************************************************************************/
+static void display_file_info_3(FILE *out_hnd, enum action_type action,
+ const FILE_INFO_3 *info3,
+ const FILE_INFO_3_STR *str3)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "File Info Level 3:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring path_name;
+ fstring user_name;
+
+ if (info3 == NULL || str3 == NULL)
+ {
+ return;
+ }
+
+ unistr2_to_ascii(path_name, &str3->uni_path_name,
+ sizeof(path_name)-1);
+ unistr2_to_ascii(user_name, &str3->uni_user_name,
+ sizeof(user_name)-1);
+
+ report(out_hnd, "\tid :\t%d\n", info3->id);
+ report(out_hnd, "\tperms :\t%s\n", get_file_mode_str(info3->perms));
+ report(out_hnd, "\tnum_locks:\t%d\n", info3->num_locks);
+
+ report(out_hnd, "\tpath name:\t%s\n", path_name);
+ report(out_hnd, "\tuser name:\t%s\n", user_name);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+file info level 3 container display function
+****************************************************************************/
+static void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action,
+ const SRV_FILE_INFO_3 *ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_srv_file_info_3_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ display_file_info_3(out_hnd, ACTION_HEADER, NULL, NULL);
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_file_info_3(out_hnd, ACTION_ENUMERATE, ctr->info_3[i], ctr->info_3_str[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ display_file_info_3(out_hnd, ACTION_FOOTER, NULL, NULL);
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+file info container display function
+****************************************************************************/
+void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_FILE_INFO_CTR *const ctr)
+{
+ if (ctr == NULL || ctr->ptr_file_ctr == 0)
+ {
+ report(out_hnd, "display_srv_file_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 3:
+ {
+ display_srv_file_info_3_ctr(out_hnd, action,
+ &(ctr->file.info3));
+ break;
+ }
+ default:
+ {
+ report(out_hnd, "display_srv_file_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+sess info level 0 display function
+****************************************************************************/
+void display_sess_info_0(FILE *out_hnd, enum action_type action,
+ SESS_INFO_0 *const info0, SESS_INFO_0_STR *const str0)
+{
+ if (info0 == NULL || str0 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Session Info Level 0:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+
+ unistr2_to_ascii(name, &str0->uni_name,
+ sizeof(name)-1);
+
+ report(out_hnd, "\tname:\t%s\n", name);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+sess info level 1 display function
+****************************************************************************/
+void display_sess_info_1(FILE *out_hnd, enum action_type action,
+ SESS_INFO_1 *const info1, SESS_INFO_1_STR *const str1)
+{
+ if (info1 == NULL || str1 == NULL)
+ {
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "Session Info Level 1:\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+ fstring user_name;
+
+ unistr2_to_ascii(user_name, &str1->uni_user,
+ sizeof(user_name)-1);
+ unistr2_to_ascii(name, &str1->uni_name,
+ sizeof(name)-1);
+
+ report(out_hnd, "\tname:\t%s\n", name);
+
+ report(out_hnd, "\topen :\t%d\n", info1->num_opens);
+ report(out_hnd, "\ttime :\t%d\n", info1->open_time);
+ report(out_hnd, "\tidle :\t%d\n", info1->idle_time);
+ report(out_hnd, "\tflags:\t%d\n", info1->user_flags);
+
+ report(out_hnd, "\tuser :\t%s\n", user_name);
+
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+
+}
+
+/****************************************************************************
+sess info level 0 container display function
+****************************************************************************/
+void display_srv_sess_info_0_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SESS_INFO_0 *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_srv_sess_info_0_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_sess_info_0(out_hnd, ACTION_HEADER , &(ctr->info_0[i]), &(ctr->info_0_str[i]));
+ display_sess_info_0(out_hnd, ACTION_ENUMERATE, &(ctr->info_0[i]), &(ctr->info_0_str[i]));
+ display_sess_info_0(out_hnd, ACTION_FOOTER , &(ctr->info_0[i]), &(ctr->info_0_str[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+sess info level 1 container display function
+****************************************************************************/
+void display_srv_sess_info_1_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SESS_INFO_1 *const ctr)
+{
+ if (ctr == NULL)
+ {
+ report(out_hnd, "display_srv_sess_info_1_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+
+ for (i = 0; i < ctr->num_entries_read; i++)
+ {
+ display_sess_info_1(out_hnd, ACTION_HEADER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ display_sess_info_1(out_hnd, ACTION_ENUMERATE, &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ display_sess_info_1(out_hnd, ACTION_FOOTER , &(ctr->info_1[i]), &(ctr->info_1_str[i]));
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+sess info container display function
+****************************************************************************/
+void display_srv_sess_info_ctr(FILE *out_hnd, enum action_type action,
+ SRV_SESS_INFO_CTR *const ctr)
+{
+ if (ctr == NULL || ctr->ptr_sess_ctr == 0)
+ {
+ report(out_hnd, "display_srv_sess_info_ctr: unavailable due to an internal error\n");
+ return;
+ }
+
+ switch (ctr->switch_value)
+ {
+ case 0:
+ {
+ display_srv_sess_info_0_ctr(out_hnd, action,
+ &(ctr->sess.info0));
+ break;
+ }
+ case 1:
+ {
+ display_srv_sess_info_1_ctr(out_hnd, action,
+ &(ctr->sess.info1));
+ break;
+ }
+ default:
+ {
+ report(out_hnd, "display_srv_sess_info_ctr: Unknown Info Level\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ print browse connection on a host
+ ****************************************************************************/
+void display_server(FILE *out_hnd, enum action_type action,
+ char *const sname, uint32 type, char *const comment)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ report(out_hnd, "\t%-15.15s%-20s %s\n",
+ sname, get_server_type_str(type), comment);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+print shares on a host
+****************************************************************************/
+void display_share(FILE *out_hnd, enum action_type action,
+ char *const sname, uint32 type, char *const comment)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ report(out_hnd, "\t%-15.15s%-8s %s\n",
+ sname, get_share_type_str(type), comment);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+print shares on a host, level 2
+****************************************************************************/
+void display_share2(FILE *out_hnd, enum action_type action,
+ char *const sname, uint32 type, char *const comment,
+ uint32 perms, uint32 max_uses, uint32 num_uses,
+ char *const path, char *const password)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ report(out_hnd,
+ "\t%-15.15s%-8s %x %d/%d\n",
+ sname, get_share_type_str(type),
+ perms, num_uses, max_uses);
+ report(out_hnd,
+ "\t\t\t\t%s %s\n", path, password);
+ if (comment && *comment)
+ {
+ report(out_hnd, "\t\t\t\t%s\n", comment);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+
+/****************************************************************************
+print name info
+****************************************************************************/
+void display_name(FILE *out_hnd, enum action_type action,
+ char *const sname)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ report(out_hnd, "\t%-21.21s\n", sname);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
diff --git a/source/rpcclient/display_svc.c b/source/rpcclient/display_svc.c
new file mode 100644
index 00000000000..04b366a216d
--- /dev/null
+++ b/source/rpcclient/display_svc.c
@@ -0,0 +1,126 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+/****************************************************************************
+convert a security permissions into a string
+****************************************************************************/
+char *get_svc_start_type_str(uint32 type)
+{
+ static fstring typestr;
+
+ switch (type)
+ {
+ case 0x00: fstrcpy(typestr, "Boot" ); return typestr;
+ case 0x01: fstrcpy(typestr, "System" ); return typestr;
+ case 0x02: fstrcpy(typestr, "Auto" ); return typestr;
+ case 0x03: fstrcpy(typestr, "Manual" ); return typestr;
+ case 0x04: fstrcpy(typestr, "Disabled"); return typestr;
+ default : break;
+ }
+ slprintf(typestr, sizeof(typestr)-1, "[%d]", type);
+ return typestr;
+}
+
+
+/****************************************************************************
+ display structure
+ ****************************************************************************/
+void display_query_svc_cfg(FILE *out_hnd, enum action_type action,
+ const QUERY_SERVICE_CONFIG *const cfg)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ fstring service;
+
+ unistr2_to_ascii(service, &cfg->uni_display_name, sizeof(service)-1);
+ report(out_hnd, "\tService:\t%s\n", service);
+ report(out_hnd, "\t-------\n");
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring temp;
+
+ unistr2_to_ascii(temp, &cfg->uni_bin_path_name, sizeof(temp)-1);
+ report(out_hnd, "\tPath:\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &cfg->uni_load_order_grp, sizeof(temp)-1);
+ report(out_hnd, "\tLoad Order:\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &cfg->uni_dependencies, sizeof(temp)-1);
+ report(out_hnd, "\tDependencies:\t%s\n", temp);
+
+ unistr2_to_ascii(temp, &cfg->uni_service_start_name, sizeof(temp)-1);
+ report(out_hnd, "\tService Start:\t%s\n", temp);
+
+ report(out_hnd, "\tService Type:\t%d\n", cfg->service_type);
+ report(out_hnd, "\tStart Type:\t%s\n" , get_svc_start_type_str(cfg->start_type));
+ report(out_hnd, "\tError Control:\t%d\n" , cfg->error_control);
+ report(out_hnd, "\tTag Id:\t%d\n" , cfg->tag_id);
+ break;
+
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display structure
+ ****************************************************************************/
+void display_svc_info(FILE *out_hnd, enum action_type action,
+ const ENUM_SRVC_STATUS *const svc)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ fstring name;
+
+ unistr_to_ascii(name, svc->uni_srvc_name.buffer,
+ sizeof(name)-1); /* service name */
+ report(out_hnd, "\t%s:", name);
+
+ unistr_to_ascii(name, svc->uni_disp_name.buffer,
+ sizeof(name)-1); /* display name */
+ report(out_hnd, "\t%s\n", name);
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
diff --git a/source/rpcclient/display_sync.c b/source/rpcclient/display_sync.c
new file mode 100644
index 00000000000..8250a96f021
--- /dev/null
+++ b/source/rpcclient/display_sync.c
@@ -0,0 +1,116 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Samba utility functions
+ Copyright (C) Andrew Tridgell 1992-1999
+ Copyright (C) Luke Kenneth Casson Leighton 1996 - 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+/****************************************************************************
+ display sam sync structure
+ ****************************************************************************/
+void display_sam_sync_ctr(FILE *out_hnd, enum action_type action,
+ SAM_DELTA_HDR *const delta,
+ SAM_DELTA_CTR *const ctr)
+{
+ fstring name;
+
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ switch (delta->type)
+ {
+ case 1:
+ {
+ unistr2_to_ascii(name, &(ctr->domain_info.uni_dom_name), sizeof(name)-1);
+ report(out_hnd, "Domain: %s\n", name);
+ break;
+ }
+ case 2:
+ {
+ unistr2_to_ascii(name, &(ctr->group_info.uni_grp_name), sizeof(name)-1);
+ report(out_hnd, "Group: %s\n", name);
+ break;
+ }
+ case 5:
+ {
+ unsigned char lm_pwd[16];
+ unsigned char nt_pwd[16];
+
+ unistr2_to_ascii(name, &(ctr->account_info.uni_acct_name), sizeof(name)-1);
+ report(out_hnd, "Account: %s\n", name);
+
+ sam_pwd_hash(ctr->account_info.user_rid, ctr->account_info.pass.buf_lm_pwd, lm_pwd, 0);
+ out_struct(out_hnd, lm_pwd, 16, 8);
+
+ sam_pwd_hash(ctr->account_info.user_rid, ctr->account_info.pass.buf_nt_pwd, nt_pwd, 0);
+ out_struct(out_hnd, nt_pwd, 16, 8);
+ }
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ break;
+ }
+ }
+}
+
+/****************************************************************************
+ display sam sync structure
+ ****************************************************************************/
+void display_sam_sync(FILE *out_hnd, enum action_type action,
+ SAM_DELTA_HDR *const deltas,
+ SAM_DELTA_CTR *const ctr,
+ uint32 num)
+{
+ switch (action)
+ {
+ case ACTION_HEADER:
+ {
+ report(out_hnd, "\tSAM Database Sync\n");
+ report(out_hnd, "\t-----------------\n");
+
+ break;
+ }
+ case ACTION_ENUMERATE:
+ {
+ int i;
+ for (i = 0; i < num; i++)
+ {
+ display_sam_sync_ctr(out_hnd, ACTION_HEADER , &deltas[i], &ctr[i]);
+ display_sam_sync_ctr(out_hnd, ACTION_ENUMERATE, &deltas[i], &ctr[i]);
+ display_sam_sync_ctr(out_hnd, ACTION_FOOTER , &deltas[i], &ctr[i]);
+ }
+ break;
+ }
+ case ACTION_FOOTER:
+ {
+ report(out_hnd, "\n");
+ break;
+ }
+ }
+}
+
diff --git a/source/rpcclient/eventlog.c b/source/rpcclient/eventlog.c
new file mode 100644
index 00000000000..675d18f3640
--- /dev/null
+++ b/source/rpcclient/eventlog.c
@@ -0,0 +1,35 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+
+int main(int argc, char *argv[])
+{
+ add_evt_commands();
+
+ return command_main(argc, argv);
+}
diff --git a/source/rpcclient/eventlog_cmds.c b/source/rpcclient/eventlog_cmds.c
new file mode 100644
index 00000000000..23df4598a91
--- /dev/null
+++ b/source/rpcclient/eventlog_cmds.c
@@ -0,0 +1,56 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "ntdomain.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+static const struct command_set evt_commands[] = {
+ /*
+ * eventlog
+ */
+
+ {
+ "eventlog",
+ cmd_eventlog,
+ "list the events",
+ {NULL, NULL}
+ },
+
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
+ }
+};
+
+void add_evt_commands(void)
+{
+ add_command_set(evt_commands);
+}
diff --git a/source/rpcclient/lsa.c b/source/rpcclient/lsa.c
new file mode 100644
index 00000000000..a431c26a40d
--- /dev/null
+++ b/source/rpcclient/lsa.c
@@ -0,0 +1,35 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+
+ int main(int argc, char *argv[])
+{
+ add_lsa_commands();
+
+ return command_main(argc, argv);
+}
diff --git a/source/rpcclient/lsa_cmds.c b/source/rpcclient/lsa_cmds.c
new file mode 100644
index 00000000000..117832076c9
--- /dev/null
+++ b/source/rpcclient/lsa_cmds.c
@@ -0,0 +1,101 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "ntdomain.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+static const struct command_set lsa_commands[] =
+{
+ /*
+ * lsa
+ */
+
+ {
+ "lsaquery",
+ cmd_lsa_query_info,
+ "Query Info Policy (domain member or server)",
+ {NULL, NULL}
+ },
+ {
+ "lsaenumdomains",
+ cmd_lsa_enum_trust_dom,
+ "Enumerate Trusted Domains",
+ {NULL, NULL}
+ },
+ {
+ "lookupsids",
+ cmd_lsa_lookup_sids,
+ "Resolve names from SIDs",
+ {NULL, NULL}
+ },
+ {
+ "lookupnames",
+ cmd_lsa_lookup_names,
+ "Resolve SIDs from names",
+ {NULL, NULL}
+ },
+ {
+ "createsecret",
+ cmd_lsa_create_secret,
+ "LSA Create Secret (developer use)",
+ {NULL, NULL}
+ },
+ {
+ "setsecret",
+ cmd_lsa_set_secret,
+ "LSA Set Secret (developer use)",
+ {NULL, NULL}
+ },
+ {
+ "querysecretsecobj",
+ cmd_lsa_query_secret_secobj,
+ "LSA Query Secret Security Descriptor (developer use)",
+ {NULL, NULL}
+ },
+
+ {
+ "querysecret",
+ cmd_lsa_query_secret,
+ "LSA Query Secret (developer use)",
+ {NULL, NULL}
+ },
+
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
+ }
+};
+
+void add_lsa_commands(void)
+{
+ add_command_set(lsa_commands);
+}
diff --git a/source/rpcclient/net.c b/source/rpcclient/net.c
new file mode 100644
index 00000000000..b70452cc074
--- /dev/null
+++ b/source/rpcclient/net.c
@@ -0,0 +1,35 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+
+ int main(int argc, char *argv[])
+{
+ add_net_commands();
+
+ return command_main(argc, argv);
+}
diff --git a/source/rpcclient/net_cmds.c b/source/rpcclient/net_cmds.c
new file mode 100644
index 00000000000..fdc2b549bfb
--- /dev/null
+++ b/source/rpcclient/net_cmds.c
@@ -0,0 +1,111 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "ntdomain.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+static const struct command_set net_commands[] =
+{
+ /*
+ * server
+ */
+ {
+ "time",
+ cmd_time,
+ "Display remote time",
+ {NULL, NULL}
+ },
+ {
+ "brsinfo",
+ cmd_brs_query_info,
+ "Browser Query Info",
+ {NULL, NULL}
+ },
+ {
+ "wksinfo",
+ cmd_wks_query_info,
+ "Workstation Query Info",
+ {NULL, NULL}
+ },
+ {
+ "srvinfo",
+ cmd_srv_query_info,
+ "Server Query Info",
+ {NULL, NULL}
+ },
+ {
+ "srvsessions",
+ cmd_srv_enum_sess,
+ "List sessions on a server",
+ {NULL, NULL}
+ },
+ {
+ "srvshares",
+ cmd_srv_enum_shares,
+ "List shares on a server",
+ {NULL, NULL}
+ },
+ {
+ "srvshareinfo",
+ cmd_srv_share_get_info,
+ "SHARE [1|2|502]\tGet info for share",
+ {NULL, NULL}
+ },
+ {
+ "srvtransports",
+ cmd_srv_enum_tprt,
+ "List transports on a server",
+ {NULL, NULL}
+ },
+ {
+ "srvconnections",
+ cmd_srv_enum_conn,
+ "List connections on a server",
+ {NULL, NULL}
+ },
+ {
+ "srvfiles",
+ cmd_srv_enum_files,
+ "List files on a server",
+ {NULL, NULL}
+ },
+
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
+ }
+};
+
+void add_net_commands(void)
+{
+ add_command_set(net_commands);
+}
diff --git a/source/rpcclient/netlogon_cmds.c b/source/rpcclient/netlogon_cmds.c
new file mode 100644
index 00000000000..d0903149f7f
--- /dev/null
+++ b/source/rpcclient/netlogon_cmds.c
@@ -0,0 +1,71 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "ntdomain.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+static const struct command_set ntl_commands[] =
+{
+ /*
+ * netlogon
+ */
+
+ {
+ "ntlogin",
+ cmd_netlogon_login_test,
+ "[[DOMAIN\\]username] [password] NT Domain login test",
+ {NULL, NULL}
+ },
+ {
+ "domtrust",
+ cmd_netlogon_domain_test,
+ "<domain> NT Inter-Domain test",
+ {NULL, NULL}
+ },
+ {
+ "samsync",
+ cmd_sam_sync,
+ "SAM Synchronization Test (experimental)",
+ {NULL, NULL}
+ },
+
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
+ }
+};
+
+void add_ntl_commands(void)
+{
+ add_command_set(ntl_commands);
+}
diff --git a/source/rpcclient/regedit.c b/source/rpcclient/regedit.c
new file mode 100644
index 00000000000..dd4a893907f
--- /dev/null
+++ b/source/rpcclient/regedit.c
@@ -0,0 +1,34 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+ int main(int argc, char *argv[])
+{
+ add_reg_commands();
+
+ return command_main(argc, argv);
+}
diff --git a/source/rpcclient/regedit_cmds.c b/source/rpcclient/regedit_cmds.c
new file mode 100644
index 00000000000..426d440eea3
--- /dev/null
+++ b/source/rpcclient/regedit_cmds.c
@@ -0,0 +1,200 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+extern struct client_info cli_info;
+
+/* Complete a remote registry enum */
+
+static uint32 reg_list_len = 0;
+static char **reg_name = NULL;
+
+static void reg_init(int val, const char *full_keyname, int num)
+{
+ switch (val)
+ {
+ case 0:
+ {
+ free_char_array(reg_list_len, reg_name);
+ reg_list_len = 0;
+ reg_name = NULL;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+static void reg_key_list(const char *full_name,
+ const char *name, time_t key_mod_time)
+{
+ fstring key_name;
+ slprintf(key_name, sizeof(key_name) - 1, "%s\\", name);
+ add_chars_to_array(&reg_list_len, &reg_name, key_name);
+}
+
+static void reg_val_list(const char *full_name,
+ const char *name, uint32 type, const BUFFER2 * value)
+{
+ add_chars_to_array(&reg_list_len, &reg_name, name);
+}
+
+extern char** cmd_argv;
+extern uint32 cmd_argc;
+
+static char *complete_regenum(char *text, int state)
+{
+ pstring full_keyname;
+ static uint32 i = 0;
+
+ if (state == 0)
+ {
+ fstring srv_name;
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli_info.dest_host);
+ strupper(srv_name);
+
+ if (cmd_argc >= 2 && cmd_argv != NULL && cmd_argv[1] != NULL)
+ {
+ char *sep;
+ split_server_keyname(srv_name, full_keyname,
+ cmd_argv[1]);
+
+ sep = strrchr(full_keyname, '\\');
+ if (sep != NULL)
+ {
+ *sep = 0;
+ }
+ }
+
+ /* Iterate all keys / values */
+ if (!msrpc_reg_enum_key(srv_name, full_keyname,
+ reg_init, reg_key_list, reg_val_list))
+ {
+ return NULL;
+ }
+
+ i = 0;
+ }
+
+ for (; i < reg_list_len; i++)
+ {
+ if (text == NULL || text[0] == 0 ||
+ strnequal(text, reg_name[i], strlen(text)))
+ {
+ char *name = strdup(reg_name[i]);
+ i++;
+ return name;
+ }
+ }
+
+ return NULL;
+}
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+static const struct command_set reg_commands[] =
+{
+ /*
+ * registry
+ */
+
+ {
+ "regenum",
+ cmd_reg_enum,
+ "<keyname> Registry Enumeration (keys, values)",
+ {complete_regenum, NULL}
+ },
+ {
+ "regdeletekey",
+ cmd_reg_delete_key,
+ "<keyname> Registry Key Delete",
+ {complete_regenum, NULL}
+ },
+ {
+ "regcreatekey",
+ cmd_reg_create_key,
+ "<keyname> [keyclass] Registry Key Create",
+ {complete_regenum, NULL}
+ },
+ {
+ "shutdown",
+ cmd_reg_shutdown,
+ "[-m message] [-t timeout] [-r or --reboot] [-f or --force-close] Remote Shutdown",
+ {NULL, NULL}
+ },
+ {
+ "regqueryval",
+ cmd_reg_query_info,
+ "<valname> Registry Value Query",
+ {complete_regenum, NULL}
+ },
+ {
+ "regquerykey",
+ cmd_reg_query_key,
+ "<keyname> Registry Key Query",
+ {complete_regenum, NULL}
+ },
+ {
+ "regdeleteval",
+ cmd_reg_delete_val,
+ "<valname> Registry Value Delete",
+ {complete_regenum, complete_regenum}
+ },
+ {
+ "regcreateval",
+ cmd_reg_create_val,
+ "<valname> <valtype> <value> Registry Key Create",
+ {complete_regenum, NULL}
+ },
+ {
+ "reggetsec",
+ cmd_reg_get_key_sec,
+ "<keyname> Registry Key Security",
+ {complete_regenum, NULL}
+ },
+ {
+ "regtestsec",
+ cmd_reg_test_key_sec,
+ "<keyname> Test Registry Key Security",
+ {complete_regenum, NULL}
+ },
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
+ }
+};
+
+void add_reg_commands(void)
+{
+ add_command_set(reg_commands);
+}
diff --git a/source/rpcclient/rpcclient.c b/source/rpcclient/rpcclient.c
index 187d51c3ad6..7477cacb529 100644
--- a/source/rpcclient/rpcclient.c
+++ b/source/rpcclient/rpcclient.c
@@ -2,7 +2,8 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB client
- Copyright (C) Andrew Tridgell 1994-1998
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,750 +20,21 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifdef SYSLOG
-#undef SYSLOG
-#endif
-
#include "includes.h"
-
-#ifndef REGISTER
-#define REGISTER 0
-#endif
-
-extern pstring debugf;
-extern pstring global_myname;
-
-extern pstring user_socket_options;
-
-
-extern int DEBUGLEVEL;
-
-
-extern file_info def_finfo;
-
-#define CNV_LANG(s) dos2unix_format(s,False)
-#define CNV_INPUT(s) unix2dos_format(s,True)
-
-static int process_tok(fstring tok);
-static void cmd_help(struct client_info *info);
-static void cmd_quit(struct client_info *info);
-
-static struct cli_state smbcli;
-struct cli_state *smb_cli = &smbcli;
-
-FILE *out_hnd;
-
-/****************************************************************************
-initialise smb client structure
-****************************************************************************/
-void rpcclient_init(void)
-{
- memset((char *)smb_cli, '\0', sizeof(smb_cli));
- cli_initialise(smb_cli);
- smb_cli->capabilities |= CAP_NT_SMBS | CAP_STATUS32;
-}
-
-/****************************************************************************
-make smb client connection
-****************************************************************************/
-static BOOL rpcclient_connect(struct client_info *info)
-{
- struct nmb_name calling;
- struct nmb_name called;
-
- make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type);
- make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0 );
-
- if (!cli_establish_connection(smb_cli,
- info->dest_host, &info->dest_ip,
- &calling, &called,
- info->share, info->svc_type,
- False, True))
- {
- DEBUG(0,("rpcclient_connect: connection failed\n"));
- cli_shutdown(smb_cli);
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
-stop the smb connection(s?)
-****************************************************************************/
-static void rpcclient_stop(void)
-{
- cli_shutdown(smb_cli);
-}
-/****************************************************************************
- This defines the commands supported by this client
- ****************************************************************************/
-struct
-{
- char *name;
- void (*fn)(struct client_info*);
- char *description;
-} commands[] =
-{
- {"regenum", cmd_reg_enum, "<keyname> Registry Enumeration (keys, values)"},
- {"regdeletekey",cmd_reg_delete_key, "<keyname> Registry Key Delete"},
- {"regcreatekey",cmd_reg_create_key, "<keyname> [keyclass] Registry Key Create"},
- {"regquerykey",cmd_reg_query_key, "<keyname> Registry Key Query"},
- {"regdeleteval",cmd_reg_delete_val, "<valname> Registry Value Delete"},
- {"regcreateval",cmd_reg_create_val, "<valname> <valtype> <value> Registry Key Create"},
- {"reggetsec", cmd_reg_get_key_sec, "<keyname> Registry Key Security"},
- {"regtestsec", cmd_reg_test_key_sec, "<keyname> Test Registry Key Security"},
- {"ntlogin", cmd_netlogon_login_test, "[username] [password] NT Domain login test"},
- {"wksinfo", cmd_wks_query_info, "Workstation Query Info"},
- {"srvinfo", cmd_srv_query_info, "Server Query Info"},
- {"srvsessions",cmd_srv_enum_sess, "List sessions on a server"},
- {"srvshares", cmd_srv_enum_shares, "List shares on a server"},
- {"srvconnections",cmd_srv_enum_conn, "List connections on a server"},
- {"srvfiles", cmd_srv_enum_files, "List files on a server"},
- {"lsaquery", cmd_lsa_query_info, "Query Info Policy (domain member or server)"},
- {"lookupsids", cmd_lsa_lookup_sids, "Resolve names from SIDs"},
- {"enumusers", cmd_sam_enum_users, "SAM User Database Query (experimental!)"},
- {"ntpass", cmd_sam_ntchange_pwd, "NT SAM Password Change"},
- {"samuser", cmd_sam_query_user, "<username> SAM User Query (experimental!)"},
- {"samtest", cmd_sam_test , "SAM User Encrypted RPC test (experimental!)"},
- {"enumaliases",cmd_sam_enum_aliases, "SAM Aliases Database Query (experimental!)"},
-#if 0
- {"enumgroups", cmd_sam_enum_groups, "SAM Group Database Query (experimental!)"},
-#endif
- {"samgroups", cmd_sam_query_groups, "SAM Group Database Query (experimental!)"},
- {"quit", cmd_quit, "logoff the server"},
- {"q", cmd_quit, "logoff the server"},
- {"exit", cmd_quit, "logoff the server"},
- {"bye", cmd_quit, "logoff the server"},
- {"help", cmd_help, "[command] give help on a command"},
- {"?", cmd_help, "[command] give help on a command"},
- {"!", NULL, "run a shell command on the local system"},
- {"", NULL, NULL}
-};
-
-
-/****************************************************************************
-do a (presumably graceful) quit...
-****************************************************************************/
-static void cmd_quit(struct client_info *info)
-{
- rpcclient_stop();
- exit(0);
-}
-
-/****************************************************************************
-help
-****************************************************************************/
-static void cmd_help(struct client_info *info)
-{
- int i=0,j;
- fstring buf;
-
- if (next_token(NULL,buf,NULL, sizeof(buf)))
- {
- if ((i = process_tok(buf)) >= 0)
- fprintf(out_hnd, "HELP %s:\n\t%s\n\n",commands[i].name,commands[i].description);
- }
- else
- while (commands[i].description)
- {
- for (j=0; commands[i].description && (j<5); j++) {
- fprintf(out_hnd, "%-15s",commands[i].name);
- i++;
- }
- fprintf(out_hnd, "\n");
- }
-}
-
-/*******************************************************************
- lookup a command string in the list of commands, including
- abbreviations
- ******************************************************************/
-static int process_tok(fstring tok)
-{
- int i = 0, matches = 0;
- int cmd=0;
- int tok_len = strlen(tok);
-
- while (commands[i].fn != NULL)
- {
- if (strequal(commands[i].name,tok))
- {
- matches = 1;
- cmd = i;
- break;
- }
- else if (strnequal(commands[i].name, tok, tok_len))
- {
- matches++;
- cmd = i;
- }
- i++;
- }
-
- if (matches == 0)
- return(-1);
- else if (matches == 1)
- return(cmd);
- else
- return(-2);
-}
-
-/****************************************************************************
-wait for keyboard activity, swallowing network packets
-****************************************************************************/
-static void wait_keyboard(struct cli_state *cli)
-{
- fd_set fds;
- struct timeval timeout;
-
- while (1)
- {
- FD_ZERO(&fds);
- FD_SET(cli->fd,&fds);
- FD_SET(fileno(stdin),&fds);
-
- timeout.tv_sec = 20;
- timeout.tv_usec = 0;
- sys_select(MAX(cli->fd,fileno(stdin))+1,&fds,&timeout);
-
- if (FD_ISSET(fileno(stdin),&fds))
- return;
-
- /* We deliberately use receive_smb instead of
- client_receive_smb as we want to receive
- session keepalives and then drop them here.
- */
- if (FD_ISSET(cli->fd,&fds))
- receive_smb(cli->fd,cli->inbuf,0);
- }
-}
-
-/****************************************************************************
- process commands from the client
-****************************************************************************/
-static void do_command(struct client_info *info, char *tok, char *line)
-{
- int i;
-
- if ((i = process_tok(tok)) >= 0)
- {
- commands[i].fn(info);
- }
- else if (i == -2)
- {
- fprintf(out_hnd, "%s: command abbreviation ambiguous\n", CNV_LANG(tok));
- }
- else
- {
- fprintf(out_hnd, "%s: command not found\n", CNV_LANG(tok));
- }
-}
-
-/****************************************************************************
- process commands from the client
-****************************************************************************/
-static BOOL process( struct client_info *info, char *cmd_str)
-{
- pstring line;
- char *cmd = cmd_str;
-
- if (cmd[0] != '\0') while (cmd[0] != '\0')
- {
- char *p;
- fstring tok;
-
- if ((p = strchr(cmd, ';')) == 0)
- {
- strncpy(line, cmd, 999);
- line[1000] = '\0';
- cmd += strlen(cmd);
- }
- else
- {
- if (p - cmd > 999) p = cmd + 999;
- strncpy(line, cmd, p - cmd);
- line[p - cmd] = '\0';
- cmd = p + 1;
- }
-
- /* input language code to internal one */
- CNV_INPUT (line);
-
- /* get the first part of the command */
- {
- char *ptr = line;
- if (!next_token(&ptr,tok,NULL, sizeof(tok))) continue;
- }
-
- do_command(info, tok, line);
- }
- else while (!feof(stdin))
- {
- fstring tok;
-
- /* display a prompt */
- fprintf(out_hnd, "smb: %s> ", CNV_LANG(info->cur_dir));
- fflush(out_hnd);
-
-#ifdef CLIX
- line[0] = wait_keyboard(smb_cli);
- /* this might not be such a good idea... */
- if ( line[0] == EOF)
- {
- break;
- }
-#else
- wait_keyboard(smb_cli);
-#endif
-
- /* and get a response */
-#ifdef CLIX
- fgets( &line[1],999, stdin);
-#else
- if (!fgets(line,1000,stdin))
- {
- break;
- }
-#endif
-
- /* input language code to internal one */
- CNV_INPUT (line);
-
- /* special case - first char is ! */
- if (*line == '!')
- {
- system(line + 1);
- continue;
- }
-
- fprintf(out_hnd, "%s\n", line);
-
- /* get the first part of the command */
- {
- char *ptr = line;
- if (!next_token(&ptr,tok,NULL, sizeof(tok))) continue;
- }
-
- do_command(info, tok, line);
- }
-
- return(True);
-}
-
-/****************************************************************************
-usage on the program
-****************************************************************************/
-static void usage(char *pname)
-{
- fprintf(out_hnd, "Usage: %s service <password> [-d debuglevel] [-l log] ",
- pname);
-
- fprintf(out_hnd, "\nVersion %s\n",VERSION);
- fprintf(out_hnd, "\t-d debuglevel set the debuglevel\n");
- fprintf(out_hnd, "\t-l log basename. Basename for log/debug files\n");
- fprintf(out_hnd, "\t-n netbios name. Use this name as my netbios name\n");
- fprintf(out_hnd, "\t-N don't ask for a password\n");
- fprintf(out_hnd, "\t-m max protocol set the max protocol level\n");
- fprintf(out_hnd, "\t-I dest IP use this IP to connect to\n");
- fprintf(out_hnd, "\t-E write messages to stderr instead of stdout\n");
- fprintf(out_hnd, "\t-U username set the network username\n");
- fprintf(out_hnd, "\t-W workgroup set the workgroup name\n");
- fprintf(out_hnd, "\t-c command string execute semicolon separated commands\n");
- fprintf(out_hnd, "\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
- fprintf(out_hnd, "\n");
-}
-
-enum client_action
-{
- CLIENT_NONE,
- CLIENT_IPC,
- CLIENT_SVC
-};
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
- BOOL interactive = True;
- int opt;
- extern FILE *dbf;
- extern char *optarg;
- extern int optind;
- static pstring servicesf = CONFIGFILE;
- pstring term_code;
- char *p;
- BOOL got_pass = False;
- char *cmd_str="";
- mode_t myumask = 0755;
- enum client_action cli_action = CLIENT_NONE;
-
- struct client_info cli_info;
-
- pstring password; /* local copy only, if one is entered */
-
- printf("Please use rpcclient from the SAMBA_TNG cvs tag.\n");
- printf("Please refer to http://samba.org/cvs.html for details.\n");
- exit(-1);
-
- out_hnd = stdout;
- fstrcpy(debugf, argv[0]);
-
- rpcclient_init();
-
-#ifdef KANJI
- pstrcpy(term_code, KANJI);
-#else /* KANJI */
- *term_code = 0;
-#endif /* KANJI */
-
- DEBUGLEVEL = 2;
-
- cli_info.put_total_size = 0;
- cli_info.put_total_time_ms = 0;
- cli_info.get_total_size = 0;
- cli_info.get_total_time_ms = 0;
-
- cli_info.dir_total = 0;
- cli_info.newer_than = 0;
- cli_info.archive_level = 0;
- cli_info.print_mode = 1;
-
- cli_info.translation = False;
- cli_info.recurse_dir = False;
- cli_info.lowercase = False;
- cli_info.prompt = True;
- cli_info.abort_mget = True;
-
- cli_info.dest_ip.s_addr = 0;
- cli_info.name_type = 0x20;
-
- pstrcpy(cli_info.cur_dir , "\\");
- pstrcpy(cli_info.file_sel, "");
- pstrcpy(cli_info.base_dir, "");
- pstrcpy(smb_cli->domain, "");
- pstrcpy(smb_cli->user_name, "");
- pstrcpy(cli_info.myhostname, "");
- pstrcpy(cli_info.dest_host, "");
-
- pstrcpy(cli_info.svc_type, "A:");
- pstrcpy(cli_info.share, "");
- pstrcpy(cli_info.service, "");
-
- ZERO_STRUCT(cli_info.dom.level3_sid);
- ZERO_STRUCT(cli_info.dom.level5_sid);
- fstrcpy(cli_info.dom.level3_dom, "");
- fstrcpy(cli_info.dom.level5_dom, "");
-
- smb_cli->nt_pipe_fnum = 0xffff;
-
- TimeInit();
- charset_initialise();
-
- myumask = umask(0);
- umask(myumask);
-
- if (!get_myname(global_myname))
- {
- fprintf(stderr, "Failed to get my hostname.\n");
- }
-
- if (getenv("USER"))
- {
- pstrcpy(smb_cli->user_name,getenv("USER"));
-
- /* modification to support userid%passwd syntax in the USER var
- 25.Aug.97, jdblair@uab.edu */
-
- if ((p=strchr(smb_cli->user_name,'%')))
- {
- *p = 0;
- pstrcpy(password,p+1);
- got_pass = True;
- memset(strchr(getenv("USER"),'%')+1,'X',strlen(password));
- }
- strupper(smb_cli->user_name);
- }
-
- password[0] = 0;
-
- /* modification to support PASSWD environmental var
- 25.Aug.97, jdblair@uab.edu */
- if (getenv("PASSWD"))
- {
- pstrcpy(password,getenv("PASSWD"));
- }
-
- if (*smb_cli->user_name == 0 && getenv("LOGNAME"))
- {
- pstrcpy(smb_cli->user_name,getenv("LOGNAME"));
- strupper(smb_cli->user_name);
- }
-
- if (argc < 2)
- {
- usage(argv[0]);
- exit(1);
- }
-
- if (*argv[1] != '-')
- {
-
- pstrcpy(cli_info.service, argv[1]);
- /* Convert any '/' characters in the service name to '\' characters */
- string_replace( cli_info.service, '/','\\');
- argc--;
- argv++;
-
- fprintf(out_hnd, "service: %s\n", cli_info.service);
-
- if (count_chars(cli_info.service,'\\') < 3)
- {
- usage(argv[0]);
- printf("\n%s: Not enough '\\' characters in service\n", cli_info.service);
- exit(1);
- }
-
- /*
- if (count_chars(cli_info.service,'\\') > 3)
- {
- usage(pname);
- printf("\n%s: Too many '\\' characters in service\n", cli_info.service);
- exit(1);
- }
- */
-
- if (argc > 1 && (*argv[1] != '-'))
- {
- got_pass = True;
- pstrcpy(password,argv[1]);
- memset(argv[1],'X',strlen(argv[1]));
- argc--;
- argv++;
- }
-
- cli_action = CLIENT_SVC;
- }
-
- while ((opt = getopt(argc, argv,"s:O:M:S:i:N:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
- {
- switch (opt)
- {
- case 'm':
- {
- /* FIXME ... max_protocol seems to be funny here */
-
- int max_protocol = 0;
- max_protocol = interpret_protocol(optarg,max_protocol);
- fprintf(stderr, "max protocol not currently supported\n");
- break;
- }
-
- case 'O':
- {
- pstrcpy(user_socket_options,optarg);
- break;
- }
-
- case 'S':
- {
- pstrcpy(cli_info.dest_host,optarg);
- strupper(cli_info.dest_host);
- cli_action = CLIENT_IPC;
- break;
- }
-
- case 'i':
- {
- extern pstring global_scope;
- pstrcpy(global_scope, optarg);
- strupper(global_scope);
- break;
- }
-
- case 'U':
- {
- char *lp;
- pstrcpy(smb_cli->user_name,optarg);
- if ((lp=strchr(smb_cli->user_name,'%')))
- {
- *lp = 0;
- pstrcpy(password,lp+1);
- got_pass = True;
- memset(strchr(optarg,'%')+1,'X',strlen(password));
- }
- break;
- }
-
- case 'W':
- {
- pstrcpy(smb_cli->domain,optarg);
- break;
- }
-
- case 'E':
- {
- dbf = stderr;
- break;
- }
-
- case 'I':
- {
- cli_info.dest_ip = *interpret_addr2(optarg);
- if (zero_ip(cli_info.dest_ip))
- {
- exit(1);
- }
- break;
- }
-
- case 'n':
- {
- fstrcpy(global_myname, optarg);
- break;
- }
-
- case 'N':
- {
- got_pass = True;
- break;
- }
-
- case 'd':
- {
- if (*optarg == 'A')
- DEBUGLEVEL = 10000;
- else
- DEBUGLEVEL = atoi(optarg);
- break;
- }
-
- case 'l':
- {
- slprintf(debugf, sizeof(debugf)-1,
- "%s.client", optarg);
- interactive = False;
- break;
- }
-
- case 'c':
- {
- cmd_str = optarg;
- got_pass = True;
- break;
- }
-
- case 'h':
- {
- usage(argv[0]);
- exit(0);
- break;
- }
-
- case 's':
- {
- pstrcpy(servicesf, optarg);
- break;
- }
-
- case 't':
- {
- pstrcpy(term_code, optarg);
- break;
- }
-
- default:
- {
- usage(argv[0]);
- exit(1);
- break;
- }
- }
- }
-
- setup_logging(debugf, interactive);
-
- if (cli_action == CLIENT_NONE)
- {
- usage(argv[0]);
- exit(1);
- }
-
- strupper(global_myname);
- fstrcpy(cli_info.myhostname, global_myname);
-
- DEBUG(3,("%s client started (version %s)\n",timestring(False),VERSION));
-
- if (!lp_load(servicesf,True, False, False))
- {
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
- }
-
- codepage_initialise(lp_client_code_page());
-
- if (*smb_cli->domain == 0) pstrcpy(smb_cli->domain,lp_workgroup());
-
- load_interfaces();
-
- if (cli_action == CLIENT_IPC)
- {
- pstrcpy(cli_info.share, "IPC$");
- pstrcpy(cli_info.svc_type, "IPC");
- }
-
- fstrcpy(cli_info.mach_acct, cli_info.myhostname);
- strupper(cli_info.mach_acct);
- fstrcat(cli_info.mach_acct, "$");
-
- /* set the password cache info */
- if (got_pass)
- {
- if (password[0] == 0)
- {
- pwd_set_nullpwd(&(smb_cli->pwd));
- }
- else
- {
- pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
- }
- }
- else
- {
- pwd_read(&(smb_cli->pwd), "Enter Password:", True);
- }
-
- /* paranoia: destroy the local copy of the password */
- memset((char *)password, '\0', sizeof(password));
-
- /* establish connections. nothing to stop these being re-established. */
- rpcclient_connect(&cli_info);
-
- DEBUG(5,("rpcclient_connect: smb_cli->fd:%d\n", smb_cli->fd));
- if (smb_cli->fd <= 0)
- {
- fprintf(stderr, "warning: connection could not be established to %s<%02x>\n",
- cli_info.dest_host, cli_info.name_type);
- fprintf(stderr, "this version of smbclient may crash if you proceed\n");
- exit(-1);
- }
-
- switch (cli_action)
- {
- case CLIENT_IPC:
- {
- process(&cli_info, cmd_str);
- break;
- }
-
- default:
- {
- fprintf(stderr, "unknown client action requested\n");
- break;
- }
- }
-
- rpcclient_stop();
-
- return(0);
+#include "ntdomain.h"
+#include "rpcclient.h"
+
+ int main(int argc, char *argv[])
+{
+ add_lsa_commands();
+ add_net_commands();
+ add_evt_commands();
+ add_sam_commands();
+ add_svc_commands();
+ add_reg_commands();
+ add_ntl_commands();
+ add_at_commands();
+ add_spl_commands();
+
+ return command_main(argc, argv);
}
diff --git a/source/rpcclient/samedit.c b/source/rpcclient/samedit.c
new file mode 100644
index 00000000000..9f34ae339fb
--- /dev/null
+++ b/source/rpcclient/samedit.c
@@ -0,0 +1,36 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+
+ int main(int argc, char *argv[])
+{
+ add_ntl_commands();
+ add_sam_commands();
+
+ return command_main(argc, argv);
+}
diff --git a/source/rpcclient/samedit_cmds.c b/source/rpcclient/samedit_cmds.c
new file mode 100644
index 00000000000..5103da129fa
--- /dev/null
+++ b/source/rpcclient/samedit_cmds.c
@@ -0,0 +1,226 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "ntdomain.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+static const struct command_set sam_commands[] = {
+ /*
+ * sam
+ */
+
+ {
+ "lookupdomain",
+ cmd_sam_lookup_domain,
+ "Obtain SID for a local domain",
+ {NULL, NULL}
+ },
+ {
+ "samlookuprids",
+ cmd_sam_lookup_rids,
+ "[-d <domain>] <rid> [<rid> ...]\n" "\tLookup RIDs in SAM",
+ {NULL, NULL}
+ },
+ {
+ "samlookupnames",
+ cmd_sam_lookup_names,
+ "[-d <domain>] <name> [<name> ...]\n" "\tLookup Names in SAM",
+ {NULL, NULL}
+ },
+ {
+ "enumusers",
+ cmd_sam_enum_users,
+ "SAM User Database Query (experimental!)",
+ {NULL, NULL}
+ },
+ {
+ "addgroupmem",
+ cmd_sam_add_groupmem,
+ "<group rid> [user] [user] ... SAM Add Domain Group Member",
+ {complete_samenum_grp, complete_samenum_usr}
+ },
+
+ {
+ "addaliasmem",
+ cmd_sam_add_aliasmem,
+ "<alias rid> [member sid1] [member sid2] ... SAM Add Domain Alias Member",
+ {complete_samenum_als, NULL}
+ },
+ {
+ "delgroupmem",
+ cmd_sam_del_groupmem,
+ "<group rid> [user] [user] ... SAM Delete Domain Group Member",
+ {complete_samenum_grp, complete_samenum_usr}
+ },
+ {
+ "delaliasmem",
+ cmd_sam_del_aliasmem,
+ "<alias rid> [member sid1] [member sid2] ... SAM Delete Domain Alias Member",
+ {complete_samenum_als, NULL}
+ },
+ {
+ "creategroup",
+ cmd_sam_create_dom_group,
+ "SAM Create Domain Group",
+ {NULL, NULL}
+ },
+ {
+ "createalias",
+ cmd_sam_create_dom_alias,
+ "SAM Create Domain Alias",
+ {NULL, NULL}
+ },
+ {
+ "createuser",
+ cmd_sam_create_dom_user,
+ "<username> SAM Create Domain User",
+ {NULL, NULL}
+ },
+ {
+ "deluser",
+ cmd_sam_delete_dom_user,
+ "SAM Delete Domain User",
+ {complete_samenum_usr, NULL}
+ },
+ {
+ "delgroup",
+ cmd_sam_delete_dom_group,
+ "SAM Delete Domain Group",
+ {complete_samenum_grp, NULL}
+ },
+ {
+ "delalias",
+ cmd_sam_delete_dom_alias,
+ "SAM Delete Domain Alias",
+ {complete_samenum_als, NULL}
+ },
+ {
+ "ntpass",
+ cmd_sam_ntchange_pwd,
+ "NT SAM Password Change",
+ {NULL, NULL}
+ },
+ {
+ "samquerysec",
+ cmd_sam_query_sec_obj,
+ "<username>",
+ {complete_samenum_usr, NULL}
+ },
+ {
+ "samuserset2",
+ cmd_sam_set_userinfo2,
+ "<username> [-s acb_bits] SAM User Set Info 2 (experimental!)",
+ {complete_samenum_usr, NULL}
+ },
+ {
+ "samuserset",
+ cmd_sam_set_userinfo,
+ "<username> [-p password] SAM User Set Info (experimental!)",
+ {complete_samenum_usr, NULL}
+ },
+ {
+ "samuser",
+ cmd_sam_query_user,
+ "<username> [-g] [-u] [-a] SAM User Query (experimental!)",
+ {complete_samenum_usr, NULL}
+ },
+ {
+ "samgroup",
+ cmd_sam_query_group,
+ "<groupname> SAM Group Query (experimental!)",
+ {complete_samenum_grp, NULL}
+ },
+ {
+ "samalias",
+ cmd_sam_query_alias,
+ "<aliasname> SAM Alias Query",
+ {complete_samenum_als, NULL}
+ },
+ {
+ "samaliasmem",
+ cmd_sam_query_aliasmem,
+ "<aliasname> SAM Alias Members",
+ {complete_samenum_als, NULL}
+ },
+ {
+ "samgroupmem",
+ cmd_sam_query_groupmem,
+ "SAM Group Members",
+ {complete_samenum_grp, NULL}
+ },
+ {
+ "samtest",
+ cmd_sam_test,
+ "SAM User Encrypted RPC test (experimental!)",
+ {NULL, NULL}
+ },
+ {
+ "enumaliases",
+ cmd_sam_enum_aliases,
+ "SAM Aliases Database Query (experimental!)",
+ {NULL, NULL}
+ },
+ {
+ "enumdomains",
+ cmd_sam_enum_domains,
+ "SAM Domains Database Query (experimental!)",
+ {NULL, NULL}
+ },
+ {
+ "enumgroups",
+ cmd_sam_enum_groups,
+ "SAM Group Database Query (experimental!)",
+ {NULL, NULL}
+ },
+ {
+ "dominfo",
+ cmd_sam_query_dominfo,
+ "SAM Query Domain Info",
+ {NULL, NULL}
+ },
+ {
+ "dispinfo",
+ cmd_sam_query_dispinfo,
+ "SAM Query Display Info",
+ {NULL, NULL}
+ },
+
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
+ }
+};
+
+void add_sam_commands(void)
+{
+ add_command_set(sam_commands);
+}
diff --git a/source/rpcclient/spoolss.c b/source/rpcclient/spoolss.c
new file mode 100644
index 00000000000..14f476c939b
--- /dev/null
+++ b/source/rpcclient/spoolss.c
@@ -0,0 +1,35 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+
+int main(int argc, char *argv[])
+{
+ add_spl_commands();
+
+ return command_main(argc, argv);
+}
diff --git a/source/rpcclient/spoolss_cmds.c b/source/rpcclient/spoolss_cmds.c
new file mode 100644
index 00000000000..9dca9053141
--- /dev/null
+++ b/source/rpcclient/spoolss_cmds.c
@@ -0,0 +1,117 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "ntdomain.h"
+#include "rpcclient.h"
+#include "rpc_parse.h"
+
+extern struct client_info cli_info;
+
+static char *complete_printersenum(char *text, int state)
+{
+ static uint32 i = 0;
+ static uint32 num = 0;
+ static PRINTER_INFO_1 **ctr = NULL;
+
+ if (state == 0)
+ {
+ fstring srv_name;
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli_info.dest_host);
+ strupper(srv_name);
+
+ free_print1_array(num, ctr);
+ ctr = NULL;
+ num = 0;
+
+ /* Iterate all users */
+ if (!msrpc_spoolss_enum_printers(srv_name,
+ 1, &num, (void ***)&ctr,
+ NULL))
+ {
+ return NULL;
+ }
+
+ i = 0;
+ }
+
+ for (; i < num; i++)
+ {
+ fstring name;
+ unistr_to_ascii(name, ctr[i]->name.buffer, sizeof(name) - 1);
+
+ if (text == NULL || text[0] == 0 ||
+ strnequal(text, name, strlen(text)))
+ {
+ char *copy = strdup(name);
+ i++;
+ return copy;
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+static const struct command_set spl_commands[] = {
+ /*
+ * printer testing
+ */
+
+ {
+ "spoolenum",
+ cmd_spoolss_enum_printers,
+ "Enumerate Printers",
+ {NULL, NULL}
+ },
+ {
+ "spooljobs",
+ cmd_spoolss_enum_jobs,
+ "<printer name> Enumerate Printer Jobs",
+ {complete_printersenum, NULL}
+ },
+ {
+ "spoolopen",
+ cmd_spoolss_open_printer_ex,
+ "<printer name> Spool Printer Open Test",
+ {complete_printersenum, NULL}
+ },
+
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
+ }
+};
+
+void add_spl_commands(void)
+{
+ add_command_set(spl_commands);
+}
diff --git a/source/rpcclient/svcctrl.c b/source/rpcclient/svcctrl.c
new file mode 100644
index 00000000000..03a61770c7e
--- /dev/null
+++ b/source/rpcclient/svcctrl.c
@@ -0,0 +1,34 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpcclient.h"
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+int main(int argc, char *argv[])
+{
+ add_svc_commands();
+
+ return command_main(argc, argv);
+}
diff --git a/source/rpcclient/svcctrl_cmds.c b/source/rpcclient/svcctrl_cmds.c
new file mode 100644
index 00000000000..7b8e15806de
--- /dev/null
+++ b/source/rpcclient/svcctrl_cmds.c
@@ -0,0 +1,133 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ SMB client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "ntdomain.h"
+#include "rpcclient.h"
+
+extern struct client_info cli_info;
+
+char *complete_svcenum(char *text, int state)
+{
+ static uint32 i = 0;
+ static uint32 num_svcs = 0;
+ static ENUM_SRVC_STATUS *svc = NULL;
+ fstring srv_name;
+
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, cli_info.dest_host);
+ strupper(srv_name);
+
+
+ if (state == 0)
+ {
+ free(svc);
+ svc = NULL;
+ num_svcs = 0;
+
+ /* Iterate all users */
+ if (msrpc_svc_enum(srv_name, &svc, &num_svcs,
+ NULL, NULL) == 0)
+ {
+ return NULL;
+ }
+
+ i = 0;
+ }
+
+ for (; i < num_svcs; i++)
+ {
+ fstring svc_name;
+ unistr_to_ascii(svc_name, svc[i].uni_srvc_name.buffer,
+ sizeof(svc_name) - 1);
+
+ if (text == NULL || text[0] == 0 ||
+ strnequal(text, svc_name, strlen(text)))
+ {
+ char *name = strdup(svc_name);
+ i++;
+ return name;
+ }
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
+static const struct command_set svc_commands[] = {
+ /*
+ * service control
+ */
+
+ {
+ "svcenum",
+ cmd_svc_enum,
+ "[-i] Lists Services Manager",
+ {NULL, NULL}
+ },
+
+ {
+ "svcinfo",
+ cmd_svc_info,
+ "<service> Service Information",
+ {complete_svcenum, NULL}
+ },
+
+ {
+ "svcstart",
+ cmd_svc_start,
+ "<service> [arg 0] [arg 1] ... Start Service",
+ {complete_svcenum, NULL}
+ },
+
+ {
+ "svcset",
+ cmd_svc_set,
+ "<service> Test Set Service",
+ {complete_svcenum, NULL}
+ },
+
+ {
+ "svcstop",
+ cmd_svc_stop,
+ "<service> Stop Service",
+ {complete_svcenum, NULL}
+ },
+
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
+ }
+};
+
+void add_svc_commands(void)
+{
+ add_command_set(svc_commands);
+}
diff --git a/source/samrd/.cvsignore b/source/samrd/.cvsignore
new file mode 100644
index 00000000000..c8b522d6e79
--- /dev/null
+++ b/source/samrd/.cvsignore
@@ -0,0 +1 @@
+*.lo
diff --git a/source/samrd/samrd.c b/source/samrd/samrd.c
new file mode 100644
index 00000000000..0ab8c88928a
--- /dev/null
+++ b/source/samrd/samrd.c
@@ -0,0 +1,132 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+fstring pipe_name;
+
+pstring servicesf = CONFIGFILE;
+extern pstring debugf;
+extern BOOL append_log;
+extern int DEBUGLEVEL;
+
+/*****************************************************************************
+ initialise srv_auth_fns array
+ *****************************************************************************/
+static void auth_init(rpcsrv_struct *l)
+{
+ extern srv_auth_fns ntlmssp_fns;
+ add_srv_auth_fn(l, &ntlmssp_fns);
+}
+
+/*************************************************************************
+ initialise an msrpc service
+ *************************************************************************/
+static void service_init(char* service_name)
+{
+ DEBUG(10,("service_init\n"));
+
+ add_msrpc_command_processor( pipe_name, service_name, api_samr_rpc );
+
+ if (!pwdb_initialise(True))
+ {
+ exit(-1);
+ }
+ if (!pwdbsam_initialise())
+ {
+ exit(-1);
+ }
+}
+
+/****************************************************************************
+ reload the services file
+ **************************************************************************/
+static BOOL reload_msrpc(BOOL test)
+{
+ BOOL ret;
+
+ if (lp_loaded()) {
+ pstring fname;
+ pstrcpy(fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
+ reopen_logs();
+
+ if (test && !lp_file_list_changed())
+ return(True);
+
+ lp_killunused(NULL);
+
+ ret = lp_load(servicesf,False,False,True);
+
+ /* perhaps the config filename is now set */
+ if (!test)
+ reload_msrpc(True);
+
+ reopen_logs();
+
+ load_interfaces();
+
+ return(ret);
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+static int main_init(int argc,char *argv[])
+{
+#ifdef HAVE_SET_AUTH_PARAMETERS
+ set_auth_parameters(argc,argv);
+#endif
+
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ append_log = True;
+
+ TimeInit();
+
+ setup_logging(argv[0],False);
+ fstrcpy(pipe_name, "samr");
+ slprintf(debugf, sizeof(debugf), "%s/log.%s", LOGFILEBASE, pipe_name);
+
+ return 0;
+}
+
+static msrpc_service_fns fn_table =
+{
+ auth_init,
+ service_init,
+ reload_msrpc,
+ main_init,
+ NULL
+};
+
+msrpc_service_fns *get_service_fns(void)
+{
+ return &fn_table;
+}
diff --git a/source/samrd/srv_samr_als_nt5ldap.c b/source/samrd/srv_samr_als_nt5ldap.c
new file mode 100644
index 00000000000..918d61f216b
--- /dev/null
+++ b/source/samrd/srv_samr_als_nt5ldap.c
@@ -0,0 +1,403 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ opens a samr group by rid, returns a policy handle.
+ ********************************************************************/
+static uint32 samr_open_by_nt5ldapsid(LDAPDB *hds,
+ const POLICY_HND *parent_pol,
+ const DOM_SID *dom_sid,
+ POLICY_HND *pol,
+ uint32 access_mask,
+ uint32 rid)
+{
+ DOM_SID sid;
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ parent_pol, pol, access_mask))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ DEBUG(0,("TODO: verify that the rid exists\n"));
+
+ /* associate a SID with the (unique) handle. */
+ sid_copy(&sid, dom_sid);
+ sid_append_rid(&sid, rid);
+
+ /* associate an group SID with the (unique) handle. */
+ if (!set_nt5ldapsid(get_global_hnd_cache(), pol, hds, &sid))
+ {
+ /* close the policy in case we can't associate a group SID */
+ close_policy_hnd(get_global_hnd_cache(), pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_add_aliasmem
+ ********************************************************************/
+uint32 _samr_add_aliasmem(const POLICY_HND *alias_pol, const DOM_SID *sid)
+{
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+ LDAPDB *hds = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_nt5ldapsid(get_global_hnd_cache(), alias_pol, &hds, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(alias_sid_str, &alias_sid);
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (sid_equal(&alias_sid, &global_sam_sid))
+ {
+ DEBUG(10,("add member on Domain SID\n"));
+
+#if 0
+ if (!add_alias_member(alias_rid, sid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+ {
+ DEBUG(10,("add member on BUILTIN SID\n"));
+
+#if 0
+ if (!add_builtin_member(alias_rid, sid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_del_aliasmem
+ ********************************************************************/
+uint32 _samr_del_aliasmem(const POLICY_HND *alias_pol, const DOM_SID *sid)
+{
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+ LDAPDB *hds = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_nt5ldapsid(get_global_hnd_cache(), alias_pol, &hds, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(alias_sid_str, &alias_sid);
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (sid_equal(&alias_sid, &global_sam_sid))
+ {
+ DEBUG(10,("del member on Domain SID\n"));
+
+#if 0
+ if (!del_alias_member(alias_rid, sid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+ {
+ DEBUG(10,("del member on BUILTIN SID\n"));
+
+#if 0
+ if (!del_builtin_member(alias_rid, sid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_aliasinfo
+ ********************************************************************/
+uint32 _samr_query_aliasinfo(const POLICY_HND *alias_pol,
+ uint16 switch_level,
+ ALIAS_INFO_CTR *ctr)
+{
+ /* find the policy handle. open a policy on it. */
+ if ((find_policy_by_hnd(get_global_hnd_cache(), alias_pol) == -1))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ switch (switch_level)
+ {
+ case 3:
+ {
+ ctr->switch_value1 = 3;
+ make_samr_alias_info3(&ctr->alias.info3,
+ "<fake account description>");
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+/*******************************************************************
+ samr_reply_delete_dom_alias
+ ********************************************************************/
+uint32 _samr_delete_dom_alias(POLICY_HND *alias_pol)
+{
+ LDAPDB *hds = NULL;
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+
+ DEBUG(5,("samr_delete_dom_alias: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_nt5ldapsid(get_global_hnd_cache(), alias_pol, &hds, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(alias_sid_str, &alias_sid );
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (!sid_equal(&alias_sid, &global_sam_sid))
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ DEBUG(10,("lookup on Domain SID\n"));
+
+#if 0
+ if (!del_alias_entry(alias_rid))
+#endif
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ return _samr_close(alias_pol);
+}
+
+
+/*******************************************************************
+ samr_reply_query_aliasmem
+ ********************************************************************/
+uint32 _samr_query_aliasmem(const POLICY_HND *alias_pol,
+ uint32 *num_mem, DOM_SID2 **sid)
+{
+ LDAPDB *hds = NULL;
+ LOCAL_GRP_MEMBER *mem_grp = NULL;
+ LOCAL_GRP *grp = NULL;
+ int num_sids = 0;
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+
+ DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
+
+ (*sid) = NULL;
+ (*num_mem) = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_nt5ldapsid(get_global_hnd_cache(), alias_pol, &hds, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(alias_sid_str, &alias_sid );
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+ {
+ DEBUG(10,("lookup on S-1-5-20\n"));
+
+ become_root(True);
+#if 0
+ grp = getbuiltinrid(alias_rid, &mem_grp, &num_sids);
+#endif
+ unbecome_root(True);
+ }
+ else if (sid_equal(&alias_sid, &global_sam_sid))
+ {
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ become_root(True);
+#if 0
+ grp = getaliasrid(alias_rid, &mem_grp, &num_sids);
+#endif
+ unbecome_root(True);
+ }
+ else
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ if (grp == NULL)
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ if (num_sids > 0)
+ {
+ (*sid) = malloc(num_sids * sizeof(DOM_SID2));
+ if (mem_grp != NULL && sid != NULL)
+ {
+ int i;
+ for (i = 0; i < num_sids; i++)
+ {
+ make_dom_sid2(&(*sid)[i], &mem_grp[i].sid);
+ }
+ }
+ }
+
+ (*num_mem) = num_sids;
+
+ if (mem_grp != NULL)
+ {
+ free(mem_grp);
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_create_dom_alias
+ ********************************************************************/
+uint32 _samr_create_dom_alias(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_acct_name,
+ uint32 access_mask,
+ POLICY_HND *alias_pol, uint32 *rid)
+{
+ uint32 status;
+ DOM_SID dom_sid;
+ LOCAL_GRP grp;
+ LDAPDB *hds = NULL;
+
+ bzero(alias_pol, POL_HND_SIZE);
+
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the domain sid */
+ if (!get_nt5ldapsid(get_global_hnd_cache(), domain_pol, &hds))
+ {
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if (!sid_equal(&dom_sid, &global_sam_sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ unistr2_to_ascii(grp.name, uni_acct_name, sizeof(grp.name)-1);
+ fstrcpy(grp.comment, "");
+ *rid = grp.rid = 0xffffffff;
+
+ *rid = grp.rid;
+ status = samr_open_by_nt5ldapsid(hds, domain_pol,
+ &dom_sid, alias_pol, access_mask, grp.rid);
+
+ if (status != NT_STATUS_NOPROBLEMO)
+ {
+ return status;
+ }
+
+#if 0
+ if (!add_alias_entry(&grp))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_open_alias
+ ********************************************************************/
+uint32 _samr_open_alias(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 alias_rid,
+ POLICY_HND *alias_pol)
+{
+ DOM_SID sid;
+ LDAPDB *hds = NULL;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_nt5ldapsid(get_global_hnd_cache(), domain_pol, &hds, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* this should not be hard-coded like this */
+ if (!sid_equal(&sid, &global_sam_sid) &&
+ !sid_equal(&sid, &global_sid_S_1_5_20))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return samr_open_by_nt5ldapsid(hds, domain_pol,
+ &sid, alias_pol, access_mask, alias_rid);
+}
+
diff --git a/source/samrd/srv_samr_als_tdb.c b/source/samrd/srv_samr_als_tdb.c
new file mode 100644
index 00000000000..beec1f5cad7
--- /dev/null
+++ b/source/samrd/srv_samr_als_tdb.c
@@ -0,0 +1,406 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+#include "rpc_parse.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ opens a samr group by rid, returns a policy handle.
+ ********************************************************************/
+static uint32 samr_open_by_tdbsid(TDB_CONTEXT *ptdb,
+ const POLICY_HND *parent_pol,
+ const DOM_SID *dom_sid,
+ POLICY_HND *pol,
+ uint32 access_mask,
+ uint32 rid)
+{
+ DOM_SID sid;
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ parent_pol, pol, access_mask))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ DEBUG(0,("TODO: verify that the rid exists\n"));
+
+ /* associate a SID with the (unique) handle. */
+ sid_copy(&sid, dom_sid);
+ sid_append_rid(&sid, rid);
+
+ /* associate an group SID with the (unique) handle. */
+ if (!set_tdbsid(get_global_hnd_cache(), pol, ptdb, &sid))
+ {
+ /* close the policy in case we can't associate a group SID */
+ close_policy_hnd(get_global_hnd_cache(), pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_add_aliasmem
+ ********************************************************************/
+uint32 _samr_add_aliasmem(const POLICY_HND *alias_pol, const DOM_SID *sid)
+{
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+ TDB_CONTEXT *tdb = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbsid(get_global_hnd_cache(), alias_pol, &tdb, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(alias_sid_str, &alias_sid);
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (sid_equal(&alias_sid, &global_sam_sid))
+ {
+ DEBUG(10,("add member on Domain SID\n"));
+
+#if 0
+ if (!add_alias_member(alias_rid, sid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+ {
+ DEBUG(10,("add member on BUILTIN SID\n"));
+
+#if 0
+ if (!add_builtin_member(alias_rid, sid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_del_aliasmem
+ ********************************************************************/
+uint32 _samr_del_aliasmem(const POLICY_HND *alias_pol, const DOM_SID *sid)
+{
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+ TDB_CONTEXT *tdb = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbsid(get_global_hnd_cache(), alias_pol, &tdb, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(alias_sid_str, &alias_sid);
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (sid_equal(&alias_sid, &global_sam_sid))
+ {
+ DEBUG(10,("del member on Domain SID\n"));
+
+#if 0
+ if (!del_alias_member(alias_rid, sid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+ {
+ DEBUG(10,("del member on BUILTIN SID\n"));
+
+#if 0
+ if (!del_builtin_member(alias_rid, sid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_aliasinfo
+ ********************************************************************/
+uint32 _samr_query_aliasinfo(const POLICY_HND *alias_pol,
+ uint16 switch_level,
+ ALIAS_INFO_CTR *ctr)
+{
+ /* find the policy handle. open a policy on it. */
+ if ((find_policy_by_hnd(get_global_hnd_cache(), alias_pol) == -1))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ switch (switch_level)
+ {
+ case 3:
+ {
+ ctr->switch_value1 = 3;
+ make_samr_alias_info3(&ctr->alias.info3,
+ "<fake account description>");
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+/*******************************************************************
+ samr_reply_delete_dom_alias
+ ********************************************************************/
+uint32 _samr_delete_dom_alias(POLICY_HND *alias_pol)
+{
+ TDB_CONTEXT *tdb = NULL;
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+
+ DEBUG(5,("samr_delete_dom_alias: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbsid(get_global_hnd_cache(), alias_pol, &tdb, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(alias_sid_str, &alias_sid );
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (!sid_equal(&alias_sid, &global_sam_sid))
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ DEBUG(10,("lookup on Domain SID\n"));
+
+#if 0
+ if (!del_alias_entry(alias_rid))
+#endif
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ return _samr_close(alias_pol);
+}
+
+
+/*******************************************************************
+ samr_reply_query_aliasmem
+ ********************************************************************/
+uint32 _samr_query_aliasmem(const POLICY_HND *alias_pol,
+ uint32 *num_mem, DOM_SID2 **sid)
+{
+ TDB_CONTEXT *tdb = NULL;
+ LOCAL_GRP_MEMBER *mem_grp = NULL;
+ LOCAL_GRP *grp = NULL;
+ int num_sids = 0;
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+
+ DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
+
+ (*sid) = NULL;
+ (*num_mem) = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbsid(get_global_hnd_cache(), alias_pol, &tdb, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(alias_sid_str, &alias_sid );
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+ {
+ DEBUG(10,("lookup on S-1-5-20\n"));
+
+ become_root(True);
+#if 0
+ grp = getbuiltinrid(alias_rid, &mem_grp, &num_sids);
+#endif
+ unbecome_root(True);
+ }
+ else if (sid_equal(&alias_sid, &global_sam_sid))
+ {
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ become_root(True);
+#if 0
+ grp = getaliasrid(alias_rid, &mem_grp, &num_sids);
+#endif
+ unbecome_root(True);
+ }
+ else
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ if (grp == NULL)
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ if (num_sids > 0)
+ {
+ (*sid) = malloc(num_sids * sizeof(DOM_SID2));
+ if (mem_grp != NULL && sid != NULL)
+ {
+ int i;
+ for (i = 0; i < num_sids; i++)
+ {
+ make_dom_sid2(&(*sid)[i], &mem_grp[i].sid);
+ }
+ }
+ }
+
+ (*num_mem) = num_sids;
+
+ if (mem_grp != NULL)
+ {
+ free(mem_grp);
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_create_dom_alias
+ ********************************************************************/
+uint32 _samr_create_dom_alias(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_acct_name,
+ uint32 access_mask,
+ POLICY_HND *alias_pol, uint32 *rid)
+{
+ uint32 status;
+ DOM_SID dom_sid;
+ LOCAL_GRP grp;
+ TDB_CONTEXT *dom_tdb = NULL;
+ TDB_CONTEXT *tdb_grp = NULL;
+
+ bzero(alias_pol, POL_HND_SIZE);
+
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the domain sid */
+ if (!get_tdbsid(get_global_hnd_cache(), domain_pol, &dom_tdb, &dom_sid))
+ {
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if (!sid_equal(&dom_sid, &global_sam_sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ unistr2_to_ascii(grp.name, uni_acct_name, sizeof(grp.name)-1);
+ fstrcpy(grp.comment, "");
+ *rid = grp.rid = 0xffffffff;
+
+ *rid = grp.rid;
+ status = samr_open_by_tdbsid(tdb_grp, domain_pol,
+ &dom_sid, alias_pol, access_mask, grp.rid);
+
+ if (status != NT_STATUS_NOPROBLEMO)
+ {
+ return status;
+ }
+
+#if 0
+ if (!add_alias_entry(&grp))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_open_alias
+ ********************************************************************/
+uint32 _samr_open_alias(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 alias_rid,
+ POLICY_HND *alias_pol)
+{
+ DOM_SID sid;
+ TDB_CONTEXT *dom_tdb = NULL;
+ TDB_CONTEXT *tdb_als = NULL;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_tdbsid(get_global_hnd_cache(), domain_pol, &dom_tdb, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* this should not be hard-coded like this */
+ if (!sid_equal(&sid, &global_sam_sid) &&
+ !sid_equal(&sid, &global_sid_S_1_5_20))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return samr_open_by_tdbsid(tdb_als, domain_pol,
+ &sid, alias_pol, access_mask, alias_rid);
+}
+
diff --git a/source/samrd/srv_samr_dom_nt5ldap.c b/source/samrd/srv_samr_dom_nt5ldap.c
new file mode 100644
index 00000000000..b703f27c32a
--- /dev/null
+++ b/source/samrd/srv_samr_dom_nt5ldap.c
@@ -0,0 +1,623 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+#include "rpc_parse.h"
+#include "ldapdb.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+ samr_reply_open_domain
+ ********************************************************************/
+uint32 _samr_open_domain(const POLICY_HND *connect_pol,
+ uint32 ace_perms,
+ const DOM_SID *sid,
+ POLICY_HND *domain_pol)
+{
+ LDAPDB *hds = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_nt5ldapsam(get_global_hnd_cache(), connect_pol, &hds))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ connect_pol, domain_pol, ace_perms))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!ldapdb_open(&hds))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* associate the domain SID with the (unique) handle. */
+ if (!set_nt5ldapdomsid(get_global_hnd_cache(), domain_pol, hds, sid))
+ {
+ ldapdb_close(&hds);
+ close_policy_hnd(get_global_hnd_cache(), domain_pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ DEBUG(5,("_samr_open_domain: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_enum_dom_users
+ ********************************************************************/
+uint32 _samr_enum_dom_users( const POLICY_HND *pol, uint32 *start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_users)
+{
+ LDAPDB *hds = NULL;
+ char *attrs[] = {
+ "objectSid",
+ "sAMAccountName",
+ "dBCSPwd",
+ "unicodePwd",
+ "userAccountFlags"
+ };
+ int num_sam_entries;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_nt5ldapsid(get_global_hnd_cache(), pol, &hds))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_enum_users:\n"));
+
+ (void) ldapdb_set_synchronous(hds, True);
+
+ if (!ldapdb_search(hds, NULL, "(objectClass=User)", attrs, LDAP_NO_LIMIT))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!ldapdb_count_entries(hds, &num_sam_entries))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ (*sam) = (SAM_ENTRY *)Realloc(NULL, num_sam_entries * sizeof((*sam)[0]));
+ if (*sam == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ (*uni_acct_name) = (UNISTR2 *)Realloc(NULL, num_sam_entries * sizeof((*uni_acct_name)[0]));
+ if (*uni_acct_name == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *num_sam_users = 0;
+
+ do
+ {
+ SAM_USER_INFO_21 pass;
+
+ if (nt5ldap_make_sam_user_info_21(hds, &pass))
+ {
+ make_sam_entry(&((*sam)[*num_sam_users]), pass.uni_user_name.uni_str_len, pass.user_rid);
+ copy_unistr2(&((*uni_acct_name)[*num_sam_users]), &(pass.uni_user_name));
+ (*num_sam_users)++;
+ }
+ }
+ while (ldapdb_seq(hds));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_enum_dom_groups
+ ********************************************************************/
+uint32 _samr_enum_dom_groups(const POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_groups)
+{
+ LDAPDB *hds = NULL;
+ char *attrs[] = {
+ "objectSid",
+ "sAMAccountName",
+ "groupType"
+ };
+ int num_sam_entries;
+ fstring filter;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_nt5ldapsid(get_global_hnd_cache(), pol, &hds))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_enum_dom_groups:\n"));
+
+ (void) ldapdb_set_synchronous(hds, True);
+
+ slprintf(filter, sizeof(filter)-1, "(&(objectClass=Group)(groupType=%d))",
+ NTDS_GROUP_TYPE_GLOBAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+
+ if (!ldapdb_search(hds, NULL, filter, attrs, LDAP_NO_LIMIT))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!ldapdb_count_entries(hds, &num_sam_entries))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ (*sam) = (SAM_ENTRY *)Realloc(NULL, num_sam_entries * sizeof((*sam)[0]));
+ if (*sam == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ (*uni_acct_name) = (UNISTR2 *)Realloc(NULL, num_sam_entries * sizeof((*uni_acct_name)[0]));
+ if (*uni_acct_name == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *num_sam_groups = 0;
+
+ do
+ {
+ DOMAIN_GRP group;
+
+ if (nt5ldap_make_domain_grp(hds, &group, NULL, NULL))
+ {
+ int len = strlen(group.name);
+
+ make_sam_entry(&((*sam)[*num_sam_groups]), len, group.rid);
+ make_unistr2(&((*uni_acct_name)[*num_sam_groups]), group.name, len);
+ (*num_sam_groups)++;
+ }
+ }
+ while (ldapdb_seq(hds));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_enum_dom_aliases
+ ********************************************************************/
+uint32 _samr_enum_dom_aliases(const POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_aliases)
+{
+ LDAPDB *hds = NULL;
+ char *attrs[] = {
+ "objectSid",
+ "sAMAccountName",
+ "groupType"
+ };
+ int num_sam_entries;
+ fstring filter;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_nt5ldapsid(get_global_hnd_cache(), pol, &hds))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_enum_aliases:\n"));
+
+ (void) ldapdb_set_synchronous(hds, True);
+
+ slprintf(filter, sizeof(filter)-1, "(&(objectClass=Group)(groupType=%d))",
+ NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP | NTDS_GROUP_TYPE_SECURITY_ENABLED);
+
+ if (!ldapdb_search(hds, NULL, "(objectClass=User)", attrs, LDAP_NO_LIMIT))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!ldapdb_count_entries(hds, &num_sam_entries))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ (*sam) = (SAM_ENTRY *)Realloc(NULL, num_sam_entries * sizeof((*sam)[0]));
+ if (*sam == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ (*uni_acct_name) = (UNISTR2 *)Realloc(NULL, num_sam_entries * sizeof((*uni_acct_name)[0]));
+ if (*uni_acct_name == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *num_sam_aliases = 0;
+
+ do
+ {
+ LOCAL_GRP group;
+
+ if (nt5ldap_make_local_grp(hds, &group, NULL, NULL, 0))
+ {
+ int len = strlen(group.name);
+
+ make_sam_entry(&((*sam)[*num_sam_aliases]), len, group.rid);
+ make_unistr2(&((*uni_acct_name)[*num_sam_aliases]), group.name, len);
+ (*num_sam_aliases)++;
+ }
+ }
+ while (ldapdb_seq(hds));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_dispinfo
+ ********************************************************************/
+uint32 _samr_query_dispinfo( const POLICY_HND *domain_pol, uint16 level,
+ uint32 start_idx,
+ uint32 max_entries,
+ uint32 max_size,
+ uint32 *data_size,
+ uint32 *num_entries,
+ SAM_DISPINFO_CTR *ctr)
+{
+ uint16 acb_mask = ACB_NORMAL;
+ int num_sam_entries = 0;
+ LDAPDB *hds = NULL;
+ DOM_SID sid;
+ /* XXX Unifnished */
+ SAM_USER_INFO_21 *pass = NULL;
+ DOMAIN_GRP *grps = NULL;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_nt5ldapsid(get_global_hnd_cache(), domain_pol, &hds))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_nt5ldapdomsid(get_global_hnd_cache(), domain_pol, &hds, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
+
+ (*num_entries) = 0;
+ (*data_size) = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol) == -1)
+ {
+ DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* Now create reply structure */
+ switch (level)
+ {
+ case 0x1:
+ {
+ ctr->sam.info1 = malloc(sizeof(SAM_DISPINFO_1));
+ make_sam_dispinfo_1(ctr->sam.info1,
+ num_entries, data_size,
+ start_idx, pass);
+ break;
+ }
+ case 0x2:
+ {
+ ctr->sam.info2 = malloc(sizeof(SAM_DISPINFO_2));
+ make_sam_dispinfo_2(ctr->sam.info2,
+ num_entries, data_size,
+ start_idx, pass);
+ break;
+ }
+ case 0x3:
+ {
+ ctr->sam.info3 = malloc(sizeof(SAM_DISPINFO_3));
+ make_sam_dispinfo_3(ctr->sam.info3,
+ num_entries, data_size,
+ start_idx, grps);
+ break;
+ }
+ case 0x4:
+ {
+ ctr->sam.info4 = malloc(sizeof(SAM_DISPINFO_4));
+ make_sam_dispinfo_4(ctr->sam.info4,
+ num_entries, data_size,
+ start_idx, pass);
+ break;
+ }
+ case 0x5:
+ {
+ ctr->sam.info5 = malloc(sizeof(SAM_DISPINFO_5));
+ make_sam_dispinfo_5(ctr->sam.info5,
+ num_entries, data_size,
+ start_idx, grps);
+ break;
+ }
+ default:
+ {
+ ctr->sam.info = NULL;
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
+
+ if ((*num_entries) < num_sam_entries)
+ {
+ return STATUS_MORE_ENTRIES;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_lookup_names
+ ********************************************************************/
+uint32 _samr_lookup_names(const POLICY_HND *dom_pol,
+
+ uint32 num_names,
+ uint32 flags,
+ uint32 ptr,
+ const UNISTR2 *uni_name,
+
+ uint32 *num_rids,
+ uint32 rid[MAX_SAM_ENTRIES],
+ uint32 *num_types,
+ uint32 type[MAX_SAM_ENTRIES])
+{
+ LDAPDB *hds = NULL;
+ DOM_SID dom_sid;
+ char *attrs[] = { "objectSid", "sAMAccountName", "objectClass", "groupType" };
+ int i;
+ BOOL found_one = False;
+
+ DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
+
+ if (!get_nt5ldapdomsid(get_global_hnd_cache(), dom_pol, &hds, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ for (i = 0; i < num_names; i++)
+ {
+ BOOL ok = False;
+ fstring name;
+
+ unistr2_to_ascii(name, &uni_name[i], sizeof(name)-1);
+
+ if (ldapdb_lookup_by_ntname(hds, name))
+ {
+ uint32 gt;
+
+ found_one = True;
+
+ if (!ldapdb_get_rid(hds, "objectSid", &(rid[i])))
+ {
+ rid[i] = 0xffffffff;
+ }
+ else if (ldapdb_get_uint32(hds, "groupType", &gt) &&
+ (gt & NTDS_GROUP_TYPE_SECURITY_ENABLED))
+ {
+ if (gt & NTDS_GROUP_TYPE_BUILTIN_GROUP)
+ type[i] = SID_NAME_WKN_GRP;
+ else if (gt & NTDS_GROUP_TYPE_GLOBAL_GROUP)
+ type[i] = SID_NAME_DOM_GRP;
+ else if (gt & NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP)
+ type[i] = SID_NAME_ALIAS;
+ else
+ type[i] = SID_NAME_UNKNOWN;
+ ok = True;
+ }
+ else
+ {
+ /* presumably a user */
+ type[i] = SID_NAME_USER;
+ ok = True;
+ }
+ }
+
+ if (!ok)
+ {
+ type[i] = SID_NAME_UNKNOWN;
+ }
+ }
+
+ *num_types = *num_rids = num_names;
+
+ return found_one ? NT_STATUS_NOPROBLEMO : NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ samr_reply_lookup_rids
+ ********************************************************************/
+uint32 _samr_lookup_rids(const POLICY_HND *dom_pol,
+ uint32 num_rids, uint32 flags,
+ const uint32 *rids,
+ uint32 *num_names,
+ UNIHDR **hdr_name, UNISTR2** uni_name,
+ uint32 **types)
+{
+ LDAPDB *hds = NULL;
+ DOM_SID dom_sid;
+ int i;
+ BOOL found_one = False;
+
+ DEBUG(5,("samr_lookup_rids: %d\n", __LINE__));
+
+ if (!get_nt5ldapdomsid(get_global_hnd_cache(), dom_pol, &hds, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ *types = (uint32 *)Realloc(NULL, num_rids * sizeof(**types));
+ if (*types == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *uni_name = (UNISTR2 *)Realloc(NULL, num_rids * sizeof(**uni_name));
+ if (*uni_name == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ *hdr_name = (UNIHDR *)Realloc(NULL, num_rids * sizeof(**hdr_name));
+ if (*hdr_name == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i = 0; i < num_rids; i++)
+ {
+ BOOL ok = False;
+
+ if (ldapdb_lookup_by_rid(hds, rids[i]))
+ {
+ found_one = True;
+ if (ldapdb_get_unistr_value(hds, "sAMAccountName", &((*uni_name)[i])))
+ {
+ uint32 gt;
+
+ make_uni_hdr(&((*hdr_name)[i]), ((*uni_name)[i]).uni_str_len);
+ if (ldapdb_get_uint32(hds, "groupType", &gt) &&
+ (gt & NTDS_GROUP_TYPE_SECURITY_ENABLED))
+ {
+ if (gt & NTDS_GROUP_TYPE_BUILTIN_GROUP)
+ (*types)[i] = SID_NAME_WKN_GRP;
+ else if (gt & NTDS_GROUP_TYPE_GLOBAL_GROUP)
+ (*types)[i] = SID_NAME_DOM_GRP;
+ else if (gt & NTDS_GROUP_TYPE_DOMAIN_LOCAL_GROUP)
+ (*types)[i] = SID_NAME_ALIAS;
+ else
+ (*types)[i] = SID_NAME_UNKNOWN;
+ }
+ else
+ {
+ /* presumably a user */
+ (*types)[i] = SID_NAME_USER;
+ }
+ ok = True;
+ }
+ }
+
+ if (!ok)
+ {
+ (*types)[i] = SID_NAME_UNKNOWN;
+ }
+ }
+
+ *num_names = num_rids;
+
+ return found_one ? NT_STATUS_NOPROBLEMO : NT_STATUS_NONE_MAPPED;
+}
+
+/*******************************************************************
+ _samr_query_dom_info
+ ********************************************************************/
+uint32 _samr_query_dom_info(const POLICY_HND *domain_pol,
+ uint16 switch_value,
+ SAM_UNK_CTR *ctr)
+{
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol) == -1)
+ {
+ DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ switch (switch_value)
+ {
+ case 0x07:
+ {
+ make_unk_info7(&(ctr->info.inf7));
+ break;
+ }
+ case 0x06:
+ {
+ make_unk_info6(&(ctr->info.inf6));
+ break;
+ }
+ case 0x03:
+ {
+ make_unk_info3(&(ctr->info.inf3));
+ break;
+ }
+ case 0x02:
+ {
+ extern fstring global_sam_name;
+ extern pstring global_myname;
+ make_unk_info2(&(ctr->info.inf2), global_sam_name, global_myname);
+ break;
+ }
+ case 0x01:
+ {
+ make_unk_info1(&(ctr->info.inf1));
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_set_groupinfo
+ ********************************************************************/
+uint32 _samr_set_groupinfo(const POLICY_HND *pol,
+ uint16 switch_level,
+ const GROUP_INFO_CTR* ctr)
+{
+ return NT_STATUS_ACCESS_DENIED;
+}
+
+/*******************************************************************
+ samr_reply_unknown_2d
+ ********************************************************************/
+uint32 _samr_unknown_2d(const POLICY_HND *domain_pol, const DOM_SID *sid)
+{
+ DEBUG(0,("_samr_unknown_2d: not implemented, returning OK\n"));
+
+ return NT_STATUS_NOPROBLEMO;
+}
diff --git a/source/samrd/srv_samr_dom_tdb.c b/source/samrd/srv_samr_dom_tdb.c
new file mode 100644
index 00000000000..32d1c256a14
--- /dev/null
+++ b/source/samrd/srv_samr_dom_tdb.c
@@ -0,0 +1,907 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+#include "rpc_parse.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+typedef struct sam_data21_info
+{
+ SAM_USER_INFO_21 *usr;
+ uint32 num_sam_entries;
+ uint32 start_idx;
+ uint32 current_idx;;
+
+}
+SAM_DATA_21;
+
+/******************************************************************
+makes a SAMR_R_ENUM_USERS structure.
+********************************************************************/
+static int tdb_user21_traverse(TDB_CONTEXT * tdb,
+ TDB_DATA kbuf, TDB_DATA dbuf, void *state)
+{
+ prs_struct ps;
+ SAM_USER_INFO_21 *usr;
+ SAM_DATA_21 *data = (SAM_DATA_21 *) state;
+ uint32 num_sam_entries = data->num_sam_entries + 1;
+
+ DEBUG(5, ("tdb_user21_traverse: idx: %d %d\n",
+ data->current_idx, num_sam_entries));
+
+ dump_data_pw("usr:\n", dbuf.dptr, dbuf.dsize);
+ dump_data_pw("rid:\n", kbuf.dptr, kbuf.dsize);
+
+ /* skip first requested items */
+ if (data->current_idx < data->start_idx)
+ {
+ data->current_idx++;
+ return 0;
+ }
+
+ data->usr = (SAM_USER_INFO_21 *) Realloc(data->usr,
+ num_sam_entries *
+ sizeof(data->usr[0]));
+
+ if (data->usr == NULL)
+ {
+ DEBUG(0, ("NULL pointers in tdb_user21_traverse\n"));
+ return -1;
+ }
+
+ prs_create(&ps, dbuf.dptr, dbuf.dsize, 4, True);
+
+ usr = &data->usr[data->num_sam_entries];
+ if (sam_io_user_info21("usr", usr, &ps, 0))
+ {
+ data->num_sam_entries++;
+ }
+
+ return 0;
+}
+
+/*******************************************************************
+ samr_reply_open_domain
+ ********************************************************************/
+uint32 _samr_open_domain(const POLICY_HND *connect_pol,
+ uint32 ace_perms,
+ const DOM_SID * sid, POLICY_HND *domain_pol)
+{
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbsam(get_global_hnd_cache(), connect_pol, NULL))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ connect_pol, domain_pol, ace_perms))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* associate the domain SID with the (unique) handle. */
+ if (!set_tdbdomsid(get_global_hnd_cache(), domain_pol,
+ NULL, NULL, NULL, NULL, NULL, sid))
+ {
+ close_policy_hnd(get_global_hnd_cache(), domain_pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ DEBUG(5, ("_samr_open_domain: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+typedef struct sam_data_info
+{
+ SAM_ENTRY *sam;
+ UNISTR2 *uni_name;
+ uint32 num_sam_entries;
+ uint32 start_idx;
+ uint32 current_idx;;
+
+}
+SAM_DATA;
+
+/******************************************************************
+tdb_userlookup_names
+********************************************************************/
+static int tdb_user_traverse(TDB_CONTEXT * tdb, void *state)
+{
+ SAM_USER_INFO_21 usr;
+ SAM_DATA *data = (SAM_DATA *) state;
+ uint32 num_sam_entries = data->num_sam_entries + 1;
+ SAM_ENTRY *sam;
+ UNISTR2 *str;
+
+ DEBUG(5, ("tdb_userlookup_names\n"));
+
+ if (!tdb_lookup_user(tdb, &usr))
+ {
+ return -1;
+ }
+
+ DEBUG(5, ("tdb_user_traverse: idx: %d %d\n",
+ data->current_idx, num_sam_entries));
+
+ /* skip first requested items */
+ if (data->current_idx < data->start_idx)
+ {
+ data->current_idx++;
+ return 0;
+ }
+
+ data->sam = (SAM_ENTRY *) Realloc(data->sam,
+ num_sam_entries *
+ sizeof(data->sam[0]));
+ data->uni_name =
+ (UNISTR2 *) Realloc(data->uni_name,
+ num_sam_entries *
+ sizeof(data->uni_name[0]));
+
+ if (data->sam == NULL || data->uni_name == NULL)
+ {
+ DEBUG(0, ("NULL pointers in tdb_user_traverse\n"));
+ return -1;
+ }
+
+ sam = &data->sam[data->num_sam_entries];
+ str = &data->uni_name[data->num_sam_entries];
+
+ ZERO_STRUCTP(sam);
+ ZERO_STRUCTP(str);
+
+ sam->rid = usr.user_rid;
+ copy_unistr2(str, &usr.uni_user_name);
+ make_uni_hdr(&sam->hdr_name, str->uni_str_len);
+
+ data->num_sam_entries++;
+
+ return 0;
+}
+
+/*******************************************************************
+ samr_reply_enum_dom_users
+ ********************************************************************/
+uint32 _samr_enum_dom_users(const POLICY_HND *pol, uint32 * start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ SAM_ENTRY ** sam,
+ UNISTR2 ** uni_acct_name, uint32 * num_sam_users)
+{
+ TDB_CONTEXT *sam_tdb = NULL;
+ SAM_DATA state;
+ DOM_SID dom_sid;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_tdbdomsid(get_global_hnd_cache(), pol, &sam_tdb,
+ NULL, NULL, NULL, NULL, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5, ("samr_reply_enum_users:\n"));
+
+ ZERO_STRUCT(state);
+
+ state.start_idx = (*start_idx);
+ /* lookups */
+ if (!dom_user_traverse
+ (&dom_sid, tdb_user_traverse, (void *)&state))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ (*sam) = state.sam;
+ (*uni_acct_name) = state.uni_name;
+ (*start_idx) += state.num_sam_entries;
+ (*num_sam_users) = state.num_sam_entries;
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+makes a SAMR_R_ENUM_DOM_GROUPS structure.
+********************************************************************/
+static void make_samr_dom_groups(SAM_ENTRY ** sam, UNISTR2 ** uni_grp_name,
+ uint32 num_sam_entries, DOMAIN_GRP * grps)
+{
+ uint32 i;
+
+ DEBUG(5, ("make_samr_dom_groups\n"));
+
+ (*sam) = NULL;
+ (*uni_grp_name) = NULL;
+
+ if (num_sam_entries == 0)
+ {
+ return;
+ }
+
+ (*sam) = (SAM_ENTRY *) Realloc(NULL, num_sam_entries * sizeof((*sam)[0]));
+
+ (*uni_grp_name) =
+ (UNISTR2 *) Realloc(NULL,
+ num_sam_entries *
+ sizeof((*uni_grp_name)[0]));
+
+ if ((*sam) == NULL || (*uni_grp_name) == NULL)
+ {
+ DEBUG(0, ("NULL pointers in SAMR_R_ENUM_DOM_GROUPS\n"));
+ return;
+ }
+
+ for (i = 0; i < num_sam_entries; i++)
+ {
+ int len = strlen(grps[i].name);
+
+ make_sam_entry(&((*sam)[i]), len, grps[i].rid);
+ make_unistr2(&((*uni_grp_name)[i]), grps[i].name, len);
+ }
+}
+
+/*******************************************************************
+ samr_reply_enum_dom_groups
+ ********************************************************************/
+uint32 _samr_enum_dom_groups(const POLICY_HND *pol,
+ uint32 * start_idx, uint32 size,
+ SAM_ENTRY ** sam,
+ UNISTR2 ** uni_acct_name,
+ uint32 * num_sam_groups)
+{
+ DOMAIN_GRP *grps = NULL;
+ int num_entries = 0;
+ DOM_SID sid;
+ fstring sid_str;
+ BOOL ret = False;
+ TDB_CONTEXT *tdb = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbsid(get_global_hnd_cache(), pol, &tdb, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(sid_str, &sid);
+
+ DEBUG(5, ("samr_reply_enum_dom_groups: sid %s\n", sid_str));
+
+ if (!sid_equal(&sid, &global_sam_sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ become_root(True);
+#if 0
+ ret = enumdomgroups(&grps, &num_entries);
+#endif
+ unbecome_root(True);
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ (*start_idx) += num_entries;
+ (*num_sam_groups) = num_entries;
+
+ make_samr_dom_groups(sam, uni_acct_name, num_entries, grps);
+
+ safe_free(grps);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+makes a SAMR_R_ENUM_DOM_ALIASES structure.
+********************************************************************/
+static void make_samr_dom_aliases(SAM_ENTRY ** sam, UNISTR2 ** uni_grp_name,
+ uint32 num_sam_entries, LOCAL_GRP * alss)
+{
+ uint32 i;
+
+ DEBUG(5, ("make_samr_r_enum_dom_aliases\n"));
+
+ (*sam) = NULL;
+ (*uni_grp_name) = NULL;
+
+ if (num_sam_entries == 0)
+ {
+ return;
+ }
+
+ (*sam) = (SAM_ENTRY *) Realloc(NULL, num_sam_entries * sizeof((*sam)[0]));
+
+ (*uni_grp_name) =
+ (UNISTR2 *) Realloc(NULL,
+ num_sam_entries *
+ sizeof((*uni_grp_name)[0]));
+
+ if ((*sam) == NULL || (*uni_grp_name) == NULL)
+ {
+ DEBUG(0, ("NULL pointers in SAMR_R_ENUM_DOM_ALIASES\n"));
+ return;
+ }
+
+ for (i = 0; i < num_sam_entries; i++)
+ {
+ int len = strlen(alss[i].name);
+
+ make_sam_entry(&((*sam)[i]), len, alss[i].rid);
+ make_unistr2(&((*uni_grp_name)[i]), alss[i].name, len);
+ }
+}
+
+/*******************************************************************
+ samr_reply_enum_dom_aliases
+ ********************************************************************/
+uint32 _samr_enum_dom_aliases(const POLICY_HND *pol,
+ uint32 * start_idx, uint32 size,
+ SAM_ENTRY ** sam,
+ UNISTR2 ** uni_acct_name,
+ uint32 * num_sam_aliases)
+{
+ LOCAL_GRP *alss = NULL;
+ int num_entries = 0;
+ DOM_SID sid;
+ fstring sid_str;
+ TDB_CONTEXT *als_tdb = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbdomsid(get_global_hnd_cache(), pol,
+ NULL, NULL, NULL, NULL, &als_tdb, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(sid_str, &sid);
+
+ DEBUG(5, ("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
+
+ /* well-known aliases */
+ if (sid_equal(&sid, &global_sid_S_1_5_20))
+ {
+ BOOL ret = True;
+ /* builtin aliases */
+
+ become_root(True);
+#if 0
+ ret = enumdombuiltins(&alss, &num_entries);
+#endif
+ unbecome_root(True);
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else if (sid_equal(&sid, &global_sam_sid))
+ {
+ BOOL ret = True;
+ /* local aliases */
+
+ become_root(True);
+#if 0
+ ret = enumdomaliases(&alss, &num_entries);
+#endif
+ unbecome_root(True);
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+
+ (*start_idx) += num_entries;
+ (*num_sam_aliases) = num_entries;
+
+ make_samr_dom_aliases(sam, uni_acct_name, num_entries, alss);
+
+ safe_free(alss);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_dispinfo
+ ********************************************************************/
+uint32 _samr_query_dispinfo(const POLICY_HND *domain_pol, uint16 level,
+ uint32 start_idx,
+ uint32 max_entries,
+ uint32 max_size,
+ uint32 * data_size,
+ uint32 * num_entries, SAM_DISPINFO_CTR * ctr)
+{
+ SAM_USER_INFO_21 *pass = NULL;
+ DOMAIN_GRP *grps = NULL;
+ DOMAIN_GRP *sam_grps = NULL;
+ uint16 acb_mask = ACB_NORMAL;
+ int num_sam_entries = 0;
+ int total_entries;
+
+ TDB_CONTEXT *sam_tdb = NULL;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_tdbdomsid(get_global_hnd_cache(), domain_pol, &sam_tdb,
+ NULL, NULL, NULL, NULL, NULL))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
+
+ (*num_entries) = 0;
+ (*data_size) = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol) == -1)
+ {
+ DEBUG(5, ("samr_reply_query_dispinfo: invalid handle\n"));
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* Get what we need from the password database */
+ switch (level)
+ {
+ case 0x2:
+ {
+ acb_mask = ACB_WSTRUST;
+ /* Fall through */
+ }
+ case 0x1:
+ case 0x4:
+ {
+ SAM_DATA_21 state;
+ ZERO_STRUCT(state);
+
+ state.start_idx = start_idx;
+ total_entries = tdb_traverse(sam_tdb,
+ tdb_user21_traverse,
+ (void *)&state);
+
+ pass = state.usr;
+ start_idx += state.num_sam_entries;
+ num_sam_entries = state.num_sam_entries;
+
+ break;
+ }
+ case 0x3:
+ case 0x5:
+ {
+ BOOL ret = True;
+
+ become_root(True);
+#if 0
+ ret = enumdomgroups(&sam_grps, &num_sam_entries);
+#endif
+ unbecome_root(True);
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (start_idx < num_sam_entries)
+ {
+ grps = sam_grps + start_idx;
+ num_sam_entries -= start_idx;
+ }
+ else
+ {
+ num_sam_entries = 0;
+ }
+ break;
+ }
+ }
+
+ (*num_entries) = num_sam_entries;
+
+ if ((*num_entries) > max_entries)
+ {
+ (*num_entries) = max_entries;
+ }
+
+ (*data_size) = max_size;
+
+ /* Now create reply structure */
+ switch (level)
+ {
+ case 0x1:
+ {
+ ctr->sam.info1 = malloc(sizeof(SAM_DISPINFO_1));
+ make_sam_dispinfo_1(ctr->sam.info1,
+ num_entries, data_size,
+ start_idx, pass);
+ break;
+ }
+ case 0x2:
+ {
+ ctr->sam.info2 = malloc(sizeof(SAM_DISPINFO_2));
+ make_sam_dispinfo_2(ctr->sam.info2,
+ num_entries, data_size,
+ start_idx, pass);
+ break;
+ }
+ case 0x3:
+ {
+ ctr->sam.info3 = malloc(sizeof(SAM_DISPINFO_3));
+ make_sam_dispinfo_3(ctr->sam.info3,
+ num_entries, data_size,
+ start_idx, grps);
+ break;
+ }
+ case 0x4:
+ {
+ ctr->sam.info4 = malloc(sizeof(SAM_DISPINFO_4));
+ make_sam_dispinfo_4(ctr->sam.info4,
+ num_entries, data_size,
+ start_idx, pass);
+ break;
+ }
+ case 0x5:
+ {
+ ctr->sam.info5 = malloc(sizeof(SAM_DISPINFO_5));
+ make_sam_dispinfo_5(ctr->sam.info5,
+ num_entries, data_size,
+ start_idx, grps);
+ break;
+ }
+ default:
+ {
+ ctr->sam.info = NULL;
+ safe_free(sam_grps);
+ safe_free(grps);
+ safe_free(pass);
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__));
+
+ safe_free(sam_grps);
+ safe_free(grps);
+ safe_free(pass);
+
+ if ((*num_entries) < num_sam_entries)
+ {
+ return STATUS_MORE_ENTRIES;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+typedef struct tdb_name_info
+{
+ const UNISTR2 *uni_name;
+ uint32 *rids;
+ uint32 *types;
+ uint32 num_names;
+ BOOL found_one;
+
+} TDB_NAME_INFO;
+
+/******************************************************************
+tdb_userlookup_names
+********************************************************************/
+static int tdb_userlookup_names(TDB_CONTEXT * tdb, void *state)
+{
+ SAM_USER_INFO_21 usr;
+ TDB_NAME_INFO *data = (TDB_NAME_INFO *) state;
+ int i;
+
+ DEBUG(5, ("tdb_userlookup_names\n"));
+
+ if (!tdb_lookup_user(tdb, &usr))
+ {
+ return -1;
+ }
+
+ for (i = 0; i < data->num_names; i++)
+ {
+ const UNISTR2 *str = &data->uni_name[i];
+ if (unistr2equal(str, &usr.uni_user_name))
+ {
+ DEBUG(10, ("found user rid[i]: %d\n", i));
+
+ data->types[i] = SID_NAME_USER;
+ data->rids[i] = usr.user_rid;
+ data->found_one = True;
+
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+BOOL dom_user_traverse(const DOM_SID * dom_sid,
+ int (*fn) (TDB_CONTEXT *, void *), void *state)
+{
+ DIR *dirp;
+ char *dpname;
+ pstring tmp;
+ pstring dirname;
+
+ sid_to_string(tmp, dom_sid);
+ slprintf(dirname, sizeof(dirname) - 1, "%s/usr", tmp);
+
+ dirp = opendir(passdb_path(dirname));
+
+ if (dirp == NULL)
+ {
+ DEBUG(2, ("Error opening directory [%s]\n", dirname));
+ return False;
+ }
+
+ while ((dpname = readdirname(dirp)) != NULL)
+ {
+ TDB_CONTEXT *usr_tdb;
+ uint32 rid = strtoul(dpname, (char **)NULL, 16);
+
+ DEBUG(10, ("dom_user_traverse: %s\n", dpname));
+
+ if (rid == 0)
+ {
+ continue;
+ }
+ usr_tdb = open_usr_db(dom_sid, rid, O_RDONLY);
+ if (usr_tdb != NULL && fn(usr_tdb, state) != 0)
+ {
+ tdb_close(usr_tdb);
+ break;
+ }
+ tdb_close(usr_tdb);
+ }
+ closedir(dirp);
+
+ return True;
+}
+
+/*******************************************************************
+ samr_reply_lookup_names
+ ********************************************************************/
+uint32 _samr_lookup_names(const POLICY_HND *dom_pol,
+ uint32 num_names,
+ uint32 flags,
+ uint32 ptr,
+ const UNISTR2 * uni_name,
+ uint32 * num_rids,
+ uint32 rid[MAX_SAM_ENTRIES],
+ uint32 * num_types, uint32 type[MAX_SAM_ENTRIES])
+{
+ DOM_SID dom_sid;
+ TDB_NAME_INFO state;
+
+ DEBUG(5, ("samr_lookup_names: %d\n", __LINE__));
+
+ if (!get_tdbdomsid(get_global_hnd_cache(), dom_pol,
+ NULL, NULL, NULL, NULL, NULL, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* prepare memory, ready for state-based traversion */
+
+ if (num_names > MAX_SAM_ENTRIES)
+ {
+ num_names = MAX_SAM_ENTRIES;
+ }
+
+ state.found_one = False;
+ state.num_names = num_names;
+ state.rids = rid;
+ state.types = type;
+ state.uni_name = uni_name;
+
+ if (state.rids == NULL ||
+ state.types == NULL || state.uni_name == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* lookups */
+ if (!dom_user_traverse
+ (&dom_sid, tdb_userlookup_names, (void *)&state))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!state.found_one)
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ (*num_types) = num_names;
+ (*num_rids) = num_names;
+ return NT_STATUS_NOPROBLEMO;
+}
+
+typedef struct tdb_rid_info
+{
+ const uint32 *rids;
+ uint32 *types;
+ UNIHDR *hdr_name;
+ UNISTR2 *uni_name;
+ uint32 num_rids;
+ BOOL found_one;
+}
+TDB_RID_INFO;
+
+/******************************************************************
+tdb_userlookup_names
+********************************************************************/
+static int tdb_userlookup_rids(TDB_CONTEXT * tdb, void *state)
+{
+ SAM_USER_INFO_21 usr;
+ TDB_RID_INFO *data = (TDB_RID_INFO *) state;
+ int i;
+
+ DEBUG(5, ("tdb_userlookup_rids\n"));
+
+ if (!tdb_lookup_user(tdb, &usr))
+ {
+ return -1;
+ }
+
+ for (i = 0; i < data->num_rids; i++)
+ {
+ if (usr.user_rid == data->rids[i])
+ {
+ UNISTR2 *str = &data->uni_name[i];
+ UNIHDR *hdr = &data->hdr_name[i];
+ DEBUG(10, ("found user rid[i]: %d\n", i));
+ data->types[i] = SID_NAME_USER;
+ copy_unistr2(str, &usr.uni_user_name);
+ make_uni_hdr(hdr, str->uni_str_len);
+ data->found_one = True;
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+/*******************************************************************
+ samr_reply_lookup_rids
+ ********************************************************************/
+uint32 _samr_lookup_rids(const POLICY_HND *dom_pol,
+ uint32 num_rids, uint32 flags,
+ const uint32 * rids,
+ uint32 * num_names,
+ UNIHDR ** hdr_name, UNISTR2 ** uni_name,
+ uint32 ** types)
+{
+ TDB_CONTEXT *usr_tdb = NULL;
+ DOM_SID dom_sid;
+ TDB_RID_INFO state;
+ DEBUG(5, ("samr_lookup_rids: %d\n", __LINE__));
+ if (!get_tdbdomsid(get_global_hnd_cache(), dom_pol,
+ &usr_tdb, NULL, NULL, NULL, NULL, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* prepare memory, ready for state-based traversion */
+
+ state.found_one = False;
+ state.num_rids = num_rids;
+ state.rids = rids;
+ state.types = malloc(num_rids * sizeof(*state.types));
+ state.hdr_name =
+ (UNIHDR *) malloc(num_rids * sizeof(*state.hdr_name));
+ state.uni_name =
+ (UNISTR2 *) malloc(num_rids * sizeof(*state.uni_name));
+ if (state.types == NULL || state.hdr_name == NULL
+ || state.uni_name == NULL)
+ {
+ safe_free(state.types);
+ safe_free(state.hdr_name);
+ safe_free(state.uni_name);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* lookups */
+ if (!dom_user_traverse
+ (&dom_sid, tdb_userlookup_rids, (void *)&state))
+ {
+ safe_free(state.types);
+ safe_free(state.hdr_name);
+ safe_free(state.uni_name);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ if (!state.found_one)
+ {
+ safe_free(state.types);
+ safe_free(state.hdr_name);
+ safe_free(state.uni_name);
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ (*num_names) = num_rids;
+ (*types) = state.types;
+ (*hdr_name) = state.hdr_name;
+ (*uni_name) = state.uni_name;
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_query_dom_info
+ ********************************************************************/
+uint32 _samr_query_dom_info(const POLICY_HND *domain_pol,
+ uint16 switch_value, SAM_UNK_CTR * ctr)
+{
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol) == -1)
+ {
+ DEBUG(5, ("samr_reply_query_dom_info: invalid handle\n"));
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ switch (switch_value)
+ {
+ case 0x07:
+ {
+ make_unk_info7(&(ctr->info.inf7));
+ break;
+ }
+ case 0x06:
+ {
+ make_unk_info6(&(ctr->info.inf6));
+ break;
+ }
+ case 0x03:
+ {
+ make_unk_info3(&(ctr->info.inf3));
+ break;
+ }
+ case 0x02:
+ {
+ extern fstring global_sam_name;
+ extern pstring global_myname;
+ make_unk_info2(&(ctr->info.inf2), global_sam_name,
+ global_myname);
+ break;
+ }
+ case 0x01:
+ {
+ make_unk_info1(&(ctr->info.inf1));
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+/*******************************************************************
+ samr_reply_unknown_2d
+ ********************************************************************/
+uint32 _samr_unknown_2d(const POLICY_HND *domain_pol, const DOM_SID * sid)
+{
+ DEBUG(0, ("_samr_unknown_2d: not implemented, returning OK\n"));
+ return NT_STATUS_NOPROBLEMO;
+}
diff --git a/source/samrd/srv_samr_grp_tdb.c b/source/samrd/srv_samr_grp_tdb.c
new file mode 100644
index 00000000000..c2690c192aa
--- /dev/null
+++ b/source/samrd/srv_samr_grp_tdb.c
@@ -0,0 +1,552 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+static BOOL tdb_lookup_group_mem(TDB_CONTEXT * tdb,
+ uint32 rid,
+ uint32 * num_rids,
+ uint32 ** rids,
+ uint32 * num_types, uint32 ** types)
+{
+ prs_struct key;
+ prs_struct data;
+
+ prs_init(&key, 0, 4, False);
+ if (!_prs_uint32("sid", &key, 0, &rid))
+ {
+ return False;
+ }
+
+ prs_tdb_fetch(tdb, &key, &data);
+
+ if (!samr_io_rids("rids", num_rids, rids, &data, 0) ||
+ !samr_io_rids("types", num_types, types, &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+static BOOL tdb_lookup_group(TDB_CONTEXT * tdb, uint32 rid, GROUP_INFO1 * grp)
+{
+ prs_struct key;
+ prs_struct data;
+
+ prs_init(&key, 0, 4, False);
+ if (!_prs_uint32("rid", &key, 0, &rid))
+ {
+ return False;
+ }
+
+ prs_tdb_fetch(tdb, &key, &data);
+
+ if (!samr_io_group_info1("grp", grp, &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+static BOOL tdb_store_group_mem(TDB_CONTEXT * tdb,
+ uint32 rid,
+ uint32 * num_rids,
+ uint32 ** rids,
+ uint32 * num_types, uint32 ** types)
+{
+ prs_struct key;
+ prs_struct data;
+
+ if (DEBUGLVL(10))
+ {
+ DEBUG(10, ("storing group members %x\n", rid));
+ }
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!_prs_uint32("sid", &key, 0, &rid) ||
+ !samr_io_rids("rids", num_rids, rids, &data, 0) ||
+ !samr_io_rids("types", num_types, types, &data, 0) ||
+ prs_tdb_store(tdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+static BOOL tdb_store_group(TDB_CONTEXT * tdb, uint32 rid, GROUP_INFO1 * grp)
+{
+ prs_struct key;
+ prs_struct data;
+
+ DEBUG(10, ("storing group %x\n", rid));
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!_prs_uint32("rid", &key, 0, &rid) ||
+ !samr_io_group_info1("grp", grp, &data, 0) ||
+ prs_tdb_store(tdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+static BOOL tdb_set_groupinfo_4(TDB_CONTEXT * tdb,
+ uint32 rid, const UNISTR2 * uni_acct_desc)
+{
+ GROUP_INFO1 grp;
+
+ if (tdb_writelock(tdb) != 0)
+ {
+ return False;
+ }
+
+ if (!tdb_lookup_group(tdb, rid, &grp))
+ {
+ tdb_writeunlock(tdb);
+ return False;
+ }
+
+ copy_unistr2(&grp.uni_acct_desc, uni_acct_desc);
+ make_uni_hdr(&grp.hdr_acct_desc, uni_acct_desc->uni_str_len);
+
+ if (!tdb_store_group(tdb, rid, &grp))
+ {
+ tdb_writeunlock(tdb);
+ return False;
+ }
+
+ tdb_writeunlock(tdb);
+ return True;
+}
+
+
+/*******************************************************************
+ samr_reply_add_groupmem
+ ********************************************************************/
+uint32 _samr_add_groupmem(const POLICY_HND *pol, uint32 rid, uint32 unknown)
+{
+ uint32 group_rid;
+ TDB_CONTEXT *tdb = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbrid
+ (get_global_hnd_cache(), pol, NULL, &tdb, NULL, &group_rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+#if 0
+ if (!add_group_member(group_rid, rid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_del_groupmem
+ ********************************************************************/
+uint32 _samr_del_groupmem(const POLICY_HND *pol, uint32 rid)
+{
+ uint32 group_rid;
+ TDB_CONTEXT *tdb = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbrid
+ (get_global_hnd_cache(), pol, NULL, &tdb, NULL, &group_rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+#if 0
+ if (!del_group_member(group_rid, rid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_delete_dom_group
+ ********************************************************************/
+uint32 _samr_delete_dom_group(POLICY_HND *group_pol)
+{
+ uint32 group_rid;
+ TDB_CONTEXT *tdb = NULL;
+
+ DEBUG(5, ("samr_delete_dom_group: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbrid
+ (get_global_hnd_cache(), group_pol, NULL, &tdb, NULL, &group_rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+#if 0
+ if (!del_group_entry(group_rid))
+#endif
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return _samr_close(group_pol);
+}
+
+
+/*******************************************************************
+ samr_reply_query_groupmem
+ ********************************************************************/
+uint32 _samr_query_groupmem(const POLICY_HND *group_pol,
+ uint32 * num_mem, uint32 ** rid, uint32 ** attr)
+{
+ TDB_CONTEXT *g_tdb = NULL;
+ int num_rids = 0;
+ uint32 group_rid;
+
+ DEBUG(5, ("samr_query_groupmem: %d\n", __LINE__));
+
+ (*rid) = NULL;
+ (*attr) = NULL;
+ (*num_mem) = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbrid
+ (get_global_hnd_cache(), group_pol, NULL, &g_tdb, NULL,
+ &group_rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(10, ("lookup on Domain SID\n"));
+
+#if 0
+ grp = getgrouprid(group_rid, &mem_grp, &num_rids);
+#endif
+
+ {
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+#if 0
+ if (num_rids > 0)
+ {
+ (*rid) = malloc(num_rids * sizeof(uint32));
+ (*attr) = malloc(num_rids * sizeof(uint32));
+ if (mem_grp != NULL && (*rid) != NULL && (*attr) != NULL)
+ {
+ int i;
+ for (i = 0; i < num_rids; i++)
+ {
+ (*rid)[i] = mem_grp[i].rid;
+ (*attr)[i] = mem_grp[i].attr;
+ }
+ }
+ }
+
+#endif
+
+ (*num_mem) = num_rids;
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+/*******************************************************************
+ samr_set_groupinfo
+ ********************************************************************/
+uint32 _samr_set_groupinfo(const POLICY_HND *pol,
+ uint16 switch_level, const GROUP_INFO_CTR * ctr)
+{
+ uint32 group_rid;
+ TDB_CONTEXT *tdb = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbrid
+ (get_global_hnd_cache(), pol, NULL, &tdb, NULL, &group_rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ switch (switch_level)
+ {
+ case 1:
+ {
+ GROUP_INFO1 grp;
+ memcpy(&grp, &ctr->group.info1, sizeof(grp));
+ if (!tdb_store_group(tdb, group_rid, &grp))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+ case 4:
+ {
+ if (!tdb_set_groupinfo_4(tdb, group_rid,
+ &ctr->group.info4.
+ uni_acct_desc))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_groupinfo
+ ********************************************************************/
+uint32 _samr_query_groupinfo(const POLICY_HND *pol,
+ uint16 switch_level, GROUP_INFO_CTR * ctr)
+{
+ uint32 group_rid;
+ TDB_CONTEXT *tdb = NULL;
+ GROUP_INFO1 grp;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbrid
+ (get_global_hnd_cache(), pol, NULL, &tdb, NULL, &group_rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!tdb_lookup_group(tdb, group_rid, &grp))
+ {
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ switch (switch_level)
+ {
+ case 1:
+ {
+ ctr->switch_value1 = 1;
+ memcpy(&ctr->group.info1, &grp, sizeof(grp));
+ break;
+ }
+ case 4:
+ {
+ ctr->switch_value1 = 4;
+ copy_unistr2(&ctr->group.info1.uni_acct_desc,
+ &grp.uni_acct_desc);
+ make_uni_hdr(&ctr->group.info1.hdr_acct_desc,
+ grp.uni_acct_desc.uni_str_len);
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_create_dom_group
+ ********************************************************************/
+uint32 _samr_create_dom_group(const POLICY_HND *domain_pol,
+ const UNISTR2 * uni_acct_name,
+ uint32 access_mask,
+ POLICY_HND *group_pol, uint32 * group_rid)
+{
+ DOM_SID dom_sid;
+ DOM_SID grp_sid;
+ DOM_SID sid;
+ TDB_CONTEXT *tdb_grp = NULL;
+
+ GROUP_INFO1 grp;
+ uint32 status1;
+ uint32 rid;
+ uint32 type;
+ uint32 num_rids;
+ uint32 num_types;
+
+ struct group *uxgrp = NULL;
+
+ (*group_rid) = 0x0;
+
+ /* find the machine account: tell the caller if it exists.
+ lkclXXXX i have *no* idea if this is a problem or not
+ or even if you are supposed to construct a different
+ reply if the account already exists...
+ */
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_tdbdomsid(get_global_hnd_cache(), domain_pol,
+ NULL, &tdb_grp, NULL, NULL, NULL, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ status1 = _samr_lookup_names(domain_pol, 1, 0x3e8, 1, uni_acct_name,
+ &num_rids, &rid, &num_types, &type);
+
+ if (status1 == NT_STATUS_NOPROBLEMO)
+ {
+ switch (type)
+ {
+ case SID_NAME_USER:
+ return NT_STATUS_USER_EXISTS;
+ case SID_NAME_ALIAS:
+ return NT_STATUS_ALIAS_EXISTS;
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ return NT_STATUS_GROUP_EXISTS;
+ case SID_NAME_DOMAIN:
+ return NT_STATUS_DOMAIN_EXISTS;
+ default:
+ {
+ DEBUG(3,
+ ("create group: unknown, ignoring\n"));
+ break;
+ }
+ }
+ }
+
+ {
+ fstring grp_name;
+ unistr2_to_ascii(grp_name, uni_acct_name,
+ sizeof(grp_name) - 1);
+ uxgrp = getgrnam(grp_name);
+ DEBUG(10, ("create group: %s\n", grp_name));
+ if (uxgrp == NULL)
+ {
+ DEBUG(0, ("create group: no unix group named %s\n",
+ grp_name));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+
+ /* create a User SID for the unix group */
+ if (!surs_unixid_to_sam_sid(uxgrp->gr_gid, SID_NAME_DOM_GRP,
+ &grp_sid, True))
+ {
+ DEBUG(0, ("create group: unix gid %d to RID failed\n",
+ uxgrp->gr_gid));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ sid_copy(&sid, &grp_sid);
+
+ if (!sid_split_rid(&sid, group_rid) || !sid_equal(&dom_sid, &sid))
+ {
+ fstring tmp;
+ DEBUG(0, ("create group: invalid Group SID %s\n",
+ sid_to_string(tmp, &grp_sid)));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ ZERO_STRUCT(grp);
+ copy_unistr2(&grp.uni_acct_name, uni_acct_name);
+ make_uni_hdr(&grp.hdr_acct_name, uni_acct_name->uni_str_len);
+ grp.unknown_1 = 0x3;
+ grp.num_members = 0x0;
+
+ if (!tdb_store_group(tdb_grp, (*group_rid), &grp))
+ {
+ /* account doesn't exist: say so */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_ACCESS_DENIED;
+#if 0
+ if (!tdb_store_group_mem(tdb_usg, (*group_rid), 0, NULL, 0, NULL))
+ {
+ /* account doesn't exist: say so */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return samr_open_by_tdbrid(domain_pol, NULL, tdb_grp, NULL,
+ group_pol, access_mask, *group_rid);
+#endif
+}
+
+/*******************************************************************
+ _samr_open_group
+ ********************************************************************/
+uint32 _samr_open_group(const POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 group_rid, POLICY_HND *group_pol)
+{
+ DOM_SID dom_sid;
+ TDB_CONTEXT *tdb_grp = NULL;
+ GROUP_INFO1 grp;
+
+ if (!get_tdbdomsid(get_global_hnd_cache(), domain_pol,
+ NULL, NULL, NULL, &tdb_grp, NULL, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!tdb_lookup_group(tdb_grp, group_rid, &grp))
+ {
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ return NT_STATUS_NO_SUCH_GROUP;
+#if 0
+ return samr_open_by_tdbrid(domain_pol,
+ NULL, tdb_grp, NULL,
+ group_pol, access_mask, group_rid);
+#endif
+}
diff --git a/source/samrd/srv_samr_nt5ldap.c b/source/samrd/srv_samr_nt5ldap.c
new file mode 100644
index 00000000000..9d8a628d16a
--- /dev/null
+++ b/source/samrd/srv_samr_nt5ldap.c
@@ -0,0 +1,332 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Luke Howard 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+#include "ldapdb.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+typedef struct nt5ldap_dom_info
+{
+ LDAPDB *hds;
+ DOM_SID sid;
+} NT5LDAP_DOM_INFO;
+
+typedef struct nt5ldap_sid_info
+{
+ LDAPDB *hds;
+ DOM_SID sid;
+} NT5LDAP_SID_INFO;
+
+typedef struct nt5ldap_rid_info
+{
+ LDAPDB *hds;
+ uint32 rid;
+} NT5LDAP_RID_INFO;
+
+typedef struct nt5ldap_sam_info
+{
+ LDAPDB *hds;
+} NT5LDAP_SAM_INFO;
+
+static void free_nt5ldapdom_info(void *dev)
+{
+ NT5LDAP_DOM_INFO *ldbi = (NT5LDAP_DOM_INFO *)dev;
+ DEBUG(10,("free policy connection\n"));
+ if (ldbi->hds != NULL)
+ {
+ ldapdb_close(&ldbi->hds);
+ }
+ free(ldbi);
+}
+
+static void free_nt5ldapsam_info(void *dev)
+{
+ NT5LDAP_SAM_INFO *ldbi = (NT5LDAP_SAM_INFO *)dev;
+ DEBUG(10,("free policy connection\n"));
+ if (ldbi->hds != NULL)
+ {
+ ldapdb_close(&ldbi->hds);
+ }
+ free(ldbi);
+}
+
+static void free_nt5ldapsid_info(void *dev)
+{
+ NT5LDAP_SID_INFO *ldbi = (NT5LDAP_SID_INFO *)dev;
+ DEBUG(10,("free policy connection\n"));
+ if (ldbi->hds != NULL)
+ {
+ ldapdb_close(&ldbi->hds);
+ }
+ free(ldbi);
+}
+
+/****************************************************************************
+ set samr rid
+****************************************************************************/
+BOOL set_nt5ldaprid(struct policy_cache *cache, POLICY_HND *hnd,
+ LDAPDB *hds, uint32 rid)
+{
+ NT5LDAP_RID_INFO *dev = malloc(sizeof(*dev));
+
+ if (dev != NULL)
+ {
+ dev->rid = rid;
+ dev->hds = hds;
+ if (set_policy_state(cache, hnd, NULL, (void*)dev))
+ {
+ DEBUG(3,("Service setting policy rid=%x\n", rid));
+ return True;
+ }
+ free(dev);
+ return False;
+ }
+ DEBUG(3,("Error setting policy rid\n"));
+ return False;
+}
+
+/****************************************************************************
+ get samr rid
+****************************************************************************/
+BOOL get_nt5ldaprid(struct policy_cache *cache, const POLICY_HND *hnd,
+ LDAPDB **hds, uint32 *rid)
+{
+ NT5LDAP_RID_INFO *dev = (NT5LDAP_RID_INFO*)get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ if (rid != NULL)
+ {
+ (*rid) = dev->rid;
+ DEBUG(3,("Service getting policy rid=%x\n", (*rid)));
+ }
+ if (hds != NULL)
+ {
+ (*hds) = dev->hds;
+ }
+ return True;
+ }
+
+ DEBUG(3,("Error getting policy rid\n"));
+ return False;
+}
+
+/****************************************************************************
+ set samr sid
+****************************************************************************/
+BOOL set_nt5ldapsam(struct policy_cache *cache, POLICY_HND *hnd,
+ LDAPDB *hds)
+{
+ pstring sidstr;
+ NT5LDAP_SAM_INFO *dev = malloc(sizeof(*dev));
+
+ if (dev != NULL)
+ {
+ dev->hds = hds;
+
+ if (set_policy_state(cache, hnd, free_nt5ldapsam_info, (void*)dev))
+ {
+ DEBUG(3,("Service setting policy sid=%s\n", sidstr));
+ return True;
+ }
+ free(dev);
+ return False;
+ }
+ DEBUG(3,("Error setting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ get samr sid
+****************************************************************************/
+BOOL get_nt5ldapsam(struct policy_cache *cache, const POLICY_HND *hnd,
+ LDAPDB **hds)
+{
+ NT5LDAP_SAM_INFO *dev = (NT5LDAP_SAM_INFO*)get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ if (hds != NULL)
+ {
+ (*hds) = dev->hds;
+ return (dev->hds != NULL);
+ }
+ return True;
+ }
+
+ DEBUG(3,("Error getting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ set samr sid
+****************************************************************************/
+BOOL set_nt5ldapdomsid(struct policy_cache *cache, POLICY_HND *hnd,
+ LDAPDB *hds,
+ const DOM_SID *sid)
+{
+ pstring sidstr;
+ NT5LDAP_DOM_INFO *dev;
+
+ dev = malloc(sizeof(*dev));
+
+ DEBUG(3,("Setting policy sid=%s\n", sid_to_string(sidstr, sid)));
+
+ if (dev != NULL)
+ {
+ sid_copy(&dev->sid, sid);
+ dev->hds = hds;
+
+ if (set_policy_state(cache, hnd, free_nt5ldapdom_info, (void*)dev))
+ {
+ DEBUG(3,("Service setting policy sid=%s\n", sidstr));
+ return True;
+ }
+ free(dev);
+ return False;
+ }
+ DEBUG(3,("Error setting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ get samr sid
+****************************************************************************/
+BOOL get_nt5ldapdomsid(struct policy_cache *cache, const POLICY_HND *hnd,
+ LDAPDB **hds,
+ DOM_SID *sid)
+{
+ NT5LDAP_DOM_INFO *dev = (NT5LDAP_DOM_INFO*)get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ pstring tmp;
+ if (sid != NULL)
+ {
+ sid_copy(sid, &dev->sid);
+ DEBUG(3,("Getting policy sid=%s\n",
+ sid_to_string(tmp, sid)));
+ }
+ if (hds != NULL)
+ {
+ (*hds) = dev->hds;
+ }
+ return True;
+ }
+
+ DEBUG(3,("Error getting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ set samr sid
+****************************************************************************/
+BOOL set_nt5ldapsid(struct policy_cache *cache, POLICY_HND *hnd,
+ LDAPDB *hds, const DOM_SID *sid)
+{
+ pstring sidstr;
+ NT5LDAP_SID_INFO *dev;
+
+ dev = malloc(sizeof(*dev));
+
+ DEBUG(3,("Setting policy sid=%s\n", sid_to_string(sidstr, sid)));
+
+ if (dev != NULL)
+ {
+ sid_copy(&dev->sid, sid);
+ dev->hds = hds;
+
+ if (set_policy_state(cache, hnd, free_nt5ldapsid_info, (void*)dev))
+ {
+ DEBUG(3,("Service setting policy sid=%s\n", sidstr));
+ return True;
+ }
+ free(dev);
+ return False;
+ }
+ DEBUG(3,("Error setting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ get samr sid
+****************************************************************************/
+BOOL get_nt5ldapsid(struct policy_cache *cache, const POLICY_HND *hnd,
+ LDAPDB **hds, DOM_SID *sid)
+{
+ NT5LDAP_SID_INFO *dev = (NT5LDAP_SID_INFO*)get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ pstring tmp;
+ if (sid != NULL)
+ {
+ sid_copy(sid, &dev->sid);
+ DEBUG(3,("Getting policy sid=%s\n",
+ sid_to_string(tmp, sid)));
+ }
+ if (hds != NULL)
+ {
+ (*hds) = dev->hds;
+ return (dev->hds != NULL);
+ }
+ return True;
+ }
+
+ DEBUG(3,("Error getting policy sid\n"));
+ return False;
+}
+
+/*******************************************************************
+ opens a samr entiry by rid, returns a policy handle.
+ ********************************************************************/
+uint32 samr_open_by_nt5ldaprid( LDAPDB *hds,
+ const POLICY_HND *parent_pol,
+ POLICY_HND *pol, uint32 access_mask, uint32 rid)
+{
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ parent_pol, pol, access_mask))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* associate a RID with the (unique) handle. */
+ if (!set_nt5ldaprid(get_global_hnd_cache(), pol, hds, rid))
+ {
+ /* close the policy in case we can't associate a group SID */
+ close_policy_hnd(get_global_hnd_cache(), pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return 0x0;
+}
+
+BOOL pwdbsam_initialise(void)
+{
+ DEBUG(0,("TODO: initialise SAM NT5 LDAP Database\n"));
+ return True;
+}
diff --git a/source/samrd/srv_samr_passdb.c b/source/samrd/srv_samr_passdb.c
new file mode 100644
index 00000000000..d866fb696f0
--- /dev/null
+++ b/source/samrd/srv_samr_passdb.c
@@ -0,0 +1,2530 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+
+/****************************************************************************
+ set samr sid
+****************************************************************************/
+static BOOL set_policy_samr_sid(struct policy_cache *cache, POLICY_HND *hnd,
+ const DOM_SID *sid)
+{
+ pstring sidstr;
+ DOM_SID *dev = sid_dup(sid);
+
+ DEBUG(3,("Setting policy sid=%s\n", sid_to_string(sidstr, sid)));
+
+ if (dev != NULL)
+ {
+ if (set_policy_state(cache, hnd, NULL, (void*)dev))
+ {
+ DEBUG(3,("Service setting policy sid=%s\n", sidstr));
+ return True;
+ }
+ free(dev);
+ return True;
+ }
+ DEBUG(3,("Error setting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ get samr sid
+****************************************************************************/
+static BOOL get_policy_samr_sid(struct policy_cache *cache,
+ const POLICY_HND *hnd, DOM_SID *sid)
+{
+ DOM_SID *dev = (DOM_SID*)get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ pstring tmp;
+ sid_copy(sid, dev);
+ DEBUG(3,("Getting policy sid=%s\n", sid_to_string(tmp, sid)));
+ return True;
+ }
+
+ DEBUG(3,("Error getting policy sid\n"));
+ return False;
+}
+
+/*******************************************************************
+ This next function should be replaced with something that
+ dynamically returns the correct user info..... JRA.
+ ********************************************************************/
+
+static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
+ int start_idx,
+ int *total_entries, int *num_entries,
+ int max_num_entries,
+ uint16 acb_mask)
+{
+ void *vp = NULL;
+ struct sam_passwd *pwd = NULL;
+
+ (*num_entries) = 0;
+ (*total_entries) = 0;
+
+ if (pw_buf == NULL) return False;
+
+ vp = startsmbpwent(False);
+ if (!vp)
+ {
+ DEBUG(0, ("get_sampwd_entries: Unable to open SMB password database.\n"));
+ return False;
+ }
+
+ while (((pwd = getsam21pwent(vp)) != NULL) && (*num_entries) < max_num_entries)
+ {
+ int user_name_len;
+
+ if (start_idx > 0)
+ {
+ /* skip the requested number of entries.
+ not very efficient, but hey...
+ */
+ if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
+ {
+ start_idx--;
+ }
+ continue;
+ }
+
+ user_name_len = strlen(pwd->nt_name);
+ make_unistr2(&(pw_buf[(*num_entries)].uni_user_name), pwd->nt_name, user_name_len);
+ make_uni_hdr(&(pw_buf[(*num_entries)].hdr_user_name), user_name_len);
+ pw_buf[(*num_entries)].user_rid = pwd->user_rid;
+ bzero( pw_buf[(*num_entries)].nt_pwd , 16);
+
+ /* Now check if the NT compatible password is available. */
+ if (pwd->smb_nt_passwd != NULL)
+ {
+ memcpy( pw_buf[(*num_entries)].nt_pwd , pwd->smb_nt_passwd, 16);
+ }
+
+ pw_buf[(*num_entries)].acb_info = (uint16)pwd->acct_ctrl;
+
+ DEBUG(5, ("entry idx: %d user %s, rid 0x%x, acb %x",
+ (*num_entries), pwd->nt_name,
+ pwd->user_rid, pwd->acct_ctrl));
+
+ if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
+ {
+ DEBUG(5,(" acb_mask %x accepts\n", acb_mask));
+ (*num_entries)++;
+ }
+ else
+ {
+ DEBUG(5,(" acb_mask %x rejects\n", acb_mask));
+ }
+
+ (*total_entries)++;
+ }
+
+ endsmbpwent(vp);
+
+ return (*total_entries) > 0;
+}
+
+/*******************************************************************
+ opens a samr group by rid, returns a policy handle.
+ ********************************************************************/
+static uint32 samr_open_by_sid( const POLICY_HND *parent_pol,
+ const DOM_SID *dom_sid,
+ POLICY_HND *pol,
+ uint32 access_mask,
+ uint32 rid)
+{
+ DOM_SID sid;
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ parent_pol, pol, access_mask))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ DEBUG(0,("TODO: verify that the rid exists\n"));
+
+ /* associate a SID with the (unique) handle. */
+ sid_copy(&sid, dom_sid);
+ sid_append_rid(&sid, rid);
+
+ /* associate an group SID with the (unique) handle. */
+ if (!set_policy_samr_sid(get_global_hnd_cache(), pol, &sid))
+ {
+ /* close the policy in case we can't associate a group SID */
+ close_policy_hnd(get_global_hnd_cache(), pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_close
+ ********************************************************************/
+uint32 _samr_close(POLICY_HND *hnd)
+{
+ /* set up the SAMR unknown_1 response */
+
+ /* close the policy handle */
+ if (close_policy_hnd(get_global_hnd_cache(), hnd))
+ {
+ bzero(hnd, sizeof(*hnd));
+ return NT_STATUS_NOPROBLEMO;
+ }
+ return NT_STATUS_OBJECT_NAME_INVALID;
+}
+
+/*******************************************************************
+ samr_reply_unknown_2d
+ ********************************************************************/
+uint32 _samr_unknown_2d(const POLICY_HND *domain_pol, const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+
+ /* associate the domain SID with the (unique) handle. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol, &dom_sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ DEBUG(0,("_samr_unknown_2d: not implemented, returning OK\n"));
+ DEBUG(5,("_samr_unknown_2d: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_open_domain
+ ********************************************************************/
+uint32 _samr_open_domain(const POLICY_HND *connect_pol,
+ uint32 ace_perms,
+ const DOM_SID *sid,
+ POLICY_HND *domain_pol)
+{
+ /* find the connection policy handle. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), connect_pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ connect_pol, domain_pol, ace_perms))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* associate the domain SID with the (unique) handle. */
+ if (!set_policy_samr_sid(get_global_hnd_cache(), domain_pol, sid))
+ {
+ close_policy_hnd(get_global_hnd_cache(), domain_pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ DEBUG(5,("_samr_open_domain: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_get_usrdom_pwinfo
+ ********************************************************************/
+uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
+ uint32 *unknown_0,
+ uint32 *unknown_1)
+{
+ uint32 rid;
+ DOM_SID sid;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), user_pol, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_split_rid(&sid, &rid);
+
+ *unknown_0 = 0x00150000;
+ *unknown_1 = 0x00000000;
+
+ DEBUG(5,("samr_get_usrdom_pwinfo: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_sec_obj
+ ********************************************************************/
+uint32 _samr_query_sec_obj(const POLICY_HND *user_pol, SEC_DESC_BUF *buf)
+{
+ DOM_SID usr_sid;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), user_pol, &usr_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ SMB_ASSERT_ARRAY(usr_sid.sub_auths, usr_sid.num_auths+1);
+
+#if 0
+ /* maybe need another 1 or 2 (S-1-5-0x20-0x220 and S-1-5-20-0x224) */
+ /* these two are DOMAIN_ADMIN and DOMAIN_ACCT_OP group RIDs */
+ make_dom_sid3(&sid_stuff->sid[0], 0x035b, 0x0002, &global_sid_S_1_1);
+ make_dom_sid3(&sid_stuff->sid[1], 0x0044, 0x0002, &usr_sid);
+
+ make_sam_sid_stuff(sid_stuff,
+ 0x0001, 0x8004,
+ 0x00000014, 0x0002, 0x0070,
+ 2);
+
+#endif
+ DEBUG(5,("samr_query_sec_obj: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+makes a SAM_ENTRY / UNISTR2* structure.
+********************************************************************/
+static void make_samr_dom_users(SAM_ENTRY **sam, UNISTR2 **uni_acct_name,
+ uint32 num_sam_entries,
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES])
+{
+ uint32 i;
+
+ *sam = NULL;
+ *uni_acct_name = NULL;
+
+ if (num_sam_entries == 0)
+ {
+ return;
+ }
+
+ (*sam) = (SAM_ENTRY*)Realloc(NULL, num_sam_entries * sizeof((*sam)[0]));
+ (*uni_acct_name) = (UNISTR2*)Realloc(NULL, num_sam_entries * sizeof((*uni_acct_name)[0]));
+
+ if ((*sam) == NULL || (*uni_acct_name) == NULL)
+ {
+ DEBUG(0,("NULL pointers in SAMR_R_QUERY_DISPINFO\n"));
+ return;
+ }
+
+ for (i = 0; i < num_sam_entries; i++)
+ {
+ make_sam_entry(&((*sam)[i]),
+ pass[i].uni_user_name.uni_str_len,
+ pass[i].user_rid);
+
+ copy_unistr2(&((*uni_acct_name)[i]), &(pass[i].uni_user_name));
+ }
+}
+
+/*******************************************************************
+ samr_reply_enum_dom_users
+ ********************************************************************/
+uint32 _samr_enum_dom_users( const POLICY_HND *pol, uint32 *start_idx,
+ uint16 acb_mask, uint16 unk_1, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_users)
+{
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+ int total_entries;
+ BOOL ret;
+
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
+
+ become_root(True);
+ ret = get_sampwd_entries(pass, (*start_idx), &total_entries,
+ num_sam_users,
+ MAX_SAM_ENTRIES, acb_mask);
+ unbecome_root(True);
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ (*start_idx) += (*num_sam_users);
+ make_samr_dom_users(sam, uni_acct_name, (*num_sam_users), pass);
+
+ DEBUG(5,("samr_enum_dom_users: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_add_groupmem
+ ********************************************************************/
+uint32 _samr_add_groupmem(const POLICY_HND *pol, uint32 rid, uint32 unknown)
+{
+ DOM_SID group_sid;
+ uint32 group_rid;
+ fstring group_sid_str;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &group_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(group_sid_str, &group_sid);
+ sid_split_rid(&group_sid, &group_rid);
+
+ DEBUG(10,("sid is %s\n", group_sid_str));
+
+ if (!sid_equal(&group_sid, &global_sam_sid))
+ {
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ if (!add_group_member(group_rid, rid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_del_groupmem
+ ********************************************************************/
+uint32 _samr_del_groupmem(const POLICY_HND *pol, uint32 rid)
+{
+ DOM_SID group_sid;
+ uint32 group_rid;
+ fstring group_sid_str;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &group_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(group_sid_str, &group_sid);
+ sid_split_rid(&group_sid, &group_rid);
+
+ DEBUG(10,("sid is %s\n", group_sid_str));
+
+ if (!sid_equal(&group_sid, &global_sam_sid))
+ {
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ if (!del_group_member(group_rid, rid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_add_aliasmem
+ ********************************************************************/
+uint32 _samr_add_aliasmem(const POLICY_HND *alias_pol, const DOM_SID *sid)
+{
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), alias_pol, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(alias_sid_str, &alias_sid);
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (sid_equal(&alias_sid, &global_sam_sid))
+ {
+ DEBUG(10,("add member on Domain SID\n"));
+
+ if (!add_alias_member(alias_rid, sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+ {
+ DEBUG(10,("add member on BUILTIN SID\n"));
+
+ if (!add_builtin_member(alias_rid, sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_del_aliasmem
+ ********************************************************************/
+uint32 _samr_del_aliasmem(const POLICY_HND *alias_pol, const DOM_SID *sid)
+{
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), alias_pol, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(alias_sid_str, &alias_sid);
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (sid_equal(&alias_sid, &global_sam_sid))
+ {
+ DEBUG(10,("del member on Domain SID\n"));
+
+ if (!del_alias_member(alias_rid, sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+ {
+ DEBUG(10,("del member on BUILTIN SID\n"));
+
+ if (!del_builtin_member(alias_rid, sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/******************************************************************
+makes a SAMR_R_ENUM_DOMAINS structure.
+********************************************************************/
+static void make_enum_domains(SAM_ENTRY **sam, UNISTR2 **uni_dom_name,
+ uint32 num_sam_entries, char **doms)
+{
+ uint32 i;
+
+ DEBUG(5,("make_enum_domains\n"));
+
+ (*sam) = NULL;
+ (*uni_dom_name) = NULL;
+
+ if (num_sam_entries == 0)
+ {
+ return;
+ }
+
+ (*sam) = (SAM_ENTRY*)Realloc(NULL, num_sam_entries * sizeof((*sam)[0]));
+ (*uni_dom_name) = (UNISTR2*)Realloc(NULL, num_sam_entries * sizeof((*uni_dom_name)[0]));
+
+ if ((*sam) == NULL || (*uni_dom_name) == NULL)
+ {
+ DEBUG(0,("NULL pointers in make_enum_domains\n"));
+ return;
+ }
+
+ for (i = 0; i < num_sam_entries; i++)
+ {
+ int len = doms[i] != NULL ? strlen(doms[i]) : 0;
+
+ make_sam_entry(&((*sam)[i]), len, 0);
+ make_unistr2(&((*uni_dom_name)[i]), doms[i], len);
+ }
+}
+
+/*******************************************************************
+ samr_reply_enum_domains
+ ********************************************************************/
+uint32 _samr_enum_domains(const POLICY_HND *pol, uint32 *start_idx,
+ uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_users)
+{
+ char **doms = NULL;
+ uint32 num_entries = 0;
+
+ /* find the connection policy handle. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_enum_domains:\n"));
+
+ if (!enumdomains(&doms, &num_entries))
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ make_enum_domains(sam, uni_acct_name, num_entries, doms);
+
+ (*start_idx) += num_entries;
+ (*num_sam_users) = num_entries;
+
+ free_char_array(num_entries, doms);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+makes a SAMR_R_ENUM_DOM_GROUPS structure.
+********************************************************************/
+static void make_samr_dom_groups(SAM_ENTRY **sam, UNISTR2 **uni_grp_name,
+ uint32 num_sam_entries, DOMAIN_GRP *grps)
+{
+ uint32 i;
+
+ DEBUG(5,("make_samr_dom_groups\n"));
+
+ (*sam) = NULL;
+ (*uni_grp_name) = NULL;
+
+ if (num_sam_entries == 0)
+ {
+ return;
+ }
+
+ (*sam) = (SAM_ENTRY*)Realloc(NULL, num_sam_entries * sizeof((*sam)[0]));
+ (*uni_grp_name) = (UNISTR2*)Realloc(NULL, num_sam_entries * sizeof((*uni_grp_name)[0]));
+
+ if ((*sam) == NULL || (*uni_grp_name) == NULL)
+ {
+ DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_GROUPS\n"));
+ return;
+ }
+
+ for (i = 0; i < num_sam_entries; i++)
+ {
+ int len = strlen(grps[i].name);
+
+ make_sam_entry(&((*sam)[i]), len, grps[i].rid);
+ make_unistr2(&((*uni_grp_name)[i]), grps[i].name, len);
+ }
+}
+
+/*******************************************************************
+ samr_reply_enum_dom_groups
+ ********************************************************************/
+uint32 _samr_enum_dom_groups(const POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_groups)
+{
+ DOMAIN_GRP *grps = NULL;
+ int num_entries = 0;
+ DOM_SID sid;
+ fstring sid_str;
+ BOOL ret;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(sid_str, &sid);
+
+ DEBUG(5,("samr_reply_enum_dom_groups: sid %s\n", sid_str));
+
+ if (!sid_equal(&sid, &global_sam_sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ become_root(True);
+ ret = enumdomgroups(&grps, &num_entries);
+ unbecome_root(True);
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ (*start_idx) += num_entries;
+ (*num_sam_groups) = num_entries;
+
+ make_samr_dom_groups(sam, uni_acct_name, num_entries, grps);
+
+ safe_free(grps);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+makes a SAMR_R_ENUM_DOM_ALIASES structure.
+********************************************************************/
+static void make_samr_dom_aliases(SAM_ENTRY **sam, UNISTR2 **uni_grp_name,
+ uint32 num_sam_entries, LOCAL_GRP *alss)
+{
+ uint32 i;
+
+ DEBUG(5,("make_samr_r_enum_dom_aliases\n"));
+
+ (*sam) = NULL;
+ (*uni_grp_name) = NULL;
+
+ if (num_sam_entries == 0)
+ {
+ return;
+ }
+
+ (*sam) = (SAM_ENTRY*)Realloc(NULL, num_sam_entries * sizeof((*sam)[0]));
+ (*uni_grp_name) = (UNISTR2*)Realloc(NULL, num_sam_entries * sizeof((*uni_grp_name)[0]));
+
+ if ((*sam) == NULL || (*uni_grp_name) == NULL)
+ {
+ DEBUG(0,("NULL pointers in SAMR_R_ENUM_DOM_ALIASES\n"));
+ return;
+ }
+
+ for (i = 0; i < num_sam_entries; i++)
+ {
+ int len = strlen(alss[i].name);
+
+ make_sam_entry(&((*sam)[i]), len, alss[i].rid);
+ make_unistr2(&((*uni_grp_name)[i]), alss[i].name, len);
+ }
+}
+
+/*******************************************************************
+ samr_reply_enum_dom_aliases
+ ********************************************************************/
+uint32 _samr_enum_dom_aliases(const POLICY_HND *pol,
+ uint32 *start_idx, uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_aliases)
+{
+ LOCAL_GRP *alss = NULL;
+ int num_entries = 0;
+ DOM_SID sid;
+ fstring sid_str;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(sid_str, &sid);
+
+ DEBUG(5,("samr_reply_enum_dom_aliases: sid %s\n", sid_str));
+
+ /* well-known aliases */
+ if (sid_equal(&sid, &global_sid_S_1_5_20))
+ {
+ BOOL ret;
+ /* builtin aliases */
+
+ become_root(True);
+ ret = enumdombuiltins(&alss, &num_entries);
+ unbecome_root(True);
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else if (sid_equal(&sid, &global_sam_sid))
+ {
+ BOOL ret;
+ /* local aliases */
+
+ become_root(True);
+ ret = enumdomaliases(&alss, &num_entries);
+ unbecome_root(True);
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+
+ (*start_idx) += num_entries;
+ (*num_sam_aliases) = num_entries;
+
+ make_samr_dom_aliases(sam, uni_acct_name, num_entries, alss);
+
+ safe_free(alss);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_dispinfo
+ ********************************************************************/
+uint32 _samr_query_dispinfo( const POLICY_HND *domain_pol, uint16 level,
+ uint32 start_idx,
+ uint32 max_entries,
+ uint32 max_size,
+ uint32 *data_size,
+ uint32 *num_entries,
+ SAM_DISPINFO_CTR *ctr)
+{
+ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES];
+ DOMAIN_GRP *grps = NULL;
+ DOMAIN_GRP *sam_grps = NULL;
+ uint16 acb_mask = ACB_NORMAL;
+ int num_sam_entries = 0;
+ int total_entries = 0;
+
+ DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
+
+ (*num_entries) = 0;
+ (*data_size) = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol) == -1)
+ {
+ DEBUG(5,("samr_reply_query_dispinfo: invalid handle\n"));
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* Get what we need from the password database */
+ switch (level)
+ {
+ case 0x2:
+ {
+ acb_mask = ACB_WSTRUST;
+ /* Fall through */
+ }
+ case 0x1:
+ case 0x4:
+ {
+ BOOL ret;
+
+ become_root(True);
+ ret = get_sampwd_entries(pass, start_idx,
+ &total_entries, &num_sam_entries,
+ MAX_SAM_ENTRIES, acb_mask);
+ unbecome_root(True);
+ if (!ret)
+ {
+ DEBUG(5,("get_sampwd_entries: failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+ case 0x3:
+ case 0x5:
+ {
+ BOOL ret;
+
+ become_root(True);
+ ret = enumdomgroups(&sam_grps, &num_sam_entries);
+ unbecome_root(True);
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (start_idx < num_sam_entries) {
+ grps = sam_grps + start_idx;
+ num_sam_entries -= start_idx;
+ } else {
+ num_sam_entries = 0;
+ }
+ break;
+ }
+ }
+
+
+ (*num_entries) = num_sam_entries;
+
+ if ((*num_entries) > max_entries)
+ {
+ (*num_entries) = max_entries;
+ }
+
+ if ((*num_entries) > MAX_SAM_ENTRIES)
+ {
+ (*num_entries) = MAX_SAM_ENTRIES;
+ DEBUG(5,("limiting number of entries to %d\n",
+ (*num_entries)));
+ }
+
+ (*data_size) = max_size;
+
+ /* Now create reply structure */
+ switch (level)
+ {
+ case 0x1:
+ {
+ ctr->sam.info1 = malloc(sizeof(SAM_DISPINFO_1));
+ make_sam_dispinfo_1(ctr->sam.info1,
+ num_entries, data_size,
+ start_idx, pass);
+ break;
+ }
+ case 0x2:
+ {
+ ctr->sam.info2 = malloc(sizeof(SAM_DISPINFO_2));
+ make_sam_dispinfo_2(ctr->sam.info2,
+ num_entries, data_size,
+ start_idx, pass);
+ break;
+ }
+ case 0x3:
+ {
+ ctr->sam.info3 = malloc(sizeof(SAM_DISPINFO_3));
+ make_sam_dispinfo_3(ctr->sam.info3,
+ num_entries, data_size,
+ start_idx, grps);
+ break;
+ }
+ case 0x4:
+ {
+ ctr->sam.info4 = malloc(sizeof(SAM_DISPINFO_4));
+ make_sam_dispinfo_4(ctr->sam.info4,
+ num_entries, data_size,
+ start_idx, pass);
+ break;
+ }
+ case 0x5:
+ {
+ ctr->sam.info5 = malloc(sizeof(SAM_DISPINFO_5));
+ make_sam_dispinfo_5(ctr->sam.info5,
+ num_entries, data_size,
+ start_idx, grps);
+ break;
+ }
+ default:
+ {
+ ctr->sam.info = NULL;
+ safe_free(sam_grps);
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ DEBUG(5,("samr_reply_query_dispinfo: %d\n", __LINE__));
+
+ safe_free(sam_grps);
+
+ if ((*num_entries) < num_sam_entries)
+ {
+ return STATUS_MORE_ENTRIES;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+/*******************************************************************
+ samr_reply_delete_dom_user
+ ********************************************************************/
+uint32 _samr_delete_dom_user(POLICY_HND *user_pol)
+{
+ DEBUG(0,("samr_delete_dom_user: not implemented\n"));
+ return NT_STATUS_ACCESS_DENIED;
+}
+
+
+/*******************************************************************
+ samr_reply_delete_dom_group
+ ********************************************************************/
+uint32 _samr_delete_dom_group(POLICY_HND *group_pol)
+{
+ DOM_SID group_sid;
+ uint32 group_rid;
+ fstring group_sid_str;
+
+ DEBUG(5,("samr_delete_dom_group: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), group_pol, &group_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(group_sid_str, &group_sid);
+ sid_split_rid(&group_sid, &group_rid);
+
+ DEBUG(10,("sid is %s\n", group_sid_str));
+
+ if (!sid_equal(&group_sid, &global_sam_sid))
+ {
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ if (!del_group_entry(group_rid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return _samr_close(group_pol);
+}
+
+
+/*******************************************************************
+ samr_reply_query_groupmem
+ ********************************************************************/
+uint32 _samr_query_groupmem(const POLICY_HND *group_pol,
+ uint32 *num_mem,
+ uint32 **rid,
+ uint32 **attr)
+{
+ DOMAIN_GRP_MEMBER *mem_grp = NULL;
+ DOMAIN_GRP *grp = NULL;
+ int num_rids = 0;
+ DOM_SID group_sid;
+ uint32 group_rid;
+ fstring group_sid_str;
+
+ DEBUG(5,("samr_query_groupmem: %d\n", __LINE__));
+
+ (*rid) = NULL;
+ (*attr) = NULL;
+ (*num_mem) = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), group_pol, &group_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(group_sid_str, &group_sid);
+ sid_split_rid(&group_sid, &group_rid);
+
+ DEBUG(10,("sid is %s\n", group_sid_str));
+
+ if (!sid_equal(&group_sid, &global_sam_sid))
+ {
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ become_root(True);
+ grp = getgrouprid(group_rid, &mem_grp, &num_rids);
+ unbecome_root(True);
+
+ if (grp == NULL)
+ {
+ return NT_STATUS_NO_SUCH_GROUP;
+ }
+
+ if (num_rids > 0)
+ {
+ (*rid) = malloc(num_rids * sizeof(uint32));
+ (*attr) = malloc(num_rids * sizeof(uint32));
+ if (mem_grp != NULL && (*rid) != NULL && (*attr) != NULL)
+ {
+ int i;
+ for (i = 0; i < num_rids; i++)
+ {
+ (*rid) [i] = mem_grp[i].rid;
+ (*attr)[i] = mem_grp[i].attr;
+ }
+ }
+ }
+
+ safe_free(mem_grp);
+
+ (*num_mem) = num_rids;
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_set_groupinfo
+ ********************************************************************/
+uint32 _samr_set_groupinfo(const POLICY_HND *pol,
+ uint16 switch_level,
+ const GROUP_INFO_CTR* ctr)
+{
+ return NT_STATUS_ACCESS_DENIED;
+}
+
+/*******************************************************************
+ samr_reply_query_groupinfo
+ ********************************************************************/
+uint32 _samr_query_groupinfo(const POLICY_HND *pol,
+ uint16 switch_level,
+ GROUP_INFO_CTR* ctr)
+{
+ /* find the policy handle. open a policy on it. */
+ if ((find_policy_by_hnd(get_global_hnd_cache(), pol) == -1))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ switch (switch_level)
+ {
+ case 1:
+ {
+ ctr->switch_value1 = 1;
+ make_samr_group_info1(&ctr->group.info1,
+ "fake account name",
+ "fake account description", 2);
+ break;
+ }
+ case 4:
+ {
+ ctr->switch_value1 = 4;
+ make_samr_group_info4(&ctr->group.info4,
+ "fake account description");
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+/*******************************************************************
+ samr_reply_query_aliasinfo
+ ********************************************************************/
+uint32 _samr_query_aliasinfo(const POLICY_HND *alias_pol,
+ uint16 switch_level,
+ ALIAS_INFO_CTR *ctr)
+{
+ /* find the policy handle. open a policy on it. */
+ if ((find_policy_by_hnd(get_global_hnd_cache(), alias_pol) == -1))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ switch (switch_level)
+ {
+ case 3:
+ {
+ ctr->switch_value1 = 3;
+ make_samr_alias_info3(&ctr->alias.info3,
+ "<fake account description>");
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+/*******************************************************************
+ samr_reply_query_useraliases
+ ********************************************************************/
+uint32 _samr_query_useraliases(const POLICY_HND *pol,
+ const uint32 *ptr_sid, const DOM_SID2 *sid,
+ uint32 *num_aliases, uint32 **rid)
+{
+ LOCAL_GRP *mem_grp = NULL;
+ int num_rids = 0;
+ struct sam_passwd *sam_pass;
+ DOM_SID usr_sid;
+ DOM_SID dom_sid;
+ uint32 user_rid;
+ fstring sam_sid_str;
+ fstring dom_sid_str;
+ fstring usr_sid_str;
+
+ DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
+
+ (*rid) = NULL;
+ (*num_aliases) = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(dom_sid_str, &dom_sid );
+ sid_to_string(sam_sid_str, &global_sam_sid);
+
+ usr_sid = sid[0].sid;
+ sid_split_rid(&usr_sid, &user_rid);
+ sid_to_string(usr_sid_str, &usr_sid);
+
+ /* find the user account */
+ become_root(True);
+ sam_pass = getsam21pwrid(user_rid);
+ unbecome_root(True);
+
+ if (sam_pass == NULL)
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ DEBUG(10,("sid is %s\n", dom_sid_str));
+
+ if (sid_equal(&dom_sid, &global_sid_S_1_5_20))
+ {
+ BOOL ret;
+ DEBUG(10,("lookup on S-1-5-20\n"));
+
+ become_root(True);
+ ret = getuserbuiltinntnam(sam_pass->nt_name, &mem_grp,
+ &num_rids);
+ unbecome_root(True);
+
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else if (sid_equal(&dom_sid, &usr_sid))
+ {
+ BOOL ret;
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ become_root(True);
+ ret = getuseraliasntnam(sam_pass->nt_name, &mem_grp,
+ &num_rids);
+ unbecome_root(True);
+
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ if (num_rids > 0)
+ {
+ (*rid) = malloc(num_rids * sizeof(uint32));
+ if (mem_grp != NULL && (*rid) != NULL)
+ {
+ int i;
+ for (i = 0; i < num_rids; i++)
+ {
+ (*rid)[i] = mem_grp[i].rid;
+ }
+ }
+ }
+
+ (*num_aliases) = num_rids;
+ safe_free(mem_grp);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_delete_dom_alias
+ ********************************************************************/
+uint32 _samr_delete_dom_alias(POLICY_HND *alias_pol)
+{
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+
+ DEBUG(5,("samr_delete_dom_alias: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), alias_pol, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(alias_sid_str, &alias_sid );
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (!sid_equal(&alias_sid, &global_sam_sid))
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ if (!del_alias_entry(alias_rid))
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ return _samr_close(alias_pol);
+}
+
+
+/*******************************************************************
+ samr_reply_query_aliasmem
+ ********************************************************************/
+uint32 _samr_query_aliasmem(const POLICY_HND *alias_pol,
+ uint32 *num_mem, DOM_SID2 **sid)
+{
+ LOCAL_GRP_MEMBER *mem_grp = NULL;
+ LOCAL_GRP *grp = NULL;
+ int num_sids = 0;
+ DOM_SID alias_sid;
+ uint32 alias_rid;
+ fstring alias_sid_str;
+
+ DEBUG(5,("samr_query_aliasmem: %d\n", __LINE__));
+
+ (*sid) = NULL;
+ (*num_mem) = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), alias_pol, &alias_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_to_string(alias_sid_str, &alias_sid );
+ sid_split_rid(&alias_sid, &alias_rid);
+
+ DEBUG(10,("sid is %s\n", alias_sid_str));
+
+ if (sid_equal(&alias_sid, &global_sid_S_1_5_20))
+ {
+ DEBUG(10,("lookup on S-1-5-20\n"));
+
+ become_root(True);
+ grp = getbuiltinrid(alias_rid, &mem_grp, &num_sids);
+ unbecome_root(True);
+ }
+ else if (sid_equal(&alias_sid, &global_sam_sid))
+ {
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ become_root(True);
+ grp = getaliasrid(alias_rid, &mem_grp, &num_sids);
+ unbecome_root(True);
+ }
+ else
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ if (grp == NULL)
+ {
+ return NT_STATUS_NO_SUCH_ALIAS;
+ }
+
+ if (num_sids > 0)
+ {
+ (*sid) = malloc(num_sids * sizeof(DOM_SID2));
+ if (mem_grp != NULL && sid != NULL)
+ {
+ int i;
+ for (i = 0; i < num_sids; i++)
+ {
+ make_dom_sid2(&(*sid)[i], &mem_grp[i].sid);
+ }
+ }
+ }
+
+ (*num_mem) = num_sids;
+
+ if (mem_grp != NULL)
+ {
+ free(mem_grp);
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_lookup_names
+ ********************************************************************/
+uint32 _samr_lookup_names(const POLICY_HND *pol,
+
+ uint32 num_names1,
+ uint32 flags,
+ uint32 ptr,
+ const UNISTR2 *uni_name,
+
+ uint32 *num_rids1,
+ uint32 rid[MAX_SAM_ENTRIES],
+ uint32 *num_types1,
+ uint32 type[MAX_SAM_ENTRIES])
+{
+ int i;
+ int num_rids = num_names1;
+ DOM_SID pol_sid;
+ fstring tmp;
+ BOOL found_one = False;
+
+ DEBUG(5,("samr_lookup_names: %d\n", __LINE__));
+
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &pol_sid))
+ {
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ sid_to_string(tmp, &pol_sid);
+ DEBUG(5,("pol_sid: %s\n", tmp));
+
+ if (num_rids > MAX_SAM_ENTRIES)
+ {
+ num_rids = MAX_SAM_ENTRIES;
+ DEBUG(5,("samr_lookup_names: truncating entries to %d\n", num_rids));
+ }
+
+ for (i = 0; i < num_rids; i++)
+ {
+ DOM_SID sid;
+ fstring name;
+ uint32 status1;
+ unistr2_to_ascii(name, &uni_name[i], sizeof(name)-1);
+
+ status1 = lookup_name(name, &sid, &(type[i]));
+ if (status1 == 0x0)
+ {
+ found_one = True;
+ sid_split_rid(&sid, &rid[i]);
+ }
+ if ((status1 != 0x0) || !sid_equal(&pol_sid, &sid))
+ {
+ rid [i] = 0xffffffff;
+ type[i] = SID_NAME_UNKNOWN;
+ }
+
+ sid_to_string(tmp, &sid);
+ DEBUG(10,("name: %s sid: %s rid: %x type: %d\n",
+ name, tmp, rid[i], type[i]));
+ }
+
+ if (!found_one)
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ (*num_rids1) = num_rids;
+ (*num_types1) = num_rids;
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_chgpasswd_user
+ ********************************************************************/
+uint32 _samr_chgpasswd_user( const UNISTR2 *uni_dest_host,
+ const UNISTR2 *uni_user_name,
+ const char nt_newpass[516],
+ const uchar nt_oldhash[16],
+ const char lm_newpass[516],
+ const uchar lm_oldhash[16])
+{
+ fstring user_name;
+ fstring wks;
+
+ unistr2_to_ascii(user_name, uni_user_name, sizeof(user_name)-1);
+ unistr2_to_ascii(wks, uni_dest_host, sizeof(wks)-1);
+
+ DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
+
+ if (!pass_oem_change(user_name,
+ lm_newpass, lm_oldhash,
+ nt_newpass, nt_oldhash))
+ {
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+/*******************************************************************
+ samr_reply_get_dom_pwinfo
+ ********************************************************************/
+uint32 _samr_get_dom_pwinfo(const UNISTR2 *uni_srv_name,
+ uint16 *unk_0, uint16 *unk_1, uint16 *unk_2)
+{
+ /* absolutely no idea what to do, here */
+ *unk_0 = 0;
+ *unk_1 = 0;
+ *unk_2 = 0;
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+makes a SAMR_R_LOOKUP_RIDS structure.
+********************************************************************/
+static BOOL make_samr_lookup_rids( uint32 num_names, char *const *name,
+ UNIHDR **hdr_name, UNISTR2** uni_name)
+{
+ uint32 i;
+ if (name == NULL) return False;
+
+ *uni_name = NULL;
+ *hdr_name = NULL;
+
+ if (num_names != 0)
+ {
+ (*hdr_name) = (UNIHDR*)malloc(num_names * sizeof((*hdr_name)[0]));
+ if ((*hdr_name) == NULL)
+ {
+ return False;
+ }
+ (*uni_name) = (UNISTR2*)malloc(num_names * sizeof((*uni_name)[0]));
+ if ((*uni_name) == NULL)
+ {
+ free(*uni_name);
+ *uni_name = NULL;
+ return False;
+ }
+ }
+
+ for (i = 0; i < num_names; i++)
+ {
+ int len = name[i] != NULL ? strlen(name[i]) : 0;
+ DEBUG(10,("name[%d]:%s\n", i, name[i]));
+ make_uni_hdr(&((*hdr_name)[i]), len);
+ make_unistr2(&((*uni_name)[i]), name[i], len);
+ }
+
+ return True;
+}
+
+/*******************************************************************
+ samr_reply_lookup_rids
+ ********************************************************************/
+uint32 _samr_lookup_rids(const POLICY_HND *pol,
+ uint32 num_rids, uint32 flags,
+ const uint32 *rids,
+ uint32 *num_names,
+ UNIHDR **hdr_name, UNISTR2** uni_name,
+ uint32 **types)
+{
+ char **grp_names = NULL;
+ DOM_SID pol_sid;
+ BOOL found_one = False;
+ int i;
+
+ DEBUG(5,("samr_lookup_rids: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &pol_sid))
+ {
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ (*types) = malloc(num_rids * sizeof(**types));
+
+ if ((*types) == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ grp_names = g_new(char *, num_rids);
+ if (grp_names == NULL)
+ {
+ free(*types);
+ (*types) = NULL;
+ return NT_STATUS_NO_MEMORY;
+ }
+
+
+ for (i = 0; i < num_rids; i++)
+ {
+ uint32 status1;
+ DOM_SID sid;
+ fstring tmpname;
+
+ sid_copy(&sid, &pol_sid);
+ sid_append_rid(&sid, rids[i]);
+
+ status1 = lookup_sid(&sid, tmpname, &(*types)[i]);
+
+ if (status1 == 0)
+ {
+ found_one = True;
+ grp_names[i] = strdup(tmpname);
+ }
+ else
+ {
+ (*types)[i] = SID_NAME_UNKNOWN;
+ grp_names[i] = NULL;
+ }
+ }
+
+ if (!found_one)
+ {
+ return NT_STATUS_NONE_MAPPED;
+ }
+
+ (*num_names) = num_rids;
+ make_samr_lookup_rids(num_rids, grp_names, hdr_name, uni_name);
+
+ free_char_array(num_rids, grp_names);
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_open_user
+ ********************************************************************/
+uint32 _samr_open_user(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 user_rid,
+ POLICY_HND *user_pol)
+{
+ struct sam_passwd *sam_pass;
+ DOM_SID sid;
+
+ /* set up the SAMR open_user response */
+ bzero(user_pol->data, POL_HND_SIZE);
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* this should not be hard-coded like this */
+ if (!sid_equal(&sid, &global_sam_sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ become_root(True);
+ sam_pass = getsam21pwrid(user_rid);
+ unbecome_root(True);
+
+ /* check that the RID exists in our domain. */
+ if (sam_pass == NULL)
+ {
+ close_policy_hnd(get_global_hnd_cache(), user_pol);
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ return samr_open_by_sid(domain_pol, &sid, user_pol,
+ access_mask, user_rid);
+}
+
+
+/*************************************************************************
+ get_user_info_10
+ *************************************************************************/
+static BOOL get_user_info_10(SAM_USER_INFO_10 *id10, uint32 user_rid)
+{
+ struct sam_passwd *sam_pass;
+
+ become_root(True);
+ sam_pass = getsam21pwrid(user_rid);
+ unbecome_root(True);
+
+ if (sam_pass == NULL)
+ {
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ return False;
+ }
+
+ DEBUG(3,("User:[%s]\n", sam_pass->nt_name));
+
+ make_sam_user_info10(id10, sam_pass->acct_ctrl);
+
+ return True;
+}
+
+/*************************************************************************
+ get_user_info_21
+ *************************************************************************/
+static BOOL get_user_info_12(SAM_USER_INFO_12 *id12, uint32 user_rid)
+{
+ struct sam_passwd *sam_pass;
+
+ become_root(True);
+ sam_pass = getsam21pwrid(user_rid);
+ unbecome_root(True);
+
+ if (sam_pass == NULL)
+ {
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ return False;
+ }
+
+ DEBUG(3,("User:[%s] %x\n", sam_pass->nt_name, sam_pass->acct_ctrl));
+
+ if (IS_BITS_SET_ALL(sam_pass->acct_ctrl, ACB_DISABLED))
+ {
+ return False;
+ }
+
+ make_sam_user_info12(id12, sam_pass->acct_ctrl,
+ sam_pass->smb_passwd,
+ sam_pass->smb_nt_passwd);
+
+ return True;
+}
+
+/*************************************************************************
+ get_user_info_21
+ *************************************************************************/
+static BOOL get_user_info_21(SAM_USER_INFO_21 *id21, uint32 user_rid)
+{
+ struct sam_passwd *sam_pass;
+ LOGON_HRS hrs;
+ int i;
+
+ become_root(True);
+ sam_pass = getsam21pwrid(user_rid);
+ unbecome_root(True);
+
+ if (sam_pass == NULL)
+ {
+ DEBUG(4,("User 0x%x not found\n", user_rid));
+ return False;
+ }
+
+ DEBUG(3,("User:[%s]\n", sam_pass->nt_name));
+
+ /* create a LOGON_HRS structure */
+ hrs.len = sam_pass->hours_len;
+ SMB_ASSERT_ARRAY(hrs.hours, hrs.len);
+ for (i = 0; i < hrs.len; i++)
+ {
+ hrs.hours[i] = sam_pass->hours[i];
+ }
+
+ make_sam_user_info21A(id21,
+
+ &sam_pass->logon_time,
+ &sam_pass->logoff_time,
+ &sam_pass->kickoff_time,
+ &sam_pass->pass_last_set_time,
+ &sam_pass->pass_can_change_time,
+ &sam_pass->pass_must_change_time,
+
+ sam_pass->nt_name, /* user_name */
+ sam_pass->full_name, /* full_name */
+ sam_pass->home_dir, /* home_dir */
+ sam_pass->dir_drive, /* dir_drive */
+ sam_pass->logon_script, /* logon_script */
+ sam_pass->profile_path, /* profile_path */
+ sam_pass->acct_desc, /* description */
+ sam_pass->workstations, /* workstations user can log in from */
+ sam_pass->unknown_str, /* don't know, yet */
+ sam_pass->munged_dial, /* dialin info. contains dialin path and tel no */
+
+ sam_pass->user_rid, /* RID user_id */
+ sam_pass->group_rid, /* RID group_id */
+ sam_pass->acct_ctrl,
+
+ sam_pass->unknown_3, /* unknown_3 */
+ sam_pass->logon_divs, /* divisions per week */
+ &hrs, /* logon hours */
+ sam_pass->unknown_5,
+ sam_pass->unknown_6);
+
+ return True;
+}
+
+/*******************************************************************
+ samr_reply_query_userinfo
+ ********************************************************************/
+uint32 _samr_query_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr)
+{
+ uint32 rid = 0x0;
+ DOM_SID group_sid;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &group_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ sid_split_rid(&group_sid, &rid);
+
+ DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
+
+ /* ok! user info levels (lots: see MSDEV help), off we go... */
+ ctr->switch_value = switch_value;
+ switch (switch_value)
+ {
+ case 0x10:
+ {
+ ctr->info.id = (SAM_USER_INFO_10*)Realloc(NULL,
+ sizeof(*ctr->info.id10));
+ if (ctr->info.id == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (!get_user_info_10(ctr->info.id10, rid))
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+ break;
+ }
+#if 0
+/* whoops - got this wrong. i think. or don't understand what's happening. */
+ case 0x11:
+ {
+ NTTIME expire;
+ info = (void*)&id11;
+
+ expire.low = 0xffffffff;
+ expire.high = 0x7fffffff;
+
+ ctr->info.id = (SAM_USER_INFO_11*)Realloc(NULL,
+ sizeof(*ctr->info.id11));
+ make_sam_user_info11(ctr->info.id11, &expire,
+ "BROOKFIELDS$", /* name */
+ 0x03ef, /* user rid */
+ 0x201, /* group rid */
+ 0x0080); /* acb info */
+
+ break;
+ }
+#endif
+ case 0x12:
+ {
+ ctr->info.id = (SAM_USER_INFO_12*)Realloc(NULL,
+ sizeof(*ctr->info.id12));
+ if (ctr->info.id == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (!get_user_info_12(ctr->info.id12, rid))
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+ break;
+ }
+ case 21:
+ {
+ ctr->info.id = (SAM_USER_INFO_21*)Realloc(NULL,
+ sizeof(*ctr->info.id21));
+ if (ctr->info.id == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (!get_user_info_21(ctr->info.id21, rid))
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+ break;
+ }
+
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ set_user_info_12
+ ********************************************************************/
+static BOOL set_user_info_12(const SAM_USER_INFO_12 *id12, uint32 rid)
+{
+ struct sam_passwd *pwd = getsam21pwrid(rid);
+ struct sam_passwd new_pwd;
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+
+ if (pwd == NULL)
+ {
+ return False;
+ }
+
+ pwdb_init_sam(&new_pwd);
+ copy_sam_passwd(&new_pwd, pwd);
+
+ memcpy(nt_hash, id12->nt_pwd, sizeof(nt_hash));
+ memcpy(lm_hash, id12->lm_pwd, sizeof(lm_hash));
+
+ new_pwd.smb_passwd = lm_hash;
+ new_pwd.smb_nt_passwd = nt_hash;
+
+ return mod_sam21pwd_entry(&new_pwd, True);
+}
+
+/*******************************************************************
+ set_user_info_24
+ ********************************************************************/
+static BOOL set_user_info_24(const SAM_USER_INFO_24 *id24, uint32 rid)
+{
+ struct sam_passwd *pwd = getsam21pwrid(rid);
+ struct sam_passwd new_pwd;
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+ UNISTR2 new_pw;
+ uint32 len;
+
+ if (pwd == NULL)
+ {
+ return False;
+ }
+
+ pwdb_init_sam(&new_pwd);
+ copy_sam_passwd(&new_pwd, pwd);
+
+ if (!decode_pw_buffer(id24->pass, (char *)new_pw.buffer, 256, &len))
+ {
+ return False;
+ }
+
+ new_pw.uni_max_len = len / 2;
+ new_pw.uni_str_len = len / 2;
+
+ nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
+
+ new_pwd.smb_passwd = lm_hash;
+ new_pwd.smb_nt_passwd = nt_hash;
+
+ return mod_sam21pwd_entry(&new_pwd, True);
+}
+
+/*******************************************************************
+ set_user_info_23
+ ********************************************************************/
+static BOOL set_user_info_23(const SAM_USER_INFO_23 *id23, uint32 rid)
+{
+ struct sam_passwd *pwd = getsam21pwrid(rid);
+ struct sam_passwd new_pwd;
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+ UNISTR2 new_pw;
+ uint32 len;
+
+ if (id23 == NULL)
+ {
+ DEBUG(5, ("set_user_info_23: NULL id23\n"));
+ return False;
+ }
+ if (pwd == NULL)
+ {
+ return False;
+ }
+
+ pwdb_init_sam(&new_pwd);
+ copy_sam_passwd(&new_pwd, pwd);
+ copy_id23_to_sam_passwd(&new_pwd, id23);
+
+ if (!decode_pw_buffer(id23->pass, (char*)new_pw.buffer, 256, &len))
+ {
+ return False;
+ }
+
+ new_pw.uni_max_len = len / 2;
+ new_pw.uni_str_len = len / 2;
+
+ nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
+
+ new_pwd.smb_passwd = lm_hash;
+ new_pwd.smb_nt_passwd = nt_hash;
+
+ return mod_sam21pwd_entry(&new_pwd, True);
+}
+
+/*******************************************************************
+ samr_reply_set_userinfo
+ ********************************************************************/
+uint32 _samr_set_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr)
+{
+ uchar user_sess_key[16];
+ uint32 rid = 0x0;
+ DOM_SID sid;
+
+ DEBUG(5,("samr_reply_set_userinfo: %d\n", __LINE__));
+
+ /* search for the handle */
+ if (find_policy_by_hnd(get_global_hnd_cache(), pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!pol_get_usr_sesskey(get_global_hnd_cache(), pol, user_sess_key))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_split_rid(&sid, &rid);
+
+ DEBUG(5,("samr_reply_set_userinfo: rid:0x%x\n", rid));
+
+ if (ctr == NULL)
+ {
+ DEBUG(5,("samr_reply_set_userinfo: NULL info level\n"));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ /* ok! user info levels (lots: see MSDEV help), off we go... */
+ switch (switch_value)
+ {
+ case 0x12:
+ {
+ SAM_USER_INFO_12 *id12 = ctr->info.id12;
+ if (!set_user_info_12(id12, rid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+
+ case 24:
+ {
+ SAM_USER_INFO_24 *id24 = ctr->info.id24;
+ SamOEMhash(id24->pass, user_sess_key, True);
+ if (!set_user_info_24(id24, rid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+
+ case 23:
+ {
+ SAM_USER_INFO_23 *id23 = ctr->info.id23;
+ SamOEMhash(id23->pass, user_sess_key, 1);
+ dump_data_pw("pass buff:\n", id23->pass, sizeof(id23->pass));
+ dbgflush();
+
+ if (!set_user_info_23(id23, rid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ set_user_info_10
+ ********************************************************************/
+static BOOL set_user_info_10(const SAM_USER_INFO_10 *id10, uint32 rid)
+{
+ struct sam_passwd *pwd = getsam21pwrid(rid);
+ struct sam_passwd new_pwd;
+
+ if (id10 == NULL)
+ {
+ DEBUG(5, ("set_user_info_10: NULL id10\n"));
+ return False;
+ }
+ if (pwd == NULL)
+ {
+ return False;
+ }
+
+ copy_sam_passwd(&new_pwd, pwd);
+
+ new_pwd.acct_ctrl = id10->acb_info;
+
+ return mod_sam21pwd_entry(&new_pwd, True);
+}
+
+/*******************************************************************
+ samr_reply_set_userinfo2
+ ********************************************************************/
+uint32 _samr_set_userinfo2(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr)
+{
+ DOM_SID sid;
+ uint32 rid = 0x0;
+
+ DEBUG(5,("samr_reply_set_userinfo2: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_split_rid(&sid, &rid);
+
+ DEBUG(5,("samr_reply_set_userinfo2: rid:0x%x\n", rid));
+
+ if (ctr == NULL)
+ {
+ DEBUG(5,("samr_reply_set_userinfo2: NULL info level\n"));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ ctr->switch_value = switch_value;
+
+ /* ok! user info levels (lots: see MSDEV help), off we go... */
+ switch (switch_value)
+ {
+ case 16:
+ {
+ SAM_USER_INFO_10 *id10 = ctr->info.id10;
+ if (!set_user_info_10(id10, rid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+
+/*******************************************************************
+ samr_reply_query_usergroups
+ ********************************************************************/
+uint32 _samr_query_usergroups(const POLICY_HND *pol,
+ uint32 *num_groups,
+ DOM_GID **gids)
+{
+ DOMAIN_GRP *mem_grp = NULL;
+ struct sam_passwd *sam_pass;
+ DOM_SID sid;
+ uint32 rid;
+ BOOL ret;
+
+ DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), pol, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_split_rid(&sid, &rid);
+
+ become_root(True);
+ sam_pass = getsam21pwrid(rid);
+ unbecome_root(True);
+
+ if (sam_pass == NULL)
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ become_root(True);
+ ret = getusergroupsntnam(sam_pass->nt_name, &mem_grp, num_groups);
+ unbecome_root(True);
+
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ (*gids) = NULL;
+ (*num_groups) = make_dom_gids(mem_grp, *num_groups, gids);
+
+ if (mem_grp != NULL)
+ {
+ free(mem_grp);
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_create_dom_alias
+ ********************************************************************/
+uint32 _samr_create_dom_alias(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_acct_name,
+ uint32 access_mask,
+ POLICY_HND *alias_pol, uint32 *rid)
+{
+ uint32 status;
+ DOM_SID dom_sid;
+ LOCAL_GRP grp;
+
+ bzero(alias_pol, POL_HND_SIZE);
+
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the domain sid */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol, &dom_sid))
+ {
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if (!sid_equal(&dom_sid, &global_sam_sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ unistr2_to_ascii(grp.name, uni_acct_name, sizeof(grp.name)-1);
+ fstrcpy(grp.comment, "");
+ *rid = grp.rid = 0xffffffff;
+
+ *rid = grp.rid;
+ status = samr_open_by_sid(domain_pol, &dom_sid, alias_pol,
+ access_mask, grp.rid);
+
+ if (status != 0x0)
+ {
+ return status;
+ }
+
+ if (!add_alias_entry(&grp))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_create_dom_group
+ ********************************************************************/
+uint32 _samr_create_dom_group(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_acct_name,
+ uint32 access_mask,
+ POLICY_HND *group_pol, uint32 *rid)
+{
+ uint32 status;
+ DOM_SID dom_sid;
+ DOMAIN_GRP grp;
+
+ bzero(group_pol, POL_HND_SIZE);
+
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the domain sid */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol, &dom_sid))
+ {
+ return NT_STATUS_OBJECT_TYPE_MISMATCH;
+ }
+
+ if (!sid_equal(&dom_sid, &global_sam_sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ unistr2_to_ascii(grp.name, uni_acct_name, sizeof(grp.name)-1);
+ fstrcpy(grp.comment, "");
+ *rid = grp.rid = 0xffffffff;
+ grp.attr = 0x07;
+
+ *rid = grp.rid;
+ status = samr_open_by_sid(domain_pol, &dom_sid, group_pol,
+ access_mask, grp.rid);
+ if (status != 0x0)
+ {
+ return status;
+ }
+
+ if (!add_group_entry(&grp))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_query_dom_info
+ ********************************************************************/
+uint32 _samr_query_dom_info(const POLICY_HND *domain_pol,
+ uint16 switch_value,
+ SAM_UNK_CTR *ctr)
+{
+ /* find the policy handle. open a policy on it. */
+ if (find_policy_by_hnd(get_global_hnd_cache(), domain_pol) == -1)
+ {
+ DEBUG(5,("samr_reply_query_dom_info: invalid handle\n"));
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ switch (switch_value)
+ {
+ case 0x07:
+ {
+ make_unk_info7(&(ctr->info.inf7));
+ break;
+ }
+ case 0x06:
+ {
+ make_unk_info6(&(ctr->info.inf6));
+ break;
+ }
+ case 0x03:
+ {
+ make_unk_info3(&(ctr->info.inf3));
+ break;
+ }
+ case 0x02:
+ {
+ extern fstring global_sam_name;
+ extern pstring global_myname;
+ make_unk_info2(&(ctr->info.inf2), global_sam_name, global_myname);
+ break;
+ }
+ case 0x01:
+ {
+ make_unk_info1(&(ctr->info.inf1));
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_create_user
+ ********************************************************************/
+uint32 _samr_create_user(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_username,
+ uint16 acb_info, uint32 access_mask,
+ POLICY_HND *user_pol,
+ uint32 *unknown_0, uint32 *user_rid)
+{
+ DOM_SID sid;
+
+ struct sam_passwd *sam_pass;
+ fstring user_name;
+ pstring err_str;
+ pstring msg_str;
+
+ (*unknown_0) = 0x30;
+ (*user_rid) = 0x0;
+
+ /* find the machine account: tell the caller if it exists.
+ lkclXXXX i have *no* idea if this is a problem or not
+ or even if you are supposed to construct a different
+ reply if the account already exists...
+ */
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ if (!sid_equal(&sid, &global_sam_sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ unistr2_to_ascii(user_name, uni_username, sizeof(user_name)-1);
+
+ sam_pass = getsam21pwntnam(user_name);
+
+ if (sam_pass != NULL)
+ {
+ /* account exists: say so */
+ return NT_STATUS_USER_EXISTS;
+ }
+
+ if (!local_password_change(user_name, True,
+ acb_info | ACB_DISABLED | ACB_PWNOTREQ, 0xffff,
+ NULL,
+ err_str, sizeof(err_str),
+ msg_str, sizeof(msg_str)))
+ {
+ DEBUG(0,("%s\n", err_str));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ sam_pass = getsam21pwntnam(user_name);
+ if (sam_pass == NULL)
+ {
+ /* account doesn't exist: say so */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ *unknown_0 = 0x000703ff;
+ *user_rid = sam_pass->user_rid;
+
+ return samr_open_by_sid(domain_pol, &sid, user_pol,
+ access_mask, *user_rid);
+}
+
+/*******************************************************************
+ _samr_connect_anon
+ ********************************************************************/
+uint32 _samr_connect_anon(const UNISTR2 *srv_name, uint32 access_mask,
+ POLICY_HND *connect_pol)
+
+{
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd(get_global_hnd_cache(),
+ get_sec_ctx(), connect_pol, access_mask))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_connect
+ ********************************************************************/
+uint32 _samr_connect(const UNISTR2 *srv_name, uint32 access_mask,
+ POLICY_HND *connect_pol)
+{
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd(get_global_hnd_cache(),
+ get_sec_ctx(), connect_pol, access_mask))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_open_alias
+ ********************************************************************/
+uint32 _samr_open_alias(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 alias_rid,
+ POLICY_HND *alias_pol)
+{
+ DOM_SID sid;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* this should not be hard-coded like this */
+ if (!sid_equal(&sid, &global_sam_sid) &&
+ !sid_equal(&sid, &global_sid_S_1_5_20))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return samr_open_by_sid(domain_pol, &sid, alias_pol, access_mask, alias_rid);
+}
+
+/*******************************************************************
+ _samr_open_group
+ ********************************************************************/
+uint32 _samr_open_group(const POLICY_HND *domain_pol, uint32 access_mask,
+ uint32 group_rid,
+ POLICY_HND *group_pol)
+{
+ DOM_SID sid;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_policy_samr_sid(get_global_hnd_cache(), domain_pol, &sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* this should not be hard-coded like this */
+ if (!sid_equal(&sid, &global_sam_sid))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return samr_open_by_sid(domain_pol, &sid, group_pol, access_mask, group_rid);
+}
+
+/*******************************************************************
+_samr_lookup_domain
+********************************************************************/
+uint32 _samr_lookup_domain(const POLICY_HND *connect_pol,
+ const UNISTR2 *uni_domain,
+ DOM_SID *dom_sid)
+{
+ fstring domain;
+
+ /* find the connection policy handle */
+ if (find_policy_by_hnd(get_global_hnd_cache(), connect_pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ unistr2_to_ascii(domain, uni_domain, sizeof(domain));
+ DEBUG(5, ("Lookup Domain: %s\n", domain));
+
+ /* check it's one of ours */
+ if (strequal(domain, global_sam_name))
+ {
+ sid_copy(dom_sid, &global_sam_sid);
+ return 0x0;
+ }
+ else if (strequal(domain, "BUILTIN"))
+ {
+ sid_copy(dom_sid, &global_sid_S_1_5_20);
+ return 0x0;
+ }
+
+ return NT_STATUS_NO_SUCH_DOMAIN;
+}
+
+BOOL pwdbsam_initialise(void)
+{
+ return initialise_password_db() &&
+ initialise_sam_password_db() &&
+ initialise_passgrp_db() &&
+ initialise_group_db() &&
+ initialise_alias_db() &&
+ initialise_builtin_db();
+}
diff --git a/source/samrd/srv_samr_sam_tdb.c b/source/samrd/srv_samr_sam_tdb.c
new file mode 100644
index 00000000000..2f81392ab5e
--- /dev/null
+++ b/source/samrd/srv_samr_sam_tdb.c
@@ -0,0 +1,365 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+typedef struct sam_data_info
+{
+ SAM_ENTRY *sam;
+ UNISTR2 *uni_name;
+ uint32 num_sam_entries;
+ uint32 start_idx;
+ uint32 current_idx;;
+
+} SAM_DATA;
+
+/******************************************************************
+makes a SAMR_R_ENUM_DOMAINS structure.
+********************************************************************/
+static int tdb_domain_traverse(TDB_CONTEXT *tdb,
+ TDB_DATA kbuf,
+ TDB_DATA dbuf,
+ void *state)
+{
+ prs_struct key;
+ UNISTR2 *str;
+ SAM_DATA *data = (SAM_DATA*)state;
+ uint32 num_sam_entries = data->num_sam_entries + 1;
+ SAM_ENTRY *sam;
+
+ DEBUG(5,("tdb_domain_traverse: idx: %d %d\n",
+ data->current_idx,
+ num_sam_entries));
+
+ dump_data_pw("sid:\n" , dbuf.dptr, dbuf.dsize);
+ dump_data_pw("domain:\n", kbuf.dptr, kbuf.dsize);
+
+ /* skip first requested items */
+ if (data->current_idx < data->start_idx)
+ {
+ data->current_idx++;
+ return 0;
+ }
+
+ data->sam = (SAM_ENTRY*)Realloc(data->sam,
+ num_sam_entries * sizeof(data->sam[0]));
+ data->uni_name = (UNISTR2*)Realloc(data->uni_name,
+ num_sam_entries * sizeof(data->uni_name[0]));
+
+ if (data->sam == NULL || data->uni_name == NULL)
+ {
+ DEBUG(0,("NULL pointers in make_enum_domains\n"));
+ return -1;
+ }
+
+ sam = &data->sam[data->num_sam_entries];
+ str = &data->uni_name[data->num_sam_entries];
+
+ ZERO_STRUCTP(sam);
+ ZERO_STRUCTP(str);
+
+ prs_create(&key, kbuf.dptr, kbuf.dsize, 4, True);
+
+ if (smb_io_unistr2("dom", str, True, &key, 0))
+ {
+ sam->rid = 0x0;
+ make_uni_hdr(&sam->hdr_name, str->uni_str_len);
+
+ data->num_sam_entries++;
+ }
+
+ return 0;
+}
+
+/*******************************************************************
+ samr_reply_enum_domains
+ ********************************************************************/
+uint32 _samr_enum_domains(const POLICY_HND *pol, uint32 *start_idx,
+ uint32 size,
+ SAM_ENTRY **sam,
+ UNISTR2 **uni_acct_name,
+ uint32 *num_sam_users)
+{
+ TDB_CONTEXT *sam_tdb = NULL;
+ SAM_DATA state;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_tdbsid(get_global_hnd_cache(), pol, &sam_tdb, NULL))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_enum_domains:\n"));
+
+ ZERO_STRUCT(state);
+
+ state.start_idx = (*start_idx);
+ tdb_traverse(sam_tdb, tdb_domain_traverse, (void*)&state);
+
+ (*sam) = state.sam;
+ (*uni_acct_name) = state.uni_name;
+ (*start_idx) += state.num_sam_entries;
+ (*num_sam_users) = state.num_sam_entries;
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ tdb_samr_connect
+ ********************************************************************/
+static uint32 tdb_samr_connect( POLICY_HND *pol, uint32 ace_perms)
+{
+ TDB_CONTEXT *sam_tdb = NULL;
+
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd(get_global_hnd_cache(),
+ get_sec_ctx(), pol, ace_perms))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ become_root(True);
+ sam_tdb = tdb_open(passdb_path("sam.tdb"), 0, 0, O_RDONLY, 0644);
+ unbecome_root(True);
+
+ if (sam_tdb == NULL)
+ {
+ close_policy_hnd(get_global_hnd_cache(), pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* associate the domain SID with the (unique) handle. */
+ if (!set_tdbsid(get_global_hnd_cache(), pol, sam_tdb,
+ &global_sid_S_1_1))
+ {
+ close_policy_hnd(get_global_hnd_cache(), pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _samr_connect_anon
+ ********************************************************************/
+uint32 _samr_connect_anon(const UNISTR2 *srv_name, uint32 access_mask,
+ POLICY_HND *connect_pol)
+
+{
+ return tdb_samr_connect(connect_pol, access_mask);
+}
+
+/*******************************************************************
+ _samr_connect
+ ********************************************************************/
+uint32 _samr_connect(const UNISTR2 *srv_name, uint32 access_mask,
+ POLICY_HND *connect_pol)
+{
+ return tdb_samr_connect(connect_pol, access_mask);
+}
+
+static uint32 tdb_lookup_domain(TDB_CONTEXT *tdb,
+ const UNISTR2* uni_domain,
+ DOM_SID *sid)
+{
+ prs_struct key;
+ prs_struct data;
+ UNISTR2 uni_dom_copy;
+
+ copy_unistr2(&uni_dom_copy, uni_domain);
+
+ prs_init(&key, 0, 4, False);
+ if (!smb_io_unistr2("dom", &uni_dom_copy, True, &key, 0))
+ {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ prs_tdb_fetch(tdb, &key, &data);
+
+ if (!smb_io_dom_sid("sid", sid, &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+_samr_lookup_domain
+********************************************************************/
+uint32 _samr_lookup_domain(const POLICY_HND *connect_pol,
+ const UNISTR2 *uni_domain,
+ DOM_SID *dom_sid)
+{
+ TDB_CONTEXT *sam_tdb = NULL;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_tdbsid(get_global_hnd_cache(), connect_pol, &sam_tdb, NULL))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ {
+ fstring domain;
+ unistr2_to_ascii(domain, uni_domain, sizeof(domain));
+ DEBUG(5, ("Lookup Domain: %s\n", domain));
+ }
+
+ return tdb_lookup_domain(sam_tdb, uni_domain, dom_sid);
+}
+
+/*******************************************************************
+ _samr_close
+ ********************************************************************/
+uint32 _samr_close(POLICY_HND *hnd)
+{
+ /* set up the SAMR unknown_1 response */
+
+ /* close the policy handle */
+ if (close_policy_hnd(get_global_hnd_cache(), hnd))
+ {
+ bzero(hnd, sizeof(*hnd));
+ return NT_STATUS_NOPROBLEMO;
+ }
+ return NT_STATUS_OBJECT_NAME_INVALID;
+}
+
+/*******************************************************************
+ samr_reply_chgpasswd_user
+ ********************************************************************/
+uint32 _samr_chgpasswd_user( const UNISTR2 *uni_dest_host,
+ const UNISTR2 *uni_user_name,
+ const char nt_newpass[516],
+ const uchar nt_oldhash[16],
+ const char lm_newpass[516],
+ const uchar lm_oldhash[16])
+{
+ fstring user_name;
+ fstring wks;
+
+ unistr2_to_ascii(user_name, uni_user_name, sizeof(user_name)-1);
+ unistr2_to_ascii(wks, uni_dest_host, sizeof(wks)-1);
+
+ DEBUG(5,("samr_chgpasswd_user: user: %s wks: %s\n", user_name, wks));
+
+#if 0
+ if (!pass_oem_change(user_name,
+ lm_newpass, lm_oldhash,
+ nt_newpass, nt_oldhash))
+#endif
+ {
+ return NT_STATUS_WRONG_PASSWORD;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+
+/*******************************************************************
+ samr_reply_get_dom_pwinfo
+ ********************************************************************/
+uint32 _samr_get_dom_pwinfo(const UNISTR2 *uni_srv_name,
+ uint16 *unk_0, uint16 *unk_1, uint16 *unk_2)
+{
+ /* absolutely no idea what to do, here */
+ *unk_0 = 0;
+ *unk_1 = 0;
+ *unk_2 = 0;
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_sec_obj
+ ********************************************************************/
+uint32 _samr_query_sec_obj(const POLICY_HND *pol, SEC_DESC_BUF *buf)
+{
+ uint32 rid;
+ DOM_SID usr_sid;
+ DOM_SID adm_sid;
+ DOM_SID glb_sid;
+ TDB_CONTEXT *tdb = NULL;
+ SEC_ACL *dacl = NULL;
+ SEC_ACE *dace = NULL;
+ SEC_ACCESS mask;
+ SEC_DESC *sec = NULL;
+ int len;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbrid(get_global_hnd_cache(), pol, &tdb, NULL, NULL, &rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ dacl = malloc(sizeof(*dacl));
+ dace = malloc(3 * sizeof(*dace));
+ sec = malloc(sizeof(*sec));
+
+ if (dacl == NULL || dace == NULL || sec == NULL)
+ {
+ safe_free(dacl);
+ safe_free(dace);
+ safe_free(sec);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ sid_copy(&usr_sid, &global_sam_sid);
+ sid_append_rid(&usr_sid, rid);
+
+ sid_copy(&adm_sid, &global_sid_S_1_5_20);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&glb_sid, &global_sid_S_1_1);
+ sid_append_rid(&glb_sid, 0x0);
+
+
+ mask.mask = 0x20044;
+ make_sec_ace(&dace[0], &usr_sid, 0, mask, 0);
+ mask.mask = 0xf07ff;
+ make_sec_ace(&dace[1], &adm_sid, 0, mask, 0);
+ mask.mask = 0x2035b;
+ make_sec_ace(&dace[2], &glb_sid, 0, mask, 0);
+
+ make_sec_acl(dacl, 2, 3, dace);
+
+ len = make_sec_desc(sec, 1,
+ SEC_DESC_DACL_PRESENT|SEC_DESC_SELF_RELATIVE,
+ NULL, NULL, NULL, dacl);
+
+ make_sec_desc_buf(buf, len, sec);
+ buf->undoc = 0x1;
+
+ DEBUG(5,("samr_query_sec_obj: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
diff --git a/source/samrd/srv_samr_tdb.c b/source/samrd/srv_samr_tdb.c
new file mode 100644
index 00000000000..bd905f48f17
--- /dev/null
+++ b/source/samrd/srv_samr_tdb.c
@@ -0,0 +1,480 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+typedef struct tdb_dom_info
+{
+ TDB_CONTEXT *usr_tdb;
+ TDB_CONTEXT *usg_tdb;
+ TDB_CONTEXT *usa_tdb;
+ TDB_CONTEXT *grp_tdb;
+ TDB_CONTEXT *als_tdb;
+ DOM_SID sid;
+
+}
+TDB_DOM_INFO;
+
+typedef struct tdb_sid_info
+{
+ TDB_CONTEXT *tdb;
+ DOM_SID sid;
+
+}
+TDB_SID_INFO;
+
+typedef struct tdb_rid_info
+{
+ TDB_CONTEXT *usr_tdb;
+ TDB_CONTEXT *grp_tdb;
+ TDB_CONTEXT *als_tdb;
+ uint32 rid;
+
+}
+TDB_RID_INFO;
+
+typedef struct tdb_sam_info
+{
+ TDB_CONTEXT *tdb;
+
+}
+TDB_SAM_INFO;
+
+static void free_tdbdom_info(void *dev)
+{
+ TDB_DOM_INFO *tdbi = (TDB_DOM_INFO *) dev;
+ DEBUG(10, ("free dom info \n"));
+ if (tdbi->usr_tdb != NULL)
+ {
+ tdb_close(tdbi->usr_tdb);
+ }
+ if (tdbi->usg_tdb != NULL)
+ {
+ tdb_close(tdbi->usg_tdb);
+ }
+ if (tdbi->usa_tdb != NULL)
+ {
+ tdb_close(tdbi->usa_tdb);
+ }
+ if (tdbi->grp_tdb != NULL)
+ {
+ tdb_close(tdbi->grp_tdb);
+ }
+ if (tdbi->als_tdb != NULL)
+ {
+ tdb_close(tdbi->als_tdb);
+ }
+ free(tdbi);
+}
+
+static void free_tdbrid_info(void *dev)
+{
+ TDB_RID_INFO *tdbi = (TDB_RID_INFO *) dev;
+ DEBUG(10, ("free rid info\n"));
+ if (tdbi->usr_tdb != NULL)
+ {
+ tdb_close(tdbi->usr_tdb);
+ }
+ if (tdbi->grp_tdb != NULL)
+ {
+ tdb_close(tdbi->grp_tdb);
+ }
+ if (tdbi->als_tdb != NULL)
+ {
+ tdb_close(tdbi->als_tdb);
+ }
+ free(tdbi);
+}
+
+static void free_tdbsam_info(void *dev)
+{
+ TDB_SAM_INFO *tdbi = (TDB_SAM_INFO *) dev;
+ DEBUG(10, ("free sam info\n"));
+ if (tdbi->tdb != NULL)
+ {
+ tdb_close(tdbi->tdb);
+ }
+ free(tdbi);
+}
+
+static void free_tdbsid_info(void *dev)
+{
+ TDB_SID_INFO *tdbi = (TDB_SID_INFO *) dev;
+ DEBUG(10, ("free policy connection\n"));
+ if (tdbi->tdb != NULL)
+ {
+ tdb_close(tdbi->tdb);
+ }
+ free(tdbi);
+}
+
+/****************************************************************************
+ set samr rid
+****************************************************************************/
+BOOL set_tdbrid(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT * usr_tdb,
+ TDB_CONTEXT * grp_tdb, TDB_CONTEXT * als_tdb, uint32 rid)
+{
+ TDB_RID_INFO *dev = malloc(sizeof(*dev));
+
+ if (dev != NULL)
+ {
+ dev->rid = rid;
+ dev->usr_tdb = usr_tdb;
+ dev->grp_tdb = grp_tdb;
+ dev->als_tdb = als_tdb;
+ if (set_policy_state(cache, hnd, NULL, /*free_tdbrid_info */
+ (void *)dev))
+ {
+ DEBUG(3, ("Service setting policy rid=%x\n", rid));
+ return True;
+ }
+ free(dev);
+ return False;
+ }
+ DEBUG(3, ("Error setting policy rid\n"));
+ return False;
+}
+
+/****************************************************************************
+ get samr rid
+****************************************************************************/
+BOOL get_tdbrid(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT ** usr_tdb,
+ TDB_CONTEXT ** grp_tdb, TDB_CONTEXT ** als_tdb, uint32 * rid)
+{
+ TDB_RID_INFO *dev =
+ (TDB_RID_INFO *) get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ if (rid != NULL)
+ {
+ (*rid) = dev->rid;
+ DEBUG(3, ("Service getting policy rid=%x\n", (*rid)));
+ }
+ if (usr_tdb != NULL)
+ {
+ (*usr_tdb) = dev->usr_tdb;
+ }
+ if (grp_tdb != NULL)
+ {
+ (*grp_tdb) = dev->grp_tdb;
+ }
+ if (als_tdb != NULL)
+ {
+ (*als_tdb) = dev->als_tdb;
+ }
+ return True;
+ }
+
+ DEBUG(3, ("Error getting policy rid\n"));
+ return False;
+}
+
+/****************************************************************************
+ set samr sid
+****************************************************************************/
+BOOL set_tdbsam(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT * tdb)
+{
+ pstring sidstr;
+ TDB_SAM_INFO *dev = malloc(sizeof(*dev));
+
+ if (dev != NULL)
+ {
+ dev->tdb = tdb;
+
+ if (set_policy_state
+ (cache, hnd, free_tdbsam_info, (void *)dev))
+ {
+ DEBUG(3, ("Service setting policy sid=%s\n", sidstr));
+ return True;
+ }
+ free(dev);
+ return False;
+ }
+ DEBUG(3, ("Error setting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ get samr sid
+****************************************************************************/
+BOOL get_tdbsam(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT ** tdb)
+{
+ TDB_SAM_INFO *dev =
+ (TDB_SAM_INFO *) get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ if (tdb != NULL)
+ {
+ (*tdb) = dev->tdb;
+ return (dev->tdb != NULL);
+ }
+ return True;
+ }
+
+ DEBUG(3, ("Error getting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ set samr sid
+****************************************************************************/
+BOOL set_tdbdomsid(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT * usr_tdb,
+ TDB_CONTEXT * usg_tdb,
+ TDB_CONTEXT * usa_tdb,
+ TDB_CONTEXT * grp_tdb,
+ TDB_CONTEXT * als_tdb, const DOM_SID * sid)
+{
+ pstring sidstr;
+ TDB_DOM_INFO *dev;
+
+ dev = malloc(sizeof(*dev));
+
+ DEBUG(3, ("Setting policy sid=%s\n", sid_to_string(sidstr, sid)));
+
+ if (dev != NULL)
+ {
+ sid_copy(&dev->sid, sid);
+ dev->usr_tdb = usr_tdb;
+ dev->usg_tdb = usg_tdb;
+ dev->usa_tdb = usa_tdb;
+ dev->grp_tdb = grp_tdb;
+ dev->als_tdb = als_tdb;
+
+ if (set_policy_state
+ (cache, hnd, free_tdbdom_info, (void *)dev))
+ {
+ DEBUG(3, ("Service setting policy sid=%s\n", sidstr));
+ return True;
+ }
+ free(dev);
+ return False;
+ }
+ DEBUG(3, ("Error setting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ get samr sid
+****************************************************************************/
+BOOL get_tdbdomsid(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT ** usr_tdb,
+ TDB_CONTEXT ** usg_tdb,
+ TDB_CONTEXT ** usa_tdb,
+ TDB_CONTEXT ** grp_tdb,
+ TDB_CONTEXT ** als_tdb, DOM_SID * sid)
+{
+ TDB_DOM_INFO *dev =
+ (TDB_DOM_INFO *) get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ pstring tmp;
+ if (sid != NULL)
+ {
+ sid_copy(sid, &dev->sid);
+ DEBUG(3, ("Getting policy sid=%s\n",
+ sid_to_string(tmp, sid)));
+ }
+ if (usr_tdb != NULL)
+ {
+ (*usr_tdb) = dev->usr_tdb;
+ }
+ if (usg_tdb != NULL)
+ {
+ (*usg_tdb) = dev->usg_tdb;
+ }
+ if (usa_tdb != NULL)
+ {
+ (*usa_tdb) = dev->usa_tdb;
+ }
+ if (grp_tdb != NULL)
+ {
+ (*grp_tdb) = dev->grp_tdb;
+ }
+ if (als_tdb != NULL)
+ {
+ (*als_tdb) = dev->als_tdb;
+ }
+ return True;
+ }
+
+ DEBUG(3, ("Error getting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ set samr sid
+****************************************************************************/
+BOOL set_tdbsid(struct policy_cache *cache, POLICY_HND *hnd,
+ TDB_CONTEXT * tdb, const DOM_SID * sid)
+{
+ pstring sidstr;
+ TDB_SID_INFO *dev;
+
+ dev = malloc(sizeof(*dev));
+
+ DEBUG(3, ("Setting policy sid=%s\n", sid_to_string(sidstr, sid)));
+
+ if (dev != NULL)
+ {
+ sid_copy(&dev->sid, sid);
+ dev->tdb = tdb;
+
+ if (set_policy_state
+ (cache, hnd, free_tdbsid_info, (void *)dev))
+ {
+ DEBUG(3, ("Service setting policy sid=%s\n", sidstr));
+ return True;
+ }
+ free(dev);
+ return False;
+ }
+ DEBUG(3, ("Error setting policy sid\n"));
+ return False;
+}
+
+/****************************************************************************
+ get samr sid
+****************************************************************************/
+BOOL get_tdbsid(struct policy_cache *cache, const POLICY_HND *hnd,
+ TDB_CONTEXT ** tdb, DOM_SID * sid)
+{
+ TDB_SID_INFO *dev =
+ (TDB_SID_INFO *) get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ pstring tmp;
+ if (sid != NULL)
+ {
+ sid_copy(sid, &dev->sid);
+ DEBUG(3, ("Getting policy sid=%s\n",
+ sid_to_string(tmp, sid)));
+ }
+ if (tdb != NULL)
+ {
+ (*tdb) = dev->tdb;
+ return (dev->tdb != NULL);
+ }
+ return True;
+ }
+
+ DEBUG(3, ("Error getting policy sid\n"));
+ return False;
+}
+
+TDB_CONTEXT *open_usr_db(const DOM_SID * sid, uint32 rid, int perms)
+{
+ TDB_CONTEXT *db;
+ pstring tmp;
+ pstring usr;
+
+ sid_to_string(tmp, sid);
+ slprintf(usr, sizeof(usr) - 1, "%s/usr/%x", tmp, rid);
+
+ db = tdb_open(passdb_path(usr), 0, 0, perms, 0644);
+ if (db == NULL)
+ {
+ DEBUG(2,("open_usr_db: open failed, perms: %x\n", perms));
+ }
+ return db;
+}
+
+/*******************************************************************
+ opens a samr entiry by rid, returns a policy handle.
+ ********************************************************************/
+uint32 samr_open_user_tdb(const POLICY_HND *parent_pol,
+ const DOM_SID * sid,
+ TDB_CONTEXT * usr_tdb,
+ POLICY_HND *pol, uint32 ace_perms, uint32 rid)
+{
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ parent_pol, pol, ace_perms))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (usr_tdb == NULL && ace_perms == SEC_RIGHTS_MAXIMUM_ALLOWED)
+ {
+ DEBUG(10, ("samr_open_user_tdb: max perms requested\n"));
+
+ usr_tdb = open_usr_db(sid, rid, O_RDWR);
+ if (usr_tdb == NULL)
+ {
+ usr_tdb = open_usr_db(sid, rid, O_RDONLY);
+ }
+ }
+
+ if (usr_tdb == NULL)
+ {
+ int perms = 0;
+ BOOL perms_read;
+ BOOL perms_write;
+
+ perms_write = IS_BITS_SET_SOME(ace_perms,
+ SEC_RIGHTS_WRITE_OWNER |
+ SEC_RIGHTS_WRITE_DAC);
+ perms_read = IS_BITS_SET_ALL(ace_perms, SEC_RIGHTS_READ_CONTROL);
+
+ DEBUG(10,("_samr_open_user: read: %s ", BOOLSTR(perms_read)));
+ DEBUG(10,("write: %s\n", BOOLSTR(perms_write)));
+
+ if (perms_write)
+ perms = O_WRONLY;
+ if (perms_read)
+ perms = O_RDONLY;
+ if (perms_write && perms_read)
+ perms = O_RDWR;
+
+ usr_tdb = open_usr_db(sid, rid, perms);
+ }
+
+ if (usr_tdb == NULL)
+ {
+ close_policy_hnd(get_global_hnd_cache(), pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* associate a SID with the (unique) handle. */
+ if (!set_tdbsam(get_global_hnd_cache(), pol, usr_tdb))
+ {
+ /* close the policy in case we can't associate a group SID */
+ close_policy_hnd(get_global_hnd_cache(), pol);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
diff --git a/source/samrd/srv_samr_tdb_init.c b/source/samrd/srv_samr_tdb_init.c
new file mode 100644
index 00000000000..1ff3c7dd44b
--- /dev/null
+++ b/source/samrd/srv_samr_tdb_init.c
@@ -0,0 +1,182 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+uint32 initialise_dom_tdb(const DOM_SID * sid)
+{
+ pstring usr;
+ pstring grp;
+ pstring als;
+ fstring tmp;
+ uint32 rid = 999;
+ uint32 k = 0;
+ prs_struct key;
+ prs_struct data;
+ TDB_CONTEXT *dom_tdb;
+
+ sid_to_string(tmp, sid);
+
+ mkdir(passdb_path(tmp), 0755);
+
+ slprintf(usr, sizeof(usr) - 1, "%s/usr", tmp);
+ mkdir(passdb_path(usr), 0755);
+
+ slprintf(grp, sizeof(grp) - 1, "%s/grp", tmp);
+ mkdir(passdb_path(grp), 0755);
+
+ slprintf(als, sizeof(als) - 1, "%s/als", tmp);
+ mkdir(passdb_path(als), 0755);
+
+ safe_strcat(tmp, "/dom.tdb", sizeof(tmp)-1);
+ dom_tdb = tdb_open(passdb_path(tmp), 0, 0, O_RDWR, 0600);
+ if (dom_tdb != NULL)
+ {
+ tdb_close(dom_tdb);
+ return NT_STATUS_NOPROBLEMO;
+ }
+
+ dom_tdb = tdb_open(passdb_path(tmp), 0, 0, O_RDWR|O_CREAT, 0644);
+
+ if (dom_tdb == NULL)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!_prs_uint32("key", &key, 0, &k) ||
+ !_prs_uint32("rid", &data, 0, &rid) ||
+ prs_tdb_store(dom_tdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ tdb_close(dom_tdb);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ tdb_close(dom_tdb);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+static BOOL create_domain(TDB_CONTEXT * tdb, const char *domain,
+ const DOM_SID * sid)
+{
+ prs_struct key;
+ prs_struct data;
+ UNISTR2 uni_domain;
+ DOM_SID s;
+
+ sid_copy(&s, sid);
+
+ DEBUG(10, ("creating domain %s\n", domain));
+
+ make_unistr2(&uni_domain, domain, strlen(domain));
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!smb_io_unistr2("dom", &uni_domain, True, &key, 0) ||
+ !smb_io_dom_sid("sid", &s, &data, 0) ||
+ prs_tdb_store(tdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+static uint32 init_dom_tdbs(const DOM_SID * sam_sid)
+{
+ uint32 status;
+
+ DEBUG(0,
+ ("initialise_dom_tdb: TODO - create BUILTIN domain aliases\n"));
+
+ status = initialise_dom_tdb(sam_sid);
+ if (status != 0x0)
+ return status;
+ status = initialise_dom_tdb(&global_sid_S_1_5_20);
+ return status;
+}
+
+/***************************************************************************
+ create various sam tdb databases, initialising them as necessary.
+ ***************************************************************************/
+uint32 initialise_sam_tdb(const char *sam_name, const DOM_SID * sam_sid)
+{
+ pstring srv_db_name;
+ fstring dom_name;
+ TDB_CONTEXT *sam_tdb;
+
+ sam_tdb = tdb_open(passdb_path("sam.tdb"), 0, 0, O_RDWR, 0644);
+
+ if (sam_tdb != NULL)
+ {
+ tdb_close(sam_tdb);
+ return init_dom_tdbs(sam_sid);
+ }
+
+ DEBUG(0, ("initialise_sam_tdb: creating %s\n", srv_db_name));
+
+ /* create if not-exist with root-readwrite, all others read */
+ sam_tdb =
+ tdb_open(passdb_path("sam.tdb"), 0, 0, O_RDWR | O_CREAT,
+ 0644);
+
+ if (sam_tdb == NULL)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ fstrcpy(dom_name, sam_name);
+ strupper(dom_name);
+
+ if (!create_domain(sam_tdb, sam_name, sam_sid) ||
+ !create_domain(sam_tdb, "BUILTIN", &global_sid_S_1_5_20))
+ {
+ tdb_close(sam_tdb);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ tdb_close(sam_tdb);
+ return init_dom_tdbs(sam_sid);
+}
+
+BOOL pwdbsam_initialise(void)
+{
+ return initialise_sam_tdb(global_sam_name, &global_sam_sid) ==
+ NT_STATUS_NOPROBLEMO;
+}
diff --git a/source/samrd/srv_samr_usr_nt5ldap.c b/source/samrd/srv_samr_usr_nt5ldap.c
new file mode 100644
index 00000000000..e6cecb6a921
--- /dev/null
+++ b/source/samrd/srv_samr_usr_nt5ldap.c
@@ -0,0 +1,809 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000
+ * Copyright (C) Luke Howard 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+
+#ifdef WITH_NT5LDAP
+
+#include "nterr.h"
+#include "sids.h"
+#include "ldapdb.h"
+
+extern int DEBUGLEVEL;
+
+static BOOL nt5ldap_lookup_user(LDAPDB *hds,
+ uint32 rid,
+ SAM_USER_INFO_21 *usr)
+{
+ if (!ldapdb_lookup_by_rid(hds, rid))
+ {
+ return False;
+ }
+
+ return nt5ldap_make_sam_user_info21(hds, usr);
+}
+
+static BOOL nt5ldap_set_userinfo_16(LDAPDB *hds, uint32 rid,
+ uint16 acb_info)
+{
+ LDAPMod **mods = NULL;
+ pstring dn;
+
+ if (!ldapdb_rid_to_dn(hds, rid, dn))
+ {
+ return False;
+ }
+
+ if (!ldapdb_queue_uint32_mod(&mods, LDAP_MOD_REPLACE, "userAccountControl",
+ pwdb_acct_ctrl_to_ad(acb_info)))
+ {
+ return False;
+ }
+
+ return ldapdb_commit(hds, dn, mods, False);
+}
+
+static BOOL nt5ldap_set_userinfo_24(LDAPDB *hds, uint32 rid,
+ const uchar lm_pwd[16], const uchar nt_pwd[16])
+{
+ LDAPMod **mods = NULL;
+ pstring dn;
+ struct berval *bv;
+
+ if (!ldapdb_rid_to_dn(hds, rid, dn))
+ {
+ return False;
+ }
+
+ if (dbcspwd_to_berval(lm_pwd, &bv))
+ {
+ if (!ldapdb_queue_mod_len(&mods, LDAP_MOD_REPLACE, "dBCSPwd", bv))
+ {
+ ber_bvfree(bv);
+ return False;
+ }
+ }
+
+ if (unicodepwd_to_berval(nt_pwd, &bv))
+ {
+ if (!ldapdb_queue_mod_len(&mods, LDAP_MOD_REPLACE, "unicodePwd", bv))
+ {
+ ber_bvfree(bv);
+ return False;
+ }
+ }
+
+ return ldapdb_commit(hds, dn, mods, False);
+}
+
+static BOOL nt5ldap_set_userinfo_23(LDAPDB *hds, uint32 rid,
+ const SAM_USER_INFO_23 *usr23,
+ const uchar lm_pwd[16], const uchar nt_pwd[16])
+{
+ SAM_USER_INFO_21 usr;
+ LDAPMod **mods = NULL;
+ fstring dn;
+
+ if (!ldapdb_rid_to_dn(hds, rid, dn))
+ {
+ return False;
+ }
+
+ if (!make_sam_user_info21W(&usr,
+ &usr23->logon_time,
+ &usr23->logoff_time,
+ &usr23->kickoff_time,
+ &usr23->pass_last_set_time,
+ &usr23->pass_can_change_time,
+ &usr23->pass_must_change_time,
+
+ &usr23->uni_user_name,
+ &usr23->uni_full_name,
+ &usr23->uni_home_dir,
+ &usr23->uni_dir_drive,
+ &usr23->uni_logon_script,
+ &usr23->uni_profile_path,
+ &usr23->uni_acct_desc,
+ &usr23->uni_workstations,
+ &usr23->uni_unknown_str,
+ &usr23->uni_munged_dial,
+
+ lm_pwd, nt_pwd,
+
+ usr.user_rid,
+ usr23->group_rid,
+ usr23->acb_info,
+
+ usr.unknown_3,
+ usr23->logon_divs,
+ &usr23->logon_hrs,
+ usr23->unknown_5,
+ usr.unknown_6))
+ {
+ return False;
+ }
+
+ DEBUG(10,("storing user %x\n", rid));
+
+ if (!nt5ldap_sam_user_info21_mods(&usr, &mods, LDAP_MOD_REPLACE, NULL, 0, NULL))
+ {
+ return False;
+ }
+
+ return ldapdb_commit(hds, dn, mods, False);
+}
+
+/*******************************************************************
+ samr_reply_get_usrdom_pwinfo
+ ********************************************************************/
+uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
+ uint32 *unknown_0,
+ uint32 *unknown_1)
+{
+ uint32 rid;
+ LDAPDB *hds = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_nt5ldaprid(get_global_hnd_cache(), user_pol, &hds, &rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ *unknown_0 = 0x00150000;
+ *unknown_1 = 0x00000000;
+
+ DEBUG(5,("samr_get_usrdom_pwinfo: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_sec_obj
+ ********************************************************************/
+uint32 _samr_query_sec_obj(const POLICY_HND *pol, SEC_DESC_BUF *buf)
+{
+ uint32 rid;
+ DOM_SID usr_sid;
+ DOM_SID adm_sid;
+ DOM_SID glb_sid;
+ SEC_ACL *dacl = NULL;
+ SEC_ACE *dace = NULL;
+ SEC_ACCESS mask;
+ SEC_DESC *sec = NULL;
+ int len;
+
+ LDAPDB *hds = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_nt5ldaprid(get_global_hnd_cache(), user_pol, &hds, &rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_copy(&usr_sid, &global_sam_sid);
+ sid_append_rid(&usr_sid, rid);
+
+ sid_copy(&adm_sid, &global_sid_S_1_5_20);
+ sid_append_rid(&adm_sid, BUILTIN_ALIAS_RID_ADMINS);
+
+ sid_copy(&glb_sid, &global_sid_S_1_1);
+ sid_append_rid(&glb_sid, 0x0);
+
+ dacl = malloc(sizeof(*dacl));
+ dace = malloc(3 * sizeof(*dace));
+ sec = malloc(sizeof(*sec));
+
+ if (dacl == NULL || dace == NULL || sec == NULL)
+ {
+ safe_free(dacl);
+ safe_free(dace);
+ safe_free(sec);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+
+ mask.mask = 0x20044;
+ make_sec_ace(&dace[0], &usr_sid , 0, mask, 0);
+ mask.mask = 0xf07ff;
+ make_sec_ace(&dace[1], &adm_sid , 0, mask, 0);
+ mask.mask = 0x2035b;
+ make_sec_ace(&dace[2], &glb_sid, 0, mask, 0);
+
+ make_sec_acl(dacl, 2, 3, dace);
+
+ len = make_sec_desc(sec, 1,
+ SEC_DESC_DACL_PRESENT|SEC_DESC_SELF_RELATIVE,
+ NULL, NULL, NULL, dacl);
+
+ make_sec_desc_buf(buf, len, sec);
+ buf->undoc = 0x1;
+
+ DEBUG(5,("samr_query_sec_obj: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_usergroups
+ ********************************************************************/
+uint32 _samr_query_usergroups(const POLICY_HND *pol,
+ uint32 *num_groups,
+ DOM_GID **gids)
+{
+ DOMAIN_GRP *mem_grp = NULL;
+ struct sam_passwd *sam_pass = NULL;
+ uint32 rid;
+ BOOL ret = False;
+ LDAPDB *hds = NULL;
+
+ DEBUG(5,("samr_query_usergroups: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_nt5ldaprid(get_global_hnd_cache(), pol, &hds, &rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ become_root(True);
+#if 0
+ sam_pass = getsam21pwrid(rid);
+#endif
+ unbecome_root(True);
+
+ if (sam_pass == NULL)
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ become_root(True);
+#if 0
+ ret = getusergroupsntnam(sam_pass->nt_name, &mem_grp, num_groups);
+#endif
+ unbecome_root(True);
+
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ (*gids) = NULL;
+#if 0
+ (*num_groups) = make_dom_gids(mem_grp, *num_groups, gids);
+#endif
+
+ if (mem_grp != NULL)
+ {
+ free(mem_grp);
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+/*******************************************************************
+ samr_reply_query_useraliases
+ ********************************************************************/
+uint32 _samr_query_useraliases(const POLICY_HND *pol,
+ const uint32 *ptr_sid, const DOM_SID2 *sid,
+ uint32 *num_aliases, uint32 **rid)
+{
+ LDAPDB *hds = NULL;
+ LOCAL_GRP *mem_grp = NULL;
+ int num_rids = 0;
+ uint32 user_rid;
+
+ DEBUG(5,("samr_query_useraliases: %d\n", __LINE__));
+
+ (*rid) = NULL;
+ (*num_aliases) = 0;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_nt5ldaprid(get_global_hnd_cache(), pol, &hds, &user_rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* find the user account */
+
+#if 0
+ if (sid_equal(&dom_sid, &global_sid_S_1_5_20))
+ {
+ BOOL ret;
+ DEBUG(10,("lookup on S-1-5-20\n"));
+
+ become_root(True);
+ ret = getuserbuiltinntnam(sam_pass->nt_name, &mem_grp,
+ &num_rids);
+ unbecome_root(True);
+
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+ else if (sid_equal(&dom_sid, &usr_sid))
+ {
+ BOOL ret;
+ DEBUG(10,("lookup on Domain SID\n"));
+
+ become_root(True);
+ ret = getuseraliasntnam(sam_pass->nt_name, &mem_grp,
+ &num_rids);
+ unbecome_root(True);
+
+ if (!ret)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ }
+#endif
+ else
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+ if (num_rids > 0)
+ {
+ (*rid) = malloc(num_rids * sizeof(uint32));
+ if (mem_grp != NULL && (*rid) != NULL)
+ {
+ int i;
+ for (i = 0; i < num_rids; i++)
+ {
+ (*rid)[i] = mem_grp[i].rid;
+ }
+ }
+ }
+
+ (*num_aliases) = num_rids;
+ safe_free(mem_grp);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_open_user
+ ********************************************************************/
+uint32 _samr_open_user(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 user_rid,
+ POLICY_HND *user_pol)
+{
+ LDAPDB *hds = NULL;
+ DOM_SID dom_sid;
+ SAM_USER_INFO_21 usr;
+
+ if (!get_nt5ldapdomsid(get_global_hnd_cache(), domain_pol,
+ &hds, NULL, NULL, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!nt5ldap_lookup_user(hds, user_rid, &usr))
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ return samr_open_by_nt5ldaprid(hds, domain_pol,
+ user_pol, access_mask, user_rid);
+}
+
+/*******************************************************************
+ samr_reply_query_userinfo
+ ********************************************************************/
+uint32 _samr_query_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr)
+{
+ LDAPDB *hds = NULL;
+ uint32 rid = 0x0;
+ SAM_USER_INFO_21 usr;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_nt5ldaprid(get_global_hnd_cache(), pol, &hds, &rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ if (!nt5ldap_lookup_user(hds, rid, &usr))
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ DEBUG(5,("samr_reply_query_userinfo: rid:0x%x\n", rid));
+
+ return make_samr_userinfo_ctr_usr21(ctr, switch_value, &usr);
+}
+
+/*******************************************************************
+ set_user_info_24
+ ********************************************************************/
+static BOOL set_user_info_24(LDAPDB *hds, uint32 rid,
+ const SAM_USER_INFO_24 *id24)
+{
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+ UNISTR2 new_pw;
+ uint32 len;
+
+ if (!decode_pw_buffer(id24->pass, (char *)new_pw.buffer, 256, &len))
+ {
+ return False;
+ }
+
+ new_pw.uni_max_len = len / 2;
+ new_pw.uni_str_len = len / 2;
+
+ nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
+
+ return nt5ldap_set_userinfo_24(hds, rid, lm_hash, nt_hash);
+}
+
+/*******************************************************************
+ set_user_info_23
+ ********************************************************************/
+static BOOL set_user_info_23(LDAPDB *hds, uint32 rid,
+ const SAM_USER_INFO_23 *id23)
+{
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+ UNISTR2 new_pw;
+ uint32 len;
+
+ if (id23 == NULL)
+ {
+ DEBUG(5, ("set_user_info_23: NULL id23\n"));
+ return False;
+ }
+
+ if (!decode_pw_buffer(id23->pass, (char*)new_pw.buffer, 256, &len))
+ {
+ return False;
+ }
+
+ new_pw.uni_max_len = len / 2;
+ new_pw.uni_str_len = len / 2;
+
+ nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
+
+ return nt5ldap_set_userinfo_23(hds, rid, id23, lm_hash, nt_hash);
+}
+
+/*******************************************************************
+ samr_reply_set_userinfo
+ ********************************************************************/
+uint32 _samr_set_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr)
+{
+ LDAPDB *hds = NULL;
+ uchar user_sess_key[16];
+ uint32 rid = 0x0;
+
+ DEBUG(5,("samr_reply_set_userinfo: %d\n", __LINE__));
+
+ /* find the domain rid associated with the policy handle */
+ if (!get_nt5ldaprid(get_global_hnd_cache(), pol, &hds, &rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_set_userinfo: rid:0x%x\n", rid));
+
+ if (!pol_get_usr_sesskey(get_global_hnd_cache(), pol, user_sess_key))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (ctr == NULL)
+ {
+ DEBUG(5,("samr_reply_set_userinfo: NULL info level\n"));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ /* ok! user info levels (lots: see MSDEV help), off we go... */
+ switch (switch_value)
+ {
+ case 24:
+ {
+ SAM_USER_INFO_24 *id24 = ctr->info.id24;
+ SamOEMhash(id24->pass, user_sess_key, True);
+ if (!set_user_info_24(hds, rid, id24))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+
+ case 23:
+ {
+ SAM_USER_INFO_23 *id23 = ctr->info.id23;
+ SamOEMhash(id23->pass, user_sess_key, 1);
+ dump_data_pw("pass buff:\n",
+ id23->pass, sizeof(id23->pass));
+ dbgflush();
+
+ if (!set_user_info_23(hds, rid, id23))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ set_user_info_16
+ ********************************************************************/
+static BOOL set_user_info_16(LDAPDB *hds, uint32 rid,
+ const SAM_USER_INFO_16 *id16)
+{
+ return nt5ldap_set_userinfo_16(hds, rid, id16->acb_info);
+}
+
+/*******************************************************************
+ samr_reply_set_userinfo2
+ ********************************************************************/
+uint32 _samr_set_userinfo2(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR *ctr)
+{
+ LDAPDB *hds = NULL;
+ uint32 rid = 0x0;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_nt5ldaprid(get_global_hnd_cache(), pol, &hds, &rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5,("samr_reply_set_userinfo2: rid:0x%x\n", rid));
+
+ if (ctr == NULL)
+ {
+ DEBUG(5,("samr_reply_set_userinfo2: NULL info level\n"));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ ctr->switch_value = switch_value;
+
+ /* ok! user info levels (lots: see MSDEV help), off we go... */
+ switch (switch_value)
+ {
+ case 16:
+ {
+ SAM_USER_INFO_16 *id16 = ctr->info.id16;
+ if (!set_user_info_16(hds, rid, id16))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+static void create_user_info_21(SAM_USER_INFO_21 *usr,
+ const UNISTR2 *uni_user_name,
+ uint16 acb_info, uint32 user_rid,
+ uint32 group_rid)
+{
+ time_t t = time(NULL);
+
+ ZERO_STRUCTP(usr);
+
+ init_nt_time(&usr->logon_time);
+ init_nt_time(&usr->logoff_time);
+ init_nt_time(&usr->kickoff_time);
+ init_nt_time(&usr->pass_can_change_time);
+ unix_to_nt_time(&usr->pass_last_set_time, t);
+ unix_to_nt_time(&usr->pass_must_change_time, t);
+
+ usr->acb_info = acb_info | ACB_DISABLED | ACB_PWNOTREQ;
+ usr->user_rid = user_rid;
+ usr->group_rid = group_rid;
+
+ copy_unistr2(&usr->uni_user_name, uni_user_name);
+ make_uni_hdr(&usr->hdr_user_name, uni_user_name->uni_str_len);
+
+ usr->unknown_3 = 0xffffff; /* don't know */
+ usr->logon_divs = 168; /* hours per week */
+ usr->ptr_logon_hrs = 1;
+ usr->logon_hrs.len = 21;
+ memset(&usr->logon_hrs.hours, 0xff, sizeof(usr->logon_hrs.hours));
+ usr->unknown_5 = 0x00020000; /* don't know */
+ usr->unknown_6 = 0x000004ec; /* don't know */
+}
+
+/*******************************************************************
+ _samr_create_user
+ ********************************************************************/
+uint32 _samr_create_user(const POLICY_HND *domain_pol,
+ const UNISTR2 *uni_username,
+ uint16 acb_info, uint32 access_mask,
+ POLICY_HND *user_pol,
+ uint32 *unknown_0, uint32 *user_rid)
+{
+ DOM_SID dom_sid;
+ DOM_SID usr_sid;
+ DOM_SID grp_sid;
+ LDAPDB *hds = NULL;
+
+ LDAPMod **mods = NULL;
+ fstring rdn;
+ BOOL iscomputer;
+ char *container;
+
+ SAM_USER_INFO_21 usr;
+ uint32 status1;
+ uint32 rid;
+ uint32 type;
+ uint32 num_rids;
+ uint32 num_types;
+
+ struct passwd *pass = NULL;
+ uint32 group_rid;
+
+ (*unknown_0) = 0x30;
+ (*user_rid) = 0x0;
+
+ /* find the machine account: tell the caller if it exists.
+ lkclXXXX i have *no* idea if this is a problem or not
+ or even if you are supposed to construct a different
+ reply if the account already exists...
+ */
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_nt5ldapdomsid(get_global_hnd_cache(), domain_pol,
+ &hds, NULL, NULL, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ status1 = _samr_lookup_names(domain_pol, 1, 0x3e8, 1, uni_username,
+
+ &num_rids,
+ &rid,
+ &num_types,
+ &type);
+
+ if (status1 == NT_STATUS_NOPROBLEMO)
+ {
+ switch (type)
+ {
+ case SID_NAME_USER: return NT_STATUS_USER_EXISTS;
+ case SID_NAME_ALIAS: return NT_STATUS_ALIAS_EXISTS;
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP: return NT_STATUS_GROUP_EXISTS;
+ case SID_NAME_DOMAIN: return NT_STATUS_DOMAIN_EXISTS;
+ default:
+ {
+ DEBUG(3,("create user: unknown, ignoring\n"));
+ break;
+ }
+ }
+ }
+
+ {
+ fstring user_name;
+ unistr2_to_ascii(user_name, uni_username, sizeof(user_name)-1);
+ pass = Get_Pwnam(user_name, False);
+ DEBUG(10,("create user: %s\n", user_name));
+ if (pass == NULL)
+ {
+ DEBUG(0,("create user: no unix user named %s\n",
+ user_name));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ }
+
+ /* create a User SID for the unix user */
+ if (!surs_unixid_to_sam_sid(hds, pass->pw_uid, SID_NAME_USER, &usr_sid,
+ True))
+ {
+ DEBUG(0,("create user: unix uid %d to RID failed\n",
+ pass->pw_uid));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* create a Group SID for the unix user */
+ if (!surs_unixid_to_sam_sid(hds, pass->pw_gid, SID_NAME_DOM_GRP, &grp_sid,
+ True))
+ {
+ DEBUG(0,("create user: unix uid %d to RID failed\n",
+ pass->pw_uid));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ /* Get those posixAccount attributes in. Of course, SURS needs to use them. */
+ if (!ldapdb_queue_uint32_mod(&mods, LDAP_MOD_ADD, "gidNumber", pass->pw_gid) ||
+ !ldapdb_queue_uint32_mod(&mods, LDAP_MOD_ADD, "uidNumber", pass->pw_uid) ||
+ !ldapdb_queue_mod (&mods, LDAP_MOD_ADD, "uid", pass->pw_name) ||
+ !ldapdb_queue_mod (&mods, LDAP_MOD_ADD, "mSSFUName", pass->pw_name) ||
+ !ldapdb_queue_mod (&mods, LDAP_MOD_ADD, "gECOS", pass->pw_gecos) ||
+ !ldapdb_queue_mod (&mods, LDAP_MOD_ADD, "loginShell", pass->pw_shell) ||
+ !ldapdb_queue_mod (&mods, LDAP_MOD_ADD, "objectClass", "posixAccount"))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!sid_split_rid(&usr_sid, user_rid) ||
+ !sid_equal(&dom_sid, &usr_sid))
+ {
+ fstring tmp;
+ DEBUG(0,("create user: invalid User SID %s\n",
+ sid_to_string(tmp, &usr_sid)));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!sid_split_rid(&grp_sid, &group_rid) ||
+ !sid_equal(&dom_sid, &grp_sid))
+ {
+ fstring tmp;
+ DEBUG(0,("create user: invalid Group SID %s\n",
+ sid_to_string(tmp, &grp_sid)));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ create_user_info_21(&usr, uni_username, acb_info,
+ (*user_rid), group_rid);
+
+ DEBUG(10,("storing user %x\n", rid));
+
+ if (!nt5ldap_sam_user_info21_mods(&usr, &mods, LDAP_MOD_ADD, rdn, sizeof(rdn)-1, &iscomputer))
+ {
+ /* account doesn't exist: say so */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ container = iscomputer ? lp_ldap_computers_subcontext() : lp_ldap_users_subcontext();
+ if (!ldapdb_update(hds, container, "cn", rdn, mods, True))
+ {
+ /* account doesn't exist: say so */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ *unknown_0 = 0x000703ff;
+
+ return samr_open_by_nt5ldaprid(hds, domain_pol,
+ user_pol, access_mask, *user_rid);
+}
+
+/*******************************************************************
+ samr_reply_delete_dom_user
+ ********************************************************************/
+uint32 _samr_delete_dom_user(POLICY_HND *user_pol)
+{
+ DEBUG(0,("samr_delete_dom_user: not implemented\n"));
+ return NT_STATUS_ACCESS_DENIED;
+}
+
+#endif /* WITH_NT5LDAP */
+
diff --git a/source/samrd/srv_samr_usr_tdb.c b/source/samrd/srv_samr_usr_tdb.c
new file mode 100644
index 00000000000..81533b938b3
--- /dev/null
+++ b/source/samrd/srv_samr_usr_tdb.c
@@ -0,0 +1,1000 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+#include "sids.h"
+
+extern int DEBUGLEVEL;
+
+#if 0
+static BOOL tdb_lookup_user_als(TDB_CONTEXT * tdb,
+ const DOM_SID * sid,
+ uint32 * num_rids, uint32 ** rids)
+{
+ prs_struct key;
+ prs_struct data;
+ DOM_SID s;
+ sid_copy(&s, sid);
+
+ prs_init(&key, 0, 4, False);
+ if (!smb_io_dom_sid("sid", &s, &key, 0))
+ {
+ return False;
+ }
+
+ prs_tdb_fetch(tdb, &key, &data);
+
+ if (!samr_io_rids("rids", num_rids, rids, &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+static BOOL tdb_lookup_user_grps(TDB_CONTEXT * tdb,
+ uint32 rid,
+ uint32 * num_gids, DOM_GID ** gids)
+{
+ prs_struct key;
+ prs_struct data;
+
+ prs_init(&key, 0, 4, False);
+ if (!_prs_uint32("rid", &key, 0, &rid))
+ {
+ return False;
+ }
+
+ prs_tdb_fetch(tdb, &key, &data);
+
+ if (!samr_io_gids("grps", num_gids, gids, &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+#endif
+BOOL tdb_lookup_user(TDB_CONTEXT * tdb, SAM_USER_INFO_21 * usr)
+{
+ prs_struct key;
+ prs_struct data;
+ uint8 k = 0;
+
+ prs_init(&key, 0, 4, False);
+ if (!_prs_uint8("usr", &key, 0, &k))
+ {
+ return False;
+ }
+
+ prs_tdb_fetch(tdb, &key, &data);
+
+ if (!sam_io_user_info21("usr", usr, &data, 0))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ return True;
+}
+
+#if 0
+static BOOL tdb_store_user_grps(TDB_CONTEXT * tdb,
+ uint32 rid, uint32 num_gids, DOM_GID * gids)
+{
+ prs_struct key;
+ prs_struct data;
+
+ DEBUG(10, ("storing user group GIDs %x\n", rid));
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!_prs_uint32("rid", &key, 0, &rid) ||
+ !samr_io_gids("grps", &num_gids, &gids, &data, 0) ||
+ prs_tdb_store(tdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+static BOOL tdb_store_user_als(TDB_CONTEXT * tdb,
+ const DOM_SID * sid,
+ uint32 num_rids, uint32 * rids)
+{
+ prs_struct key;
+ prs_struct data;
+ fstring tmp;
+ DOM_SID s;
+ sid_copy(&s, sid);
+
+ if (DEBUGLVL(10))
+ {
+ DEBUG(10, ("storing user alias RIDs %s\n",
+ sid_to_string(tmp, sid)));
+ }
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!smb_io_dom_sid("sid", &s, &key, 0) ||
+ !samr_io_rids("rids", &num_rids, &rids, &data, 0) ||
+ prs_tdb_store(tdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+#endif
+
+static BOOL tdb_store_user(TDB_CONTEXT * tdb, SAM_USER_INFO_21 * usr)
+{
+ prs_struct key;
+ prs_struct data;
+ uint8 k = 0;
+
+ prs_init(&key, 0, 4, False);
+ prs_init(&data, 0, 4, False);
+
+ if (!_prs_uint8("usr", &key, 0, &k) ||
+ !sam_io_user_info21("usr", usr, &data, 0) ||
+ prs_tdb_store(tdb, TDB_REPLACE, &key, &data) != 0)
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return False;
+ }
+
+ prs_free_data(&key);
+ prs_free_data(&data);
+ return True;
+}
+
+static BOOL tdb_set_userinfo_10(TDB_CONTEXT * tdb, uint16 acb_info)
+{
+ SAM_USER_INFO_21 usr;
+
+ if (tdb_writelock(tdb) != 0)
+ {
+ return False;
+ }
+
+ if (!tdb_lookup_user(tdb, &usr))
+ {
+ tdb_writeunlock(tdb);
+ return False;
+ }
+
+ usr.acb_info = acb_info;
+
+ if (!tdb_store_user(tdb, &usr))
+ {
+ tdb_writeunlock(tdb);
+ return False;
+ }
+
+ tdb_writeunlock(tdb);
+ return True;
+}
+
+static BOOL tdb_set_userinfo_pwds(TDB_CONTEXT * tdb,
+ const uchar lm_pwd[16],
+ const uchar nt_pwd[16])
+{
+ SAM_USER_INFO_21 usr;
+
+ if (tdb_writelock(tdb) != 0)
+ {
+ DEBUG(5, ("tdb_set_userinfo_pwds: write lock failed\n"));
+ return False;
+ }
+
+ if (!tdb_lookup_user(tdb, &usr))
+ {
+ tdb_writeunlock(tdb);
+ return False;
+ }
+
+ memcpy(usr.lm_pwd, lm_pwd, sizeof(usr.lm_pwd));
+ memcpy(usr.nt_pwd, nt_pwd, sizeof(usr.nt_pwd));
+
+ if (!tdb_store_user(tdb, &usr))
+ {
+ tdb_writeunlock(tdb);
+ return False;
+ }
+
+ tdb_writeunlock(tdb);
+ return True;
+}
+
+static BOOL tdb_set_userinfo_23(TDB_CONTEXT * tdb,
+ const SAM_USER_INFO_23 * usr23,
+ const uchar lm_pwd[16],
+ const uchar nt_pwd[16])
+{
+ SAM_USER_INFO_21 usr;
+
+ if (tdb_writelock(tdb) != 0)
+ {
+ return False;
+ }
+
+ if (!tdb_lookup_user(tdb, &usr))
+ {
+ tdb_writeunlock(tdb);
+ return False;
+ }
+
+ if (!make_sam_user_info21W(&usr,
+ &usr23->logon_time,
+ &usr23->logoff_time,
+ &usr23->kickoff_time,
+ &usr23->pass_last_set_time,
+ &usr23->pass_can_change_time,
+ &usr23->pass_must_change_time,
+ &usr23->uni_user_name,
+ &usr23->uni_full_name,
+ &usr23->uni_home_dir,
+ &usr23->uni_dir_drive,
+ &usr23->uni_logon_script,
+ &usr23->uni_profile_path,
+ &usr23->uni_acct_desc,
+ &usr23->uni_workstations,
+ &usr23->uni_unknown_str,
+ &usr23->uni_munged_dial,
+ lm_pwd, nt_pwd,
+ usr.user_rid,
+ usr23->group_rid,
+ usr23->acb_info,
+ usr.unknown_3,
+ usr23->logon_divs,
+ &usr23->logon_hrs,
+ usr23->unknown_5, usr.unknown_6))
+ {
+ tdb_writeunlock(tdb);
+ return False;
+ }
+
+ if (!tdb_store_user(tdb, &usr))
+ {
+ tdb_writeunlock(tdb);
+ return False;
+ }
+
+ tdb_writeunlock(tdb);
+ return True;
+}
+
+/*******************************************************************
+ samr_reply_get_usrdom_pwinfo
+ ********************************************************************/
+uint32 _samr_get_usrdom_pwinfo(const POLICY_HND *user_pol,
+ uint32 * unknown_0, uint32 * unknown_1)
+{
+ uint32 rid;
+ TDB_CONTEXT *tdb = NULL;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbrid(get_global_hnd_cache(), user_pol, &tdb,
+ NULL, NULL, &rid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ *unknown_0 = 0x00150000;
+ *unknown_1 = 0x00000000;
+
+ DEBUG(5, ("samr_get_usrdom_pwinfo: %d\n", __LINE__));
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_usergroups
+ ********************************************************************/
+uint32 _samr_query_usergroups(const POLICY_HND *pol,
+ uint32 * num_groups, DOM_GID ** gids)
+{
+#if 0
+ uint32 rid;
+#endif
+ TDB_CONTEXT *usr_tdb = NULL;
+
+ (*gids) = NULL;
+ (*num_groups) = 0;
+
+ DEBUG(5, ("samr_query_usergroups: %d\n", __LINE__));
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbsam(get_global_hnd_cache(), pol, &usr_tdb))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+#if 0
+ if (!tdb_lookup_user_grps(usg_tdb, rid, num_groups, gids))
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+#endif
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_query_useraliases
+ ********************************************************************/
+uint32 _samr_query_useraliases(const POLICY_HND *domain_pol,
+ const uint32 * ptr_sid, const DOM_SID2 * sid,
+ uint32 * num_aliases, uint32 ** rid)
+{
+#if 0
+ TDB_CONTEXT *tdb = NULL;
+ DOM_SID dom_sid;
+#endif
+
+ DEBUG(5, ("samr_query_useraliases: %d\n", __LINE__));
+
+ (*rid) = NULL;
+ (*num_aliases) = 0;
+
+ if (sid == NULL)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+#if 0
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbsam(get_global_hnd_cache(), domain_pol,
+ NULL, NULL, &tdb, NULL, NULL, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!tdb_lookup_user_als(tdb, &sid->sid, num_aliases, rid))
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+#endif
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ samr_reply_open_user
+ ********************************************************************/
+uint32 _samr_open_user(const POLICY_HND *domain_pol,
+ uint32 access_mask, uint32 user_rid,
+ POLICY_HND *user_pol)
+{
+ DOM_SID dom_sid;
+
+ if (!get_tdbdomsid(get_global_hnd_cache(), domain_pol,
+ NULL, NULL, NULL, NULL, NULL, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ return samr_open_user_tdb(domain_pol, &dom_sid, NULL,
+ user_pol, access_mask, user_rid);
+}
+
+/*******************************************************************
+ samr_reply_query_userinfo
+ ********************************************************************/
+uint32 _samr_query_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR * ctr)
+{
+ TDB_CONTEXT *tdb_usr = NULL;
+ SAM_USER_INFO_21 usr;
+
+ /* find the policy handle. open a policy on it. */
+ if (!get_tdbsam(get_global_hnd_cache(), pol, &tdb_usr))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+ if (!tdb_lookup_user(tdb_usr, &usr))
+ {
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ DEBUG(5, ("samr_reply_query_userinfo\n"));
+
+ return make_samr_userinfo_ctr_usr21(ctr, switch_value, &usr);
+}
+
+/*******************************************************************
+ set_user_info_24
+ ********************************************************************/
+static BOOL set_user_info_24(TDB_CONTEXT * usr_tdb,
+ const SAM_USER_INFO_24 * id24)
+{
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+ UNISTR2 new_pw;
+ uint32 len;
+
+ if (!decode_pw_buffer(id24->pass, (char *)new_pw.buffer, 256, &len))
+ {
+ return False;
+ }
+
+ new_pw.uni_max_len = len / 2;
+ new_pw.uni_str_len = len / 2;
+
+ nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
+
+ return tdb_set_userinfo_pwds(usr_tdb, lm_hash, nt_hash);
+}
+
+/*******************************************************************
+ set_user_info_12
+ ********************************************************************/
+static BOOL set_user_info_12(TDB_CONTEXT * usr_tdb,
+ const SAM_USER_INFO_12 * id12)
+{
+ return tdb_set_userinfo_pwds(usr_tdb, id12->lm_pwd, id12->nt_pwd);
+}
+
+/*******************************************************************
+ set_user_info_23
+ ********************************************************************/
+static BOOL set_user_info_23(TDB_CONTEXT * usr_tdb,
+ const SAM_USER_INFO_23 * id23)
+{
+ static uchar nt_hash[16];
+ static uchar lm_hash[16];
+ UNISTR2 new_pw;
+ uint32 len;
+
+ if (id23 == NULL)
+ {
+ DEBUG(5, ("set_user_info_23: NULL id23\n"));
+ return False;
+ }
+
+ if (!decode_pw_buffer(id23->pass, (char *)new_pw.buffer, 256, &len))
+ {
+ return False;
+ }
+
+ new_pw.uni_max_len = len / 2;
+ new_pw.uni_str_len = len / 2;
+
+ nt_lm_owf_genW(&new_pw, nt_hash, lm_hash);
+
+ return tdb_set_userinfo_23(usr_tdb, id23, lm_hash, nt_hash);
+}
+
+/*******************************************************************
+ samr_reply_set_userinfo
+ ********************************************************************/
+uint32 _samr_set_userinfo(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR * ctr)
+{
+ TDB_CONTEXT *tdb_usr = NULL;
+ uchar user_sess_key[16];
+
+ DEBUG(5, ("samr_reply_set_userinfo: %d\n", __LINE__));
+
+ /* find the domain rid associated with the policy handle */
+ if (!get_tdbsam(get_global_hnd_cache(), pol, &tdb_usr))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!pol_get_usr_sesskey(get_global_hnd_cache(), pol, user_sess_key))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (ctr == NULL)
+ {
+ DEBUG(5, ("samr_reply_set_userinfo: NULL info level\n"));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ /* ok! user info levels (lots: see MSDEV help), off we go... */
+ switch (switch_value)
+ {
+ case 0x12:
+ {
+ SAM_USER_INFO_12 *id12 = ctr->info.id12;
+ if (!set_user_info_12(tdb_usr, id12))
+ {
+ DEBUG(10,
+ ("_samr_set_userinfo 0x12 failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+
+ case 24:
+ {
+ SAM_USER_INFO_24 *id24 = ctr->info.id24;
+ SamOEMhash(id24->pass, user_sess_key, True);
+ if (!set_user_info_24(tdb_usr, id24))
+ {
+ DEBUG(10,
+ ("_samr_set_userinfo 0x18 failed\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+
+ case 23:
+ {
+ SAM_USER_INFO_23 *id23 = ctr->info.id23;
+ SamOEMhash(id23->pass, user_sess_key, 1);
+ dump_data_pw("pass buff:\n",
+ id23->pass, sizeof(id23->pass));
+ dbgflush();
+
+ if (!set_user_info_23(tdb_usr, id23))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ set_user_info_10
+ ********************************************************************/
+static BOOL set_user_info_10(TDB_CONTEXT * usr_tdb,
+ const SAM_USER_INFO_10 * id16)
+{
+ return tdb_set_userinfo_10(usr_tdb, id16->acb_info);
+}
+
+/*******************************************************************
+ samr_reply_set_userinfo2
+ ********************************************************************/
+uint32 _samr_set_userinfo2(const POLICY_HND *pol, uint16 switch_value,
+ SAM_USERINFO_CTR * ctr)
+{
+ TDB_CONTEXT *tdb_usr = NULL;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_tdbsam(get_global_hnd_cache(), pol, &tdb_usr))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ DEBUG(5, ("samr_reply_set_userinfo2\n"));
+
+ if (ctr == NULL)
+ {
+ DEBUG(5, ("samr_reply_set_userinfo2: NULL info level\n"));
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+
+ ctr->switch_value = switch_value;
+
+ /* ok! user info levels (lots: see MSDEV help), off we go... */
+ switch (switch_value)
+ {
+ case 16:
+ {
+ SAM_USER_INFO_10 *id10 = ctr->info.id10;
+ if (!set_user_info_10(tdb_usr, id10))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+static void create_user_info_21(SAM_USER_INFO_21 * usr,
+ const UNISTR2 * uni_user_name,
+ uint16 acb_info, uint32 user_rid,
+ uint32 group_rid)
+{
+ time_t t = time(NULL);
+
+ ZERO_STRUCTP(usr);
+
+ init_nt_time(&usr->logon_time);
+ init_nt_time(&usr->logoff_time);
+ init_nt_time(&usr->kickoff_time);
+ init_nt_time(&usr->pass_must_change_time);
+ unix_to_nt_time(&usr->pass_last_set_time, t);
+ unix_to_nt_time(&usr->pass_can_change_time, t);
+
+ usr->acb_info = acb_info | ACB_DISABLED | ACB_PWNOTREQ;
+ usr->user_rid = user_rid;
+ usr->group_rid = group_rid;
+
+ make_uni_hdr(&(usr->hdr_full_name), 0);
+ make_uni_hdr(&(usr->hdr_home_dir), 1);
+ make_uni_hdr(&(usr->hdr_dir_drive), 0);
+ make_uni_hdr(&(usr->hdr_logon_script), 0);
+ make_uni_hdr(&(usr->hdr_profile_path), 1);
+ make_uni_hdr(&(usr->hdr_acct_desc), 0);
+ make_uni_hdr(&(usr->hdr_workstations), 0);
+ make_uni_hdr(&(usr->hdr_unknown_str), 0);
+ make_uni_hdr(&(usr->hdr_munged_dial), 0);
+
+ make_unistr2(&(usr->uni_user_name), "", 0);
+ make_unistr2(&(usr->uni_full_name), "", 0);
+ make_unistr2(&(usr->uni_home_dir), "", 1);
+ make_unistr2(&(usr->uni_dir_drive), "", 0);
+ make_unistr2(&(usr->uni_logon_script), "", 0);
+ make_unistr2(&(usr->uni_profile_path), "", 1);
+ make_unistr2(&(usr->uni_acct_desc), "", 0);
+ make_unistr2(&(usr->uni_workstations), "", 0);
+ make_unistr2(&(usr->uni_unknown_str), "", 0);
+ make_unistr2(&(usr->uni_munged_dial), "", 0);
+
+ copy_unistr2(&usr->uni_user_name, uni_user_name);
+ make_uni_hdr(&usr->hdr_user_name, uni_user_name->uni_str_len);
+
+ usr->unknown_3 = 0xffffff; /* don't know */
+ usr->logon_divs = 168; /* hours per week */
+ usr->ptr_logon_hrs = 1;
+ usr->logon_hrs.len = 21;
+ memset(&usr->logon_hrs.hours, 0xff, sizeof(usr->logon_hrs.hours));
+ usr->unknown_5 = 0x00020000; /* don't know */
+ usr->unknown_6 = 0x000004ec; /* don't know */
+}
+
+/*******************************************************************
+ _samr_create_user
+ ********************************************************************/
+uint32 _samr_create_user(const POLICY_HND *domain_pol,
+ const UNISTR2 * uni_username,
+ uint16 acb_info, uint32 access_mask,
+ POLICY_HND *user_pol,
+ uint32 * unknown_0, uint32 * user_rid)
+{
+ DOM_SID dom_sid;
+ DOM_SID usr_sid;
+ DOM_SID sid;
+ DOM_SID grp_sid;
+ TDB_CONTEXT *tdb_usr = NULL;
+ TDB_CONTEXT *tdb_dom = NULL;
+ fstring riddb;
+ prs_struct key;
+ prs_struct data;
+
+ SAM_USER_INFO_21 usr;
+ uint32 status1;
+ uint32 rid;
+ uint32 type;
+ uint32 num_rids;
+ uint32 num_types;
+
+ struct passwd *pass = NULL;
+ uint32 group_rid;
+
+ uint32 k = 0;
+ uint32 unique_rid = 0;
+#if 0
+ uint32 num_gids = 0;
+ DOM_GID *gids = NULL;
+
+ uint32 num_alss = 0;
+ uint32 *als_rids = NULL;
+#endif
+
+ (*unknown_0) = 0x30;
+ (*user_rid) = 0x0;
+
+ /* find the domain sid associated with the policy handle */
+ if (!get_tdbdomsid(get_global_hnd_cache(), domain_pol,
+ NULL, NULL, NULL, NULL, NULL, &dom_sid))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ sid_to_string(riddb, &dom_sid);
+ safe_strcat(riddb, "/dom.tdb", sizeof(riddb)-1);
+
+ status1 = _samr_lookup_names(domain_pol, 1, 0x3e8, 1, uni_username,
+ &num_rids, &rid, &num_types, &type);
+
+ if (status1 == NT_STATUS_NOPROBLEMO)
+ {
+ switch (type)
+ {
+ case SID_NAME_USER:
+ return NT_STATUS_USER_EXISTS;
+ case SID_NAME_ALIAS:
+ return NT_STATUS_ALIAS_EXISTS;
+ case SID_NAME_DOM_GRP:
+ case SID_NAME_WKN_GRP:
+ return NT_STATUS_GROUP_EXISTS;
+ case SID_NAME_DOMAIN:
+ return NT_STATUS_DOMAIN_EXISTS;
+ default:
+ {
+ DEBUG(3,
+ ("create user: unknown, ignoring\n"));
+ break;
+ }
+ }
+ }
+
+ {
+#if 0
+ int i;
+ int n_groups = 0;
+ gid_t *groups = NULL;
+#endif
+ fstring user_name;
+ unistr2_to_ascii(user_name, uni_username,
+ sizeof(user_name) - 1);
+ pass = Get_Pwnam(user_name, False);
+ DEBUG(10, ("create user: %s\n", user_name));
+ if (pass == NULL)
+ {
+ DEBUG(0, ("create user: no unix user named %s\n",
+ user_name));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+#if 0
+ get_unixgroups(user_name, pass->pw_uid, pass->pw_gid,
+ &n_groups, &groups);
+
+ for (i = 0; i < n_groups; i++)
+ {
+ if (surs_unixid_to_sam_sid(groups[i],
+ SID_NAME_ALIAS,
+ &grp_sid, True))
+ {
+ uint32 grp_rid = 0xffffffff;
+ if (!sid_split_rid(&grp_sid, &grp_rid))
+ {
+ continue;
+ }
+ if (sid_equal(&grp_sid, &dom_sid))
+ {
+ als_rids =
+ g_renew(uint32, als_rids,
+ num_alss + 1);
+ als_rids[num_alss] = grp_rid;
+ num_alss++;
+ }
+ }
+ if (surs_unixid_to_sam_sid(groups[i],
+ SID_NAME_DOM_GRP,
+ &grp_sid, True))
+ {
+ uint32 grp_rid = 0xffffffff;
+ if (!sid_split_rid(&grp_sid, &grp_rid))
+ {
+ continue;
+ }
+ if (sid_equal(&grp_sid, &global_sam_sid))
+ {
+ gids =
+ g_renew(DOM_GID, gids,
+ num_gids + 1);
+ gids[num_gids].g_rid = grp_rid;
+ gids[num_gids].attr = 0x7;
+ num_gids++;
+ }
+ }
+ }
+#endif
+ }
+
+ tdb_dom = tdb_open(passdb_path(riddb),0,0,O_RDWR, 600);
+ if (tdb_dom == NULL || tdb_writelock(tdb_dom) != 0)
+ {
+ tdb_close(tdb_dom);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ prs_init(&key, 0, 4, False);
+ k = 0;
+
+ if (!_prs_uint32("key", &key, 0, &k))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ tdb_writeunlock(tdb_dom);
+ tdb_close(tdb_dom);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ prs_tdb_fetch(tdb_dom, &key, &data);
+
+ if (!_prs_uint32("rid", &data, 0, &unique_rid))
+ {
+ prs_free_data(&key);
+ prs_free_data(&data);
+
+ tdb_writeunlock(tdb_dom);
+ tdb_close(tdb_dom);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ prs_free_data(&data);
+
+ /* up-me a rid */
+ unique_rid++;
+ (*user_rid) = unique_rid;
+ sid_copy(&usr_sid, &global_sam_sid);
+ sid_append_rid(&usr_sid, *user_rid);
+ sid_copy(&sid, &usr_sid);
+
+ /* create a User SID for the unix user */
+ if (!surs_unixid_to_sam_sid(pass->pw_uid, SID_NAME_USER, &usr_sid,
+ True))
+ {
+ DEBUG(0, ("create user: unix uid %d to RID failed\n",
+ pass->pw_uid));
+ tdb_writeunlock(tdb_dom);
+ tdb_close(tdb_dom);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (sid_equal(&usr_sid, &sid))
+ {
+ /* you know that rid? well, we dinna WAN' IT! } */
+ unique_rid--;
+ }
+
+ /* up-me a rid */
+ unique_rid++;
+ group_rid = unique_rid;
+ sid_copy(&grp_sid, &dom_sid);
+ sid_append_rid(&grp_sid, *user_rid);
+ sid_copy(&sid, &grp_sid);
+
+ /* create a Group SID for the unix user */
+ if (!surs_unixid_to_sam_sid
+ (pass->pw_gid, SID_NAME_DOM_GRP, &grp_sid, True))
+ {
+ DEBUG(0, ("create user: unix uid %d to RID failed\n",
+ pass->pw_uid));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (sid_equal(&grp_sid, &sid))
+ {
+ /* you know that rid? well, we dinna WAN' IT! } */
+ unique_rid--;
+ }
+
+ prs_init(&data, 0, 4, False);
+
+ if (!_prs_uint32("rid", &data, 0, &unique_rid) ||
+ prs_tdb_store(tdb_dom, TDB_REPLACE, &key, &data) != 0)
+ {
+ tdb_writeunlock(tdb_dom);
+ tdb_close(tdb_dom);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ tdb_writeunlock(tdb_dom);
+ tdb_close(tdb_dom);
+
+ sid_copy(&sid, &usr_sid);
+
+ if (!sid_split_rid(&sid, user_rid) || !sid_equal(&dom_sid, &sid))
+ {
+ fstring tmp;
+ DEBUG(0, ("create user: invalid User SID %s\n",
+ sid_to_string(tmp, &usr_sid)));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!sid_split_rid(&grp_sid, &group_rid) ||
+ !sid_equal(&dom_sid, &grp_sid))
+ {
+ fstring tmp;
+ DEBUG(0, ("create user: invalid Group SID %s\n",
+ sid_to_string(tmp, &grp_sid)));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ create_user_info_21(&usr, uni_username, acb_info,
+ (*user_rid), group_rid);
+
+ tdb_usr = open_usr_db(&dom_sid, (*user_rid), O_RDWR | O_CREAT);
+
+ if (tdb_usr == NULL)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!tdb_store_user(tdb_usr, &usr))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+#if 0
+ if (!tdb_store_user_grps(tdb_usg, usr.user_rid, num_gids, gids))
+ {
+ /* account doesn't exist: say so */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!tdb_store_user_als(tdb_usa, &usr_sid, num_alss, als_rids))
+ {
+ /* account doesn't exist: say so */
+ return NT_STATUS_ACCESS_DENIED;
+ }
+#endif
+
+ *unknown_0 = 0x000703ff;
+
+ return samr_open_user_tdb(domain_pol, &dom_sid, tdb_usr,
+ user_pol, access_mask, *user_rid);
+}
+
+/*******************************************************************
+ samr_reply_delete_dom_user
+ ********************************************************************/
+uint32 _samr_delete_dom_user(POLICY_HND *user_pol)
+{
+ DEBUG(0, ("samr_delete_dom_user: not implemented\n"));
+ return NT_STATUS_ACCESS_DENIED;
+}
diff --git a/source/script/installbin.sh b/source/script/installbin.sh
index 69cca942953..22771ce5a07 100755
--- a/source/script/installbin.sh
+++ b/source/script/installbin.sh
@@ -26,16 +26,10 @@ for p in $*; do
p2=`basename $p`
echo Installing $p as $BINDIR/$p2
if [ -f $BINDIR/$p2 ]; then
- rm -f $BINDIR/$p2.old
mv $BINDIR/$p2 $BINDIR/$p2.old
fi
cp $p $BINDIR/
chmod $INSTALLPERMS $BINDIR/$p2
-
- # this is a special case, mount needs this in a specific location
- if [ $p2 = smbmount ]; then
- ln -sf $BINDIR/$p2 /sbin/mount.smbfs
- fi
done
@@ -49,3 +43,4 @@ binaries, man pages and shell scripts.
EOF
exit 0
+
diff --git a/source/script/installcp.sh b/source/script/installcp.sh
index d0c5bf8ecc9..87b0ef1a8ab 100755
--- a/source/script/installcp.sh
+++ b/source/script/installcp.sh
@@ -21,14 +21,8 @@ fi
done
for p in $*; do
- if [ -f ${srcdir}/codepages/codepage_def.$p ]; then
- echo Creating codepage file $CODEPAGEDIR/codepage.$p
- $BINDIR/make_smbcodepage c $p ${srcdir}/codepages/codepage_def.$p $CODEPAGEDIR/codepage.$p
- fi
- if [ -f ${srcdir}/codepages/CP${p}.TXT ]; then
- echo Creating unicode map $CODEPAGEDIR/unicode_map.$p
- $BINDIR/make_unicodemap $p ${srcdir}/codepages/CP${p}.TXT $CODEPAGEDIR/unicode_map.$p
- fi
+ echo Creating codepage file $CODEPAGEDIR/codepage.$p
+ $BINDIR/make_smbcodepage c $p ${srcdir}/codepages/codepage_def.$p $CODEPAGEDIR/codepage.$p
done
diff --git a/source/script/installscripts.sh b/source/script/installscripts.sh
index bff5423e7cb..6d55317e9e1 100755
--- a/source/script/installscripts.sh
+++ b/source/script/installscripts.sh
@@ -25,7 +25,6 @@ for p in $*; do
p2=`basename $p`
echo Installing $BINDIR/$p2
if [ -f $BINDIR/$p2 ]; then
- rm -f $BINDIR/$p2.old
mv $BINDIR/$p2 $BINDIR/$p2.old
fi
cp $p $BINDIR/
diff --git a/source/script/installswat.sh b/source/script/installswat.sh
index ab760cb545b..cc2ab943d9a 100755
--- a/source/script/installswat.sh
+++ b/source/script/installswat.sh
@@ -6,7 +6,7 @@ SRCDIR=$2/
echo Installing SWAT in $SWATDIR
-echo Installing the Samba Web Administration Tool
+echo Installing the Samba Web Admisistration Tool
for d in $SWATDIR $SWATDIR/help $SWATDIR/images $SWATDIR/include; do
if [ ! -d $d ]; then
diff --git a/source/script/makeunicodecasemap.awk b/source/script/makeunicodecasemap.awk
deleted file mode 100644
index 8424b6c6725..00000000000
--- a/source/script/makeunicodecasemap.awk
+++ /dev/null
@@ -1,59 +0,0 @@
-function reset_vals() {
- upperstr = "";
- lowerstr = "";
- flagstr = "0";
-}
-
-function print_val() {
- upperstr = $13;
- lowerstr = $14;
- if ( upperstr == "" )
- upperstr = strval;
- if ( lowerstr == "" )
- lowerstr = strval;
-
- if ( $3 == "Lu" )
- flagstr = sprintf("%s|%s", flagstr, "UNI_UPPER");
- if ( $3 == "Ll" )
- flagstr = sprintf("%s|%s", flagstr, "UNI_LOWER");
- if ( val >= 48 && val <= 57)
- flagstr = sprintf("%s|%s", flagstr, "UNI_DIGIT");
- if ((val >= 48 && val <= 57) || (val >= 65 && val <= 70) || (val >=97 && val <= 102))
- flagstr = sprintf("%s|%s", flagstr, "UNI_XDIGIT");
- if ( val == 32 || (val >=9 && val <= 13))
- flagstr = sprintf("%s|%s", flagstr, "UNI_SPACE");
- if( index(flagstr, "0|") == 1)
- flagstr = substr(flagstr, 3, length(flagstr) - 2);
- printf("{ 0x%s, 0x%s, %s }, \t\t\t/* %s %s */\n", lowerstr, upperstr, flagstr, strval, $2);
- val++;
- strval=sprintf("%04X", val);
- reset_vals();
-}
-
-BEGIN {
- val=0
- FS=";"
- strval=sprintf("%04X", val);
- reset_vals();
-}
-
-{
- if ( $1 == strval ) {
- print_val();
- } else {
- while ( $1 != strval) {
- printf("{ 0x%04X, 0x%04X, 0 }, \t\t\t/* %s NOMAP */\n", val, val, strval);
- val++;
- strval=sprintf("%04X", val);
- }
- print_val();
- }
-}
-
-END {
- while ( val < 65536 ) {
- printf("{ 0x%04X, 0x%04X, 0 }, \t\t\t/* %s NOMAP */\n", val, val, strval);
- val++;
- strval=sprintf("%04X", val);
- }
-}
diff --git a/source/script/makeyodldocs.sh b/source/script/makeyodldocs.sh
index d0abaab7aec..c943224fe5b 100755
--- a/source/script/makeyodldocs.sh
+++ b/source/script/makeyodldocs.sh
@@ -55,8 +55,16 @@ do
exit 1
fi
cp $bn.html ../htmldocs || echo "Cannot create $YODLDIR/../htmldocs/$bn.html"
+#
+# Copy to SWAT directory.
+#
+ if [ $bn = "smb.conf.5" ]; then
+ rm -f ../../swat/help/smb.conf.5.html || echo "Cannot remove ../../swat/help/smb.conf.5.html"
+
+ cp $bn.html ../../swat/help || echo "Cannot copy smb.conf.5.html to ../../swat/help/smb.conf.5.html"
+ fi
rm -f $bn.html
- ;;
+ ;;
*)
#
# Non man-page YODL docs - just make html and text.
diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk
index a8c807a10ce..16996561a01 100644
--- a/source/script/mkproto.awk
+++ b/source/script/mkproto.awk
@@ -1,15 +1,18 @@
BEGIN {
inheader=0;
# use_ldap_define = 0;
+ if (headername=="") {
+ headername="_PROTO_H_";
+ }
current_file="";
- print "#ifndef _PROTO_H_"
- print "#define _PROTO_H_"
+ print "#ifndef",headername
+ print "#define",headername
print "/* This file is automatically generated with \"make proto\". DO NOT EDIT */"
print ""
}
END {
- print "#endif /* _PROTO_H_ */"
+ print "#endif /*",headername,"*/"
}
{
@@ -41,6 +44,11 @@ END {
# we handle the loadparm.c fns separately
+/^FN_VUSER_STRING/ {
+ split($0,a,"[,()]")
+ printf "char *%s(const user_struct* );\n", a[2]
+}
+
/^FN_LOCAL_BOOL/ {
split($0,a,"[,()]")
printf "BOOL %s(int );\n", a[2]
@@ -90,19 +98,31 @@ END {
{
gotstart = 0;
- if( $0 ~ /^connection_struct|^pipes_struct|^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^pid_t|^ino_t|^off_t/ ) {
+ if( $0 ~ /^connection_struct|^LOCAL_GRP|^DOMAIN_GRP|^pipes_struct|^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^pid_t|^ino_t|^off_t/ ) {
+ gotstart = 1;
+ }
+
+ if( $0 ~ /^JOB_INFO_1|^JOB_INFO_2/ ) {
+ gotstart = 1;
+ }
+
+ if( $0 ~ /^PRINTER_INFO_1|^PRINTER_INFO_2/ ) {
+ gotstart = 1;
+ }
+
+ if( $0 ~ /^UNISTR2|^LOCAL_GRP|^DOMAIN_GRP|^DOM_SID|^SEC_DESC/ ) {
gotstart = 1;
}
- if( $0 ~ /^LOCAL_GRP|^DOMAIN_GRP|^SMB_STRUCT_DIRENT|^SEC_ACL|^SEC_DESC|^SEC_DESC_BUF|^DOM_SID/ ) {
+ if( $0 ~ /^msrpc_service_fns/ ) {
gotstart = 1;
}
- if( $0 ~ /^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t|^TALLOC_CTX|^hash_element/ ) {
+ if( $0 ~ /^TDB_CONTEXT|^TDB_DATA|^smb_ucs2_t/ ) {
gotstart = 1;
}
- if( $0 ~ /^long|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT/ ) {
+ if( $0 ~ /^const|^long|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE|^SMB_OFF_T|^size_t|^ssize_t|^SMB_BIG_UINT|dbg_Token/ ) {
gotstart = 1;
}
if(!gotstart) {
diff --git a/source/script/mysql_convert.pl b/source/script/mysql_convert.pl
new file mode 100644
index 00000000000..1479ce62b78
--- /dev/null
+++ b/source/script/mysql_convert.pl
@@ -0,0 +1,433 @@
+#!/bin/env perl
+#
+# MYSQL Convert - Creates and initialises mysql tables for use by samba
+#
+# Copyright (C) Benjamin Kuit 1999,
+# Copyright (C) Andrew Tridgell 1992-1999,
+# Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#
+# Converts smbpasswd files into MySQL tables.
+# Can understand Samba 1.19 and Samba 2.0 file formats.
+# Assumes table structure:
+# unix_name char(20) not null,
+# unix_uid int(10) unsigned not null,
+# nt_name char(20) not null,
+# user_rid int(10) unsigned not null,
+# smb_passwd char(32),
+# smb_nt_passwd char(32),
+# acct_ctrl int(10) unsigned not null,
+# pass_last_set_time int(10) unsigned not null,
+# unique (unix_name),
+# unique (unix_uid)
+# When given the --create option, mysql_convert will generate this
+# statement.
+#
+# To move from flat file smbpasswd directly into a mysql table:
+#
+# mysql_convert.pl --db=samba --table=smbpasswd --user=samba --create --infile=smbpasswd
+#
+# Assumes mysql server on localhost, use --host if otherwise.
+# To convert back to flat file:
+#
+# mysql_convert.pl --db=samba --table=smbpasswd --user=samba --outfile=smbpasswd
+#
+# If smbpasswd file already exists, use --file=append or --file=trash
+# to determine whether to append or over-right the file.
+#
+# In converting from NT Server PDC to Samba PDC:
+# Run pwdump on NT Server to generate an smbpasswd file (Samba 1.19 format),
+# called say NTpasslist.
+# then:
+#
+# mysql_convert.pl --db=samba --table=smbpasswd --user=samba --infile=NTpasslist --create --check
+#
+# The --check option will change the unix_uid field to the real uid
+# value of respective users, also filter out users that dont exist on
+# the system.
+#
+# If dont have mysql perl module:
+#
+# mysql_convert.pl --table=smbpasswd --infile=NTpasslist --outfile=mysql.txt
+#
+# Then use the mysql client:
+#
+# mysql -u samba < mysql.txt
+#
+
+$ACB_DISABLED=0x0001;
+$ACB_HOMDIRREQ=0x0002;
+$ACB_PWNOTREQ=0x0004;
+$ACB_TEMPDUP=0x0008;
+$ACB_NORMAL=0x0010;
+$ACB_MNS=0x0020;
+$ACB_DOMTRUST=0x0040;
+$ACB_WSTRUST=0x0080;
+$ACB_SVRTRUST=0x0100;
+$ACB_PWNOEXP=0x0200;
+$ACB_AUTOLOCK=0x0400;
+
+sub getoptionval {
+ my ($option) = @_;
+
+ my ($value) = ($option =~ /^[^=]+=\s*(\S.*\S)\s*$/ );
+
+ return $value;
+}
+
+sub usage {
+
+print <<EOUSAGE;
+$0 [options]
+options:
+ --infile=<filename> # smbpasswd style file to read entries from
+ --outfile=<filename> # file to dump results to, format depending
+ # on --infile:
+ # With --infile: Dump mysql script queries
+ # Without --infile: Dump smbpasswd format
+ # from reading mysql database
+ --host=<hostname> # Mysql Server name (default: localhost)
+ --db=<database> # Mysql Database name
+ --user=<user> # Mysql User
+ --password[=<password>] # Mysql password for --user
+ --table=<table> # Mysql table
+ --create # Generate 'create table' query
+ --file=[trash|append] # Action to take if --outfile file exists
+ --check # Do not alter or skip bad uids
+
+EOUSAGE
+exit 0;
+}
+
+sub getpass {
+ my($prompt)=@_;
+ my($ret);
+
+ print $prompt;
+ system "stty -echo";
+ chomp($ret=<STDIN>);
+ system "stty echo";
+ print "\n";
+ $ret;
+}
+
+sub next_entry {
+ my ($name,$uid,$lm,$nt,$f,$lct) = ();
+
+ $name="";
+ if ( not $infile ) {
+ ($name,$uid,$lm,$nt,$f,$lct) = $mysqlquery->fetchrow();
+ }
+ else {
+ my $line=<INFILE>;
+
+ return () if ( not $line );
+
+ chomp($line);
+
+ next if ( $line !~ /^[^: ]+:\d+:/ );
+
+ ($name,$uid,$lm,$nt,$f,$lct) = split(/:/,$line);
+
+ if ( $lct =~ /^LCT-/ ) {
+ # New Format smbpasswd file
+ my $flags=0;
+
+ $flags |= $ACB_PWNOTREQ if ( $f =~ /N/ );
+ $flags |= $ACB_DISABLED if ( $f =~ /D/ );
+ $flags |= $ACB_HOMDIRREQ if ( $f =~ /H/ );
+ $flags |= $ACB_TEMPDUP if ( $f =~ /T/ );
+ $flags |= $ACB_NORMAL if ( $f =~ /U/ );
+ $flags |= $ACB_MNS if ( $f =~ /M/ );
+ $flags |= $ACB_WSTRUST if ( $f =~ /W/ );
+ $flags |= $ACB_SVRTRUST if ( $f =~ /S/ );
+ $flags |= $ACB_AUTOLOCK if ( $f =~ /L/ );
+ $flags |= $ACB_PWNOEXP if ( $f =~ /X/ );
+ $flags |= $ACB_DOMTRUST if ( $f =~ /I/ );
+
+ $f = $flags;
+
+ $f = $ACB_NORMAL if ( not $f );
+
+ $lct =~ s/LCT-//;
+ $lct = (unpack("L",pack("H8",$lct)))[0];
+ }
+ else {
+ # Old Format smbpasswd file
+ $f = 0;
+ $lct = time();
+ if ( $lm =~ /^NO PASS/ ) {
+ $f |= $ACB_PWNOTREQ;
+ $lm = "";
+ $nt = "";
+ }
+ elsif ( $lm =~ /^XX/ ) {
+ $f |= $ACB_DISABLED;
+
+ $lm = "";
+ $nt = "";
+ }
+
+ if ( $name =~ /\$$/ ) {
+ $f |= $ACB_WSTRUST;
+ }
+
+ $f = $ACB_NORMAL if ( not $f );
+ }
+ }
+ return () if ( not $name );
+ ($name,$uid,$lm,$nt,$f,$lct);
+}
+
+sub do_query {
+ my ( $query ) = @_;
+
+ chomp($query);
+ if ( $outfile ) {
+ print OUTFILE "$query;\n";
+ }
+ else {
+ if ( not $mysqldb->query($query) ) {
+ print "$query: $Mysql::db_errstr\n";
+ }
+ }
+}
+
+sub do_file {
+ my ($file,$name,$uid,$lm,$nt,$f,$lct)=@_;
+
+ my $strings = "";
+
+ $strings .= "N" if ( $f & $ACB_PWNOTREQ );
+ $strings .= "D" if ( $f & $ACB_DISABLED );
+ $strings .= "H" if ( $f & $ACB_HOMDIRREQ );
+ $strings .= "T" if ( $f & $ACB_TEMPDUP );
+ $strings .= "U" if ( $f & $ACB_NORMAL );
+ $strings .= "M" if ( $f & $ACB_MNS );
+ $strings .= "W" if ( $f & $ACB_WSTRUST );
+ $strings .= "S" if ( $f & $ACB_SVRTRUST );
+ $strings .= "L" if ( $f & $ACB_AUTOLOCK );
+ $strings .= "X" if ( $f & $ACB_PWNOEXP );
+ $strings .= "I" if ( $f & $ACB_DOMTRUST );
+
+ $f = sprintf( "[%-11s]", $strings );
+
+ $lct=uc("LCT-".(unpack("H8",pack("L","$lct")))[0]);
+
+ $lm = "X"x32 if ( not $lm );
+ $nt = "X"x32 if ( not $nt );
+
+ print $file "$name:$uid:$lm:$nt:$f:$lct\n";
+}
+
+$dbhost = "localhost";
+
+for $option ( @ARGV ) {
+ if ( $option =~ /--outfile=/ ) {
+ $outfile = getoptionval($option);
+ }
+ elsif ( $option =~ /--infile=/ ) {
+ $infile = getoptionval($option);
+ }
+ elsif ( $option =~ /--db=/ ) {
+ $dbname = getoptionval($option);
+ }
+ elsif ( $option =~ /--user=/ ) {
+ $dbuser = getoptionval($option);
+ }
+ elsif ( $option =~ /--host=/ ) {
+ $dbhost = getoptionval($option);
+ }
+ elsif ( $option =~ /--password/ ) {
+ $dbpasswd = getoptionval($option);
+ $need_password = "yes"
+ }
+ elsif ( $option =~ /--table=/ ) {
+ $dbtable = getoptionval($option);
+ }
+ elsif ( $option =~ /--create/ ) {
+ $create_table = "yes";
+ }
+ elsif ( $option =~ /--file=/ ) {
+ $file_action = getoptionval($option);
+ }
+ elsif ( $option =~ /--check/ ) {
+ $check = "yes";
+ }
+ else {
+ print "Unknown option: $option\n";
+ $unknown = "yes";
+ }
+}
+
+&usage if ( $unknown eq "yes" );
+
+if ( ( not $infile ) && ( not $outfile ) && ( $create_table ne "yes" ) ) {
+ print "Need file to read from or write to\n";
+ &usage;
+}
+elsif ( $infile && $outfile ) {
+ if ( not $dbtable ) {
+ print "Need --table to create queries\n";
+ exit 1;
+ }
+
+ # Reading a smbpasswd file, dumping queries into an file which
+ # can be used for a mysql script
+ # --db* options are ignored.
+
+ $ignored = "";
+ $ignored .= " --db" if ( $dbname );
+ $ignored .= " --user" if ( $dbuser );
+ $ignored .= " --password" if ( $dbuser );
+
+ if ( $ignored ) {
+ print "Ignoring options: $ignored\n";
+ }
+}
+elsif ( (not $dbname) || (not $dbtable) || (not $dbuser) ) {
+ print "Missing database particulars:\n";
+ print " --db=??\n" if ( not $dbname );
+ print " --user=??\n" if ( not $dbuser );
+ print " --table=??\n" if ( not $dbtable );
+ &usage;
+}
+else {
+ use Mysql;
+
+ if ( ($need_password eq "yes") && ( not $dbpasswd )) {
+ $dbpasswd = getpass("Enter MySQL password for $dbuser: ");
+ }
+ $mysqldb = Connect Mysql($dbhost,$dbname,$dbuser,$dbpasswd);
+
+ if ( not $mysqldb ) {
+ print "Cannot connect to database: $Mysql::db_errstr\n";
+ exit 1;
+ }
+
+ if ( $outfile ) {
+ $mysqlquery = $mysqldb->query("select unix_name,unix_uid,smb_passwd,smb_nt_passwd,acct_ctrl,pass_last_set_time from $dbtable");
+
+ if ( not $mysqlquery ) {
+ print "MySQL Query failed: $Mysql::db_errstr\n";
+ exit 1;
+ }
+ }
+}
+
+if ( $create_table eq "yes" ) {
+ $create_table_query=<<EOSQL;
+create table $dbtable (
+unix_name char(20) not null,
+unix_uid int(10) unsigned not null,
+nt_name char(20) not null,
+user_rid int(10) unsigned not null,
+smb_passwd char(32),
+smb_nt_passwd char(32),
+acct_ctrl int(10) unsigned not null,
+pass_last_set_time int(10) unsigned not null,
+unique (unix_name),
+unique (unix_uid)
+)
+EOSQL
+ print "$create_table_query\n";
+}
+if ( $infile ) {
+ if ( not open(INFILE,$infile) ) {
+ print "$infile: $!\n";
+ exit 1;
+ }
+}
+
+if ( $outfile ) {
+ if ( ! -f $outfile ) {
+ $open_string=">$outfile";
+ }
+ elsif ( not $file_action ) {
+ print "File $outfile exists:\n";
+ print "Please use --file=[trash|append] option to determine destiny of file\n";
+ exit 1;
+ }
+ elsif ( $file_action eq "append" ) {
+ $open_string = ">>$outfile";
+ }
+ else {
+ $open_string = ">$outfile";
+ }
+
+ if ( not open(OUTFILE,$open_string) ) {
+ print "$outfile: $!\n";
+ exit 1;
+ }
+}
+
+do_query($create_table_query) if ( $create_table_query );
+
+$linenum=1;
+while (($name,$uid,$lm,$nt,$f,$lct)=next_entry()) {
+
+ $| = 1;
+ print "\r$linenum ";
+ $linenum++;
+
+ $nuid = "";
+
+ $nuid = (getpwnam(lc($name)))[2];
+
+ if ( $check ) {
+ if ( not $nuid ) {
+ # print "Removing $name: Does not exist\n";
+ push(@removed,[$name,$uid,$lm,$nt,$f,$lct]);
+ next;
+ }
+ else {
+ # print "Changing uid of $name\n";
+ $uid = $nuid;
+ }
+ }
+
+ if ( $infile ) {
+ if ( $lm ) {
+ $lm = "'$lm'";
+ }
+ else {
+ $lm = "NULL";
+ }
+ if ( $nt ) {
+ $nt = "'$nt'";
+ }
+ else {
+ $nt = "NULL";
+ }
+ $rid=(4*$uid)+1000;
+ do_query("insert into $dbtable (unix_name,unix_uid,smb_passwd,smb_nt_passwd,acct_ctrl,pass_last_set_time,nt_name,user_rid) values ('$name',$uid,$lm,$nt,$f,$lct,'$name',$rid)");
+ }
+ else {
+ do_file(OUTFILE,$name,$uid,$lm,$nt,$f,$lct);
+ }
+}
+
+if ( @removed ) {
+ print "\n\nIgnored entries because usernames do not exist\n";
+ foreach $line ( @removed ) {
+ do_file(STDOUT,@{ $line });
+ }
+}
+
+close (OUTFILE) if ( $outfile );
+close (INFILE) if ( $infile );
+print "\n";
diff --git a/source/script/samba b/source/script/samba
new file mode 100644
index 00000000000..2525b8f295d
--- /dev/null
+++ b/source/script/samba
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# samba
+#
+# This is from a Solaris box. Proper links need to be made to it from the
+# rcX.d directories. For Linux, it goes into /etc/rc.d/init.d
+#
+# Lonnie
+
+SAMBA=/usr/local/samba
+
+case "$1" in
+'start')
+ echo "SMB Service starting."
+ PATH="/usr/bin:/sbin:/usr/sbin"
+ export PATH
+ ${SAMBA}/bin/smbd -D
+ ${SAMBA}/bin/nmbd -D
+ ${SAMBA}/bin/browserd -D
+ ${SAMBA}/bin/lsarpcd -D
+ ${SAMBA}/bin/netlogond -D
+ ${SAMBA}/bin/samrd -D
+ ${SAMBA}/bin/spoolssd -D
+ ${SAMBA}/bin/srvsvcd -D
+ ${SAMBA}/bin/svcctld -D
+ ${SAMBA}/bin/winregd -D
+ ${SAMBA}/bin/wkssvcd -D
+ ;;
+'restart')
+ $0 stop
+ $0 start
+ ;;
+'stop')
+ echo "SMB Service stopping."
+ for file in ${SAMBA}/var/locks/*.pid
+ do
+ if [ -r $file ]
+ then
+ kill `cat $file`
+ rm $file
+ fi
+ done
+ ;;
+*)
+ echo "Usage: /etc/init.d/samba { start | stop | restart }"
+ ;;
+esac
+exit 0
diff --git a/source/script/samba-init.d-solaris b/source/script/samba-init.d-solaris
new file mode 100755
index 00000000000..2525b8f295d
--- /dev/null
+++ b/source/script/samba-init.d-solaris
@@ -0,0 +1,48 @@
+#!/bin/sh
+#
+# samba
+#
+# This is from a Solaris box. Proper links need to be made to it from the
+# rcX.d directories. For Linux, it goes into /etc/rc.d/init.d
+#
+# Lonnie
+
+SAMBA=/usr/local/samba
+
+case "$1" in
+'start')
+ echo "SMB Service starting."
+ PATH="/usr/bin:/sbin:/usr/sbin"
+ export PATH
+ ${SAMBA}/bin/smbd -D
+ ${SAMBA}/bin/nmbd -D
+ ${SAMBA}/bin/browserd -D
+ ${SAMBA}/bin/lsarpcd -D
+ ${SAMBA}/bin/netlogond -D
+ ${SAMBA}/bin/samrd -D
+ ${SAMBA}/bin/spoolssd -D
+ ${SAMBA}/bin/srvsvcd -D
+ ${SAMBA}/bin/svcctld -D
+ ${SAMBA}/bin/winregd -D
+ ${SAMBA}/bin/wkssvcd -D
+ ;;
+'restart')
+ $0 stop
+ $0 start
+ ;;
+'stop')
+ echo "SMB Service stopping."
+ for file in ${SAMBA}/var/locks/*.pid
+ do
+ if [ -r $file ]
+ then
+ kill `cat $file`
+ rm $file
+ fi
+ done
+ ;;
+*)
+ echo "Usage: /etc/init.d/samba { start | stop | restart }"
+ ;;
+esac
+exit 0
diff --git a/source/script/samba-init.d-sysv b/source/script/samba-init.d-sysv
new file mode 100644
index 00000000000..8a2228546e6
--- /dev/null
+++ b/source/script/samba-init.d-sysv
@@ -0,0 +1,64 @@
+#! /bin/sh
+
+#
+# Samba server control
+#
+
+IS_ON=/etc/chkconfig
+KILLALL=/sbin/killall
+
+SAMBA_HOME="/usr/samba/bin"
+
+SAMBAD=${SAMBA_HOME}/smbd
+#SAMBA_OPTS=-d2
+NMBD=${SAMBA_HOME}/nmbd
+BROWSERD=${SAMBA_HOME}/browserd
+LSARPCD=${SAMBA_HOME}/lsarpcd
+NETLOGOND=${SAMBA_HOME}/netlogond
+SAMRD=${SAMBA_HOME}/samrd
+SPOOLSSD=${SAMBA_HOME}/spoolssd
+SRVSVCD=${SAMBA_HOME}/srvsvcd
+SVCCTLD=${SAMBA_HOME}/svcctld
+WINREGD=${SAMBA_HOME}/winregd
+WKSSVCD=${SAMBA_HOME}/wkssvcd
+
+#NMBD_OPTS=-d1
+
+if test ! -x $IS_ON ; then
+ IS_ON=true
+fi
+
+if $IS_ON verbose ; then
+ ECHO=echo
+else # For a quiet startup and shutdown
+ ECHO=:
+fi
+
+case $1 in
+'start')
+ if $IS_ON samba && test -x $SAMBAD; then
+ $KILLALL -15 smbd nmbd browserd lsarpcd netlogond samrd spoolssd srvsvcd svcctld winregd wkssvcd
+ $ECHO "Samba:\c"
+ $SAMBAD $SAMBA_OPTS -D; $ECHO " smbd\c"
+ $NMBD $NMBD_OPTS -D; $ECHO " nmbd\c"
+ $LSARPCD; $ECHO " lsarpcd\c"
+ $NETLOGOND; $ECHO " netlogond\c"
+ $SAMRD; $ECHO " samrd\c"
+ $SPOOLSSD; $ECHO " spoolssd\c"
+ $SRVSVCD; $ECHO " srvsvcd\c"
+ $SVCCTLD; $ECHO " svcctld\c"
+ $WINREGD; $ECHO " winregd\c"
+ $WKSSVCD; $ECHO " wkssvcd\c"
+ $BROWSERD; $ECHO " browserd\c"
+ $ECHO "."
+ fi
+ ;;
+'stop')
+ $ECHO "Stopping Samba Servers."
+ $KILLALL -15 smbd nmbd browserd lsarpcd netlogond samrd spoolssd srvsvcd svcctld winregd wkssvcd
+ exit 0
+ ;;
+*)
+ echo "usage: /etc/init.d/samba {start|stop}"
+ ;;
+esac
diff --git a/source/script/smbtar b/source/script/smbtar
index cf3ff0ebe68..f04eddc32ba 100644
--- a/source/script/smbtar
+++ b/source/script/smbtar
@@ -30,9 +30,7 @@ username=$LOGNAME # Default: same user name as in *nix
verbose="2>/dev/null" # Default: no echo to stdout
log="-d 2"
newer=""
-newerarg=""
blocksize=""
-blocksizearg=""
clientargs="-c 'tarmode full'"
tarcmd="c"
tarargs=""
@@ -64,7 +62,7 @@ Options: (Description) (Default)
exit $ex
}
-# echo Params count: $#
+echo Params count: $#
# DEC OSF AKA Digital UNIX does not seem to return a value in OPTIND if
# there are no command line params, so protect us against that ...
@@ -99,7 +97,7 @@ while getopts riavl:b:d:N:s:p:x:u:Xt: c; do
N) # compare with a file, test if [n]ewer
if [ -f $OPTARG ]; then
newer=$OPTARG
- newerarg="N"
+ tarargs=${tarargs}N
else
echo >&2 $0: Warning, $OPTARG not found
fi
@@ -117,7 +115,7 @@ while getopts riavl:b:d:N:s:p:x:u:Xt: c; do
*) echo >&2 "$0: Error, block size not numeric: -b $OPTARG"
exit 1
esac
- blocksizearg="b"
+ tarargs=${tarargs}b
;;
p) # specify [p]assword to use
password="$OPTARG"
@@ -157,8 +155,7 @@ if [ -z "$verbose" ]; then
echo "blocksize is $blocksize"
fi
-tarargs=${tarargs}${blocksizearg}${newerarg}
-
eval $SMBCLIENT "'\\\\$server\\$service'" "'$password'" -U "'$username'" \
-E -N $log -D "'$cdcmd'" ${clientargs} \
-T${tarcmd}${tarargs} $blocksize $newer $tapefile '${1+"$@"}' $verbose
+
diff --git a/source/smbd/.cvsignore b/source/smbd/.cvsignore
index e69de29bb2d..c8b522d6e79 100644
--- a/source/smbd/.cvsignore
+++ b/source/smbd/.cvsignore
@@ -0,0 +1 @@
+*.lo
diff --git a/source/smbd/blocking.c b/source/smbd/blocking.c
index c90f475b463..96833286e2b 100644
--- a/source/smbd/blocking.c
+++ b/source/smbd/blocking.c
@@ -20,8 +20,11 @@
*/
#include "includes.h"
+#include "nterr.h"
+
extern int DEBUGLEVEL;
extern int Client;
+extern int chain_size;
extern char *OutBuffer;
/****************************************************************************
@@ -207,25 +210,21 @@ static void reply_lockingX_error(blocking_lock_record *blr, int eclass, int32 ec
* of smb_lkrng structs.
*/
- /*
- * Ensure we don't do a remove on the lock that just failed,
- * as under POSIX rules, if we have a lock already there, we
- * will delete it (and we shouldn't) .....
- */
-
- for(i = blr->lock_num - 1; i >= 0; i--) {
+ for(i = blr->lock_num; i >= 0; i--) {
int dummy1;
uint32 dummy2;
- BOOL err;
-
- count = get_lock_count( data, i, large_file_format, &err);
- offset = get_lock_offset( data, i, large_file_format, &err);
-
- /*
- * We know err cannot be set as if it was the lock
- * request would never have been queued. JRA.
- */
-
+ if(!large_file_format) {
+ count = IVAL(data,SMB_LKLEN_OFFSET(i));
+ offset = IVAL(data,SMB_LKOFF_OFFSET(i));
+ }
+#ifdef LARGE_SMB_OFF_T
+ else {
+ count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
+ ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
+ offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
+ ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
+ }
+#endif /* LARGE_SMB_OFF_T */
do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
}
@@ -279,7 +278,7 @@ static BOOL process_lockread(blocking_lock_record *blr)
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
data = smb_buf(outbuf) + 3;
- if(!do_lock( fsp, conn, numtoread, startpos, READ_LOCK, &eclass, &ecode)) {
+ if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) {
if((errno != EACCES) && (errno != EAGAIN)) {
/*
* We have other than a "can't get lock" POSIX
@@ -316,7 +315,7 @@ static BOOL process_lockread(blocking_lock_record *blr)
SSVAL(smb_buf(outbuf),1,nread);
DEBUG(3, ( "process_lockread file = %s, fnum=%d num=%d nread=%d\n",
- fsp->fsp_name, fsp->fnum, (int)numtoread, (int)nread ) );
+ fsp->fsp_name, fsp->fnum, numtoread, nread ) );
send_blocking_reply(outbuf,outsize);
return True;
@@ -342,7 +341,7 @@ static BOOL process_lock(blocking_lock_record *blr)
offset = IVAL(inbuf,smb_vwv3);
errno = 0;
- if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode)) {
+ if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode)) {
if((errno != EACCES) && (errno != EAGAIN)) {
/*
@@ -404,17 +403,20 @@ static BOOL process_lockingX(blocking_lock_record *blr)
*/
for(; blr->lock_num < num_locks; blr->lock_num++) {
- BOOL err;
-
- count = get_lock_count( data, blr->lock_num, large_file_format, &err);
- offset = get_lock_offset( data, blr->lock_num, large_file_format, &err);
-
- /*
- * We know err cannot be set as if it was the lock
- * request would never have been queued. JRA.
- */
+ if(!large_file_format) {
+ count = IVAL(data,SMB_LKLEN_OFFSET(blr->lock_num));
+ offset = IVAL(data,SMB_LKOFF_OFFSET(blr->lock_num));
+ }
+#ifdef LARGE_SMB_OFF_T
+ else {
+ count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(blr->lock_num))) << 32) |
+ ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(blr->lock_num)));
+ offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(blr->lock_num))) << 32) |
+ ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(blr->lock_num)));
+ }
+#endif /* LARGE_SMB_OFF_T */
errno = 0;
- if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK),
+ if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
&eclass, &ecode))
break;
}
@@ -527,16 +529,6 @@ file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
}
/****************************************************************************
- Return True if the blocking lock queue has entries.
-*****************************************************************************/
-
-BOOL blocking_locks_pending(void)
-{
- blocking_lock_record *blr = (blocking_lock_record *)ubi_slFirst( &blocking_lock_queue );
- return (blr == NULL ? False : True);
-}
-
-/****************************************************************************
Process the blocking lock queue. Note that this is only called as root.
*****************************************************************************/
diff --git a/source/smbd/challenge.c b/source/smbd/challenge.c
new file mode 100644
index 00000000000..cbb34e63954
--- /dev/null
+++ b/source/smbd/challenge.c
@@ -0,0 +1,61 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Password and authentication handling
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+/* Data to do lanman1/2 password challenge. */
+static unsigned char saved_challenge[8];
+static BOOL challenge_sent=False;
+
+/*******************************************************************
+Get the next challenge value - no repeats.
+********************************************************************/
+void generate_next_challenge(char *challenge)
+{
+ unsigned char buf[8];
+ generate_random_buffer(buf,8,False);
+ memcpy(saved_challenge, buf, 8);
+ memcpy(challenge,buf,8);
+ challenge_sent = True;
+}
+
+/*******************************************************************
+set the last challenge sent, usually from a password server
+********************************************************************/
+BOOL set_challenge(unsigned char *challenge)
+{
+ memcpy(saved_challenge,challenge,8);
+ challenge_sent = True;
+ return(True);
+}
+
+/*******************************************************************
+get the last challenge sent
+********************************************************************/
+BOOL last_challenge(unsigned char *challenge)
+{
+ if (!challenge_sent) return False;
+ memcpy(challenge,saved_challenge,8);
+ return(True);
+}
+
diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c
index 406f4604b11..6e50c3acb69 100644
--- a/source/smbd/chgpasswd.c
+++ b/source/smbd/chgpasswd.c
@@ -52,20 +52,24 @@
extern int DEBUGLEVEL;
#if ALLOW_CHANGE_PASSWORD
+#define MINPASSWDLENGTH 5
+#define BUFSIZE 512
static int findpty(char **slave)
{
int master;
+#ifndef HAVE_GRANTPT
static fstring line;
- void *dirp;
+ DIR *dirp;
+ struct dirent *dentry;
char *dpname;
+#endif /* !HAVE_GRANTPT */
#if defined(HAVE_GRANTPT)
- /* Try to open /dev/ptmx. If that fails, fall through to old method. */
- if ((master = sys_open("/dev/ptmx", O_RDWR, 0)) >= 0) {
+ if ((master = sys_open("/dev/ptmx", O_RDWR, 0)) >= 1) {
grantpt(master);
unlockpt(master);
- *slave = (char *)ptsname(master);
+ *slave = ptsname(master);
if (*slave == NULL) {
DEBUG(0,("findpty: Unable to create master/slave pty pair.\n"));
/* Stop fd leak on error. */
@@ -76,14 +80,14 @@ static int findpty(char **slave)
return (master);
}
}
-#endif /* HAVE_GRANTPT */
-
+#else /* HAVE_GRANTPT */
fstrcpy( line, "/dev/ptyXX" );
- dirp = OpenDir(NULL, "/dev", False);
+ dirp = opendir("/dev");
if (!dirp)
return(-1);
- while ((dpname = ReadDirName(dirp)) != NULL) {
+ while ((dentry = readdir(dirp)) != NULL) {
+ dpname = dentry->d_name;
if (strncmp(dpname, "pty", 3) == 0 && strlen(dpname) == 5) {
DEBUG(3,("pty: try to open %s, line was %s\n", dpname, line ) );
line[8] = dpname[3];
@@ -92,22 +96,27 @@ static int findpty(char **slave)
DEBUG(3,("pty: opened %s\n", line ) );
line[5] = 't';
*slave = line;
- CloseDir(dirp);
+ closedir(dirp);
return (master);
}
}
}
- CloseDir(dirp);
+ closedir(dirp);
+#endif /* HAVE_GRANTPT */
return (-1);
}
-static int dochild(int master,char *slavedev, char *name, char *passwordprogram, BOOL as_root)
+static int dochild(int master,char *slavedev, const char *_name, char *passwordprogram, BOOL as_root)
{
int slave;
struct termios stermios;
- struct passwd *pass = Get_Pwnam(name,True);
- gid_t gid;
- uid_t uid;
+ const struct passwd *pass;
+ int gid;
+ int uid;
+
+ fstring name;
+ fstrcpy(name, _name);
+ pass = Get_Pwnam(name,True);
if (pass == NULL) {
DEBUG(0,("dochild: user name %s doesn't exist in the UNIX password database.\n",
@@ -117,8 +126,11 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram,
gid = pass->pw_gid;
uid = pass->pw_uid;
-
- gain_root_privilege();
+#ifdef HAVE_SETRESUID
+ setresuid(0,0,0);
+#else
+ setuid(0);
+#endif
/* Start new session - gets rid of controlling terminal. */
if (setsid() < 0) {
@@ -178,7 +190,19 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram,
/* make us completely into the right uid */
if (!as_root) {
- become_user_permanently(uid, gid);
+#ifdef HAVE_SETRESUID
+ setresgid(0,0,0);
+ setresuid(0,0,0);
+ setresgid(gid,gid,gid);
+ setresuid(uid,uid,uid);
+#else
+ setuid(0);
+ seteuid(0);
+ setgid(gid);
+ setegid(gid);
+ setuid(uid);
+ seteuid(uid);
+#endif
}
DEBUG(10, ("Invoking '%s' as password change program.\n", passwordprogram));
@@ -191,92 +215,93 @@ static int dochild(int master,char *slavedev, char *name, char *passwordprogram,
return(True);
}
-static int expect(int master, char *issue, char *expected)
+static int expect(int master,char *expected,char *buf)
{
- pstring buffer;
- int attempts, timeout, nread, len;
- BOOL match = False;
-
- for (attempts = 0; attempts < 2; attempts++)
- {
- if (!strequal(issue, "."))
- {
- if (lp_passwd_chat_debug())
- DEBUG(100, ("expect: sending [%s]\n", issue));
-
- write(master, issue, strlen(issue));
- }
-
- if (strequal(expected, "."))
- return True;
-
- timeout = 2000;
- nread = 0;
- buffer[nread] = 0;
-
- while ((len = read_with_timeout(master, buffer + nread, 1,
- sizeof(buffer) - nread - 1, timeout)) > 0)
- {
- nread += len;
- buffer[nread] = 0;
-
- if ((match = unix_do_match(buffer, expected, False)))
- timeout = 200;
- }
-
- if (lp_passwd_chat_debug())
- DEBUG(100, ("expect: expected [%s] received [%s]\n",
- expected, buffer));
+ int n, m;
+
+ n = 0;
+ buf[0] = 0;
+ while (1) {
+ if (n >= BUFSIZE-1) {
+ return False;
+ }
- if (match)
- break;
+ /* allow 4 seconds for some output to appear */
+ m = read_with_timeout(master, buf+n, 1, BUFSIZE-1-n, 4000);
+ if (m < 0)
+ return False;
- if (len < 0)
- {
- DEBUG(2, ("expect: %s\n", strerror(errno)));
- return False;
- }
- }
+ n += m;
+ buf[n] = 0;
- return match;
+ {
+ pstring s1,s2;
+ pstrcpy(s1,buf);
+ pstrcpy(s2,expected);
+ if (do_match(s1, s2, False))
+ return(True);
+ }
+ }
}
static void pwd_sub(char *buf)
{
- all_string_sub(buf,"\\n","\n",0);
- all_string_sub(buf,"\\r","\r",0);
- all_string_sub(buf,"\\s"," ",0);
- all_string_sub(buf,"\\t","\t",0);
+ string_sub(buf,"\\n","\n");
+ string_sub(buf,"\\r","\r");
+ string_sub(buf,"\\s"," ");
+ string_sub(buf,"\\t","\t");
}
-static int talktochild(int master, char *seq)
+static void writestring(int fd,char *s)
{
- int count = 0;
- fstring issue, expected;
+ int l;
+
+ l = strlen (s);
+ write (fd, s, l);
+}
- fstrcpy(issue, ".");
- while (next_token(&seq, expected, NULL, sizeof(expected)))
- {
- pwd_sub(expected);
- count++;
+static int talktochild(int master, char *chatsequence)
+{
+ char buf[BUFSIZE];
+ int count=0;
+ char *ptr=chatsequence;
+ fstring chatbuf;
+
+ *buf = 0;
+ sleep(1);
+
+ while (next_token(&ptr,chatbuf,NULL,sizeof(chatbuf))) {
+ BOOL ok=True;
+ count++;
+ pwd_sub(chatbuf);
+ if (!strequal(chatbuf,"."))
+ ok = expect(master,chatbuf,buf);
+
+ if (lp_passwd_chat_debug())
+ DEBUG(100,("talktochild: chatbuf=[%s] responsebuf=[%s]\n",chatbuf,buf));
+
+ if (!ok) {
+ DEBUG(3,("response %d incorrect\n",count));
+ return(False);
+ }
- if (!expect(master, issue, expected))
- {
- DEBUG(3,("Response %d incorrect\n", count));
- return False;
- }
+ if (!next_token(&ptr,chatbuf,NULL,sizeof(chatbuf))) break;
+ pwd_sub(chatbuf);
+ if (!strequal(chatbuf,"."))
+ writestring(master,chatbuf);
- if (!next_token(&seq, issue, NULL, sizeof(issue)))
- fstrcpy(issue, ".");
+ if (lp_passwd_chat_debug())
+ DEBUG(100,("talktochild: sendbuf=[%s]\n",chatbuf));
+ }
- pwd_sub(issue);
- }
+ if (count<1) return(False);
- return (count > 0);
+ return (True);
}
-static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence, BOOL as_root)
+
+static BOOL chat_with_program(char *passwordprogram,const char *name,char *chatsequence, BOOL as_root)
{
char *slavedev;
int master;
@@ -290,17 +315,9 @@ static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequenc
return(False);
}
- /*
- * We need to temporarily stop CatchChild from eating
- * SIGCLD signals as it also eats the exit status code. JRA.
- */
-
- CatchChildLeaveStatus();
-
if ((pid = fork()) < 0) {
DEBUG(3,("Cannot fork() child for password change: %s\n",name));
close(master);
- CatchChild();
return(False);
}
@@ -311,26 +328,12 @@ static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequenc
kill(pid, SIGKILL); /* be sure to end this process */
}
- while((wpid = sys_waitpid(pid, &wstat, 0)) < 0) {
- if(errno == EINTR) {
- errno = 0;
- continue;
- }
- break;
- }
-
- if (wpid < 0) {
+ if ((wpid = sys_waitpid(pid, &wstat, 0)) < 0) {
DEBUG(3,("The process is no longer waiting!\n\n"));
close(master);
- CatchChild();
return(False);
}
- /*
- * Go back to ignoring children.
- */
- CatchChild();
-
close(master);
if (pid != wpid) {
@@ -363,12 +366,8 @@ static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequenc
DEBUG(3,("Dochild for user %s (uid=%d,gid=%d)\n",name,(int)getuid(),(int)getgid()));
chstat = dochild(master, slavedev, name, passwordprogram, as_root);
- /*
- * The child should never return from dochild() ....
- */
-
- DEBUG(0,("chat_with_program: Error: dochild() returned %d\n", chstat ));
- exit(1);
+ if (as_root)
+ unbecome_root(False);
}
if (chstat)
@@ -377,13 +376,15 @@ static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequenc
}
-BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root)
+BOOL chgpasswd(const char *_name,char *oldpass,char *newpass, BOOL as_root)
{
pstring passwordprogram;
pstring chatsequence;
- size_t i;
- size_t len;
+ int i;
+ int len;
+ fstring name;
+ fstrcpy(name, _name);
strlower(name);
DEBUG(3,("Password change for user: %s\n",name));
@@ -393,10 +394,9 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root)
/* Take the passed information and test it for minimum criteria */
/* Minimum password length */
- if (strlen(newpass) < lp_min_passwd_length()) /* too short, must be at least MINPASSWDLENGTH */
+ if (strlen(newpass) < MINPASSWDLENGTH) /* too short, must be at least MINPASSWDLENGTH */
{
- DEBUG(0,("Password Change: user %s, New password is shorter than minimum password length = %d\n",
- name, lp_min_passwd_length()));
+ DEBUG(2,("Password Change: %s, New password is shorter than MINPASSWDLENGTH\n",name));
return (False); /* inform the user */
}
@@ -441,19 +441,18 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root)
}
}
- pstring_sub(passwordprogram,"%u",name);
- /* note that we do NOT substitute the %o and %n in the password program
- as this would open up a security hole where the user could use
- a new password containing shell escape characters */
+ string_sub(passwordprogram,"%u",name);
+ all_string_sub(passwordprogram,"%o",oldpass, 0);
+ all_string_sub(passwordprogram,"%n",newpass, 0);
- pstring_sub(chatsequence,"%u",name);
- all_string_sub(chatsequence,"%o",oldpass,sizeof(pstring));
- all_string_sub(chatsequence,"%n",newpass,sizeof(pstring));
+ string_sub(chatsequence,"%u",name);
+ all_string_sub(chatsequence,"%o",oldpass, sizeof(pstring));
+ all_string_sub(chatsequence,"%n",newpass, sizeof(pstring));
return(chat_with_program(passwordprogram,name,chatsequence, as_root));
}
#else /* ALLOW_CHANGE_PASSWORD */
-BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root)
+BOOL chgpasswd(const char *name,char *oldpass,char *newpass, BOOL as_root)
{
DEBUG(0,("Password changing not compiled in (user=%s)\n",name));
return(False);
@@ -461,176 +460,43 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root)
#endif /* ALLOW_CHANGE_PASSWORD */
/***********************************************************
- Code to check the lanman hashed password.
-************************************************************/
-
-BOOL check_lanman_password(char *user, uchar *pass1,
- uchar *pass2, struct smb_passwd **psmbpw)
-{
- static uchar null_pw[16];
- uchar unenc_new_pw[16];
- uchar unenc_old_pw[16];
- struct smb_passwd *smbpw;
-
- *psmbpw = NULL;
-
- become_root(0);
- smbpw = getsmbpwnam(user);
- unbecome_root(0);
-
- if (smbpw == NULL)
- {
- DEBUG(0,("check_lanman_password: getsmbpwnam returned NULL\n"));
- return False;
- }
-
- if (smbpw->acct_ctrl & ACB_DISABLED)
- {
- DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
- return False;
- }
-
- if ((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
- {
- uchar no_pw[14];
- memset(no_pw, '\0', 14);
- E_P16(no_pw, null_pw);
- smbpw->smb_passwd = null_pw;
- } else if (smbpw->smb_passwd == NULL) {
- DEBUG(0,("check_lanman_password: no lanman password !\n"));
- return False;
- }
-
- /* Get the new lanman hash. */
- D_P16(smbpw->smb_passwd, pass2, unenc_new_pw);
-
- /* Use this to get the old lanman hash. */
- D_P16(unenc_new_pw, pass1, unenc_old_pw);
-
- /* Check that the two old passwords match. */
- if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
- {
- DEBUG(0,("check_lanman_password: old password doesn't match.\n"));
- return False;
- }
-
- *psmbpw = smbpw;
- return True;
-}
-
-/***********************************************************
- Code to change the lanman hashed password.
- It nulls out the NT hashed password as it will
- no longer be valid.
-************************************************************/
-
-BOOL change_lanman_password(struct smb_passwd *smbpw, uchar *pass1, uchar *pass2)
-{
- static uchar null_pw[16];
- uchar unenc_new_pw[16];
- BOOL ret;
-
- if (smbpw == NULL)
- {
- DEBUG(0,("change_lanman_password: no smb password entry.\n"));
- return False;
- }
-
- if (smbpw->acct_ctrl & ACB_DISABLED)
- {
- DEBUG(0,("change_lanman_password: account %s disabled.\n", smbpw->smb_name));
- return False;
- }
-
- if ((smbpw->smb_passwd == NULL) && (smbpw->acct_ctrl & ACB_PWNOTREQ))
- {
- uchar no_pw[14];
- memset(no_pw, '\0', 14);
- E_P16(no_pw, null_pw);
- smbpw->smb_passwd = null_pw;
- } else if (smbpw->smb_passwd == NULL) {
- DEBUG(0,("change_lanman_password: no lanman password !\n"));
- return False;
- }
-
- /* Get the new lanman hash. */
- D_P16(smbpw->smb_passwd, pass2, unenc_new_pw);
-
- smbpw->smb_passwd = unenc_new_pw;
- smbpw->smb_nt_passwd = NULL; /* We lose the NT hash. Sorry. */
-
- /* Now write it into the file. */
- become_root(0);
- ret = mod_smbpwd_entry(smbpw,False);
- unbecome_root(0);
-
- return ret;
-}
-
-/***********************************************************
- Code to check and change the OEM hashed password.
-************************************************************/
-BOOL pass_oem_change(char *user,
- uchar *lmdata, uchar *lmhash,
- uchar *ntdata, uchar *nthash)
-{
- fstring new_passwd;
- struct smb_passwd *sampw;
- BOOL ret = check_oem_password( user, lmdata, lmhash, ntdata, nthash,
- &sampw,
- new_passwd, sizeof(new_passwd));
-
- /*
- * At this point we have the new case-sensitive plaintext
- * password in the fstring new_passwd. If we wanted to synchronise
- * with UNIX passwords we would call a UNIX password changing
- * function here. However it would have to be done as root
- * as the plaintext of the old users password is not
- * available. JRA.
- */
-
- if ( ret && lp_unix_password_sync())
- {
- ret = chgpasswd(user,"", new_passwd, True);
- }
-
- if (ret)
- {
- ret = change_oem_password( sampw, new_passwd, False );
- }
-
- memset(new_passwd, 0, sizeof(new_passwd));
-
- return ret;
-}
-
-/***********************************************************
Code to check the OEM hashed password.
this function ignores the 516 byte nt OEM hashed password
but does use the lm OEM password to check the nt hashed-hash.
************************************************************/
-BOOL check_oem_password(char *user,
- uchar *lmdata, uchar *lmhash,
- uchar *ntdata, uchar *nthash,
- struct smb_passwd **psmbpw, char *new_passwd,
- int new_passwd_size)
+static BOOL check_oem_password(const char *user,
+ const uchar *_lmdata, const uchar *lmhash,
+ const uchar *_ntdata, const uchar *nthash,
+ struct smb_passwd **psmbpw, UNISTR2 *new_passwd)
{
static uchar null_pw[16];
static uchar null_ntpw[16];
struct smb_passwd *smbpw = NULL;
- int new_pw_len;
uchar new_ntp16[16];
uchar unenc_old_ntpw[16];
uchar new_p16[16];
uchar unenc_old_pw[16];
char no_pw[2];
+ uint32 len;
+ uchar lmdata[516];
+ uchar ntdata[516];
- BOOL nt_pass_set = (ntdata != NULL && nthash != NULL);
+ BOOL nt_pass_set = (_ntdata != NULL && nthash != NULL);
+
+ if (_lmdata != NULL)
+ {
+ memcpy(lmdata, _lmdata, sizeof(lmdata));
+ }
+
+ if (_ntdata != NULL)
+ {
+ memcpy(ntdata, _ntdata, sizeof(ntdata));
+ }
become_root(False);
- *psmbpw = smbpw = getsmbpwnam(user);
+ (*psmbpw) = smbpw = getsmbpwnam(user);
unbecome_root(False);
if (smbpw == NULL)
@@ -639,7 +505,7 @@ BOOL check_oem_password(char *user,
return False;
}
- if (smbpw->acct_ctrl & ACB_DISABLED)
+ if (IS_BITS_SET_ALL(smbpw->acct_ctrl, ACB_DISABLED))
{
DEBUG(0,("check_lanman_password: account %s disabled.\n", user));
return False;
@@ -682,44 +548,21 @@ BOOL check_oem_password(char *user,
*/
SamOEMhash( (uchar *)lmdata, (uchar *)smbpw->smb_passwd, True);
- /*
- * The length of the new password is in the last 4 bytes of
- * the data buffer.
- */
-
- new_pw_len = IVAL(lmdata, 512);
- if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1)
+ if (!decode_pw_buffer(lmdata, (char*)new_passwd->buffer, 256, &len))
{
- DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len));
return False;
}
- if (nt_pass_set)
- {
- /*
- * nt passwords are in unicode
- */
- int uni_pw_len = new_pw_len;
- char *pw;
- new_pw_len /= 2;
- pw = dos_unistrn2((uint16*)(&lmdata[512-uni_pw_len]), new_pw_len);
- memcpy(new_passwd, pw, new_pw_len+1);
- }
- else
- {
- memcpy(new_passwd, &lmdata[512-new_pw_len], new_pw_len);
- new_passwd[new_pw_len] = '\0';
- }
-
/*
* To ensure we got the correct new password, hash it and
* use it as a key to test the passed old password.
*/
- nt_lm_owf_gen(new_passwd, new_ntp16, new_p16);
-
if (!nt_pass_set)
{
+ DEBUG(10,("check_oem_password: non-unicode\n"));
+ nt_lm_owf_gen((char*)new_passwd->buffer, new_ntp16, new_p16);
+
/*
* Now use new_p16 as the key to see if the old
* password matches.
@@ -733,10 +576,17 @@ BOOL check_oem_password(char *user,
}
#ifdef DEBUG_PASSWORD
- DEBUG(100,("check_oem_password: password %s ok\n", new_passwd));
+ DEBUG(100,("check_oem_password: password %s ok\n",
+ (char*)new_passwd->buffer));
#endif
return True;
}
+ else
+ {
+ new_passwd->uni_max_len = len / 2;
+ new_passwd->uni_str_len = len / 2;
+ nt_lm_owf_genW(new_passwd, new_ntp16, new_p16);
+ }
/*
* Now use new_p16 as the key to see if the old
@@ -745,6 +595,12 @@ BOOL check_oem_password(char *user,
D_P16(new_ntp16, lmhash, unenc_old_pw);
D_P16(new_ntp16, nthash, unenc_old_ntpw);
+#ifdef DEBUG_PASSWORD
+ dump_data(100, lmhash, 16);
+ dump_data(100, unenc_old_pw, 16);
+ dump_data(100, new_ntp16, 16);
+ dump_data(100, smbpw->smb_passwd, 16);
+#endif
if (memcmp(smbpw->smb_passwd, unenc_old_pw, 16))
{
DEBUG(0,("check_oem_password: old lm password doesn't match.\n"));
@@ -757,78 +613,142 @@ BOOL check_oem_password(char *user,
return False;
}
#ifdef DEBUG_PASSWORD
- DEBUG(100,("check_oem_password: password %s ok\n", new_passwd));
+ DEBUG(100,("check_oem_password: password ok\n"));
#endif
return True;
}
/***********************************************************
+ Code to check and change the OEM hashed password.
+************************************************************/
+BOOL pass_oem_change(const char *user,
+ const uchar *lmdata, const uchar *lmhash,
+ const uchar *ntdata, const uchar *nthash)
+{
+ UNISTR2 new_passwd;
+ struct smb_passwd *sampw = NULL;
+ BOOL ret = check_oem_password( user, lmdata, lmhash, ntdata, nthash,
+ &sampw,
+ &new_passwd);
+
+ /* now we check to see if we are actually allowed to change the
+ password. */
+
+ if (ret && (sampw == NULL ||
+ IS_BITS_SET_ALL(sampw->acct_ctrl,ACB_PWLOCK)))
+ {
+ if (sampw == NULL)
+ {
+ DEBUG(3,("pass_oem_change: account %s not known\n",
+ user));
+ }
+ else
+ {
+ DEBUG(3,("pass_oem_change: account %s disabled (%x)\n",
+ user, sampw->acct_ctrl));
+ }
+ ret = False;
+ }
+
+ /*
+ * At this point we have the new case-sensitive plaintext
+ * password in the fstring new_passwd. If we wanted to synchronise
+ * with UNIX passwords we would call a UNIX password changing
+ * function here. However it would have to be done as root
+ * as the plaintext of the old users password is not
+ * available. JRA.
+ */
+
+ if ( ret && lp_unix_password_sync())
+ {
+ ret = chgpasswd(user,"", (char*)new_passwd.buffer, True);
+ }
+
+ if (ret)
+ {
+ ret = change_oem_password( sampw, &new_passwd,
+ ntdata != NULL, False );
+ }
+
+ ZERO_STRUCT(new_passwd);
+
+ return ret;
+}
+
+/***********************************************************
Code to change the oem password. Changes both the lanman
and NT hashes.
override = False, normal
override = True, override XXXXXXXXXX'd password
************************************************************/
-BOOL change_oem_password(struct smb_passwd *smbpw, char *new_passwd, BOOL override)
+BOOL change_oem_password(struct smb_passwd *smbpw, UNISTR2 *new_passwd,
+ BOOL unicode, BOOL override)
{
- int ret;
- uchar new_nt_p16[16];
- uchar new_p16[16];
+ int ret;
+ uchar new_nt_p16[16];
+ uchar new_p16[16];
- nt_lm_owf_gen(new_passwd, new_nt_p16, new_p16);
+ DEBUG(100,("change_oem_password: %d\n", __LINE__));
- smbpw->smb_passwd = new_p16;
- smbpw->smb_nt_passwd = new_nt_p16;
-
- /* Now write it into the file. */
- become_root(0);
- ret = mod_smbpwd_entry(smbpw,override);
- unbecome_root(0);
+ if (unicode)
+ {
+ nt_lm_owf_genW(new_passwd, new_nt_p16, new_p16);
+ }
+ else
+ {
+ nt_lm_owf_gen((char*)new_passwd->buffer, new_nt_p16, new_p16);
+ }
- memset(new_passwd, '\0', strlen(new_passwd));
+ DEBUG(100,("change_oem_password: %d\n", __LINE__));
+ dbgflush();
- return ret;
-}
+ smbpw->smb_passwd = new_p16;
+ smbpw->smb_nt_passwd = new_nt_p16;
-/***********************************************************
- Code to check a plaintext password against smbpasswd entries.
-***********************************************************/
+ DEBUG(100,("change_oem_password: %d\n", __LINE__));
+ dbgflush();
-BOOL check_plaintext_password(char *user,char *old_passwd,
- int old_passwd_size, struct smb_passwd **psmbpw)
-{
- struct smb_passwd *smbpw = NULL;
- uchar old_pw[16],old_ntpw[16];
+ /* Now write it into the file. */
+ become_root(0);
+ ret = mod_smbpwd_entry(smbpw,override);
+ unbecome_root(0);
- become_root(False);
- *psmbpw = smbpw = getsmbpwnam(user);
- unbecome_root(False);
+ ZERO_STRUCTP(new_passwd);
- if (smbpw == NULL) {
- DEBUG(0,("check_plaintext_password: getsmbpwnam returned NULL\n"));
- return False;
- }
+ return ret;
+}
- if (smbpw->acct_ctrl & ACB_DISABLED) {
- DEBUG(0,("check_plaintext_password: account %s disabled.\n", user));
- return(False);
- }
+/****************************************************************************
+update the encrypted smbpasswd file from the plaintext username and password
+*****************************************************************************/
+BOOL update_smbpassword_file(const char *user, const char *password)
+{
+ struct smb_passwd *smbpw;
+ UNISTR2 newpw;
+ BOOL ret;
+
+ become_root(0);
+ smbpw = getsmbpwnam(user);
+ unbecome_root(0);
+
+ if(smbpw == NULL)
+ {
+ DEBUG(0,("getsmbpwnam returned NULL\n"));
+ return False;
+ }
+
+ make_unistr2(&newpw, password, password != NULL ? strlen(password) : 0);
- nt_lm_owf_gen(old_passwd,old_ntpw,old_pw);
+ /* Here, the flag is one, because we want to ignore the
+ XXXXXXX'd out password */
+ ret = change_oem_password( smbpw, &newpw, True, True);
+ if (!ret)
+ {
+ DEBUG(3,("change_oem_password returned False\n"));
+ }
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("check_plaintext_password: smbpw->smb_nt_passwd \n"));
- dump_data(100,smbpw->smb_nt_passwd,16);
- DEBUG(100,("check_plaintext_password: old_ntpw \n"));
- dump_data(100,old_ntpw,16);
- DEBUG(100,("check_plaintext_password: smbpw->smb_passwd \n"));
- dump_data(100,smbpw->smb_passwd,16);
- DEBUG(100,("check_plaintext_password: old_pw\n"));
- dump_data(100,old_pw,16);
-#endif
+ ZERO_STRUCT(newpw);
- if(memcmp(smbpw->smb_nt_passwd,old_ntpw,16) && memcmp(smbpw->smb_passwd,old_pw,16))
- return(False);
- else
- return(True);
+ return ret;
}
diff --git a/source/smbd/close.c b/source/smbd/close.c
index 8e2ed0de0e6..f588f248487 100644
--- a/source/smbd/close.c
+++ b/source/smbd/close.c
@@ -23,6 +23,9 @@
extern int DEBUGLEVEL;
+extern int32 global_oplocks_open;
+
+
/****************************************************************************
run a file if it is a magic script
****************************************************************************/
@@ -69,8 +72,6 @@ static void close_filestruct(files_struct *fsp)
{
connection_struct *conn = fsp->conn;
- flush_write_cache(fsp, CLOSE_FLUSH);
-
fsp->open = False;
fsp->is_directory = False;
@@ -79,6 +80,13 @@ static void close_filestruct(files_struct *fsp)
free((char *)fsp->wbmpx_ptr);
fsp->wbmpx_ptr = NULL;
}
+
+#if WITH_MMAP
+ if(fsp->mmap_ptr) {
+ munmap(fsp->mmap_ptr,fsp->mmap_size);
+ fsp->mmap_ptr = NULL;
+ }
+#endif
}
/****************************************************************************
@@ -89,15 +97,13 @@ static void close_filestruct(files_struct *fsp)
the closing of the connection. In the latter case printing and
magic scripts are not run.
****************************************************************************/
-
-static int close_normal_file(files_struct *fsp, BOOL normal_close)
+void close_file(files_struct *fsp, BOOL normal_close)
{
SMB_DEV_T dev = fsp->fd_ptr->dev;
SMB_INO_T inode = fsp->fd_ptr->inode;
- BOOL last_reference = False;
- BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
+ BOOL last_reference = False;
+ BOOL delete_on_close = fsp->fd_ptr->delete_on_close;
connection_struct *conn = fsp->conn;
- int err = 0;
remove_pending_lock_requests_by_fid(fsp);
@@ -112,22 +118,22 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
del_share_mode(fsp);
}
- if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- release_file_oplock(fsp);
-
- locking_close_file(fsp);
-
- if(fd_attempt_close(fsp, &err) == 0)
+ if(fd_attempt_close(fsp) == 0)
last_reference = True;
- fsp->fd_ptr = NULL;
+ fsp->fd_ptr = NULL;
if (lp_share_modes(SNUM(conn)))
unlock_share_entry(conn, dev, inode);
/* NT uses smbclose to start a print - weird */
if (normal_close && fsp->print_file)
- print_file(conn, fsp);
+ {
+ vuser_key key;
+ key.pid = getpid();
+ key.vuid = fsp->vuid;
+ print_file(conn, &key, SNUM(conn), fsp);
+ }
/* check for magic scripts */
if (normal_close) {
@@ -155,47 +161,31 @@ with error %s\n", fsp->fsp_name, strerror(errno) ));
}
}
- DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
+ if(fsp->granted_oplock == True)
+ global_oplocks_open--;
+
+ fsp->sent_oplock_break = False;
+
+ DEBUG(2,("%s closed file %s (numopen=%d)\n",
conn->user,fsp->fsp_name,
- conn->num_files_open, err ? strerror(err) : ""));
+ conn->num_files_open));
if (fsp->fsp_name) {
string_free(&fsp->fsp_name);
}
file_free(fsp);
-
- return err;
}
/****************************************************************************
Close a directory opened by an NT SMB call.
****************************************************************************/
-static int close_directory(files_struct *fsp, BOOL normal_close)
+void close_directory(files_struct *fsp)
{
remove_pending_change_notify_requests_by_fid(fsp);
/*
- * NT can set delete_on_close of the last open
- * reference to a directory also.
- */
-
- if (normal_close && fsp->directory_delete_on_close) {
- BOOL ok = rmdir_internals(fsp->conn, fsp->fsp_name);
- DEBUG(5,("close_directory: %s. Delete on close was set - deleting directory %s.\n",
- fsp->fsp_name, ok ? "succeeded" : "failed" ));
-
- /*
- * Ensure we remove any change notify requests that would
- * now fail as the directory has been deleted.
- */
-
- if(ok)
- remove_pending_change_notify_requests_by_filename(fsp);
- }
-
- /*
* Do the code common to files and directories.
*/
close_filestruct(fsp);
@@ -204,35 +194,5 @@ static int close_directory(files_struct *fsp, BOOL normal_close)
string_free(&fsp->fsp_name);
file_free(fsp);
-
- return 0;
}
-/****************************************************************************
- Close a file opened with null permissions in order to read permissions.
-****************************************************************************/
-
-static int close_statfile(files_struct *fsp, BOOL normal_close)
-{
- close_filestruct(fsp);
-
- if (fsp->fsp_name)
- string_free(&fsp->fsp_name);
-
- file_free(fsp);
-
- return 0;
-}
-
-/****************************************************************************
- Close a directory opened by an NT SMB call.
-****************************************************************************/
-
-int close_file(files_struct *fsp, BOOL normal_close)
-{
- if(fsp->is_directory)
- return close_directory(fsp, normal_close);
- else if(fsp->stat_open)
- return close_statfile(fsp, normal_close);
- return close_normal_file(fsp, normal_close);
-}
diff --git a/source/smbd/conn.c b/source/smbd/conn.c
index 83289b21848..fcec05acce7 100644
--- a/source/smbd/conn.c
+++ b/source/smbd/conn.c
@@ -110,15 +110,16 @@ connection_struct *conn_new(void)
ZERO_STRUCTP(conn);
conn->cnum = i;
+ conn->smbd_pid = getpid();
bitmap_set(bmap, i);
num_open++;
- string_set(&conn->user,"");
- string_set(&conn->dirpath,"");
- string_set(&conn->connectpath,"");
- string_set(&conn->origpath,"");
+ string_init(&conn->user,"");
+ string_init(&conn->dirpath,"");
+ string_init(&conn->connectpath,"");
+ string_init(&conn->origpath,"");
DLIST_ADD(Connections, conn);
diff --git a/source/smbd/connection.c b/source/smbd/connection.c
index 9a678ba88f3..fc025bc826a 100644
--- a/source/smbd/connection.c
+++ b/source/smbd/connection.c
@@ -27,11 +27,6 @@ static TDB_CONTEXT *tdb;
extern int DEBUGLEVEL;
-#ifdef WITH_UTMP
-static void utmp_yield(pid_t pid, const connection_struct *conn);
-static void utmp_claim(const struct connections_data *crec, const connection_struct *conn);
-#endif
-
/****************************************************************************
delete a connection record
****************************************************************************/
@@ -53,12 +48,6 @@ BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
kbuf.dsize = sizeof(key);
tdb_delete(tdb, kbuf);
-
-#ifdef WITH_UTMP
- if(conn)
- utmp_yield(key.pid, conn);
-#endif
-
return(True);
}
@@ -71,7 +60,6 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
struct connections_key key;
struct connections_data crec;
TDB_DATA kbuf, dbuf;
- extern int Client;
if (max_connections <= 0)
return(True);
@@ -106,213 +94,12 @@ BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOO
crec.start = time(NULL);
StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
- StrnCpy(crec.addr,conn?conn->client_address:client_addr(Client),sizeof(crec.addr)-1);
+ StrnCpy(crec.addr,conn?conn->client_address:client_connection_addr(),sizeof(crec.addr)-1);
dbuf.dptr = (char *)&crec;
dbuf.dsize = sizeof(crec);
if (tdb_store(tdb, kbuf, dbuf, TDB_REPLACE) != 0) return False;
-#ifdef WITH_UTMP
- if (conn)
- utmp_claim(&crec, conn);
-#endif
-
return True;
}
-
-#ifdef WITH_UTMP
-
-/****************************************************************************
-Reflect connection status in utmp/wtmp files.
- T.D.Lee@durham.ac.uk September 1999
-
-Hints for porting:
- o Always attempt to use programmatic interface (pututline() etc.)
- o The "x" (utmpx/wtmpx; HAVE_UTMPX_H) seems preferable.
-
-OS status:
- Solaris 2.x: Tested on 2.6 and 2.7; should be OK on other flavours.
- T.D.Lee@durham.ac.uk
- HPUX 9.x: Not tested. Appears not to have "x".
- IRIX 6.5: Not tested. Appears to have "x".
-
-Notes:
- The 4 byte 'ut_id' component is vital to distinguish connections,
- of which there could be several hundered or even thousand.
- Entries seem to be printable characters, with optional NULL pads.
-
- We need to be distinct from other entries in utmp/wtmp.
-
- Observed things: therefore avoid them. Add to this list please.
- From Solaris 2.x (because that's what I have):
- 'sN' : run-levels; N: [0-9]
- 'co' : console
- 'CC' : arbitrary things; C: [a-z]
- 'rXNN' : rlogin; N: [0-9]; X: [0-9a-z]
- 'tXNN' : rlogin; N: [0-9]; X: [0-9a-z]
- '/NNN' : Solaris CDE
- 'ftpZ' : ftp (Z is the number 255, aka 0377, aka 0xff)
- Mostly a record uses the same 'ut_id' in both "utmp" and "wtmp",
- but differences have been seen.
-
- Arbitrarily I have chosen to use a distinctive 'SM' for the
- first two bytes.
-
- The remaining two encode the connection number used in samba locking
- functions "claim_connection() and "yield_connection()". This seems
- to be a "nicely behaved" number: starting from 0 then working up
- looking for an available slot.
-
-****************************************************************************/
-
-#include <utmp.h>
-
-#ifdef HAVE_UTMPX_H
-#include <utmpx.h>
-#endif
-
-static const char *ut_id_encstr =
- "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
-
-static
-int
-ut_id_encode(int i, char *fourbyte)
-{
- int nbase;
-
- fourbyte[0] = 'S';
- fourbyte[1] = 'M';
-
-/*
- * Encode remaining 2 bytes from 'i'.
- * 'ut_id_encstr' is the character set on which modulo arithmetic is done.
- * Example: digits would produce the base-10 numbers from '001'.
- */
- nbase = strlen(ut_id_encstr);
-
- fourbyte[3] = ut_id_encstr[i % nbase];
- i /= nbase;
- fourbyte[2] = ut_id_encstr[i % nbase];
- i /= nbase;
-
- return(i); /* 0: good; else overflow */
-}
-
-static int utmp_fill(struct utmp *u, const connection_struct *conn, pid_t pid, int i)
-{
- struct timeval timeval;
- int rc;
-
- pstrcpy(u->ut_user, conn->user);
- rc = ut_id_encode(i, u->ut_id);
- slprintf(u->ut_line, 12, "smb/%d", i);
-
- u->ut_pid = pid;
-
- gettimeofday(&timeval, NULL);
- u->ut_time = timeval.tv_sec;
-
- return(rc);
-}
-
-static void utmp_update(const pstring dirname, const struct utmp *u, const char *host)
-{
- pstring fname;
-
-#ifdef HAVE_UTMPX_H
- struct utmpx ux, *uxrc;
-
- getutmpx(u, &ux);
- if (host) {
- ux.ut_syslen = strlen(host);
- pstrcpy(ux.ut_host, host);
- }
-
- pstrcpy(fname, dirname);
- pstrcat(fname, "utmpx");
- utmpxname(fname);
- uxrc = pututxline(&ux);
- if (uxrc == NULL) {
- DEBUG(2,("utmp_update: pututxline() failed\n"));
- return;
- }
-
- pstrcpy(fname, dirname);
- pstrcat(fname, "wtmpx");
- updwtmpx(fname, &ux);
-#else
- pstrcpy(fname, dirname);
- pstrcat(fname, "utmp");
-
- utmpname(fname);
- pututline(u);
-
- pstrcpy(fname, dirname);
- pstrcat(fname, "wtmp");
-
- /* *** OK. Appending wtmp (as distinct from overwriting utmp) has
- me baffled. How is it to be done? *** */
-#endif
-}
-
-static void utmp_yield(int pid, const connection_struct *conn)
-{
- struct utmp u;
- pstring dirname;
-
- if (! lp_utmp(SNUM(conn))) {
- DEBUG(2,("utmp_yield: lp_utmp() NULL\n"));
- return;
- }
-
- pstrcpy(dirname,lp_utmpdir());
- trim_string(dirname,"","/");
- pstrcat(dirname,"/");
-
- DEBUG(2,("utmp_yield: dir:%s conn: user:%s cnum:%d i:%d\n",
- dirname, conn->user, conn->cnum, conn->cnum));
-
- memset((char *)&u, '\0', sizeof(struct utmp));
- u.ut_type = DEAD_PROCESS;
- u.ut_exit.e_termination = 0;
- u.ut_exit.e_exit = 0;
- if (utmp_fill(&u, conn, pid, conn->cnum) == 0) {
- utmp_update(dirname, &u, NULL);
- }
-}
-
-static void utmp_claim(const struct connections_data *crec, const connection_struct *conn)
-{
- extern int Client;
- struct utmp u;
- pstring dirname;
-
- if (conn == NULL) {
- DEBUG(2,("utmp_claim: conn NULL\n"));
- return;
- }
-
- if (! lp_utmp(SNUM(conn))) {
- DEBUG(2,("utmp_claim: lp_utmp() NULL\n"));
- return;
- }
-
- pstrcpy(dirname,lp_utmpdir());
- trim_string(dirname,"","/");
- pstrcat(dirname,"/");
-
- DEBUG(2,("utmp_claim: dir:%s conn: user:%s cnum:%d i:%d\n",
- dirname, conn->user, conn->cnum, conn->cnum));
- DEBUG(2,("utmp_claim: crec: pid:%d, cnum:%d name:%s addr:%s mach:%s DNS:%s\n",
- crec->pid, crec->cnum, crec->name, crec->addr, crec->machine, client_name(Client)));
-
-
- memset((char *)&u, '\0', sizeof(struct utmp));
- u.ut_type = USER_PROCESS;
- if (utmp_fill(&u, conn, crec->pid, conn->cnum) == 0) {
- utmp_update(dirname, &u, crec->machine);
- }
-}
-
-#endif
diff --git a/source/smbd/dfree.c b/source/smbd/dfree.c
index 7866d60277d..8cba8d0644a 100644
--- a/source/smbd/dfree.c
+++ b/source/smbd/dfree.c
@@ -27,7 +27,7 @@ extern int DEBUGLEVEL;
/****************************************************************************
normalise for DOS usage
****************************************************************************/
-static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+static void disk_norm(SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
{
/* check if the disk is beyond the max disk size */
SMB_BIG_UINT maxdisksize = lp_maxdisksize();
@@ -39,23 +39,18 @@ static void disk_norm(BOOL small_query, SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,
/* the -1 should stop applications getting div by 0
errors */
}
-
+
while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) {
*dfree /= 2;
*dsize /= 2;
*bsize *= 2;
- if(small_query) {
- /*
- * Force max to fit in 16 bit fields.
- */
- if (*bsize > (WORDMAX*512)) {
- *bsize = (WORDMAX*512);
- if (*dsize > WORDMAX)
- *dsize = WORDMAX;
- if (*dfree > WORDMAX)
- *dfree = WORDMAX;
- break;
- }
+ if (*bsize > WORDMAX) {
+ *bsize = WORDMAX;
+ if (*dsize > WORDMAX)
+ *dsize = WORDMAX;
+ if (*dfree > WORDMAX)
+ *dfree = WORDMAX;
+ break;
}
}
}
@@ -157,7 +152,7 @@ static int fsusage(const char *path, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
#endif /* STAT_STATFS4 */
-#if defined(STAT_STATVFS) || defined(STAT_STATVFS64) /* SVR4 */
+#ifdef STAT_STATVFS /* SVR4 */
# define CONVERT_BLOCKS(B) \
adjust_blocks ((SMB_BIG_UINT)(B), fsd.f_frsize ? (SMB_BIG_UINT)fsd.f_frsize : (SMB_BIG_UINT)fsd.f_bsize, (SMB_BIG_UINT)512)
@@ -190,68 +185,17 @@ static int fsusage(const char *path, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
/****************************************************************************
return number of 1K blocks available on a path and total number
****************************************************************************/
-
-static SMB_BIG_UINT disk_free(char *path, BOOL small_query,
- SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+static SMB_BIG_UINT disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
{
int dfree_retval;
SMB_BIG_UINT dfree_q = 0;
SMB_BIG_UINT bsize_q = 0;
SMB_BIG_UINT dsize_q = 0;
- char *dfree_command;
(*dfree) = (*dsize) = 0;
(*bsize) = 512;
-
- /*
- * If external disk calculation specified, use it.
- */
-
- dfree_command = lp_dfree_command();
- if (dfree_command && *dfree_command) {
- pstring line;
- char *p;
- FILE *pp;
-
- slprintf (line, sizeof(pstring) - 1, "%s %s", dfree_command, path);
- DEBUG (3, ("disk_free: Running command %s\n", line));
-
- pp = sys_popen(line, "r");
- if (pp) {
- fgets(line, sizeof(pstring), pp);
- line[sizeof(pstring)-1] = '\0';
- if (strlen(line) > 0)
- line[strlen(line)-1] = '\0';
-
- DEBUG (3, ("Read input from dfree, \"%s\"\n", line));
-
- *dsize = (SMB_BIG_UINT)strtoul(line, &p, 10);
- while (p && *p & isspace(*p))
- p++;
- if (p && *p)
- *dfree = (SMB_BIG_UINT)strtoul(p, &p, 10);
- while (p && *p & isspace(*p))
- p++;
- if (p && *p)
- *bsize = (SMB_BIG_UINT)strtoul(p, NULL, 10);
- else
- *bsize = 1024;
- sys_pclose (pp);
- DEBUG (3, ("Parsed output of dfree, dsize=%u, dfree=%u, bsize=%u\n",
- (unsigned int)*dsize, (unsigned int)*dfree, (unsigned int)*bsize));
-
- if (!*dsize)
- *dsize = 2048;
- if (!*dfree)
- *dfree = 1024;
- } else {
- DEBUG (0, ("disk_free: sys_popen() failed for command %s. Error was : %s\n",
- line, strerror(errno) ));
- fsusage(path, dfree, dsize);
- }
- } else
- fsusage(path, dfree, dsize);
+ fsusage(path, dfree, dsize);
if (disk_quotas(path, &bsize_q, &dfree_q, &dsize_q)) {
(*bsize) = bsize_q;
@@ -275,7 +219,7 @@ static SMB_BIG_UINT disk_free(char *path, BOOL small_query,
*dfree = MAX(1,*dfree);
}
- disk_norm(small_query,bsize,dfree,dsize);
+ disk_norm(bsize,dfree,dsize);
if ((*bsize) < 1024) {
dfree_retval = (*dfree)/(1024/(*bsize));
@@ -290,8 +234,7 @@ static SMB_BIG_UINT disk_free(char *path, BOOL small_query,
/****************************************************************************
wrap it to get filenames right
****************************************************************************/
-SMB_BIG_UINT sys_disk_free(char *path, BOOL small_query,
- SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
+SMB_BIG_UINT sys_disk_free(char *path,SMB_BIG_UINT *bsize,SMB_BIG_UINT *dfree,SMB_BIG_UINT *dsize)
{
- return(disk_free(dos_to_unix(path,False),small_query, bsize,dfree,dsize));
+ return(disk_free(dos_to_unix(path,False),bsize,dfree,dsize));
}
diff --git a/source/smbd/dfs.c b/source/smbd/dfs.c
new file mode 100644
index 00000000000..55433f2c479
--- /dev/null
+++ b/source/smbd/dfs.c
@@ -0,0 +1,255 @@
+
+#include "includes.h"
+
+extern int DEBUGLEVEL;
+
+dfs_internal dfs_struct;
+extern pstring global_myname;
+
+/****************************************************************************
+read a line and split it
+****************************************************************************/
+static BOOL parse_dfs_text_entry(char *line, dfs_internal_table *buf)
+{
+#define MAXTOK 4
+ char *tok[MAXTOK+1];
+ int count = 0;
+
+ tok[count] = strtok(line,":");
+
+ /* strip the comment lines */
+ if (tok[0][0] == '#') return (False);
+ count++;
+
+ while ( ((tok[count] = strtok(NULL,":")) != NULL ) && count < MAXTOK)
+ {
+ count++;
+ }
+
+ DEBUG(7,("Found [%d] tokens\n", count));
+
+ if (count > 1) {
+ StrnCpy(buf->localpath, tok[0], sizeof(buf->localpath)-1);
+ StrnCpy(buf->sharename, tok[1], sizeof(buf->sharename)-1);
+/*
+ strupper(buf->localpath);
+ strupper(buf->sharename);
+*/
+ buf->localpath_length = strlen(buf->localpath);
+ buf->sharename_length = strlen(buf->sharename);
+ }
+ else
+ return (False);
+
+ if (count > 2)
+ buf->proximity = atoi(tok[2]);
+ else
+ buf->proximity = 0;
+
+ if (count > 3)
+ buf->type = atoi(tok[3]);
+ else
+ buf->type = 2;
+
+ DEBUGADD(7,("localpath: [%s]\n", buf->localpath));
+ DEBUGADD(7,("sharename: [%s]\n", buf->sharename));
+ return True;
+}
+
+/****************************************************************************
+mangle the localpath and store it.
+****************************************************************************/
+static void mangle_dfs_path(dfs_internal_table *buf)
+{
+ char *p;
+ char *mp;
+ char *q;
+ int mlen;
+
+ fstring temp;
+
+ p = buf->localpath;
+ mp = buf->mangledpath;
+ mlen = sizeof(buf->mangledpath);
+
+ ZERO_STRUCTP(mp);
+ DEBUG(2, ("DFS name is: [%s]\n", buf->localpath));
+
+ /* copy the head: \server-name\ */
+ q = strchr(p + 1, '\\');
+ safe_strcpy(mp, p, mlen);
+ p = q + 1;
+
+ while (q != NULL)
+ {
+ q = strchr(p, '\\');
+
+ safe_strcpy(temp, p, sizeof(temp));
+
+ if (!is_8_3(temp, True))
+ {
+ mangle_name_83(temp);
+ }
+
+ safe_strcat(mp, temp, mlen);
+
+ if (q != NULL)
+ {
+ safe_strcat(mp, "\\", mlen);
+ }
+ p = q + 1;
+ }
+
+/*
+ strupper(mp);
+*/
+ buf->mangledpath_length = strlen(mp);
+ DEBUGADD(2, ("DFS mangled name is: [%s]\n", mp));
+}
+
+/****************************************************************************
+initialisation de la table dfs en memoire au demarrage de samba
+****************************************************************************/
+BOOL init_dfs_table(void)
+{
+ char *file = lp_dfs_map();
+ int num_lines = 0;
+ int total = 0;
+ FILE *f;
+ pstring line;
+ int i;
+
+ dfs_internal_table *entry;
+
+ entry = NULL;
+ dfs_struct.ready = False;
+
+ if (*file == '\0') {
+ DEBUG(0,("No DFS map, Samba is running in NON DFS mode\n"));
+ return False;
+ }
+
+ f = sys_fopen(file, "r");
+ if (!f) {
+ DEBUG(0,("No DFS map file, Samba is running in NON DFS mode\n"));
+ return False;
+ }
+
+ while ( fgets(line, sizeof(pstring), f) )
+ {
+ entry = Realloc(entry,sizeof(dfs_internal_table)*(total+1));
+ if (! entry)
+ {
+ total = 0;
+ break;
+ }
+
+ if ( parse_dfs_text_entry(line, &(entry[total]) ) )
+ {
+ total++;
+ }
+ num_lines++;
+ }
+ dfs_struct.size = total;
+ dfs_struct.table = entry;
+ fclose(f);
+
+ /* we have the file in memory */
+ /* now initialise the mangled names */
+ for (i = 0; i < total; i++)
+ {
+ mangle_dfs_path(&(entry[i]));
+ }
+
+ dfs_struct.ready = True;
+ DEBUG(0,("Samba is DFS aware now!\n"));
+ return True;
+}
+
+static BOOL check_dfs_path(int search_len, const char *search_path,
+ int path_len, const char* fullpath,
+ const char* sharename,
+ const char* share_path, size_t share_len,
+ char *localpath, size_t local_plen)
+{
+ if (StrnCaseCmp(search_path, fullpath, search_len) != 0)
+ {
+ return False;
+ }
+
+ DEBUG(2,("found one linked to [%s]. share_path: %s\n",
+ sharename, share_path));
+
+ if (StrnCaseCmp(fullpath, share_path, share_len) == 0)
+ {
+ safe_strcpy(localpath, fullpath + share_len, local_plen);
+ }
+ else
+ {
+ localpath[0] = 0;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+ check if a path name is a DFS branch
+****************************************************************************/
+int under_dfs(connection_struct *conn, const char *path,
+ char *local_path, size_t local_plen)
+{
+ fstring fullpath;
+ pstring share_path;
+ int i;
+ int snum;
+
+ int path_len;
+ int share_len;
+
+ dfs_internal_table *list = dfs_struct.table;
+
+ snum = SNUM(conn);
+ snprintf(share_path, sizeof(share_path), "\\%s\\%s",
+ global_myname, lp_servicename(snum));
+ share_len = strlen(share_path);
+
+ if (path[0] != '\\')
+ {
+ snprintf(fullpath, sizeof(fullpath), "%s\\%s",
+ share_path, path);
+ }
+ else
+ {
+ safe_strcpy(fullpath, path, sizeof(fullpath));
+ }
+
+ path_len = strlen(fullpath);
+
+ DEBUG(2,("DFS looking for: [%s]\n", fullpath));
+
+ for (i = 0; i < dfs_struct.size; i++)
+ {
+ DEBUG(6,("checking against [%s][%d]\n", list[i].localpath,i));
+
+ if (check_dfs_path(list[i].localpath_length,
+ list[i].localpath,
+ path_len, fullpath,
+ list[i].sharename,
+ share_path, share_len,
+ local_path, local_plen))
+ {
+ return True;
+ }
+
+ if (check_dfs_path(list[i].mangledpath_length,
+ list[i].mangledpath,
+ path_len, fullpath,
+ list[i].sharename,
+ share_path, share_len,
+ local_path, local_plen))
+ {
+ return True;
+ }
+ }
+ return False;
+}
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index 58b0061e19d..b7c3177ce2c 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -27,378 +27,257 @@ extern int DEBUGLEVEL;
This module implements directory related functions for Samba.
*/
-typedef struct _dptr_struct {
- struct _dptr_struct *next, *prev;
- int dnum;
- uint16 spid;
+
+
+static uint32 dircounter = 0;
+
+
+#define NUMDIRPTRS 256
+
+
+static struct dptr_struct {
+ int pid;
connection_struct *conn;
+ uint32 lastused;
void *ptr;
+ BOOL valid;
+ BOOL finished;
BOOL expect_close;
char *wcard; /* Field only used for trans2_ searches */
uint16 attr; /* Field only used for trans2_ searches */
char *path;
-} dptr_struct;
+}
+dirptrs[NUMDIRPTRS];
-static struct bitmap *dptr_bmap;
-static dptr_struct *dirptrs;
static int dptrs_open = 0;
-#define INVALID_DPTR_KEY (-3)
-
/****************************************************************************
- Initialise the dir bitmap.
+initialise the dir array
****************************************************************************/
-
void init_dptrs(void)
{
static BOOL dptrs_init=False;
+ int i;
- if (dptrs_init)
- return;
-
- dptr_bmap = bitmap_allocate(MAX_DIRECTORY_HANDLES);
-
- if (!dptr_bmap)
- exit_server("out of memory in init_dptrs\n");
-
+ if (dptrs_init) return;
+ for (i=0;i<NUMDIRPTRS;i++)
+ {
+ dirptrs[i].valid = False;
+ dirptrs[i].wcard = NULL;
+ dirptrs[i].ptr = NULL;
+ string_init(&dirptrs[i].path,"");
+ }
dptrs_init = True;
}
/****************************************************************************
- Idle a dptr - the directory is closed but the control info is kept.
+idle a dptr - the directory is closed but the control info is kept
****************************************************************************/
-
-static void dptr_idle(dptr_struct *dptr)
+static void dptr_idle(int key)
{
- if (dptr->ptr) {
- DEBUG(4,("Idling dptr dnum %d\n",dptr->dnum));
+ if (dirptrs[key].valid && dirptrs[key].ptr) {
+ DEBUG(4,("Idling dptr key %d\n",key));
dptrs_open--;
- CloseDir(dptr->ptr);
- dptr->ptr = NULL;
- }
+ CloseDir(dirptrs[key].ptr);
+ dirptrs[key].ptr = NULL;
+ }
}
/****************************************************************************
- Idle the oldest dptr.
+idle the oldest dptr
****************************************************************************/
-
static void dptr_idleoldest(void)
{
- dptr_struct *dptr;
-
- /*
- * Go to the end of the list.
- */
- for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
- ;
-
- if(!dptr) {
- DEBUG(0,("No dptrs available to idle ?\n"));
- return;
- }
-
- /*
- * Idle the oldest pointer.
- */
-
- for(; dptr; dptr = dptr->prev) {
- if (dptr->ptr) {
- dptr_idle(dptr);
- return;
+ int i;
+ uint32 old=dircounter+1;
+ int oldi= -1;
+ for (i=0;i<NUMDIRPTRS;i++)
+ if (dirptrs[i].valid && dirptrs[i].ptr && dirptrs[i].lastused < old) {
+ old = dirptrs[i].lastused;
+ oldi = i;
}
- }
+ if (oldi != -1)
+ dptr_idle(oldi);
+ else
+ DEBUG(0,("No dptrs available to idle??\n"));
}
/****************************************************************************
- Get the dptr_struct for a dir index.
+get the dir ptr for a dir index
****************************************************************************/
-
-static dptr_struct *dptr_get(int key, BOOL forclose)
-{
- dptr_struct *dptr;
-
- for(dptr = dirptrs; dptr; dptr = dptr->next) {
- if(dptr->dnum == key) {
- if (!forclose && !dptr->ptr) {
- if (dptrs_open >= MAX_OPEN_DIRECTORIES)
- dptr_idleoldest();
- DEBUG(4,("Reopening dptr key %d\n",key));
- if ((dptr->ptr = OpenDir(dptr->conn, dptr->path, True)))
- dptrs_open++;
- }
- DLIST_PROMOTE(dirptrs,dptr);
- return dptr;
- }
- }
- return(NULL);
-}
-
-/****************************************************************************
- Get the dptr ptr for a dir index.
-****************************************************************************/
-
-static void *dptr_ptr(int key)
-{
- dptr_struct *dptr = dptr_get(key, False);
-
- if (dptr)
- return(dptr->ptr);
- return(NULL);
+static void *dptr_get(int key,uint32 lastused)
+{
+ struct dptr_struct *dp = &dirptrs[key];
+
+ if (dp->valid) {
+ if (lastused) dp->lastused = lastused;
+ if (!dp->ptr) {
+ if (dptrs_open >= MAX_OPEN_DIRECTORIES)
+ dptr_idleoldest();
+ DEBUG(4,("Reopening dptr key %d\n",key));
+ if ((dp->ptr = OpenDir(dp->conn, dp->path, True)))
+ dptrs_open++;
+ }
+ return(dp->ptr);
+ }
+ return(NULL);
}
/****************************************************************************
- Get the dir path for a dir index.
+get the dir path for a dir index
****************************************************************************/
-
char *dptr_path(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
-
- if (dptr)
- return(dptr->path);
+ if (dirptrs[key].valid)
+ return(dirptrs[key].path);
return(NULL);
}
/****************************************************************************
- Get the dir wcard for a dir index (lanman2 specific).
+get the dir wcard for a dir index (lanman2 specific)
****************************************************************************/
-
char *dptr_wcard(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
-
- if (dptr)
- return(dptr->wcard);
+ if (dirptrs[key].valid)
+ return(dirptrs[key].wcard);
return(NULL);
}
/****************************************************************************
- Set the dir wcard for a dir index (lanman2 specific).
- Returns 0 on ok, 1 on fail.
+set the dir wcard for a dir index (lanman2 specific)
+Returns 0 on ok, 1 on fail.
****************************************************************************/
-
BOOL dptr_set_wcard(int key, char *wcard)
{
- dptr_struct *dptr = dptr_get(key, False);
-
- if (dptr) {
- dptr->wcard = wcard;
+ if (dirptrs[key].valid) {
+ dirptrs[key].wcard = wcard;
return True;
}
return False;
}
/****************************************************************************
- Set the dir attrib for a dir index (lanman2 specific).
- Returns 0 on ok, 1 on fail.
+set the dir attrib for a dir index (lanman2 specific)
+Returns 0 on ok, 1 on fail.
****************************************************************************/
-
BOOL dptr_set_attr(int key, uint16 attr)
{
- dptr_struct *dptr = dptr_get(key, False);
-
- if (dptr) {
- dptr->attr = attr;
+ if (dirptrs[key].valid) {
+ dirptrs[key].attr = attr;
return True;
}
return False;
}
/****************************************************************************
- Get the dir attrib for a dir index (lanman2 specific)
+get the dir attrib for a dir index (lanman2 specific)
****************************************************************************/
-
uint16 dptr_attr(int key)
{
- dptr_struct *dptr = dptr_get(key, False);
-
- if (dptr)
- return(dptr->attr);
+ if (dirptrs[key].valid)
+ return(dirptrs[key].attr);
return(0);
}
/****************************************************************************
- Close a dptr (internal func).
+close a dptr
****************************************************************************/
-
-static void dptr_close_internal(dptr_struct *dptr)
+void dptr_close(int key)
{
- DEBUG(4,("closing dptr key %d\n",dptr->dnum));
-
- DLIST_REMOVE(dirptrs, dptr);
-
- /*
- * Free the dnum in the bitmap. Remember the dnum value is always
- * biased by one with respect to the bitmap.
- */
-
- if(bitmap_query( dptr_bmap, dptr->dnum - 1) != True) {
- DEBUG(0,("dptr_close_internal : Error - closing dnum = %d and bitmap not set !\n",
- dptr->dnum ));
- }
-
- bitmap_clear(dptr_bmap, dptr->dnum - 1);
-
- if (dptr->ptr) {
- CloseDir(dptr->ptr);
- dptrs_open--;
- }
-
- /* Lanman 2 specific code */
- if (dptr->wcard)
- free(dptr->wcard);
- string_set(&dptr->path,"");
- free((char *)dptr);
-}
-
-/****************************************************************************
- Close a dptr given a key.
-****************************************************************************/
-
-void dptr_close(int *key)
-{
- dptr_struct *dptr;
-
- if(*key == INVALID_DPTR_KEY)
- return;
-
/* OS/2 seems to use -1 to indicate "close all directories" */
- if (*key == -1) {
- dptr_struct *next;
- for(dptr = dirptrs; dptr; dptr = next) {
- next = dptr->next;
- dptr_close_internal(dptr);
- }
- *key = INVALID_DPTR_KEY;
+ if (key == -1) {
+ int i;
+ for (i=0;i<NUMDIRPTRS;i++)
+ dptr_close(i);
return;
}
- dptr = dptr_get(*key, True);
-
- if (!dptr) {
- DEBUG(0,("Invalid key %d given to dptr_close\n", *key));
+ if (key < 0 || key >= NUMDIRPTRS) {
+ DEBUG(3,("Invalid key %d given to dptr_close\n",key));
return;
}
- dptr_close_internal(dptr);
-
- *key = INVALID_DPTR_KEY;
+ if (dirptrs[key].valid) {
+ DEBUG(4,("closing dptr key %d\n",key));
+ if (dirptrs[key].ptr) {
+ CloseDir(dirptrs[key].ptr);
+ dptrs_open--;
+ }
+ /* Lanman 2 specific code */
+ if (dirptrs[key].wcard)
+ free(dirptrs[key].wcard);
+ dirptrs[key].valid = False;
+ string_set(&dirptrs[key].path,"");
+ }
}
/****************************************************************************
- Close all dptrs for a cnum.
+close all dptrs for a cnum
****************************************************************************/
-
void dptr_closecnum(connection_struct *conn)
{
- dptr_struct *dptr, *next;
- for(dptr = dirptrs; dptr; dptr = next) {
- next = dptr->next;
- if (dptr->conn == conn)
- dptr_close_internal(dptr);
- }
+ int i;
+ for (i=0;i<NUMDIRPTRS;i++)
+ if (dirptrs[i].valid && dirptrs[i].conn == conn)
+ dptr_close(i);
}
/****************************************************************************
- Idle all dptrs for a cnum.
+idle all dptrs for a cnum
****************************************************************************/
-
void dptr_idlecnum(connection_struct *conn)
{
- dptr_struct *dptr;
- for(dptr = dirptrs; dptr; dptr = dptr->next) {
- if (dptr->conn == conn && dptr->ptr)
- dptr_idle(dptr);
- }
+ int i;
+ for (i=0;i<NUMDIRPTRS;i++)
+ if (dirptrs[i].valid && dirptrs[i].conn == conn && dirptrs[i].ptr)
+ dptr_idle(i);
}
/****************************************************************************
- Close a dptr that matches a given path, only if it matches the spid also.
+close a dptr that matches a given path, only if it matches the pid also
****************************************************************************/
-
-void dptr_closepath(char *path,uint16 spid)
+void dptr_closepath(char *path,int pid)
{
- dptr_struct *dptr, *next;
- for(dptr = dirptrs; dptr; dptr = next) {
- next = dptr->next;
- if (spid == dptr->spid && strequal(dptr->path,path))
- dptr_close_internal(dptr);
- }
+ int i;
+ for (i=0;i<NUMDIRPTRS;i++)
+ if (dirptrs[i].valid && pid == dirptrs[i].pid &&
+ strequal(dirptrs[i].path,path))
+ dptr_close(i);
}
/****************************************************************************
- Start a directory listing.
+ start a directory listing
****************************************************************************/
-
static BOOL start_dir(connection_struct *conn,char *directory)
{
- DEBUG(5,("start_dir dir=%s\n",directory));
+ DEBUG(5,("start_dir dir=%s\n",directory));
- if (!check_name(directory,conn))
- return(False);
+ if (!check_name(directory,conn))
+ return(False);
- if (! *directory)
- directory = ".";
-
- conn->dirptr = OpenDir(conn, directory, True);
- if (conn->dirptr) {
- dptrs_open++;
- string_set(&conn->dirpath,directory);
- return(True);
- }
+ if (! *directory)
+ directory = ".";
+
+ conn->dirptr = OpenDir(conn, directory, True);
+ if (conn->dirptr) {
+ dptrs_open++;
+ string_set(&conn->dirpath,directory);
+ return(True);
+ }
- return(False);
+ return(False);
}
-/****************************************************************************
- Try and close the oldest handle not marked for
- expect close in the hope that the client has
- finished with that one.
-****************************************************************************/
-
-static void dptr_close_oldest(BOOL old)
-{
- dptr_struct *dptr;
-
- /*
- * Go to the end of the list.
- */
- for(dptr = dirptrs; dptr && dptr->next; dptr = dptr->next)
- ;
-
- if(!dptr) {
- DEBUG(0,("No old dptrs available to close oldest ?\n"));
- return;
- }
-
- /*
- * If 'old' is true, close the oldest oldhandle dnum (ie. 1 < dnum < 256) that
- * does not have expect_close set. If 'old' is false, close
- * one of the new dnum handles.
- */
-
- for(; dptr; dptr = dptr->prev) {
- if ((old && (dptr->dnum < 256) && !dptr->expect_close) ||
- (!old && (dptr->dnum > 255))) {
- dptr_close_internal(dptr);
- return;
- }
- }
-}
/****************************************************************************
- Create a new dir ptr. If the flag old_handle is true then we must allocate
- from the bitmap range 0 - 255 as old SMBsearch directory handles are only
- one byte long. If old_handle is false we allocate from the range
- 256 - MAX_DIRECTORY_HANDLES. We bias the number we return by 1 to ensure
- a directory handle is never zero. All the above is folklore taught to
- me at Andrew's knee.... :-) :-). JRA.
+create a new dir ptr
****************************************************************************/
-
-int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect_close,uint16 spid)
+int dptr_create(connection_struct *conn,char *path, BOOL expect_close,int pid)
{
- dptr_struct *dptr;
+ int i;
+ uint32 old;
+ int oldi;
if (!start_dir(conn,path))
return(-2); /* Code to say use a unix error return code. */
@@ -406,101 +285,70 @@ int dptr_create(connection_struct *conn,char *path, BOOL old_handle, BOOL expect
if (dptrs_open >= MAX_OPEN_DIRECTORIES)
dptr_idleoldest();
- dptr = (dptr_struct *)malloc(sizeof(dptr_struct));
- if(!dptr) {
- DEBUG(0,("malloc fail in dptr_create.\n"));
- return -1;
- }
-
- ZERO_STRUCTP(dptr);
-
- if(old_handle) {
-
- /*
- * This is an old-style SMBsearch request. Ensure the
- * value we return will fit in the range 1-255.
- */
-
- dptr->dnum = bitmap_find(dptr_bmap, 0);
+ for (i=0;i<NUMDIRPTRS;i++)
+ if (!dirptrs[i].valid)
+ break;
+ if (i == NUMDIRPTRS) i = -1;
- if(dptr->dnum == -1 || dptr->dnum > 254) {
- /*
- * Try and close the oldest handle not marked for
- * expect close in the hope that the client has
- * finished with that one.
- */
-
- dptr_close_oldest(True);
-
- /* Now try again... */
- dptr->dnum = bitmap_find(dptr_bmap, 0);
-
- if(dptr->dnum == -1 || dptr->dnum > 254) {
- DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
- free((char *)dptr);
- return -1;
+ /* as a 2nd option, grab the oldest not marked for expect_close */
+ if (i == -1) {
+ old=dircounter+1;
+ oldi= -1;
+ for (i=0;i<NUMDIRPTRS;i++)
+ if (!dirptrs[i].expect_close && dirptrs[i].lastused < old) {
+ old = dirptrs[i].lastused;
+ oldi = i;
}
- }
- } else {
-
- /*
- * This is a new-style trans2 request. Allocate from
- * a range that will return 256 - MAX_DIRECTORY_HANDLES.
- */
-
- dptr->dnum = bitmap_find(dptr_bmap, 255);
-
- if(dptr->dnum == -1 || dptr->dnum < 255) {
-
- /*
- * Try and close the oldest handle close in the hope that
- * the client has finished with that one. This will only
- * happen in the case of the Win98 client bug where it leaks
- * directory handles.
- */
-
- dptr_close_oldest(False);
-
- /* Now try again... */
- dptr->dnum = bitmap_find(dptr_bmap, 255);
+ i = oldi;
+ }
- if(dptr->dnum == -1 || dptr->dnum < 255) {
- DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
- free((char *)dptr);
- return -1;
+ /* a 3rd option - grab the oldest one */
+ if (i == -1) {
+ old=dircounter+1;
+ oldi= -1;
+ for (i=0;i<NUMDIRPTRS;i++)
+ if (dirptrs[i].lastused < old) {
+ old = dirptrs[i].lastused;
+ oldi = i;
}
- }
+ i = oldi;
}
- bitmap_set(dptr_bmap, dptr->dnum);
-
- dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
+ if (i == -1) {
+ DEBUG(0,("Error - all dirptrs in use??\n"));
+ return(-1);
+ }
- dptr->ptr = conn->dirptr;
- string_set(&dptr->path,path);
- dptr->conn = conn;
- dptr->spid = spid;
- dptr->expect_close = expect_close;
- dptr->wcard = NULL; /* Only used in lanman2 searches */
- dptr->attr = 0; /* Only used in lanman2 searches */
+ if (dirptrs[i].valid)
+ dptr_close(i);
- DLIST_ADD(dirptrs, dptr);
+ dirptrs[i].ptr = conn->dirptr;
+ string_set(&dirptrs[i].path,path);
+ dirptrs[i].lastused = dircounter++;
+ dirptrs[i].finished = False;
+ dirptrs[i].conn = conn;
+ dirptrs[i].pid = pid;
+ dirptrs[i].expect_close = expect_close;
+ dirptrs[i].wcard = NULL; /* Only used in lanman2 searches */
+ dirptrs[i].attr = 0; /* Only used in lanman2 searches */
+ dirptrs[i].valid = True;
DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
- dptr->dnum,path,expect_close));
+ i,path,expect_close));
- return(dptr->dnum);
+ return(i);
}
+#define DPTR_MASK ((uint32)(((uint32)1)<<31))
+
/****************************************************************************
- Fill the 5 byte server reserved dptr field.
+fill the 5 byte server reserved dptr field
****************************************************************************/
-
BOOL dptr_fill(char *buf1,unsigned int key)
{
unsigned char *buf = (unsigned char *)buf1;
- void *p = dptr_ptr(key);
+ void *p = dptr_get(key,0);
uint32 offset;
if (!p) {
DEBUG(1,("filling null dirptr %d\n",key));
@@ -514,14 +362,22 @@ BOOL dptr_fill(char *buf1,unsigned int key)
return(True);
}
+
/****************************************************************************
- Fetch the dir ptr and seek it given the 5 byte server field.
+return True is the offset is at zero
****************************************************************************/
+BOOL dptr_zero(char *buf)
+{
+ return((IVAL(buf,1)&~DPTR_MASK) == 0);
+}
+/****************************************************************************
+fetch the dir ptr and seek it given the 5 byte server field
+****************************************************************************/
void *dptr_fetch(char *buf,int *num)
{
unsigned int key = *(unsigned char *)buf;
- void *p = dptr_ptr(key);
+ void *p = dptr_get(key,dircounter++);
uint32 offset;
if (!p) {
DEBUG(3,("fetched null dirptr %d\n",key));
@@ -536,12 +392,11 @@ void *dptr_fetch(char *buf,int *num)
}
/****************************************************************************
- Fetch the dir ptr.
+fetch the dir ptr.
****************************************************************************/
-
void *dptr_fetch_lanman2(int dptr_num)
{
- void *p = dptr_ptr(dptr_num);
+ void *p = dptr_get(dptr_num,dircounter++);
if (!p) {
DEBUG(3,("fetched null dirptr %d\n",dptr_num));
@@ -552,9 +407,8 @@ void *dptr_fetch_lanman2(int dptr_num)
}
/****************************************************************************
- Check a filetype for being valid.
+check a filetype for being valid
****************************************************************************/
-
BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype)
{
if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
@@ -563,9 +417,8 @@ BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int di
}
/****************************************************************************
- Get an 8.3 directory entry.
+ get a directory entry
****************************************************************************/
-
BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
SMB_OFF_T *size,int *mode,time_t *date,BOOL check_descend)
{
@@ -584,68 +437,64 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype,char *fname,
strequal(conn->dirpath,".") ||
strequal(conn->dirpath,"/"));
- needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
+ needslash =
+ ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
if (!conn->dirptr)
return(False);
while (!found)
- {
- BOOL filename_is_mask = False;
- dname = ReadDirName(conn->dirptr);
+ {
+ dname = ReadDirName(conn->dirptr);
- DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
- (long)conn->dirptr,TellDir(conn->dirptr)));
+ DEBUG(6,("readdir on dirptr 0x%lx now at offset %d\n",
+ (long)conn->dirptr,TellDir(conn->dirptr)));
- if (dname == NULL)
- return(False);
+ if (dname == NULL)
+ return(False);
- pstrcpy(filename,dname);
-
- if ((filename_is_mask = (strcmp(filename,mask) == 0)) ||
- (name_map_mangle(filename,True,False,SNUM(conn)) &&
- mask_match(filename,mask,False,False)))
- {
- if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
- continue;
-
- pstrcpy(fname,filename);
- *path = 0;
- pstrcpy(path,conn->dirpath);
- if(needslash)
- pstrcat(path,"/");
- pstrcpy(pathreal,path);
- pstrcat(path,fname);
- pstrcat(pathreal,dname);
- if (conn->vfs_ops.stat(dos_to_unix(pathreal, False), &sbuf) != 0)
- {
- DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
- continue;
- }
+ pstrcpy(filename,dname);
+
+ if ((strcmp(filename,mask) == 0) ||
+ (name_map_mangle(filename,True,SNUM(conn)) &&
+ mask_match(filename,mask,False,False)))
+ {
+ if (isrootdir && (strequal(filename,"..") || strequal(filename,".")))
+ continue;
+
+ pstrcpy(fname,filename);
+ *path = 0;
+ pstrcpy(path,conn->dirpath);
+ if(needslash)
+ pstrcat(path,"/");
+ pstrcpy(pathreal,path);
+ pstrcat(path,fname);
+ pstrcat(pathreal,dname);
+ if (conn->vfs_ops.stat(dos_to_unix(pathreal, False), &sbuf) != 0)
+ {
+ DEBUG(5,("Couldn't stat 1 [%s]\n",path));
+ continue;
+ }
+
+ if (check_descend &&
+ !strequal(fname,".") && !strequal(fname,".."))
+ continue;
- *mode = dos_mode(conn,pathreal,&sbuf);
+ *mode = dos_mode(conn,pathreal,&sbuf);
- if (!dir_check_ftype(conn,*mode,&sbuf,dirtype))
- {
- DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
- continue;
- }
+ if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) {
+ DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
+ continue;
+ }
- if (!filename_is_mask)
- {
- /* Now we can allow the mangled cache to be updated */
- pstrcpy(filename,dname);
- name_map_mangle(filename,True,True,SNUM(conn));
- }
-
- *size = sbuf.st_size;
- *date = sbuf.st_mtime;
+ *size = sbuf.st_size;
+ *date = sbuf.st_mtime;
- DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
+ DEBUG(5,("get_dir_entry found %s fname=%s\n",pathreal,fname));
- found = True;
+ found = True;
+ }
}
- }
return(found);
}
@@ -663,9 +512,8 @@ typedef struct
/*******************************************************************
- Open a directory.
+open a directory
********************************************************************/
-
void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
{
Dir *dirp;
@@ -684,11 +532,10 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
while ((n = vfs_readdirname(conn, p)))
{
- int l;
+ int l = strlen(n)+1;
pstring zn;
-
- pstrcpy(zn, unix_to_dos(n,True));
- l = strlen(zn)+1;
+
+ pstrcpy(zn, unix_to_dos(n, True));
/* If it's a vetoed file, pretend it doesn't even exist */
if (use_veto && conn && IS_VETO_PATH(conn, zn)) continue;
@@ -716,9 +563,8 @@ void *OpenDir(connection_struct *conn, char *name, BOOL use_veto)
/*******************************************************************
- Close a directory.
+close a directory
********************************************************************/
-
void CloseDir(void *p)
{
Dir *dirp = (Dir *)p;
@@ -728,9 +574,8 @@ void CloseDir(void *p)
}
/*******************************************************************
- Read from a directory.
+read from a directory
********************************************************************/
-
char *ReadDirName(void *p)
{
char *ret;
@@ -747,9 +592,8 @@ char *ReadDirName(void *p)
/*******************************************************************
- Seek a dir.
+seek a dir
********************************************************************/
-
BOOL SeekDir(void *p,int pos)
{
Dir *dirp = (Dir *)p;
@@ -767,9 +611,8 @@ BOOL SeekDir(void *p,int pos)
}
/*******************************************************************
- Tell a dir position.
+tell a dir position
********************************************************************/
-
int TellDir(void *p)
{
Dir *dirp = (Dir *)p;
@@ -779,32 +622,38 @@ int TellDir(void *p)
return(dirp->pos);
}
-/*******************************************************************************
- This section manages a global directory cache.
- (It should probably be split into a separate module. crh)
-********************************************************************************/
-typedef struct {
+/* -------------------------------------------------------------------------- **
+ * This section manages a global directory cache.
+ * (It should probably be split into a separate module. crh)
+ * -------------------------------------------------------------------------- **
+ */
+
+typedef struct
+ {
ubi_dlNode node;
char *path;
char *name;
char *dname;
int snum;
-} dir_cache_entry;
+ } dir_cache_entry;
static ubi_dlNewList( dir_cache );
-/*****************************************************************************
- Add an entry to the directory cache.
- Input: path -
- name -
- dname -
- snum -
- Output: None.
-*****************************************************************************/
-
void DirCacheAdd( char *path, char *name, char *dname, int snum )
-{
+ /* ------------------------------------------------------------------------ **
+ * Add an entry to the directory cache.
+ *
+ * Input: path -
+ * name -
+ * dname -
+ * snum -
+ *
+ * Output: None.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
int pathlen;
int namelen;
dir_cache_entry *entry;
@@ -835,23 +684,27 @@ void DirCacheAdd( char *path, char *name, char *dname, int snum )
while( DIRCACHESIZE < dir_cache->count )
free( ubi_dlRemTail( dir_cache ) );
-}
-
-/*****************************************************************************
- Search for an entry to the directory cache.
- Input: path -
- name -
- snum -
- Output: The dname string of the located entry, or NULL if the entry was
- not found.
+ } /* DirCacheAdd */
- Notes: This uses a linear search, which is is okay because of
- the small size of the cache. Use a splay tree or hash
- for large caches.
-*****************************************************************************/
char *DirCacheCheck( char *path, char *name, int snum )
-{
+ /* ------------------------------------------------------------------------ **
+ * Search for an entry to the directory cache.
+ *
+ * Input: path -
+ * name -
+ * snum -
+ *
+ * Output: The dname string of the located entry, or NULL if the entry was
+ * not found.
+ *
+ * Notes: This uses a linear search, which is is okay because of
+ * the small size of the cache. Use a splay tree or hash
+ * for large caches.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
dir_cache_entry *entry;
for( entry = (dir_cache_entry *)ubi_dlFirst( dir_cache );
@@ -868,15 +721,18 @@ char *DirCacheCheck( char *path, char *name, int snum )
}
return(NULL);
-}
-
-/*****************************************************************************
- Remove all cache entries which have an snum that matches the input.
- Input: snum -
- Output: None.
-*****************************************************************************/
+ } /* DirCacheCheck */
void DirCacheFlush(int snum)
+ /* ------------------------------------------------------------------------ **
+ * Remove all cache entries which have an snum that matches the input.
+ *
+ * Input: snum -
+ *
+ * Output: None.
+ *
+ * ------------------------------------------------------------------------ **
+ */
{
dir_cache_entry *entry;
ubi_dlNodePtr next;
@@ -888,4 +744,11 @@ void DirCacheFlush(int snum)
free( ubi_dlRemThis( dir_cache, entry ) );
entry = (dir_cache_entry *)next;
}
-}
+} /* DirCacheFlush */
+
+/* -------------------------------------------------------------------------- **
+ * End of the section that manages the global directory cache.
+ * -------------------------------------------------------------------------- **
+ */
+
+
diff --git a/source/smbd/dosmode.c b/source/smbd/dosmode.c
index 278a4ab5e3d..2923959b038 100644
--- a/source/smbd/dosmode.c
+++ b/source/smbd/dosmode.c
@@ -26,68 +26,33 @@ extern int DEBUGLEVEL;
/****************************************************************************
change a dos mode to a unix mode
base permission for files:
- if inheriting
- apply read/write bits from parent directory.
- else
- everybody gets read bit set
+ everybody gets read bit set
dos readonly is represented in unix by removing everyone's write bit
dos archive is represented in unix by the user's execute bit
dos system is represented in unix by the group's execute bit
dos hidden is represented in unix by the other's execute bit
- if !inheriting {
- Then apply create mask,
- then add force bits.
- }
+ Then apply create mask,
+ then add force bits.
base permission for directories:
dos directory is represented in unix by unix's dir bit and the exec bit
- if !inheriting {
- Then apply create mask,
- then add force bits.
- }
+ Then apply create mask,
+ then add force bits.
****************************************************************************/
-mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
+mode_t unix_mode(connection_struct *conn,int dosmode)
{
mode_t result = (S_IRUSR | S_IRGRP | S_IROTH);
- mode_t dir_mode = 0; /* Mode of the parent directory if inheriting. */
if ( !IS_DOS_READONLY(dosmode) )
result |= (S_IWUSR | S_IWGRP | S_IWOTH);
-
- if (fname && lp_inherit_perms(SNUM(conn))) {
- char *dname;
- SMB_STRUCT_STAT sbuf;
-
- dname = parent_dirname(fname);
- DEBUG(2,("unix_mode(%s) inheriting from %s\n",fname,dname));
- if (dos_stat(dname,&sbuf) != 0) {
- DEBUG(4,("unix_mode(%s) failed, [dir %s]: %s\n",fname,dname,strerror(errno)));
- return(0); /* *** shouldn't happen! *** */
- }
-
- /* Save for later - but explicitly remove setuid bit for safety. */
- dir_mode = sbuf.st_mode & ~S_ISUID;
- DEBUG(2,("unix_mode(%s) inherit mode %o\n",fname,(int)dir_mode));
- /* Clear "result" */
- result = 0;
- }
-
+
if (IS_DOS_DIR(dosmode)) {
/* We never make directories read only for the owner as under DOS a user
can always create a file in a read-only directory. */
- result |= (S_IFDIR | S_IWUSR);
-
- if (dir_mode) {
- /* Inherit mode of parent directory. */
- result |= dir_mode;
- } else {
- /* Provisionally add all 'x' bits */
- result |= (S_IXUSR | S_IXGRP | S_IXOTH);
-
- /* Apply directory mask */
- result &= lp_dir_mask(SNUM(conn));
- /* Add in force bits */
- result |= lp_force_dir_mode(SNUM(conn));
- }
+ result |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH | S_IWUSR);
+ /* Apply directory mask */
+ result &= lp_dir_mode(SNUM(conn));
+ /* Add in force bits */
+ result |= lp_force_dir_mode(SNUM(conn));
} else {
if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
result |= S_IXUSR;
@@ -97,17 +62,11 @@ mode_t unix_mode(connection_struct *conn,int dosmode,const char *fname)
if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
result |= S_IXOTH;
-
- if (dir_mode) {
- /* Inherit 666 component of parent directory mode */
- result |= dir_mode
- & (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH);
- } else {
- /* Apply mode mask */
- result &= lp_create_mask(SNUM(conn));
- /* Add in force bits */
- result |= lp_force_create_mode(SNUM(conn));
- }
+
+ /* Apply mode mask */
+ result &= lp_create_mode(SNUM(conn));
+ /* Add in force bits */
+ result |= lp_force_create_mode(SNUM(conn));
}
return(result);
}
@@ -196,7 +155,7 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *
if (dos_mode(conn,fname,st) == dosmode) return(0);
- unixmode = unix_mode(conn,dosmode,fname);
+ unixmode = unix_mode(conn,dosmode);
/* preserve the s bits */
mask |= (S_ISUID | S_ISGID);
@@ -220,9 +179,11 @@ int file_chmod(connection_struct *conn,char *fname,int dosmode,SMB_STRUCT_STAT *
}
/* if we previously had any w bits set then leave them alone
- whilst adding in the new w bits, if the new mode is not rdonly */
- if (!IS_DOS_READONLY(dosmode)) {
- unixmode |= (st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
+ if the new mode is not rdonly */
+ if (!IS_DOS_READONLY(dosmode) &&
+ (tmp = st->st_mode & (S_IWUSR|S_IWGRP|S_IWOTH))) {
+ unixmode &= ~(S_IWUSR|S_IWGRP|S_IWOTH);
+ unixmode |= tmp;
}
return(conn->vfs_ops.chmod(dos_to_unix(fname,False),unixmode));
@@ -290,8 +251,9 @@ BOOL set_filetime(connection_struct *conn, char *fname, time_t mtime)
if (file_utime(conn, fname, &times)) {
DEBUG(4,("set_filetime(%s) failed: %s\n",fname,strerror(errno)));
- return False;
}
return(True);
}
+
+
diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c
index 348486d4300..1e166275152 100644
--- a/source/smbd/fileio.c
+++ b/source/smbd/fileio.c
@@ -23,7 +23,6 @@
extern int DEBUGLEVEL;
-static BOOL setup_write_cache(files_struct *, SMB_OFF_T);
/****************************************************************************
seek a file. Try to avoid the seek if possible
@@ -39,18 +38,6 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos)
seek_ret = fsp->conn->vfs_ops.lseek(fsp->fd_ptr->fd,pos+offset,SEEK_SET);
- /*
- * We want to maintain the fiction that we can seek
- * on a fifo for file system purposes. This allows
- * people to set up UNIX fifo's that feed data to Windows
- * applications. JRA.
- */
-
- if((seek_ret == -1) && (errno == ESPIPE)) {
- seek_ret = pos+offset;
- errno = 0;
- }
-
if((seek_ret == -1) || (seek_ret != pos+offset)) {
DEBUG(0,("seek_file: sys_lseek failed. Error was %s\n", strerror(errno) ));
fsp->pos = -1;
@@ -66,29 +53,6 @@ SMB_OFF_T seek_file(files_struct *fsp,SMB_OFF_T pos)
}
/****************************************************************************
- Read from write cache if we can.
-****************************************************************************/
-
-static unsigned int cache_read_hits;
-
-BOOL read_from_write_cache(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
-{
- write_cache *wcp = fsp->wcp;
-
- if(!wcp)
- return False;
-
- if(n > wcp->data_size || pos < wcp->offset || pos + n > wcp->offset + wcp->data_size)
- return False;
-
- memcpy(data, wcp->data + (pos - wcp->offset), n);
-
- cache_read_hits++;
-
- return True;
-}
-
-/****************************************************************************
read from a file
****************************************************************************/
@@ -98,7 +62,7 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
#if USE_READ_PREDICTION
if (!fsp->can_write) {
- ret = read_predict(fsp->fd_ptr->fd,pos,data,NULL,n);
+ ret = read_predict(fsp, fsp->fd_ptr->fd,pos,data,NULL,n);
data += ret;
n -= ret;
@@ -106,19 +70,25 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
}
#endif
- /*
- * Serve from write cache if we can.
- */
- if(read_from_write_cache(fsp, data, pos, n))
- return n;
-
- flush_write_cache(fsp, READ_FLUSH);
+#if WITH_MMAP
+ if (fsp->mmap_ptr) {
+ SMB_OFF_T num = (fsp->mmap_size > pos) ? (fsp->mmap_size - pos) : 0;
+ num = MIN(n,num);
+ if (num > 0) {
+ memcpy(data,fsp->mmap_ptr+pos,num);
+ data += num;
+ pos += num;
+ n -= num;
+ ret += num;
+ }
+ }
+#endif
if (seek_file(fsp,pos) == -1) {
DEBUG(3,("read_file: Failed to seek to %.0f\n",(double)pos));
return(ret);
}
-
+
if (n > 0) {
readret = fsp->conn->vfs_ops.read(fsp->fd_ptr->fd,data,n);
if (readret > 0) ret += readret;
@@ -127,43 +97,13 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
return(ret);
}
-/* Write cache static counters. */
-
-static unsigned int abutted_writes;
-static unsigned int total_writes;
-static unsigned int non_oplock_writes;
-static unsigned int direct_writes;
-static unsigned int init_writes;
-static unsigned int flushed_writes;
-static unsigned int num_perfect_writes;
-static unsigned int flush_reasons[NUM_FLUSH_REASONS];
-
-/* how many write cache buffers have been allocated */
-static unsigned int allocated_write_caches;
-static unsigned int num_write_caches;
-
-/****************************************************************************
- *Really* write to a file
-****************************************************************************/
-
-static ssize_t real_write_file(files_struct *fsp,char *data,SMB_OFF_T pos, size_t n)
-{
- if ((pos != -1) && (seek_file(fsp,pos) == -1))
- return -1;
-
- return write_data(fsp->fd_ptr->fd,data,n);
-}
/****************************************************************************
write to a file
****************************************************************************/
-ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
+ssize_t write_file(files_struct *fsp,char *data,size_t n)
{
- write_cache *wcp = fsp->wcp;
- ssize_t total_written = 0;
- int write_path = -1;
-
if (!fsp->can_write) {
errno = EPERM;
return(0);
@@ -172,489 +112,25 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
if (!fsp->modified) {
SMB_STRUCT_STAT st;
fsp->modified = True;
-
if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&st) == 0) {
int dosmode = dos_mode(fsp->conn,fsp->fsp_name,&st);
if (MAP_ARCHIVE(fsp->conn) && !IS_DOS_ARCHIVE(dosmode)) {
file_chmod(fsp->conn,fsp->fsp_name,dosmode | aARCH,&st);
}
-
- /*
- * If this is the first write and we have an exclusive oplock then setup
- * the write cache.
- */
-
- if ((fsp->oplock_type == EXCLUSIVE_OPLOCK) && !wcp) {
- setup_write_cache(fsp, st.st_size);
- wcp = fsp->wcp;
- }
}
}
- total_writes++;
- if (!fsp->oplock_type) {
- non_oplock_writes++;
- }
-
- /*
- * If this file is level II oplocked then we need
- * to grab the shared memory lock and inform all
- * other files with a level II lock that they need
- * to flush their read caches. We keep the lock over
- * the shared memory area whilst doing this.
- */
-
- if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
- SMB_DEV_T dev = fsp->fd_ptr->dev;
- SMB_INO_T inode = fsp->fd_ptr->inode;
- share_mode_entry *share_list = NULL;
- pid_t pid = getpid();
- int token = -1;
- int num_share_modes = 0;
- int i;
-
- if (lock_share_entry(fsp->conn, dev, inode) == False) {
- DEBUG(0,("write_file: failed to lock share mode entry for file %s.\n", fsp->fsp_name ));
- }
-
- num_share_modes = get_share_modes(fsp->conn, dev, inode, &share_list);
-
- for(i = 0; i < num_share_modes; i++) {
- share_mode_entry *share_entry = &share_list[i];
-
- /*
- * As there could have been multiple writes waiting at the lock_share_entry
- * gate we may not be the first to enter. Hence the state of the op_types
- * in the share mode entries may be partly NO_OPLOCK and partly LEVEL_II
- * oplock. It will do no harm to re-send break messages to those smbd's
- * that are still waiting their turn to remove their LEVEL_II state, and
- * also no harm to ignore existing NO_OPLOCK states. JRA.
- */
-
- if (share_entry->op_type == NO_OPLOCK)
- continue;
-
- /* Paranoia .... */
- if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) {
- DEBUG(0,("write_file: PANIC. share mode entry %d is an exlusive oplock !\n", i ));
- abort();
- }
-
- /*
- * Check if this is a file we have open (including the
- * file we've been called to do write_file on. If so
- * then break it directly without releasing the lock.
- */
-
- if (pid == share_entry->pid) {
- files_struct *new_fsp = file_find_dit(dev, inode, &share_entry->time);
-
- /* Paranoia check... */
- if(new_fsp == NULL) {
- DEBUG(0,("write_file: PANIC. share mode entry %d is not a local file !\n", i ));
- abort();
- }
- oplock_break_level2(new_fsp, True, token);
-
- } else {
-
- /*
- * This is a remote file and so we send an asynchronous
- * message.
- */
-
- request_oplock_break(share_entry, dev, inode);
- }
- }
-
- free((char *)share_list);
- unlock_share_entry(fsp->conn, dev, inode);
- }
-
- /* Paranoia check... */
- if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type)) {
- DEBUG(0,("write_file: PANIC. File %s still has a level II oplock.\n", fsp->fsp_name));
- abort();
- }
-
- if (total_writes % 500 == 0) {
- DEBUG(3,("WRITECACHE: initwrites=%u abutted=%u flushes=%u total=%u \
-nonop=%u allocated=%u active=%u direct=%u perfect=%u readhits=%u\n",
- init_writes, abutted_writes, flushed_writes, total_writes, non_oplock_writes,
- allocated_write_caches,
- num_write_caches, direct_writes, num_perfect_writes, cache_read_hits ));
-
- DEBUG(3,("WRITECACHE: SEEK=%d, READ=%d, WRITE=%d, READRAW=%d, OPLOCK=%d, CLOSE=%d, SYNC=%d\n",
- flush_reasons[SEEK_FLUSH],
- flush_reasons[READ_FLUSH],
- flush_reasons[WRITE_FLUSH],
- flush_reasons[READRAW_FLUSH],
- flush_reasons[OPLOCK_RELEASE_FLUSH],
- flush_reasons[CLOSE_FLUSH],
- flush_reasons[SYNC_FLUSH] ));
- }
-
- if(!wcp) {
- direct_writes++;
- return real_write_file(fsp, data, pos, n);
- }
-
- DEBUG(9,("write_file(fd=%d pos=%d size=%d) wofs=%d wsize=%d\n",
- fsp->fd_ptr->fd, (int)pos, (int)n, (int)wcp->offset, (int)wcp->data_size));
-
- /*
- * If we have active cache and it isn't contiguous then we flush.
- * NOTE: There is a small problem with running out of disk ....
- */
-
- if (wcp->data_size) {
-
- BOOL cache_flush_needed = False;
-
- if ((pos >= wcp->offset) && (pos <= wcp->offset + wcp->data_size)) {
-
- /*
- * Start of write overlaps or abutts the existing data.
- */
-
- size_t data_used = MIN((wcp->alloc_size - (pos - wcp->offset)), n);
-
- memcpy(wcp->data + (pos - wcp->offset), data, data_used);
-
- /*
- * Update the current buffer size with the new data.
- */
-
- if(pos + data_used > wcp->offset + wcp->data_size)
- wcp->data_size = pos + data_used - wcp->offset;
-
- /*
- * If we used all the data then
- * return here.
- */
-
- if(n == data_used)
- return n;
- else
- cache_flush_needed = True;
-
- /*
- * Move the start of data forward by the amount used,
- * cut down the amount left by the same amount.
- */
-
- data += data_used;
- pos += data_used;
- n -= data_used;
-
- abutted_writes++;
- total_written = data_used;
-
- write_path = 1;
-
- } else if ((pos < wcp->offset) && (pos + n > wcp->offset) &&
- (pos + n <= wcp->offset + wcp->alloc_size)) {
-
- /*
- * End of write overlaps the existing data.
- */
-
- size_t data_used = pos + n - wcp->offset;
-
- memcpy(wcp->data, data + n - data_used, data_used);
-
- /*
- * Update the current buffer size with the new data.
- */
-
- if(pos + n > wcp->offset + wcp->data_size)
- wcp->data_size = pos + n - wcp->offset;
-
- /*
- * We don't need to move the start of data, but we
- * cut down the amount left by the amount used.
- */
-
- n -= data_used;
-
- /*
- * We cannot have used all the data here.
- */
-
- cache_flush_needed = True;
-
- abutted_writes++;
- total_written = data_used;
-
- write_path = 2;
-
- } else if ( (pos >= wcp->file_size) &&
- (pos > wcp->offset + wcp->data_size) &&
- (pos < wcp->offset + wcp->alloc_size) ) {
-
- /*
- * Non-contiguous write part of which fits within
- * the cache buffer and is extending the file.
- */
-
- size_t data_used;
-
- if(pos + n <= wcp->offset + wcp->alloc_size)
- data_used = n;
- else
- data_used = wcp->offset + wcp->alloc_size - pos;
-
- /*
- * Fill in the non-continuous area with zeros.
- */
-
- memset(wcp->data + wcp->data_size, '\0',
- pos - (wcp->offset + wcp->data_size) );
-
- memcpy(wcp->data + (pos - wcp->offset), data, data_used);
-
- /*
- * Update the current buffer size with the new data.
- */
-
- if(pos + data_used > wcp->offset + wcp->data_size)
- wcp->data_size = pos + data_used - wcp->offset;
-
- /*
- * Update the known file length.
- */
-
- wcp->file_size = wcp->offset + wcp->data_size;
-
-#if 0
- if (set_filelen(fsp->fd_ptr->fd, wcp->file_size) == -1) {
- DEBUG(0,("write_file: error %s in setting file to length %.0f\n",
- strerror(errno), (double)wcp->file_size ));
- return -1;
- }
-#endif
-
- /*
- * If we used all the data then
- * return here.
- */
-
- if(n == data_used)
- return n;
- else
- cache_flush_needed = True;
-
- /*
- * Move the start of data forward by the amount used,
- * cut down the amount left by the same amount.
- */
-
- data += data_used;
- pos += data_used;
- n -= data_used;
-
- abutted_writes++;
- total_written = data_used;
-
- write_path = 3;
-
- } else {
-
- /*
- * Write is bigger than buffer, or there is no overlap on the
- * low or high ends.
- */
-
- DEBUG(9,("write_file: non cacheable write : fd = %d, pos = %.0f, len = %u, current cache pos = %.0f \
-len = %u\n",fsp->fd_ptr->fd, (double)pos, (unsigned int)n, (double)wcp->offset, (unsigned int)wcp->data_size ));
-
- /*
- * Update the file size if needed.
- */
-
- if(pos + n > wcp->file_size)
- wcp->file_size = pos + n;
-
- /*
- * If write would fit in the cache, and is larger than
- * the data already in the cache, flush the cache and
- * preferentially copy the data new data into it. Otherwise
- * just write the data directly.
- */
-
- if ( n <= wcp->alloc_size && n > wcp->data_size) {
- cache_flush_needed = True;
- } else {
- direct_writes++;
- return real_write_file(fsp, data, pos, n);
- }
-
- write_path = 4;
-
- }
-
- if(wcp->data_size > wcp->file_size)
- wcp->file_size = wcp->data_size;
-
- if (cache_flush_needed) {
- flushed_writes++;
-
- DEBUG(3,("WRITE_FLUSH:%d: due to noncontinuous write: fd = %d, size = %.0f, pos = %.0f, \
-n = %u, wcp->offset=%.0f, wcp->data_size=%u\n",
- write_path, fsp->fd_ptr->fd, (double)wcp->file_size, (double)pos, (unsigned int)n,
- (double)wcp->offset, (unsigned int)wcp->data_size ));
-
- flush_write_cache(fsp, WRITE_FLUSH);
- }
- }
-
- /*
- * If the write request is bigger than the cache
- * size, write it all out.
- */
-
- if (n > wcp->alloc_size ) {
- if(real_write_file(fsp, data, pos, n) == -1)
- return -1;
- direct_writes++;
- return total_written + n;
- }
-
- /*
- * If there's any data left, cache it.
- */
-
- if (n) {
- if (wcp->data_size) {
- abutted_writes++;
- DEBUG(9,("abutted write (%u)\n", abutted_writes));
- } else {
- init_writes++;
- }
- memcpy(wcp->data+wcp->data_size, data, n);
- if (wcp->data_size == 0) {
- wcp->offset = pos;
- num_write_caches++;
- }
- wcp->data_size += n;
- DEBUG(9,("cache return %u\n", (unsigned int)n));
- total_written += n;
- return total_written; /* .... that's a write :) */
- }
-
- return total_written;
+ return(vfs_write_data(fsp,data,n));
}
-/****************************************************************************
- Delete the write cache structure.
-****************************************************************************/
-
-void delete_write_cache(files_struct *fsp)
-{
- write_cache *wcp;
-
- if(!fsp)
- return;
-
- if(!(wcp = fsp->wcp))
- return;
-
- allocated_write_caches--;
-
- SMB_ASSERT(wcp->data_size == 0);
-
- free(wcp->data);
- free(wcp);
-
- fsp->wcp = NULL;
-}
-
-/****************************************************************************
- Setup the write cache structure.
-****************************************************************************/
-
-static BOOL setup_write_cache(files_struct *fsp, SMB_OFF_T file_size)
-{
- ssize_t alloc_size = lp_write_cache_size(SNUM(fsp->conn));
- write_cache *wcp;
-
- if (allocated_write_caches >= MAX_WRITE_CACHES) return False;
-
- if(alloc_size == 0 || fsp->wcp)
- return False;
-
- if((wcp = (write_cache *)malloc(sizeof(write_cache))) == NULL) {
- DEBUG(0,("setup_write_cache: malloc fail.\n"));
- return False;
- }
-
- wcp->file_size = file_size;
- wcp->offset = 0;
- wcp->alloc_size = alloc_size;
- wcp->data_size = 0;
- if((wcp->data = malloc(wcp->alloc_size)) == NULL) {
- DEBUG(0,("setup_write_cache: malloc fail for buffer size %u.\n",
- (unsigned int)wcp->alloc_size ));
- free(wcp);
- return False;
- }
-
- fsp->wcp = wcp;
- allocated_write_caches++;
-
- return True;
-}
-
-/****************************************************************************
- Cope with a size change.
-****************************************************************************/
-
-void set_filelen_write_cache(files_struct *fsp, SMB_OFF_T file_size)
-{
- if(fsp->wcp) {
- flush_write_cache(fsp, SIZECHANGE_FLUSH);
- fsp->wcp->file_size = file_size;
- }
-}
-
-/*******************************************************************
- Flush a write cache struct to disk.
-********************************************************************/
-
-ssize_t flush_write_cache(files_struct *fsp, enum flush_reason_enum reason)
-{
- write_cache *wcp = fsp->wcp;
- size_t data_size;
-
- if(!wcp || !wcp->data_size)
- return 0;
-
- data_size = wcp->data_size;
- wcp->data_size = 0;
-
- num_write_caches--;
-
- flush_reasons[(int)reason]++;
-
- DEBUG(9,("flushing write cache: fd = %d, off=%.0f, size=%u\n",
- fsp->fd_ptr->fd, (double)wcp->offset, (unsigned int)data_size));
-
- if(data_size == wcp->alloc_size)
- num_perfect_writes++;
-
- return real_write_file(fsp, wcp->data, wcp->offset, data_size);
-}
/*******************************************************************
sync a file
********************************************************************/
-void sys_fsync_file(connection_struct *conn, files_struct *fsp)
+void sys_sync_file(int fd)
{
#ifdef HAVE_FSYNC
- if(lp_strict_sync(SNUM(conn)) && fsp->fd_ptr != NULL) {
- flush_write_cache(fsp, SYNC_FLUSH);
- conn->vfs_ops.fsync(fsp->fd_ptr->fd);
- }
+ fsync(fd);
#endif
}
diff --git a/source/smbd/filename.c b/source/smbd/filename.c
index 729ef8c8099..504c35aeec4 100644
--- a/source/smbd/filename.c
+++ b/source/smbd/filename.c
@@ -3,8 +3,6 @@
Version 1.9.
filename handling routines
Copyright (C) Andrew Tridgell 1992-1998
- Copyright (C) Jeremy Allison 1999-200
- Copyright (C) Ying Chen 2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,10 +19,6 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/*
- * New hash table stat cache code added by Ying Chen.
- */
-
#include "includes.h"
extern int DEBUGLEVEL;
@@ -32,6 +26,7 @@ extern BOOL case_sensitive;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
extern fstring remote_machine;
+extern pstring global_myname;
extern BOOL use_mangled_map;
static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL docache);
@@ -102,12 +97,7 @@ static int global_stat_cache_hits;
void print_stat_cache_statistics(void)
{
- double eff;
-
- if(global_stat_cache_lookups == 0)
- return;
-
- eff = (100.0* (double)global_stat_cache_hits)/(double)global_stat_cache_lookups;
+ double eff = (100.0* (double)global_stat_cache_hits)/(double)global_stat_cache_lookups;
DEBUG(0,("stat cache stats: lookups = %d, hits = %d, misses = %d, \
stat cache was %f%% effective.\n", global_stat_cache_lookups,
@@ -115,12 +105,15 @@ stat cache was %f%% effective.\n", global_stat_cache_lookups,
}
typedef struct {
+ ubi_dlNode link;
int name_len;
- char names[2]; /* This is extended via malloc... */
+ pstring orig_name;
+ pstring translated_name;
} stat_cache_entry;
-#define INIT_STAT_CACHE_SIZE 512
-static hash_table stat_cache;
+#define MAX_STAT_CACHE_SIZE 50
+
+static ubi_dlList stat_cache = { NULL, (ubi_dlNodePtr)&stat_cache, 0};
/****************************************************************************
Compare a pathname to a name in the stat cache - of a given length.
@@ -131,7 +124,6 @@ static hash_table stat_cache;
case.
*****************************************************************************/
-#if 0 /* This function unused?? */
static BOOL stat_name_equal_len( char *stat_name, char *orig_name, int len)
{
BOOL matched = (memcmp( stat_name, orig_name, len) == 0);
@@ -140,7 +132,6 @@ static BOOL stat_name_equal_len( char *stat_name, char *orig_name, int len)
return matched;
}
-#endif
/****************************************************************************
Add an entry into the stat cache.
@@ -149,11 +140,9 @@ static BOOL stat_name_equal_len( char *stat_name, char *orig_name, int len)
static void stat_cache_add( char *full_orig_name, char *orig_translated_path)
{
stat_cache_entry *scp;
- stat_cache_entry *found_scp;
pstring orig_name;
pstring translated_path;
int namelen;
- hash_element *hash_elem;
if (!lp_stat_cache()) return;
@@ -201,39 +190,39 @@ static void stat_cache_add( char *full_orig_name, char *orig_translated_path)
* add it.
*/
- if ((hash_elem = hash_lookup(&stat_cache, orig_name))) {
- found_scp = (stat_cache_entry *)(hash_elem->value);
- if (strcmp((found_scp->names+found_scp->name_len+1), translated_path) == 0) {
- return;
- } else {
- hash_remove(&stat_cache, hash_elem);
- if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry)+2*namelen)) == NULL) {
- DEBUG(0,("stat_cache_add: Out of memory !\n"));
- return;
+ for( scp = (stat_cache_entry *)ubi_dlFirst( &stat_cache); scp;
+ scp = (stat_cache_entry *)ubi_dlNext( scp )) {
+ if((strcmp( scp->orig_name, orig_name) == 0) &&
+ (strcmp( scp->translated_name, translated_path) == 0)) {
+ /*
+ * Name does exist - promote it.
+ */
+ if( (stat_cache_entry *)ubi_dlFirst( &stat_cache) != scp ) {
+ ubi_dlRemThis( &stat_cache, scp);
+ ubi_dlAddHead( &stat_cache, scp);
}
- pstrcpy(scp->names, orig_name);
- pstrcpy((scp->names+namelen+1), translated_path);
- scp->name_len = namelen;
- hash_insert(&stat_cache, (char *)scp, orig_name);
+ return;
}
+ }
+
+ if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry))) == NULL) {
+ DEBUG(0,("stat_cache_add: Out of memory !\n"));
return;
- } else {
+ }
- /*
- * New entry.
- */
+ pstrcpy(scp->orig_name, orig_name);
+ pstrcpy(scp->translated_name, translated_path);
+ scp->name_len = namelen;
- if((scp = (stat_cache_entry *)malloc(sizeof(stat_cache_entry)+2*namelen)) == NULL) {
- DEBUG(0,("stat_cache_add: Out of memory !\n"));
- return;
- }
- pstrcpy(scp->names, orig_name);
- pstrcpy(scp->names+namelen+1, translated_path);
- scp->name_len = namelen;
- hash_insert(&stat_cache, (char *)scp, orig_name);
- }
+ ubi_dlAddHead( &stat_cache, scp);
- DEBUG(5,("stat_cache_add: Added entry %s -> %s\n", scp->names, (scp->names+scp->name_len+1)));
+ DEBUG(10,("stat_cache_add: Added entry %s -> %s\n", scp->orig_name, scp->translated_name ));
+
+ if(ubi_dlCount(&stat_cache) > lp_stat_cache_size()) {
+ scp = (stat_cache_entry *)ubi_dlRemTail( &stat_cache );
+ free((char *)scp);
+ return;
+ }
}
/****************************************************************************
@@ -241,18 +230,16 @@ static void stat_cache_add( char *full_orig_name, char *orig_translated_path)
Return True if we translated (and did a scuccessful stat on) the entire name.
*****************************************************************************/
-static BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath,
- char **start, SMB_STRUCT_STAT *pst)
+static BOOL stat_cache_lookup(struct connection_struct *conn, char *name,
+ char *dirpath, char **start,
+ SMB_STRUCT_STAT *pst)
{
stat_cache_entry *scp;
- char *trans_name;
+ stat_cache_entry *longest_hit = NULL;
pstring chk_name;
int namelen;
- hash_element *hash_elem;
- char *sp;
- if (!lp_stat_cache())
- return False;
+ if (!lp_stat_cache()) return False;
namelen = strlen(name);
@@ -271,47 +258,124 @@ static BOOL stat_cache_lookup(connection_struct *conn, char *name, char *dirpath
if(!case_sensitive)
strupper( chk_name );
- while (1) {
- hash_elem = hash_lookup(&stat_cache, chk_name);
- if(hash_elem == NULL) {
- /*
- * Didn't find it - remove last component for next try.
- */
- sp = strrchr(chk_name, '/');
- if (sp) {
- *sp = '\0';
- } else {
- /*
- * We reached the end of the name - no match.
- */
- global_stat_cache_misses++;
- return False;
- }
- if((*chk_name == '\0') || (strcmp(chk_name, ".") == 0)
- || (strcmp(chk_name, "..") == 0)) {
- global_stat_cache_misses++;
- return False;
+ for( scp = (stat_cache_entry *)ubi_dlFirst( &stat_cache); scp;
+ scp = (stat_cache_entry *)ubi_dlNext( scp )) {
+ if(scp->name_len <= namelen) {
+ if(stat_name_equal_len(scp->orig_name, chk_name, scp->name_len)) {
+ if((longest_hit == NULL) || (longest_hit->name_len <= scp->name_len))
+ longest_hit = scp;
}
- } else {
- scp = (stat_cache_entry *)(hash_elem->value);
- global_stat_cache_hits++;
- trans_name = scp->names+scp->name_len+1;
- if(conn->vfs_ops.stat(dos_to_unix(trans_name,False), pst) != 0) {
- /* Discard this entry - it doesn't exist in the filesystem. */
- hash_remove(&stat_cache, hash_elem);
- return False;
- }
- memcpy(name, trans_name, scp->name_len);
- *start = &name[scp->name_len];
- if(**start == '/')
- ++*start;
- StrnCpy( dirpath, trans_name, name - (*start));
- return (namelen == scp->name_len);
}
}
+
+ if(longest_hit == NULL) {
+ DEBUG(10,("stat_cache_lookup: cache miss on %s\n", name));
+ global_stat_cache_misses++;
+ return False;
+ }
+
+ global_stat_cache_hits++;
+
+ DEBUG(10,("stat_cache_lookup: cache hit for name %s. %s -> %s\n",
+ name, longest_hit->orig_name, longest_hit->translated_name ));
+
+ /*
+ * longest_hit is the longest match we got in the list.
+ * Check it exists - if so, overwrite the original name
+ * and then promote it to the top.
+ */
+
+ if(conn->vfs_ops.stat(dos_to_unix(longest_hit->translated_name,False),
+ pst) != 0) {
+ /*
+ * Discard this entry.
+ */
+ ubi_dlRemThis( &stat_cache, longest_hit);
+ free((char *)longest_hit);
+ return False;
+ }
+
+ memcpy(name, longest_hit->translated_name, longest_hit->name_len);
+ if( (stat_cache_entry *)ubi_dlFirst( &stat_cache) != longest_hit ) {
+ ubi_dlRemThis( &stat_cache, longest_hit);
+ ubi_dlAddHead( &stat_cache, longest_hit);
+ }
+
+ *start = &name[longest_hit->name_len];
+ if(**start == '/')
+ ++*start;
+
+ StrnCpy( dirpath, longest_hit->translated_name, name - (*start));
+
+ return (namelen == longest_hit->name_len);
}
/****************************************************************************
+ this routine converts from the dos and dfs namespace to the unix namespace.
+****************************************************************************/
+BOOL unix_dfs_convert(char *name,connection_struct *conn,
+ char *saved_last_component,
+ BOOL *bad_path, SMB_STRUCT_STAT *pst)
+{
+ pstring local_path;
+
+ DEBUG(10,("unix_dfs_convert: %s\n", name));
+
+ if (name != NULL &&
+ under_dfs(conn, name, local_path, sizeof(local_path)))
+ {
+ DEBUG(10,("%s is in dfs map.\n", name));
+
+ /* check for our own name */
+ if (StrCaseCmp(global_myname, name+1) > 0)
+ {
+ return False;
+ }
+
+ pstrcpy(name, local_path);
+
+ DEBUG(10,("removed name: %s\n", name));
+ }
+ return unix_convert(name, conn, saved_last_component, bad_path, pst);
+}
+
+
+/*******************************************************************
+reduce a file name, removing .. elements.
+********************************************************************/
+static void unix_clean_name(char *s)
+{
+ char *p=NULL;
+
+ DEBUG(3,("unix_clean_name [%s]\n",s));
+
+ /* remove any double slashes */
+ string_sub(s, "//","/");
+
+ /* Remove leading ./ characters */
+ if(strncmp(s, "./", 2) == 0) {
+ trim_string(s, "./", NULL);
+ if(*s == 0)
+ pstrcpy(s,"./");
+ }
+
+ while ((p = strstr(s,"/../")) != NULL)
+ {
+ pstring s1;
+
+ *p = 0;
+ pstrcpy(s1,p+3);
+
+ if ((p=strrchr(s,'/')) != NULL)
+ *p = 0;
+ else
+ *s = 0;
+ pstrcat(s,s1);
+ }
+
+ trim_string(s,NULL,"/..");
+}
+/****************************************************************************
This routine is called to convert names from the dos namespace to unix
namespace. It needs to handle any case conversions, mangling, format
changes etc.
@@ -332,14 +396,15 @@ used to pick the correct error code to return between ENOENT and ENOTDIR
as Windows applications depend on ERRbadpath being returned if a component
of a pathname does not exist.
****************************************************************************/
-
-BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
- BOOL *bad_path, SMB_STRUCT_STAT *pst)
+BOOL unix_convert(char *name,connection_struct *conn,
+ char *saved_last_component,
+ BOOL *bad_path, SMB_STRUCT_STAT *pst)
{
SMB_STRUCT_STAT st;
char *start, *end;
pstring dirpath;
pstring orig_path;
+ int saved_errno;
BOOL component_was_mangled = False;
BOOL name_has_wildcard = False;
#if 0
@@ -352,7 +417,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
*dirpath = 0;
*bad_path = False;
if(pst) {
- ZERO_STRUCTP(pst);
+ ZERO_STRUCTP(pst);
}
if(saved_last_component)
@@ -415,7 +480,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
for (s=name2 ; *s ; s++)
if (!issafe(*s)) *s = '_';
- pstrcpy(name,(char *)smbd_mktemp(name2));
+ pstrcpy(name,(char *)mktemp(name2));
}
return(True);
}
@@ -453,6 +518,8 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
return(True);
}
+ saved_errno = errno;
+
DEBUG(5,("unix_convert begin: name = %s, dirpath = %s, start = %s\n",
name, dirpath, start));
@@ -462,7 +529,7 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
*/
if (case_sensitive && !is_mangled(name) &&
- !lp_strip_dot() && !use_mangled_map)
+ !lp_strip_dot() && !use_mangled_map && (saved_errno != ENOENT))
return(False);
if(strchr(start,'?') || strchr(start,'*'))
@@ -635,6 +702,136 @@ BOOL unix_convert(char *name,connection_struct *conn,char *saved_last_component,
return(True);
}
+/*******************************************************************
+reduce a file name, removing .. elements and checking that
+it is below dir in the hierarchy. This uses GetWd() and so must be run
+on the system that has the referenced file system.
+
+widelinks are allowed if widelinks is true
+********************************************************************/
+
+static BOOL reduce_name(char *s,char *dir,BOOL widelinks)
+{
+#ifndef REDUCE_PATHS
+ return True;
+#else
+ pstring dir2;
+ pstring wd;
+ pstring base_name;
+ pstring newname;
+ char *p=NULL;
+ BOOL relative = (*s != '/');
+
+ *dir2 = *wd = *base_name = *newname = 0;
+
+ if (widelinks)
+ {
+ unix_clean_name(s);
+ /* can't have a leading .. */
+ if (strncmp(s,"..",2) == 0 && (s[2]==0 || s[2]=='/'))
+ {
+ DEBUG(3,("Illegal file name? (%s)\n",s));
+ return(False);
+ }
+
+ if (strlen(s) == 0)
+ pstrcpy(s,"./");
+
+ return(True);
+ }
+
+ DEBUG(3,("reduce_name [%s] [%s]\n",s,dir));
+
+ /* remove any double slashes */
+ string_sub(s,"//","/");
+
+ pstrcpy(base_name,s);
+ p = strrchr(base_name,'/');
+
+ if (!p)
+ return(True);
+
+ if (!dos_GetWd(wd))
+ {
+ DEBUG(0,("couldn't getwd for %s %s\n",s,dir));
+ return(False);
+ }
+
+ if (dos_ChDir(dir) != 0)
+ {
+ DEBUG(0,("couldn't chdir to %s\n",dir));
+ return(False);
+ }
+
+ if (!dos_GetWd(dir2))
+ {
+ DEBUG(0,("couldn't getwd for %s\n",dir));
+ dos_ChDir(wd);
+ return(False);
+ }
+
+
+ if (p && (p != base_name))
+ {
+ *p = 0;
+ if (strcmp(p+1,".")==0)
+ p[1]=0;
+ if (strcmp(p+1,"..")==0)
+ *p = '/';
+ }
+
+ if (dos_ChDir(base_name) != 0)
+ {
+ dos_ChDir(wd);
+ DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name));
+ return(False);
+ }
+
+ if (!dos_GetWd(newname))
+ {
+ dos_ChDir(wd);
+ DEBUG(2,("couldn't get wd for %s %s\n",s,dir2));
+ return(False);
+ }
+
+ if (p && (p != base_name))
+ {
+ pstrcat(newname,"/");
+ pstrcat(newname,p+1);
+ }
+
+ {
+ size_t l = strlen(dir2);
+ if (dir2[l-1] == '/')
+ l--;
+
+ if (strncmp(newname,dir2,l) != 0)
+ {
+ dos_ChDir(wd);
+ DEBUG(2,("Bad access attempt? s=%s dir=%s newname=%s l=%d\n",s,dir2,newname,l));
+ return(False);
+ }
+
+ if (relative)
+ {
+ if (newname[l] == '/')
+ pstrcpy(s,newname + l + 1);
+ else
+ pstrcpy(s,newname+l);
+ }
+ else
+ pstrcpy(s,newname);
+ }
+
+ dos_ChDir(wd);
+
+ if (strlen(s) == 0)
+ pstrcpy(s,"./");
+
+ DEBUG(3,("reduced to %s\n",s));
+ return(True);
+#endif
+}
/****************************************************************************
check a filename - possibly caling reducename
@@ -728,8 +925,7 @@ static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL d
continue;
pstrcpy(name2,dname);
- if (!name_map_mangle(name2,False,True,SNUM(conn)))
- continue;
+ if (!name_map_mangle(name2,False,SNUM(conn))) continue;
if ((mangled && mangled_equal(name,name2))
|| fname_equal(name, name2))
@@ -745,16 +941,3 @@ static BOOL scan_directory(char *path, char *name,connection_struct *conn,BOOL d
CloseDir(cur_dir);
return(False);
}
-
-/*************************************************************************** **
- * Initializes or clears the stat cache.
- *
- * Input: none.
- * Output: none.
- *
- * ************************************************************************** **
- */
-BOOL reset_stat_cache( void )
-{
- return hash_table_init( &stat_cache, INIT_STAT_CACHE_SIZE, (compare_function)(strcmp));
-} /* reset_stat_cache */
diff --git a/source/smbd/files.c b/source/smbd/files.c
index d62950c568a..7f4533e7ae7 100644
--- a/source/smbd/files.c
+++ b/source/smbd/files.c
@@ -97,7 +97,7 @@ files_struct *file_new(void )
files_used++;
fsp->fnum = i + FILE_HANDLE_OFFSET;
- string_set(&fsp->fsp_name,"");
+ string_init(&fsp->fsp_name,"");
DLIST_ADD(Files, fsp);
@@ -186,7 +186,10 @@ void file_close_conn(connection_struct *conn)
for (fsp=Files;fsp;fsp=next) {
next = fsp->next;
if (fsp->conn == conn && fsp->open) {
- close_file(fsp,False);
+ if (fsp->is_directory)
+ close_directory(fsp);
+ else
+ close_file(fsp,False);
}
}
}
@@ -223,7 +226,7 @@ open files, %d are available.\n", request_max_open_files, real_max_open_files));
}
/*
- * Ensure that pipe_handle_oppset is set correctly.
+ * Ensure that pipe_handle_offset is set correctly.
*/
set_pipe_handle_offset(real_max_open_files);
}
@@ -239,7 +242,10 @@ void file_close_user(int vuid)
for (fsp=Files;fsp;fsp=next) {
next=fsp->next;
if ((fsp->vuid == vuid) && fsp->open) {
- close_file(fsp,False);
+ if(!fsp->is_directory)
+ close_file(fsp,False);
+ else
+ close_directory(fsp);
}
}
}
@@ -334,13 +340,13 @@ void file_sync_all(connection_struct *conn)
for (fsp=Files;fsp;fsp=next) {
next=fsp->next;
- if (fsp->open && (conn == fsp->conn) && (fsp->fd_ptr != NULL)) {
- conn->vfs_ops.fsync(fsp->fd_ptr->fd);
+ if (fsp->open && (conn == fsp->conn) && (fsp->fd_ptr != NULL)
+ && lp_strict_sync(SNUM(conn))){
+ conn->vfs_ops.sync(fsp->fd_ptr->fd);
}
}
}
-
/****************************************************************************
free up a fd_ptr
****************************************************************************/
diff --git a/source/smbd/groupname.c b/source/smbd/groupname.c
index 4dadfaa9396..0be558848ab 100644
--- a/source/smbd/groupname.c
+++ b/source/smbd/groupname.c
@@ -19,225 +19,4 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#ifdef USING_GROUPNAME_MAP
-
-#include "includes.h"
-extern int DEBUGLEVEL;
-extern DOM_SID global_sam_sid;
-
-
-/**************************************************************************
- Groupname map functionality. The code loads a groupname map file and
- (currently) loads it into a linked list. This is slow and memory
- hungry, but can be changed into a more efficient storage format
- if the demands on it become excessive.
-***************************************************************************/
-
-typedef struct groupname_map {
- ubi_slNode next;
-
- char *windows_name;
- DOM_SID windows_sid;
- char *unix_name;
- gid_t unix_gid;
-} groupname_map_entry;
-
-static ubi_slList groupname_map_list;
-
-/**************************************************************************
- Delete all the entries in the groupname map list.
-***************************************************************************/
-
-static void delete_groupname_map_list(void)
-{
- groupname_map_entry *gmep;
-
- while((gmep = (groupname_map_entry *)ubi_slRemHead( &groupname_map_list )) != NULL) {
- if(gmep->windows_name)
- free(gmep->windows_name);
- if(gmep->unix_name)
- free(gmep->unix_name);
- free((char *)gmep);
- }
-}
-
-/**************************************************************************
- Load a groupname map file. Sets last accessed timestamp.
-***************************************************************************/
-
-void load_groupname_map(void)
-{
- static time_t groupmap_file_last_modified = (time_t)0;
- static BOOL initialized = False;
- char *groupname_map_file = lp_groupname_map();
- SMB_STRUCT_STAT st;
- FILE *fp;
- char *s;
- pstring buf;
- groupname_map_entry *new_ep;
-
- if(!initialized) {
- ubi_slInitList( &groupname_map_list );
- initialized = True;
- }
-
- if (!*groupname_map_file)
- return;
-
- if(sys_stat(groupname_map_file, &st) != 0) {
- DEBUG(0, ("load_groupname_map: Unable to stat file %s. Error was %s\n",
- groupname_map_file, strerror(errno) ));
- return;
- }
-
- /*
- * Check if file has changed.
- */
- if( st.st_mtime <= groupmap_file_last_modified)
- return;
-
- groupmap_file_last_modified = st.st_mtime;
-
- /*
- * Load the file.
- */
-
- fp = sys_fopen(groupname_map_file,"r");
- if (!fp) {
- DEBUG(0,("load_groupname_map: can't open groupname map %s. Error was %s\n",
- groupname_map_file, strerror(errno)));
- return;
- }
-
- /*
- * Throw away any previous list.
- */
- delete_groupname_map_list();
-
- DEBUG(4,("load_groupname_map: Scanning groupname map %s\n",groupname_map_file));
-
- while((s=fgets_slash(buf,sizeof(buf),fp))!=NULL) {
- pstring unixname;
- pstring windows_name;
- struct group *gptr;
- DOM_SID tmp_sid;
-
- DEBUG(10,("load_groupname_map: Read line |%s|\n", s));
-
- if (!*s || strchr("#;",*s))
- continue;
-
- if(!next_token(&s,unixname, "\t\n\r=", sizeof(unixname)))
- continue;
-
- if(!next_token(&s,windows_name, "\t\n\r=", sizeof(windows_name)))
- continue;
-
- trim_string(unixname, " ", " ");
- trim_string(windows_name, " ", " ");
-
- if (!*windows_name)
- continue;
-
- if(!*unixname)
- continue;
-
- DEBUG(5,("load_groupname_map: unixname = %s, windowsname = %s.\n",
- unixname, windows_name));
-
- /*
- * Attempt to get the unix gid_t for this name.
- */
-
- if((gptr = (struct group *)getgrnam(unixname)) == NULL) {
- DEBUG(0,("load_groupname_map: getgrnam for group %s failed.\
-Error was %s.\n", unixname, strerror(errno) ));
- continue;
- }
-
- /*
- * Now map to an NT SID.
- */
-
- if(!lookup_wellknown_sid_from_name(windows_name, &tmp_sid)) {
- /*
- * It's not a well known name, convert the UNIX gid_t
- * to a rid within this domain SID.
- */
- tmp_sid = global_sam_sid;
- tmp_sid.sub_auths[tmp_sid.num_auths++] =
- pdb_gid_to_group_rid((gid_t)gptr->gr_gid);
- }
-
- /*
- * Create the list entry and add it onto the list.
- */
-
- if((new_ep = (groupname_map_entry *)malloc( sizeof(groupname_map_entry) ))== NULL) {
- DEBUG(0,("load_groupname_map: malloc fail for groupname_map_entry.\n"));
- fclose(fp);
- return;
- }
-
- new_ep->unix_gid = gptr->gr_gid;
- new_ep->windows_sid = tmp_sid;
- new_ep->windows_name = strdup( windows_name );
- new_ep->unix_name = strdup( unixname );
-
- if(new_ep->windows_name == NULL || new_ep->unix_name == NULL) {
- DEBUG(0,("load_groupname_map: malloc fail for names in groupname_map_entry.\n"));
- fclose(fp);
- if(new_ep->windows_name != NULL)
- free(new_ep->windows_name);
- if(new_ep->unix_name != NULL)
- free(new_ep->unix_name);
- free((char *)new_ep);
- return;
- }
- memset((char *)&new_ep->next, '\0', sizeof(new_ep->next) );
-
- ubi_slAddHead( &groupname_map_list, (ubi_slNode *)new_ep);
- }
-
- DEBUG(10,("load_groupname_map: Added %ld entries to groupname map.\n",
- ubi_slCount(&groupname_map_list)));
-
- fclose(fp);
-}
-
-/***********************************************************
- Lookup a SID entry by gid_t.
-************************************************************/
-
-void map_gid_to_sid( gid_t gid, DOM_SID *psid)
-{
- groupname_map_entry *gmep;
-
- /*
- * Initialize and load if not already loaded.
- */
- load_groupname_map();
-
- for( gmep = (groupname_map_entry *)ubi_slFirst( &groupname_map_list);
- gmep; gmep = (groupname_map_entry *)ubi_slNext( gmep )) {
-
- if( gmep->unix_gid == gid) {
- *psid = gmep->windows_sid;
- DEBUG(7,("map_gid_to_sid: Mapping unix group %s to windows group %s.\n",
- gmep->unix_name, gmep->windows_name ));
- return;
- }
- }
-
- /*
- * If there's no map, convert the UNIX gid_t
- * to a rid within this domain SID.
- */
- *psid = global_sam_sid;
- psid->sub_auths[psid->num_auths++] = pdb_gid_to_group_rid(gid);
-
- return;
-}
-#else /* USING_GROUPNAME_MAP */
- void load_groupname_map(void) {;}
-#endif /* USING_GROUPNAME_MAP */
+/* this module is retired, it is moved to lib/domain_namemap.c */
diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c
index 5ee70e7d949..68b449c7329 100644
--- a/source/smbd/ipc.c
+++ b/source/smbd/ipc.c
@@ -29,105 +29,17 @@
#include "includes.h"
#include "nterr.h"
-#ifdef CHECK_TYPES
-#undef CHECK_TYPES
-#endif
-#define CHECK_TYPES 0
-
extern int DEBUGLEVEL;
extern int max_send;
extern fstring local_machine;
-extern fstring global_myworkgroup;
-#define NERR_Success 0
-#define NERR_badpass 86
#define NERR_notsupported 50
-#define NERR_BASE (2100)
-#define NERR_BufTooSmall (NERR_BASE+23)
-#define NERR_JobNotFound (NERR_BASE+51)
-#define NERR_DestNotFound (NERR_BASE+52)
-#define ERROR_INVALID_LEVEL 124
-
-#define ACCESS_READ 0x01
-#define ACCESS_WRITE 0x02
-#define ACCESS_CREATE 0x04
-
-#define SHPWLEN 8 /* share password length */
-#define NNLEN 12 /* 8.3 net name length */
-#define SNLEN 15 /* service name length */
-#define QNLEN 12 /* queue name maximum length */
extern int Client;
extern int smb_read_error;
-
-static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len);
-
-
-static int CopyExpanded(connection_struct *conn,
- int snum, char** dst, char* src, int* n)
-{
- pstring buf;
- int l;
-
- if (!src || !dst || !n || !(*dst)) return(0);
-
- StrnCpy(buf,src,sizeof(buf)/2);
- pstring_sub(buf,"%S",lp_servicename(snum));
- standard_sub(conn,buf);
- StrnCpy(*dst,buf,*n);
- l = strlen(*dst) + 1;
- (*dst) += l;
- (*n) -= l;
- return l;
-}
-
-static int CopyAndAdvance(char** dst, char* src, int* n)
-{
- int l;
- if (!src || !dst || !n || !(*dst)) return(0);
- StrnCpy(*dst,src,*n-1);
- l = strlen(*dst) + 1;
- (*dst) += l;
- (*n) -= l;
- return l;
-}
-
-static int StrlenExpanded(connection_struct *conn, int snum, char* s)
-{
- pstring buf;
- if (!s) return(0);
- StrnCpy(buf,s,sizeof(buf)/2);
- pstring_sub(buf,"%S",lp_servicename(snum));
- standard_sub(conn,buf);
- return strlen(buf) + 1;
-}
-
-static char* Expand(connection_struct *conn, int snum, char* s)
-{
- static pstring buf;
- if (!s) return(NULL);
- StrnCpy(buf,s,sizeof(buf)/2);
- pstring_sub(buf,"%S",lp_servicename(snum));
- standard_sub(conn,buf);
- return &buf[0];
-}
-
-/*******************************************************************
- check a API string for validity when we only need to check the prefix
- ******************************************************************/
-static BOOL prefix_ok(char *str,char *prefix)
-{
- return(strncmp(str,prefix,strlen(prefix)) == 0);
-}
+extern uint32 global_client_caps;
/*******************************************************************
copies parameters and data, as needed, into the smb buffer
@@ -138,69 +50,74 @@ static BOOL prefix_ok(char *str,char *prefix)
cause of some of the ipc problems being experienced. lkcl26dec97
******************************************************************/
-
static void copy_trans_params_and_data(char *outbuf, int align,
- char *rparam, int param_offset, int param_len,
- char *rdata, int data_offset, int data_len)
+ prs_struct *rparam, prs_struct *rdata,
+ int param_offset, int data_offset,
+ int param_len, int data_len)
{
char *copy_into = smb_buf(outbuf)+1;
- if(param_len < 0)
- param_len = 0;
-
- if(data_len < 0)
- data_len = 0;
-
DEBUG(5,("copy_trans_params_and_data: params[%d..%d] data[%d..%d]\n",
param_offset, param_offset + param_len,
data_offset , data_offset + data_len));
- if (param_len)
- memcpy(copy_into, &rparam[param_offset], param_len);
-
+ if (param_len) prs_buf_copy(copy_into, rparam, param_offset, param_len);
copy_into += param_len + align;
-
- if (data_len )
- memcpy(copy_into, &rdata[data_offset], data_len);
+ if (data_len ) prs_buf_copy(copy_into, rdata , data_offset , data_len);
}
/****************************************************************************
- Send a trans reply.
- ****************************************************************************/
-
-static void send_trans_reply(char *outbuf,
- char *rparam, int rparam_len,
- char *rdata, int rdata_len,
- BOOL buffer_too_large)
+ send a trans reply
+ ****************************************************************************/
+void send_trans_reply(char *outbuf,
+ prs_struct *rdata,
+ prs_struct *rparam,
+ uint16 *setup, int lsetup, int max_data_ret,
+ BOOL pipe_data_outstanding)
{
+ int i;
int this_ldata,this_lparam;
- int tot_data_sent = 0;
- int tot_param_sent = 0;
+ int tot_data=0,tot_param=0;
int align;
- int ldata = rdata ? rdata_len : 0;
- int lparam = rparam ? rparam_len : 0;
+ int ldata = rdata ? prs_buf_len(rdata ) : 0;
+ int lparam = rparam ? prs_buf_len(rparam) : 0;
+
+ BOOL buffer_too_large = max_data_ret ? ldata > max_data_ret : False;
+
+ DEBUG(10,("send_trans_reply: max_data_ret: %d datalen: %d plen: %d\n",
+ max_data_ret, ldata, lparam));
if (buffer_too_large)
- DEBUG(5,("send_trans_reply: buffer %d too large\n", ldata ));
+ {
+ DEBUG(5,("send_trans_reply: buffer %d too large %d\n", ldata, max_data_ret));
+ ldata = max_data_ret;
+ }
- this_lparam = MIN(lparam,max_send - 500); /* hack */
- this_ldata = MIN(ldata,max_send - (500+this_lparam));
+ this_lparam = MIN(lparam,max_send - (500+lsetup*SIZEOFWORD)); /* hack */
+ this_ldata = MIN(ldata,max_send - (500+lsetup*SIZEOFWORD+this_lparam));
align = ((this_lparam)%4);
- set_message(outbuf,10,1+align+this_ldata+this_lparam,True);
+ set_message(outbuf,10+lsetup,1+align+this_ldata+this_lparam,True);
- if (buffer_too_large)
+ if (buffer_too_large || pipe_data_outstanding)
{
- /* issue a buffer size warning. on a DCE/RPC pipe, expect an SMBreadX... */
- SIVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- SIVAL(outbuf, smb_rcls, 0x80000000 | NT_STATUS_ACCESS_VIOLATION);
+ if (global_client_caps & CAP_STATUS32)
+ {
+ /* issue a buffer size warning. on a DCE/RPC pipe, expect an SMBreadX... */
+ SIVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ SIVAL(outbuf, smb_rcls, 0x80000005); /* STATUS_BUFFER_OVERFLOW */
+ } else {
+ SCVAL(outbuf, smb_rcls, ERRDOS);
+ SSVAL(outbuf, smb_err, ERRmoredata);
+ }
}
copy_trans_params_and_data(outbuf, align,
- rparam, tot_param_sent, this_lparam,
- rdata, tot_data_sent, this_ldata);
+ rparam , rdata,
+ tot_param , tot_data,
+ this_lparam, this_ldata);
SSVAL(outbuf,smb_vwv0,lparam);
SSVAL(outbuf,smb_vwv1,ldata);
@@ -210,3044 +127,76 @@ static void send_trans_reply(char *outbuf,
SSVAL(outbuf,smb_vwv6,this_ldata);
SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,outbuf));
SSVAL(outbuf,smb_vwv8,0);
- SSVAL(outbuf,smb_vwv9,0);
+ SSVAL(outbuf,smb_vwv9,lsetup);
+
+ for (i=0;i<lsetup;i++)
+ {
+ SSVAL(outbuf,smb_vwv10+i*SIZEOFWORD,setup[i]);
+ }
show_msg(outbuf);
send_smb(Client,outbuf);
- tot_data_sent = this_ldata;
- tot_param_sent = this_lparam;
+ tot_data = this_ldata;
+ tot_param = this_lparam;
- while (tot_data_sent < ldata || tot_param_sent < lparam)
+ while (tot_data < ldata || tot_param < lparam)
{
- this_lparam = MIN(lparam-tot_param_sent, max_send - 500); /* hack */
- this_ldata = MIN(ldata -tot_data_sent, max_send - (500+this_lparam));
-
- if(this_lparam < 0)
- this_lparam = 0;
-
- if(this_ldata < 0)
- this_ldata = 0;
+ this_lparam = MIN(lparam-tot_param, max_send - 500); /* hack */
+ this_ldata = MIN(ldata -tot_data , max_send - (500+this_lparam));
align = (this_lparam%4);
set_message(outbuf,10,1+this_ldata+this_lparam+align,False);
copy_trans_params_and_data(outbuf, align,
- rparam, tot_param_sent, this_lparam,
- rdata, tot_data_sent, this_ldata);
+ rparam , rdata,
+ tot_param , tot_data,
+ this_lparam, this_ldata);
SSVAL(outbuf,smb_vwv3,this_lparam);
SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
- SSVAL(outbuf,smb_vwv5,tot_param_sent);
+ SSVAL(outbuf,smb_vwv5,tot_param);
SSVAL(outbuf,smb_vwv6,this_ldata);
SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,outbuf));
- SSVAL(outbuf,smb_vwv8,tot_data_sent);
+ SSVAL(outbuf,smb_vwv8,tot_data);
SSVAL(outbuf,smb_vwv9,0);
show_msg(outbuf);
send_smb(Client,outbuf);
- tot_data_sent += this_ldata;
- tot_param_sent += this_lparam;
+ tot_data += this_ldata;
+ tot_param += this_lparam;
}
}
-struct pack_desc {
- char* format; /* formatstring for structure */
- char* subformat; /* subformat for structure */
- char* base; /* baseaddress of buffer */
- int buflen; /* remaining size for fixed part; on init: length of base */
- int subcount; /* count of substructures */
- char* structbuf; /* pointer into buffer for remaining fixed part */
- int stringlen; /* remaining size for variable part */
- char* stringbuf; /* pointer into buffer for remaining variable part */
- int neededlen; /* total needed size */
- int usedlen; /* total used size (usedlen <= neededlen and usedlen <= buflen) */
- char* curpos; /* current position; pointer into format or subformat */
- int errcode;
-};
-
-static int get_counter(char** p)
-{
- int i, n;
- if (!p || !(*p)) return(1);
- if (!isdigit((int)**p)) return 1;
- for (n = 0;;) {
- i = **p;
- if (isdigit(i))
- n = 10 * n + (i - '0');
- else
- return n;
- (*p)++;
- }
-}
-
-static int getlen(char* p)
-{
- int n = 0;
- if (!p) return(0);
- while (*p) {
- switch( *p++ ) {
- case 'W': /* word (2 byte) */
- n += 2;
- break;
- case 'N': /* count of substructures (word) at end */
- n += 2;
- break;
- case 'D': /* double word (4 byte) */
- case 'z': /* offset to zero terminated string (4 byte) */
- case 'l': /* offset to user data (4 byte) */
- n += 4;
- break;
- case 'b': /* offset to data (with counter) (4 byte) */
- n += 4;
- get_counter(&p);
- break;
- case 'B': /* byte (with optional counter) */
- n += get_counter(&p);
- break;
- }
- }
- return n;
-}
-
-static BOOL init_package(struct pack_desc* p, int count, int subcount)
-{
- int n = p->buflen;
- int i;
-
- if (!p->format || !p->base) return(False);
-
- i = count * getlen(p->format);
- if (p->subformat) i += subcount * getlen(p->subformat);
- p->structbuf = p->base;
- p->neededlen = 0;
- p->usedlen = 0;
- p->subcount = 0;
- p->curpos = p->format;
- if (i > n) {
- p->neededlen = i;
- i = n = 0;
- p->errcode = ERRmoredata;
- }
- else
- p->errcode = NERR_Success;
- p->buflen = i;
- n -= i;
- p->stringbuf = p->base + i;
- p->stringlen = n;
- return(p->errcode == NERR_Success);
-}
-
-#ifdef HAVE_STDARG_H
-static int package(struct pack_desc* p, ...)
-{
-#else
-static int package(va_alist)
-va_dcl
-{
- struct pack_desc* p;
-#endif
- va_list args;
- int needed=0, stringneeded;
- char* str=NULL;
- int is_string=0, stringused;
- int32 temp;
-
-#ifdef HAVE_STDARG_H
- va_start(args,p);
-#else
- va_start(args);
- p = va_arg(args,struct pack_desc *);
-#endif
-
- if (!*p->curpos) {
- if (!p->subcount)
- p->curpos = p->format;
- else {
- p->curpos = p->subformat;
- p->subcount--;
- }
- }
-#if CHECK_TYPES
- str = va_arg(args,char*);
- SMB_ASSERT(strncmp(str,p->curpos,strlen(str)) == 0);
-#endif
- stringneeded = -1;
-
- if (!p->curpos) {
- va_end(args);
- return(0);
- }
-
- switch( *p->curpos++ ) {
- case 'W': /* word (2 byte) */
- needed = 2;
- temp = va_arg(args,int);
- if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
- break;
- case 'N': /* count of substructures (word) at end */
- needed = 2;
- p->subcount = va_arg(args,int);
- if (p->buflen >= needed) SSVAL(p->structbuf,0,p->subcount);
- break;
- case 'D': /* double word (4 byte) */
- needed = 4;
- temp = va_arg(args,int);
- if (p->buflen >= needed) SIVAL(p->structbuf,0,temp);
- break;
- case 'B': /* byte (with optional counter) */
- needed = get_counter(&p->curpos);
- {
- char *s = va_arg(args,char*);
- if (p->buflen >= needed) StrnCpy(p->structbuf,s?s:"",needed-1);
- }
- break;
- case 'z': /* offset to zero terminated string (4 byte) */
- str = va_arg(args,char*);
- stringneeded = (str ? strlen(str)+1 : 0);
- is_string = 1;
- break;
- case 'l': /* offset to user data (4 byte) */
- str = va_arg(args,char*);
- stringneeded = va_arg(args,int);
- is_string = 0;
- break;
- case 'b': /* offset to data (with counter) (4 byte) */
- str = va_arg(args,char*);
- stringneeded = get_counter(&p->curpos);
- is_string = 0;
- break;
- }
- va_end(args);
- if (stringneeded >= 0) {
- needed = 4;
- if (p->buflen >= needed) {
- stringused = stringneeded;
- if (stringused > p->stringlen) {
- stringused = (is_string ? p->stringlen : 0);
- if (p->errcode == NERR_Success) p->errcode = ERRmoredata;
- }
- if (!stringused)
- SIVAL(p->structbuf,0,0);
- else {
- SIVAL(p->structbuf,0,PTR_DIFF(p->stringbuf,p->base));
- memcpy(p->stringbuf,str?str:"",stringused);
- if (is_string) p->stringbuf[stringused-1] = '\0';
- p->stringbuf += stringused;
- p->stringlen -= stringused;
- p->usedlen += stringused;
- }
- }
- p->neededlen += stringneeded;
- }
- p->neededlen += needed;
- if (p->buflen >= needed) {
- p->structbuf += needed;
- p->buflen -= needed;
- p->usedlen += needed;
- }
- else {
- if (p->errcode == NERR_Success) p->errcode = ERRmoredata;
- }
- return 1;
-}
-
-#if CHECK_TYPES
-#define PACK(desc,t,v) package(desc,t,v,0,0,0,0)
-#define PACKl(desc,t,v,l) package(desc,t,v,l,0,0,0,0)
-#else
-#define PACK(desc,t,v) package(desc,v)
-#define PACKl(desc,t,v,l) package(desc,v,l)
-#endif
-
-static void PACKI(struct pack_desc* desc,char *t,int v)
+static void api_rpc_trans_reply(char *outbuf, char *rdata, int rlen,
+ BOOL pipe_data_outstanding)
{
- PACK(desc,t,v);
-}
-
-static void PACKS(struct pack_desc* desc,char *t,char *v)
-{
- PACK(desc,t,v);
-}
-
-
-/****************************************************************************
- get a print queue
- ****************************************************************************/
-
-static void PackDriverData(struct pack_desc* desc)
-{
- char drivdata[4+4+32];
- SIVAL(drivdata,0,sizeof drivdata); /* cb */
- SIVAL(drivdata,4,1000); /* lVersion */
- memset(drivdata+8,0,32); /* szDeviceName */
- pstrcpy(drivdata+8,"NULL");
- PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
-}
-
-static int check_printq_info(struct pack_desc* desc,
- int uLevel, char *id1, char *id2)
-{
- desc->subformat = NULL;
- switch( uLevel ) {
- case 0:
- desc->format = "B13";
- break;
- case 1:
- desc->format = "B13BWWWzzzzzWW";
- break;
- case 2:
- desc->format = "B13BWWWzzzzzWN";
- desc->subformat = "WB21BB16B10zWWzDDz";
- break;
- case 3:
- desc->format = "zWWWWzzzzWWzzl";
- break;
- case 4:
- desc->format = "zWWWWzzzzWNzzl";
- desc->subformat = "WWzWWDDzz";
- break;
- case 5:
- desc->format = "z";
- break;
- case 52:
- desc->format = "WzzzzzzzzN";
- desc->subformat = "z";
- break;
- default: return False;
- }
- if (strcmp(desc->format,id1) != 0) return False;
- if (desc->subformat && strcmp(desc->subformat,id2) != 0) return False;
- return True;
-}
-
-static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
- struct pack_desc* desc,
- print_queue_struct* queue, int n)
-{
- time_t t = queue->time;
-
- /* the client expects localtime */
- t -= TimeDiff(t);
-
- PACKI(desc,"W",printjob_encode(snum, queue->job)); /* uJobId */
- if (uLevel == 1) {
- PACKS(desc,"B21",queue->user); /* szUserName */
- PACKS(desc,"B",""); /* pad */
- PACKS(desc,"B16",""); /* szNotifyName */
- PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
- PACKS(desc,"z",""); /* pszParms */
- PACKI(desc,"W",n+1); /* uPosition */
- PACKI(desc,"W",queue->status); /* fsStatus */
- PACKS(desc,"z",""); /* pszStatus */
- PACKI(desc,"D",t); /* ulSubmitted */
- PACKI(desc,"D",queue->size); /* ulSize */
- PACKS(desc,"z",queue->file); /* pszComment */
- }
- if (uLevel == 2 || uLevel == 3) {
- PACKI(desc,"W",queue->priority); /* uPriority */
- PACKS(desc,"z",queue->user); /* pszUserName */
- PACKI(desc,"W",n+1); /* uPosition */
- PACKI(desc,"W",queue->status); /* fsStatus */
- PACKI(desc,"D",t); /* ulSubmitted */
- PACKI(desc,"D",queue->size); /* ulSize */
- PACKS(desc,"z","Samba"); /* pszComment */
- PACKS(desc,"z",queue->file); /* pszDocument */
- if (uLevel == 3) {
- PACKS(desc,"z",""); /* pszNotifyName */
- PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */
- PACKS(desc,"z",""); /* pszParms */
- PACKS(desc,"z",""); /* pszStatus */
- PACKS(desc,"z",SERVICE(snum)); /* pszQueue */
- PACKS(desc,"z","lpd"); /* pszQProcName */
- PACKS(desc,"z",""); /* pszQProcParms */
- PACKS(desc,"z","NULL"); /* pszDriverName */
- PackDriverData(desc); /* pDriverData */
- PACKS(desc,"z",""); /* pszPrinterName */
- }
- }
-}
-
-static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
- struct pack_desc* desc,
- int count, print_queue_struct* queue,
- print_status_struct* status)
-{
- switch (uLevel) {
- case 1:
- case 2:
- PACKS(desc,"B13",SERVICE(snum));
- break;
- case 3:
- case 4:
- case 5:
- PACKS(desc,"z",Expand(conn,snum,SERVICE(snum)));
- break;
- }
-
- if (uLevel == 1 || uLevel == 2) {
- PACKS(desc,"B",""); /* alignment */
- PACKI(desc,"W",5); /* priority */
- PACKI(desc,"W",0); /* start time */
- PACKI(desc,"W",0); /* until time */
- PACKS(desc,"z",""); /* pSepFile */
- PACKS(desc,"z","lpd"); /* pPrProc */
- PACKS(desc,"z",SERVICE(snum)); /* pDestinations */
- PACKS(desc,"z",""); /* pParms */
- if (snum < 0) {
- PACKS(desc,"z","UNKNOWN PRINTER");
- PACKI(desc,"W",LPSTAT_ERROR);
- }
- else if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(conn,snum,lp_comment(snum)));
- PACKI(desc,"W",LPSTAT_OK); /* status */
- } else {
- PACKS(desc,"z",status->message);
- PACKI(desc,"W",status->status); /* status */
- }
- PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
- }
- if (uLevel == 3 || uLevel == 4) {
- PACKI(desc,"W",5); /* uPriority */
- PACKI(desc,"W",0); /* uStarttime */
- PACKI(desc,"W",0); /* uUntiltime */
- PACKI(desc,"W",5); /* pad1 */
- PACKS(desc,"z",""); /* pszSepFile */
- PACKS(desc,"z","WinPrint"); /* pszPrProc */
- PACKS(desc,"z",""); /* pszParms */
- if (!status || !status->message[0]) {
- PACKS(desc,"z",Expand(conn,snum,lp_comment(snum))); /* pszComment */
- PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
- } else {
- PACKS(desc,"z",status->message); /* pszComment */
- PACKI(desc,"W",status->status); /* fsStatus */
- }
- PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */
- PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
- PACKS(desc,"z",lp_printerdriver(snum)); /* pszDriverName */
- PackDriverData(desc); /* pDriverData */
- }
- if (uLevel == 2 || uLevel == 4) {
- int i;
- for (i=0;i<count;i++)
- fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
- }
-
- if (uLevel==52) {
- int i,ok=0;
- pstring tok,driver,datafile,langmon,helpfile,datatype;
- char *p,*q;
- FILE *f;
- pstring fname;
-
- pstrcpy(fname,lp_driverfile());
- f=sys_fopen(fname,"r");
- if (!f) {
- DEBUG(3,("fill_printq_info: Can't open %s - %s\n",fname,strerror(errno)));
- desc->errcode=NERR_notsupported;
- return;
- }
-
- if((p=(char *)malloc(8192*sizeof(char))) == NULL) {
- DEBUG(0,("fill_printq_info: malloc fail !\n"));
- desc->errcode=NERR_notsupported;
- fclose(f);
- return;
- }
-
- memset(p, '\0',8192*sizeof(char));
- q=p;
-
- /* lookup the long printer driver name in the file description */
- while (f && !feof(f) && !ok)
- {
- p = q; /* reset string pointer */
- fgets(p,8191,f);
- p[strlen(p)-1]='\0';
- if (next_token(&p,tok,":",sizeof(tok)) &&
- (strlen(lp_printerdriver(snum)) == strlen(tok)) &&
- (!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
- ok=1;
- }
- fclose(f);
-
- /* driver file name */
- if (ok && !next_token(&p,driver,":",sizeof(driver))) ok = 0;
- /* data file name */
- if (ok && !next_token(&p,datafile,":",sizeof(datafile))) ok = 0;
- /*
- * for the next tokens - which may be empty - I have to check for empty
- * tokens first because the next_token function will skip all empty
- * token fields
- */
- if (ok) {
- /* help file */
- if (*p == ':') {
- *helpfile = '\0';
- p++;
- } else if (!next_token(&p,helpfile,":",sizeof(helpfile))) ok = 0;
- }
-
- if (ok) {
- /* language monitor */
- if (*p == ':') {
- *langmon = '\0';
- p++;
- } else if (!next_token(&p,langmon,":",sizeof(langmon))) ok = 0;
- }
-
- /* default data type */
- if (ok && !next_token(&p,datatype,":",sizeof(datatype))) ok = 0;
-
- if (ok) {
- PACKI(desc,"W",0x0400); /* don't know */
- PACKS(desc,"z",lp_printerdriver(snum)); /* long printer name */
- PACKS(desc,"z",driver); /* Driverfile Name */
- PACKS(desc,"z",datafile); /* Datafile name */
- PACKS(desc,"z",langmon); /* language monitor */
- PACKS(desc,"z",lp_driverlocation(snum)); /* share to retrieve files */
- PACKS(desc,"z",datatype); /* default data type */
- PACKS(desc,"z",helpfile); /* helpfile name */
- PACKS(desc,"z",driver); /* driver name */
- DEBUG(3,("Driver:%s:\n",driver));
- DEBUG(3,("Data File:%s:\n",datafile));
- DEBUG(3,("Language Monitor:%s:\n",langmon));
- DEBUG(3,("Data Type:%s:\n",datatype));
- DEBUG(3,("Help File:%s:\n",helpfile));
- PACKI(desc,"N",count); /* number of files to copy */
- for (i=0;i<count;i++)
- {
- /* no need to check return value here - it was already tested in
- * get_printerdrivernumber
- */
- next_token(&p,tok,",",sizeof(tok));
- PACKS(desc,"z",tok); /* driver files to copy */
- DEBUG(3,("file:%s:\n",tok));
- }
-
- DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
- SERVICE(snum),count));
- } else {
- DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
- desc->errcode=NERR_notsupported;
- }
- free(q);
- }
-}
-
-/* This function returns the number of files for a given driver */
-static int get_printerdrivernumber(int snum)
-{
- int i=0,ok=0;
- pstring tok;
- char *p,*q;
- FILE *f;
- pstring fname;
-
- pstrcpy(fname,lp_driverfile());
-
- DEBUG(4,("In get_printerdrivernumber: %s\n",fname));
- f=sys_fopen(fname,"r");
- if (!f) {
- DEBUG(3,("get_printerdrivernumber: Can't open %s - %s\n",fname,strerror(errno)));
- return(0);
- }
-
- if((p=(char *)malloc(8192*sizeof(char))) == NULL) {
- DEBUG(3,("get_printerdrivernumber: malloc fail !\n"));
- fclose(f);
- return 0;
- }
-
- q=p; /* need it to free memory because p change ! */
-
- /* lookup the long printer driver name in the file description */
- while (!feof(f) && !ok)
- {
- p = q; /* reset string pointer */
- fgets(p,8191,f);
- if (next_token(&p,tok,":",sizeof(tok)) &&
- (!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
- ok=1;
- }
- fclose(f);
-
- if (ok) {
- /* skip 5 fields */
- i = 5;
- while (*p && i) {
- if (*p++ == ':') i--;
- }
- if (!*p || i)
- return(0);
-
- /* count the number of files */
- while (next_token(&p,tok,",",sizeof(tok)))
- i++;
- }
- free(q);
-
- return(i);
-}
-
-static BOOL api_DosPrintQGetInfo(connection_struct *conn,
- uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char *QueueName = p;
- int uLevel;
- int count=0;
- int snum;
- char* str3;
- struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
-
- memset((char *)&status,'\0',sizeof(status));
- memset((char *)&desc,'\0',sizeof(desc));
-
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
- str3 = p + 4;
-
- /* remove any trailing username */
- if ((p = strchr(QueueName,'%'))) *p = 0;
-
- DEBUG(3,("PrintQueue uLevel=%d name=%s\n",uLevel,QueueName));
-
- /* check it's a supported varient */
- if (!prefix_ok(str1,"zWrLh")) return False;
- if (!check_printq_info(&desc,uLevel,str2,str3)) {
- /*
- * Patch from Scott Moomaw <scott@bridgewater.edu>
- * to return the 'invalid info level' error if an
- * unknown level was requested.
- */
- *rdata_len = 0;
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,ERROR_INVALID_LEVEL);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,0);
- return(True);
- }
-
- snum = lp_servicenumber(QueueName);
- if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(QueueName,pnum);
- snum = lp_servicenumber(QueueName);
- }
- }
-
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
-
- if (uLevel==52) {
- count = get_printerdrivernumber(snum);
- DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
- } else {
- count = get_printqueue(snum, conn,&queue,&status);
- }
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,1,count)) {
- desc.subcount = count;
- fill_printq_info(conn,snum,uLevel,&desc,count,queue,&status);
- } else if(uLevel == 0) {
- /*
- * This is a *disgusting* hack.
- * This is *so* bad that even I'm embarrassed (and I
- * have no shame). Here's the deal :
- * Until we get the correct SPOOLSS code into smbd
- * then when we're running with NT SMB support then
- * NT makes this call with a level of zero, and then
- * immediately follows it with an open request to
- * the \\SRVSVC pipe. If we allow that open to
- * succeed then NT barfs when it cannot open the
- * \\SPOOLSS pipe immediately after and continually
- * whines saying "Printer name is invalid" forever
- * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC
- * to fail, then NT downgrades to using the downlevel code
- * and everything works as well as before. I hate
- * myself for adding this code.... JRA.
- */
-
- fail_next_srvsvc_open();
- }
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
-
- if (queue) free(queue);
-
- return(True);
-}
-
-
-/****************************************************************************
- view list of all print jobs on all queues
- ****************************************************************************/
-static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param, char* data,
- int mdrcnt, int mprcnt,
- char **rdata, char** rparam,
- int *rdata_len, int *rparam_len)
-{
- char *param_format = param+2;
- char *output_format1 = skip_string(param_format,1);
- char *p = skip_string(output_format1,1);
- int uLevel = SVAL(p,0);
- char *output_format2 = p + 4;
- int services = lp_numservices();
- int i, n;
- struct pack_desc desc;
- print_queue_struct **queue = NULL;
- print_status_struct *status = NULL;
- int* subcntarr = NULL;
- int queuecnt, subcnt=0, succnt=0;
-
- memset((char *)&desc,'\0',sizeof(desc));
-
- DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
-
- if (!prefix_ok(param_format,"WrLeh")) return False;
- if (!check_printq_info(&desc,uLevel,output_format1,output_format2)) {
- /*
- * Patch from Scott Moomaw <scott@bridgewater.edu>
- * to return the 'invalid info level' error if an
- * unknown level was requested.
- */
- *rdata_len = 0;
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,ERROR_INVALID_LEVEL);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,0);
- return(True);
- }
-
- queuecnt = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
- queuecnt++;
- if (uLevel > 0) {
- if((queue = (print_queue_struct**)malloc(queuecnt*sizeof(print_queue_struct*))) == NULL) {
- DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
- return False;
- }
- memset(queue,0,queuecnt*sizeof(print_queue_struct*));
- if((status = (print_status_struct*)malloc(queuecnt*sizeof(print_status_struct))) == NULL) {
- DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
- return False;
- }
- memset(status,0,queuecnt*sizeof(print_status_struct));
- if((subcntarr = (int*)malloc(queuecnt*sizeof(int))) == NULL) {
- DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
- return False;
- }
- subcnt = 0;
- n = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- subcntarr[n] = get_printqueue(i, conn,&queue[n],&status[n]);
- subcnt += subcntarr[n];
- n++;
- }
- }
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
-
- if (init_package(&desc,queuecnt,subcnt)) {
- n = 0;
- succnt = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printq_info(conn,i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
- n++;
- if (desc.errcode == NERR_Success) succnt = n;
- }
- }
-
- if (subcntarr) free(subcntarr);
-
- *rdata_len = desc.usedlen;
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,queuecnt);
-
- for (i = 0; i < queuecnt; i++) {
- if (queue && queue[i]) free(queue[i]);
- }
-
- if (queue) free(queue);
- if (status) free(status);
-
- return True;
-}
-
-/****************************************************************************
- get info level for a server list query
- ****************************************************************************/
-static BOOL check_server_info(int uLevel, char* id)
-{
- switch( uLevel ) {
- case 0:
- if (strcmp(id,"B16") != 0) return False;
- break;
- case 1:
- if (strcmp(id,"B16BBDz") != 0) return False;
- break;
- default:
- return False;
- }
- return True;
-}
-
-struct srv_info_struct
-{
- fstring name;
- uint32 type;
- fstring comment;
- fstring domain;
- BOOL server_added;
-};
-
-
-/*******************************************************************
- get server info lists from the files saved by nmbd. Return the
- number of entries
- ******************************************************************/
-static int get_server_info(uint32 servertype,
- struct srv_info_struct **servers,
- char *domain)
-{
- FILE *f;
- pstring fname;
- int count=0;
- int alloced=0;
- pstring line;
- BOOL local_list_only;
-
- pstrcpy(fname,lp_lockdir());
- trim_string(fname,NULL,"/");
- pstrcat(fname,"/");
- pstrcat(fname,SERVER_LIST);
-
- f = sys_fopen(fname,"r");
-
- if (!f) {
- DEBUG(4,("Can't open %s - %s\n",fname,strerror(errno)));
- return(0);
- }
-
- /* request for everything is code for request all servers */
- if (servertype == SV_TYPE_ALL)
- servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
-
- local_list_only = (servertype & SV_TYPE_LOCAL_LIST_ONLY);
-
- DEBUG(4,("Servertype search: %8x\n",servertype));
-
- while (!feof(f))
- {
- fstring stype;
- struct srv_info_struct *s;
- char *ptr = line;
- BOOL ok = True;
- *ptr = 0;
-
- fgets(line,sizeof(line)-1,f);
- if (!*line) continue;
-
- if (count == alloced) {
- alloced += 10;
- (*servers) = (struct srv_info_struct *)
- Realloc(*servers,sizeof(**servers)*alloced);
- if (!(*servers)) return(0);
- memset((char *)((*servers)+count),'\0',sizeof(**servers)*(alloced-count));
- }
- s = &(*servers)[count];
-
- if (!next_token(&ptr,s->name , NULL, sizeof(s->name))) continue;
- if (!next_token(&ptr,stype , NULL, sizeof(stype))) continue;
- if (!next_token(&ptr,s->comment, NULL, sizeof(s->comment))) continue;
- if (!next_token(&ptr,s->domain , NULL, sizeof(s->domain))) {
- /* this allows us to cope with an old nmbd */
- pstrcpy(s->domain,global_myworkgroup);
- }
-
- if (sscanf(stype,"%X",&s->type) != 1) {
- DEBUG(4,("r:host file "));
- ok = False;
- }
-
- /* Filter the servers/domains we return based on what was asked for. */
-
- /* Check to see if we are being asked for a local list only. */
- if(local_list_only && ((s->type & SV_TYPE_LOCAL_LIST_ONLY) == 0)) {
- DEBUG(4,("r: local list only"));
- ok = False;
- }
-
- /* doesn't match up: don't want it */
- if (!(servertype & s->type)) {
- DEBUG(4,("r:serv type "));
- ok = False;
- }
-
- if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
- (s->type & SV_TYPE_DOMAIN_ENUM))
- {
- DEBUG(4,("s: dom mismatch "));
- ok = False;
- }
-
- if (!strequal(domain, s->domain) && !(servertype & SV_TYPE_DOMAIN_ENUM))
- {
- ok = False;
- }
-
- /* We should never return a server type with a SV_TYPE_LOCAL_LIST_ONLY set. */
- s->type &= ~SV_TYPE_LOCAL_LIST_ONLY;
-
- if (ok)
- {
- DEBUG(4,("**SV** %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
-
- s->server_added = True;
- count++;
- }
- else
- {
- DEBUG(4,("%20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
- }
- }
-
- fclose(f);
- return(count);
-}
-
-
-/*******************************************************************
- fill in a server info structure
- ******************************************************************/
-static int fill_srv_info(struct srv_info_struct *service,
- int uLevel, char **buf, int *buflen,
- char **stringbuf, int *stringspace, char *baseaddr)
-{
- int struct_len;
- char* p;
- char* p2;
- int l2;
- int len;
-
- switch (uLevel) {
- case 0: struct_len = 16; break;
- case 1: struct_len = 26; break;
- default: return -1;
- }
-
- if (!buf)
- {
- len = 0;
- switch (uLevel)
- {
- case 1:
- len = strlen(service->comment)+1;
- break;
- }
-
- if (buflen) *buflen = struct_len;
- if (stringspace) *stringspace = len;
- return struct_len + len;
- }
-
- len = struct_len;
- p = *buf;
- if (*buflen < struct_len) return -1;
- if (stringbuf)
- {
- p2 = *stringbuf;
- l2 = *stringspace;
- }
- else
- {
- p2 = p + struct_len;
- l2 = *buflen - struct_len;
- }
- if (!baseaddr) baseaddr = p;
-
- switch (uLevel)
- {
- case 0:
- StrnCpy(p,service->name,15);
- break;
-
- case 1:
- StrnCpy(p,service->name,15);
- SIVAL(p,18,service->type);
- SIVAL(p,22,PTR_DIFF(p2,baseaddr));
- len += CopyAndAdvance(&p2,service->comment,&l2);
- break;
- }
-
- if (stringbuf)
- {
- *buf = p + struct_len;
- *buflen -= struct_len;
- *stringbuf = p2;
- *stringspace = l2;
- }
- else
- {
- *buf = p2;
- *buflen -= len;
- }
- return len;
-}
-
-
-static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
-{
- return(strcmp(s1->name,s2->name));
-}
-
-/****************************************************************************
- view list of servers available (or possibly domains). The info is
- extracted from lists saved by nmbd on the local host
- ****************************************************************************/
-static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param, char *data,
- int mdrcnt, int mprcnt, char **rdata,
- char **rparam, int *rdata_len, int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
- uint32 servertype = IVAL(p,4);
- char *p2;
- int data_len, fixed_len, string_len;
- int f_len = 0, s_len = 0;
- struct srv_info_struct *servers=NULL;
- int counted=0,total=0;
- int i,missed;
- fstring domain;
- BOOL domain_request;
- BOOL local_request;
-
- /* If someone sets all the bits they don't really mean to set
- DOMAIN_ENUM and LOCAL_LIST_ONLY, they just want all the
- known servers. */
-
- if (servertype == SV_TYPE_ALL)
- servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
-
- /* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
- any other bit (they may just set this bit on it's own) they
- want all the locally seen servers. However this bit can be
- set on its own so set the requested servers to be
- ALL - DOMAIN_ENUM. */
-
- if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM))
- servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);
-
- domain_request = ((servertype & SV_TYPE_DOMAIN_ENUM) != 0);
- local_request = ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0);
-
- p += 8;
-
- if (!prefix_ok(str1,"WrLehD")) return False;
- if (!check_server_info(uLevel,str2)) return False;
-
- DEBUG(4, ("server request level: %s %8x ", str2, servertype));
- DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
- DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
-
- if (strcmp(str1, "WrLehDz") == 0) {
- StrnCpy(domain, p, sizeof(fstring)-1);
- } else {
- StrnCpy(domain, global_myworkgroup, sizeof(fstring)-1);
- }
-
- if (lp_browse_list())
- total = get_server_info(servertype,&servers,domain);
-
- data_len = fixed_len = string_len = 0;
- missed = 0;
-
- qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp);
-
- {
- char *lastname=NULL;
-
- for (i=0;i<total;i++)
- {
- struct srv_info_struct *s = &servers[i];
- if (lastname && strequal(lastname,s->name)) continue;
- lastname = s->name;
- data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
- DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
-
- if (data_len <= buf_len) {
- counted++;
- fixed_len += f_len;
- string_len += s_len;
- } else {
- missed++;
- }
- }
- }
-
- *rdata_len = fixed_len + string_len;
- *rdata = REALLOC(*rdata,*rdata_len);
- memset(*rdata,'\0',*rdata_len);
-
- p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */
- p = *rdata;
- f_len = fixed_len;
- s_len = string_len;
-
- {
- char *lastname=NULL;
- int count2 = counted;
- for (i = 0; i < total && count2;i++)
- {
- struct srv_info_struct *s = &servers[i];
- if (lastname && strequal(lastname,s->name)) continue;
- lastname = s->name;
- fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata);
- DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
- s->name, s->type, s->comment, s->domain));
- count2--;
- }
- }
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERRmoredata));
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,counted);
- SSVAL(*rparam,6,counted+missed);
-
- if (servers) free(servers);
-
- DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
- domain,uLevel,counted,counted+missed));
-
- return(True);
-}
-
-/****************************************************************************
- command 0x34 - suspected of being a "Lookup Names" stub api
- ****************************************************************************/
-static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid, char *param, char *data,
- int mdrcnt, int mprcnt, char **rdata,
- char **rparam, int *rdata_len, int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
- int counted=0;
- int missed=0;
-
- DEBUG(5,("RNetGroupGetUsers: %s %s %s %d %d\n",
- str1, str2, p, uLevel, buf_len));
-
- if (!prefix_ok(str1,"zWrLeh")) return False;
-
- *rdata_len = 0;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- SSVAL(*rparam,0,0x08AC); /* informational warning message */
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,counted);
- SSVAL(*rparam,6,counted+missed);
-
- return(True);
-}
-
-/****************************************************************************
- get info about a share
- ****************************************************************************/
-static BOOL check_share_info(int uLevel, char* id)
-{
- switch( uLevel ) {
- case 0:
- if (strcmp(id,"B13") != 0) return False;
- break;
- case 1:
- if (strcmp(id,"B13BWz") != 0) return False;
- break;
- case 2:
- if (strcmp(id,"B13BWzWWWzB9B") != 0) return False;
- break;
- case 91:
- if (strcmp(id,"B13BWzWWWzB9BB9BWzWWzWW") != 0) return False;
- break;
- default: return False;
- }
- return True;
-}
-
-static int fill_share_info(connection_struct *conn, int snum, int uLevel,
- char** buf, int* buflen,
- char** stringbuf, int* stringspace, char* baseaddr)
-{
- int struct_len;
- char* p;
- char* p2;
- int l2;
- int len;
-
- switch( uLevel ) {
- case 0: struct_len = 13; break;
- case 1: struct_len = 20; break;
- case 2: struct_len = 40; break;
- case 91: struct_len = 68; break;
- default: return -1;
- }
-
-
- if (!buf)
- {
- len = 0;
- if (uLevel > 0) len += StrlenExpanded(conn,snum,lp_comment(snum));
- if (uLevel > 1) len += strlen(lp_pathname(snum)) + 1;
- if (buflen) *buflen = struct_len;
- if (stringspace) *stringspace = len;
- return struct_len + len;
- }
-
- len = struct_len;
- p = *buf;
- if ((*buflen) < struct_len) return -1;
- if (stringbuf)
- {
- p2 = *stringbuf;
- l2 = *stringspace;
- }
- else
- {
- p2 = p + struct_len;
- l2 = (*buflen) - struct_len;
- }
- if (!baseaddr) baseaddr = p;
-
- StrnCpy(p,lp_servicename(snum),13);
-
- if (uLevel > 0)
- {
- int type;
- CVAL(p,13) = 0;
- type = STYPE_DISKTREE;
- if (lp_print_ok(snum)) type = STYPE_PRINTQ;
- if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
- SSVAL(p,14,type); /* device type */
- SIVAL(p,16,PTR_DIFF(p2,baseaddr));
- len += CopyExpanded(conn,snum,&p2,lp_comment(snum),&l2);
- }
-
- if (uLevel > 1)
- {
- SSVAL(p,20,ACCESS_READ|ACCESS_WRITE|ACCESS_CREATE); /* permissions */
- SSVALS(p,22,-1); /* max uses */
- SSVAL(p,24,1); /* current uses */
- SIVAL(p,26,PTR_DIFF(p2,baseaddr)); /* local pathname */
- len += CopyAndAdvance(&p2,lp_pathname(snum),&l2);
- memset(p+30,0,SHPWLEN+2); /* passwd (reserved), pad field */
- }
-
- if (uLevel > 2)
- {
- memset(p+40,0,SHPWLEN+2);
- SSVAL(p,50,0);
- SIVAL(p,52,0);
- SSVAL(p,56,0);
- SSVAL(p,58,0);
- SIVAL(p,60,0);
- SSVAL(p,64,0);
- SSVAL(p,66,0);
- }
-
- if (stringbuf)
- {
- (*buf) = p + struct_len;
- (*buflen) -= struct_len;
- (*stringbuf) = p2;
- (*stringspace) = l2;
- }
- else
- {
- (*buf) = p2;
- (*buflen) -= len;
- }
- return len;
-}
-
-static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *netname = skip_string(str2,1);
- char *p = skip_string(netname,1);
- int uLevel = SVAL(p,0);
- int snum = find_service(netname);
-
- if (snum < 0) return False;
-
- /* check it's a supported varient */
- if (!prefix_ok(str1,"zWrLh")) return False;
- if (!check_share_info(uLevel,str2)) return False;
-
- *rdata = REALLOC(*rdata,mdrcnt);
- p = *rdata;
- *rdata_len = fill_share_info(conn,snum,uLevel,&p,&mdrcnt,0,0,0);
- if (*rdata_len < 0) return False;
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,*rdata_len);
-
- return(True);
-}
-
-/****************************************************************************
- view list of shares available
- ****************************************************************************/
-static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- int buf_len = SVAL(p,2);
- char *p2;
- int count=lp_numservices();
- int total=0,counted=0;
- BOOL missed = False;
- int i;
- int data_len, fixed_len, string_len;
- int f_len = 0, s_len = 0;
-
- if (!prefix_ok(str1,"WrLeh")) return False;
- if (!check_share_info(uLevel,str2)) return False;
-
- data_len = fixed_len = string_len = 0;
- for (i=0;i<count;i++)
- if (lp_browseable(i) && lp_snum_ok(i))
- {
- total++;
- data_len += fill_share_info(conn,i,uLevel,0,&f_len,0,&s_len,0);
- if (data_len <= buf_len)
- {
- counted++;
- fixed_len += f_len;
- string_len += s_len;
- }
- else
- missed = True;
- }
- *rdata_len = fixed_len + string_len;
- *rdata = REALLOC(*rdata,*rdata_len);
- memset(*rdata,0,*rdata_len);
-
- p2 = (*rdata) + fixed_len; /* auxillery data (strings) will go here */
- p = *rdata;
- f_len = fixed_len;
- s_len = string_len;
- for (i = 0; i < count;i++)
- if (lp_browseable(i) && lp_snum_ok(i))
- if (fill_share_info(conn,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
- break;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,missed ? ERRmoredata : NERR_Success);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,counted);
- SSVAL(*rparam,6,total);
-
- DEBUG(3,("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
- counted,total,uLevel,
- buf_len,*rdata_len,mdrcnt));
- return(True);
-}
-
-
-
-/****************************************************************************
- get the time of day info
- ****************************************************************************/
-static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *p;
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 21;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
-
- {
- struct tm *t;
- time_t unixdate = time(NULL);
-
- put_dos_date3(p,0,unixdate); /* this is the time that is looked at
- by NT in a "net time" operation,
- it seems to ignore the one below */
-
- /* the client expects to get localtime, not GMT, in this bit
- (I think, this needs testing) */
- t = LocalTime(&unixdate);
-
- SIVAL(p,4,0); /* msecs ? */
- CVAL(p,8) = t->tm_hour;
- CVAL(p,9) = t->tm_min;
- CVAL(p,10) = t->tm_sec;
- CVAL(p,11) = 0; /* hundredths of seconds */
- SSVALS(p,12,TimeDiff(unixdate)/60); /* timezone in minutes from GMT */
- SSVAL(p,14,10000); /* timer interval in 0.0001 of sec */
- CVAL(p,16) = t->tm_mday;
- CVAL(p,17) = t->tm_mon + 1;
- SSVAL(p,18,1900+t->tm_year);
- CVAL(p,20) = t->tm_wday;
- }
-
-
- return(True);
-}
-
-/****************************************************************************
- Set the user password.
-*****************************************************************************/
-
-static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *p = skip_string(param+2,2);
- fstring user;
- fstring pass1,pass2;
-
- fstrcpy(user,p);
-
- p = skip_string(p,1);
-
- memset(pass1,'\0',sizeof(pass1));
- memset(pass2,'\0',sizeof(pass2));
- memcpy(pass1,p,16);
- memcpy(pass2,p+16,16);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_badpass);
- SSVAL(*rparam,2,0); /* converter word */
-
- DEBUG(3,("Set password for <%s>\n",user));
-
- /*
- * Pass the user through the NT -> unix user mapping
- * function.
- */
-
- (void)map_username(user);
-
- /*
- * Do any UNIX username case mangling.
- */
- (void)Get_Pwnam( user, True);
-
- /*
- * Attempt to verify the old password against smbpasswd entries
- * Win98 clients send old and new password in plaintext for this call.
- */
-
- {
- fstring saved_pass2;
- struct smb_passwd *smbpw = NULL;
-
- /*
- * Save the new password as change_oem_password overwrites it
- * with zeros.
- */
-
- fstrcpy(saved_pass2, pass2);
-
- if (check_plaintext_password(user,pass1,strlen(pass1),&smbpw) &&
- change_oem_password(smbpw,pass2,False))
- {
- SSVAL(*rparam,0,NERR_Success);
-
- /*
- * If unix password sync was requested, attempt to change
- * the /etc/passwd database also. Return failure if this cannot
- * be done.
- */
-
- if(lp_unix_password_sync() && !chgpasswd(user,pass1,saved_pass2,False))
- SSVAL(*rparam,0,NERR_badpass);
- }
- }
-
- /*
- * If the above failed, attempt the plaintext password change.
- * This tests against the /etc/passwd database only.
- */
-
- if(SVAL(*rparam,0) != NERR_Success)
- {
- if (password_ok(user, pass1,strlen(pass1),NULL) &&
- chgpasswd(user,pass1,pass2,False))
- {
- SSVAL(*rparam,0,NERR_Success);
- }
- }
-
- /*
- * If the plaintext change failed, attempt
- * the old encrypted method. NT will generate this
- * after trying the samr method. Note that this
- * method is done as a last resort as this
- * password change method loses the NT password hash
- * and cannot change the UNIX password as no plaintext
- * is received.
- */
-
- if(SVAL(*rparam,0) != NERR_Success)
- {
- struct smb_passwd *sampw = NULL;
-
- if(check_lanman_password(user,(unsigned char *)pass1,(unsigned char *)pass2, &sampw) &&
- change_lanman_password(sampw,(unsigned char *)pass1,(unsigned char *)pass2))
- {
- SSVAL(*rparam,0,NERR_Success);
- }
- }
-
- memset((char *)pass1,'\0',sizeof(fstring));
- memset((char *)pass2,'\0',sizeof(fstring));
-
- return(True);
-}
-
-/****************************************************************************
- Set the user password (SamOEM version - gets plaintext).
-****************************************************************************/
-
-static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- fstring user;
- char *p = param + 2;
- *rparam_len = 2;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_badpass);
-
- /*
- * Check the parameter definition is correct.
- */
- if(!strequal(param + 2, "zsT")) {
- DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
- return False;
- }
- p = skip_string(p, 1);
-
- if(!strequal(p, "B516B16")) {
- DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
- return False;
- }
- p = skip_string(p,1);
-
- fstrcpy(user,p);
- p = skip_string(p,1);
-
- DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
-
- /*
- * Pass the user through the NT -> unix user mapping
- * function.
- */
-
- (void)map_username(user);
-
- /*
- * Do any UNIX username case mangling.
- */
- (void)Get_Pwnam( user, True);
-
- if (pass_oem_change(user, (uchar*) data, (uchar *)&data[516], NULL, NULL))
- {
- SSVAL(*rparam,0,NERR_Success);
- }
-
- return(True);
-}
-
-/****************************************************************************
- delete a print job
- Form: <W> <>
- ****************************************************************************/
-static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- int function = SVAL(param,0);
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int jobid, snum;
- int i, count;
-
- printjob_decode(SVAL(p,0), &snum, &jobid);
-
- /* check it's a supported varient */
- if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
- return(False);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_Success);
-
- if (snum >= 0 && VALID_SNUM(snum))
- {
- print_queue_struct *queue=NULL;
- lpq_reset(snum);
- count = get_printqueue(snum,conn,&queue,NULL);
-
- for (i=0;i<count;i++)
- if ((queue[i].job&0xFF) == jobid)
- {
- switch (function) {
- case 81: /* delete */
- DEBUG(3,("Deleting queue entry %d\n",queue[i].job));
- del_printqueue(conn,snum,queue[i].job);
- break;
- case 82: /* pause */
- case 83: /* resume */
- DEBUG(3,("%s queue entry %d\n",
- (function==82?"pausing":"resuming"),queue[i].job));
- status_printjob(conn,snum,queue[i].job,
- (function==82?LPQ_PAUSED:LPQ_QUEUED));
- break;
- }
- break;
- }
-
- if (i==count)
- SSVAL(*rparam,0,NERR_JobNotFound);
-
- if (queue) free(queue);
- }
-
- SSVAL(*rparam,2,0); /* converter word */
-
- return(True);
-}
-
-/****************************************************************************
- Purge a print queue - or pause or resume it.
- ****************************************************************************/
-static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- int function = SVAL(param,0);
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *QueueName = skip_string(str2,1);
- int snum;
-
- /* check it's a supported varient */
- if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
- return(False);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- snum = lp_servicenumber(QueueName);
- if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(QueueName,pnum);
- snum = lp_servicenumber(QueueName);
- }
- }
-
- if (snum >= 0 && VALID_SNUM(snum)) {
- lpq_reset(snum);
-
- switch (function) {
- case 74: /* Pause queue */
- case 75: /* Resume queue */
- status_printqueue(conn,snum,(function==74?LPSTAT_STOPPED:LPSTAT_OK));
- DEBUG(3,("Print queue %s, queue=%s\n",
- (function==74?"pause":"resume"),QueueName));
- break;
- case 103: /* Purge */
- {
- print_queue_struct *queue=NULL;
- int i, count;
- count = get_printqueue(snum,conn,&queue,NULL);
- for (i = 0; i < count; i++)
- del_printqueue(conn,snum,queue[i].job);
-
- if (queue) free(queue);
- DEBUG(3,("Print queue purge, queue=%s\n",QueueName));
- break;
- }
- }
- }
-
- return(True);
-}
-
-
-/****************************************************************************
- set the property of a print job (undocumented?)
- ? function = 0xb -> set name of print job
- ? function = 0x6 -> move print job up/down
- Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz>
- or <WWsTP> <WB21BB16B10zWWzDDz>
-****************************************************************************/
-static int check_printjob_info(struct pack_desc* desc,
- int uLevel, char* id)
-{
- desc->subformat = NULL;
- switch( uLevel ) {
- case 0: desc->format = "W"; break;
- case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
- case 2: desc->format = "WWzWWDDzz"; break;
- case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
- default: return False;
- }
- if (strcmp(desc->format,id) != 0) return False;
- return True;
-}
-
-static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- struct pack_desc desc;
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int jobid, snum;
- int uLevel = SVAL(p,2);
- int function = SVAL(p,4); /* what is this ?? */
- int i;
- char *s = data;
- files_struct *fsp;
-
- printjob_decode(SVAL(p,0), &snum, &jobid);
-
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- /* check it's a supported varient */
- if ((strcmp(str1,"WWsTP")) ||
- (!check_printjob_info(&desc,uLevel,str2)))
- return(False);
-
- switch (function) {
- case 0x6: /* change job place in the queue,
- data gives the new place */
- if (snum >= 0 && VALID_SNUM(snum)) {
- print_queue_struct *queue=NULL;
- int count;
-
- lpq_reset(snum);
- count = get_printqueue(snum,conn,&queue,NULL);
- for (i=0;i<count;i++) /* find job */
- if ((queue[i].job&0xFF) == jobid) break;
-
- if (i==count) {
- desc.errcode=NERR_JobNotFound;
- if (queue) free(queue);
- } else {
- desc.errcode=NERR_Success;
- i++;
-#if 0
- {
- int place= SVAL(data,0);
- /* we currently have no way of
- doing this. Can any unix do it? */
- if (i < place) /* move down */;
- else if (i > place ) /* move up */;
- }
-#endif
- desc.errcode=NERR_notsupported; /* not yet
- supported */
- if (queue) free(queue);
- }
- } else {
- desc.errcode=NERR_JobNotFound;
- }
- break;
-
- case 0xb: /* change print job name, data gives the name */
- /* jobid, snum should be zero */
- if (isalpha((int)*s)) {
- pstring name;
- int l = 0;
-
- while (l<64 && *s) {
- if (issafe(*s)) name[l++] = *s;
- s++;
- }
- name[l] = 0;
-
- DEBUG(3,("Setting print name to %s\n",name));
-
- fsp = file_find_print();
-
- if (fsp) {
- pstring zfrom,zto;
- connection_struct *fconn = fsp->conn;
-
- unbecome_user();
-
- if (!become_user(fconn,vuid) ||
- !become_service(fconn,True))
- break;
-
- pstrcpy(zfrom, dos_to_unix(fsp->fsp_name,False));
- pstrcpy(zto, dos_to_unix(name,False));
-
- if (fsp->conn->vfs_ops.rename(zfrom,zto) == 0) {
- string_set(&fsp->fsp_name,name);
- }
-
- break;
- }
- }
- desc.errcode=NERR_Success;
- break;
-
- default: /* not implemented */
- return False;
- }
-
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0); /* converter word */
-
- return(True);
-}
-
-
-/****************************************************************************
- get info about the server
- ****************************************************************************/
-static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel = SVAL(p,0);
- char *p2;
- int struct_len;
-
- DEBUG(4,("NetServerGetInfo level %d\n",uLevel));
-
- /* check it's a supported varient */
- if (!prefix_ok(str1,"WrLh")) return False;
- switch( uLevel ) {
- case 0:
- if (strcmp(str2,"B16") != 0) return False;
- struct_len = 16;
- break;
- case 1:
- if (strcmp(str2,"B16BBDz") != 0) return False;
- struct_len = 26;
- break;
- case 2:
- if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz")
- != 0) return False;
- struct_len = 134;
- break;
- case 3:
- if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz")
- != 0) return False;
- struct_len = 144;
- break;
- case 20:
- if (strcmp(str2,"DN") != 0) return False;
- struct_len = 6;
- break;
- case 50:
- if (strcmp(str2,"B16BBDzWWzzz") != 0) return False;
- struct_len = 42;
- break;
- default: return False;
- }
-
- *rdata_len = mdrcnt;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- p = *rdata;
- p2 = p + struct_len;
- if (uLevel != 20) {
- StrnCpy(p,local_machine,16);
- strupper(p);
- }
- p += 16;
- if (uLevel > 0)
- {
- struct srv_info_struct *servers=NULL;
- int i,count;
- pstring comment;
- uint32 servertype= lp_default_server_announce();
-
- pstrcpy(comment,string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
-
- if ((count=get_server_info(SV_TYPE_ALL,&servers,global_myworkgroup))>0) {
- for (i=0;i<count;i++)
- if (strequal(servers[i].name,local_machine))
- {
- servertype = servers[i].type;
- pstrcpy(comment,servers[i].comment);
- }
- }
- if (servers) free(servers);
-
- SCVAL(p,0,lp_major_announce_version());
- SCVAL(p,1,lp_minor_announce_version());
- SIVAL(p,2,servertype);
-
- if (mdrcnt == struct_len) {
- SIVAL(p,6,0);
- } else {
- SIVAL(p,6,PTR_DIFF(p2,*rdata));
- standard_sub(conn,comment);
- StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
- p2 = skip_string(p2,1);
- }
- }
- if (uLevel > 1)
- {
- return False; /* not yet implemented */
- }
-
- *rdata_len = PTR_DIFF(p2,*rdata);
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,*rdata_len);
-
- return(True);
-}
-
-
-/****************************************************************************
- get info about the server
- ****************************************************************************/
-static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char *p2;
- extern pstring sesssetup_user;
- int level = SVAL(p,0);
-
- DEBUG(4,("NetWkstaGetInfo level %d\n",level));
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- /* check it's a supported varient */
- if (!(level==10 && strcsequal(str1,"WrLh") && strcsequal(str2,"zzzBBzz")))
- return(False);
-
- *rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
- p2 = p + 22;
-
-
- SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* host name */
- pstrcpy(p2,local_machine);
- strupper(p2);
- p2 = skip_string(p2,1);
- p += 4;
-
- SIVAL(p,0,PTR_DIFF(p2,*rdata));
- pstrcpy(p2,sesssetup_user);
- p2 = skip_string(p2,1);
- p += 4;
-
- SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
- pstrcpy(p2,global_myworkgroup);
- strupper(p2);
- p2 = skip_string(p2,1);
- p += 4;
-
- SCVAL(p,0,lp_major_announce_version()); /* system version - e.g 4 in 4.1 */
- SCVAL(p,1,lp_minor_announce_version()); /* system version - e.g .1 in 4.1 */
- p += 2;
-
- SIVAL(p,0,PTR_DIFF(p2,*rdata));
- pstrcpy(p2,global_myworkgroup); /* don't know. login domain?? */
- p2 = skip_string(p2,1);
- p += 4;
-
- SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* don't know */
- pstrcpy(p2,"");
- p2 = skip_string(p2,1);
- p += 4;
-
- *rdata_len = PTR_DIFF(p2,*rdata);
-
- SSVAL(*rparam,4,*rdata_len);
-
- return(True);
-}
-
-/****************************************************************************
- get info about a user
-
- struct user_info_11 {
- char usri11_name[21]; 0-20
- char usri11_pad; 21
- char *usri11_comment; 22-25
- char *usri11_usr_comment; 26-29
- unsigned short usri11_priv; 30-31
- unsigned long usri11_auth_flags; 32-35
- long usri11_password_age; 36-39
- char *usri11_homedir; 40-43
- char *usri11_parms; 44-47
- long usri11_last_logon; 48-51
- long usri11_last_logoff; 52-55
- unsigned short usri11_bad_pw_count; 56-57
- unsigned short usri11_num_logons; 58-59
- char *usri11_logon_server; 60-63
- unsigned short usri11_country_code; 64-65
- char *usri11_workstations; 66-69
- unsigned long usri11_max_storage; 70-73
- unsigned short usri11_units_per_week; 74-75
- unsigned char *usri11_logon_hours; 76-79
- unsigned short usri11_code_page; 80-81
- };
-
-where:
-
- usri11_name specifies the user name for which information is retireved
-
- usri11_pad aligns the next data structure element to a word boundary
-
- usri11_comment is a null terminated ASCII comment
-
- usri11_user_comment is a null terminated ASCII comment about the user
-
- usri11_priv specifies the level of the privilege assigned to the user.
- The possible values are:
-
-Name Value Description
-USER_PRIV_GUEST 0 Guest privilege
-USER_PRIV_USER 1 User privilege
-USER_PRV_ADMIN 2 Administrator privilege
-
- usri11_auth_flags specifies the account operator privileges. The
- possible values are:
-
-Name Value Description
-AF_OP_PRINT 0 Print operator
-
-
-Leach, Naik [Page 28]
-
-
-INTERNET-DRAFT CIFS Remote Admin Protocol January 10, 1997
-
-
-AF_OP_COMM 1 Communications operator
-AF_OP_SERVER 2 Server operator
-AF_OP_ACCOUNTS 3 Accounts operator
-
-
- usri11_password_age specifies how many seconds have elapsed since the
- password was last changed.
-
- usri11_home_dir points to a null terminated ASCII string that contains
- the path name of the user's home directory.
-
- usri11_parms points to a null terminated ASCII string that is set
- aside for use by applications.
-
- usri11_last_logon specifies the time when the user last logged on.
- This value is stored as the number of seconds elapsed since
- 00:00:00, January 1, 1970.
-
- usri11_last_logoff specifies the time when the user last logged off.
- This value is stored as the number of seconds elapsed since
- 00:00:00, January 1, 1970. A value of 0 means the last logoff
- time is unknown.
-
- usri11_bad_pw_count specifies the number of incorrect passwords
- entered since the last successful logon.
-
- usri11_log1_num_logons specifies the number of times this user has
- logged on. A value of -1 means the number of logons is unknown.
-
- usri11_logon_server points to a null terminated ASCII string that
- contains the name of the server to which logon requests are sent.
- A null string indicates logon requests should be sent to the
- domain controller.
-
- usri11_country_code specifies the country code for the user's language
- of choice.
-
- usri11_workstations points to a null terminated ASCII string that
- contains the names of workstations the user may log on from.
- There may be up to 8 workstations, with the names separated by
- commas. A null strings indicates there are no restrictions.
-
- usri11_max_storage specifies the maximum amount of disk space the user
- can occupy. A value of 0xffffffff indicates there are no
- restrictions.
-
- usri11_units_per_week specifies the equal number of time units into
- which a week is divided. This value must be equal to 168.
-
- usri11_logon_hours points to a 21 byte (168 bits) string that
- specifies the time during which the user can log on. Each bit
- represents one unique hour in a week. The first bit (bit 0, word
- 0) is Sunday, 0:00 to 0:59, the second bit (bit 1, word 0) is
-
-
-
-Leach, Naik [Page 29]
-
-
-INTERNET-DRAFT CIFS Remote Admin Protocol January 10, 1997
-
-
- Sunday, 1:00 to 1:59 and so on. A null pointer indicates there
- are no restrictions.
-
- usri11_code_page specifies the code page for the user's language of
- choice
-
-All of the pointers in this data structure need to be treated
-specially. The pointer is a 32 bit pointer. The higher 16 bits need
-to be ignored. The converter word returned in the parameters section
-needs to be subtracted from the lower 16 bits to calculate an offset
-into the return buffer where this ASCII string resides.
-
-There is no auxiliary data in the response.
-
- ****************************************************************************/
-
-#define usri11_name 0
-#define usri11_pad 21
-#define usri11_comment 22
-#define usri11_usr_comment 26
-#define usri11_full_name 30
-#define usri11_priv 34
-#define usri11_auth_flags 36
-#define usri11_password_age 40
-#define usri11_homedir 44
-#define usri11_parms 48
-#define usri11_last_logon 52
-#define usri11_last_logoff 56
-#define usri11_bad_pw_count 60
-#define usri11_num_logons 62
-#define usri11_logon_server 64
-#define usri11_country_code 68
-#define usri11_workstations 70
-#define usri11_max_storage 74
-#define usri11_units_per_week 78
-#define usri11_logon_hours 80
-#define usri11_code_page 84
-#define usri11_end 86
-
-#define USER_PRIV_GUEST 0
-#define USER_PRIV_USER 1
-#define USER_PRIV_ADMIN 2
-
-#define AF_OP_PRINT 0
-#define AF_OP_COMM 1
-#define AF_OP_SERVER 2
-#define AF_OP_ACCOUNTS 3
-
-
-static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *UserName = skip_string(str2,1);
- char *p = skip_string(UserName,1);
- int uLevel = SVAL(p,0);
- char *p2;
-
- /* get NIS home of a previously validated user - simeon */
- /* With share level security vuid will always be zero.
- Don't depend on vuser being non-null !!. JRA */
- user_struct *vuser = get_valid_user_struct(vuid);
- if(vuser != NULL)
- DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid, vuser->name));
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- DEBUG(4,("RNetUserGetInfo level=%d\n", uLevel));
-
- /* check it's a supported variant */
- if (strcmp(str1,"zWrLh") != 0) return False;
- switch( uLevel )
- {
- case 0: p2 = "B21"; break;
- case 1: p2 = "B21BB16DWzzWz"; break;
- case 2: p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
- case 10: p2 = "B21Bzzz"; break;
- case 11: p2 = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
- default: return False;
- }
-
- if (strcmp(p2,str2) != 0) return False;
-
- *rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
- p2 = p + usri11_end;
-
- memset(p,0,21);
- fstrcpy(p+usri11_name,UserName); /* 21 bytes - user name */
-
- if (uLevel > 0)
- {
- SCVAL(p,usri11_pad,0); /* padding - 1 byte */
- *p2 = 0;
- }
- if (uLevel >= 10)
- {
- SIVAL(p,usri11_comment,PTR_DIFF(p2,p)); /* comment */
- pstrcpy(p2,"Comment");
- p2 = skip_string(p2,1);
-
- SIVAL(p,usri11_usr_comment,PTR_DIFF(p2,p)); /* user_comment */
- pstrcpy(p2,"UserComment");
- p2 = skip_string(p2,1);
-
- /* EEK! the cifsrap.txt doesn't have this in!!!! */
- SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */
- pstrcpy(p2,((vuser != NULL) ? vuser->real_name : UserName));
- p2 = skip_string(p2,1);
- }
-
- if (uLevel == 11) /* modelled after NTAS 3.51 reply */
- {
- SSVAL(p,usri11_priv,conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
- SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
- SIVALS(p,usri11_password_age,-1); /* password age */
- SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
- pstrcpy(p2, lp_logon_home());
- p2 = skip_string(p2,1);
- SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
- pstrcpy(p2,"");
- p2 = skip_string(p2,1);
- SIVAL(p,usri11_last_logon,0); /* last logon */
- SIVAL(p,usri11_last_logoff,0); /* last logoff */
- SSVALS(p,usri11_bad_pw_count,-1); /* bad pw counts */
- SSVALS(p,usri11_num_logons,-1); /* num logons */
- SIVAL(p,usri11_logon_server,PTR_DIFF(p2,p)); /* logon server */
- pstrcpy(p2,"\\\\*");
- p2 = skip_string(p2,1);
- SSVAL(p,usri11_country_code,0); /* country code */
-
- SIVAL(p,usri11_workstations,PTR_DIFF(p2,p)); /* workstations */
- pstrcpy(p2,"");
- p2 = skip_string(p2,1);
-
- SIVALS(p,usri11_max_storage,-1); /* max storage */
- SSVAL(p,usri11_units_per_week,168); /* units per week */
- SIVAL(p,usri11_logon_hours,PTR_DIFF(p2,p)); /* logon hours */
-
- /* a simple way to get logon hours at all times. */
- memset(p2,0xff,21);
- SCVAL(p2,21,0); /* fix zero termination */
- p2 = skip_string(p2,1);
-
- SSVAL(p,usri11_code_page,0); /* code page */
- }
- if (uLevel == 1 || uLevel == 2)
- {
- memset(p+22,' ',16); /* password */
- SIVALS(p,38,-1); /* password age */
- SSVAL(p,42,
- conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
- SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
- pstrcpy(p2,lp_logon_home());
- p2 = skip_string(p2,1);
- SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
- *p2++ = 0;
- SSVAL(p,52,0); /* flags */
- SIVAL(p,54,PTR_DIFF(p2,*rdata)); /* script_path */
- pstrcpy(p2,lp_logon_script());
- standard_sub( conn, p2 );
- p2 = skip_string(p2,1);
- if (uLevel == 2)
- {
- SIVAL(p,60,0); /* auth_flags */
- SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
- pstrcpy(p2,((vuser != NULL) ? vuser->real_name : UserName));
- p2 = skip_string(p2,1);
- SIVAL(p,68,0); /* urs_comment */
- SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
- pstrcpy(p2,"");
- p2 = skip_string(p2,1);
- SIVAL(p,76,0); /* workstations */
- SIVAL(p,80,0); /* last_logon */
- SIVAL(p,84,0); /* last_logoff */
- SIVALS(p,88,-1); /* acct_expires */
- SIVALS(p,92,-1); /* max_storage */
- SSVAL(p,96,168); /* units_per_week */
- SIVAL(p,98,PTR_DIFF(p2,*rdata)); /* logon_hours */
- memset(p2,-1,21);
- p2 += 21;
- SSVALS(p,102,-1); /* bad_pw_count */
- SSVALS(p,104,-1); /* num_logons */
- SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
- pstrcpy(p2,"\\\\%L");
- standard_sub_basic(p2);
- p2 = skip_string(p2,1);
- SSVAL(p,110,49); /* country_code */
- SSVAL(p,112,860); /* code page */
- }
- }
-
- *rdata_len = PTR_DIFF(p2,*rdata);
-
- SSVAL(*rparam,4,*rdata_len); /* is this right?? */
-
- return(True);
-}
-
-/*******************************************************************
- get groups that a user is a member of
- ******************************************************************/
-static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *UserName = skip_string(str2,1);
- char *p = skip_string(UserName,1);
- int uLevel = SVAL(p,0);
- char *p2;
- int count=0;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- /* check it's a supported varient */
- if (strcmp(str1,"zWrLeh") != 0) return False;
- switch( uLevel ) {
- case 0: p2 = "B21"; break;
- default: return False;
- }
- if (strcmp(p2,str2) != 0) return False;
-
- *rdata_len = mdrcnt + 1024;
- *rdata = REALLOC(*rdata,*rdata_len);
-
- SSVAL(*rparam,0,NERR_Success);
- SSVAL(*rparam,2,0); /* converter word */
-
- p = *rdata;
-
- /* XXXX we need a real SAM database some day */
- pstrcpy(p,"Users"); p += 21; count++;
- pstrcpy(p,"Domain Users"); p += 21; count++;
- pstrcpy(p,"Guests"); p += 21; count++;
- pstrcpy(p,"Domain Guests"); p += 21; count++;
-
- *rdata_len = PTR_DIFF(p,*rdata);
-
- SSVAL(*rparam,4,count); /* is this right?? */
- SSVAL(*rparam,6,count); /* is this right?? */
-
- return(True);
-}
-
-
-static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- struct pack_desc desc;
- char* name;
-
- uLevel = SVAL(p,0);
- name = p + 2;
-
- memset((char *)&desc,'\0',sizeof(desc));
-
- DEBUG(3,("WWkstaUserLogon uLevel=%d name=%s\n",uLevel,name));
-
- /* check it's a supported varient */
- if (strcmp(str1,"OOWb54WrLh") != 0) return False;
- if (uLevel != 1 || strcmp(str2,"WB21BWDWWDDDDDDDzzzD") != 0) return False;
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.subformat = NULL;
- desc.format = str2;
-
- if (init_package(&desc,1,0))
- {
- PACKI(&desc,"W",0); /* code */
- PACKS(&desc,"B21",name); /* eff. name */
- PACKS(&desc,"B",""); /* pad */
- PACKI(&desc,"W",
- conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
- PACKI(&desc,"D",0); /* auth flags XXX */
- PACKI(&desc,"W",0); /* num logons */
- PACKI(&desc,"W",0); /* bad pw count */
- PACKI(&desc,"D",0); /* last logon */
- PACKI(&desc,"D",-1); /* last logoff */
- PACKI(&desc,"D",-1); /* logoff time */
- PACKI(&desc,"D",-1); /* kickoff time */
- PACKI(&desc,"D",0); /* password age */
- PACKI(&desc,"D",0); /* password can change */
- PACKI(&desc,"D",-1); /* password must change */
- {
- fstring mypath;
- fstrcpy(mypath,"\\\\");
- fstrcat(mypath,local_machine);
- strupper(mypath);
- PACKS(&desc,"z",mypath); /* computer */
- }
- PACKS(&desc,"z",global_myworkgroup);/* domain */
-
-/* JHT - By calling lp_logon_script() and standard_sub() we have */
-/* made sure all macros are fully substituted and available */
- {
- pstring logon_script;
- pstrcpy(logon_script,lp_logon_script());
- standard_sub( conn, logon_script );
- PACKS(&desc,"z", logon_script); /* script path */
- }
-/* End of JHT mods */
-
- PACKI(&desc,"D",0x00000000); /* reserved */
- }
-
- *rdata_len = desc.usedlen;
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- DEBUG(4,("WWkstaUserLogon: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-
-/****************************************************************************
- api_WAccessGetUserPerms
- ****************************************************************************/
-static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *user = skip_string(str2,1);
- char *resource = skip_string(user,1);
-
- DEBUG(3,("WAccessGetUserPerms user=%s resource=%s\n",user,resource));
-
- /* check it's a supported varient */
- if (strcmp(str1,"zzh") != 0) return False;
- if (strcmp(str2,"") != 0) return False;
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,0); /* errorcode */
- SSVAL(*rparam,2,0); /* converter word */
- SSVAL(*rparam,4,0x7f); /* permission flags */
-
- return(True);
-}
-
-/****************************************************************************
- api_WPrintJobEnumerate
- ****************************************************************************/
-static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- int count;
- int i;
- int snum;
- int job;
- struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
-
- uLevel = SVAL(p,2);
-
- memset((char *)&desc,'\0',sizeof(desc));
- memset((char *)&status,'\0',sizeof(status));
-
- DEBUG(3,("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n",uLevel,SVAL(p,0)));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WWrLh") != 0) return False;
- if (!check_printjob_info(&desc,uLevel,str2)) return False;
-
- printjob_decode(SVAL(p,0), &snum, &job);
-
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
-
- count = get_printqueue(snum,conn,&queue,&status);
- for (i = 0; i < count; i++) {
- if ((queue[i].job & 0xFF) == job) break;
- }
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
-
- if (init_package(&desc,1,0)) {
- if (i < count) {
- fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
- *rdata_len = desc.usedlen;
- }
- else {
- desc.errcode = NERR_JobNotFound;
- *rdata_len = 0;
- }
- }
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- if (queue) free(queue);
-
- DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char* name = p;
- int uLevel;
- int count;
- int i, succnt=0;
- int snum;
- struct pack_desc desc;
- print_queue_struct *queue=NULL;
- print_status_struct status;
-
- memset((char *)&desc,'\0',sizeof(desc));
- memset((char *)&status,'\0',sizeof(status));
-
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
-
- DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
-
- /* check it's a supported varient */
- if (strcmp(str1,"zWrLeh") != 0) return False;
- if (uLevel > 2) return False; /* defined only for uLevel 0,1,2 */
- if (!check_printjob_info(&desc,uLevel,str2)) return False;
-
- snum = lp_servicenumber(name);
- if (snum < 0 && pcap_printername_ok(name,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(name,pnum);
- snum = lp_servicenumber(name);
- }
- }
-
- if (snum < 0 || !VALID_SNUM(snum)) return(False);
-
- count = get_printqueue(snum,conn,&queue,&status);
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
-
- if (init_package(&desc,count,0)) {
- succnt = 0;
- for (i = 0; i < count; i++) {
- fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
- if (desc.errcode == NERR_Success) succnt = i+1;
- }
- }
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,count);
-
- if (queue) free(queue);
-
- DEBUG(4,("WPrintJobEnumerate: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static int check_printdest_info(struct pack_desc* desc,
- int uLevel, char* id)
-{
- desc->subformat = NULL;
- switch( uLevel ) {
- case 0: desc->format = "B9"; break;
- case 1: desc->format = "B9B21WWzW"; break;
- case 2: desc->format = "z"; break;
- case 3: desc->format = "zzzWWzzzWW"; break;
- default: return False;
- }
- if (strcmp(desc->format,id) != 0) return False;
- return True;
-}
-
-static void fill_printdest_info(connection_struct *conn, int snum, int uLevel,
- struct pack_desc* desc)
-{
- char buf[100];
- strncpy(buf,SERVICE(snum),sizeof(buf)-1);
- buf[sizeof(buf)-1] = 0;
- strupper(buf);
- if (uLevel <= 1) {
- PACKS(desc,"B9",buf); /* szName */
- if (uLevel == 1) {
- PACKS(desc,"B21",""); /* szUserName */
- PACKI(desc,"W",0); /* uJobId */
- PACKI(desc,"W",0); /* fsStatus */
- PACKS(desc,"z",""); /* pszStatus */
- PACKI(desc,"W",0); /* time */
- }
- }
- if (uLevel == 2 || uLevel == 3) {
- PACKS(desc,"z",buf); /* pszPrinterName */
- if (uLevel == 3) {
- PACKS(desc,"z",""); /* pszUserName */
- PACKS(desc,"z",""); /* pszLogAddr */
- PACKI(desc,"W",0); /* uJobId */
- PACKI(desc,"W",0); /* fsStatus */
- PACKS(desc,"z",""); /* pszStatus */
- PACKS(desc,"z",""); /* pszComment */
- PACKS(desc,"z","NULL"); /* pszDrivers */
- PACKI(desc,"W",0); /* time */
- PACKI(desc,"W",0); /* pad1 */
- }
- }
-}
-
-static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- char* PrinterName = p;
- int uLevel;
- struct pack_desc desc;
- int snum;
-
- memset((char *)&desc,'\0',sizeof(desc));
-
- p = skip_string(p,1);
- uLevel = SVAL(p,0);
-
- DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel,PrinterName));
-
- /* check it's a supported varient */
- if (strcmp(str1,"zWrLh") != 0) return False;
- if (!check_printdest_info(&desc,uLevel,str2)) return False;
-
- snum = lp_servicenumber(PrinterName);
- if (snum < 0 && pcap_printername_ok(PrinterName,NULL)) {
- int pnum = lp_servicenumber(PRINTERS_NAME);
- if (pnum >= 0) {
- lp_add_printer(PrinterName,pnum);
- snum = lp_servicenumber(PrinterName);
- }
- }
-
- if (snum < 0) {
- *rdata_len = 0;
- desc.errcode = NERR_DestNotFound;
- desc.neededlen = 0;
- }
- else {
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,1,0)) {
- fill_printdest_info(conn,snum,uLevel,&desc);
- }
- *rdata_len = desc.usedlen;
- }
-
- *rparam_len = 6;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,desc.neededlen);
-
- DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- int queuecnt;
- int i, n, succnt=0;
- struct pack_desc desc;
- int services = lp_numservices();
-
- memset((char *)&desc,'\0',sizeof(desc));
-
- uLevel = SVAL(p,0);
-
- DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (!check_printdest_info(&desc,uLevel,str2)) return False;
-
- queuecnt = 0;
- for (i = 0; i < services; i++)
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
- queuecnt++;
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,queuecnt,0)) {
- succnt = 0;
- n = 0;
- for (i = 0; i < services; i++) {
- if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
- fill_printdest_info(conn,i,uLevel,&desc);
- n++;
- if (desc.errcode == NERR_Success) succnt = n;
- }
- }
- }
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,queuecnt);
-
- DEBUG(4,("WPrintDestEnumerate: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- int succnt;
- struct pack_desc desc;
-
- memset((char *)&desc,'\0',sizeof(desc));
-
- uLevel = SVAL(p,0);
-
- DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (uLevel != 0 || strcmp(str2,"B41") != 0) return False;
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- if (init_package(&desc,1,0)) {
- PACKS(&desc,"B41","NULL");
- }
-
- succnt = (desc.errcode == NERR_Success ? 1 : 0);
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,1);
-
- DEBUG(4,("WPrintDriverEnum: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- int succnt;
- struct pack_desc desc;
-
- memset((char *)&desc,'\0',sizeof(desc));
-
- uLevel = SVAL(p,0);
-
- DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (uLevel != 0 || strcmp(str2,"B13") != 0) return False;
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.format = str2;
- if (init_package(&desc,1,0)) {
- PACKS(&desc,"B13","lpd");
- }
-
- succnt = (desc.errcode == NERR_Success ? 1 : 0);
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,1);
-
- DEBUG(4,("WPrintQProcEnum: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- char *str1 = param+2;
- char *str2 = skip_string(str1,1);
- char *p = skip_string(str2,1);
- int uLevel;
- int succnt;
- struct pack_desc desc;
-
- memset((char *)&desc,'\0',sizeof(desc));
-
- uLevel = SVAL(p,0);
-
- DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel));
-
- /* check it's a supported varient */
- if (strcmp(str1,"WrLeh") != 0) return False;
- if (uLevel != 0 || strcmp(str2,"B9") != 0) return False;
-
- if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
- memset((char *)&desc,'\0',sizeof(desc));
- desc.base = *rdata;
- desc.buflen = mdrcnt;
- desc.format = str2;
- if (init_package(&desc,1,0)) {
- PACKS(&desc,"B13","lp0");
- }
-
- succnt = (desc.errcode == NERR_Success ? 1 : 0);
-
- *rdata_len = desc.usedlen;
-
- *rparam_len = 8;
- *rparam = REALLOC(*rparam,*rparam_len);
- SSVALS(*rparam,0,desc.errcode);
- SSVAL(*rparam,2,0);
- SSVAL(*rparam,4,succnt);
- SSVAL(*rparam,6,1);
-
- DEBUG(4,("WPrintPortEnum: errorcode %d\n",desc.errcode));
- return(True);
-}
-
-/****************************************************************************
- Start the first part of an RPC reply which began with an SMBtrans request.
-****************************************************************************/
-
-static BOOL api_rpc_trans_reply(char *outbuf, pipes_struct *p,
- char *redir_data, int redir_len)
-{
- char *rdata;
- int data_len;
-
- if (redir_data != NULL)
- {
- send_trans_reply(outbuf, NULL, 0, redir_data, redir_len,
- redir_len > p->max_trans_reply);
- return True;
- }
-
- rdata = malloc(p->max_trans_reply);
- if(rdata == NULL) {
- DEBUG(0,("api_rpc_trans_reply: malloc fail.\n"));
- return False;
- }
-
- if((data_len = read_from_pipe( p, rdata, p->max_trans_reply)) < 0) {
- free(rdata);
- return False;
- }
-
- send_trans_reply(outbuf, NULL, 0, rdata, data_len, (int)prs_offset(&p->out_data.rdata) > data_len);
-
- free(rdata);
- return True;
+ prs_struct ps;
+ prs_create(&ps, rdata, rlen, 0, False);
+ prs_debug_out(&ps, "api_rpc_trans_reply", 200);
+ send_trans_reply(outbuf, &ps, NULL, NULL, 0, rlen,
+ pipe_data_outstanding);
}
/****************************************************************************
WaitNamedPipeHandleState
****************************************************************************/
-
-static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
+static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param, int mdrcnt)
{
uint16 priority;
- if (!param || param_len < 2)
- return False;
+ if (!param) return False;
- priority = SVAL(param,0);
+ priority = param[0] + (param[1] << 8);
DEBUG(4,("WaitNamedPipeHandleState priority %x\n", priority));
- if (wait_rpc_pipe_hnd_state(p, priority)) {
+ if (wait_rpc_pipe_hnd_state(p, priority))
+ {
/* now send the reply */
- send_trans_reply(outbuf, NULL, 0, NULL, 0, False);
+ send_trans_reply(outbuf, NULL, NULL, NULL, 0, mdrcnt, False);
+
return True;
}
return False;
@@ -3257,20 +206,20 @@ static BOOL api_WNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
/****************************************************************************
SetNamedPipeHandleState
****************************************************************************/
-
-static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
+static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param, int mdrcnt)
{
uint16 id;
- if (!param || param_len < 2)
- return False;
+ if (!param) return False;
- id = SVAL(param,0);
+ id = param[0] + (param[1] << 8);
DEBUG(4,("SetNamedPipeHandleState to code %x\n", id));
- if (set_rpc_pipe_hnd_state(p, id)) {
+ if (set_rpc_pipe_hnd_state(p, id))
+ {
/* now send the reply */
- send_trans_reply(outbuf, NULL, 0, NULL, 0, False);
+ send_trans_reply(outbuf, NULL, NULL, NULL, 0, mdrcnt, False);
+
return True;
}
return False;
@@ -3278,262 +227,110 @@ static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param, int param_len)
/****************************************************************************
- When no reply is generated, indicate unsupported.
+ when no reply is generated, indicate unsupported.
****************************************************************************/
-
static BOOL api_no_reply(char *outbuf, int max_rdata_len)
{
- char rparam[4];
+ prs_struct rparam;
+
+ prs_init(&rparam, 4, 0, False);
+
+ rparam.start = 0;
+ rparam.end = 4;
/* unsupported */
- SSVAL(rparam,0,NERR_notsupported);
- SSVAL(rparam,2,0); /* converter word */
+ SSVAL(rparam.data,0,NERR_notsupported);
+ SSVAL(rparam.data,2,0); /* converter word */
DEBUG(3,("Unsupported API fd command\n"));
/* now send the reply */
- send_trans_reply(outbuf, rparam, 4, NULL, 0, False);
+ send_trans_reply(outbuf, NULL, &rparam, NULL, 0, max_rdata_len, False);
- return -1;
+ prs_free_data(&rparam);
+
+ return(-1);
}
/****************************************************************************
- Handle remote api calls delivered to a named pipe already opened.
- ****************************************************************************/
-
+ handle remote api calls delivered to a named pipe already opened.
+ ****************************************************************************/
static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
uint16 *setup,char *data,char *params,
int suwcnt,int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
{
- BOOL reply = False;
+ BOOL reply = False;
+
+ uint16 pnum;
+ uint16 subcommand;
pipes_struct *p = NULL;
- int pnum;
- int subcommand;
DEBUG(5,("api_fd_reply\n"));
/* First find out the name of this file. */
- if (suwcnt != 2) {
+ if (suwcnt != 2)
+ {
DEBUG(0,("Unexpected named pipe transaction.\n"));
return(-1);
}
/* Get the file handle and hence the file name. */
- /*
- * NB. The setup array has already been transformed
- * via SVAL and so is in gost byte order.
- */
- pnum = ((int)setup[1]) & 0xFFFF;
- subcommand = ((int)setup[0]) & 0xFFFF;
-
- if(!(p = get_rpc_pipe(pnum))) {
- DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
- return api_no_reply(outbuf, mdrcnt);
- }
-
- DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)", subcommand, p->name, pnum));
-
- /* record maximum data length that can be transmitted in an SMBtrans */
- p->max_trans_reply = mdrcnt;
-
- DEBUG(10,("api_fd_reply: p:%p max_trans_reply: %d\n", p, p->max_trans_reply));
+ pnum = setup[1];
+ subcommand = setup[0];
+ p = get_rpc_pipe(pnum);
- switch (subcommand) {
- case 0x26:
+ if (p != NULL)
{
- char *rdata = NULL;
- int rlen = mdrcnt;
+ DEBUG(3,("Got API command 0x%x on pipe \"%s\" (pnum %x)",
+ subcommand, p->name, pnum));
- if (p->m)
- {
- reply = readwrite_pipe(p, data, tdscnt, &rdata, &rlen);
- }
- else
+ /* record maximum data length that can be transmitted in an SMBtrans */
+ DEBUG(10,("api_fd_reply: p:%p mdrcnt: %d\n", p, mdrcnt));
+
+ switch (subcommand)
{
- /* dce/rpc command */
- reply = rpc_command(p, data, tdscnt);
+ case 0x26:
+ {
+ BOOL pipe_outstanding = False;
+ char *rdata = NULL;
+ int rlen = mdrcnt;
+ reply = readwrite_pipe(p, data, tdscnt,
+ &rdata, &rlen,
+ &pipe_outstanding);
+ if (reply)
+ {
+ api_rpc_trans_reply(outbuf, rdata, rlen,
+ pipe_outstanding);
+ }
+ break;
+ }
+ case 0x53:
+ {
+ /* Wait Named Pipe Handle state */
+ reply = api_WNPHS(outbuf, p, params, mdrcnt);
+ break;
+ }
+ case 0x01:
+ {
+ /* Set Named Pipe Handle state */
+ reply = api_SNPHS(outbuf, p, params, mdrcnt);
+ break;
+ }
}
- if (reply)
- reply = api_rpc_trans_reply(outbuf, p, rdata, rlen);
- break;
}
- case 0x53:
- /* Wait Named Pipe Handle state */
- reply = api_WNPHS(outbuf, p, params, tpscnt);
- break;
- case 0x01:
- /* Set Named Pipe Handle state */
- reply = api_SNPHS(outbuf, p, params, tpscnt);
- break;
+ else
+ {
+ DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
}
if (!reply)
+ {
return api_no_reply(outbuf, mdrcnt);
-
+ }
return -1;
}
/****************************************************************************
- The buffer was too small
- ****************************************************************************/
-
-static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- *rparam_len = MIN(*rparam_len,mprcnt);
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_BufTooSmall);
-
- DEBUG(3,("Supplied buffer too small in API command\n"));
-
- return(True);
-}
-
-
-/****************************************************************************
- The request is not supported
- ****************************************************************************/
-
-static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data,
- int mdrcnt,int mprcnt,
- char **rdata,char **rparam,
- int *rdata_len,int *rparam_len)
-{
- *rparam_len = 4;
- *rparam = REALLOC(*rparam,*rparam_len);
-
- *rdata_len = 0;
-
- SSVAL(*rparam,0,NERR_notsupported);
- SSVAL(*rparam,2,0); /* converter word */
-
- DEBUG(3,("Unsupported API command\n"));
-
- return(True);
-}
-
-
-
-
-struct
-{
- char *name;
- int id;
- BOOL (*fn)(connection_struct *,uint16,char *,char *,
- int,int,char **,char **,int *,int *);
- int flags;
-} api_commands[] = {
- {"RNetShareEnum", 0, api_RNetShareEnum,0},
- {"RNetShareGetInfo", 1, api_RNetShareGetInfo,0},
- {"RNetServerGetInfo", 13, api_RNetServerGetInfo,0},
- {"RNetGroupGetUsers", 52, api_RNetGroupGetUsers,0},
- {"RNetUserGetInfo", 56, api_RNetUserGetInfo,0},
- {"NetUserGetGroups", 59, api_NetUserGetGroups,0},
- {"NetWkstaGetInfo", 63, api_NetWkstaGetInfo,0},
- {"DosPrintQEnum", 69, api_DosPrintQEnum,0},
- {"DosPrintQGetInfo", 70, api_DosPrintQGetInfo,0},
- {"WPrintQueuePause", 74, api_WPrintQueuePurge,0},
- {"WPrintQueueResume", 75, api_WPrintQueuePurge,0},
- {"WPrintJobEnumerate",76, api_WPrintJobEnumerate,0},
- {"WPrintJobGetInfo", 77, api_WPrintJobGetInfo,0},
- {"RDosPrintJobDel", 81, api_RDosPrintJobDel,0},
- {"RDosPrintJobPause", 82, api_RDosPrintJobDel,0},
- {"RDosPrintJobResume",83, api_RDosPrintJobDel,0},
- {"WPrintDestEnum", 84, api_WPrintDestEnum,0},
- {"WPrintDestGetInfo", 85, api_WPrintDestGetInfo,0},
- {"NetRemoteTOD", 91, api_NetRemoteTOD,0},
- {"WPrintQueuePurge", 103, api_WPrintQueuePurge,0},
- {"NetServerEnum", 104, api_RNetServerEnum,0},
- {"WAccessGetUserPerms",105, api_WAccessGetUserPerms,0},
- {"SetUserPassword", 115, api_SetUserPassword,0},
- {"WWkstaUserLogon", 132, api_WWkstaUserLogon,0},
- {"PrintJobInfo", 147, api_PrintJobInfo,0},
- {"WPrintDriverEnum", 205, api_WPrintDriverEnum,0},
- {"WPrintQProcEnum", 206, api_WPrintQProcEnum,0},
- {"WPrintPortEnum", 207, api_WPrintPortEnum,0},
- {"SamOEMChangePassword", 214, api_SamOEMChangePassword,0},
- {NULL, -1, api_Unsupported,0}};
-
-
-/****************************************************************************
- Handle remote api calls
- ****************************************************************************/
-
-static int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
- int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
-{
- int api_command;
- char *rdata = NULL;
- char *rparam = NULL;
- int rdata_len = 0;
- int rparam_len = 0;
- BOOL reply=False;
- int i;
-
- if (!params) {
- DEBUG(0,("ERROR: NULL params in api_reply()\n"));
- return 0;
- }
-
- api_command = SVAL(params,0);
-
- DEBUG(3,("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
- api_command,
- params+2,
- skip_string(params+2,1),
- tdscnt,tpscnt,mdrcnt,mprcnt));
-
- for (i=0;api_commands[i].name;i++) {
- if (api_commands[i].id == api_command && api_commands[i].fn) {
- DEBUG(3,("Doing %s\n",api_commands[i].name));
- break;
- }
- }
-
- rdata = (char *)malloc(1024);
- if (rdata)
- memset(rdata,'\0',1024);
-
- rparam = (char *)malloc(1024);
- if (rparam)
- memset(rparam,'\0',1024);
-
- if(!rdata || !rparam) {
- DEBUG(0,("api_reply: malloc fail !\n"));
- return -1;
- }
-
- reply = api_commands[i].fn(conn,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
-
-
- if (rdata_len > mdrcnt ||
- rparam_len > mprcnt) {
- reply = api_TooSmall(conn,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
- }
-
- /* if we get False back then it's actually unsupported */
- if (!reply)
- api_Unsupported(conn,vuid,params,data,mdrcnt,mprcnt,
- &rdata,&rparam,&rdata_len,&rparam_len);
-
- send_trans_reply(outbuf, rparam, rparam_len, rdata, rdata_len, False);
-
- if (rdata )
- free(rdata);
- if (rparam)
- free(rparam);
-
- return -1;
-}
-
-/****************************************************************************
handle named pipe commands
****************************************************************************/
static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *name,
@@ -3544,7 +341,9 @@ static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *na
DEBUG(3,("named pipe command on <%s> name\n", name));
if (strequal(name,"LANMAN"))
+ {
return api_reply(conn,vuid,outbuf,data,params,tdscnt,tpscnt,mdrcnt,mprcnt);
+ }
if (strequal(name,"WKSSVC") ||
strequal(name,"SRVSVC") ||
@@ -3557,23 +356,26 @@ static int named_pipe(connection_struct *conn,uint16 vuid, char *outbuf,char *na
}
if (strlen(name) < 1)
+ {
return api_fd_reply(conn,vuid,outbuf,setup,data,params,suwcnt,tdscnt,tpscnt,mdrcnt,mprcnt);
+ }
if (setup)
+ {
DEBUG(3,("unknown named pipe: setup 0x%X setup1=%d\n", (int)setup[0],(int)setup[1]));
+ }
return 0;
}
/****************************************************************************
- Reply to a SMBtrans.
- ****************************************************************************/
-
+ reply to a SMBtrans
+ ****************************************************************************/
int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int bufsize)
{
fstring name;
- int name_offset = 0;
+ int name_offset = 0;
char *data=NULL,*params=NULL;
uint16 *setup=NULL;
int outsize = 0;
@@ -3591,7 +393,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
int dsoff = SVAL(inbuf,smb_vwv12);
int suwcnt = CVAL(inbuf,smb_vwv13);
- memset(name, '\0',sizeof(name));
+ bzero(name, sizeof(name));
fstrcpy(name,smb_buf(inbuf));
if (dscnt > tdscnt || pscnt > tpscnt) {
@@ -3617,7 +419,7 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
if (suwcnt) {
int i;
if((setup = (uint16 *)malloc(suwcnt*sizeof(uint16))) == NULL) {
- DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", (int)(suwcnt * sizeof(uint16))));
+ DEBUG(0,("reply_trans: setup malloc fail for %d bytes !\n", suwcnt * sizeof(uint16)));
return(ERROR(ERRDOS,ERRnomem));
}
for (i=0;i<suwcnt;i++)
@@ -3640,24 +442,23 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
ret = receive_next_smb(inbuf,bufsize,SMB_SECONDARY_WAIT);
- if ((ret && (CVAL(inbuf, smb_com) != SMBtranss)) || !ret) {
+ show_msg(inbuf);
+
+ if ((ret && (CVAL(inbuf, smb_com) != SMBtrans &&
+ CVAL(inbuf, smb_com) != SMBtranss)) || !ret)
+ {
if(ret) {
DEBUG(0,("reply_trans: Invalid secondary trans packet\n"));
} else {
DEBUG(0,("reply_trans: %s in getting secondary trans response.\n",
(smb_read_error == READ_ERROR) ? "error" : "timeout" ));
}
- if (params)
- free(params);
- if (data)
- free(data);
- if (setup)
- free(setup);
+ if (params) free(params);
+ if (data) free(data);
+ if (setup) free(setup);
return(ERROR(ERRSRV,ERRerror));
}
- show_msg(inbuf);
-
tpscnt = SVAL(inbuf,smb_vwv0);
tdscnt = SVAL(inbuf,smb_vwv1);
@@ -3686,13 +487,14 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
DEBUG(3,("trans <%s> data=%d params=%d setup=%d\n",
name,tdscnt,tpscnt,suwcnt));
- /*
- * WinCE wierdness....
- */
+ /*
+ * WinCE wierdness....
+ */
- if (name[0] == '\\' && (StrnCaseCmp(&name[1],local_machine, strlen(local_machine)) == 0) &&
- (name[strlen(local_machine)+1] == '\\'))
- name_offset = strlen(local_machine)+1;
+ if (name[0] == '\\' && (StrnCaseCmp(&name[1],local_machine,
+ strlen(local_machine)) == 0)) {
+ name_offset = strlen(local_machine)+1;
+ }
if (strncmp(&name[name_offset],"\\PIPE\\",strlen("\\PIPE\\")) == 0) {
DEBUG(5,("calling named_pipe\n"));
@@ -3705,12 +507,9 @@ int reply_trans(connection_struct *conn, char *inbuf,char *outbuf, int size, int
}
- if (data)
- free(data);
- if (params)
- free(params);
- if (setup)
- free(setup);
+ if (data) free(data);
+ if (params) free(params);
+ if (setup) free(setup);
if (close_on_completion)
close_cnum(conn,vuid);
diff --git a/source/smbd/lanman.c b/source/smbd/lanman.c
new file mode 100644
index 00000000000..9f1d46b2de7
--- /dev/null
+++ b/source/smbd/lanman.c
@@ -0,0 +1,3219 @@
+ /*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Inter-process communication and named pipe handling
+ Copyright (C) Andrew Tridgell 1992-2000
+
+ SMB Version handling
+ Copyright (C) John H Terpstra 1995-2000
+
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+ This file handles the named pipe and mailslot calls
+ in the SMBtrans protocol
+ */
+
+#include "includes.h"
+#include "nterr.h"
+
+#ifdef CHECK_TYPES
+#undef CHECK_TYPES
+#endif
+#define CHECK_TYPES 0
+
+extern int DEBUGLEVEL;
+
+extern fstring local_machine;
+extern fstring global_myworkgroup;
+extern fstring global_sam_name;
+
+#define NERR_Success 0
+#define NERR_badpass 86
+#define NERR_notsupported 50
+
+#define NERR_BASE (2100)
+#define NERR_BufTooSmall (NERR_BASE+23)
+#define NERR_JobNotFound (NERR_BASE+51)
+#define NERR_DestNotFound (NERR_BASE+52)
+#define ERROR_INVALID_LEVEL 124
+
+#define ACCESS_READ 0x01
+#define ACCESS_WRITE 0x02
+#define ACCESS_CREATE 0x04
+
+#define SHPWLEN 8 /* share password length */
+#define NNLEN 12 /* 8.3 net name length */
+#define SNLEN 15 /* service name length */
+#define QNLEN 12 /* queue name maximum length */
+
+extern int Client;
+extern int smb_read_error;
+extern uint32 global_client_caps;
+
+static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len);
+static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len);
+
+
+static int CopyExpanded(connection_struct *conn, const vuser_key *key,
+ int snum, char** dst, char* src, int* n)
+{
+ pstring buf;
+ int l;
+ user_struct *vuser;
+
+ if (!src || !dst || !n || !(*dst)) return(0);
+
+ StrnCpy(buf,src,sizeof(buf)/2);
+ string_sub(buf,"%S",lp_servicename(snum));
+ vuser = get_valid_user_struct(key);
+ standard_sub(conn,vuser, buf);
+ vuid_free_user_struct(vuser);
+ StrnCpy(*dst,buf,*n);
+ l = strlen(*dst) + 1;
+ (*dst) += l;
+ (*n) -= l;
+ return l;
+}
+
+static int CopyAndAdvance(char** dst, char* src, int* n)
+{
+ int l;
+ if (!src || !dst || !n || !(*dst)) return(0);
+ StrnCpy(*dst,src,*n);
+ l = strlen(*dst) + 1;
+ (*dst) += l;
+ (*n) -= l;
+ return l;
+}
+
+static int StrlenExpanded(connection_struct *conn,
+ const vuser_key *key, int snum, char* s)
+{
+ user_struct *vuser;
+ pstring buf;
+ if (!s) return(0);
+ StrnCpy(buf,s,sizeof(buf)/2);
+ string_sub(buf,"%S",lp_servicename(snum));
+ vuser = get_valid_user_struct(key);
+ standard_sub(conn,vuser, buf);
+ vuid_free_user_struct(vuser);
+ return strlen(buf) + 1;
+}
+
+static char* Expand(connection_struct *conn, const vuser_key *key, int snum, char* s)
+{
+ user_struct *vuser;
+ static pstring buf;
+ if (!s) return(NULL);
+ StrnCpy(buf,s,sizeof(buf)/2);
+ string_sub(buf,"%S",lp_servicename(snum));
+ vuser = get_valid_user_struct(key);
+ standard_sub(conn,vuser, buf);
+ return &buf[0];
+}
+
+/*******************************************************************
+ check a API string for validity when we only need to check the prefix
+ ******************************************************************/
+static BOOL prefix_ok(char *str,char *prefix)
+{
+ return(strncmp(str,prefix,strlen(prefix)) == 0);
+}
+
+struct pack_desc {
+ char* format; /* formatstring for structure */
+ char* subformat; /* subformat for structure */
+ char* base; /* baseaddress of buffer */
+ int buflen; /* remaining size for fixed part; on init: length of base */
+ int subcount; /* count of substructures */
+ char* structbuf; /* pointer into buffer for remaining fixed part */
+ int stringlen; /* remaining size for variable part */
+ char* stringbuf; /* pointer into buffer for remaining variable part */
+ int neededlen; /* total needed size */
+ int usedlen; /* total used size (usedlen <= neededlen and usedlen <= buflen) */
+ char* curpos; /* current position; pointer into format or subformat */
+ int errcode;
+};
+
+static int get_counter(char** p)
+{
+ int i, n;
+ if (!p || !(*p)) return(1);
+ if (!isdigit((int)**p)) return 1;
+ for (n = 0;;) {
+ i = **p;
+ if (isdigit(i))
+ n = 10 * n + (i - '0');
+ else
+ return n;
+ (*p)++;
+ }
+}
+
+static int getlen(char* p)
+{
+ int n = 0;
+ if (!p) return(0);
+ while (*p) {
+ switch( *p++ ) {
+ case 'W': /* word (2 byte) */
+ n += 2;
+ break;
+ case 'N': /* count of substructures (word) at end */
+ n += 2;
+ break;
+ case 'D': /* double word (4 byte) */
+ case 'z': /* offset to zero terminated string (4 byte) */
+ case 'l': /* offset to user data (4 byte) */
+ n += 4;
+ break;
+ case 'b': /* offset to data (with counter) (4 byte) */
+ n += 4;
+ get_counter(&p);
+ break;
+ case 'B': /* byte (with optional counter) */
+ n += get_counter(&p);
+ break;
+ }
+ }
+ return n;
+}
+
+static BOOL init_package(struct pack_desc* p, int count, int subcount)
+{
+ int n = p->buflen;
+ int i;
+
+ if (!p->format || !p->base) return(False);
+
+ i = count * getlen(p->format);
+ if (p->subformat) i += subcount * getlen(p->subformat);
+ p->structbuf = p->base;
+ p->neededlen = 0;
+ p->usedlen = 0;
+ p->subcount = 0;
+ p->curpos = p->format;
+ if (i > n) {
+ p->neededlen = i;
+ i = n = 0;
+ p->errcode = ERRmoredata;
+ }
+ else
+ p->errcode = NERR_Success;
+ p->buflen = i;
+ n -= i;
+ p->stringbuf = p->base + i;
+ p->stringlen = n;
+ return(p->errcode == NERR_Success);
+}
+
+#ifdef HAVE_STDARG_H
+static int package(struct pack_desc* p, ...)
+{
+#else
+static int package(va_alist)
+va_dcl
+{
+ struct pack_desc* p;
+#endif
+ va_list args;
+ int needed=0, stringneeded;
+ char* str=NULL;
+ int is_string=0, stringused;
+ int32 temp;
+
+#ifdef HAVE_STDARG_H
+ va_start(args,p);
+#else
+ va_start(args);
+ p = va_arg(args,struct pack_desc *);
+#endif
+
+ if (!*p->curpos) {
+ if (!p->subcount)
+ p->curpos = p->format;
+ else {
+ p->curpos = p->subformat;
+ p->subcount--;
+ }
+ }
+#if CHECK_TYPES
+ str = va_arg(args,char*);
+ SMB_ASSERT(strncmp(str,p->curpos,strlen(str)) == 0);
+#endif
+ stringneeded = -1;
+
+ if (!p->curpos) return(0);
+
+ switch( *p->curpos++ ) {
+ case 'W': /* word (2 byte) */
+ needed = 2;
+ temp = va_arg(args,int);
+ if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
+ break;
+ case 'N': /* count of substructures (word) at end */
+ needed = 2;
+ p->subcount = va_arg(args,int);
+ if (p->buflen >= needed) SSVAL(p->structbuf,0,p->subcount);
+ break;
+ case 'D': /* double word (4 byte) */
+ needed = 4;
+ temp = va_arg(args,int);
+ if (p->buflen >= needed) SIVAL(p->structbuf,0,temp);
+ break;
+ case 'B': /* byte (with optional counter) */
+ needed = get_counter(&p->curpos);
+ {
+ char *s = va_arg(args,char*);
+ if (p->buflen >= needed) StrnCpy(p->structbuf,s?s:"",needed);
+ }
+ break;
+ case 'z': /* offset to zero terminated string (4 byte) */
+ str = va_arg(args,char*);
+ stringneeded = (str ? strlen(str)+1 : 0);
+ is_string = 1;
+ break;
+ case 'l': /* offset to user data (4 byte) */
+ str = va_arg(args,char*);
+ stringneeded = va_arg(args,int);
+ is_string = 0;
+ break;
+ case 'b': /* offset to data (with counter) (4 byte) */
+ str = va_arg(args,char*);
+ stringneeded = get_counter(&p->curpos);
+ is_string = 0;
+ break;
+ }
+ va_end(args);
+ if (stringneeded >= 0) {
+ needed = 4;
+ if (p->buflen >= needed) {
+ stringused = stringneeded;
+ if (stringused > p->stringlen) {
+ stringused = (is_string ? p->stringlen : 0);
+ if (p->errcode == NERR_Success) p->errcode = ERRmoredata;
+ }
+ if (!stringused)
+ SIVAL(p->structbuf,0,0);
+ else {
+ SIVAL(p->structbuf,0,PTR_DIFF(p->stringbuf,p->base));
+ memcpy(p->stringbuf,str?str:"",stringused);
+ if (is_string) p->stringbuf[stringused-1] = '\0';
+ p->stringbuf += stringused;
+ p->stringlen -= stringused;
+ p->usedlen += stringused;
+ }
+ }
+ p->neededlen += stringneeded;
+ }
+ p->neededlen += needed;
+ if (p->buflen >= needed) {
+ p->structbuf += needed;
+ p->buflen -= needed;
+ p->usedlen += needed;
+ }
+ else {
+ if (p->errcode == NERR_Success) p->errcode = ERRmoredata;
+ }
+ return 1;
+}
+
+#if CHECK_TYPES
+#define PACK(desc,t,v) package(desc,t,v,0,0,0,0)
+#define PACKl(desc,t,v,l) package(desc,t,v,l,0,0,0,0)
+#else
+#define PACK(desc,t,v) package(desc,v)
+#define PACKl(desc,t,v,l) package(desc,v,l)
+#endif
+
+static void PACKI(struct pack_desc* desc,char *t,int v)
+{
+ PACK(desc,t,v);
+}
+
+static void PACKS(struct pack_desc* desc,char *t,char *v)
+{
+ PACK(desc,t,v);
+}
+
+
+/****************************************************************************
+ get a print queue
+ ****************************************************************************/
+
+static void PackDriverData(struct pack_desc* desc)
+{
+ char drivdata[4+4+32];
+ SIVAL(drivdata,0,sizeof drivdata); /* cb */
+ SIVAL(drivdata,4,1000); /* lVersion */
+ memset(drivdata+8,0,32); /* szDeviceName */
+ pstrcpy(drivdata+8,"NULL");
+ PACKl(desc,"l",drivdata,sizeof drivdata); /* pDriverData */
+}
+
+static int check_printq_info(struct pack_desc* desc,
+ int uLevel, char *id1, char *id2)
+{
+ desc->subformat = NULL;
+ switch( uLevel ) {
+ case 0:
+ desc->format = "B13";
+ break;
+ case 1:
+ desc->format = "B13BWWWzzzzzWW";
+ break;
+ case 2:
+ desc->format = "B13BWWWzzzzzWN";
+ desc->subformat = "WB21BB16B10zWWzDDz";
+ break;
+ case 3:
+ desc->format = "zWWWWzzzzWWzzl";
+ break;
+ case 4:
+ desc->format = "zWWWWzzzzWNzzl";
+ desc->subformat = "WWzWWDDzz";
+ break;
+ case 5:
+ desc->format = "z";
+ break;
+ case 52:
+ desc->format = "WzzzzzzzzN";
+ desc->subformat = "z";
+ break;
+ default: return False;
+ }
+ if (strcmp(desc->format,id1) != 0) return False;
+ if (desc->subformat && strcmp(desc->subformat,id2) != 0) return False;
+ return True;
+}
+
+static void fill_printjob_info(connection_struct *conn,
+ int snum, int uLevel,
+ struct pack_desc* desc,
+ print_queue_struct* queue, int n)
+{
+ time_t t = queue->time;
+
+ /* the client expects localtime */
+ t -= TimeDiff(t);
+
+ PACKI(desc,"W",printjob_encode(snum, queue->job)); /* uJobId */
+ if (uLevel == 1) {
+ PACKS(desc,"B21",queue->user); /* szUserName */
+ PACKS(desc,"B",""); /* pad */
+ PACKS(desc,"B16",""); /* szNotifyName */
+ PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */
+ PACKS(desc,"z",""); /* pszParms */
+ PACKI(desc,"W",n+1); /* uPosition */
+ PACKI(desc,"W",queue->status); /* fsStatus */
+ PACKS(desc,"z",""); /* pszStatus */
+ PACKI(desc,"D",t); /* ulSubmitted */
+ PACKI(desc,"D",queue->size); /* ulSize */
+ PACKS(desc,"z",queue->file); /* pszComment */
+ }
+ if (uLevel == 2 || uLevel == 3) {
+ PACKI(desc,"W",queue->priority); /* uPriority */
+ PACKS(desc,"z",queue->user); /* pszUserName */
+ PACKI(desc,"W",n+1); /* uPosition */
+ PACKI(desc,"W",queue->status); /* fsStatus */
+ PACKI(desc,"D",t); /* ulSubmitted */
+ PACKI(desc,"D",queue->size); /* ulSize */
+ PACKS(desc,"z","Samba"); /* pszComment */
+ PACKS(desc,"z",queue->file); /* pszDocument */
+ if (uLevel == 3) {
+ PACKS(desc,"z",""); /* pszNotifyName */
+ PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */
+ PACKS(desc,"z",""); /* pszParms */
+ PACKS(desc,"z",""); /* pszStatus */
+ PACKS(desc,"z",SERVICE(snum)); /* pszQueue */
+ PACKS(desc,"z","lpd"); /* pszQProcName */
+ PACKS(desc,"z",""); /* pszQProcParms */
+ PACKS(desc,"z","NULL"); /* pszDriverName */
+ PackDriverData(desc); /* pDriverData */
+ PACKS(desc,"z",""); /* pszPrinterName */
+ }
+ }
+}
+
+static void fill_printq_info(connection_struct *conn, const vuser_key *key,
+ int snum, int uLevel,
+ struct pack_desc* desc,
+ int count, print_queue_struct* queue,
+ print_status_struct* status)
+{
+ switch (uLevel) {
+ case 1:
+ case 2:
+ PACKS(desc,"B13",SERVICE(snum));
+ break;
+ case 3:
+ case 4:
+ case 5:
+ PACKS(desc,"z",Expand(conn,key, snum,SERVICE(snum)));
+ break;
+ }
+
+ if (uLevel == 1 || uLevel == 2) {
+ PACKS(desc,"B",""); /* alignment */
+ PACKI(desc,"W",5); /* priority */
+ PACKI(desc,"W",0); /* start time */
+ PACKI(desc,"W",0); /* until time */
+ PACKS(desc,"z",""); /* pSepFile */
+ PACKS(desc,"z","lpd"); /* pPrProc */
+ PACKS(desc,"z",SERVICE(snum)); /* pDestinations */
+ PACKS(desc,"z",""); /* pParms */
+ if (snum < 0) {
+ PACKS(desc,"z","UNKNOWN PRINTER");
+ PACKI(desc,"W",LPSTAT_ERROR);
+ }
+ else if (!status || !status->message[0]) {
+ PACKS(desc,"z",Expand(conn,key, snum,lp_comment(snum)));
+ PACKI(desc,"W",LPSTAT_OK); /* status */
+ } else {
+ PACKS(desc,"z",status->message);
+ PACKI(desc,"W",status->status); /* status */
+ }
+ PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
+ }
+ if (uLevel == 3 || uLevel == 4) {
+ PACKI(desc,"W",5); /* uPriority */
+ PACKI(desc,"W",0); /* uStarttime */
+ PACKI(desc,"W",0); /* uUntiltime */
+ PACKI(desc,"W",5); /* pad1 */
+ PACKS(desc,"z",""); /* pszSepFile */
+ PACKS(desc,"z","WinPrint"); /* pszPrProc */
+ PACKS(desc,"z",""); /* pszParms */
+ if (!status || !status->message[0]) {
+ PACKS(desc,"z",Expand(conn,key, snum,lp_comment(snum))); /* pszComment */
+ PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
+ } else {
+ PACKS(desc,"z",status->message); /* pszComment */
+ PACKI(desc,"W",status->status); /* fsStatus */
+ }
+ PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */
+ PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
+ PACKS(desc,"z",lp_printerdriver(snum)); /* pszDriverName */
+ PackDriverData(desc); /* pDriverData */
+ }
+ if (uLevel == 2 || uLevel == 4) {
+ int i;
+ for (i=0;i<count;i++)
+ fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
+ }
+
+ if (uLevel==52) {
+ int i,ok=0;
+ pstring tok,driver,datafile,langmon,helpfile,datatype;
+ char *p,*q;
+ FILE *f;
+ pstring fname;
+
+ pstrcpy(fname,lp_driverfile());
+ f=sys_fopen(fname,"r");
+ if (!f) {
+ DEBUG(3,("fill_printq_info: Can't open %s - %s\n",fname,strerror(errno)));
+ desc->errcode=NERR_notsupported;
+ return;
+ }
+
+ if ((p=(char *)malloc(8192*sizeof(char))) == NULL) {
+ DEBUG(0,("fill_printq_info: malloc fail !\n"));
+ desc->errcode=NERR_notsupported;
+ fclose(f);
+ return;
+ }
+
+ bzero(p, 8192*sizeof(char));
+ q=p;
+
+ /* lookup the long printer driver name in the file description */
+ while (f && !feof(f) && !ok)
+ {
+ p = q; /* reset string pointer */
+ fgets(p,8191,f);
+ p[strlen(p)-1]='\0';
+ if (next_token(&p,tok,":",sizeof(tok)) &&
+ (strlen(lp_printerdriver(snum)) == strlen(tok)) &&
+ (!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
+ ok=1;
+ }
+ fclose(f);
+
+ /* driver file name */
+ if (ok && !next_token(&p,driver,":",sizeof(driver))) ok = 0;
+ /* data file name */
+ if (ok && !next_token(&p,datafile,":",sizeof(datafile))) ok = 0;
+ /*
+ * for the next tokens - which may be empty - I have to check for empty
+ * tokens first because the next_token function will skip all empty
+ * token fields
+ */
+ if (ok) {
+ /* help file */
+ if (*p == ':') {
+ *helpfile = '\0';
+ p++;
+ } else if (!next_token(&p,helpfile,":",sizeof(helpfile))) ok = 0;
+ }
+
+ if (ok) {
+ /* language monitor */
+ if (*p == ':') {
+ *langmon = '\0';
+ p++;
+ } else if (!next_token(&p,langmon,":",sizeof(langmon))) ok = 0;
+ }
+
+ /* default data type */
+ if (ok && !next_token(&p,datatype,":",sizeof(datatype))) ok = 0;
+
+ if (ok) {
+ PACKI(desc,"W",0x0400); /* don't know */
+ PACKS(desc,"z",lp_printerdriver(snum)); /* long printer name */
+ PACKS(desc,"z",driver); /* Driverfile Name */
+ PACKS(desc,"z",datafile); /* Datafile name */
+ PACKS(desc,"z",langmon); /* language monitor */
+ PACKS(desc,"z",lp_driverlocation(snum)); /* share to retrieve files */
+ PACKS(desc,"z",datatype); /* default data type */
+ PACKS(desc,"z",helpfile); /* helpfile name */
+ PACKS(desc,"z",driver); /* driver name */
+ DEBUG(3,("Driver:%s:\n",driver));
+ DEBUG(3,("Data File:%s:\n",datafile));
+ DEBUG(3,("Language Monitor:%s:\n",langmon));
+ DEBUG(3,("Data Type:%s:\n",datatype));
+ DEBUG(3,("Help File:%s:\n",helpfile));
+ PACKI(desc,"N",count); /* number of files to copy */
+ for (i=0;i<count;i++)
+ {
+ /* no need to check return value here - it was already tested in
+ * get_printerdrivernumber
+ */
+ next_token(&p,tok,",",sizeof(tok));
+ PACKS(desc,"z",tok); /* driver files to copy */
+ DEBUG(3,("file:%s:\n",tok));
+ }
+
+ DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
+ SERVICE(snum),count));
+ } else {
+ DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
+ desc->errcode=NERR_notsupported;
+ }
+ free(q);
+ }
+}
+
+/* This function returns the number of files for a given driver */
+static int get_printerdrivernumber(int snum)
+{
+ int i=0,ok=0;
+ pstring tok;
+ char *p,*q;
+ FILE *f;
+ pstring fname;
+
+ pstrcpy(fname,lp_driverfile());
+
+ DEBUG(4,("In get_printerdrivernumber: %s\n",fname));
+ f=sys_fopen(fname,"r");
+ if (!f) {
+ DEBUG(3,("get_printerdrivernumber: Can't open %s - %s\n",fname,strerror(errno)));
+ return(0);
+ }
+
+ if ((p=(char *)malloc(8192*sizeof(char))) == NULL) {
+ DEBUG(3,("get_printerdrivernumber: malloc fail !\n"));
+ fclose(f);
+ return 0;
+ }
+
+ q=p; /* need it to free memory because p change ! */
+
+ /* lookup the long printer driver name in the file description */
+ while (!feof(f) && !ok)
+ {
+ p = q; /* reset string pointer */
+ fgets(p,8191,f);
+ if (next_token(&p,tok,":",sizeof(tok)) &&
+ (!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
+ ok=1;
+ }
+ fclose(f);
+
+ if (ok) {
+ /* skip 5 fields */
+ i = 5;
+ while (*p && i) {
+ if (*p++ == ':') i--;
+ }
+ if (!*p || i)
+ return(0);
+
+ /* count the number of files */
+ while (next_token(&p,tok,",",sizeof(tok)))
+ i++;
+ }
+ free(q);
+
+ return(i);
+}
+
+static BOOL api_DosPrintQGetInfo(connection_struct *conn,
+ uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ char *QueueName = p;
+ int uLevel;
+ int count=0;
+ int snum;
+ char* str3;
+ struct pack_desc desc;
+ print_queue_struct *queue=NULL;
+ print_status_struct status;
+
+ VUSER_KEY;
+
+ bzero(&status,sizeof(status));
+ bzero(&desc,sizeof(desc));
+
+ p = skip_string(p,1);
+ uLevel = SVAL(p,0);
+ str3 = p + 4;
+
+ /* remove any trailing username */
+ if ((p = strchr(QueueName,'%'))) *p = 0;
+
+ DEBUG(3,("PrintQueue uLevel=%d name=%s\n",uLevel,QueueName));
+
+ /* check it's a supported varient */
+ if (!prefix_ok(str1,"zWrLh")) return False;
+ if (!check_printq_info(&desc,uLevel,str2,str3)) return False;
+
+ snum = lp_servicenumber(QueueName);
+ if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ if (pnum >= 0) {
+ lp_add_printer(QueueName,pnum);
+ snum = lp_servicenumber(QueueName);
+ }
+ }
+
+ if (snum < 0 || !VALID_SNUM(snum)) return(False);
+
+ if (uLevel==52) {
+ count = get_printerdrivernumber(snum);
+ DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
+ } else {
+ count = get_printqueue(snum, conn,&key,&queue,&status);
+ }
+
+ if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ if (init_package(&desc,1,count)) {
+ desc.subcount = count;
+ fill_printq_info(conn,&key,snum,uLevel,&desc,count,queue,&status);
+ } else if (uLevel == 0) {
+ /*
+ * This is a *disgusting* hack.
+ * This is *so* bad that even I'm embarrassed (and I
+ * have no shame). Here's the deal :
+ * Until we get the correct SPOOLSS code into smbd
+ * then when we're running with NT SMB support then
+ * NT makes this call with a level of zero, and then
+ * immediately follows it with an open request to
+ * the \\SRVSVC pipe. If we allow that open to
+ * succeed then NT barfs when it cannot open the
+ * \\SPOOLSS pipe immediately after and continually
+ * whines saying "Printer name is invalid" forever
+ * after. If we cause *JUST THIS NEXT OPEN* of \\SRVSVC
+ * to fail, then NT downgrades to using the downlevel code
+ * and everything works as well as before. I hate
+ * myself for adding this code.... JRA.
+ */
+
+ fail_next_srvsvc_open();
+ }
+
+ *rdata_len = desc.usedlen;
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,desc.neededlen);
+
+ DEBUG(4,("printqgetinfo: errorcode %d\n",desc.errcode));
+
+ if (queue) free(queue);
+
+ return(True);
+}
+
+
+/****************************************************************************
+ view list of all print jobs on all queues
+ ****************************************************************************/
+static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param, char* data,
+ int mdrcnt, int mprcnt,
+ char **rdata, char** rparam,
+ int *rdata_len, int *rparam_len)
+{
+ char *param_format = param+2;
+ char *output_format1 = skip_string(param_format,1);
+ char *p = skip_string(output_format1,1);
+ int uLevel = SVAL(p,0);
+ char *output_format2 = p + 4;
+ int services = lp_numservices();
+ int i, n;
+ struct pack_desc desc;
+ print_queue_struct **queue = NULL;
+ print_status_struct *status = NULL;
+ int* subcntarr = NULL;
+ int queuecnt, subcnt=0, succnt=0;
+ VUSER_KEY;
+
+ bzero(&desc,sizeof(desc));
+
+ DEBUG(3,("DosPrintQEnum uLevel=%d\n",uLevel));
+
+ if (!prefix_ok(param_format,"WrLeh")) return False;
+ if (!check_printq_info(&desc,uLevel,output_format1,output_format2))
+ return False;
+ queuecnt = 0;
+ for (i = 0; i < services; i++)
+ if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
+ queuecnt++;
+ if (uLevel > 0) {
+ if ((queue = (print_queue_struct**)malloc(queuecnt*sizeof(print_queue_struct*))) == NULL) {
+ DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+ return False;
+ }
+ memset(queue,0,queuecnt*sizeof(print_queue_struct*));
+ if ((status = (print_status_struct*)malloc(queuecnt*sizeof(print_status_struct))) == NULL) {
+ DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+ return False;
+ }
+ memset(status,0,queuecnt*sizeof(print_status_struct));
+ if ((subcntarr = (int*)malloc(queuecnt*sizeof(int))) == NULL) {
+ DEBUG(0,("api_DosPrintQEnum: malloc fail !\n"));
+ return False;
+ }
+ subcnt = 0;
+ n = 0;
+ for (i = 0; i < services; i++)
+ if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
+ subcntarr[n] = get_printqueue(i, conn, &key, &queue[n],&status[n]);
+ subcnt += subcntarr[n];
+ n++;
+ }
+ }
+ if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+
+ if (init_package(&desc,queuecnt,subcnt)) {
+ n = 0;
+ succnt = 0;
+ for (i = 0; i < services; i++)
+ if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
+ fill_printq_info(conn,&key, i,uLevel,&desc,subcntarr[n],queue[n],&status[n]);
+ n++;
+ if (desc.errcode == NERR_Success) succnt = n;
+ }
+ }
+
+ if (subcntarr) free(subcntarr);
+
+ *rdata_len = desc.usedlen;
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,succnt);
+ SSVAL(*rparam,6,queuecnt);
+
+ for (i = 0; i < queuecnt; i++) {
+ if (queue && queue[i]) free(queue[i]);
+ }
+
+ if (queue) free(queue);
+ if (status) free(status);
+
+ return True;
+}
+
+/****************************************************************************
+ get info level for a server list query
+ ****************************************************************************/
+static BOOL check_server_info(int uLevel, char* id)
+{
+ switch( uLevel ) {
+ case 0:
+ if (strcmp(id,"B16") != 0) return False;
+ break;
+ case 1:
+ if (strcmp(id,"B16BBDz") != 0) return False;
+ break;
+ default:
+ return False;
+ }
+ return True;
+}
+
+struct srv_info_struct
+{
+ fstring name;
+ uint32 type;
+ fstring comment;
+ fstring domain;
+ BOOL server_added;
+};
+
+
+/*******************************************************************
+ get server info lists from the files saved by nmbd. Return the
+ number of entries
+ ******************************************************************/
+static int get_server_info(uint32 servertype,
+ struct srv_info_struct **servers,
+ char *domain)
+{
+ FILE *f;
+ pstring fname;
+ int count=0;
+ int alloced=0;
+ pstring line;
+ BOOL local_list_only;
+
+ pstrcpy(fname,lp_lockdir());
+ trim_string(fname,NULL,"/");
+ pstrcat(fname,"/");
+ pstrcat(fname,SERVER_LIST);
+
+ f = sys_fopen(fname,"r");
+
+ if (!f) {
+ DEBUG(4,("Can't open %s - %s\n",fname,strerror(errno)));
+ return(0);
+ }
+
+ /* request for everything is code for request all servers */
+ if (servertype == SV_TYPE_ALL)
+ servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
+
+ local_list_only = (servertype & SV_TYPE_LOCAL_LIST_ONLY);
+
+ DEBUG(4,("Servertype search: %8x\n",servertype));
+
+ while (!feof(f))
+ {
+ fstring stype;
+ struct srv_info_struct *s;
+ char *ptr = line;
+ BOOL ok = True;
+ *ptr = 0;
+
+ fgets(line,sizeof(line)-1,f);
+ if (!*line) continue;
+
+ if (count == alloced) {
+ alloced += 10;
+ (*servers) = (struct srv_info_struct *)
+ Realloc(*servers,sizeof(**servers)*alloced);
+ if (!(*servers)) return(0);
+ bzero((char *)((*servers)+count),sizeof(**servers)*(alloced-count));
+ }
+ s = &(*servers)[count];
+
+ if (!next_token(&ptr,s->name , NULL, sizeof(s->name))) continue;
+ if (!next_token(&ptr,stype , NULL, sizeof(stype))) continue;
+ if (!next_token(&ptr,s->comment, NULL, sizeof(s->comment))) continue;
+ if (!next_token(&ptr,s->domain , NULL, sizeof(s->domain))) {
+ /* this allows us to cope with an old nmbd */
+ pstrcpy(s->domain,global_myworkgroup);
+ }
+
+ if (sscanf(stype,"%X",&s->type) != 1) {
+ DEBUG(4,("r:host file "));
+ ok = False;
+ }
+
+ /* Filter the servers/domains we return based on what was asked for. */
+
+ /* Check to see if we are being asked for a local list only. */
+ if (local_list_only && ((s->type & SV_TYPE_LOCAL_LIST_ONLY) == 0)) {
+ DEBUG(4,("r: local list only"));
+ ok = False;
+ }
+
+ /* doesn't match up: don't want it */
+ if (!(servertype & s->type)) {
+ DEBUG(4,("r:serv type "));
+ ok = False;
+ }
+
+ if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
+ (s->type & SV_TYPE_DOMAIN_ENUM))
+ {
+ DEBUG(4,("s: dom mismatch "));
+ ok = False;
+ }
+
+ if (!strequal(domain, s->domain) && !(servertype & SV_TYPE_DOMAIN_ENUM))
+ {
+ ok = False;
+ }
+
+ /* We should never return a server type with a SV_TYPE_LOCAL_LIST_ONLY set. */
+ s->type &= ~SV_TYPE_LOCAL_LIST_ONLY;
+
+ if (ok)
+ {
+ DEBUG(4,("**SV** %20s %8x %25s %15s\n",
+ s->name, s->type, s->comment, s->domain));
+
+ s->server_added = True;
+ count++;
+ }
+ else
+ {
+ DEBUG(4,("%20s %8x %25s %15s\n",
+ s->name, s->type, s->comment, s->domain));
+ }
+ }
+
+ fclose(f);
+ return(count);
+}
+
+
+/*******************************************************************
+ fill in a server info structure
+ ******************************************************************/
+static int fill_srv_info(struct srv_info_struct *service,
+ int uLevel, char **buf, int *buflen,
+ char **stringbuf, int *stringspace, char *baseaddr)
+{
+ int struct_len;
+ char* p;
+ char* p2;
+ int l2;
+ int len;
+
+ switch (uLevel) {
+ case 0: struct_len = 16; break;
+ case 1: struct_len = 26; break;
+ default: return -1;
+ }
+
+ if (!buf)
+ {
+ len = 0;
+ switch (uLevel)
+ {
+ case 1:
+ len = strlen(service->comment)+1;
+ break;
+ }
+
+ if (buflen) *buflen = struct_len;
+ if (stringspace) *stringspace = len;
+ return struct_len + len;
+ }
+
+ len = struct_len;
+ p = *buf;
+ if (*buflen < struct_len) return -1;
+ if (stringbuf)
+ {
+ p2 = *stringbuf;
+ l2 = *stringspace;
+ }
+ else
+ {
+ p2 = p + struct_len;
+ l2 = *buflen - struct_len;
+ }
+ if (!baseaddr) baseaddr = p;
+
+ switch (uLevel)
+ {
+ case 0:
+ StrnCpy(p,service->name,15);
+ break;
+
+ case 1:
+ StrnCpy(p,service->name,15);
+ SIVAL(p,18,service->type);
+ SIVAL(p,22,PTR_DIFF(p2,baseaddr));
+ len += CopyAndAdvance(&p2,service->comment,&l2);
+ break;
+ }
+
+ if (stringbuf)
+ {
+ *buf = p + struct_len;
+ *buflen -= struct_len;
+ *stringbuf = p2;
+ *stringspace = l2;
+ }
+ else
+ {
+ *buf = p2;
+ *buflen -= len;
+ }
+ return len;
+}
+
+
+static BOOL srv_comp(struct srv_info_struct *s1,struct srv_info_struct *s2)
+{
+ return(strcmp(s1->name,s2->name));
+}
+
+/****************************************************************************
+ view list of servers available (or possibly domains). The info is
+ extracted from lists saved by nmbd on the local host
+ ****************************************************************************/
+static BOOL api_RNetServerEnum(connection_struct *conn, uint16 vuid, char *param, char *data,
+ int mdrcnt, int mprcnt, char **rdata,
+ char **rparam, int *rdata_len, int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel = SVAL(p,0);
+ int buf_len = SVAL(p,2);
+ uint32 servertype = IVAL(p,4);
+ char *p2;
+ int data_len, fixed_len, string_len;
+ int f_len = 0, s_len = 0;
+ struct srv_info_struct *servers=NULL;
+ int counted=0,total=0;
+ int i,missed;
+ fstring domain;
+ BOOL domain_request;
+ BOOL local_request;
+
+ /* If someone sets all the bits they don't really mean to set
+ DOMAIN_ENUM and LOCAL_LIST_ONLY, they just want all the
+ known servers. */
+
+ if (servertype == SV_TYPE_ALL)
+ servertype &= ~(SV_TYPE_DOMAIN_ENUM|SV_TYPE_LOCAL_LIST_ONLY);
+
+ /* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
+ any other bit (they may just set this bit on it's own) they
+ want all the locally seen servers. However this bit can be
+ set on its own so set the requested servers to be
+ ALL - DOMAIN_ENUM. */
+
+ if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM))
+ servertype = SV_TYPE_ALL & ~(SV_TYPE_DOMAIN_ENUM);
+
+ domain_request = ((servertype & SV_TYPE_DOMAIN_ENUM) != 0);
+ local_request = ((servertype & SV_TYPE_LOCAL_LIST_ONLY) != 0);
+
+ p += 8;
+
+ if (!prefix_ok(str1,"WrLehD")) return False;
+ if (!check_server_info(uLevel,str2)) return False;
+
+ DEBUG(4, ("server request level: %s %8x ", str2, servertype));
+ DEBUG(4, ("domains_req:%s ", BOOLSTR(domain_request)));
+ DEBUG(4, ("local_only:%s\n", BOOLSTR(local_request)));
+
+ if (strcmp(str1, "WrLehDz") == 0) {
+ StrnCpy(domain, p, sizeof(fstring)-1);
+ } else {
+ StrnCpy(domain, global_myworkgroup, sizeof(fstring)-1);
+ }
+
+ if (lp_browse_list())
+ total = get_server_info(servertype,&servers,domain);
+
+ data_len = fixed_len = string_len = 0;
+ missed = 0;
+
+ qsort(servers,total,sizeof(servers[0]),QSORT_CAST srv_comp);
+
+ {
+ char *lastname=NULL;
+
+ for (i=0;i<total;i++)
+ {
+ struct srv_info_struct *s = &servers[i];
+ if (lastname && strequal(lastname,s->name)) continue;
+ lastname = s->name;
+ data_len += fill_srv_info(s,uLevel,0,&f_len,0,&s_len,0);
+ DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
+ s->name, s->type, s->comment, s->domain));
+
+ if (data_len <= buf_len) {
+ counted++;
+ fixed_len += f_len;
+ string_len += s_len;
+ } else {
+ missed++;
+ }
+ }
+ }
+
+ *rdata_len = fixed_len + string_len;
+ *rdata = REALLOC(*rdata,*rdata_len);
+ bzero(*rdata,*rdata_len);
+
+ p2 = (*rdata) + fixed_len; /* auxilliary data (strings) will go here */
+ p = *rdata;
+ f_len = fixed_len;
+ s_len = string_len;
+
+ {
+ char *lastname=NULL;
+ int count2 = counted;
+ for (i = 0; i < total && count2;i++)
+ {
+ struct srv_info_struct *s = &servers[i];
+ if (lastname && strequal(lastname,s->name)) continue;
+ lastname = s->name;
+ fill_srv_info(s,uLevel,&p,&f_len,&p2,&s_len,*rdata);
+ DEBUG(4,("fill_srv_info %20s %8x %25s %15s\n",
+ s->name, s->type, s->comment, s->domain));
+ count2--;
+ }
+ }
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERRmoredata));
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,counted);
+ SSVAL(*rparam,6,counted+missed);
+
+ if (servers) free(servers);
+
+ DEBUG(3,("NetServerEnum domain = %s uLevel=%d counted=%d total=%d\n",
+ domain,uLevel,counted,counted+missed));
+
+ return(True);
+}
+
+/****************************************************************************
+ command 0x34 - suspected of being a "Lookup Names" stub api
+ ****************************************************************************/
+static BOOL api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid, char *param, char *data,
+ int mdrcnt, int mprcnt, char **rdata,
+ char **rparam, int *rdata_len, int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel = SVAL(p,0);
+ int buf_len = SVAL(p,2);
+ int counted=0;
+ int missed=0;
+
+ DEBUG(5,("RNetGroupGetUsers: %s %s %s %d %d\n",
+ str1, str2, p, uLevel, buf_len));
+
+ if (!prefix_ok(str1,"zWrLeh")) return False;
+
+ *rdata_len = 0;
+ *rdata = NULL;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ SSVAL(*rparam,0,0x08AC); /* informational warning message */
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,counted);
+ SSVAL(*rparam,6,counted+missed);
+
+ return(True);
+}
+
+/****************************************************************************
+ get info about a share
+ ****************************************************************************/
+static BOOL check_share_info(int uLevel, char* id)
+{
+ switch( uLevel ) {
+ case 0:
+ if (strcmp(id,"B13") != 0) return False;
+ break;
+ case 1:
+ if (strcmp(id,"B13BWz") != 0) return False;
+ break;
+ case 2:
+ if (strcmp(id,"B13BWzWWWzB9B") != 0) return False;
+ break;
+ case 91:
+ if (strcmp(id,"B13BWzWWWzB9BB9BWzWWzWW") != 0) return False;
+ break;
+ default: return False;
+ }
+ return True;
+}
+
+static int fill_share_info(connection_struct *conn, const vuser_key *key,
+ int snum, int uLevel,
+ char** buf, int* buflen,
+ char** stringbuf, int* stringspace, char* baseaddr)
+{
+ int struct_len;
+ char* p;
+ char* p2;
+ int l2;
+ int len;
+
+ switch( uLevel ) {
+ case 0: struct_len = 13; break;
+ case 1: struct_len = 20; break;
+ case 2: struct_len = 40; break;
+ case 91: struct_len = 68; break;
+ default: return -1;
+ }
+
+
+ if (!buf)
+ {
+ len = 0;
+ if (uLevel > 0) len += StrlenExpanded(conn,key,snum,lp_comment(snum));
+ if (uLevel > 1) len += strlen(lp_pathname(snum)) + 1;
+ if (buflen) *buflen = struct_len;
+ if (stringspace) *stringspace = len;
+ return struct_len + len;
+ }
+
+ len = struct_len;
+ p = *buf;
+ if ((*buflen) < struct_len) return -1;
+ if (stringbuf)
+ {
+ p2 = *stringbuf;
+ l2 = *stringspace;
+ }
+ else
+ {
+ p2 = p + struct_len;
+ l2 = (*buflen) - struct_len;
+ }
+ if (!baseaddr) baseaddr = p;
+
+ StrnCpy(p,lp_servicename(snum),13);
+
+ if (uLevel > 0)
+ {
+ int type;
+ CVAL(p,13) = 0;
+ type = STYPE_DISKTREE;
+ if (lp_print_ok(snum)) type = STYPE_PRINTQ;
+ if (strequal("IPC$",lp_servicename(snum))) type = STYPE_IPC;
+ SSVAL(p,14,type); /* device type */
+ SIVAL(p,16,PTR_DIFF(p2,baseaddr));
+ len += CopyExpanded(conn,key, snum,&p2,lp_comment(snum),&l2);
+ }
+
+ if (uLevel > 1)
+ {
+ SSVAL(p,20,ACCESS_READ|ACCESS_WRITE|ACCESS_CREATE); /* permissions */
+ SSVALS(p,22,-1); /* max uses */
+ SSVAL(p,24,1); /* current uses */
+ SIVAL(p,26,PTR_DIFF(p2,baseaddr)); /* local pathname */
+ len += CopyAndAdvance(&p2,lp_pathname(snum),&l2);
+ memset(p+30,0,SHPWLEN+2); /* passwd (reserved), pad field */
+ }
+
+ if (uLevel > 2)
+ {
+ memset(p+40,0,SHPWLEN+2);
+ SSVAL(p,50,0);
+ SIVAL(p,52,0);
+ SSVAL(p,56,0);
+ SSVAL(p,58,0);
+ SIVAL(p,60,0);
+ SSVAL(p,64,0);
+ SSVAL(p,66,0);
+ }
+
+ if (stringbuf)
+ {
+ (*buf) = p + struct_len;
+ (*buflen) -= struct_len;
+ (*stringbuf) = p2;
+ (*stringspace) = l2;
+ }
+ else
+ {
+ (*buf) = p2;
+ (*buflen) -= len;
+ }
+ return len;
+}
+
+static BOOL api_RNetShareGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *netname = skip_string(str2,1);
+ char *p = skip_string(netname,1);
+ int uLevel = SVAL(p,0);
+ int snum = find_service(netname);
+ VUSER_KEY;
+
+ if (snum < 0) return False;
+
+ /* check it's a supported varient */
+ if (!prefix_ok(str1,"zWrLh")) return False;
+ if (!check_share_info(uLevel,str2)) return False;
+
+ *rdata = REALLOC(*rdata,mdrcnt);
+ p = *rdata;
+ *rdata_len = fill_share_info(conn,&key,snum,uLevel,&p,&mdrcnt,0,0,0);
+ if (*rdata_len < 0) return False;
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,2,0); /* converter word */
+ SSVAL(*rparam,4,*rdata_len);
+
+ return(True);
+}
+
+/****************************************************************************
+ view list of shares available
+ ****************************************************************************/
+static BOOL api_RNetShareEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel = SVAL(p,0);
+ int buf_len = SVAL(p,2);
+ char *p2;
+ int count=lp_numservices();
+ int total=0,counted=0;
+ BOOL missed = False;
+ int i;
+ int data_len, fixed_len, string_len;
+ int f_len = 0, s_len = 0;
+ VUSER_KEY;
+
+ if (!prefix_ok(str1,"WrLeh")) return False;
+ if (!check_share_info(uLevel,str2)) return False;
+
+ data_len = fixed_len = string_len = 0;
+ for (i=0;i<count;i++)
+ if (lp_browseable(i) && lp_snum_ok(i))
+ {
+ total++;
+ data_len += fill_share_info(conn,&key,i,uLevel,0,&f_len,0,&s_len,0);
+ if (data_len <= buf_len)
+ {
+ counted++;
+ fixed_len += f_len;
+ string_len += s_len;
+ }
+ else
+ missed = True;
+ }
+ *rdata_len = fixed_len + string_len;
+ *rdata = REALLOC(*rdata,*rdata_len);
+ memset(*rdata,0,*rdata_len);
+
+ p2 = (*rdata) + fixed_len; /* auxillery data (strings) will go here */
+ p = *rdata;
+ f_len = fixed_len;
+ s_len = string_len;
+ for (i = 0; i < count;i++)
+ if (lp_browseable(i) && lp_snum_ok(i))
+ if (fill_share_info(conn,&key,i,uLevel,&p,&f_len,&p2,&s_len,*rdata) < 0)
+ break;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVAL(*rparam,0,missed ? ERRmoredata : NERR_Success);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,counted);
+ SSVAL(*rparam,6,total);
+
+ DEBUG(3,("RNetShareEnum gave %d entries of %d (%d %d %d %d)\n",
+ counted,total,uLevel,
+ buf_len,*rdata_len,mdrcnt));
+ return(True);
+}
+
+
+
+/****************************************************************************
+ get the time of day info
+ ****************************************************************************/
+static BOOL api_NetRemoteTOD(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *p;
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ *rdata_len = 21;
+ *rdata = REALLOC(*rdata,*rdata_len);
+
+ SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ p = *rdata;
+
+ {
+ struct tm *t;
+ time_t unixdate = time(NULL);
+
+ put_dos_date3(p,0,unixdate); /* this is the time that is looked at
+ by NT in a "net time" operation,
+ it seems to ignore the one below */
+
+ /* the client expects to get localtime, not GMT, in this bit
+ (I think, this needs testing) */
+ t = LocalTime(&unixdate);
+
+ SIVAL(p,4,0); /* msecs ? */
+ CVAL(p,8) = t->tm_hour;
+ CVAL(p,9) = t->tm_min;
+ CVAL(p,10) = t->tm_sec;
+ CVAL(p,11) = 0; /* hundredths of seconds */
+ SSVALS(p,12,TimeDiff(unixdate)/60); /* timezone in minutes from GMT */
+ SSVAL(p,14,10000); /* timer interval in 0.0001 of sec */
+ CVAL(p,16) = t->tm_mday;
+ CVAL(p,17) = t->tm_mon + 1;
+ SSVAL(p,18,1900+t->tm_year);
+ CVAL(p,20) = t->tm_wday;
+ }
+
+
+ return(True);
+}
+
+/****************************************************************************
+ set the user password
+ ****************************************************************************/
+static BOOL api_SetUserPassword(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *p = skip_string(param+2,2);
+ fstring user;
+ fstring pass1,pass2;
+ uchar pwbuf[516];
+ uchar nt_pw[16];
+ uchar lm_pw[16];
+
+ fstrcpy(user,p);
+
+ p = skip_string(p,1);
+
+ memcpy(pass1,p,16);
+ memcpy(pass2,p+16,16);
+
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ *rdata_len = 0;
+
+ SSVAL(*rparam,0,NERR_badpass);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ DEBUG(3,("Set password for <%s>\n",user));
+
+ /*
+ * Pass the user through the NT -> unix user mapping
+ * function.
+ */
+
+ (void)map_username(user);
+
+ /*
+ * Do any UNIX username case mangling.
+ */
+ (void)Get_Pwnam( user, True);
+
+ if (strequal(param + 2, "zb16b16WW"))
+ {
+ /*
+ * attempt the encrypted pw change. NT will generate this
+ * after trying the samr method.
+ */
+
+ if (SVAL(*rparam,0) != NERR_Success)
+ {
+ if (make_oem_passwd_hash(pwbuf, pass1, 16, NULL, False) &&
+ msrpc_sam_ntpasswd_set("\\\\.", user, NULL,
+ pwbuf, pass2, /* lm pw */
+ NULL, NULL)) /* nt pw */
+ {
+ SSVAL(*rparam,0,NERR_Success);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Attempt the plaintext password change first.
+ * Older versions of Windows seem to do this.
+ */
+
+ nt_lm_owf_gen(pass1, nt_pw, lm_pw);
+ if (msrpc_sam_ntchange_pwd("\\\\.", user, global_sam_name,
+ lm_pw, nt_pw, pass2))
+ {
+ SSVAL(*rparam,0,NERR_Success);
+ }
+ }
+ ZERO_STRUCT(pwbuf);
+ ZERO_STRUCT(pass1);
+ ZERO_STRUCT(pass2);
+
+ return(True);
+}
+
+/****************************************************************************
+ Set the user password (SamOEM version - gets plaintext).
+****************************************************************************/
+
+static BOOL api_SamOEMChangePassword(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ fstring user;
+ char *p = param + 2;
+ *rparam_len = 2;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ *rdata_len = 0;
+
+ SSVAL(*rparam,0,NERR_badpass);
+
+ /*
+ * Check the parameter definition is correct.
+ */
+ if (!strequal(param + 2, "zsT")) {
+ DEBUG(0,("api_SamOEMChangePassword: Invalid parameter string %s\n", param + 2));
+ return False;
+ }
+ p = skip_string(p, 1);
+
+ if (!strequal(p, "B516B16")) {
+ DEBUG(0,("api_SamOEMChangePassword: Invalid data parameter string %s\n", p));
+ return False;
+ }
+ p = skip_string(p,1);
+
+ fstrcpy(user,p);
+ p = skip_string(p,1);
+
+ DEBUG(3,("api_SamOEMChangePassword: Change password for <%s>\n",user));
+
+ if (msrpc_sam_ntpasswd_set("\\\\.", user, NULL,
+ (uchar*) data, (uchar *)&data[516], /* lm pw */
+ NULL, NULL)) /* nt pw */
+ {
+ SSVAL(*rparam,0,NERR_Success);
+ }
+
+ return(True);
+}
+
+/****************************************************************************
+ delete a print job
+ Form: <W> <>
+ ****************************************************************************/
+static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ int function = SVAL(param,0);
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int jobid, snum;
+ int i, count;
+ VUSER_KEY;
+
+ printjob_decode(SVAL(p,0), &snum, &jobid);
+
+ /* check it's a supported varient */
+ if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
+ return(False);
+
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ *rdata_len = 0;
+
+ SSVAL(*rparam,0,NERR_Success);
+
+ if (snum >= 0 && VALID_SNUM(snum))
+ {
+ print_queue_struct *queue=NULL;
+ lpq_reset(snum);
+ count = get_printqueue(snum,conn,&key,&queue,NULL);
+
+ for (i=0;i<count;i++)
+ if ((queue[i].job&0xFF) == jobid)
+ {
+ switch (function) {
+ case 81: /* delete */
+ DEBUG(3,("Deleting queue entry %d\n",queue[i].job));
+ del_printqueue(conn,&key,snum,queue[i].job);
+ break;
+ case 82: /* pause */
+ case 83: /* resume */
+ DEBUG(3,("%s queue entry %d\n",
+ (function==82?"pausing":"resuming"),queue[i].job));
+ status_printjob(conn,&key,snum,queue[i].job,
+ (function==82?LPQ_PAUSED:LPQ_QUEUED));
+ break;
+ }
+ break;
+ }
+
+ if (i==count)
+ SSVAL(*rparam,0,NERR_JobNotFound);
+
+ if (queue) free(queue);
+ }
+
+ SSVAL(*rparam,2,0); /* converter word */
+
+ return(True);
+}
+
+/****************************************************************************
+ Purge a print queue - or pause or resume it.
+ ****************************************************************************/
+static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ int function = SVAL(param,0);
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *QueueName = skip_string(str2,1);
+ int snum;
+ VUSER_KEY;
+
+ /* check it's a supported varient */
+ if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
+ return(False);
+
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ *rdata_len = 0;
+
+ SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ snum = lp_servicenumber(QueueName);
+ if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ if (pnum >= 0) {
+ lp_add_printer(QueueName,pnum);
+ snum = lp_servicenumber(QueueName);
+ }
+ }
+
+ if (snum >= 0 && VALID_SNUM(snum)) {
+ lpq_reset(snum);
+
+ switch (function) {
+ case 74: /* Pause queue */
+ case 75: /* Resume queue */
+ {
+ status_printqueue(conn,&key,snum,(function==74?LPSTAT_STOPPED:LPSTAT_OK));
+ DEBUG(3,("Print queue %s, queue=%s\n",
+ (function==74?"pause":"resume"),QueueName));
+ break;
+ }
+ case 103: /* Purge */
+ {
+ print_queue_struct *queue=NULL;
+ int i, count;
+ count = get_printqueue(snum,conn,&key,&queue,NULL);
+ for (i = 0; i < count; i++)
+ del_printqueue(conn,&key,snum,queue[i].job);
+
+ if (queue) free(queue);
+ DEBUG(3,("Print queue purge, queue=%s\n",QueueName));
+ break;
+ }
+ }
+ }
+
+ return(True);
+}
+
+
+/****************************************************************************
+ set the property of a print job (undocumented?)
+ ? function = 0xb -> set name of print job
+ ? function = 0x6 -> move print job up/down
+ Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz>
+ or <WWsTP> <WB21BB16B10zWWzDDz>
+****************************************************************************/
+static int check_printjob_info(struct pack_desc* desc,
+ int uLevel, char* id)
+{
+ desc->subformat = NULL;
+ switch( uLevel ) {
+ case 0: desc->format = "W"; break;
+ case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
+ case 2: desc->format = "WWzWWDDzz"; break;
+ case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
+ default: return False;
+ }
+ if (strcmp(desc->format,id) != 0) return False;
+ return True;
+}
+
+static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ struct pack_desc desc;
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int jobid, snum;
+ int uLevel = SVAL(p,2);
+ int function = SVAL(p,4); /* what is this ?? */
+ int i;
+ char *s = data;
+ files_struct *fsp;
+ VUSER_KEY;
+
+ printjob_decode(SVAL(p,0), &snum, &jobid);
+
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ *rdata_len = 0;
+
+ /* check it's a supported varient */
+ if ((strcmp(str1,"WWsTP")) ||
+ (!check_printjob_info(&desc,uLevel,str2)))
+ return(False);
+
+ switch (function) {
+ case 0x6: /* change job place in the queue,
+ data gives the new place */
+ if (snum >= 0 && VALID_SNUM(snum)) {
+ print_queue_struct *queue=NULL;
+ int count;
+
+ lpq_reset(snum);
+ count = get_printqueue(snum,conn,&key,&queue,NULL);
+ for (i=0;i<count;i++) /* find job */
+ if ((queue[i].job&0xFF) == jobid) break;
+
+ if (i==count) {
+ desc.errcode=NERR_JobNotFound;
+ if (queue) free(queue);
+ } else {
+ desc.errcode=NERR_Success;
+ i++;
+#if 0
+ {
+ int place= SVAL(data,0);
+ /* we currently have no way of
+ doing this. Can any unix do it? */
+ if (i < place) /* move down */;
+ else if (i > place ) /* move up */;
+ }
+#endif
+ desc.errcode=NERR_notsupported; /* not yet
+ supported */
+ if (queue) free(queue);
+ }
+ } else {
+ desc.errcode=NERR_JobNotFound;
+ }
+ break;
+
+ case 0xb: /* change print job name, data gives the name */
+ /* jobid, snum should be zero */
+ if (isalpha((int)*s)) {
+ pstring name;
+ int l = 0;
+ while (l<64 && *s) {
+ if (issafe(*s)) name[l++] = *s;
+ s++;
+ }
+ name[l] = 0;
+
+ DEBUG(3,("Setting print name to %s\n",name));
+
+ fsp = file_find_print();
+
+ if (fsp) {
+ connection_struct *fconn = fsp->conn;
+ unbecome_user();
+
+ if (!become_user(fconn,vuid) ||
+ !become_service(fconn,True))
+ break;
+
+ if (conn->vfs_ops.rename(dos_to_unix(fsp->fsp_name,False),name) == 0) {
+ string_set(&fsp->fsp_name,name);
+ }
+ break;
+ }
+ }
+ desc.errcode=NERR_Success;
+ break;
+
+ default: /* not implemented */
+ return False;
+ }
+
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ return(True);
+}
+
+
+/****************************************************************************
+ get info about the server
+ ****************************************************************************/
+static BOOL api_RNetServerGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel = SVAL(p,0);
+ char *p2;
+ int struct_len;
+ VUSER_KEY;
+
+ DEBUG(4,("NetServerGetInfo level %d\n",uLevel));
+
+ /* check it's a supported varient */
+ if (!prefix_ok(str1,"WrLh")) return False;
+ switch( uLevel ) {
+ case 0:
+ if (strcmp(str2,"B16") != 0) return False;
+ struct_len = 16;
+ break;
+ case 1:
+ if (strcmp(str2,"B16BBDz") != 0) return False;
+ struct_len = 26;
+ break;
+ case 2:
+ if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWz")
+ != 0) return False;
+ struct_len = 134;
+ break;
+ case 3:
+ if (strcmp(str2,"B16BBDzDDDWWzWWWWWWWBB21zWWWWWWWWWWWWWWWWWWWWWWzDWz")
+ != 0) return False;
+ struct_len = 144;
+ break;
+ case 20:
+ if (strcmp(str2,"DN") != 0) return False;
+ struct_len = 6;
+ break;
+ case 50:
+ if (strcmp(str2,"B16BBDzWWzzz") != 0) return False;
+ struct_len = 42;
+ break;
+ default: return False;
+ }
+
+ *rdata_len = mdrcnt;
+ *rdata = REALLOC(*rdata,*rdata_len);
+
+ p = *rdata;
+ p2 = p + struct_len;
+ if (uLevel != 20) {
+ StrnCpy(p,local_machine,16);
+ strupper(p);
+ }
+ p += 16;
+ if (uLevel > 0)
+ {
+ struct srv_info_struct *servers=NULL;
+ int i,count;
+ pstring comment;
+ uint32 servertype= lp_default_server_announce();
+
+ pstrcpy(comment,lp_serverstring());
+
+ if ((count=get_server_info(SV_TYPE_ALL,&servers,global_myworkgroup))>0) {
+ for (i=0;i<count;i++)
+ if (strequal(servers[i].name,local_machine))
+ {
+ servertype = servers[i].type;
+ pstrcpy(comment,servers[i].comment);
+ }
+ }
+ if (servers) free(servers);
+
+ SCVAL(p,0,lp_major_announce_version());
+ SCVAL(p,1,lp_minor_announce_version());
+ SIVAL(p,2,servertype);
+
+ if (mdrcnt == struct_len) {
+ SIVAL(p,6,0);
+ } else {
+ user_struct *vuser = get_valid_user_struct(&key);
+ SIVAL(p,6,PTR_DIFF(p2,*rdata));
+ standard_sub(conn,vuser, comment);
+ StrnCpy(p2,comment,MAX(mdrcnt - struct_len,0));
+ p2 = skip_string(p2,1);
+ vuid_free_user_struct(vuser);
+
+ }
+ }
+ if (uLevel > 1)
+ {
+ return False; /* not yet implemented */
+ }
+
+ *rdata_len = PTR_DIFF(p2,*rdata);
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,2,0); /* converter word */
+ SSVAL(*rparam,4,*rdata_len);
+
+ return(True);
+}
+
+
+/****************************************************************************
+ get info about the server
+ ****************************************************************************/
+static BOOL api_NetWkstaGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ char *p2;
+ extern pstring sesssetup_user;
+ int level = SVAL(p,0);
+
+ DEBUG(4,("NetWkstaGetInfo level %d\n",level));
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ /* check it's a supported varient */
+ if (!(level==10 && strcsequal(str1,"WrLh") && strcsequal(str2,"zzzBBzz")))
+ return(False);
+
+ *rdata_len = mdrcnt + 1024;
+ *rdata = REALLOC(*rdata,*rdata_len);
+
+ SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ p = *rdata;
+ p2 = p + 22;
+
+
+ SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* host name */
+ pstrcpy(p2,local_machine);
+ strupper(p2);
+ p2 = skip_string(p2,1);
+ p += 4;
+
+ SIVAL(p,0,PTR_DIFF(p2,*rdata));
+ pstrcpy(p2,sesssetup_user);
+ p2 = skip_string(p2,1);
+ p += 4;
+
+ SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* login domain */
+ pstrcpy(p2,global_myworkgroup);
+ strupper(p2);
+ p2 = skip_string(p2,1);
+ p += 4;
+
+ SCVAL(p,0,lp_major_announce_version()); /* system version - e.g 4 in 4.1 */
+ SCVAL(p,1,lp_minor_announce_version()); /* system version - e.g .1 in 4.1 */
+ p += 2;
+
+ SIVAL(p,0,PTR_DIFF(p2,*rdata));
+ pstrcpy(p2,global_myworkgroup); /* don't know. login domain?? */
+ p2 = skip_string(p2,1);
+ p += 4;
+
+ SIVAL(p,0,PTR_DIFF(p2,*rdata)); /* don't know */
+ pstrcpy(p2,"");
+ p2 = skip_string(p2,1);
+ p += 4;
+
+ *rdata_len = PTR_DIFF(p2,*rdata);
+
+ SSVAL(*rparam,4,*rdata_len);
+
+ return(True);
+}
+
+/****************************************************************************
+ get info about a user
+
+ struct user_info_11 {
+ char usri11_name[21]; 0-20
+ char usri11_pad; 21
+ char *usri11_comment; 22-25
+ char *usri11_usr_comment; 26-29
+ unsigned short usri11_priv; 30-31
+ unsigned long usri11_auth_flags; 32-35
+ long usri11_password_age; 36-39
+ char *usri11_homedir; 40-43
+ char *usri11_parms; 44-47
+ long usri11_last_logon; 48-51
+ long usri11_last_logoff; 52-55
+ unsigned short usri11_bad_pw_count; 56-57
+ unsigned short usri11_num_logons; 58-59
+ char *usri11_logon_server; 60-63
+ unsigned short usri11_country_code; 64-65
+ char *usri11_workstations; 66-69
+ unsigned long usri11_max_storage; 70-73
+ unsigned short usri11_units_per_week; 74-75
+ unsigned char *usri11_logon_hours; 76-79
+ unsigned short usri11_code_page; 80-81
+ };
+
+where:
+
+ usri11_name specifies the user name for which information is retireved
+
+ usri11_pad aligns the next data structure element to a word boundary
+
+ usri11_comment is a null terminated ASCII comment
+
+ usri11_user_comment is a null terminated ASCII comment about the user
+
+ usri11_priv specifies the level of the privilege assigned to the user.
+ The possible values are:
+
+Name Value Description
+USER_PRIV_GUEST 0 Guest privilege
+USER_PRIV_USER 1 User privilege
+USER_PRV_ADMIN 2 Administrator privilege
+
+ usri11_auth_flags specifies the account operator privileges. The
+ possible values are:
+
+Name Value Description
+AF_OP_PRINT 0 Print operator
+
+
+Leach, Naik [Page 28]
+
+
+INTERNET-DRAFT CIFS Remote Admin Protocol January 10, 1997
+
+
+AF_OP_COMM 1 Communications operator
+AF_OP_SERVER 2 Server operator
+AF_OP_ACCOUNTS 3 Accounts operator
+
+
+ usri11_password_age specifies how many seconds have elapsed since the
+ password was last changed.
+
+ usri11_home_dir points to a null terminated ASCII string that contains
+ the path name of the user's home directory.
+
+ usri11_parms points to a null terminated ASCII string that is set
+ aside for use by applications.
+
+ usri11_last_logon specifies the time when the user last logged on.
+ This value is stored as the number of seconds elapsed since
+ 00:00:00, January 1, 1970.
+
+ usri11_last_logoff specifies the time when the user last logged off.
+ This value is stored as the number of seconds elapsed since
+ 00:00:00, January 1, 1970. A value of 0 means the last logoff
+ time is unknown.
+
+ usri11_bad_pw_count specifies the number of incorrect passwords
+ entered since the last successful logon.
+
+ usri11_log1_num_logons specifies the number of times this user has
+ logged on. A value of -1 means the number of logons is unknown.
+
+ usri11_logon_server points to a null terminated ASCII string that
+ contains the name of the server to which logon requests are sent.
+ A null string indicates logon requests should be sent to the
+ domain controller.
+
+ usri11_country_code specifies the country code for the user's language
+ of choice.
+
+ usri11_workstations points to a null terminated ASCII string that
+ contains the names of workstations the user may log on from.
+ There may be up to 8 workstations, with the names separated by
+ commas. A null strings indicates there are no restrictions.
+
+ usri11_max_storage specifies the maximum amount of disk space the user
+ can occupy. A value of 0xffffffff indicates there are no
+ restrictions.
+
+ usri11_units_per_week specifies the equal number of time units into
+ which a week is divided. This value must be equal to 168.
+
+ usri11_logon_hours points to a 21 byte (168 bits) string that
+ specifies the time during which the user can log on. Each bit
+ represents one unique hour in a week. The first bit (bit 0, word
+ 0) is Sunday, 0:00 to 0:59, the second bit (bit 1, word 0) is
+
+
+
+Leach, Naik [Page 29]
+
+
+INTERNET-DRAFT CIFS Remote Admin Protocol January 10, 1997
+
+
+ Sunday, 1:00 to 1:59 and so on. A null pointer indicates there
+ are no restrictions.
+
+ usri11_code_page specifies the code page for the user's language of
+ choice
+
+All of the pointers in this data structure need to be treated
+specially. The pointer is a 32 bit pointer. The higher 16 bits need
+to be ignored. The converter word returned in the parameters section
+needs to be subtracted from the lower 16 bits to calculate an offset
+into the return buffer where this ASCII string resides.
+
+There is no auxiliary data in the response.
+
+ ****************************************************************************/
+
+#define usri11_name 0
+#define usri11_pad 21
+#define usri11_comment 22
+#define usri11_usr_comment 26
+#define usri11_full_name 30
+#define usri11_priv 34
+#define usri11_auth_flags 36
+#define usri11_password_age 40
+#define usri11_homedir 44
+#define usri11_parms 48
+#define usri11_last_logon 52
+#define usri11_last_logoff 56
+#define usri11_bad_pw_count 60
+#define usri11_num_logons 62
+#define usri11_logon_server 64
+#define usri11_country_code 68
+#define usri11_workstations 70
+#define usri11_max_storage 74
+#define usri11_units_per_week 78
+#define usri11_logon_hours 80
+#define usri11_code_page 84
+#define usri11_end 86
+
+#define USER_PRIV_GUEST 0
+#define USER_PRIV_USER 1
+#define USER_PRIV_ADMIN 2
+
+#define AF_OP_PRINT 0
+#define AF_OP_COMM 1
+#define AF_OP_SERVER 2
+#define AF_OP_ACCOUNTS 3
+
+
+static BOOL api_RNetUserGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *UserName = skip_string(str2,1);
+ char *p = skip_string(UserName,1);
+ int uLevel = SVAL(p,0);
+ char *p2;
+
+ fstring nt_name;
+ fstring logon_path;
+ fstring full_name;
+ fstring home_dir;
+ fstring logon_srv;
+
+ /* get NIS home of a previously validated user - simeon */
+ /* With share level security vuid will always be zero.
+ Don't depend on vuser being non-null !!. JRA */
+ user_struct *vuser = NULL;
+ /* moved here due to initialization code (req for IRIX cc) */
+ VUSER_KEY;
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ DEBUG(4,("RNetUserGetInfo level=%d\n", uLevel));
+
+ /* check it's a supported variant */
+ if (strcmp(str1,"zWrLh") != 0) return False;
+ switch( uLevel )
+ {
+ case 0: p2 = "B21"; break;
+ case 1: p2 = "B21BB16DWzzWz"; break;
+ case 2: p2 = "B21BB16DWzzWzDzzzzDDDDWb21WWzWW"; break;
+ case 10: p2 = "B21Bzzz"; break;
+ case 11: p2 = "B21BzzzWDDzzDDWWzWzDWb21W"; break;
+ default:
+ {
+ vuid_free_user_struct(vuser);
+ return False;
+ }
+ }
+
+ if (strcmp(p2,str2) != 0)
+ {
+ return False;
+ }
+
+ vuser = get_valid_user_struct(&key);
+ if (vuser != NULL)
+ {
+ DEBUG(3,(" Username of UID %d is %s\n", (int)vuser->uid, vuser->name));
+ }
+ else
+ {
+ return False;
+ }
+
+ unistr2_to_ascii(full_name, &vuser->usr.uni_full_name, sizeof(full_name)-1);
+ unistr2_to_ascii(home_dir, &vuser->usr.uni_home_dir, sizeof(home_dir)-1);
+ unistr2_to_ascii(nt_name, &vuser->usr.uni_user_name, sizeof(nt_name)-1);
+ unistr2_to_ascii(logon_path, &vuser->usr.uni_logon_script, sizeof(logon_path)-1);
+ fstrcpy(logon_srv, "\\\\");
+ unistr2_to_ascii(&logon_srv[2], &vuser->usr.uni_logon_srv, sizeof(logon_srv)-3);
+
+ *rdata_len = mdrcnt + 1024;
+ *rdata = REALLOC(*rdata,*rdata_len);
+
+ SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ p = *rdata;
+ p2 = p + usri11_end;
+
+ memset(p,0,21);
+ fstrcpy(p+usri11_name,nt_name); /* 21 bytes - user name */
+
+ if (uLevel > 0)
+ {
+ SCVAL(p,usri11_pad,0); /* padding - 1 byte */
+ *p2 = 0;
+ }
+ if (uLevel >= 10)
+ {
+ SIVAL(p,usri11_comment,PTR_DIFF(p2,p)); /* comment */
+ pstrcpy(p2, "");
+ p2 = skip_string(p2,1);
+
+ SIVAL(p,usri11_usr_comment,PTR_DIFF(p2,p)); /* user_comment */
+ pstrcpy(p2, "");
+ p2 = skip_string(p2,1);
+
+ /* EEK! the cifsrap.txt doesn't have this in!!!! */
+ SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */
+ pstrcpy(p2, full_name);
+ p2 = skip_string(p2,1);
+ }
+
+ if (uLevel == 11) /* modelled after NTAS 3.51 reply */
+ {
+ SSVAL(p,usri11_priv,conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
+ SIVAL(p,usri11_auth_flags,AF_OP_PRINT); /* auth flags */
+ SIVALS(p,usri11_password_age,-1); /* password age */
+ SIVAL(p,usri11_homedir,PTR_DIFF(p2,p)); /* home dir */
+ pstrcpy(p2, home_dir);
+ p2 = skip_string(p2,1);
+ SIVAL(p,usri11_parms,PTR_DIFF(p2,p)); /* parms */
+ pstrcpy(p2,"");
+ p2 = skip_string(p2,1);
+ SIVAL(p,usri11_last_logon,0); /* last logon */
+ SIVAL(p,usri11_last_logoff,0); /* last logoff */
+ SSVALS(p,usri11_bad_pw_count,vuser->usr.bad_pw_count); /* bad pw counts */
+ SSVALS(p,usri11_num_logons,vuser->usr.logon_count); /* num logons */
+ SIVAL(p,usri11_logon_server,PTR_DIFF(p2,p)); /* logon server */
+ pstrcpy(p2,logon_srv);
+ p2 = skip_string(p2,1);
+ SSVAL(p,usri11_country_code,0); /* country code */
+
+ SIVAL(p,usri11_workstations,PTR_DIFF(p2,p)); /* workstations */
+ pstrcpy(p2, "");
+ p2 = skip_string(p2,1);
+
+ SIVALS(p,usri11_max_storage,-1); /* max storage */
+ SSVAL(p,usri11_units_per_week,168); /* units per week */
+ SIVAL(p,usri11_logon_hours,PTR_DIFF(p2,p)); /* logon hours */
+
+ /* a simple way to get logon hours at all times. */
+ memset(p2,0xff,21);
+ SCVAL(p2,21,0); /* fix zero termination */
+ p2 = skip_string(p2,1);
+
+ SSVAL(p,usri11_code_page,0); /* code page */
+ }
+ if (uLevel == 1 || uLevel == 2)
+ {
+ memset(p+22,' ',16); /* password */
+ SIVALS(p,38,-1); /* password age */
+ SSVAL(p,42,
+ conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
+ SIVAL(p,44,PTR_DIFF(p2,*rdata)); /* home dir */
+ pstrcpy(p2,logon_path);
+ p2 = skip_string(p2,1);
+ SIVAL(p,48,PTR_DIFF(p2,*rdata)); /* comment */
+ *p2++ = 0;
+ SSVAL(p,52,0); /* flags */
+ SIVAL(p,54,0); /* script_path */
+ if (uLevel == 2)
+ {
+ SIVAL(p,60,0); /* auth_flags */
+ SIVAL(p,64,PTR_DIFF(p2,*rdata)); /* full_name */
+ pstrcpy(p2, nt_name);
+ p2 = skip_string(p2,1);
+ SIVAL(p,68,0); /* urs_comment */
+ SIVAL(p,72,PTR_DIFF(p2,*rdata)); /* parms */
+ pstrcpy(p2,"");
+ p2 = skip_string(p2,1);
+ SIVAL(p,76,0); /* workstations */
+ SIVAL(p,80,0); /* last_logon */
+ SIVAL(p,84,0); /* last_logoff */
+ SIVALS(p,88,-1); /* acct_expires */
+ SIVALS(p,92,-1); /* max_storage */
+ SSVAL(p,96,168); /* units_per_week */
+ SIVAL(p,98,PTR_DIFF(p2,*rdata)); /* logon_hours */
+ memset(p2,-1,21);
+ p2 += 21;
+ SSVALS(p,102,vuser->usr.bad_pw_count); /* bad_pw_count */
+ SSVALS(p,104,vuser->usr.logon_count); /* num_logons */
+ SIVAL(p,106,PTR_DIFF(p2,*rdata)); /* logon_server */
+ pstrcpy(p2,logon_srv);
+ p2 = skip_string(p2,1);
+ SSVAL(p,110,49); /* country_code */
+ SSVAL(p,112,860); /* code page */
+ }
+ }
+
+ *rdata_len = PTR_DIFF(p2,*rdata);
+
+ SSVAL(*rparam,4,*rdata_len); /* is this right?? */
+
+ vuid_free_user_struct(vuser);
+
+ return(True);
+}
+
+/*******************************************************************
+ get groups that a user is a member of
+ ******************************************************************/
+static BOOL api_NetUserGetGroups(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *UserName = skip_string(str2,1);
+ char *p = skip_string(UserName,1);
+ int uLevel = SVAL(p,0);
+ char *p2;
+ int count=0;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"zWrLeh") != 0) return False;
+ switch( uLevel ) {
+ case 0: p2 = "B21"; break;
+ default: return False;
+ }
+ if (strcmp(p2,str2) != 0) return False;
+
+ *rdata_len = mdrcnt + 1024;
+ *rdata = REALLOC(*rdata,*rdata_len);
+
+ SSVAL(*rparam,0,NERR_Success);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ p = *rdata;
+
+ /* XXXX we need a real SAM database some day */
+ pstrcpy(p,"Users"); p += 21; count++;
+ pstrcpy(p,"Domain Users"); p += 21; count++;
+ pstrcpy(p,"Guests"); p += 21; count++;
+ pstrcpy(p,"Domain Guests"); p += 21; count++;
+
+ *rdata_len = PTR_DIFF(p,*rdata);
+
+ SSVAL(*rparam,4,count); /* is this right?? */
+ SSVAL(*rparam,6,count); /* is this right?? */
+
+ return(True);
+}
+
+
+static BOOL api_WWkstaUserLogon(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel;
+ struct pack_desc desc;
+ char* name;
+ user_struct *vuser;
+ VUSER_KEY;
+ vuser = get_valid_user_struct(&key); /* moved due to VUSER_KEY initialization */
+
+ if (vuser == NULL)
+ {
+ return False;
+ }
+
+ uLevel = SVAL(p,0);
+ name = p + 2;
+
+ bzero(&desc,sizeof(desc));
+
+ DEBUG(3,("WWkstaUserLogon uLevel=%d name=%s\n",uLevel,name));
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"OOWb54WrLh") != 0) return False;
+ if (uLevel != 1 || strcmp(str2,"WB21BWDWWDDDDDDDzzzD") != 0) return False;
+ if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ desc.subformat = NULL;
+ desc.format = str2;
+
+ if (init_package(&desc,1,0))
+ {
+ fstring nt_name;
+ fstring logon_script;
+ fstring logon_srv;
+ fstring logon_dom;
+
+ unistr2_to_ascii(nt_name, &vuser->usr.uni_user_name, sizeof(nt_name)-1);
+ unistr2_to_ascii(logon_script, &vuser->usr.uni_logon_script, sizeof(logon_script)-1);
+ unistr2_to_ascii(logon_dom, &vuser->usr.uni_logon_dom, sizeof(logon_dom)-1);
+ fstrcpy(logon_srv, "\\\\");
+ unistr2_to_ascii(&logon_srv[2], &vuser->usr.uni_logon_srv, sizeof(logon_srv)-3);
+
+ PACKI(&desc,"W",0); /* code */
+ PACKS(&desc,"B21",nt_name); /* eff. name */
+ PACKS(&desc,"B",""); /* pad */
+ PACKI(&desc,"W",
+ conn->admin_user?USER_PRIV_ADMIN:USER_PRIV_USER);
+ PACKI(&desc,"D",0); /* auth flags XXX */
+ PACKI(&desc,"W",0); /* num logons */
+ PACKI(&desc,"W",0); /* bad pw count */
+ PACKI(&desc,"D",0); /* last logon */
+ PACKI(&desc,"D",-1); /* last logoff */
+ PACKI(&desc,"D",-1); /* logoff time */
+ PACKI(&desc,"D",-1); /* kickoff time */
+ PACKI(&desc,"D",0); /* password age */
+ PACKI(&desc,"D",0); /* password can change */
+ PACKI(&desc,"D",-1); /* password must change */
+ {
+ PACKS(&desc,"z",logon_srv); /* computer */
+ }
+ PACKS(&desc,"z",logon_dom);/* domain */
+ PACKS(&desc,"z", logon_script); /* script path */
+
+ PACKI(&desc,"D",0x00000000); /* reserved */
+ }
+
+ *rdata_len = desc.usedlen;
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,desc.neededlen);
+
+ DEBUG(4,("WWkstaUserLogon: errorcode %d\n",desc.errcode));
+ vuid_free_user_struct(vuser);
+
+ return(True);
+}
+
+
+/****************************************************************************
+ api_WAccessGetUserPerms
+ ****************************************************************************/
+static BOOL api_WAccessGetUserPerms(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *user = skip_string(str2,1);
+ char *resource = skip_string(user,1);
+
+ DEBUG(3,("WAccessGetUserPerms user=%s resource=%s\n",user,resource));
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"zzh") != 0) return False;
+ if (strcmp(str2,"") != 0) return False;
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,0); /* errorcode */
+ SSVAL(*rparam,2,0); /* converter word */
+ SSVAL(*rparam,4,0x7f); /* permission flags */
+
+ return(True);
+}
+
+/****************************************************************************
+ api_WPrintJobEnumerate
+ ****************************************************************************/
+static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel;
+ int count;
+ int i;
+ int snum;
+ int job;
+ struct pack_desc desc;
+ print_queue_struct *queue=NULL;
+ print_status_struct status;
+ VUSER_KEY;
+
+ uLevel = SVAL(p,2);
+
+ bzero(&desc,sizeof(desc));
+ bzero(&status,sizeof(status));
+
+ DEBUG(3,("WPrintJobGetInfo uLevel=%d uJobId=0x%X\n",uLevel,SVAL(p,0)));
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"WWrLh") != 0) return False;
+ if (!check_printjob_info(&desc,uLevel,str2)) return False;
+
+ printjob_decode(SVAL(p,0), &snum, &job);
+
+ if (snum < 0 || !VALID_SNUM(snum)) return(False);
+
+ count = get_printqueue(snum,conn,&key,&queue,&status);
+ for (i = 0; i < count; i++) {
+ if ((queue[i].job & 0xFF) == job) break;
+ }
+ if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+
+ if (init_package(&desc,1,0)) {
+ if (i < count) {
+ fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
+ *rdata_len = desc.usedlen;
+ }
+ else {
+ desc.errcode = NERR_JobNotFound;
+ *rdata_len = 0;
+ }
+ }
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,desc.neededlen);
+
+ if (queue) free(queue);
+
+ DEBUG(4,("WPrintJobGetInfo: errorcode %d\n",desc.errcode));
+ return(True);
+}
+
+static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ char* name = p;
+ int uLevel;
+ int count;
+ int i, succnt=0;
+ int snum;
+ struct pack_desc desc;
+ print_queue_struct *queue=NULL;
+ print_status_struct status;
+ VUSER_KEY;
+
+ bzero(&desc,sizeof(desc));
+ bzero(&status,sizeof(status));
+
+ p = skip_string(p,1);
+ uLevel = SVAL(p,0);
+
+ DEBUG(3,("WPrintJobEnumerate uLevel=%d name=%s\n",uLevel,name));
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"zWrLeh") != 0) return False;
+ if (uLevel > 2) return False; /* defined only for uLevel 0,1,2 */
+ if (!check_printjob_info(&desc,uLevel,str2)) return False;
+
+ snum = lp_servicenumber(name);
+ if (snum < 0 && pcap_printername_ok(name,NULL)) {
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ if (pnum >= 0) {
+ lp_add_printer(name,pnum);
+ snum = lp_servicenumber(name);
+ }
+ }
+
+ if (snum < 0 || !VALID_SNUM(snum)) return(False);
+
+ count = get_printqueue(snum,conn,&key,&queue,&status);
+ if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+
+ if (init_package(&desc,count,0)) {
+ succnt = 0;
+ for (i = 0; i < count; i++) {
+ fill_printjob_info(conn,snum,uLevel,&desc,&queue[i],i);
+ if (desc.errcode == NERR_Success) succnt = i+1;
+ }
+ }
+
+ *rdata_len = desc.usedlen;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,succnt);
+ SSVAL(*rparam,6,count);
+
+ if (queue) free(queue);
+
+ DEBUG(4,("WPrintJobEnumerate: errorcode %d\n",desc.errcode));
+ return(True);
+}
+
+static int check_printdest_info(struct pack_desc* desc,
+ int uLevel, char* id)
+{
+ desc->subformat = NULL;
+ switch( uLevel ) {
+ case 0: desc->format = "B9"; break;
+ case 1: desc->format = "B9B21WWzW"; break;
+ case 2: desc->format = "z"; break;
+ case 3: desc->format = "zzzWWzzzWW"; break;
+ default: return False;
+ }
+ if (strcmp(desc->format,id) != 0) return False;
+ return True;
+}
+
+static void fill_printdest_info(connection_struct *conn, int snum, int uLevel,
+ struct pack_desc* desc)
+{
+ char buf[100];
+ strncpy(buf,SERVICE(snum),sizeof(buf)-1);
+ buf[sizeof(buf)-1] = 0;
+ strupper(buf);
+ if (uLevel <= 1) {
+ PACKS(desc,"B9",buf); /* szName */
+ if (uLevel == 1) {
+ PACKS(desc,"B21",""); /* szUserName */
+ PACKI(desc,"W",0); /* uJobId */
+ PACKI(desc,"W",0); /* fsStatus */
+ PACKS(desc,"z",""); /* pszStatus */
+ PACKI(desc,"W",0); /* time */
+ }
+ }
+ if (uLevel == 2 || uLevel == 3) {
+ PACKS(desc,"z",buf); /* pszPrinterName */
+ if (uLevel == 3) {
+ PACKS(desc,"z",""); /* pszUserName */
+ PACKS(desc,"z",""); /* pszLogAddr */
+ PACKI(desc,"W",0); /* uJobId */
+ PACKI(desc,"W",0); /* fsStatus */
+ PACKS(desc,"z",""); /* pszStatus */
+ PACKS(desc,"z",""); /* pszComment */
+ PACKS(desc,"z","NULL"); /* pszDrivers */
+ PACKI(desc,"W",0); /* time */
+ PACKI(desc,"W",0); /* pad1 */
+ }
+ }
+}
+
+static BOOL api_WPrintDestGetInfo(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ char* PrinterName = p;
+ int uLevel;
+ struct pack_desc desc;
+ int snum;
+
+ bzero(&desc,sizeof(desc));
+
+ p = skip_string(p,1);
+ uLevel = SVAL(p,0);
+
+ DEBUG(3,("WPrintDestGetInfo uLevel=%d PrinterName=%s\n",uLevel,PrinterName));
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"zWrLh") != 0) return False;
+ if (!check_printdest_info(&desc,uLevel,str2)) return False;
+
+ snum = lp_servicenumber(PrinterName);
+ if (snum < 0 && pcap_printername_ok(PrinterName,NULL)) {
+ int pnum = lp_servicenumber(PRINTERS_NAME);
+ if (pnum >= 0) {
+ lp_add_printer(PrinterName,pnum);
+ snum = lp_servicenumber(PrinterName);
+ }
+ }
+
+ if (snum < 0) {
+ *rdata_len = 0;
+ desc.errcode = NERR_DestNotFound;
+ desc.neededlen = 0;
+ }
+ else {
+ if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ if (init_package(&desc,1,0)) {
+ fill_printdest_info(conn,snum,uLevel,&desc);
+ }
+ *rdata_len = desc.usedlen;
+ }
+
+ *rparam_len = 6;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,desc.neededlen);
+
+ DEBUG(4,("WPrintDestGetInfo: errorcode %d\n",desc.errcode));
+ return(True);
+}
+
+static BOOL api_WPrintDestEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel;
+ int queuecnt;
+ int i, n, succnt=0;
+ struct pack_desc desc;
+ int services = lp_numservices();
+
+ bzero(&desc,sizeof(desc));
+
+ uLevel = SVAL(p,0);
+
+ DEBUG(3,("WPrintDestEnum uLevel=%d\n",uLevel));
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"WrLeh") != 0) return False;
+ if (!check_printdest_info(&desc,uLevel,str2)) return False;
+
+ queuecnt = 0;
+ for (i = 0; i < services; i++)
+ if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i))
+ queuecnt++;
+
+ if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ if (init_package(&desc,queuecnt,0)) {
+ succnt = 0;
+ n = 0;
+ for (i = 0; i < services; i++) {
+ if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
+ fill_printdest_info(conn,i,uLevel,&desc);
+ n++;
+ if (desc.errcode == NERR_Success) succnt = n;
+ }
+ }
+ }
+
+ *rdata_len = desc.usedlen;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,succnt);
+ SSVAL(*rparam,6,queuecnt);
+
+ DEBUG(4,("WPrintDestEnumerate: errorcode %d\n",desc.errcode));
+ return(True);
+}
+
+static BOOL api_WPrintDriverEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel;
+ int succnt;
+ struct pack_desc desc;
+
+ bzero(&desc,sizeof(desc));
+
+ uLevel = SVAL(p,0);
+
+ DEBUG(3,("WPrintDriverEnum uLevel=%d\n",uLevel));
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"WrLeh") != 0) return False;
+ if (uLevel != 0 || strcmp(str2,"B41") != 0) return False;
+
+ if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ if (init_package(&desc,1,0)) {
+ PACKS(&desc,"B41","NULL");
+ }
+
+ succnt = (desc.errcode == NERR_Success ? 1 : 0);
+
+ *rdata_len = desc.usedlen;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,succnt);
+ SSVAL(*rparam,6,1);
+
+ DEBUG(4,("WPrintDriverEnum: errorcode %d\n",desc.errcode));
+ return(True);
+}
+
+static BOOL api_WPrintQProcEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel;
+ int succnt;
+ struct pack_desc desc;
+
+ bzero(&desc,sizeof(desc));
+
+ uLevel = SVAL(p,0);
+
+ DEBUG(3,("WPrintQProcEnum uLevel=%d\n",uLevel));
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"WrLeh") != 0) return False;
+ if (uLevel != 0 || strcmp(str2,"B13") != 0) return False;
+
+ if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ desc.format = str2;
+ if (init_package(&desc,1,0)) {
+ PACKS(&desc,"B13","lpd");
+ }
+
+ succnt = (desc.errcode == NERR_Success ? 1 : 0);
+
+ *rdata_len = desc.usedlen;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,succnt);
+ SSVAL(*rparam,6,1);
+
+ DEBUG(4,("WPrintQProcEnum: errorcode %d\n",desc.errcode));
+ return(True);
+}
+
+static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ char *str1 = param+2;
+ char *str2 = skip_string(str1,1);
+ char *p = skip_string(str2,1);
+ int uLevel;
+ int succnt;
+ struct pack_desc desc;
+
+ bzero(&desc,sizeof(desc));
+
+ uLevel = SVAL(p,0);
+
+ DEBUG(3,("WPrintPortEnum uLevel=%d\n",uLevel));
+
+ /* check it's a supported varient */
+ if (strcmp(str1,"WrLeh") != 0) return False;
+ if (uLevel != 0 || strcmp(str2,"B9") != 0) return False;
+
+ if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
+ bzero(&desc,sizeof(desc));
+ desc.base = *rdata;
+ desc.buflen = mdrcnt;
+ desc.format = str2;
+ if (init_package(&desc,1,0)) {
+ PACKS(&desc,"B13","lp0");
+ }
+
+ succnt = (desc.errcode == NERR_Success ? 1 : 0);
+
+ *rdata_len = desc.usedlen;
+
+ *rparam_len = 8;
+ *rparam = REALLOC(*rparam,*rparam_len);
+ SSVALS(*rparam,0,desc.errcode);
+ SSVAL(*rparam,2,0);
+ SSVAL(*rparam,4,succnt);
+ SSVAL(*rparam,6,1);
+
+ DEBUG(4,("WPrintPortEnum: errorcode %d\n",desc.errcode));
+ return(True);
+}
+
+
+/****************************************************************************
+ the buffer was too small
+ ****************************************************************************/
+static BOOL api_TooSmall(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ *rparam_len = MIN(*rparam_len,mprcnt);
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ *rdata_len = 0;
+
+ SSVAL(*rparam,0,NERR_BufTooSmall);
+
+ DEBUG(3,("Supplied buffer too small in API command\n"));
+
+ return(True);
+}
+
+
+/****************************************************************************
+ the request is not supported
+ ****************************************************************************/
+static BOOL api_Unsupported(connection_struct *conn,uint16 vuid, char *param,char *data,
+ int mdrcnt,int mprcnt,
+ char **rdata,char **rparam,
+ int *rdata_len,int *rparam_len)
+{
+ *rparam_len = 4;
+ *rparam = REALLOC(*rparam,*rparam_len);
+
+ *rdata_len = 0;
+
+ SSVAL(*rparam,0,NERR_notsupported);
+ SSVAL(*rparam,2,0); /* converter word */
+
+ DEBUG(3,("Unsupported API command\n"));
+
+ return(True);
+}
+
+
+
+
+struct
+{
+ char *name;
+ int id;
+ BOOL (*fn)(connection_struct *,uint16,char *,char *,
+ int,int,char **,char **,int *,int *);
+ int flags;
+} api_commands[] = {
+ {"RNetShareEnum", 0, api_RNetShareEnum,0},
+ {"RNetShareGetInfo", 1, api_RNetShareGetInfo,0},
+ {"RNetServerGetInfo", 13, api_RNetServerGetInfo,0},
+ {"RNetGroupGetUsers", 52, api_RNetGroupGetUsers,0},
+ {"RNetUserGetInfo", 56, api_RNetUserGetInfo,0},
+ {"NetUserGetGroups", 59, api_NetUserGetGroups,0},
+ {"NetWkstaGetInfo", 63, api_NetWkstaGetInfo,0},
+ {"DosPrintQEnum", 69, api_DosPrintQEnum,0},
+ {"DosPrintQGetInfo", 70, api_DosPrintQGetInfo,0},
+ {"WPrintQueuePause", 74, api_WPrintQueuePurge,0},
+ {"WPrintQueueResume", 75, api_WPrintQueuePurge,0},
+ {"WPrintJobEnumerate",76, api_WPrintJobEnumerate,0},
+ {"WPrintJobGetInfo", 77, api_WPrintJobGetInfo,0},
+ {"RDosPrintJobDel", 81, api_RDosPrintJobDel,0},
+ {"RDosPrintJobPause", 82, api_RDosPrintJobDel,0},
+ {"RDosPrintJobResume",83, api_RDosPrintJobDel,0},
+ {"WPrintDestEnum", 84, api_WPrintDestEnum,0},
+ {"WPrintDestGetInfo", 85, api_WPrintDestGetInfo,0},
+ {"NetRemoteTOD", 91, api_NetRemoteTOD,0},
+ {"WPrintQueuePurge", 103, api_WPrintQueuePurge,0},
+ {"NetServerEnum", 104, api_RNetServerEnum,0},
+ {"WAccessGetUserPerms",105, api_WAccessGetUserPerms,0},
+ {"SetUserPassword", 115, api_SetUserPassword,0},
+ {"WWkstaUserLogon", 132, api_WWkstaUserLogon,0},
+ {"PrintJobInfo", 147, api_PrintJobInfo,0},
+ {"WPrintDriverEnum", 205, api_WPrintDriverEnum,0},
+ {"WPrintQProcEnum", 206, api_WPrintQProcEnum,0},
+ {"WPrintPortEnum", 207, api_WPrintPortEnum,0},
+ {"SamOEMChangePassword", 214, api_SamOEMChangePassword,0},
+ {NULL, -1, api_Unsupported,0}};
+
+
+/****************************************************************************
+ handle remote api calls
+ ****************************************************************************/
+int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data,char *params,
+ int tdscnt,int tpscnt,int mdrcnt,int mprcnt)
+{
+ int api_command;
+ prs_struct rdata_buf;
+ prs_struct rparam_buf;
+ char *rdata = NULL;
+ char *rparam = NULL;
+ int rdata_len = 0;
+ int rparam_len = 0;
+ BOOL reply=False;
+ int i;
+
+ SMB_ASSERT(params != 0);
+
+ api_command = SVAL(params,0);
+
+ DEBUG(3,("Got API command %d of form <%s> <%s> (tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d)\n",
+ api_command,
+ params+2,
+ skip_string(params+2,1),
+ tdscnt,tpscnt,mdrcnt,mprcnt));
+
+ for (i=0;api_commands[i].name;i++)
+ if (api_commands[i].id == api_command && api_commands[i].fn)
+ {
+ DEBUG(3,("Doing %s\n",api_commands[i].name));
+ break;
+ }
+
+ rdata = (char *)malloc(1024); if (rdata) bzero(rdata,1024);
+ rparam = (char *)malloc(1024); if (rparam) bzero(rparam,1024);
+
+ if (!rdata || !rparam) {
+ DEBUG(0,("api_reply: malloc fail !\n"));
+ return -1;
+ }
+
+ reply = api_commands[i].fn(conn,vuid,params,data,mdrcnt,mprcnt,
+ &rdata,&rparam,&rdata_len,&rparam_len);
+
+
+ if (rdata_len > mdrcnt ||
+ rparam_len > mprcnt)
+ {
+ reply = api_TooSmall(conn,vuid,params,data,mdrcnt,mprcnt,
+ &rdata,&rparam,&rdata_len,&rparam_len);
+ }
+
+
+ /* if we get False back then it's actually unsupported */
+ if (!reply)
+ api_Unsupported(conn,vuid,params,data,mdrcnt,mprcnt,
+ &rdata,&rparam,&rdata_len,&rparam_len);
+
+ prs_create(&rdata_buf , rdata , rdata_len , 0, False);
+ prs_create(&rparam_buf, rparam, rparam_len, 0, False);
+
+ /* now send the reply */
+ send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0, False);
+
+ prs_free_data(&rdata_buf );
+ prs_free_data(&rparam_buf);
+
+ return(-1);
+}
+
diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c
index e47bcd896f6..b829746a326 100644
--- a/source/smbd/mangle.c
+++ b/source/smbd/mangle.c
@@ -63,13 +63,11 @@ extern BOOL case_mangle; /* If true, all chars in 8.3 should be same case. */
* global. There is a call to lp_magicchar() in server.c
* that is used to override the initial value.
*
- * MANGLE_BASE - This is the number of characters we use for name mangling.
- *
- * basechars - The set characters used for name mangling. This
+ * basechars - The set of 36 characters used for name mangling. This
* is static (scope is this file only).
*
- * mangle() - Macro used to select a character from basechars (i.e.,
- * mangle(n) will return the nth digit, modulo MANGLE_BASE).
+ * base36() - Macro used to select a character from basechars (i.e.,
+ * base36(n) will return the nth digit, modulo 36).
*
* chartest - array 0..255. The index range is the set of all possible
* values of a byte. For each byte value, the content is a
@@ -112,19 +110,18 @@ extern BOOL case_mangle; /* If true, all chars in 8.3 should be same case. */
char magic_char = '~';
-static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
-#define MANGLE_BASE (sizeof(basechars)/sizeof(char)-1)
+static char basechars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
static unsigned char chartest[256] = { 0 };
static BOOL ct_initialized = False;
-#define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
+#define base36(V) ((char)(basechars[(V) % 36]))
#define BASECHAR_MASK 0xf0
#define ILLEGAL_MASK 0x0f
#define isbasechar(C) ( (chartest[ ((C) & 0xff) ]) & BASECHAR_MASK )
#define isillegal(C) ( (chartest[ ((C) & 0xff) ]) & ILLEGAL_MASK )
-static ubi_cacheRoot mangled_cache[1] = { { { 0, 0, 0, 0 }, 0, 0, 0, 0, 0, 0 } };
+static ubi_cacheRoot mangled_cache[1] = { { { 0 }, 0, 0, 0, 0, 0, 0} };
static BOOL mc_initialized = False;
#define MANGLED_CACHE_MAX_ENTRIES 0
#define MANGLED_CACHE_MAX_MEMORY 16384
@@ -151,7 +148,7 @@ static void init_chartest( void )
char *illegalchars = "*\\/?<>|\":";
unsigned char *s;
- memset( (char *)chartest, '\0', 256 );
+ bzero( (char *)chartest, 256 );
for( s = (unsigned char *)illegalchars; *s; s++ )
chartest[*s] = ILLEGAL_MASK;
@@ -255,7 +252,7 @@ static BOOL is_illegal_name( char *name )
s = (unsigned char *)name;
while( *s )
{
- skip = get_character_len( *s );
+ skip = skip_multibyte_char( *s );
if( skip != 0 )
{
s += skip;
@@ -374,7 +371,7 @@ BOOL is_8_3( char *fname, BOOL check_case )
dot_pos = NULL;
while( *p )
{
- if( (skip = get_character_len( *p )) != 0 )
+ if( (skip = skip_multibyte_char( *p )) != 0 )
p += skip;
else
{
@@ -517,7 +514,7 @@ void reset_mangled_cache( void )
*
* If the extension of the raw name maps directly to the
* extension of the mangled name, then we'll store both names
- * *without* extensions. That way, we can provide consistent
+ * *without* extensions. That way, we can provide consistant
* reverse mangling for all names that match. The test here is
* a bit more careful than the one done in earlier versions of
* mangle.c:
@@ -536,9 +533,9 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
ubi_cacheEntryPtr new_entry;
char *s1;
char *s2;
- size_t mangled_len;
- size_t raw_len;
- size_t i;
+ int mangled_len;
+ int raw_len;
+ int i;
/* If the cache isn't initialized, give up. */
if( !mc_initialized )
@@ -564,7 +561,7 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
}
}
- /* Allocate a new cache entry. If the allocation fails, just return. */
+ /* Allocate a new cache entry. If the allcoation fails, just return. */
i = sizeof( ubi_cacheEntry ) + mangled_len + raw_len + 2;
new_entry = malloc( i );
if( !new_entry )
@@ -592,13 +589,11 @@ static void cache_mangled_name( char *mangled_name, char *raw_name )
*
* ************************************************************************** **
*/
-
BOOL check_mangled_cache( char *s )
-{
+ {
ubi_cacheEntryPtr FoundPtr;
char *ext_start = NULL;
char *found_name;
- char *saved_ext = NULL;
/* If the cache isn't initialized, give up. */
if( !mc_initialized )
@@ -608,34 +603,19 @@ BOOL check_mangled_cache( char *s )
/* If we didn't find the name *with* the extension, try without. */
if( !FoundPtr )
- {
+ {
ext_start = strrchr( s, '.' );
if( ext_start )
- {
- if((saved_ext = strdup(ext_start)) == NULL)
- return False;
-
+ {
*ext_start = '\0';
FoundPtr = ubi_cacheGet( mangled_cache, (ubi_trItemPtr)s );
- /*
- * At this point s is the name without the
- * extension. We re-add the extension if saved_ext
- * is not null, before freeing saved_ext.
- */
+ *ext_start = '.';
+ }
}
- }
/* Okay, if we haven't found it we're done. */
if( !FoundPtr )
- {
- if(saved_ext)
- {
- /* Replace the saved_ext as it was truncated. */
- (void)pstrcat( s, saved_ext );
- free(saved_ext);
- }
return( False );
- }
/* If we *did* find it, we need to copy it into the string buffer. */
found_name = (char *)(FoundPtr + 1);
@@ -644,17 +624,13 @@ BOOL check_mangled_cache( char *s )
DEBUG( 3, ("Found %s on mangled stack ", s) );
(void)pstrcpy( s, found_name );
- if( saved_ext )
- {
- /* Replace the saved_ext as it was truncated. */
- (void)pstrcat( s, saved_ext );
- free(saved_ext);
- }
+ if( ext_start )
+ (void)pstrcat( s, ext_start );
DEBUG( 3, ("as %s\n", s) );
return( True );
-} /* check_mangled_cache */
+ } /* check_mangled_cache */
/* ************************************************************************** **
@@ -676,12 +652,6 @@ static char *map_filename( char *s, /* This is null terminated */
pstrcpy( matching_bit, "" ); /* Match but no star gets this. */
pp = pat; /* Initialize the pointers. */
sp = s;
-
- if( strequal(s, ".") || strequal(s, ".."))
- {
- return NULL; /* Do not map '.' and '..' */
- }
-
if( (len == 1) && (*pattern == '*') )
{
return NULL; /* Impossible, too ambiguous for */
@@ -837,7 +807,7 @@ static void do_fwd_mangled_map(char *s, char *MangledMap)
*/
void mangle_name_83( char *s)
{
- int csum;
+ int csum = str_checksum(s);
char *p;
char extension[4];
char base[9];
@@ -859,11 +829,7 @@ void mangle_name_83( char *s)
csum = str_checksum( s );
*p = '.';
}
- else
- csum = str_checksum(s);
}
- else
- csum = str_checksum(s);
strupper( s );
@@ -878,7 +844,7 @@ void mangle_name_83( char *s)
*p++ = 0;
while( *p && extlen < 3 )
{
- skip = get_character_len( *p );
+ skip = skip_multibyte_char( *p );
switch( skip )
{
case 2:
@@ -889,7 +855,7 @@ void mangle_name_83( char *s)
}
else
{
- extension[extlen++] = mangle( (unsigned char)*p );
+ extension[extlen++] = base36( (unsigned char)*p );
}
p += 2;
break;
@@ -912,7 +878,7 @@ void mangle_name_83( char *s)
while( *p && baselen < 5 )
{
- skip = get_character_len(*p);
+ skip = skip_multibyte_char(*p);
switch( skip )
{
case 2:
@@ -923,7 +889,7 @@ void mangle_name_83( char *s)
}
else
{
- base[baselen++] = mangle( (unsigned char)*p );
+ base[baselen++] = base36( (unsigned char)*p );
}
p += 2;
break;
@@ -940,10 +906,10 @@ void mangle_name_83( char *s)
}
base[baselen] = 0;
- csum = csum % (MANGLE_BASE*MANGLE_BASE);
+ csum = csum % (36*36);
(void)slprintf(s, 12, "%s%c%c%c",
- base, magic_char, mangle( csum/MANGLE_BASE ), mangle( csum ) );
+ base, magic_char, base36( csum/36 ), base36( csum ) );
if( *extension )
{
@@ -969,11 +935,6 @@ void mangle_name_83( char *s)
* signal that a client does not require name mangling,
* thus skipping the name mangling even on shares which
* have name-mangling turned on.
- * cache83 - If False, the mangled name cache will not be updated.
- * This is usually used to prevent that we overwrite
- * a conflicting cache entry prematurely, i.e. before
- * we know whether the client is really interested in the
- * current name. (See PR#13758). UKD.
* snum - Share number. This identifies the share in which the
* name exists.
*
@@ -982,11 +943,11 @@ void mangle_name_83( char *s)
*
* ****************************************************************************
*/
-BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum)
+BOOL name_map_mangle(char *OutName, BOOL need83, int snum)
{
char *map;
- DEBUG(5,("name_map_mangle( %s, need83 = %s, cache83 = %s, %d )\n", OutName,
- need83 ? "TRUE" : "FALSE", cache83 ? "TRUE" : "FALSE", snum));
+ DEBUG(5,("name_map_mangle( %s, %s, %d )\n",
+ OutName, need83?"TRUE":"FALSE", snum));
#ifdef MANGLE_LONG_FILENAMES
if( !need83 && is_illegal_name(OutName) )
@@ -1002,19 +963,17 @@ BOOL name_map_mangle(char *OutName, BOOL need83, BOOL cache83, int snum)
/* check if it's already in 8.3 format */
if (need83 && !is_8_3(OutName, True)) {
- char *tmp = NULL;
+ char *tmp;
if (!lp_manglednames(snum)) {
return(False);
}
/* mangle it into 8.3 */
- if (cache83)
- tmp = strdup(OutName);
-
+ tmp = strdup(OutName);
mangle_name_83(OutName);
- if(tmp != NULL) {
+ if(tmp) {
cache_mangled_name(OutName, tmp);
free(tmp);
}
diff --git a/source/smbd/message.c b/source/smbd/message.c
index cc329d61a65..d13dfda1e02 100644
--- a/source/smbd/message.c
+++ b/source/smbd/message.c
@@ -54,7 +54,7 @@ static void msg_deliver(void)
/* put it in a temporary file */
slprintf(s,sizeof(s)-1, "%s/msg.XXXXXX",tmpdir());
- fstrcpy(name,(char *)smbd_mktemp(s));
+ fstrcpy(name,(char *)mktemp(s));
fd = sys_open(name,O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0600);
if (fd == -1) {
@@ -62,16 +62,6 @@ static void msg_deliver(void)
return;
}
- /*
- * Incoming message is in DOS codepage format. Convert to UNIX in
- * place.
- */
-
- if(msgpos > 0) {
- msgbuf[msgpos] = '\0'; /* Ensure null terminated. */
- dos_to_unix(msgbuf,True);
- }
-
for (i=0;i<msgpos;) {
if (msgbuf[i]=='\r' && i<(msgpos-1) && msgbuf[i+1]=='\n') {
i++; continue;
@@ -84,13 +74,10 @@ static void msg_deliver(void)
/* run the command */
if (*lp_msg_command())
{
- fstring alpha_msgfrom;
- fstring alpha_msgto;
-
pstrcpy(s,lp_msg_command());
- pstring_sub(s,"%s",name);
- pstring_sub(s,"%f",alpha_strcpy(alpha_msgfrom,msgfrom,sizeof(alpha_msgfrom)));
- pstring_sub(s,"%t",alpha_strcpy(alpha_msgto,msgto,sizeof(alpha_msgto)));
+ string_sub(s,"%s",name);
+ string_sub(s,"%f",msgfrom);
+ string_sub(s,"%t",msgto);
standard_sub_basic(s);
smbrun(s,NULL,False);
}
@@ -112,6 +99,7 @@ int reply_sends(connection_struct *conn,
msgpos = 0;
+
if (! (*lp_msg_command()))
return(ERROR(ERRSRV,ERRmsgoff));
@@ -125,9 +113,7 @@ int reply_sends(connection_struct *conn,
fstrcpy(msgto,dest);
len = SVAL(msg,0);
- len = MIN(len,sizeof(msgbuf)-msgpos);
-
- memset(msgbuf,'\0',sizeof(msgbuf));
+ len = MIN(len,1600-msgpos);
memcpy(&msgbuf[msgpos],msg+2,len);
msgpos += len;
@@ -154,7 +140,6 @@ int reply_sendstrt(connection_struct *conn,
outsize = set_message(outbuf,1,0,True);
- memset(msgbuf,'\0',sizeof(msgbuf));
msgpos = 0;
orig = smb_buf(inbuf)+1;
@@ -187,7 +172,7 @@ int reply_sendtxt(connection_struct *conn,
msg = smb_buf(inbuf) + 1;
len = SVAL(msg,0);
- len = MIN(len,sizeof(msgbuf)-msgpos);
+ len = MIN(len,1600-msgpos);
memcpy(&msgbuf[msgpos],msg+2,len);
msgpos += len;
@@ -217,3 +202,4 @@ int reply_sendend(connection_struct *conn,
return(outsize);
}
+
diff --git a/source/smbd/negprot.c b/source/smbd/negprot.c
index 3cabc6b2295..4498e42950b 100644
--- a/source/smbd/negprot.c
+++ b/source/smbd/negprot.c
@@ -26,6 +26,8 @@ extern int Protocol;
extern int max_recv;
extern fstring global_myworkgroup;
extern fstring remote_machine;
+extern pstring myhostname;
+extern dfs_internal dfs_struct;
/****************************************************************************
reply for the core protocol
@@ -109,15 +111,6 @@ static int reply_lanman2(char *outbuf)
char cryptkey[8];
char crypt_len = 0;
- if (lp_security() == SEC_SERVER) {
- cli = server_cryptkey();
- }
-
- if (cli) {
- DEBUG(3,("using password server validation\n"));
- doencrypt = ((cli->sec_mode & 2) != 0);
- }
-
if (lp_security()>=SEC_USER) secword |= 1;
if (doencrypt) secword |= 2;
@@ -158,41 +151,38 @@ reply for the nt protocol
static int reply_nt1(char *outbuf)
{
/* dual names + lock_and_read + nt SMBs + remote API calls */
- int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ|
- (lp_nt_smb_support() ? CAP_NT_SMBS | CAP_RPC_REMOTE_APIS : 0) |
- (SMB_OFF_T_BITS == 64 ? CAP_LARGE_FILES : 0);
-
-
-/*
- other valid capabilities which we may support at some time...
- CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
- */
-
int secword=0;
BOOL doencrypt = SMBENCRYPT();
time_t t = time(NULL);
int data_len;
- struct cli_state *cli = NULL;
char cryptkey[8];
char crypt_len = 0;
- if (lp_security() == SEC_SERVER) {
- cli = server_cryptkey();
- }
+ int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ;
- if (cli) {
- DEBUG(3,("using password server validation\n"));
- doencrypt = ((cli->sec_mode & 2) != 0);
- }
+ if (lp_nt_smb_support())
+ {
+ capabilities |= CAP_NT_SMBS | CAP_RPC_REMOTE_APIS;
+ }
+
+ if (SMB_OFF_T_BITS == 64)
+ {
+ capabilities |= CAP_LARGE_FILES;
+ }
+
+ if (dfs_struct.ready==True)
+ {
+ capabilities |= CAP_DFS;
+ }
+
+/*
+ other valid capabilities which we may support at some time...
+ CAP_LARGE_READX|CAP_STATUS32|CAP_LEVEL_II_OPLOCKS;
+ */
if (doencrypt) {
crypt_len = 8;
- if (!cli) {
- generate_next_challenge(cryptkey);
- } else {
- memcpy(cryptkey, cli->cryptkey, 8);
- set_challenge(cli->cryptkey);
- }
+ generate_next_challenge(cryptkey);
}
if (lp_readraw() && lp_writeraw()) {
@@ -203,12 +193,13 @@ static int reply_nt1(char *outbuf)
if (doencrypt) secword |= 2;
/* decide where (if) to put the encryption challenge, and
- follow it with the OEM'd domain name
+ follow it with the OEM'd domain name in Unicode.
*/
- data_len = crypt_len + strlen(global_myworkgroup) + 1;
+ data_len = crypt_len + (strlen(global_myworkgroup)+1)*2;
set_message(outbuf,17,data_len,True);
- pstrcpy(smb_buf(outbuf)+crypt_len, global_myworkgroup);
+ ascii_to_unibuf(smb_buf(outbuf)+crypt_len, global_myworkgroup,
+ (strlen(global_myworkgroup)+1)*2);
CVAL(outbuf,smb_vwv1) = secword;
SSVALS(outbuf,smb_vwv16+1,crypt_len);
@@ -252,14 +243,6 @@ protocol [LM1.2X002]
protocol [LANMAN2.1]
protocol [NT LM 0.12]
-Win2K:
-protocol [PC NETWORK PROGRAM 1.0]
-protocol [LANMAN1.0]
-protocol [Windows for Workgroups 3.1a]
-protocol [LM1.2X002]
-protocol [LANMAN2.1]
-protocol [NT LM 0.12]
-
OS/2:
protocol [PC NETWORK PROGRAM 1.0]
protocol [XENIX CORE]
@@ -273,31 +256,29 @@ protocol [LANMAN2.1]
*
* This appears to be the matrix of which protocol is used by which
* MS product.
- Protocol WfWg Win95 WinNT Win2K OS/2
- PC NETWORK PROGRAM 1.0 1 1 1 1 1
- XENIX CORE 2 2
+ Protocol WfWg Win95 WinNT OS/2
+ PC NETWORK PROGRAM 1.0 1 1 1 1
+ XENIX CORE 2 2
MICROSOFT NETWORKS 3.0 2 2
DOS LM1.2X002 3 3
MICROSOFT NETWORKS 1.03 3
DOS LANMAN2.1 4 4
- LANMAN1.0 4 2 3
- Windows for Workgroups 3.1a 5 5 5 3
- LM1.2X002 6 4 4
- LANMAN2.1 7 5 5
- NT LM 0.12 6 8 6
+ LANMAN1.0 4 3
+ Windows for Workgroups 3.1a 5 5 5
+ LM1.2X002 6 4
+ LANMAN2.1 7 5
+ NT LM 0.12 6 8
*
* tim@fsg.com 09/29/95
- * Win2K added by matty 17/7/99
*/
#define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
#define ARCH_WIN95 0x2
-#define ARCH_WINNT 0x4
-#define ARCH_WIN2K 0xC /* Win2K is like NT */
-#define ARCH_OS2 0x14 /* Again OS/2 is like NT */
-#define ARCH_SAMBA 0x20
+#define ARCH_OS2 0xC /* Again OS/2 is like NT */
+#define ARCH_WINNT 0x8
+#define ARCH_SAMBA 0x10
-#define ARCH_ALL 0x3F
+#define ARCH_ALL 0x1F
/* List of supported protocols, most desired first */
static struct {
@@ -315,7 +296,7 @@ static struct {
{"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
{"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
{"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
- {NULL,NULL,NULL,0},
+ {NULL,NULL},
};
@@ -340,17 +321,17 @@ int reply_negprot(connection_struct *conn,
Index++;
DEBUG(3,("Requested protocol [%s]\n",p));
if (strcsequal(p,"Windows for Workgroups 3.1a"))
- arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
+ arch &= ( ARCH_WFWG | ARCH_WIN95 | ARCH_WINNT );
else if (strcsequal(p,"DOS LM1.2X002"))
arch &= ( ARCH_WFWG | ARCH_WIN95 );
else if (strcsequal(p,"DOS LANMAN2.1"))
arch &= ( ARCH_WFWG | ARCH_WIN95 );
else if (strcsequal(p,"NT LM 0.12"))
- arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K );
+ arch &= ( ARCH_WIN95 | ARCH_WINNT );
else if (strcsequal(p,"LANMAN2.1"))
- arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
+ arch &= ( ARCH_WINNT | ARCH_OS2 );
else if (strcsequal(p,"LM1.2X002"))
- arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
+ arch &= ( ARCH_WINNT | ARCH_OS2 );
else if (strcsequal(p,"MICROSOFT NETWORKS 1.03"))
arch &= ARCH_WINNT;
else if (strcsequal(p,"XENIX CORE"))
@@ -376,9 +357,6 @@ int reply_negprot(connection_struct *conn,
case ARCH_WINNT:
set_remote_arch(RA_WINNT);
break;
- case ARCH_WIN2K:
- set_remote_arch(RA_WIN2K);
- break;
case ARCH_OS2:
set_remote_arch(RA_OS2);
break;
@@ -391,7 +369,7 @@ int reply_negprot(connection_struct *conn,
reload_services(True);
/* a special case to stop password server loops */
- if (Index == 1 && strequal(remote_machine,myhostname()) &&
+ if (Index == 1 && strequal(remote_machine,myhostname) &&
(lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
exit_server("Password server loop!");
diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c
index e94e603661a..b72507d4883 100644
--- a/source/smbd/nttrans.c
+++ b/source/smbd/nttrans.c
@@ -27,6 +27,7 @@ extern int Protocol;
extern int Client;
extern int smb_read_error;
extern int global_oplock_break;
+extern int chain_size;
extern BOOL case_sensitive;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
@@ -36,8 +37,10 @@ static void remove_pending_change_notify_requests_by_mid(int mid);
static char *known_nt_pipes[] = {
"\\LANMAN",
"\\srvsvc",
+ "\\svcctl",
"\\samr",
"\\wkssvc",
+ "\\browser",
"\\NETLOGON",
"\\ntlsa",
"\\ntsvcs",
@@ -55,7 +58,7 @@ static char *known_nt_pipes[] = {
HACK ! Always assumes smb_setup field is zero.
****************************************************************************/
-static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_error, char *params,
+static int send_nt_replies(char *outbuf, int bufsize, char *params,
int paramsize, char *pdata, int datasize)
{
extern int max_send;
@@ -75,13 +78,6 @@ static int send_nt_replies(char *inbuf, char *outbuf, int bufsize, uint32 nt_err
set_message(outbuf,18,0,True);
- if(nt_error != 0) {
- /* NT Error. */
- SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2) | FLAGS2_32_BIT_ERROR_CODES);
-
- ERROR(0,nt_error);
- }
-
/*
* If there genuinely are no parameters or data to send just send
* the empty packet.
@@ -359,25 +355,18 @@ static int map_create_disposition( uint32 create_disposition)
Utility function to map share modes.
****************************************************************************/
-static int map_share_mode( BOOL *pstat_open_only, char *fname,
- uint32 desired_access, uint32 share_access, uint32 file_attributes)
+static int map_share_mode( char *fname, uint32 desired_access, uint32 share_access, uint32 file_attributes)
{
int smb_open_mode = -1;
- *pstat_open_only = False;
-
- switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA) ) {
+ switch( desired_access & (FILE_READ_DATA|FILE_WRITE_DATA) ) {
case FILE_READ_DATA:
smb_open_mode = DOS_OPEN_RDONLY;
break;
case FILE_WRITE_DATA:
- case FILE_APPEND_DATA:
- case FILE_WRITE_DATA|FILE_APPEND_DATA:
smb_open_mode = DOS_OPEN_WRONLY;
break;
case FILE_READ_DATA|FILE_WRITE_DATA:
- case FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA:
- case FILE_READ_DATA|FILE_APPEND_DATA:
smb_open_mode = DOS_OPEN_RDWR;
break;
}
@@ -397,12 +386,8 @@ static int map_share_mode( BOOL *pstat_open_only, char *fname,
*/
if (smb_open_mode == -1) {
- if(desired_access == WRITE_DAC_ACCESS || desired_access == READ_CONTROL_ACCESS)
- *pstat_open_only = True;
-
if(desired_access & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|
FILE_EXECUTE|FILE_READ_ATTRIBUTES|
- FILE_READ_EA|FILE_WRITE_EA|SYSTEM_SECURITY_ACCESS|
FILE_WRITE_ATTRIBUTES|READ_CONTROL_ACCESS))
smb_open_mode = DOS_OPEN_RDONLY;
else {
@@ -479,46 +464,18 @@ static time_t fail_time;
void fail_next_srvsvc_open(void)
{
- /* Check client is WinNT proper; Win2K doesn't like Jeremy's hack - matty */
- if (get_remote_arch() != RA_WINNT)
- return;
-
fail_next_srvsvc = True;
fail_time = time(NULL);
DEBUG(10,("fail_next_srvsvc_open: setting up timeout close of \\srvsvc pipe for print fix.\n"));
}
-/*
- * HACK alert.... see above - JRA.
- */
-
-BOOL should_fail_next_srvsvc_open(const char *pipename)
-{
-
- DEBUG(10,("should_fail_next_srvsvc_open: fail = %d, pipe = %s\n",
- (int)fail_next_srvsvc, pipename));
-
- if(fail_next_srvsvc && (time(NULL) > fail_time + HACK_FAIL_TIME)) {
- fail_next_srvsvc = False;
- fail_time = (time_t)0;
- DEBUG(10,("should_fail_next_srvsvc_open: End of timeout close of \\srvsvc pipe for print fix.\n"));
- }
-
- if(fail_next_srvsvc && strequal(pipename, "srvsvc")) {
- fail_next_srvsvc = False;
- DEBUG(10,("should_fail_next_srvsvc_open: Deliberately failing open of \\srvsvc pipe for print fix.\n"));
- return True;
- }
- return False;
-}
-
-
/****************************************************************************
Reply to an NT create and X call on a pipe.
****************************************************************************/
static int nt_open_pipe(char *fname, connection_struct *conn,
char *inbuf, char *outbuf, int *ppnum)
{
+ vuser_key key;
pipes_struct *p = NULL;
uint16 vuid = SVAL(inbuf, smb_uid);
@@ -531,18 +488,37 @@ static int nt_open_pipe(char *fname, connection_struct *conn,
if( strequal(fname,known_nt_pipes[i]))
break;
+ /*
+ * HACK alert.... see above - JRA.
+ */
+
+ if(fail_next_srvsvc && (time(NULL) > fail_time + HACK_FAIL_TIME)) {
+ fail_next_srvsvc = False;
+ fail_time = (time_t)0;
+ DEBUG(10,("nt_open_pipe: End of timeout close of \\srvsvc pipe for print fix.\n"));
+ }
+
+ if(fail_next_srvsvc && strequal(fname, "\\srvsvc")) {
+ fail_next_srvsvc = False;
+ DEBUG(10,("nt_open_pipe: Deliberately failing open of \\srvsvc pipe for print fix.\n"));
+ return(ERROR(ERRSRV,ERRaccess));
+ }
+
+ /*
+ * End hack alert.... see above - JRA.
+ */
+
if ( known_nt_pipes[i] == NULL )
return(ERROR(ERRSRV,ERRaccess));
/* Strip \\ off the name. */
fname++;
- if(should_fail_next_srvsvc_open(fname))
- return (ERROR(ERRSRV,ERRaccess));
-
DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname));
- p = open_rpc_pipe_p(fname, conn, vuid);
+ key.pid = getpid();
+ key.vuid = vuid;
+ p = open_rpc_pipe_p(fname, &key, NULL);
if (!p)
return(ERROR(ERRSRV,ERRnofids));
@@ -574,7 +550,7 @@ int reply_ntcreate_and_X(connection_struct *conn,
/* Breakout the oplock request bits so we can set the
reply bits separately. */
int oplock_request = 0;
- mode_t unixmode;
+ mode_t unixmode;
int pnum = -1;
int fmode=0,rmode=0;
SMB_OFF_T file_len = 0;
@@ -583,7 +559,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
BOOL bad_path = False;
files_struct *fsp=NULL;
char *p = NULL;
- BOOL stat_open_only = False;
/*
* We need to construct the open_and_X ofun value from the
@@ -604,23 +579,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
files_struct *dir_fsp = file_fsp(inbuf,smb_ntcreate_RootDirectoryFid);
size_t dir_name_len;
- if(!dir_fsp)
- return(ERROR(ERRDOS,ERRbadfid));
-
- if(!dir_fsp->is_directory) {
- /*
- * Check to see if this is a mac fork of some kind.
- */
-
- get_filename(&fname[0], inbuf, smb_buf(inbuf)-inbuf,
- smb_buflen(inbuf),fname_len);
-
- if( fname[0] == ':') {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
- }
+ if(!dir_fsp || !dir_fsp->is_directory)
return(ERROR(ERRDOS,ERRbadfid));
- }
/*
* Copy in the base directory name.
@@ -643,17 +603,26 @@ int reply_ntcreate_and_X(connection_struct *conn,
get_filename(&fname[dir_name_len], inbuf, smb_buf(inbuf)-inbuf,
smb_buflen(inbuf),fname_len);
+#if 0
+ StrnCpy(&fname[dir_name_len], smb_buf(inbuf),fname_len);
+ fname[dir_name_len+fname_len] = '\0';
+#endif
} else {
get_filename(fname, inbuf, smb_buf(inbuf)-inbuf,
smb_buflen(inbuf),fname_len);
+
+#if 0
+ StrnCpy(fname,smb_buf(inbuf),fname_len);
+ fname[fname_len] = '\0';
+#endif
}
/* If it's an IPC, use the pipe handler. */
- if (IS_IPC(conn) && lp_nt_pipe_support()) {
-
+ if (IS_IPC(conn) && lp_nt_pipe_support() && lp_security() != SEC_SHARE)
+ {
int ret = nt_open_pipe(fname, conn, inbuf, outbuf, &pnum);
if(ret != 0)
return ret;
@@ -688,13 +657,11 @@ int reply_ntcreate_and_X(connection_struct *conn,
* desired access and the share access.
*/
- if((smb_open_mode = map_share_mode(&stat_open_only, fname, desired_access,
+ if((smb_open_mode = map_share_mode(fname, desired_access,
share_access,
- file_attributes)) == -1)
+ file_attributes)) == -1) {
return(ERROR(ERRDOS,ERRbadaccess));
-
- oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
- oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
+ }
/*
* Ordinary file or directory.
@@ -706,7 +673,11 @@ int reply_ntcreate_and_X(connection_struct *conn,
set_posix_case_semantics(file_attributes);
- unix_convert(fname,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
fsp = file_new();
if (!fsp) {
@@ -726,8 +697,11 @@ int reply_ntcreate_and_X(connection_struct *conn,
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- unixmode = unix_mode(conn,smb_attr | aARCH, fname);
+ unixmode = unix_mode(conn,smb_attr | aARCH);
+ oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+ oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
+
/*
* If it's a request for a directory open, deal with it separately.
*/
@@ -735,8 +709,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
if(create_options & FILE_DIRECTORY_FILE) {
oplock_request = 0;
- open_directory(fsp, conn, fname, smb_ofun,
- unixmode, &smb_action);
+ open_directory(fsp, conn, fname, smb_ofun, unixmode,
+ &smb_action);
restore_case_semantics(file_attributes);
@@ -762,12 +736,13 @@ int reply_ntcreate_and_X(connection_struct *conn,
* before issuing an oplock break request to
* our client. JRA. */
- open_file_shared(fsp,conn,fname,smb_open_mode,
- smb_ofun,unixmode, oplock_request,&rmode,&smb_action);
+ open_file_shared(fsp,conn,fname,smb_open_mode,
+ smb_ofun,unixmode,
+ oplock_request,&rmode,&smb_action);
if (!fsp->open) {
- /* We cheat here. There are two cases we
- * care about. One is a directory rename,
+ /* We cheat here. The only case we
+ * care about is a directory rename,
* where the NT client will attempt to
* open the source directory for
* DELETE access. Note that when the
@@ -780,54 +755,21 @@ int reply_ntcreate_and_X(connection_struct *conn,
* will generate an EISDIR error, so
* we can catch this here and open a
* pseudo handle that is flagged as a
- * directory. The second is an open
- * for a permissions read only, which
- * we handle in the open_file_stat case. JRA.
- */
+ * directory. JRA. */
if(errno == EISDIR) {
-
- /*
- * Fail the open if it was explicitly a non-directory file.
- */
-
- if (create_options & FILE_NON_DIRECTORY_FILE) {
- file_free(fsp);
- restore_case_semantics(file_attributes);
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_FILE_IS_A_DIRECTORY));
- }
-
oplock_request = 0;
- open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
+
+ open_directory(fsp, conn, fname,
+ smb_ofun, unixmode,
+ &smb_action);
if(!fsp->open) {
file_free(fsp);
restore_case_semantics(file_attributes);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
-#ifdef EROFS
- } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
-#else /* !EROFS */
- } else if (errno == EACCES && stat_open_only) {
-#endif
- /*
- * We couldn't open normally and all we want
- * are the permissions. Try and do a stat open.
- */
-
- oplock_request = 0;
-
- open_file_stat(fsp,conn,fname,smb_open_mode,&sbuf,&smb_action);
-
- if(!fsp->open) {
- file_free(fsp);
- restore_case_semantics(file_attributes);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
} else {
-
if((errno == ENOENT) && bad_path) {
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadpath;
@@ -843,13 +785,15 @@ int reply_ntcreate_and_X(connection_struct *conn,
}
if(fsp->is_directory) {
- if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &sbuf) != 0) {
- close_file(fsp,True);
+ if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False),
+ &sbuf) != 0) {
+ close_directory(fsp);
restore_case_semantics(file_attributes);
return(ERROR(ERRDOS,ERRnoaccess));
}
} else {
- if (conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+ if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf)
+ != 0) {
close_file(fsp,False);
restore_case_semantics(file_attributes);
return(ERROR(ERRDOS,ERRnoaccess));
@@ -876,9 +820,9 @@ int reply_ntcreate_and_X(connection_struct *conn,
if (oplock_request && lp_fake_oplocks(SNUM(conn)))
smb_action |= EXTENDED_OPLOCK_GRANTED;
- if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ if(oplock_request && fsp->granted_oplock)
smb_action |= EXTENDED_OPLOCK_GRANTED;
-
+
set_message(outbuf,34,0,True);
p = outbuf + smb_vwv2;
@@ -887,14 +831,8 @@ int reply_ntcreate_and_X(connection_struct *conn,
* Currently as we don't support level II oplocks we just report
* exclusive & batch here.
*/
-
- if (smb_action & EXTENDED_OPLOCK_GRANTED)
- SCVAL(p,0, BATCH_OPLOCK_RETURN);
- else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
- SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
- else
- SCVAL(p,0,NO_OPLOCK_RETURN);
+ SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
p++;
SSVAL(p,0,fsp->fnum);
p += 2;
@@ -926,7 +864,6 @@ int reply_ntcreate_and_X(connection_struct *conn,
/****************************************************************************
Reply to a NT_TRANSACT_CREATE call (needs to process SD's).
****************************************************************************/
-
static int call_nt_transact_create(connection_struct *conn,
char *inbuf, char *outbuf, int length,
int bufsize,
@@ -959,7 +896,6 @@ static int call_nt_transact_create(connection_struct *conn,
BOOL bad_path = False;
files_struct *fsp = NULL;
char *p = NULL;
- BOOL stat_open_only = False;
/*
* We need to construct the open_and_X ofun value from the
@@ -981,24 +917,8 @@ static int call_nt_transact_create(connection_struct *conn,
files_struct *dir_fsp = file_fsp(params,4);
size_t dir_name_len;
- if(!dir_fsp)
- return(ERROR(ERRDOS,ERRbadfid));
-
- if(!dir_fsp->is_directory) {
- /*
- * Check to see if this is a mac fork of some kind.
- */
-
- StrnCpy(fname,params+53,fname_len);
- fname[fname_len] = '\0';
-
- if( fname[0] == ':') {
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_OBJECT_PATH_NOT_FOUND));
- }
-
+ if(!dir_fsp || !dir_fsp->is_directory)
return(ERROR(ERRDOS,ERRbadfid));
- }
/*
* Copy in the base directory name.
@@ -1034,26 +954,17 @@ static int call_nt_transact_create(connection_struct *conn,
return ret;
smb_action = FILE_WAS_OPENED;
} else {
-
- /*
- * Now contruct the smb_open_mode value from the desired access
- * and the share access.
- */
-
- if((smb_open_mode = map_share_mode( &stat_open_only, fname, desired_access,
- share_access, file_attributes)) == -1)
- return(ERROR(ERRDOS,ERRbadaccess));
-
- oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
- oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
-
/*
* Check if POSIX semantics are wanted.
*/
set_posix_case_semantics(file_attributes);
- unix_convert(fname,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
fsp = file_new();
if (!fsp) {
@@ -1073,8 +984,19 @@ static int call_nt_transact_create(connection_struct *conn,
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- unixmode = unix_mode(conn,smb_attr | aARCH, fname);
+ unixmode = unix_mode(conn,smb_attr | aARCH);
+ oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
+ oplock_request |= (flags & REQUEST_BATCH_OPLOCK) ? BATCH_OPLOCK : 0;
+
+ /*
+ * Now contruct the smb_open_mode value from the desired access
+ * and the share access.
+ */
+
+ if((smb_open_mode = map_share_mode( fname, desired_access, share_access, file_attributes)) == -1)
+ return(ERROR(ERRDOS,ERRbadaccess));
+
/*
* If it's a request for a directory open, deal with it separately.
*/
@@ -1093,97 +1015,37 @@ static int call_nt_transact_create(connection_struct *conn,
if(!fsp->open) {
file_free(fsp);
- restore_case_semantics(file_attributes);
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
-
- if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False),
- &sbuf) != 0) {
- close_file(fsp,True);
- restore_case_semantics(file_attributes);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
} else {
/*
* Ordinary file case.
*/
- open_file_shared(fsp,conn,fname,smb_open_mode,smb_ofun,unixmode,
- oplock_request,&rmode,&smb_action);
+ open_file_shared(fsp,conn,fname,smb_open_mode,smb_ofun,
+ unixmode,oplock_request,&rmode,&smb_action);
if (!fsp->open) {
+ if((errno == ENOENT) && bad_path) {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ file_free(fsp);
- if(errno == EISDIR) {
-
- /*
- * Fail the open if it was explicitly a non-directory file.
- */
-
- if (create_options & FILE_NON_DIRECTORY_FILE) {
- file_free(fsp);
- restore_case_semantics(file_attributes);
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_FILE_IS_A_DIRECTORY));
- }
-
- oplock_request = 0;
- open_directory(fsp, conn, fname, smb_ofun, unixmode, &smb_action);
-
- if(!fsp->open) {
- file_free(fsp);
- restore_case_semantics(file_attributes);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-#ifdef EROFS
- } else if (((errno == EACCES) || (errno == EROFS)) && stat_open_only) {
-#else /* !EROFS */
- } else if (errno == EACCES && stat_open_only) {
-#endif
-
- /*
- * We couldn't open normally and all we want
- * are the permissions. Try and do a stat open.
- */
-
- oplock_request = 0;
-
- open_file_stat(fsp,conn,fname,smb_open_mode,&sbuf,&smb_action);
-
- if(!fsp->open) {
- file_free(fsp);
- restore_case_semantics(file_attributes);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
- } else {
+ restore_case_semantics(file_attributes);
- if((errno == ENOENT) && bad_path) {
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
- }
- file_free(fsp);
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
+ if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
+ close_file(fsp,False);
- restore_case_semantics(file_attributes);
+ restore_case_semantics(file_attributes);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ return(ERROR(ERRDOS,ERRnoaccess));
}
- if(fsp->is_directory) {
- if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf) != 0) {
- close_file(fsp,True);
- restore_case_semantics(file_attributes);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
- } else {
- if (!fsp->stat_open && conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
- close_file(fsp,False);
- restore_case_semantics(file_attributes);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
- }
-
file_len = sbuf.st_size;
fmode = dos_mode(conn,fname,&sbuf);
if(fmode == 0)
@@ -1204,7 +1066,7 @@ static int call_nt_transact_create(connection_struct *conn,
if (oplock_request && lp_fake_oplocks(SNUM(conn)))
smb_action |= EXTENDED_OPLOCK_GRANTED;
- if(oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ if(oplock_request && fsp->granted_oplock)
smb_action |= EXTENDED_OPLOCK_GRANTED;
}
}
@@ -1216,16 +1078,8 @@ static int call_nt_transact_create(connection_struct *conn,
if(params == NULL)
return(ERROR(ERRDOS,ERRnomem));
- memset((char *)params,'\0',69);
-
p = params;
- if (smb_action & EXTENDED_OPLOCK_GRANTED)
- SCVAL(p,0, BATCH_OPLOCK_RETURN);
- else if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
- SCVAL(p,0, LEVEL_II_OPLOCK_RETURN);
- else
- SCVAL(p,0,NO_OPLOCK_RETURN);
-
+ SCVAL(p,0, (smb_action & EXTENDED_OPLOCK_GRANTED ? 1 : 0));
p += 2;
if (IS_IPC(conn)) {
SSVAL(p,0,pnum);
@@ -1268,7 +1122,7 @@ static int call_nt_transact_create(connection_struct *conn,
}
/* Send the required number of replies */
- send_nt_replies(inbuf, outbuf, bufsize, 0, params, 69, *ppdata, 0);
+ send_nt_replies(outbuf, bufsize, params, 69, *ppdata, 0);
return -1;
}
@@ -1305,7 +1159,6 @@ int reply_nttranss(connection_struct *conn,
/****************************************************************************
Reply to an NT transact rename command.
****************************************************************************/
-
static int call_nt_transact_rename(connection_struct *conn,
char *inbuf, char *outbuf, int length,
int bufsize,
@@ -1329,7 +1182,7 @@ static int call_nt_transact_rename(connection_struct *conn,
/*
* Rename was successful.
*/
- send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
+ send_nt_replies(outbuf, bufsize, NULL, 0, NULL, 0);
DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
fsp->fsp_name, new_name));
@@ -1341,18 +1194,6 @@ static int call_nt_transact_rename(connection_struct *conn,
}
/****************************************************************************
- This is the structure to keep the information needed to
- determine if a directory has changed.
-*****************************************************************************/
-
-typedef struct {
- time_t modify_time; /* Info from the directory we're monitoring. */
- time_t status_time; /* Info from the directory we're monitoring. */
- time_t total_time; /* Total time of all directory entries - don't care if it wraps. */
- unsigned int num_entries; /* Zero or the number of files in the directory. */
-} change_hash_data;
-
-/****************************************************************************
This is the structure to queue to implement NT change
notify. It consists of smb_size bytes stored from the
transact command (to keep the mid, tid etc around).
@@ -1363,9 +1204,9 @@ typedef struct {
ubi_slNode msg_next;
files_struct *fsp;
connection_struct *conn;
- uint32 flags;
time_t next_check_time;
- change_hash_data change_data;
+ time_t modify_time; /* Info from the directory we're monitoring. */
+ time_t status_time; /* Info from the directory we're monitoring. */
char request_buf[smb_size];
} change_notify_buf;
@@ -1406,92 +1247,8 @@ static void change_notify_reply_packet(char *inbuf, int error_class, uint32 erro
}
/****************************************************************************
- Create the hash we will use to determine if the contents changed.
-*****************************************************************************/
-
-static BOOL create_directory_notify_hash( change_notify_buf *cnbp, change_hash_data *change_data)
-{
- SMB_STRUCT_STAT st;
- files_struct *fsp = cnbp->fsp;
-
- memset((char *)change_data, '\0', sizeof(change_data));
-
- /*
- * Store the current timestamp on the directory we are monitoring.
- */
-
- if(dos_stat(fsp->fsp_name, &st) < 0) {
- DEBUG(0,("create_directory_notify_hash: Unable to stat name = %s. \
-Error was %s\n", fsp->fsp_name, strerror(errno) ));
- return False;
- }
-
- change_data->modify_time = st.st_mtime;
- change_data->status_time = st.st_ctime;
-
- /*
- * If we are to watch for changes that are only stored
- * in inodes of files, not in the directory inode, we must
- * scan the directory and produce a unique identifier with
- * which we can determine if anything changed. We use the
- * modify and change times from all the files in the
- * directory, added together (ignoring wrapping if it's
- * larger than the max time_t value).
- */
-
- if(cnbp->flags & (FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE)) {
- pstring full_name;
- char *p;
- char *fname;
- size_t remaining_len;
- size_t fullname_len;
- void *dp = OpenDir(cnbp->conn, fsp->fsp_name, True);
-
- if(dp == NULL) {
- DEBUG(0,("create_directory_notify_hash: Unable to open directory = %s. \
-Error was %s\n", fsp->fsp_name, strerror(errno) ));
- return False;
- }
-
- change_data->num_entries = 0;
-
- pstrcpy(full_name, fsp->fsp_name);
- pstrcat(full_name, "/");
-
- fullname_len = strlen(full_name);
- remaining_len = sizeof(full_name) - fullname_len - 1;
- p = &full_name[fullname_len];
-
- while ((fname = ReadDirName(dp))) {
- if(strequal(fname, ".") || strequal(fname, ".."))
- continue;
-
- change_data->num_entries++;
- safe_strcpy( p, fname, remaining_len);
-
- memset(&st, '\0', sizeof(st));
-
- /*
- * Do the stat - but ignore errors.
- */
-
- if(dos_stat(full_name, &st) < 0) {
- DEBUG(5,("create_directory_notify_hash: Unable to stat content file = %s. \
-Error was %s\n", fsp->fsp_name, strerror(errno) ));
- }
- change_data->total_time += (st.st_mtime + st.st_ctime);
- }
-
- CloseDir(dp);
- }
-
- return True;
-}
-
-/****************************************************************************
Delete entries by fnum from the change notify pending queue.
*****************************************************************************/
-
void remove_pending_change_notify_requests_by_fid(files_struct *fsp)
{
change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
@@ -1520,34 +1277,7 @@ static void remove_pending_change_notify_requests_by_mid(int mid)
while(cnbp != NULL) {
if(SVAL(cnbp->request_buf,smb_mid) == mid) {
- change_notify_reply_packet(cnbp->request_buf,0,0xC0000000 |NT_STATUS_CANCELLED);
- free((char *)ubi_slRemNext( &change_notify_queue, prev));
- cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
- continue;
- }
-
- prev = cnbp;
- cnbp = (change_notify_buf *)ubi_slNext(cnbp);
- }
-}
-
-/****************************************************************************
- Delete entries by filename and cnum from the change notify pending queue.
- Always send reply.
-*****************************************************************************/
-
-void remove_pending_change_notify_requests_by_filename(files_struct *fsp)
-{
- change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
- change_notify_buf *prev = NULL;
-
- while(cnbp != NULL) {
- /*
- * We know it refers to the same directory if the connection number and
- * the filename are identical.
- */
- if((cnbp->fsp->conn == fsp->conn) && strequal(cnbp->fsp->fsp_name,fsp->fsp_name)) {
- change_notify_reply_packet(cnbp->request_buf,0,0xC0000000 |NT_STATUS_CANCELLED);
+ change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_CANCELLED);
free((char *)ubi_slRemNext( &change_notify_queue, prev));
cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
continue;
@@ -1560,20 +1290,18 @@ void remove_pending_change_notify_requests_by_filename(files_struct *fsp)
/****************************************************************************
Process the change notify queue. Note that this is only called as root.
- Returns True if there are still outstanding change notify requests on the
- queue.
*****************************************************************************/
-BOOL process_pending_change_notify_queue(time_t t)
+void process_pending_change_notify_queue(time_t t)
{
change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
change_notify_buf *prev = NULL;
if(cnbp == NULL)
- return False;
+ return;
if(cnbp->next_check_time >= t)
- return True;
+ return;
/*
* It's time to check. Go through the queue and see if
@@ -1581,7 +1309,8 @@ BOOL process_pending_change_notify_queue(time_t t)
*/
while((cnbp != NULL) && (cnbp->next_check_time <= t)) {
- change_hash_data change_data;
+ SMB_STRUCT_STAT st;
+ files_struct *fsp = cnbp->fsp;
connection_struct *conn = cnbp->conn;
uint16 vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
SVAL(cnbp->request_buf,smb_uid);
@@ -1617,9 +1346,9 @@ BOOL process_pending_change_notify_queue(time_t t)
continue;
}
- if(!create_directory_notify_hash( cnbp, &change_data)) {
- DEBUG(0,("process_pending_change_notify_queue: Unable to create change data for \
-directory %s\n", cnbp->fsp->fsp_name ));
+ if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &st) < 0) {
+ DEBUG(0,("process_pending_change_notify_queue: Unable to stat directory %s. \
+Error was %s.\n", fsp->fsp_name, strerror(errno) ));
/*
* Remove the entry and return an error to the client.
*/
@@ -1630,12 +1359,13 @@ directory %s\n", cnbp->fsp->fsp_name ));
continue;
}
- if(memcmp( (char *)&cnbp->change_data, (char *)&change_data, sizeof(change_data))) {
+ if(cnbp->modify_time != st.st_mtime ||
+ cnbp->status_time != st.st_ctime) {
/*
* Remove the entry and return a change notify to the client.
*/
- DEBUG(5,("process_pending_change_notify_queue: directory name = %s changed.\n",
- cnbp->fsp->fsp_name ));
+ DEBUG(5,("process_pending_change_notify_queue: directory name = %s changed\n",
+ fsp->fsp_name ));
change_notify_reply_packet(cnbp->request_buf,0,NT_STATUS_NOTIFY_ENUM_DIR);
free((char *)ubi_slRemNext( &change_notify_queue, prev));
cnbp = (change_notify_buf *)(prev ? ubi_slNext(prev) : ubi_slFirst(&change_notify_queue));
@@ -1651,34 +1381,22 @@ directory %s\n", cnbp->fsp->fsp_name ));
prev = cnbp;
cnbp = (change_notify_buf *)ubi_slNext(cnbp);
}
-
- return (cnbp != NULL);
-}
-
-/****************************************************************************
- Return true if there are pending change notifies.
-****************************************************************************/
-
-BOOL change_notifies_pending(void)
-{
- change_notify_buf *cnbp = (change_notify_buf *)ubi_slFirst( &change_notify_queue );
- return (cnbp != NULL);
}
/****************************************************************************
Reply to a notify change - queue the request and
don't allow a directory to be opened.
****************************************************************************/
-
static int call_nt_transact_notify_change(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
+ char *inbuf, char *outbuf, int length,
int bufsize,
char **ppsetup,
- char **ppparams, char **ppdata)
+ char **ppparams, char **ppdata)
{
char *setup = *ppsetup;
files_struct *fsp;
change_notify_buf *cnbp;
+ SMB_STRUCT_STAT st;
fsp = file_fsp(setup,4);
@@ -1699,22 +1417,28 @@ static int call_nt_transact_notify_change(connection_struct *conn,
*/
if((cnbp = (change_notify_buf *)malloc(sizeof(change_notify_buf))) == NULL) {
- DEBUG(0,("call_nt_transact_notify_change: malloc fail !\n" ));
+ DEBUG(0,("call_nt_transact_notify_change: Malloc fail (2) !\n" ));
return -1;
}
- memset((char *)cnbp, '\0', sizeof(change_notify_buf));
+ /*
+ * Store the current timestamp on the directory we are monitoring.
+ */
+ if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &st) < 0) {
+ DEBUG(0,("call_nt_transact_notify_change: Unable to stat name = %s. \
+Error was %s\n", fsp->fsp_name, strerror(errno) ));
+ free((char *)cnbp);
+ return(UNIXERROR(ERRDOS,ERRbadfid));
+ }
+
memcpy(cnbp->request_buf, inbuf, smb_size);
cnbp->fsp = fsp;
cnbp->conn = conn;
- cnbp->next_check_time = time(NULL) + lp_change_notify_timeout();
- cnbp->flags = IVAL(setup, 0);
+ cnbp->modify_time = st.st_mtime;
+ cnbp->status_time = st.st_ctime;
- if(!create_directory_notify_hash( cnbp, &cnbp->change_data )) {
- free((char *)cnbp);
- return(UNIXERROR(ERRDOS,ERRbadfid));
- }
+ cnbp->next_check_time = time(NULL) + lp_change_notify_timeout();
/*
* Adding to the tail enables us to check only
@@ -1731,661 +1455,43 @@ name = %s\n", fsp->fsp_name ));
}
/****************************************************************************
- Map unix perms to NT.
-****************************************************************************/
-
-static SEC_ACCESS map_unix_perms( int *pacl_type, mode_t perm, int r_mask, int w_mask, int x_mask, BOOL is_directory)
-{
- SEC_ACCESS sa;
- uint32 nt_mask = 0;
-
- *pacl_type = SEC_ACE_TYPE_ACCESS_ALLOWED;
-
- if((perm & (r_mask|w_mask|x_mask)) == (r_mask|w_mask|x_mask)) {
- nt_mask = UNIX_ACCESS_RWX;
- } else if((perm & (r_mask|w_mask|x_mask)) == 0) {
- nt_mask = UNIX_ACCESS_NONE;
- } else {
- nt_mask |= (perm & r_mask) ? UNIX_ACCESS_R : 0;
- if(is_directory)
- nt_mask |= (perm & w_mask) ? UNIX_ACCESS_W : 0;
- else
- nt_mask |= (perm & w_mask) ? UNIX_ACCESS_W : 0;
- nt_mask |= (perm & x_mask) ? UNIX_ACCESS_X : 0;
- }
- init_sec_access(&sa,nt_mask);
- return sa;
-}
-
-/****************************************************************************
- Reply to query a security descriptor from an fsp. If it succeeds it allocates
- the space for the return elements and returns True.
-****************************************************************************/
-
-static size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
-{
- extern DOM_SID global_sam_sid;
- extern DOM_SID global_sid_World;
- SMB_STRUCT_STAT sbuf;
- SEC_ACE ace_list[6];
- DOM_SID owner_sid;
- DOM_SID group_sid;
- size_t sec_desc_size;
- SEC_ACL *psa = NULL;
- SEC_ACCESS owner_access;
- int owner_acl_type;
- SEC_ACCESS group_access;
- int grp_acl_type;
- SEC_ACCESS other_access;
- int other_acl_type;
- int num_acls = 0;
-
- *ppdesc = NULL;
-
- if(!lp_nt_acl_support()) {
- sid_copy( &owner_sid, &global_sid_World);
- sid_copy( &group_sid, &global_sid_World);
- } else {
-
- if(fsp->is_directory || fsp->fd_ptr == NULL) {
- if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
- return 0;
- }
- } else {
- if(fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
- return 0;
- }
- }
-
- /*
- * Get the owner, group and world SIDs.
- */
-
- sid_copy(&owner_sid, &global_sam_sid);
- sid_copy(&group_sid, &global_sam_sid);
- sid_append_rid(&owner_sid, pdb_uid_to_user_rid(sbuf.st_uid));
- sid_append_rid(&group_sid, pdb_gid_to_group_rid(sbuf.st_gid));
-
- /*
- * Create the generic 3 element UNIX acl.
- */
-
- owner_access = map_unix_perms(&owner_acl_type, sbuf.st_mode,
- S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
- group_access = map_unix_perms(&grp_acl_type, sbuf.st_mode,
- S_IRGRP, S_IWGRP, S_IXGRP, fsp->is_directory);
- other_access = map_unix_perms(&other_acl_type, sbuf.st_mode,
- S_IROTH, S_IWOTH, S_IXOTH, fsp->is_directory);
-
- if(owner_access.mask)
- init_sec_ace(&ace_list[num_acls++], &owner_sid, owner_acl_type,
- owner_access, 0);
-
- if(group_access.mask)
- init_sec_ace(&ace_list[num_acls++], &group_sid, grp_acl_type,
- group_access, 0);
-
- if(other_access.mask)
- init_sec_ace(&ace_list[num_acls++], &global_sid_World, other_acl_type,
- other_access, 0);
-
- if(fsp->is_directory) {
- /*
- * For directory ACLs we also add in the inherited permissions
- * ACE entries. These are the permissions a file would get when
- * being created in the directory.
- */
- mode_t mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name);
-
- owner_access = map_unix_perms(&owner_acl_type, mode,
- S_IRUSR, S_IWUSR, S_IXUSR, fsp->is_directory);
- group_access = map_unix_perms(&grp_acl_type, mode,
- S_IRGRP, S_IWGRP, S_IXGRP, fsp->is_directory);
- other_access = map_unix_perms(&other_acl_type, mode,
- S_IROTH, S_IWOTH, S_IXOTH, fsp->is_directory);
-
- if(owner_access.mask)
- init_sec_ace(&ace_list[num_acls++], &owner_sid, owner_acl_type,
- owner_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
-
- if(group_access.mask)
- init_sec_ace(&ace_list[num_acls++], &group_sid, grp_acl_type,
- group_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
-
- if(other_access.mask)
- init_sec_ace(&ace_list[num_acls++], &global_sid_World, other_acl_type,
- other_access, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
- }
-
- if(num_acls)
- if((psa = make_sec_acl( 3, num_acls, ace_list)) == NULL) {
- DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n"));
- return 0;
- }
- }
-
- *ppdesc = make_standard_sec_desc( &owner_sid, &group_sid, psa, &sec_desc_size);
-
- if(!*ppdesc) {
- DEBUG(0,("get_nt_acl: Unable to malloc space for security descriptor.\n"));
- sec_desc_size = 0;
- }
-
- free_sec_acl(&psa);
-
- return sec_desc_size;
-}
-
-/****************************************************************************
Reply to query a security descriptor - currently this is not implemented (it
- is planned to be though). Right now it just returns the same thing NT would
- when queried on a FAT filesystem. JRA.
+ is planned to be though).
****************************************************************************/
-
static int call_nt_transact_query_security_desc(connection_struct *conn,
- char *inbuf, char *outbuf,
- int length, int bufsize,
+ char *inbuf, char *outbuf,
+ int length,
+ int bufsize,
char **ppsetup, char **ppparams, char **ppdata)
{
- uint32 max_data_count = IVAL(inbuf,smb_nt_MaxDataCount);
- char *params = *ppparams;
- char *data = *ppdata;
- prs_struct pd;
- SEC_DESC *psd;
- size_t sec_desc_size;
-
- files_struct *fsp = file_fsp(params,0);
-
- if(!fsp)
- return(ERROR(ERRDOS,ERRbadfid));
-
- DEBUG(3,("call_nt_transact_query_security_desc: file = %s\n", fsp->fsp_name ));
-
- params = *ppparams = Realloc(*ppparams, 4);
- if(params == NULL)
- return(ERROR(ERRDOS,ERRnomem));
-
- /*
- * Get the permissions to return.
- */
-
- if((sec_desc_size = get_nt_acl(fsp, &psd)) == 0)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- DEBUG(3,("call_nt_transact_query_security_desc: sec_desc_size = %d.\n",(int)sec_desc_size));
-
- SIVAL(params,0,(uint32)sec_desc_size);
-
- if(max_data_count < sec_desc_size) {
-
- free_sec_desc(&psd);
-
- send_nt_replies(inbuf, outbuf, bufsize, 0xC0000000|NT_STATUS_BUFFER_TOO_SMALL,
- params, 4, *ppdata, 0);
- return -1;
- }
-
- /*
- * Allocate the data we will point this at.
- */
-
- data = *ppdata = Realloc(*ppdata, sec_desc_size);
- if(data == NULL) {
- free_sec_desc(&psd);
- return(ERROR(ERRDOS,ERRnomem));
- }
-
- memset(data, '\0', sec_desc_size);
-
- /*
- * Init the parse struct we will marshall into.
- */
-
- prs_init(&pd, 0, 4, MARSHALL);
-
- /*
- * Setup the prs_struct to point at the memory we just
- * allocated.
- */
-
- prs_give_memory( &pd, data, (uint32)sec_desc_size, False);
-
- /*
- * Finally, linearize into the outgoing buffer.
- */
-
- if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
- free_sec_desc(&psd);
- DEBUG(0,("call_nt_transact_query_security_desc: Error in marshalling \
-security descriptor.\n"));
- /*
- * Return access denied for want of a better error message..
- */
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- /*
- * Now we can delete the security descriptor.
- */
-
- free_sec_desc(&psd);
-
- send_nt_replies(inbuf, outbuf, bufsize, 0, params, 4, data, (int)sec_desc_size);
- return -1;
-}
-
-/****************************************************************************
- Validate a SID.
-****************************************************************************/
-
-static BOOL validate_unix_sid( DOM_SID *psid, uint32 *prid, DOM_SID *sd_sid)
-{
- extern DOM_SID global_sam_sid;
- DOM_SID sid;
-
- if(!sd_sid) {
- DEBUG(5,("validate_unix_sid: sid missing.\n"));
- return False;
- }
-
- sid_copy(psid, sd_sid);
- sid_copy(&sid, sd_sid);
-
- if(!sid_split_rid(&sid, prid)) {
- DEBUG(5,("validate_unix_sid: cannot get RID from sid.\n"));
- return False;
- }
-
- if(!sid_equal( &sid, &global_sam_sid)) {
- DEBUG(5,("validate_unix_sid: sid is not ours.\n"));
- return False;
- }
-
- return True;
-}
-
-/****************************************************************************
- Map NT perms to UNIX.
-****************************************************************************/
-
-#define FILE_SPECIFIC_READ_BITS (FILE_READ_DATA|FILE_READ_EA|FILE_READ_ATTRIBUTES)
-#define FILE_SPECIFIC_WRITE_BITS (FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_WRITE_EA|FILE_WRITE_ATTRIBUTES)
-#define FILE_SPECIFIC_EXECUTE_BITS (FILE_EXECUTE)
-
-static mode_t map_nt_perms( SEC_ACCESS sec_access, int type)
-{
- mode_t mode = 0;
-
- switch(type) {
- case S_IRUSR:
- if(sec_access.mask & GENERIC_ALL_ACCESS)
- mode = S_IRUSR|S_IWUSR|S_IXUSR;
- else {
- mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRUSR : 0;
- mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWUSR : 0;
- mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXUSR : 0;
- }
- break;
- case S_IRGRP:
- if(sec_access.mask & GENERIC_ALL_ACCESS)
- mode = S_IRGRP|S_IWGRP|S_IXGRP;
- else {
- mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IRGRP : 0;
- mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWGRP : 0;
- mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXGRP : 0;
- }
- break;
- case S_IROTH:
- if(sec_access.mask & GENERIC_ALL_ACCESS)
- mode = S_IROTH|S_IWOTH|S_IXOTH;
- else {
- mode |= (sec_access.mask & (GENERIC_READ_ACCESS|FILE_SPECIFIC_READ_BITS)) ? S_IROTH : 0;
- mode |= (sec_access.mask & (GENERIC_WRITE_ACCESS|FILE_SPECIFIC_WRITE_BITS)) ? S_IWOTH : 0;
- mode |= (sec_access.mask & (GENERIC_EXECUTE_ACCESS|FILE_SPECIFIC_EXECUTE_BITS)) ? S_IXOTH : 0;
- }
- break;
- }
-
- return mode;
-}
-
-/****************************************************************************
- Unpack a SEC_DESC into a owner, group and set of UNIX permissions.
-****************************************************************************/
-
-static BOOL unpack_nt_permissions(uid_t *puser, gid_t *pgrp, mode_t *pmode, uint32 security_info_sent,
- SEC_DESC *psd, BOOL is_directory)
-{
- extern DOM_SID global_sid_World;
- DOM_SID owner_sid;
- DOM_SID grp_sid;
- uint32 owner_rid;
- uint32 grp_rid;
- SEC_ACL *dacl = psd->dacl;
- int i;
-
- *pmode = 0;
- *puser = (uid_t)-1;
- *pgrp = (gid_t)-1;
-
- if(security_info_sent == 0) {
- DEBUG(0,("unpack_unix_permissions: no security info sent !\n"));
- return False;
- }
-
- /*
- * Validate the owner and group SID's.
- */
-
- memset(&owner_sid, '\0', sizeof(owner_sid));
- memset(&grp_sid, '\0', sizeof(grp_sid));
-
- DEBUG(5,("unpack_unix_permissions: validating owner_sid.\n"));
-
- /*
- * Don't immediately fail if the owner sid cannot be validated.
- * This may be a group chown only set.
- */
-
- if(!validate_unix_sid( &owner_sid, &owner_rid, psd->owner_sid))
- DEBUG(3,("unpack_unix_permissions: unable to validate owner sid.\n"));
- else if(security_info_sent & OWNER_SECURITY_INFORMATION)
- *puser = pdb_user_rid_to_uid(owner_rid);
-
- /*
- * Don't immediately fail if the group sid cannot be validated.
- * This may be an owner chown only set.
- */
-
- if(!validate_unix_sid( &grp_sid, &grp_rid, psd->grp_sid))
- DEBUG(3,("unpack_unix_permissions: unable to validate group sid.\n"));
- else if(security_info_sent & GROUP_SECURITY_INFORMATION)
- *pgrp = pdb_user_rid_to_gid(grp_rid);
-
- /*
- * If no DACL then this is a chown only security descriptor.
- */
-
- if(!(security_info_sent & DACL_SECURITY_INFORMATION) || !dacl) {
- *pmode = 0;
- return True;
- }
-
- /*
- * Now go through the DACL and ensure that
- * any owner/group sids match.
- */
-
- for(i = 0; i < dacl->num_aces; i++) {
- DOM_SID ace_sid;
- SEC_ACE *psa = &dacl->ace_list[i];
-
- if((psa->type != SEC_ACE_TYPE_ACCESS_ALLOWED) &&
- (psa->type != SEC_ACE_TYPE_ACCESS_DENIED)) {
- DEBUG(3,("unpack_unix_permissions: unable to set anything but an ALLOW or DENY ACE.\n"));
- return False;
- }
-
- /*
- * Ignore or remove bits we don't care about on a directory ACE.
- */
-
- if(is_directory) {
- if(psa->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
- DEBUG(3,("unpack_unix_permissions: ignoring inherit only ACE.\n"));
- continue;
- }
-
- psa->flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT);
- }
-
- if(psa->flags != 0) {
- DEBUG(1,("unpack_unix_permissions: unable to set ACE flags (%x).\n",
- (unsigned int)psa->flags));
- return False;
- }
-
- /*
- * The security mask may be UNIX_ACCESS_NONE which should map into
- * no permissions (we overload the WRITE_OWNER bit for this) or it
- * should be one of the ALL/EXECUTE/READ/WRITE bits. Arrange for this
- * to be so. Any other bits override the UNIX_ACCESS_NONE bit.
- */
-
- psa->info.mask &= (GENERIC_ALL_ACCESS|GENERIC_EXECUTE_ACCESS|GENERIC_WRITE_ACCESS|
- GENERIC_READ_ACCESS|UNIX_ACCESS_NONE|FILE_ALL_ATTRIBUTES);
-
- if(psa->info.mask != UNIX_ACCESS_NONE)
- psa->info.mask &= ~UNIX_ACCESS_NONE;
-
- sid_copy(&ace_sid, &psa->sid);
-
- if(sid_equal(&ace_sid, &owner_sid)) {
- /*
- * Map the desired permissions into owner perms.
- */
-
- if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
- *pmode |= map_nt_perms( psa->info, S_IRUSR);
- else
- *pmode &= ~(map_nt_perms( psa->info, S_IRUSR));
-
- } else if( sid_equal(&ace_sid, &grp_sid)) {
- /*
- * Map the desired permissions into group perms.
- */
-
- if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
- *pmode |= map_nt_perms( psa->info, S_IRGRP);
- else
- *pmode &= ~(map_nt_perms( psa->info, S_IRGRP));
-
- } else if( sid_equal(&ace_sid, &global_sid_World)) {
- /*
- * Map the desired permissions into other perms.
- */
-
- if(psa->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
- *pmode |= map_nt_perms( psa->info, S_IROTH);
- else
- *pmode &= ~(map_nt_perms( psa->info, S_IROTH));
+ static BOOL logged_message = False;
- } else {
- DEBUG(0,("unpack_unix_permissions: unknown SID used in ACL.\n"));
- return False;
- }
+ if(!logged_message) {
+ DEBUG(0,("call_nt_transact_query_security_desc: Currently not implemented.\n"));
+ logged_message = True; /* Only print this once... */
}
- return True;
+ return(ERROR(ERRSRV,ERRnosupport));
}
-
+
/****************************************************************************
- Reply to set a security descriptor. Map to UNIX perms.
+ Reply to set a security descriptor - currently this is not implemented (it
+ is planned to be though).
****************************************************************************/
-
static int call_nt_transact_set_security_desc(connection_struct *conn,
- char *inbuf, char *outbuf, int length,
- int bufsize, char **ppsetup,
- char **ppparams, char **ppdata)
+ char *inbuf, char *outbuf,
+ int length,
+ int bufsize,
+ char **ppsetup,
+ char **ppparams, char **ppdata)
{
- uint32 total_parameter_count = IVAL(inbuf, smb_nts_TotalParameterCount);
- char *params= *ppparams;
- char *data = *ppdata;
- prs_struct pd;
- SEC_DESC *psd = NULL;
- uint32 total_data_count = (uint32)IVAL(inbuf, smb_nts_TotalDataCount);
- uid_t user = (uid_t)-1;
- gid_t grp = (gid_t)-1;
- mode_t perms = 0;
- SMB_STRUCT_STAT sbuf;
- files_struct *fsp = NULL;
- uint32 security_info_sent = 0;
- BOOL got_dacl = False;
-
- if(!lp_nt_acl_support())
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- if(total_parameter_count < 8)
- return(ERROR(ERRDOS,ERRbadfunc));
-
- if((fsp = file_fsp(params,0)) == NULL)
- return(ERROR(ERRDOS,ERRbadfid));
-
- security_info_sent = IVAL(params,4);
-
- DEBUG(3,("call_nt_transact_set_security_desc: file = %s, sent 0x%x\n", fsp->fsp_name,
- (unsigned int)security_info_sent ));
-
- /*
- * Init the parse struct we will unmarshall from.
- */
-
- prs_init(&pd, 0, 4, UNMARSHALL);
-
- /*
- * Setup the prs_struct to point at the memory we just
- * allocated.
- */
-
- prs_give_memory( &pd, data, total_data_count, False);
-
- /*
- * Finally, unmarshall from the data buffer.
- */
-
- if(!sec_io_desc( "sd data", &psd, &pd, 1)) {
- free_sec_desc(&psd);
- DEBUG(0,("call_nt_transact_set_security_desc: Error in unmarshalling \
-security descriptor.\n"));
- /*
- * Return access denied for want of a better error message..
- */
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- /*
- * Unpack the user/group/world id's and permissions.
- */
-
- if(!unpack_nt_permissions( &user, &grp, &perms, security_info_sent, psd, fsp->is_directory)) {
- free_sec_desc(&psd);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- if (psd->dacl != NULL)
- got_dacl = True;
-
- free_sec_desc(&psd);
-
- /*
- * Get the current state of the file.
- */
-
- if(fsp->is_directory) {
- if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
- } else {
-
- int ret;
-
- if(fsp->fd_ptr == NULL)
- ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf);
- else
- ret = conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf);
-
- if(ret != 0) {
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
- }
-
- /*
- * Do we need to chown ?
- */
-
- if((user != (uid_t)-1 || grp != (uid_t)-1) && (sbuf.st_uid != user || sbuf.st_gid != grp)) {
-
- DEBUG(3,("call_nt_transact_set_security_desc: chown %s. uid = %u, gid = %u.\n",
- fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
-
- if(dos_chown( fsp->fsp_name, user, grp) == -1) {
- DEBUG(3,("call_nt_transact_set_security_desc: chown %s, %u, %u failed. Error = %s.\n",
- fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- /*
- * Recheck the current state of the file, which may have changed.
- * (suid/sgid bits, for instance)
- */
-
- if(fsp->is_directory) {
- if(dos_stat(fsp->fsp_name, &sbuf) != 0) {
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
- } else {
-
- int ret;
-
- if(fsp->fd_ptr == NULL)
- ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf);
- else
- ret = conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf);
-
- if(ret != 0)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
- }
-
- /*
- * Only change security if we got a DACL.
- */
-
- if((security_info_sent & DACL_SECURITY_INFORMATION) && got_dacl) {
-
- /*
- * Check to see if we need to change anything.
- * Enforce limits on modified bits *only*. Don't enforce masks
- * on bits not changed by the user.
- */
-
- if(fsp->is_directory) {
-
- perms &= (lp_dir_security_mask(SNUM(conn)) | sbuf.st_mode);
- perms |= (lp_force_dir_security_mode(SNUM(conn)) & ( perms ^ sbuf.st_mode ));
-
- } else {
-
- perms &= (lp_security_mask(SNUM(conn)) | sbuf.st_mode);
- perms |= (lp_force_security_mode(SNUM(conn)) & ( perms ^ sbuf.st_mode ));
-
- }
-
- /*
- * Preserve special bits.
- */
-
- perms |= (sbuf.st_mode & ~0777);
-
- /*
- * Do we need to chmod ?
- */
-
- if(sbuf.st_mode != perms) {
-
- DEBUG(3,("call_nt_transact_set_security_desc: chmod %s. perms = 0%o.\n",
- fsp->fsp_name, (unsigned int)perms ));
+ static BOOL logged_message = False;
- if(conn->vfs_ops.chmod(dos_to_unix(fsp->fsp_name, False), perms) == -1) {
- DEBUG(3,("call_nt_transact_set_security_desc: chmod %s, 0%o failed. Error = %s.\n",
- fsp->fsp_name, (unsigned int)perms, strerror(errno) ));
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
- }
+ if(!logged_message) {
+ DEBUG(0,("call_nt_transact_set_security_desc: Currently not implemented.\n"));
+ logged_message = True; /* Only print this once... */
}
-
- send_nt_replies(inbuf, outbuf, bufsize, 0, NULL, 0, NULL, 0);
- return -1;
+ return(ERROR(ERRSRV,ERRnosupport));
}
/****************************************************************************
@@ -2572,6 +1678,7 @@ due to being in oplock break state.\n" ));
length, bufsize,
&setup, &params, &data);
break;
+
default:
/* Error in request */
DEBUG(0,("reply_nttrans: Unknown request %d in nttrans call\n", function_code));
diff --git a/source/smbd/open.c b/source/smbd/open.c
index 6352233dbcf..d63de45c7e0 100644
--- a/source/smbd/open.c
+++ b/source/smbd/open.c
@@ -25,7 +25,7 @@ extern int DEBUGLEVEL;
extern pstring sesssetup_user;
extern uint16 global_oplock_port;
-extern BOOL global_client_failed_oplock_break;
+
/****************************************************************************
fd support routines - attempt to do a dos_open
@@ -71,7 +71,8 @@ static int fd_attempt_open(struct connection_struct *conn, char *fname,
char tmp = p[max_len];
p[max_len] = '\0';
- if ((fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode)) == -1)
+ if ((fd = conn->vfs_ops.open(dos_to_unix(fname,False),flags,mode))
+ == -1)
p[max_len] = tmp;
}
}
@@ -83,7 +84,6 @@ static int fd_attempt_open(struct connection_struct *conn, char *fname,
Cache a uid_t currently with this file open. This is an optimization only
used when multiple sessionsetup's have been done to one smbd.
****************************************************************************/
-
void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
{
if(fd_ptr->uid_cache_count >= sizeof(fd_ptr->uid_users_cache)/sizeof(uid_t))
@@ -95,7 +95,6 @@ void fd_add_to_uid_cache(file_fd_struct *fd_ptr, uid_t u)
Remove a uid_t that currently has this file open. This is an optimization only
used when multiple sessionsetup's have been done to one smbd.
****************************************************************************/
-
static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
{
int i;
@@ -113,7 +112,6 @@ static void fd_remove_from_uid_cache(file_fd_struct *fd_ptr, uid_t u)
Check if a uid_t that currently has this file open is present. This is an
optimization only used when multiple sessionsetup's have been done to one smbd.
****************************************************************************/
-
static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
{
int i;
@@ -123,15 +121,14 @@ static BOOL fd_is_in_uid_cache(file_fd_struct *fd_ptr, uid_t u)
return False;
}
+
/****************************************************************************
fd support routines - attempt to re-open an already open fd as O_RDWR.
Save the already open fd (we cannot close due to POSIX file locking braindamage.
****************************************************************************/
-
-static void fd_attempt_reopen(char *fname, mode_t mode, files_struct *fsp)
+static void fd_attempt_reopen(char *fname, mode_t mode, file_fd_struct *fd_ptr)
{
- int fd = fsp->conn->vfs_ops.open(dos_to_unix(fname, False), O_RDWR, mode);
- file_fd_struct *fd_ptr = fsp->fd_ptr;
+ int fd = dos_open( fname, O_RDWR, mode);
if(fd == -1)
return;
@@ -149,21 +146,18 @@ static void fd_attempt_reopen(char *fname, mode_t mode, files_struct *fsp)
fd support routines - attempt to close the file referenced by this fd.
Decrements the ref_count and returns it.
****************************************************************************/
-uint16 fd_attempt_close(files_struct *fsp, int *err_ret)
+uint16 fd_attempt_close(files_struct *fsp)
{
extern struct current_user current_user;
- file_fd_struct *fd_ptr;
+ file_fd_struct *fd_ptr = fsp->fd_ptr;
uint16 ret_ref;
- *err_ret = 0;
-
- if ((fsp == NULL) || (fsp->fd_ptr == NULL)) {
+ if (fd_ptr != NULL) {
+ ret_ref = fd_ptr->ref_count;
+ } else {
return 0;
}
- fd_ptr = fsp->fd_ptr;
- ret_ref = fd_ptr->ref_count;
-
DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %.0f, open_flags = %d, ref_count = %d.\n",
fd_ptr->fd, (unsigned int)fd_ptr->dev, (double)fd_ptr->inode,
fd_ptr->real_open_flags,
@@ -175,26 +169,12 @@ uint16 fd_attempt_close(files_struct *fsp, int *err_ret)
ret_ref = fd_ptr->ref_count;
if(fd_ptr->ref_count == 0) {
-
- if(fd_ptr->fd != -1) {
- if(fsp->conn->vfs_ops.close(fd_ptr->fd) < 0)
- *err_ret = errno;
- }
-
- if(fd_ptr->fd_readonly != -1) {
- if(fsp->conn->vfs_ops.close(fd_ptr->fd_readonly) < 0) {
- if(*err_ret == 0)
- *err_ret = errno;
- }
- }
-
- if(fd_ptr->fd_writeonly != -1) {
- if(fsp->conn->vfs_ops.close(fd_ptr->fd_writeonly) < 0) {
- if(*err_ret == 0)
- *err_ret = errno;
- }
- }
-
+ if(fd_ptr->fd != -1)
+ fsp->conn->vfs_ops.close(fd_ptr->fd);
+ if(fd_ptr->fd_readonly != -1)
+ fsp->conn->vfs_ops.close(fd_ptr->fd_readonly);
+ if(fd_ptr->fd_writeonly != -1)
+ fsp->conn->vfs_ops.close(fd_ptr->fd_writeonly);
/*
* Delete this fd_ptr.
*/
@@ -203,7 +183,7 @@ uint16 fd_attempt_close(files_struct *fsp, int *err_ret)
fd_remove_from_uid_cache(fd_ptr, (uid_t)current_user.uid);
}
- return ret_ref;
+ return ret_ref;
}
/****************************************************************************
@@ -219,16 +199,8 @@ static BOOL check_access_allowed_for_current_user(struct connection_struct
{
pid_t child_pid;
- /*
- * We need to temporarily stop CatchChild from eating
- * SIGCLD signals as it also eats the exit status code. JRA.
- */
-
- CatchChildLeaveStatus();
-
if((child_pid = fork()) < 0) {
DEBUG(0,("check_access_allowed_for_current_user: fork failed.\n"));
- CatchChild();
return False;
}
@@ -238,23 +210,11 @@ static BOOL check_access_allowed_for_current_user(struct connection_struct
*/
pid_t wpid;
int status_code;
-
- while ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
- if(errno == EINTR) {
- errno = 0;
- continue;
- }
- DEBUG(0,("check_access_allowed_for_current_user: The process \
-is no longer waiting ! Error = %s\n", strerror(errno) ));
- CatchChild();
+ if ((wpid = sys_waitpid(child_pid, &status_code, 0)) < 0) {
+ DEBUG(0,("check_access_allowed_for_current_user: The process is no longer waiting!\n"));
return(False);
}
- /*
- * Go back to ignoring children.
- */
- CatchChild();
-
if (child_pid != wpid) {
DEBUG(0,("check_access_allowed_for_current_user: We were waiting for the wrong process ID\n"));
return(False);
@@ -290,7 +250,7 @@ is no longer waiting ! Error = %s\n", strerror(errno) ));
/* Access denied. */
_exit(EACCES);
}
- conn->vfs_ops.close(fd);
+ close(fd);
DEBUG(9,("check_access_allowed_for_current_user: Child - returning ok.\n"));
_exit(0);
}
@@ -301,12 +261,11 @@ is no longer waiting ! Error = %s\n", strerror(errno) ));
/****************************************************************************
check a filename for the pipe string
****************************************************************************/
-
static void check_for_pipe(char *fname)
{
/* special case of pipe opens */
char s[10];
- StrnCpy(s,fname,sizeof(s)-1);
+ StrnCpy(s,fname,9);
strlower(s);
if (strstr(s,"pipe/")) {
DEBUG(3,("Rejecting named pipe open for %s\n",fname));
@@ -318,7 +277,6 @@ static void check_for_pipe(char *fname)
/****************************************************************************
open a file
****************************************************************************/
-
static void open_file(files_struct *fsp,connection_struct *conn,
char *fname1,int flags,mode_t mode, SMB_STRUCT_STAT *sbuf)
{
@@ -330,7 +288,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
fsp->open = False;
fsp->fd_ptr = 0;
- fsp->oplock_type = NO_OPLOCK;
+ fsp->granted_oplock = False;
errno = EPERM;
pstrcpy(fname,fname1);
@@ -347,7 +305,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
* JRA.
*/
- if (!CAN_WRITE(conn) && !conn->printer) {
+ if (conn->read_only && !conn->printer) {
/* It's a read-only share - fail if we wanted to write. */
if(accmode != O_RDONLY) {
DEBUG(3,("Permission denied opening %s\n",fname));
@@ -439,7 +397,7 @@ static void open_file(files_struct *fsp,connection_struct *conn,
* between the last open and now.
*/
if(fd_ptr->real_open_flags != O_RDWR)
- fd_attempt_reopen(fname, mode, fsp);
+ fd_attempt_reopen(fname, mode, fd_ptr);
/*
* Ensure that if we wanted write access
@@ -501,11 +459,10 @@ static void open_file(files_struct *fsp,connection_struct *conn,
pstrcpy(dname,fname);
p = strrchr(dname,'/');
if (p) *p = 0;
- if (conn->vfs_ops.disk_free(dos_to_unix(dname,False),False,&dum1,&dum2,&dum3) <
+ if (conn->vfs_ops.disk_free(dos_to_unix(dname,False),&dum1,&dum2,&dum3) <
(SMB_BIG_UINT)lp_minprintspace(SNUM(conn))) {
- int err;
- if(fd_attempt_close(fsp, &err) == 0)
- conn->vfs_ops.unlink(dos_to_unix(fname, False));
+ if(fd_attempt_close(fsp) == 0)
+ conn->vfs_ops.unlink(dos_to_unix(fname,False));
fsp->fd_ptr = 0;
errno = ENOSPC;
return;
@@ -514,11 +471,10 @@ static void open_file(files_struct *fsp,connection_struct *conn,
if (fd_ptr->fd < 0)
{
- int err;
DEBUG(3,("Error opening file %s (%s) (flags=%d)\n",
fname,strerror(errno),flags));
/* Ensure the ref_count is decremented. */
- fd_attempt_close(fsp,&err);
+ fd_attempt_close(fsp);
check_for_pipe(fname);
return;
}
@@ -528,12 +484,11 @@ static void open_file(files_struct *fsp,connection_struct *conn,
if(sbuf == 0) {
/* Do the fstat */
if(conn->vfs_ops.fstat(fd_ptr->fd, &statbuf) == -1) {
- int err;
/* Error - backout !! */
DEBUG(3,("Error doing fstat on fd %d, file %s (%s)\n",
fd_ptr->fd, fname,strerror(errno)));
/* Ensure the ref_count is decremented. */
- fd_attempt_close(fsp,&err);
+ fd_attempt_close(fsp);
return;
}
sbuf = &statbuf;
@@ -547,21 +502,21 @@ static void open_file(files_struct *fsp,connection_struct *conn,
conn->num_files_open++;
fsp->mode = sbuf->st_mode;
GetTimeOfDay(&fsp->open_time);
- fsp->vuid = current_user.vuid;
+ fsp->vuid = current_user.key.vuid;
fsp->size = 0;
fsp->pos = -1;
fsp->open = True;
+ fsp->mmap_ptr = NULL;
+ fsp->mmap_size = 0;
fsp->can_lock = True;
fsp->can_read = ((flags & O_WRONLY)==0);
fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0);
fsp->share_mode = 0;
fsp->print_file = conn->printer;
fsp->modified = False;
- fsp->oplock_type = NO_OPLOCK;
- fsp->sent_oplock_break = NO_BREAK_SENT;
+ fsp->granted_oplock = False;
+ fsp->sent_oplock_break = False;
fsp->is_directory = False;
- fsp->stat_open = False;
- fsp->directory_delete_on_close = False;
fsp->conn = conn;
/*
* Note that the file name here is the *untranslated* name
@@ -572,7 +527,6 @@ static void open_file(files_struct *fsp,connection_struct *conn,
*/
string_set(&fsp->fsp_name,fname);
fsp->wbmpx_ptr = NULL;
- fsp->wcp = NULL; /* Write cache pointer. */
/*
* If the printer is marked as postscript output a leading
@@ -595,19 +549,47 @@ static void open_file(files_struct *fsp,connection_struct *conn,
}
/****************************************************************************
+ If it's a read-only file, and we were compiled with mmap enabled,
+ try and mmap the file. This is split out from open_file() above
+ as mmap'ing the file can cause the kernel reference count to
+ be incremented, which can cause kernel oplocks to be refused.
+ Splitting this call off allows the kernel oplock to be granted, then
+ the file mmap'ed.
+****************************************************************************/
+
+static void mmap_open_file(files_struct *fsp)
+{
+#if WITH_MMAP
+ /* mmap it if read-only */
+ if (!fsp->can_write) {
+ fsp->mmap_size = dos_file_size(fsp->fsp_name);
+ if (fsp->mmap_size < MAX_MMAP_SIZE) {
+ fsp->mmap_ptr = (char *)sys_mmap(NULL,fsp->mmap_size,
+ PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,(SMB_OFF_T)0);
+
+ if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) {
+ DEBUG(3,("Failed to mmap() %s - %s\n",
+ fsp->fsp_name,strerror(errno)));
+ fsp->mmap_ptr = NULL;
+ }
+ }
+ }
+#endif
+}
+
+/****************************************************************************
C. Hoch 11/22/95
Helper for open_file_shared.
Truncate a file after checking locking; close file if locked.
**************************************************************************/
-
-static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, int token,
+static void truncate_unless_locked(files_struct *fsp, connection_struct *conn,
BOOL *share_locked)
{
if (fsp->can_write){
SMB_OFF_T mask2 = ((SMB_OFF_T)0x3) << (SMB_OFF_T_BITS-4);
SMB_OFF_T mask = (mask2<<2);
- if (is_locked(fsp,conn,~mask,0,WRITE_LOCK)){
+ if (is_locked(fsp,conn,~mask,0,F_WRLCK)){
/* If share modes are in force for this connection we
have the share entry locked. Unlock it before closing. */
if (*share_locked && lp_share_modes(SNUM(conn)))
@@ -626,121 +608,63 @@ static void truncate_unless_locked(files_struct *fsp, connection_struct *conn, i
}
-/*******************************************************************
-return True if the filename is one of the special executable types
-********************************************************************/
-static BOOL is_executable(char *fname)
-{
- if ((fname = strrchr(fname,'.'))) {
- if (strequal(fname,".com") ||
- strequal(fname,".dll") ||
- strequal(fname,".exe") ||
- strequal(fname,".sym")) {
- return True;
- }
- }
- return False;
-}
-
enum {AFAIL,AREAD,AWRITE,AALL};
/*******************************************************************
reproduce the share mode access table
-this is horrendoously complex, and really can't be justified on any
-rational grounds except that this is _exactly_ what NT does. See
-the DENY1 and DENY2 tests in smbtorture for a comprehensive set of
-test routines.
********************************************************************/
static int access_table(int new_deny,int old_deny,int old_mode,
- BOOL same_pid, BOOL isexe)
+ int share_pid,char *fname)
{
- if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
+ if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL);
+
+ if (new_deny == DENY_DOS || old_deny == DENY_DOS) {
+ int pid = getpid();
+ if (old_deny == new_deny && share_pid == pid)
+ return(AALL);
+
+ if (old_mode == 0) return(AREAD);
+
+ /* the new smbpub.zip spec says that if the file extension is
+ .com, .dll, .exe or .sym then allow the open. I will force
+ it to read-only as this seems sensible although the spec is
+ a little unclear on this. */
+ if ((fname = strrchr(fname,'.'))) {
+ if (strequal(fname,".com") ||
+ strequal(fname,".dll") ||
+ strequal(fname,".exe") ||
+ strequal(fname,".sym"))
+ return(AREAD);
+ }
- if (same_pid) {
- if (isexe && old_mode == DOS_OPEN_RDONLY &&
- old_deny == DENY_DOS && new_deny == DENY_READ) {
- return AFAIL;
- }
- if (!isexe && old_mode == DOS_OPEN_RDONLY &&
- old_deny == DENY_DOS && new_deny == DENY_DOS) {
- return AREAD;
- }
- if (new_deny == DENY_FCB && old_deny == DENY_DOS) {
- if (isexe) return AFAIL;
- if (old_mode == DOS_OPEN_RDONLY) return AFAIL;
- return AALL;
- }
- if (old_mode == DOS_OPEN_RDONLY && old_deny == DENY_DOS) {
- if (new_deny == DENY_FCB || new_deny == DENY_READ) {
- if (isexe) return AREAD;
- return AFAIL;
- }
- }
- if (old_deny == DENY_FCB) {
- if (new_deny == DENY_DOS || new_deny == DENY_FCB) return AALL;
- return AFAIL;
- }
- }
+ return(AFAIL);
+ }
- if (old_deny == DENY_DOS || new_deny == DENY_DOS ||
- old_deny == DENY_FCB || new_deny == DENY_FCB) {
- if (isexe) {
- if (old_deny == DENY_FCB || new_deny == DENY_FCB) {
- return AFAIL;
- }
- if (old_deny == DENY_DOS) {
- if (new_deny == DENY_READ &&
- (old_mode == DOS_OPEN_RDONLY ||
- old_mode == DOS_OPEN_RDWR)) {
- return AFAIL;
- }
- if (new_deny == DENY_WRITE &&
- (old_mode == DOS_OPEN_WRONLY ||
- old_mode == DOS_OPEN_RDWR)) {
- return AFAIL;
- }
- return AALL;
- }
- if (old_deny == DENY_NONE) return AALL;
- if (old_deny == DENY_READ) return AWRITE;
- if (old_deny == DENY_WRITE) return AREAD;
- }
- /* it isn't a exe, dll, sym or com file */
- if (old_deny == new_deny && same_pid)
- return(AALL);
-
- if (old_deny == DENY_READ || new_deny == DENY_READ) return AFAIL;
- if (old_mode == DOS_OPEN_RDONLY) return(AREAD);
-
- return(AFAIL);
- }
-
- switch (new_deny)
- {
- case DENY_WRITE:
- if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_RDONLY) return(AREAD);
- if (old_deny==DENY_READ && old_mode==DOS_OPEN_RDONLY) return(AWRITE);
- if (old_deny==DENY_NONE && old_mode==DOS_OPEN_RDONLY) return(AALL);
- return(AFAIL);
- case DENY_READ:
- if (old_deny==DENY_WRITE && old_mode==DOS_OPEN_WRONLY) return(AREAD);
- if (old_deny==DENY_READ && old_mode==DOS_OPEN_WRONLY) return(AWRITE);
- if (old_deny==DENY_NONE && old_mode==DOS_OPEN_WRONLY) return(AALL);
- return(AFAIL);
- case DENY_NONE:
- if (old_deny==DENY_WRITE) return(AREAD);
- if (old_deny==DENY_READ) return(AWRITE);
- if (old_deny==DENY_NONE) return(AALL);
- return(AFAIL);
- }
- return(AFAIL);
+ switch (new_deny)
+ {
+ case DENY_WRITE:
+ if (old_deny==DENY_WRITE && old_mode==0) return(AREAD);
+ if (old_deny==DENY_READ && old_mode==0) return(AWRITE);
+ if (old_deny==DENY_NONE && old_mode==0) return(AALL);
+ return(AFAIL);
+ case DENY_READ:
+ if (old_deny==DENY_WRITE && old_mode==1) return(AREAD);
+ if (old_deny==DENY_READ && old_mode==1) return(AWRITE);
+ if (old_deny==DENY_NONE && old_mode==1) return(AALL);
+ return(AFAIL);
+ case DENY_NONE:
+ if (old_deny==DENY_WRITE) return(AREAD);
+ if (old_deny==DENY_READ) return(AWRITE);
+ if (old_deny==DENY_NONE) return(AALL);
+ return(AFAIL);
+ }
+ return(AFAIL);
}
/****************************************************************************
check if we can open a file with a share mode
****************************************************************************/
-
static int check_share_mode( share_mode_entry *share, int deny_mode,
char *fname,
BOOL fcbopen, int *flags)
@@ -762,18 +686,29 @@ static int check_share_mode( share_mode_entry *share, int deny_mode,
return False;
}
+ if (old_deny_mode > 4 || old_open_mode > 2)
+ {
+ DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n",
+ deny_mode,old_deny_mode,old_open_mode,fname));
+
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadshare;
+
+ return False;
+ }
+
{
int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode,
- (share->pid == getpid()),is_executable(fname));
+ share->pid,fname);
if ((access_allowed == AFAIL) ||
(!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) ||
- (access_allowed == AREAD && *flags != O_RDONLY) ||
- (access_allowed == AWRITE && *flags != O_WRONLY))
+ (access_allowed == AREAD && *flags == O_WRONLY) ||
+ (access_allowed == AWRITE && *flags == O_RDONLY))
{
DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s,fcbopen = %d, flags = %d) = %d\n",
deny_mode,old_deny_mode,old_open_mode,
- (int)share->pid,fname, fcbopen, *flags, access_allowed));
+ share->pid,fname, fcbopen, *flags, access_allowed));
unix_ERR_class = ERRDOS;
unix_ERR_code = ERRbadshare;
@@ -792,39 +727,33 @@ static int check_share_mode( share_mode_entry *share, int deny_mode,
return True;
}
+
/****************************************************************************
open a file with a share mode
****************************************************************************/
-
-void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int share_mode,int ofun,
- mode_t mode,int oplock_request, int *Access,int *action)
+void open_file_shared(files_struct *fsp, connection_struct *conn,
+ char *fname, int share_mode, int ofun,
+ mode_t mode, int oplock_request, int *Access,
+ int *action)
{
int flags=0;
int flags2=0;
int deny_mode = GET_DENY_MODE(share_mode);
BOOL allow_share_delete = GET_ALLOW_SHARE_DELETE(share_mode);
SMB_STRUCT_STAT sbuf;
- BOOL file_existed = vfs_file_exist(conn, fname, &sbuf);
+ BOOL file_existed = vfs_file_exist(conn, dos_to_unix(fname,False), &sbuf);
BOOL share_locked = False;
BOOL fcbopen = False;
- int token = 0;
SMB_DEV_T dev = 0;
SMB_INO_T inode = 0;
int num_share_modes = 0;
- int oplock_contention_count = 0;
- BOOL all_current_opens_are_level_II = False;
+
fsp->open = False;
fsp->fd_ptr = 0;
DEBUG(10,("open_file_shared: fname = %s, share_mode = %x, ofun = %x, mode = %o, oplock request = %d\n",
fname, share_mode, ofun, (int)mode, oplock_request ));
-
- /* ignore any oplock requests if oplocks are disabled */
- if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break) {
- oplock_request = 0;
- }
-
/* this is for OS/2 EAs - try and say we don't support them */
if (strstr(fname,".+,;=[]."))
{
@@ -903,6 +832,9 @@ void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int
return;
}
+ if (deny_mode == DENY_FCB)
+ deny_mode = DENY_DOS;
+
if (lp_share_modes(SNUM(conn)))
{
int i;
@@ -929,8 +861,6 @@ void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int
{
broke_oplock = False;
- all_current_opens_are_level_II = True;
-
for(i = 0; i < num_share_modes; i++)
{
share_mode_entry *share_entry = &old_shares[i];
@@ -942,8 +872,7 @@ void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int
* Check if someone has an oplock on this file. If so we must break
* it before continuing.
*/
- if((oplock_request && EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) ||
- (!oplock_request && (share_entry->op_type != NO_OPLOCK)))
+ if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK))
{
DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \
@@ -965,10 +894,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
}
lock_share_entry(conn, dev, inode);
broke_oplock = True;
- all_current_opens_are_level_II = False;
break;
- } else if (!LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
- all_current_opens_are_level_II = False;
}
/* someone else has a share lock on it, check to see
@@ -987,7 +913,6 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
{
free((char *)old_shares);
num_share_modes = get_share_modes(conn, dev, inode, &old_shares);
- oplock_contention_count++;
}
} while(broke_oplock);
}
@@ -996,18 +921,6 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
free((char *)old_shares);
}
- /*
- * Refuse to grant an oplock in case the contention limit is
- * reached when going through the lock list multiple times.
- */
-
- if(oplock_contention_count >= lp_oplock_contention_limit(SNUM(conn)))
- {
- oplock_request = 0;
- DEBUG(4,("open_file_shared: oplock contention = %d. Not granting oplock.\n",
- oplock_contention_count ));
- }
-
DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n",
flags,flags2,(int)mode));
@@ -1065,19 +978,18 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
{
uint16 port = 0;
- /*
- * Setup the oplock info in both the shared memory and
- * file structs.
- */
+ /* JRA. Currently this only services Exlcusive and batch
+ oplocks (no other opens on this file). This needs to
+ be extended to level II oplocks (multiple reader
+ oplocks). */
- if(oplock_request && (num_share_modes == 0) &&
- !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp, oplock_request) ) {
- port = global_oplock_port;
- } else if (oplock_request && all_current_opens_are_level_II) {
+ if((oplock_request) && (num_share_modes == 0) && lp_oplocks(SNUM(conn)) &&
+ !IS_VETO_OPLOCK_PATH(conn,fname) && set_file_oplock(fsp) )
+ {
port = global_oplock_port;
- oplock_request = LEVEL_II_OPLOCK;
- set_file_oplock(fsp, oplock_request);
- } else {
+ }
+ else
+ {
port = 0;
oplock_request = 0;
}
@@ -1086,7 +998,14 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
}
if ((flags2&O_TRUNC) && file_existed)
- truncate_unless_locked(fsp,conn,token,&share_locked);
+ truncate_unless_locked(fsp,conn,&share_locked);
+
+ /*
+ * Attempt to mmap a read only file.
+ * Moved until after a kernel oplock may
+ * be granted due to reference count issues. JRA.
+ */
+ mmap_open_file(fsp);
}
if (share_locked && lp_share_modes(SNUM(conn)))
@@ -1094,69 +1013,6 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
}
/****************************************************************************
- Open a file for permissions read only. Return a pseudo file entry
- with the 'stat_open' flag set and a fd_ptr of NULL.
-****************************************************************************/
-
-int open_file_stat(files_struct *fsp,connection_struct *conn,
- char *fname, int smb_ofun, SMB_STRUCT_STAT *pst, int *action)
-{
- extern struct current_user current_user;
-
- if(conn->vfs_ops.stat(dos_to_unix(fname, False), pst) < 0) {
- DEBUG(0,("open_file_stat: unable to stat name = %s. Error was %s\n",
- fname, strerror(errno) ));
- return -1;
- }
-
- if(S_ISDIR(pst->st_mode)) {
- DEBUG(0,("open_file_stat: %s is a directory !\n", fname ));
- return -1;
- }
-
- *action = FILE_WAS_OPENED;
-
- DEBUG(5,("open_file_stat: opening file %s as a stat entry\n", fname));
-
- /*
- * Setup the files_struct for it.
- */
-
- fsp->fd_ptr = NULL;
- conn->num_files_open++;
- fsp->mode = 0;
- GetTimeOfDay(&fsp->open_time);
- fsp->vuid = current_user.vuid;
- fsp->size = 0;
- fsp->pos = -1;
- fsp->open = True;
- fsp->can_lock = False;
- fsp->can_read = False;
- fsp->can_write = False;
- fsp->share_mode = 0;
- fsp->print_file = False;
- fsp->modified = False;
- fsp->oplock_type = NO_OPLOCK;
- fsp->sent_oplock_break = NO_BREAK_SENT;
- fsp->is_directory = False;
- fsp->stat_open = True;
- fsp->directory_delete_on_close = False;
- fsp->conn = conn;
- /*
- * Note that the file name here is the *untranslated* name
- * ie. it is still in the DOS codepage sent from the client.
- * All use of this filename will pass though the sys_xxxx
- * functions which will do the dos_to_unix translation before
- * mapping into a UNIX filename. JRA.
- */
- string_set(&fsp->fsp_name,fname);
- fsp->wbmpx_ptr = NULL;
- fsp->wcp = NULL; /* Write cache pointer. */
-
- return 0;
-}
-
-/****************************************************************************
Open a directory from an NT SMB call.
****************************************************************************/
@@ -1165,56 +1021,26 @@ int open_directory(files_struct *fsp,connection_struct *conn,
{
extern struct current_user current_user;
SMB_STRUCT_STAT st;
- BOOL got_stat = False;
- if(conn->vfs_ops.stat(dos_to_unix(fname, False), &st) == 0) {
- got_stat = True;
- }
-
- if (got_stat && (GET_FILE_OPEN_DISPOSITION(smb_ofun) == FILE_EXISTS_FAIL)) {
- errno = EEXIST; /* Setup so correct error is returned to client. */
- return -1;
- }
-
- if (GET_FILE_CREATE_DISPOSITION(smb_ofun) == FILE_CREATE_IF_NOT_EXIST) {
-
- if (got_stat) {
-
- if(!S_ISDIR(st.st_mode)) {
- DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
- errno = EACCES;
- return -1;
- }
- *action = FILE_WAS_OPENED;
-
- } else {
-
- /*
- * Try and create the directory.
- */
-
- if(!CAN_WRITE(conn)) {
- DEBUG(2,("open_directory: failing create on read-only share\n"));
- errno = EACCES;
- return -1;
- }
-
- if(conn->vfs_ops.mkdir(dos_to_unix(fname, False),
- unix_mode(conn,aDIR, fname)) < 0) {
- DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
- fname, strerror(errno) ));
- return -1;
- }
- *action = FILE_WAS_CREATED;
+ if (smb_ofun & 0x10) {
+ /*
+ * Create the directory.
+ */
+ if(conn->vfs_ops.mkdir(dos_to_unix(fname,False),
+ unix_mode(conn,aDIR)) < 0) {
+ DEBUG(0,("open_directory: unable to create %s. Error was %s\n",
+ fname, strerror(errno) ));
+ return -1;
}
- } else {
+ *action = FILE_WAS_CREATED;
+ } else {
/*
- * Don't create - just check that it *was* a directory.
+ * Check that it *was* a directory.
*/
- if(!got_stat) {
+ if(conn->vfs_ops.stat(dos_to_unix(fname,False), &st) < 0) {
DEBUG(0,("open_directory: unable to stat name = %s. Error was %s\n",
fname, strerror(errno) ));
return -1;
@@ -1224,7 +1050,6 @@ int open_directory(files_struct *fsp,connection_struct *conn,
DEBUG(0,("open_directory: %s is not a directory !\n", fname ));
return -1;
}
-
*action = FILE_WAS_OPENED;
}
@@ -1239,20 +1064,21 @@ int open_directory(files_struct *fsp,connection_struct *conn,
conn->num_files_open++;
fsp->mode = 0;
GetTimeOfDay(&fsp->open_time);
- fsp->vuid = current_user.vuid;
+ fsp->vuid = current_user.key.vuid;
fsp->size = 0;
fsp->pos = -1;
fsp->open = True;
+ fsp->mmap_ptr = NULL;
+ fsp->mmap_size = 0;
fsp->can_lock = True;
fsp->can_read = False;
fsp->can_write = False;
fsp->share_mode = 0;
fsp->print_file = False;
fsp->modified = False;
- fsp->oplock_type = NO_OPLOCK;
- fsp->sent_oplock_break = NO_BREAK_SENT;
+ fsp->granted_oplock = False;
+ fsp->sent_oplock_break = False;
fsp->is_directory = True;
- fsp->directory_delete_on_close = False;
fsp->conn = conn;
/*
* Note that the file name here is the *untranslated* name
@@ -1267,9 +1093,10 @@ int open_directory(files_struct *fsp,connection_struct *conn,
return 0;
}
+
/*******************************************************************
- Check if the share mode on a file allows it to be deleted or unlinked.
- Return True if sharing doesn't prevent the operation.
+check if the share mode on a file allows it to be deleted or unlinked
+return True if sharing doesn't prevent the operation
********************************************************************/
BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
@@ -1279,7 +1106,7 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
share_mode_entry *old_shares = 0;
int num_share_modes;
SMB_STRUCT_STAT sbuf;
- pid_t pid = getpid();
+ int pid = getpid();
SMB_DEV_T dev;
SMB_INO_T inode;
@@ -1316,16 +1143,9 @@ BOOL check_file_sharing(connection_struct *conn,char *fname, BOOL rename_op)
* Check if someone has an oplock on this file. If so we must
* break it before continuing.
*/
- if(BATCH_OPLOCK_TYPE(share_entry->op_type))
+ if(share_entry->op_type & BATCH_OPLOCK)
{
-#if 0
-
-/* JRA. Try removing this code to see if the new oplock changes
- fix the problem. I'm dubious, but Andrew is recommending we
- try this....
-*/
-
/*
* It appears that the NT redirector may have a bug, in that
* it tries to do an SMBmv on a file that it has open with a
@@ -1355,7 +1175,6 @@ batch oplocked file %s, dev = %x, inode = %.0f\n", fname, (unsigned int)dev, (do
continue;
}
else
-#endif /* 0 */
{
DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \
@@ -1391,8 +1210,7 @@ dev = %x, inode = %.0f\n", old_shares[i].op_type, fname, (unsigned int)dev, (dou
* if we can too.
*/
- if ((GET_DENY_MODE(share_entry->share_mode) != DENY_DOS) ||
- (share_entry->pid != pid))
+ if ((GET_DENY_MODE(share_entry->share_mode) != DENY_DOS) || (share_entry->pid != pid))
goto free_and_exit;
} /* end for */
diff --git a/source/smbd/oplock.c b/source/smbd/oplock.c
index c5cab8c2252..ec8b3da2616 100644
--- a/source/smbd/oplock.c
+++ b/source/smbd/oplock.c
@@ -26,30 +26,18 @@ extern int DEBUGLEVEL;
/* Oplock ipc UDP socket. */
static int oplock_sock = -1;
uint16 global_oplock_port = 0;
-static int oplock_pipe_read = -1;
-
#if defined(HAVE_KERNEL_OPLOCKS)
+static int oplock_pipe_read = -1;
static int oplock_pipe_write = -1;
-#endif
+#endif /* HAVE_KERNEL_OPLOCKS */
/* Current number of oplocks we have outstanding. */
-static int32 exclusive_oplocks_open = 0;
-static int32 level_II_oplocks_open = 0;
-BOOL global_client_failed_oplock_break = False;
+int32 global_oplocks_open = 0;
BOOL global_oplock_break = False;
extern int smb_read_error;
-static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, BOOL local);
-
-/****************************************************************************
- Get the number of current exclusive oplocks.
-****************************************************************************/
-
-int32 get_number_of_exclusive_open_oplocks(void)
-{
- return exclusive_oplocks_open;
-}
+static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval);
/****************************************************************************
Setup the kernel level oplock backchannel for this process.
@@ -75,9 +63,8 @@ BOOL setup_kernel_oplock_pipe(void)
}
/****************************************************************************
- Open the oplock IPC socket communication.
+ open the oplock IPC socket communication
****************************************************************************/
-
BOOL open_oplock_ipc(void)
{
struct sockaddr_in sock_name;
@@ -140,13 +127,15 @@ BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeou
int selrtn;
int maxfd = oplock_sock;
- if(lp_kernel_oplocks() && (oplock_pipe_read != -1))
+#if defined(HAVE_KERNEL_OPLOCKS)
+ if(lp_kernel_oplocks())
maxfd = MAX(maxfd, oplock_pipe_read);
+#endif /* HAVE_KERNEL_OPLOCKS */
to.tv_sec = timeout / 1000;
to.tv_usec = (timeout % 1000) * 1000;
- selrtn = sys_select(maxfd+1,fds,&to);
+ selrtn = sys_select(maxfd+1,fds,NULL, &to);
/* Check if error */
if(selrtn == -1) {
@@ -207,7 +196,7 @@ Error was %s.\n", strerror(errno) ));
}
dev = (SMB_DEV_T)os.os_dev;
- inode = (SMB_INO_T)os.os_ino;
+ inode = (SMB_DEV_T)os.os_ino;
DEBUG(5,("receive_local_message: kernel oplock break request received for \
dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
@@ -223,9 +212,14 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
buffer += OPBRK_CMD_HEADER_LEN;
SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
+ SIVAL(buffer,KERNEL_OPLOCK_BREAK_DEV_OFFSET,dev);
- memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&dev, sizeof(dev));
- memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&inode, sizeof(inode));
+#ifdef LARGE_SMB_INO_T
+ SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode & 0xFFFFFFFF);
+ SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET+4, (inode >> 32 ) & 0xFFFFFFFF );
+#else /* LARGE_SMB_INO_T */
+ SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode);
+#endif /* LARGE_SMB_INO_T */
return True;
}
@@ -271,11 +265,11 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
}
/****************************************************************************
- Attempt to set an kernel oplock on a file. Always returns True if kernel
- oplocks not available.
+ Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
+ disabled (just sets flags). Returns True if oplock set.
****************************************************************************/
-static BOOL set_kernel_oplock(files_struct *fsp, int oplock_type)
+BOOL set_file_oplock(files_struct *fsp)
{
#if defined(HAVE_KERNEL_OPLOCKS)
if(lp_kernel_oplocks()) {
@@ -299,38 +293,23 @@ inode = %.0f. Another process had the file open.\n",
}
#endif /* HAVE_KERNEL_OPLOCKS */
- return True;
-}
-/****************************************************************************
- Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
- disabled (just sets flags). Returns True if oplock set.
-****************************************************************************/
+ DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f\n",
+ fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode));
-BOOL set_file_oplock(files_struct *fsp, int oplock_type)
-{
- if (!set_kernel_oplock(fsp, oplock_type))
- return False;
-
- fsp->oplock_type = oplock_type;
- fsp->sent_oplock_break = NO_BREAK_SENT;
- if ( oplock_type == LEVEL_II_OPLOCK)
- level_II_oplocks_open++;
- else
- exclusive_oplocks_open++;
-
- DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
- fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode,
- (int)fsp->open_time.tv_sec, (int)fsp->open_time.tv_usec ));
+ fsp->granted_oplock = True;
+ fsp->sent_oplock_break = False;
+ global_oplocks_open++;
return True;
}
/****************************************************************************
- Release a kernel oplock on a file.
+ Attempt to release an oplock on a file. Always succeeds if kernel oplocks are
+ disabled (just clears flags).
****************************************************************************/
-static void release_kernel_oplock(files_struct *fsp)
+static void release_file_oplock(files_struct *fsp)
{
#if defined(HAVE_KERNEL_OPLOCKS)
@@ -343,20 +322,20 @@ static void release_kernel_oplock(files_struct *fsp)
* oplock state of this file.
*/
int state = fcntl(fsp->fd_ptr->fd, F_OPLKACK, -1);
- dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f has kernel \
+ dbgtext("release_file_oplock: file %s, dev = %x, inode = %.0f has kernel \
oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
(double)fsp->fd_ptr->inode, state );
}
/*
- * Remove the kernel oplock on this file.
+ * Remote the kernel oplock on this file.
*/
if(fcntl(fsp->fd_ptr->fd, F_OPLKACK, OP_REVOKE) < 0)
{
if( DEBUGLVL( 0 ))
{
- dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " );
+ dbgtext("release_file_oplock: Error when removing kernel oplock on file " );
dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
(double)fsp->fd_ptr->inode, strerror(errno) );
@@ -364,90 +343,10 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
}
}
#endif /* HAVE_KERNEL_OPLOCKS */
-}
-
-
-/****************************************************************************
- Attempt to release an oplock on a file. Decrements oplock count.
-****************************************************************************/
-
-void release_file_oplock(files_struct *fsp)
-{
- release_kernel_oplock(fsp);
-
- if (fsp->oplock_type == LEVEL_II_OPLOCK)
- level_II_oplocks_open--;
- else
- exclusive_oplocks_open--;
-
- fsp->oplock_type = NO_OPLOCK;
- fsp->sent_oplock_break = NO_BREAK_SENT;
-
- flush_write_cache(fsp, OPLOCK_RELEASE_FLUSH);
-}
-
-/****************************************************************************
- Attempt to downgrade an oplock on a file. Doesn't decrement oplock count.
-****************************************************************************/
-
-static void downgrade_file_oplock(files_struct *fsp)
-{
- release_kernel_oplock(fsp);
- fsp->oplock_type = LEVEL_II_OPLOCK;
- exclusive_oplocks_open--;
- level_II_oplocks_open++;
- fsp->sent_oplock_break = NO_BREAK_SENT;
-}
-
-/****************************************************************************
- Remove a file oplock. Copes with level II and exclusive.
- Locks then unlocks the share mode lock.
-****************************************************************************/
-
-BOOL remove_oplock(files_struct *fsp)
-{
- SMB_DEV_T dev = fsp->fd_ptr->dev;
- SMB_INO_T inode = fsp->fd_ptr->inode;
- BOOL ret = True;
-
- /* Remove the oplock flag from the sharemode. */
- if (lock_share_entry(fsp->conn, dev, inode) == False) {
- DEBUG(0,("remove_oplock: failed to lock share entry for file %s\n",
- fsp->fsp_name ));
- ret = False;
- }
-
- if (fsp->sent_oplock_break == EXCLUSIVE_BREAK_SENT) {
-
- /*
- * Deal with a reply when a break-to-none was sent.
- */
-
- if(remove_share_oplock(fsp)==False) {
- DEBUG(0,("remove_oplock: failed to remove share oplock for file %s fnum %d, \
-dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
- ret = False;
- }
-
- release_file_oplock(fsp);
-
- } else {
-
- /*
- * Deal with a reply when a break-to-level II was sent.
- */
-
- if(downgrade_share_oplock(fsp)==False) {
- DEBUG(0,("remove_oplock: failed to downgrade share oplock for file %s fnum %d, \
-dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)inode));
- ret = False;
- }
- downgrade_file_oplock(fsp);
- }
-
- unlock_share_entry(fsp->conn, dev, inode);
- return ret;
+ fsp->granted_oplock = False;
+ fsp->sent_oplock_break = False;
+ global_oplocks_open--;
}
/****************************************************************************
@@ -459,16 +358,14 @@ dev = %x, inode = %.0f\n", fsp->fsp_name, fsp->fnum, (unsigned int)dev, (double)
int setup_oplock_select_set( fd_set *fds)
{
int maxfd = oplock_sock;
-
- if(oplock_sock == -1)
- return 0;
-
FD_SET(oplock_sock,fds);
- if(lp_kernel_oplocks() && (oplock_pipe_read != -1)) {
+#if defined(HAVE_KERNEL_OPLOCKS)
+ if(lp_kernel_oplocks()) {
FD_SET(oplock_pipe_read,fds);
maxfd = MAX(maxfd,oplock_pipe_read);
}
+#endif /* HAVE_KERNEL_OPLOCKS */
return maxfd;
}
@@ -485,10 +382,9 @@ BOOL process_local_message(char *buffer, int buf_size)
char *msg_start;
SMB_DEV_T dev;
SMB_INO_T inode;
- pid_t remotepid;
+ uint32 remotepid;
struct timeval tval;
struct timeval *ptval = NULL;
- uint16 break_cmd_type;
msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
@@ -502,9 +398,7 @@ BOOL process_local_message(char *buffer, int buf_size)
* Pull the info out of the requesting packet.
*/
- break_cmd_type = SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET);
-
- switch(break_cmd_type)
+ switch(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET))
{
#if defined(HAVE_KERNEL_OPLOCKS)
case KERNEL_OPLOCK_BREAK_CMD:
@@ -516,8 +410,18 @@ should be %d).\n", msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
return False;
}
{
- memcpy((char *)&inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(inode));
- memcpy((char *)&dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(dev));
+ /*
+ * Warning - beware of SMB_INO_T <> 4 bytes. !!
+ */
+#ifdef LARGE_SMB_INO_T
+ SMB_INO_T inode_low = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
+ SMB_INO_T inode_high = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET + 4);
+ inode = inode_low | (inode_high << 32);
+#else /* LARGE_SMB_INO_T */
+ inode = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
+#endif /* LARGE_SMB_INO_T */
+
+ dev = IVAL(msg_start,KERNEL_OPLOCK_BREAK_DEV_OFFSET);
ptval = NULL;
@@ -528,34 +432,36 @@ file dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode));
#endif /* HAVE_KERNEL_OPLOCKS */
case OPLOCK_BREAK_CMD:
- case LEVEL_II_OPLOCK_BREAK_CMD:
-
/* Ensure that the msg length is correct. */
if(msg_len != OPLOCK_BREAK_MSG_LEN)
{
- DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, should be %d).\n",
- (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
+ DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
+should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
return False;
}
{
- long usec;
- time_t sec;
+ /*
+ * Warning - beware of SMB_INO_T <> 4 bytes. !!
+ */
+#ifdef LARGE_SMB_INO_T
+ SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
+ SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
+ inode = inode_low | (inode_high << 32);
+#else /* LARGE_SMB_INO_T */
+ inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
+#endif /* LARGE_SMB_INO_T */
- memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
- memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
- memcpy((char *)&sec, msg_start+OPLOCK_BREAK_SEC_OFFSET,sizeof(sec));
- tval.tv_sec = sec;
- memcpy((char *)&usec, msg_start+OPLOCK_BREAK_USEC_OFFSET, sizeof(usec));
- tval.tv_usec = usec;
+ dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
+
+ tval.tv_sec = (time_t)IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
+ tval.tv_usec = (long)IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
ptval = &tval;
- memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
+ remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
- DEBUG(5,("process_local_message: (%s) oplock break request from \
-pid %d, port %d, dev = %x, inode = %.0f\n",
- (break_cmd_type == OPLOCK_BREAK_CMD) ? "exclusive" : "level II",
- (int)remotepid, from_port, (unsigned int)dev, (double)inode));
+ DEBUG(5,("process_local_message: oplock break request from \
+pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
}
break;
@@ -569,17 +475,27 @@ reply - dumping info.\n"));
if(msg_len != OPLOCK_BREAK_MSG_LEN)
{
DEBUG(0,("process_local_message: ubr: incorrect length for reply \
-(was %d, should be %d).\n", (int)msg_len, (int)OPLOCK_BREAK_MSG_LEN));
+(was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
return False;
}
{
- memcpy((char *)&inode, msg_start+OPLOCK_BREAK_INODE_OFFSET,sizeof(inode));
- memcpy((char *)&remotepid, msg_start+OPLOCK_BREAK_PID_OFFSET,sizeof(remotepid));
- memcpy((char *)&dev, msg_start+OPLOCK_BREAK_DEV_OFFSET,sizeof(dev));
+ /*
+ * Warning - beware of SMB_INO_T <> 4 bytes. !!
+ */
+#ifdef LARGE_SMB_INO_T
+ SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
+ SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
+ inode = inode_low | (inode_high << 32);
+#else /* LARGE_SMB_INO_T */
+ inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
+#endif /* LARGE_SMB_INO_T */
+
+ remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
+ dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
DEBUG(0,("process_local_message: unsolicited oplock break reply from \
-pid %d, port %d, dev = %x, inode = %.0f\n", (int)remotepid, from_port, (unsigned int)dev, (double)inode));
+pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
}
return False;
@@ -594,9 +510,9 @@ pid %d, port %d, dev = %x, inode = %.0f\n", (int)remotepid, from_port, (unsigned
* Now actually process the break request.
*/
- if((exclusive_oplocks_open + level_II_oplocks_open) != 0)
+ if(global_oplocks_open != 0)
{
- if (oplock_break(dev, inode, ptval, False) == False)
+ if(oplock_break(dev, inode, ptval) == False)
{
DEBUG(0,("process_local_message: oplock break failed.\n"));
return False;
@@ -615,7 +531,7 @@ oplocks. Returning success.\n"));
}
/*
- * Do the appropriate reply - none in the kernel or level II case.
+ * Do the appropriate reply - none in the kernel case.
*/
if(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET) == OPLOCK_BREAK_CMD)
@@ -625,7 +541,7 @@ oplocks. Returning success.\n"));
/* Send the message back after OR'ing in the 'REPLY' bit. */
SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
- memset((char *)&toaddr,'\0',sizeof(toaddr));
+ bzero((char *)&toaddr,sizeof(toaddr));
toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
toaddr.sin_port = htons(from_port);
toaddr.sin_family = AF_INET;
@@ -634,77 +550,40 @@ oplocks. Returning success.\n"));
(struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
{
DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
- (int)remotepid, strerror(errno)));
+ remotepid, strerror(errno)));
return False;
}
DEBUG(5,("process_local_message: oplock break reply sent to \
pid %d, port %d, for file dev = %x, inode = %.0f\n",
- (int)remotepid, from_port, (unsigned int)dev, (double)inode));
+ remotepid, from_port, (unsigned int)dev, (double)inode));
}
return True;
}
/****************************************************************************
- Set up an oplock break message.
-****************************************************************************/
-
-static void prepare_break_message(char *outbuf, files_struct *fsp, BOOL level2)
-{
- memset(outbuf,'\0',smb_size);
- set_message(outbuf,8,0,True);
-
- SCVAL(outbuf,smb_com,SMBlockingX);
- SSVAL(outbuf,smb_tid,fsp->conn->cnum);
- SSVAL(outbuf,smb_pid,0xFFFF);
- SSVAL(outbuf,smb_uid,0);
- SSVAL(outbuf,smb_mid,0xFFFF);
- SCVAL(outbuf,smb_vwv0,0xFF);
- SSVAL(outbuf,smb_vwv2,fsp->fnum);
- SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
- SCVAL(outbuf,smb_vwv3+1,level2 ? OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
-}
-
-/****************************************************************************
- Function to do the waiting before sending a local break.
-****************************************************************************/
-
-static void wait_before_sending_break(BOOL local_request)
-{
- extern struct timeval smb_last_time;
-
- if(local_request) {
- struct timeval cur_tv;
- long wait_left = (long)lp_oplock_break_wait_time();
-
- GetTimeOfDay(&cur_tv);
-
- wait_left -= ((cur_tv.tv_sec - smb_last_time.tv_sec)*1000) +
- ((cur_tv.tv_usec - smb_last_time.tv_usec)/1000);
-
- if(wait_left > 0) {
- wait_left = MIN(wait_left, 1000);
- sys_usleep(wait_left * 1000);
- }
- }
-}
-
-/****************************************************************************
- Ensure that we have a valid oplock.
+ Process an oplock break directly.
****************************************************************************/
-static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
+static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
{
+ extern struct current_user current_user;
+ extern int Client;
+ char *inbuf = NULL;
+ char *outbuf = NULL;
files_struct *fsp = NULL;
+ time_t start_time;
+ BOOL shutdown_server = False;
+ connection_struct *saved_conn;
+ int saved_vuid;
+ pstring saved_dir;
+ int break_counter = OPLOCK_BREAK_RESENDS;
if( DEBUGLVL( 3 ) )
{
- dbgtext( "initial_break_processing: called for dev = %x, inode = %.0f tv_sec = %x, tv_usec = %x.\n",
- (unsigned int)dev, (double)inode, tval ? (int)tval->tv_sec : 0,
- tval ? (int)tval->tv_usec : 0);
- dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n",
- exclusive_oplocks_open, level_II_oplocks_open );
+ dbgtext( "oplock_break: called for dev = %x, inode = %.0f.\n", (unsigned int)dev, (double)inode );
+ dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
}
/* We need to search the file open table for the
@@ -715,13 +594,13 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, st
if(fsp == NULL)
{
/* The file could have been closed in the meantime - return success. */
- if( DEBUGLVL( 3 ) )
+ if( DEBUGLVL( 0 ) )
{
- dbgtext( "initial_break_processing: cannot find open file with " );
+ dbgtext( "oplock_break: cannot find open file with " );
dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
dbgtext( "allowing break to succeed.\n" );
}
- return NULL;
+ return True;
}
/* Ensure we have an oplock on the file */
@@ -733,130 +612,18 @@ static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, st
as we may have just freed it.
*/
- if(fsp->oplock_type == NO_OPLOCK)
+ if(!fsp->granted_oplock)
{
- if( DEBUGLVL( 3 ) )
+ if( DEBUGLVL( 0 ) )
{
- dbgtext( "initial_break_processing: file %s ", fsp->fsp_name );
+ dbgtext( "oplock_break: file %s ", fsp->fsp_name );
dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
dbgtext( "Allowing break to succeed regardless.\n" );
}
- return NULL;
- }
-
- return fsp;
-}
-
-/****************************************************************************
- Process a level II oplock break directly.
-****************************************************************************/
-
-BOOL oplock_break_level2(files_struct *fsp, BOOL local_request, int token)
-{
- extern int Client;
- extern uint32 global_client_caps;
- char outbuf[128];
- BOOL got_lock = False;
- SMB_DEV_T dev = fsp->fd_ptr->dev;
- SMB_INO_T inode = fsp->fd_ptr->inode;
-
- /*
- * We can have a level II oplock even if the client is not
- * level II oplock aware. In this case just remove the
- * flags and don't send the break-to-none message to
- * the client.
- */
-
- if (global_client_caps & CAP_LEVEL_II_OPLOCKS) {
- /*
- * If we are sending an oplock break due to an SMB sent
- * by our own client we ensure that we wait at leat
- * lp_oplock_break_wait_time() milliseconds before sending
- * the packet. Sending the packet sooner can break Win9x
- * and has reported to cause problems on NT. JRA.
- */
-
- wait_before_sending_break(local_request);
-
- /* Prepare the SMBlockingX message. */
-
- prepare_break_message( outbuf, fsp, False);
- send_smb(Client, outbuf);
- }
-
- /*
- * Now we must update the shared memory structure to tell
- * everyone else we no longer have a level II oplock on
- * this open file. If local_request is true then token is
- * the existing lock on the shared memory area.
- */
-
- if(!local_request && lock_share_entry(fsp->conn, dev, inode) == False) {
- DEBUG(0,("oplock_break_level2: unable to lock share entry for file %s\n", fsp->fsp_name ));
- } else {
- got_lock = True;
- }
-
- if(remove_share_oplock(fsp)==False) {
- DEBUG(0,("oplock_break_level2: unable to remove level II oplock for file %s\n", fsp->fsp_name ));
- }
-
- if (!local_request && got_lock)
- unlock_share_entry(fsp->conn, dev, inode);
-
- fsp->oplock_type = NO_OPLOCK;
- level_II_oplocks_open--;
-
- if(level_II_oplocks_open < 0)
- {
- DEBUG(0,("oplock_break_level2: level_II_oplocks_open < 0 (%d). PANIC ERROR\n",
- level_II_oplocks_open));
- abort();
- }
-
- if( DEBUGLVL( 3 ) )
- {
- dbgtext( "oplock_break_level2: returning success for " );
- dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
- dbgtext( "Current level II oplocks_open = %d\n", level_II_oplocks_open );
- }
-
- return True;
-}
-
-/****************************************************************************
- Process an oplock break directly.
-****************************************************************************/
-
-static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, BOOL local_request)
-{
- extern uint32 global_client_caps;
- extern struct current_user current_user;
- extern int Client;
- char *inbuf = NULL;
- char *outbuf = NULL;
- files_struct *fsp = NULL;
- time_t start_time;
- BOOL shutdown_server = False;
- BOOL oplock_timeout = False;
- connection_struct *saved_conn;
- int saved_vuid;
- pstring saved_dir;
- int timeout = (OPLOCK_BREAK_TIMEOUT * 1000);
- pstring file_name;
- BOOL using_levelII;
-
- if((fsp = initial_break_processing(dev, inode, tval)) == NULL)
return True;
+ }
- /*
- * Deal with a level II oplock going break to none separately.
- */
-
- if (LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
- return oplock_break_level2(fsp, local_request, -1);
-
- /* Mark the oplock break as sent - we don't want to send twice! */
+ /* mark the oplock break as sent - we don't want to send twice! */
if (fsp->sent_oplock_break)
{
if( DEBUGLVL( 0 ) )
@@ -874,11 +641,6 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
return False;
}
- if(global_oplock_break) {
- DEBUG(0,("ABORT : ABORT : recursion in oplock_break !!!!!\n"));
- abort();
- }
-
/* Now comes the horrid part. We must send an oplock break to the client,
and then process incoming messages until we get a close or oplock release.
At this point we know we need a new inbuf/outbuf buffer pair.
@@ -900,31 +662,26 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
return False;
}
- /*
- * If we are sending an oplock break due to an SMB sent
- * by our own client we ensure that we wait at leat
- * lp_oplock_break_wait_time() milliseconds before sending
- * the packet. Sending the packet sooner can break Win9x
- * and has reported to cause problems on NT. JRA.
- */
-
- wait_before_sending_break(local_request);
-
/* Prepare the SMBlockingX message. */
+ bzero(outbuf,smb_size);
+ set_message(outbuf,8,0,True);
- if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && !lp_kernel_oplocks() && lp_level2_oplocks(SNUM(fsp->conn))) {
- using_levelII = True;
- } else {
- using_levelII = False;
- }
-
- prepare_break_message( outbuf, fsp, using_levelII);
- /* Remember if we just sent a break to level II on this file. */
- fsp->sent_oplock_break = using_levelII?
- LEVEL_II_BREAK_SENT:EXCLUSIVE_BREAK_SENT;
-
+ SCVAL(outbuf,smb_com,SMBlockingX);
+ SSVAL(outbuf,smb_tid,fsp->conn->cnum);
+ SSVAL(outbuf,smb_pid,0xFFFF);
+ SSVAL(outbuf,smb_uid,0);
+ SSVAL(outbuf,smb_mid,0xFFFF);
+ SCVAL(outbuf,smb_vwv0,0xFF);
+ SSVAL(outbuf,smb_vwv2,fsp->fnum);
+ SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
+ /* Change this when we have level II oplocks. */
+ SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
+
send_smb(Client, outbuf);
+ /* Remember we just sent an oplock break on this file. */
+ fsp->sent_oplock_break = True;
+
/* We need this in case a readraw crosses on the wire. */
global_oplock_break = True;
@@ -940,45 +697,46 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
* user, then unbecome the user whilst we're doing this.
*/
saved_conn = fsp->conn;
- saved_vuid = current_user.vuid;
+ saved_vuid = current_user.key.vuid;
dos_GetWd(saved_dir);
unbecome_user();
/* Save the chain fnum. */
file_chain_save();
- /*
- * From Charles Hoch <hoch@exemplary.com>. If the break processing
- * code closes the file (as it often does), then the fsp pointer here
- * points to free()'d memory. We *must* revalidate fsp each time
- * around the loop.
- */
-
- pstrcpy(file_name, fsp->fsp_name);
-
- while((fsp = initial_break_processing(dev, inode, tval)) &&
- OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ while(OPEN_FSP(fsp) && fsp->granted_oplock)
{
- if(receive_smb(Client,inbuf, timeout) == False)
+ if(receive_smb(Client,inbuf,
+ (OPLOCK_BREAK_TIMEOUT/OPLOCK_BREAK_RESENDS) * 1000) == False)
{
+
+ /* Isaac suggestd that if a MS client doesn't respond to a
+ oplock break request then we might try resending
+ it. Certainly it's no worse than just dropping the
+ socket! */
+ if (smb_read_error == READ_TIMEOUT && break_counter--) {
+ DEBUG(2, ( "oplock_break resend\n" ) );
+ send_smb(Client, outbuf);
+ continue;
+ }
+
/*
* Die if we got an error.
*/
- if (smb_read_error == READ_EOF) {
+ if (smb_read_error == READ_EOF)
DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
- shutdown_server = True;
- } else if (smb_read_error == READ_ERROR) {
+
+ if (smb_read_error == READ_ERROR)
DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
- shutdown_server = True;
- } else if (smb_read_error == READ_TIMEOUT) {
+
+ if (smb_read_error == READ_TIMEOUT)
DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
OPLOCK_BREAK_TIMEOUT ) );
- oplock_timeout = True;
- }
- DEBUGADD( 0, ( "oplock_break failed for file %s ", file_name ) );
+ DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
+ shutdown_server = True;
break;
}
@@ -1000,13 +758,13 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
{
if( DEBUGLVL( 0 ) )
- {
+ {
dbgtext( "oplock_break: no break received from client " );
dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
- }
- oplock_timeout = True;
+ }
+ shutdown_server = True;
break;
}
}
@@ -1038,21 +796,7 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
global_oplock_break = False;
/*
- * If the client timed out then clear the oplock (or go to level II)
- * and continue. This seems to be what NT does and is better than dropping
- * the connection.
- */
-
- if(oplock_timeout && (fsp = initial_break_processing(dev, inode, tval)) &&
- OPEN_FSP(fsp) && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- {
- DEBUG(0,("oplock_break: client failure in oplock break in file %s\n", fsp->fsp_name));
- remove_oplock(fsp);
- global_client_failed_oplock_break = True; /* Never grant this client an oplock again. */
- }
-
- /*
- * If the client had an error we must die.
+ * If the client did not respond we must die.
*/
if(shutdown_server)
@@ -1064,19 +808,27 @@ static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, B
exit_server("oplock break failure");
}
+ if(OPEN_FSP(fsp))
+ {
+ /* The lockingX reply will have removed the oplock flag
+ from the sharemode. */
+ release_file_oplock(fsp);
+ }
+
/* Santity check - remove this later. JRA */
- if(exclusive_oplocks_open < 0)
+ if(global_oplocks_open < 0)
{
- DEBUG(0,("oplock_break: exclusive_oplocks_open < 0 (%d). PANIC ERROR\n",
- exclusive_oplocks_open));
- abort();
+ DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
+ global_oplocks_open));
+ exit_server("oplock_break: global_oplocks_open < 0");
}
+
if( DEBUGLVL( 3 ) )
{
dbgtext( "oplock_break: returning success for " );
dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
- dbgtext( "Current exclusive_oplocks_open = %d\n", exclusive_oplocks_open );
+ dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
}
return True;
@@ -1092,11 +844,9 @@ BOOL request_oplock_break(share_mode_entry *share_entry,
{
char op_break_msg[OPLOCK_BREAK_MSG_LEN];
struct sockaddr_in addr_out;
- pid_t pid = getpid();
+ int pid = getpid();
time_t start_time;
int time_left;
- long usec;
- time_t sec;
if(pid == share_entry->pid)
{
@@ -1104,34 +854,36 @@ BOOL request_oplock_break(share_mode_entry *share_entry,
if(share_entry->op_port != global_oplock_port)
{
DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
-should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
+should be %d\n", pid, share_entry->op_port, global_oplock_port));
return False;
}
DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
/* Call oplock break direct. */
- return oplock_break(dev, inode, &share_entry->time, True);
+ return oplock_break(dev, inode, &share_entry->time);
}
/* We need to send a OPLOCK_BREAK_CMD message to the
port in the share mode entry. */
- if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
- SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,LEVEL_II_OPLOCK_BREAK_CMD);
- } else {
- SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
- }
- memcpy(op_break_msg+OPLOCK_BREAK_PID_OFFSET,(char *)&pid,sizeof(pid));
- sec = (time_t)share_entry->time.tv_sec;
- memcpy(op_break_msg+OPLOCK_BREAK_SEC_OFFSET,(char *)&sec,sizeof(sec));
- usec = (long)share_entry->time.tv_usec;
- memcpy(op_break_msg+OPLOCK_BREAK_USEC_OFFSET,(char *)&usec,sizeof(usec));
- memcpy(op_break_msg+OPLOCK_BREAK_DEV_OFFSET,(char *)&dev,sizeof(dev));
- memcpy(op_break_msg+OPLOCK_BREAK_INODE_OFFSET,(char *)&inode,sizeof(inode));
+ SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
+ SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
+ SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
+ SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
+ SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
+ /*
+ * WARNING - beware of SMB_INO_T <> 4 bytes.
+ */
+#ifdef LARGE_SMB_INO_T
+ SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,(inode & 0xFFFFFFFFL));
+ SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET+4,((inode >> 32) & 0xFFFFFFFFL));
+#else /* LARGE_SMB_INO_T */
+ SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
+#endif /* LARGE_SMB_INO_T */
/* set the address and port */
- memset((char *)&addr_out,'\0',sizeof(addr_out));
+ bzero((char *)&addr_out,sizeof(addr_out));
addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr_out.sin_port = htons( share_entry->op_port );
addr_out.sin_family = AF_INET;
@@ -1139,11 +891,8 @@ should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
if( DEBUGLVL( 3 ) )
{
dbgtext( "request_oplock_break: sending a oplock break message to " );
- dbgtext( "pid %d on port %d ", (int)share_entry->pid, share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
- (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
- (int)share_entry->time.tv_usec );
-
+ dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
+ dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
}
if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
@@ -1152,27 +901,15 @@ should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
if( DEBUGLVL( 0 ) )
{
dbgtext( "request_oplock_break: failed when sending a oplock " );
- dbgtext( "break message to pid %d ", (int)share_entry->pid );
+ dbgtext( "break message to pid %d ", share_entry->pid );
dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
- (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
- (int)share_entry->time.tv_usec );
+ dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
dbgtext( "Error was %s\n", strerror(errno) );
}
return False;
}
/*
- * If we just sent a message to a level II oplock share entry then
- * we are done and may return.
- */
-
- if (LEVEL_II_OPLOCK_TYPE(share_entry->op_type)) {
- DEBUG(3,("request_oplock_break: sent break message to level II entry.\n"));
- return True;
- }
-
- /*
* Now we must await the oplock broken message coming back
* from the target smbd process. Timeout if it fails to
* return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
@@ -1192,8 +929,10 @@ should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
FD_ZERO(&fds);
FD_SET(oplock_sock,&fds);
- if(lp_kernel_oplocks() && (oplock_pipe_read != -1))
+#if defined(HAVE_KERNEL_OPLOCKS)
+ if(lp_kernel_oplocks())
FD_SET(oplock_pipe_read,&fds);
+#endif /* HAVE_KERNEL_OPLOCKS */
if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
time_left ? time_left * 1000 : 1) == False)
@@ -1203,12 +942,9 @@ should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
if( DEBUGLVL( 0 ) )
{
dbgtext( "request_oplock_break: no response received to oplock " );
- dbgtext( "break request to pid %d ", (int)share_entry->pid );
+ dbgtext( "break request to pid %d ", share_entry->pid );
dbgtext( "on port %d ", share_entry->op_port );
dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
- dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
- (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
- (int)share_entry->time.tv_usec );
}
/*
@@ -1224,11 +960,9 @@ should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
if( DEBUGLVL( 0 ) )
{
dbgtext( "request_oplock_break: error in response received " );
- dbgtext( "to oplock break request to pid %d ", (int)share_entry->pid );
+ dbgtext( "to oplock break request to pid %d ", share_entry->pid );
dbgtext( "on port %d ", share_entry->op_port );
- dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
- (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
- (int)share_entry->time.tv_usec );
+ dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
dbgtext( "Error was (%s).\n", strerror(errno) );
}
return False;
@@ -1302,17 +1036,16 @@ should be %d\n", (int)pid, share_entry->op_port, global_oplock_port));
Used as a last ditch attempt to free a space in the
file table when we have run out.
****************************************************************************/
-
BOOL attempt_close_oplocked_file(files_struct *fsp)
{
DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
- if (fsp->open && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type) && !fsp->sent_oplock_break && (fsp->fd_ptr != NULL)) {
+ if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break && (fsp->fd_ptr != NULL)) {
/* Try and break the oplock. */
file_fd_struct *fd_ptr = fsp->fd_ptr;
- if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time, True)) {
+ if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
if(!fsp->open) /* Did the oplock break close the file ? */
return True;
}
diff --git a/source/smbd/password.c b/source/smbd/password.c
index 19e7d36443d..a4229242b3d 100644
--- a/source/smbd/password.c
+++ b/source/smbd/password.c
@@ -23,265 +23,14 @@
extern int DEBUGLEVEL;
extern int Protocol;
-extern struct in_addr ipzero;
/* users from session setup */
static pstring session_users="";
+extern pstring scope;
extern pstring global_myname;
extern fstring global_myworkgroup;
-/* Data to do lanman1/2 password challenge. */
-static unsigned char saved_challenge[8];
-static BOOL challenge_sent=False;
-
-/*******************************************************************
-Get the next challenge value - no repeats.
-********************************************************************/
-void generate_next_challenge(char *challenge)
-{
-#if 0
- /*
- * Leave this ifdef'd out while we test
- * the new crypto random number generator.
- * JRA.
- */
- unsigned char buf[16];
- static int counter = 0;
- struct timeval tval;
- int v1,v2;
-
- /* get a sort-of random number */
- GetTimeOfDay(&tval);
- v1 = (counter++) + getpid() + tval.tv_sec;
- v2 = (counter++) * getpid() + tval.tv_usec;
- SIVAL(challenge,0,v1);
- SIVAL(challenge,4,v2);
-
- /* mash it up with md4 */
- mdfour(buf, (unsigned char *)challenge, 8);
-#else
- unsigned char buf[8];
-
- generate_random_buffer(buf,8,False);
-#endif
- memcpy(saved_challenge, buf, 8);
- memcpy(challenge,buf,8);
- challenge_sent = True;
-}
-
-/*******************************************************************
-set the last challenge sent, usually from a password server
-********************************************************************/
-BOOL set_challenge(unsigned char *challenge)
-{
- memcpy(saved_challenge,challenge,8);
- challenge_sent = True;
- return(True);
-}
-
-/*******************************************************************
-get the last challenge sent
-********************************************************************/
-static BOOL last_challenge(unsigned char *challenge)
-{
- if (!challenge_sent) return(False);
- memcpy(challenge,saved_challenge,8);
- return(True);
-}
-
-/* this holds info on user ids that are already validated for this VC */
-static user_struct *validated_users = NULL;
-static int num_validated_users = 0;
-
-/****************************************************************************
-check if a uid has been validated, and return an pointer to the user_struct
-if it has. NULL if not. vuid is biased by an offset. This allows us to
-tell random client vuid's (normally zero) from valid vuids.
-****************************************************************************/
-user_struct *get_valid_user_struct(uint16 vuid)
-{
- if (vuid == UID_FIELD_INVALID)
- return NULL;
- vuid -= VUID_OFFSET;
- if ((vuid >= (uint16)num_validated_users) ||
- (validated_users[vuid].uid == (uid_t)-1) || (validated_users[vuid].gid == (gid_t)-1))
- return NULL;
- return &validated_users[vuid];
-}
-
-/****************************************************************************
-invalidate a uid
-****************************************************************************/
-void invalidate_vuid(uint16 vuid)
-{
- user_struct *vuser = get_valid_user_struct(vuid);
-
- if (vuser == NULL) return;
-
- vuser->uid = (uid_t)-1;
- vuser->gid = (gid_t)-1;
-
- vuser->n_sids = 0;
-
- /* same number of igroups as groups */
- vuser->n_groups = 0;
-
- if (vuser->groups)
- free((char *)vuser->groups);
-
- if (vuser->sids)
- free((char *)vuser->sids);
-
- vuser->sids = NULL;
- vuser->groups = NULL;
-}
-
-
-/****************************************************************************
-return a validated username
-****************************************************************************/
-char *validated_username(uint16 vuid)
-{
- user_struct *vuser = get_valid_user_struct(vuid);
- if (vuser == NULL)
- return 0;
- return(vuser->name);
-}
-
-
-/****************************************************************************
-Setup the groups a user belongs to.
-****************************************************************************/
-int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups)
-{
- int i,ngroups;
- gid_t grp = 0;
- gid_t *groups = NULL;
-
- if (-1 == initgroups(user,gid))
- {
- DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) ));
- if (getuid() == 0)
- {
- if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767)
- {
- DEBUG(0,("This is probably a problem with the account %s\n", user));
- }
- }
- return -1;
- }
-
- ngroups = sys_getgroups(0,&grp);
- if (ngroups <= 0)
- {
- ngroups = groups_max();
- }
-
- if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL)
- {
- DEBUG(0,("setup_groups malloc fail !\n"));
- return -1;
- }
-
- ngroups = sys_getgroups(ngroups,groups);
-
- (*p_ngroups) = ngroups;
- (*p_groups) = groups;
-
- DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) );
- for (i = 0; i < ngroups; i++ )
- {
- DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
- }
- DEBUG( 3, ( "\n" ) );
-
- return 0;
-}
-
-
-/****************************************************************************
-register a uid/name pair as being valid and that a valid password
-has been given. vuid is biased by an offset. This allows us to
-tell random client vuid's (normally zero) from valid vuids.
-****************************************************************************/
-uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest)
-{
- user_struct *vuser;
- struct passwd *pwfile; /* for getting real name from passwd file */
-
- /* Ensure no vuid gets registered in share level security. */
- if(lp_security() == SEC_SHARE)
- return UID_FIELD_INVALID;
-
-#if 0
- /*
- * After observing MS-Exchange services writing to a Samba share
- * I belive this code is incorrect. Each service does its own
- * sessionsetup_and_X for the same user, and as each service shuts
- * down, it does a user_logoff_and_X. As we are consolidating multiple
- * sessionsetup_and_X's onto the same vuid here, when the first service
- * shuts down, it invalidates all the open files for the other services.
- * Hence I am removing this code and forcing each sessionsetup_and_X
- * to get a new vuid.
- * Jeremy Allison. (jallison@whistle.com).
- */
-
- int i;
- for(i = 0; i < num_validated_users; i++) {
- vuser = &validated_users[i];
- if ( vuser->uid == uid )
- return (uint16)(i + VUID_OFFSET); /* User already validated */
- }
-#endif
-
- validated_users = (user_struct *)Realloc(validated_users,
- sizeof(user_struct)*
- (num_validated_users+1));
-
- if (!validated_users)
- {
- DEBUG(0,("Failed to realloc users struct!\n"));
- num_validated_users = 0;
- return UID_FIELD_INVALID;
- }
-
- vuser = &validated_users[num_validated_users];
- num_validated_users++;
-
- vuser->uid = uid;
- vuser->gid = gid;
- vuser->guest = guest;
- fstrcpy(vuser->name,unix_name);
- fstrcpy(vuser->requested_name,requested_name);
-
- vuser->n_sids = 0;
- vuser->sids = NULL;
-
- vuser->n_groups = 0;
- vuser->groups = NULL;
-
- /* Find all the groups this uid is in and store them.
- Used by become_user() */
- setup_groups(unix_name,uid,gid,
- &vuser->n_groups,
- &vuser->groups);
-
- DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name));
-
- DEBUG(3, ("Clearing default real name\n"));
- fstrcpy(vuser->real_name, "<Full Name>\0");
- if (lp_unix_realname()) {
- if ((pwfile=sys_getpwnam(vuser->name))!= NULL)
- {
- DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos));
- fstrcpy(vuser->real_name, pwfile->pw_gecos);
- }
- }
-
- return (uint16)((num_validated_users - 1) + VUID_OFFSET);
-}
-
/****************************************************************************
add a name to the session users list
@@ -305,284 +54,68 @@ void add_session_user(char *user)
}
}
-
/****************************************************************************
-update the encrypted smbpasswd file from the plaintext username and password
-*****************************************************************************/
-static BOOL update_smbpassword_file(char *user, char *password)
+check if a username/password pair is OK either via the system password
+database or the encrypted SMB password database
+return True if the password is correct, False otherwise
+****************************************************************************/
+BOOL password_ok(const char *orig_user, const char *domain,
+ const char *smb_apasswd, int smb_apasslen,
+ const char *smb_ntpasswd, int smb_ntpasslen,
+ struct passwd *pwd,
+ NET_USER_INFO_3 *info3)
{
- struct smb_passwd *smbpw;
- BOOL ret;
-
- become_root(0);
- smbpw = getsmbpwnam(user);
- unbecome_root(0);
-
- if(smbpw == NULL) {
- DEBUG(0,("getsmbpwnam returned NULL\n"));
+ uchar last_chal[8];
+ BOOL cleartext = smb_apasslen != 24 && smb_ntpasslen == 0;
+ uchar *chal = NULL;
+
+ if (info3 == NULL)
+ {
+ DEBUG(0,("password_ok: no NET_USER_INFO_3 parameter!\n"));
return False;
}
/*
- * Remove the account disabled flag - we are updating the
- * users password from a login.
+ * SMB password check
*/
- smbpw->acct_ctrl &= ~ACB_DISABLED;
-
- /* Here, the flag is one, because we want to ignore the
- XXXXXXX'd out password */
- ret = change_oem_password( smbpw, password, True);
- if (ret == False) {
- DEBUG(3,("change_oem_password returned False\n"));
- }
-
- return ret;
-}
-
-
-
-
-/****************************************************************************
-core of smb password checking routine.
-****************************************************************************/
-BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8)
-{
- /* Finish the encryption of part_passwd. */
- unsigned char p21[21];
- unsigned char p24[24];
-
- if (part_passwd == NULL)
- DEBUG(10,("No password set - allowing access\n"));
- /* No password set - always true ! */
- if (part_passwd == NULL)
- return 1;
-
- memset(p21,'\0',21);
- memcpy(p21,part_passwd,16);
- E_P24(p21, c8, p24);
-#if DEBUG_PASSWORD
- {
- int i;
- DEBUG(100,("Part password (P16) was |"));
- for(i = 0; i < 16; i++)
- DEBUG(100,("%X ", (unsigned char)part_passwd[i]));
- DEBUG(100,("|\n"));
- DEBUG(100,("Password from client was |"));
- for(i = 0; i < 24; i++)
- DEBUG(100,("%X ", (unsigned char)password[i]));
- DEBUG(100,("|\n"));
- DEBUG(100,("Given challenge was |"));
- for(i = 0; i < 8; i++)
- DEBUG(100,("%X ", (unsigned char)c8[i]));
- DEBUG(100,("|\n"));
- DEBUG(100,("Value from encryption was |"));
- for(i = 0; i < 24; i++)
- DEBUG(100,("%X ", (unsigned char)p24[i]));
- DEBUG(100,("|\n"));
- }
-#endif
- return (memcmp(p24, password, 24) == 0);
-}
-
-/****************************************************************************
- Do a specific test for an smb password being correct, given a smb_password and
- the lanman and NT responses.
-****************************************************************************/
-BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8],
- uchar lm_pass[24], uchar nt_pass[24])
-{
- uchar challenge[8];
-
- if (!lm_pass || !smb_pass) return(False);
-
- DEBUG(4,("Checking SMB password for user %s\n",
- smb_pass->smb_name));
-
- if(smb_pass->acct_ctrl & ACB_DISABLED) {
- DEBUG(1,("account for user %s was disabled.\n",
- smb_pass->smb_name));
- return(False);
- }
-
- if (chal == NULL)
+ if ((smb_apasslen != 0) ||
+ (lp_encrypted_passwords() && smb_apasslen == 0 &&
+ lp_null_passwords()))
{
- DEBUG(5,("use last SMBnegprot challenge\n"));
- if (!last_challenge(challenge))
+ DEBUG(10,("password_ok: check SMB auth\n"));
+
+ /* check security = user / domain */
+ if ((!cleartext) && last_challenge(last_chal))
{
- DEBUG(1,("no challenge done - password failed\n"));
- return False;
+ chal = last_chal;
}
- }
- else
- {
- DEBUG(5,("challenge received\n"));
- memcpy(challenge, chal, 8);
- }
-
- if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) {
- /* We have the NT MD4 hash challenge available - see if we can
- use it (ie. does it exist in the smbpasswd file).
- */
- DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
- if (smb_password_check((char *)nt_pass,
- (uchar *)smb_pass->smb_nt_passwd,
- challenge)) {
- DEBUG(4,("NT MD4 password check succeeded\n"));
- return(True);
+ if ((cleartext || chal) &&
+ check_domain_security(orig_user, domain,
+ chal,
+ smb_apasswd, smb_apasslen,
+ smb_ntpasswd, smb_ntpasslen,
+ info3) == 0x0)
+ {
+ DEBUG(10,("password_ok: domain auth succeeded\n"));
+ return True;
}
- DEBUG(4,("NT MD4 password check failed\n"));
- }
-
- /* Try against the lanman password. smb_pass->smb_passwd == NULL means
- no password, allow access. */
-
- DEBUG(4,("Checking LM MD4 password\n"));
-
- if((smb_pass->smb_passwd == NULL) &&
- (smb_pass->acct_ctrl & ACB_PWNOTREQ)) {
- DEBUG(4,("no password required for user %s\n",
- smb_pass->smb_name));
- return True;
}
- if((smb_pass->smb_passwd != NULL) &&
- smb_password_check((char *)lm_pass,
- (uchar *)smb_pass->smb_passwd, challenge)) {
- DEBUG(4,("LM MD4 password check succeeded\n"));
- return(True);
- }
-
- DEBUG(4,("LM MD4 password check failed\n"));
-
- return False;
-}
-
-
-/****************************************************************************
-check if a username/password is OK assuming the password is a 24 byte
-SMB hash
-return True if the password is correct, False otherwise
-****************************************************************************/
-
-BOOL pass_check_smb(char *user, char *domain,
- uchar *chal, uchar *lm_pwd, uchar *nt_pwd,
- struct passwd *pwd)
-{
- struct passwd *pass;
- struct smb_passwd *smb_pass;
-
- if (!lm_pwd || !nt_pwd)
- {
- return(False);
- }
-
- if (pwd != NULL && user == NULL)
- {
- pass = (struct passwd *) pwd;
- user = pass->pw_name;
- }
- else
- {
- pass = Get_Pwnam(user,True);
- }
-
- if (pass == NULL)
- {
- DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",user));
- return(False);
- }
-
- smb_pass = getsmbpwnam(user);
-
- if (smb_pass == NULL)
- {
- DEBUG(1,("Couldn't find user '%s' in smb_passwd file.\n", user));
- return(False);
- }
-
- /* Quit if the account was disabled. */
- if(smb_pass->acct_ctrl & ACB_DISABLED) {
- DEBUG(1,("Account for user '%s' was disabled.\n", user));
- return(False);
- }
-
- /* Ensure the uid's match */
- if (smb_pass->smb_userid != pass->pw_uid)
- {
- DEBUG(0,("Error : UNIX and SMB uids in password files do not match for user '%s'!\n", user));
- return(False);
- }
-
- if (lm_pwd[0] == '\0' && IS_BITS_SET_ALL(smb_pass->acct_ctrl, ACB_PWNOTREQ) && lp_null_passwords())
- {
- DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", smb_pass->smb_name));
- return(True);
- }
+ DEBUG(10,("password_ok: check Unix auth\n"));
+ /*
+ * unix password check
+ */
- if (smb_password_ok(smb_pass, chal, lm_pwd, nt_pwd))
+ if (!lp_update_encrypted())
{
- return(True);
- }
-
- DEBUG(2,("pass_check_smb failed - invalid password for user [%s]\n", user));
- return False;
-}
-
-/****************************************************************************
-check if a username/password pair is OK either via the system password
-database or the encrypted SMB password database
-return True if the password is correct, False otherwise
-****************************************************************************/
-BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd)
-{
- if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords()))
- {
- /* if 24 bytes long assume it is an encrypted password */
- uchar challenge[8];
-
- if (!last_challenge(challenge))
+ if (pass_check(orig_user, smb_apasswd, smb_apasslen, pwd, NULL))
{
- DEBUG(0,("Error: challenge not done for user=%s\n", user));
- return False;
+ DEBUG(10,("password_ok: Unix auth succeeded\n"));
+ return True;
}
-
- return pass_check_smb(user, global_myworkgroup,
- challenge, (uchar *)password, (uchar *)password, pwd);
- }
-
- return pass_check(user, password, pwlen, pwd,
- lp_update_encrypted() ?
- update_smbpassword_file : NULL);
-}
-
-/****************************************************************************
-check if a username is valid
-****************************************************************************/
-BOOL user_ok(char *user,int snum)
-{
- pstring valid, invalid;
- BOOL ret;
-
- StrnCpy(valid, lp_valid_users(snum), sizeof(pstring)-1);
- StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring)-1);
-
- pstring_sub(valid,"%S",lp_servicename(snum));
- pstring_sub(invalid,"%S",lp_servicename(snum));
-
- ret = !user_in_list(user,invalid);
-
- if (ret && valid && *valid) {
- ret = user_in_list(user,valid);
- }
-
- if (ret && lp_onlyuser(snum)) {
- char *user_list = lp_username(snum);
- pstring_sub(user_list,"%S",lp_servicename(snum));
- ret = user_in_list(user,user_list);
}
-
- return(ret);
+ return False;
}
@@ -591,86 +124,66 @@ BOOL user_ok(char *user,int snum)
/****************************************************************************
validate a group username entry. Return the username or NULL
****************************************************************************/
-static char *validate_group(char *group,char *password,int pwlen,int snum)
+static char *validate_group(char *group,char *password,int pwlen,int snum,
+ NET_USER_INFO_3 *info3)
{
-#ifdef HAVE_NETGROUP
+#if defined(HAVE_NETGROUP) && defined(HAVE_GETNETGRENT) && defined(HAVE_SETNETGRENT) && defined(HAVE_ENDNETGRENT)
+ {
+ char *host, *user, *domain;
+ setnetgrent(group);
+ while (getnetgrent(&host, &user, &domain)) {
+ if (user) {
+ if (user_ok(user, snum) &&
+ password_ok(user,NULL,password,pwlen,NULL,0,NULL,info3))
{
- char *host, *user, *domain;
- setnetgrent(group);
- while (getnetgrent(&host, &user, &domain)) {
- if (user) {
- if (user_ok(user, snum) &&
- password_ok(user,password,pwlen,NULL)) {
- endnetgrent();
- return(user);
- }
- }
- }
- endnetgrent();
+ endnetgrent();
+ return(user);
}
+ }
+ }
+ endnetgrent();
+ }
#endif
-#ifdef HAVE_GETGRENT
+#ifdef HAVE_GETGRNAM
+ {
+ struct group *gptr = (struct group *)getgrnam(group);
+ char **member;
+ if (gptr)
+ {
+ member = gptr->gr_mem;
+ while (member && *member)
+ {
+ static fstring name;
+ fstrcpy(name,*member);
+ if (user_ok(name,snum) &&
+ password_ok(name,NULL,password,pwlen,NULL,0,NULL, info3))
+ return(&name[0]);
+ member++;
+ }
+#ifdef GROUP_CHECK_PWENT
{
- struct group *gptr;
- setgrent();
- while ((gptr = (struct group *)getgrent())) {
- if (strequal(gptr->gr_name,group))
- break;
- }
-
- /*
- * As user_ok can recurse doing a getgrent(), we must
- * copy the member list into a pstring on the stack before
- * use. Bug pointed out by leon@eatworms.swmed.edu.
- */
-
- if (gptr) {
- pstring member_list;
- char *member;
- size_t copied_len = 0;
- int i;
-
- *member_list = '\0';
- member = member_list;
-
- for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) {
- size_t member_len = strlen(gptr->gr_mem[i]) + 1;
- if( copied_len + member_len < sizeof(pstring)) {
-
- DEBUG(10,("validate_group: = gr_mem = %s\n", gptr->gr_mem[i]));
-
- safe_strcpy(member, gptr->gr_mem[i], sizeof(pstring) - copied_len - 1);
- copied_len += member_len;
- member += copied_len;
- } else {
- *member = '\0';
- }
- }
-
- endgrent();
-
- member = member_list;
- while (*member) {
- static fstring name;
- fstrcpy(name,member);
- if (user_ok(name,snum) &&
- password_ok(name,password,pwlen,NULL)) {
- endgrent();
- return(&name[0]);
- }
-
- DEBUG(10,("validate_group = member = %s\n", member));
-
- member += strlen(member) + 1;
- }
- } else {
- endgrent();
- return NULL;
- }
+ struct passwd *pwd;
+ static fstring tm;
+
+ setpwent ();
+ while (pwd = getpwent ()) {
+ if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) {
+ /* This Entry have PASSWORD and same GID then check pwd */
+ if (password_ok(NULL, NULL, password, pwlen, NULL, 0, pwd, user_sess_key)) {
+ fstrcpy(tm, pwd->pw_name);
+ endpwent ();
+ return tm;
+ }
+ }
+ }
+ endpwent ();
}
+#endif /* GROUP_CHECK_PWENT */
+ }
+ }
#endif
- return(NULL);
+ return(NULL);
}
@@ -678,15 +191,18 @@ static char *validate_group(char *group,char *password,int pwlen,int snum)
/****************************************************************************
check for authority to login to a service with a given username/password
****************************************************************************/
-BOOL authorise_login(int snum,char *user,char *password, int pwlen,
- BOOL *guest,BOOL *force,uint16 vuid)
+BOOL authorise_login(int snum, char *user, char *domain,
+ char *password, int pwlen,
+ BOOL *guest,BOOL *force,
+ const vuser_key *key)
{
- BOOL ok = False;
-
- *guest = False;
-
+ BOOL ok = False;
+
+ DEBUG(0,("authorise_login: TODO. split function, it's 6 levels!\n"));
+ *guest = False;
+
#if DEBUG_PASSWORD
- DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password));
+ DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password));
#endif
/* there are several possibilities:
@@ -701,133 +217,152 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen,
if the service is guest_only then steps 1 to 5 are skipped
*/
- if (GUEST_ONLY(snum)) *force = True;
+ if (GUEST_ONLY(snum)) *force = True;
- if (!(GUEST_ONLY(snum) && GUEST_OK(snum)))
- {
+ if (!(GUEST_ONLY(snum) && GUEST_OK(snum)))
+ {
+ user_struct *vuser = get_valid_user_struct(key);
- user_struct *vuser = get_valid_user_struct(vuid);
+ /* check the given username and password */
+ if (!ok && (*user) && user_ok(user,snum))
+ {
+ ok = password_ok(user,domain, password, pwlen, NULL, 0, NULL, &vuser->usr);
+ if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
+ }
- /* check the given username and password */
- if (!ok && (*user) && user_ok(user,snum)) {
- ok = password_ok(user,password, pwlen, NULL);
- if (ok) DEBUG(3,("ACCEPTED: given username password ok\n"));
- }
+ /* check for a previously registered guest username */
+ if (!ok && (vuser != 0) && vuser->guest)
+ {
+ if (user_ok(vuser->name,snum) &&
+ password_ok(vuser->name, domain, password, pwlen, NULL, 0, NULL, &vuser->usr))
+ {
+ fstrcpy(user, vuser->name);
+ vuser->guest = False;
+ DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
+ ok = True;
+ }
+ }
- /* check for a previously registered guest username */
- if (!ok && (vuser != 0) && vuser->guest) {
- if (user_ok(vuser->name,snum) &&
- password_ok(vuser->name, password, pwlen, NULL)) {
- fstrcpy(user, vuser->name);
- vuser->guest = False;
- DEBUG(3,("ACCEPTED: given password with registered user %s\n", user));
- ok = True;
- }
- }
+ /* now check the list of session users */
+ if (!ok)
+ {
+ char *auser;
+ char *user_list = strdup(session_users);
+ if (!user_list)
+ {
+ vuid_free_user_struct(vuser);
+ return False;
+ }
- /* now check the list of session users */
- if (!ok)
- {
- char *auser;
- char *user_list = strdup(session_users);
- if (!user_list) return(False);
+ for (auser=strtok(user_list,LIST_SEP);
+ !ok && auser;
+ auser = strtok(NULL,LIST_SEP))
+ {
+ fstring user2;
+ fstrcpy(user2,auser);
+ if (!user_ok(user2,snum)) continue;
+
+ if (password_ok(user2, domain, password, pwlen, NULL, 0, NULL,
+ &vuser->usr))
+ {
+ ok = True;
+ fstrcpy(user,user2);
+ DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
+ }
+ }
+ free(user_list);
+ }
- for (auser=strtok(user_list,LIST_SEP);
- !ok && auser;
- auser = strtok(NULL,LIST_SEP))
- {
- fstring user2;
- fstrcpy(user2,auser);
- if (!user_ok(user2,snum)) continue;
-
- if (password_ok(user2,password, pwlen, NULL)) {
- ok = True;
- fstrcpy(user,user2);
- DEBUG(3,("ACCEPTED: session list username and given password ok\n"));
- }
- }
- free(user_list);
- }
+ /* check for a previously validated username/password pair */
+ if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE) &&
+ (vuser != 0) && !vuser->guest &&
+ user_ok(vuser->name,snum))
+ {
+ fstrcpy(user,vuser->name);
+ *guest = False;
+ DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n"));
+ ok = True;
+ }
- /* check for a previously validated username/password pair */
- if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE) &&
- (vuser != 0) && !vuser->guest &&
- user_ok(vuser->name,snum)) {
- fstrcpy(user,vuser->name);
- *guest = False;
- DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n"));
- ok = True;
- }
+ /* check for a rhosts entry */
+ if (!ok && user_ok(user,snum) && check_hosts_equiv(user))
+ {
+ ok = True;
+ DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n"));
+ }
- /* check for a rhosts entry */
- if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) {
- ok = True;
- DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n"));
- }
+ /* check the user= fields and the given password */
+ if (!ok && lp_username(snum))
+ {
+ char *auser;
+ pstring user_list;
+ StrnCpy(user_list,lp_username(snum),sizeof(pstring));
- /* check the user= fields and the given password */
- if (!ok && lp_username(snum)) {
- char *auser;
- pstring user_list;
- StrnCpy(user_list,lp_username(snum),sizeof(pstring));
+ string_sub(user_list,"%S",lp_servicename(snum));
- pstring_sub(user_list,"%S",lp_servicename(snum));
-
- for (auser=strtok(user_list,LIST_SEP);
- auser && !ok;
- auser = strtok(NULL,LIST_SEP))
- {
- if (*auser == '@')
- {
- auser = validate_group(auser+1,password,pwlen,snum);
- if (auser)
- {
- ok = True;
- fstrcpy(user,auser);
- DEBUG(3,("ACCEPTED: group username and given password ok\n"));
- }
- }
- else
- {
- fstring user2;
- fstrcpy(user2,auser);
- if (user_ok(user2,snum) &&
- password_ok(user2,password,pwlen,NULL))
- {
- ok = True;
- fstrcpy(user,user2);
- DEBUG(3,("ACCEPTED: user list username and given password ok\n"));
- }
- }
- }
- }
- } /* not guest only */
+ for (auser=strtok(user_list,LIST_SEP);
+ auser && !ok;
+ auser = strtok(NULL,LIST_SEP))
+ {
+ if (*auser == '@')
+ {
+ auser = validate_group(auser+1,password,pwlen,snum, &vuser->usr);
+ if (auser)
+ {
+ ok = True;
+ fstrcpy(user,auser);
+ DEBUG(3,("ACCEPTED: group username and given password ok\n"));
+ }
+ }
+ else
+ {
+ fstring user2;
+ fstrcpy(user2,auser);
+ if (user_ok(user2,snum) &&
+ password_ok(user2,domain,password,pwlen,NULL, 0,
+ NULL, &vuser->usr))
+ {
+ ok = True;
+ fstrcpy(user,user2);
+ DEBUG(3,("ACCEPTED: user list username and given password ok\n"));
+ }
+ }
+ }
+ }
- /* check for a normal guest connection */
- if (!ok && GUEST_OK(snum))
- {
- fstring guestname;
- StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
- if (Get_Pwnam(guestname,True))
+ if (vuser != NULL)
+ {
+ tdb_store_vuid(key, vuser);
+ }
+ vuid_free_user_struct(vuser);
+
+ } /* not guest only */
+
+ /* check for a normal guest connection */
+ if (!ok && GUEST_OK(snum))
{
- fstrcpy(user,guestname);
- ok = True;
- DEBUG(3,("ACCEPTED: guest account and guest ok\n"));
+ fstring guestname;
+ StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1);
+ if (Get_Pwnam(guestname,True))
+ {
+ fstrcpy(user,guestname);
+ ok = True;
+ DEBUG(3,("ACCEPTED: guest account and guest ok\n"));
+ }
+ else
+ DEBUG(0,("Invalid guest account %s??\n",guestname));
+ *guest = True;
+ *force = True;
}
- else
- DEBUG(0,("Invalid guest account %s??\n",guestname));
- *guest = True;
- *force = True;
- }
- if (ok && !user_ok(user,snum))
- {
- DEBUG(0,("rejected invalid user %s\n",user));
- ok = False;
- }
+ if (ok && !user_ok(user,snum))
+ {
+ DEBUG(0,("rejected invalid user %s\n",user));
+ ok = False;
+ }
- return(ok);
+ return(ok);
}
@@ -943,577 +478,30 @@ BOOL check_hosts_equiv(char *user)
{
char *fname = NULL;
pstring rhostsfile;
- struct passwd *pass = Get_Pwnam(user,True);
+ const struct passwd *pass = Get_Pwnam(user,True);
if (!pass)
- return(False);
+ return False;
fname = lp_hosts_equiv();
/* note: don't allow hosts.equiv on root */
if (fname && *fname && (pass->pw_uid != 0)) {
- extern int Client;
- if (check_user_equiv(user,client_name(Client),fname))
+ if (check_user_equiv(user,client_connection_name(),fname))
return(True);
}
if (lp_use_rhosts())
{
- char *home = get_user_home_dir(user);
+ char *home = get_unixhome_dir(user);
if (home) {
- extern int Client;
slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
- if (check_user_equiv(user,client_name(Client),rhostsfile))
+ if (check_user_equiv(user,client_connection_name(),rhostsfile))
return(True);
}
}
- return(False);
-}
-
-
-/****************************************************************************
- Return the client state structure.
-****************************************************************************/
-
-struct cli_state *server_client(void)
-{
- static struct cli_state pw_cli;
- return &pw_cli;
-}
-
-/****************************************************************************
- Support for server level security.
-****************************************************************************/
-
-struct cli_state *server_cryptkey(void)
-{
- struct cli_state *cli;
- fstring desthost;
- struct in_addr dest_ip;
- char *p, *pserver;
- BOOL connected_ok = False;
-
- cli = server_client();
-
- if (!cli_initialise(cli))
- return NULL;
-
- pserver = strdup(lp_passwordserver());
- p = pserver;
-
- while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) {
- standard_sub_basic(desthost);
- strupper(desthost);
-
- if(!resolve_name( desthost, &dest_ip, 0x20)) {
- DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost));
- continue;
- }
-
- if (ismyip(dest_ip)) {
- DEBUG(1,("Password server loop - disabling password server %s\n",desthost));
- continue;
- }
-
- if (cli_connect(cli, desthost, &dest_ip)) {
- DEBUG(3,("connected to password server %s\n",desthost));
- connected_ok = True;
- break;
- }
- }
-
- free(pserver);
-
- if (!connected_ok) {
- DEBUG(0,("password server not available\n"));
- cli_shutdown(cli);
- return NULL;
- }
-
- if (!attempt_netbios_session_request(cli, global_myname, desthost, &dest_ip))
- return NULL;
-
- DEBUG(3,("got session\n"));
-
- if (!cli_negprot(cli)) {
- DEBUG(1,("%s rejected the negprot\n",desthost));
- cli_shutdown(cli);
- return NULL;
- }
-
- if (cli->protocol < PROTOCOL_LANMAN2 ||
- !(cli->sec_mode & 1)) {
- DEBUG(1,("%s isn't in user level security mode\n",desthost));
- cli_shutdown(cli);
- return NULL;
- }
-
- DEBUG(3,("password server OK\n"));
-
- return cli;
-}
-
-/****************************************************************************
- Validate a password with the password server.
-****************************************************************************/
-
-BOOL server_validate(char *user, char *domain,
- char *pass, int passlen,
- char *ntpass, int ntpasslen)
-{
- struct cli_state *cli;
- static unsigned char badpass[24];
- static BOOL tested_password_server = False;
- static BOOL bad_password_server = False;
-
- cli = server_client();
-
- if (!cli->initialised) {
- DEBUG(1,("password server %s is not connected\n", cli->desthost));
- return(False);
- }
-
- if(badpass[0] == 0)
- memset(badpass, 0x1f, sizeof(badpass));
-
- if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) {
- /*
- * Very unlikely, our random bad password is the same as the users
- * password. */
- memset(badpass, badpass[0]+1, sizeof(badpass));
- }
-
- /*
- * Attempt a session setup with a totally incorrect password.
- * If this succeeds with the guest bit *NOT* set then the password
- * server is broken and is not correctly setting the guest bit. We
- * need to detect this as some versions of NT4.x are broken. JRA.
- */
-
- if(!tested_password_server) {
- if (cli_session_setup(cli, user, (char *)badpass, sizeof(badpass),
- (char *)badpass, sizeof(badpass), domain)) {
-
- /*
- * We connected to the password server so we
- * can say we've tested it.
- */
- tested_password_server = True;
-
- if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) {
- DEBUG(0,("server_validate: password server %s allows users as non-guest \
-with a bad password.\n", cli->desthost));
- DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \
-use this machine as the password server.\n"));
- cli_ulogoff(cli);
-
- /*
- * Password server has the bug.
- */
- bad_password_server = True;
- return False;
- }
- cli_ulogoff(cli);
- }
- } else {
-
- /*
- * We have already tested the password server.
- * Fail immediately if it has the bug.
- */
-
- if(bad_password_server) {
- DEBUG(0,("server_validate: [1] password server %s allows users as non-guest \
-with a bad password.\n", cli->desthost));
- DEBUG(0,("server_validate: [1] This is broken (and insecure) behaviour. Please do not \
-use this machine as the password server.\n"));
- return False;
- }
- }
-
- /*
- * Now we know the password server will correctly set the guest bit, or is
- * not guest enabled, we can try with the real password.
- */
-
- if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) {
- DEBUG(1,("password server %s rejected the password\n", cli->desthost));
- return False;
- }
-
- /* if logged in as guest then reject */
- if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) {
- DEBUG(1,("password server %s gave us guest only\n", cli->desthost));
- cli_ulogoff(cli);
- return(False);
- }
-
- cli_ulogoff(cli);
-
- return(True);
-}
-
-/***********************************************************************
- Connect to a remote machine for domain security authentication
- given a name or IP address.
-************************************************************************/
-
-static BOOL connect_to_domain_password_server(struct cli_state *pcli, char *remote_machine,
- unsigned char *trust_passwd)
-{
- struct in_addr dest_ip;
-
- if(cli_initialise(pcli) == False) {
- DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n"));
- return False;
- }
-
- standard_sub_basic(remote_machine);
- strupper(remote_machine);
-
- if(!resolve_name( remote_machine, &dest_ip, 0x20)) {
- DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine));
- cli_shutdown(pcli);
- return False;
- }
-
- if (ismyip(dest_ip)) {
- DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n",
- remote_machine));
- cli_shutdown(pcli);
- return False;
- }
-
- if (!cli_connect(pcli, remote_machine, &dest_ip)) {
- DEBUG(0,("connect_to_domain_password_server: unable to connect to SMB server on \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
- cli_shutdown(pcli);
- return False;
- }
-
- if (!attempt_netbios_session_request(pcli, global_myname, remote_machine, &dest_ip)) {
- DEBUG(0,("connect_to_password_server: machine %s rejected the NetBIOS \
-session request. Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
- return False;
- }
-
- pcli->protocol = PROTOCOL_NT1;
-
- if (!cli_negprot(pcli)) {
- DEBUG(0,("connect_to_domain_password_server: machine %s rejected the negotiate protocol. \
-Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
- cli_shutdown(pcli);
- return False;
- }
-
- if (pcli->protocol != PROTOCOL_NT1) {
- DEBUG(0,("connect_to_domain_password_server: machine %s didn't negotiate NT protocol.\n",
- remote_machine));
- cli_shutdown(pcli);
- return False;
- }
-
- /*
- * Do an anonymous session setup.
- */
-
- if (!cli_session_setup(pcli, "", "", 0, "", 0, "")) {
- DEBUG(0,("connect_to_domain_password_server: machine %s rejected the session setup. \
-Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
- cli_shutdown(pcli);
- return False;
- }
-
- if (!(pcli->sec_mode & 1)) {
- DEBUG(1,("connect_to_domain_password_server: machine %s isn't in user level security mode\n",
- remote_machine));
- cli_shutdown(pcli);
- return False;
- }
-
- if (!cli_send_tconX(pcli, "IPC$", "IPC", "", 1)) {
- DEBUG(0,("connect_to_domain_password_server: machine %s rejected the tconX on the IPC$ share. \
-Error was : %s.\n", remote_machine, cli_errstr(pcli) ));
- cli_shutdown(pcli);
- return False;
- }
-
- /*
- * We now have an anonymous connection to IPC$ on the domain password server.
- */
-
- /*
- * Even if the connect succeeds we need to setup the netlogon
- * pipe here. We do this as we may just have changed the domain
- * account password on the PDC and yet we may be talking to
- * a BDC that doesn't have this replicated yet. In this case
- * a successful connect to a DC needs to take the netlogon connect
- * into account also. This patch from "Bjart Kvarme" <bjart.kvarme@usit.uio.no>.
- */
-
- if(cli_nt_session_open(pcli, PIPE_NETLOGON) == False) {
- DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \
-machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli)));
- cli_nt_session_close(pcli);
- cli_ulogoff(pcli);
- cli_shutdown(pcli);
- return False;
- }
-
- if (cli_nt_setup_creds(pcli, trust_passwd) == False) {
- DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \
-%s. Error was : %s.\n", remote_machine, cli_errstr(pcli)));
- cli_nt_session_close(pcli);
- cli_ulogoff(pcli);
- cli_shutdown(pcli);
- return(False);
- }
-
- return True;
-}
-
-/***********************************************************************
- Utility function to attempt a connection to an IP address of a DC.
-************************************************************************/
-
-static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, unsigned char *trust_passwd)
-{
- fstring dc_name;
-
- /*
- * Ignore addresses we have already tried.
- */
-
- if (ip_equal(ipzero, *ip))
- return False;
-
- if (!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name))
- return False;
-
- return connect_to_domain_password_server(pcli, dc_name, trust_passwd);
-}
-
-
-
-/***********************************************************************
- We have been asked to dynamcially determine the IP addresses of
- the PDC and BDC's for this DOMAIN, and query them in turn.
-************************************************************************/
-static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd)
-{
- struct in_addr *ip_list = NULL;
- int count = 0;
- int i;
- BOOL connected_ok = False;
-
- if (!get_dc_list(lp_workgroup(), &ip_list, &count))
- return False;
-
- /*
- * Firstly try and contact a PDC/BDC who has the same
- * network address as any of our interfaces.
- */
- for(i = 0; i < count; i++) {
- if(!is_local_net(ip_list[i]))
- continue;
-
- if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd)))
- break;
-
- ip_list[i] = ipzero; /* Tried and failed. */
- }
-
- /*
- * Secondly try and contact a random PDC/BDC.
- */
- if(!connected_ok) {
- i = (sys_random() % count);
-
- if (!(connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd)))
- ip_list[i] = ipzero; /* Tried and failed. */
- }
-
- /*
- * Finally go through the IP list in turn, ignoring any addresses
- * we have already tried.
- */
- if(!connected_ok) {
- /*
- * Try and connect to any of the other IP addresses in the PDC/BDC list.
- * Note that from a WINS server the #1 IP address is the PDC.
- */
- for(i = 0; i < count; i++) {
- if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd)))
- break;
- }
- }
-
- if(ip_list != NULL)
- free((char *)ip_list);
-
-
- return connected_ok;
+ return False;
}
-
-/***********************************************************************
- Do the same as security=server, but using NT Domain calls and a session
- key from the machine password.
-************************************************************************/
-
-BOOL domain_client_validate( char *user, char *domain,
- char *smb_apasswd, int smb_apasslen,
- char *smb_ntpasswd, int smb_ntpasslen,
- BOOL *user_exists)
-{
- unsigned char local_challenge[8];
- unsigned char local_lm_response[24];
- unsigned char local_nt_reponse[24];
- unsigned char trust_passwd[16];
- fstring remote_machine;
- char *p, *pserver;
- NET_ID_INFO_CTR ctr;
- NET_USER_INFO_3 info3;
- struct cli_state cli;
- uint32 smb_uid_low;
- BOOL connected_ok = False;
-
- if(user_exists != NULL)
- *user_exists = True; /* Only set false on a very specific error. */
-
- /*
- * Check that the requested domain is not our own machine name.
- * If it is, we should never check the PDC here, we use our own local
- * password file.
- */
-
- if(strequal( domain, global_myname)) {
- DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n"));
- return False;
- }
-
- /*
- * Next, check that the passwords given were encrypted.
- */
-
- if(((smb_apasslen != 24) && (smb_apasslen != 0)) ||
- ((smb_ntpasslen != 24) && (smb_ntpasslen != 0))) {
-
- /*
- * Not encrypted - do so.
- */
-
- DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n"));
- generate_random_buffer( local_challenge, 8, False);
- SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response);
- SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_reponse);
- smb_apasslen = 24;
- smb_ntpasslen = 24;
- smb_apasswd = (char *)local_lm_response;
- smb_ntpasswd = (char *)local_nt_reponse;
- } else {
-
- /*
- * Encrypted - get the challenge we sent for these
- * responses.
- */
-
- if (!last_challenge(local_challenge)) {
- DEBUG(0,("domain_client_validate: no challenge done - password failed\n"));
- return False;
- }
- }
-
- /*
- * Get the machine account password.
- */
- if (!trust_get_passwd( trust_passwd, global_myworkgroup, global_myname))
- {
- return False;
- }
-
- /*
- * At this point, smb_apasswd points to the lanman response to
- * the challenge in local_challenge, and smb_ntpasswd points to
- * the NT response to the challenge in local_challenge. Ship
- * these over the secure channel to a domain controller and
- * see if they were valid.
- */
-
- ZERO_STRUCT(cli);
-
- /*
- * Treat each name in the 'password server =' line as a potential
- * PDC/BDC. Contact each in turn and try and authenticate.
- */
-
- pserver = strdup(lp_passwordserver());
- p = pserver;
-
- while (!connected_ok &&
- next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) {
- if(strequal(remote_machine, "*")) {
- connected_ok = find_connect_pdc(&cli, trust_passwd);
- } else {
- connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd);
- }
- }
-
- free(pserver);
-
- if (!connected_ok) {
- DEBUG(0,("domain_client_validate: Domain password server not available.\n"));
- cli_shutdown(&cli);
- return False;
- }
-
- /* We really don't care what LUID we give the user. */
- generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False);
-
- if(cli_nt_login_network(&cli, domain, user, smb_uid_low, (char *)local_challenge,
- ((smb_apasslen != 0) ? smb_apasswd : NULL),
- ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL),
- &ctr, &info3) == False) {
- uint32 nt_rpc_err;
-
- cli_error(&cli, NULL, NULL, &nt_rpc_err);
- DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \
-%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
-
- if((nt_rpc_err == NT_STATUS_NO_SUCH_USER) && (user_exists != NULL))
- *user_exists = False;
-
- return False;
- }
-
- /*
- * Here, if we really want it, we have lots of info about the user in info3.
- */
-
-#if 0
- /*
- * We don't actually need to do this - plus it fails currently with
- * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to
- * send here. JRA.
- */
-
- if(cli_nt_logoff(&cli, &ctr) == False) {
- DEBUG(0,("domain_client_validate: unable to log off user %s in domain \
-%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli)));
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return False;
- }
-#endif /* 0 */
-
- cli_nt_session_close(&cli);
- cli_ulogoff(&cli);
- cli_shutdown(&cli);
- return True;
-}
diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c
index 1a9ac1d7a4c..b4e3e3a0d17 100644
--- a/source/smbd/pipes.c
+++ b/source/smbd/pipes.c
@@ -51,6 +51,7 @@ int reply_open_pipe_and_X(connection_struct *conn,
int smb_ofun = SVAL(inbuf,smb_vwv8);
int size=0,fmode=0,mtime=0,rmode=0;
int i;
+ vuser_key key;
/* XXXX we need to handle passed times, sattr and flags */
pstrcpy(fname,smb_buf(inbuf));
@@ -74,18 +75,14 @@ int reply_open_pipe_and_X(connection_struct *conn,
/* Strip \PIPE\ off the name. */
pstrcpy(fname,smb_buf(inbuf) + PIPELEN);
- /*
- * Hack for NT printers... JRA.
- */
- if(should_fail_next_srvsvc_open(fname))
- return(ERROR(ERRSRV,ERRaccess));
-
/* Known pipes arrive with DIR attribs. Remove it so a regular file */
/* can be opened and add it in after the open. */
DEBUG(3,("Known pipe %s opening.\n",fname));
- smb_ofun |= FILE_CREATE_IF_NOT_EXIST;
+ smb_ofun |= 0x10; /* Add Create it not exists flag */
- p = open_rpc_pipe_p(fname, conn, vuid);
+ key.pid = getpid();
+ key.vuid = vuid;
+ p = open_rpc_pipe_p(fname, &key, NULL);
if (!p) return(ERROR(ERRSRV,ERRnofids));
/* Prepare the reply */
@@ -111,46 +108,47 @@ int reply_open_pipe_and_X(connection_struct *conn,
}
/****************************************************************************
- reply to a write on a pipe
+ reply to a write
+
+ This code is basically stolen from reply_write with some
+ wrinkles to handle pipes.
****************************************************************************/
-int reply_pipe_write(char *inbuf,char *outbuf,int length,int dum_bufsize)
+int reply_pipe_write(char *inbuf,char *outbuf,int length,int bufsize)
{
pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
size_t numtowrite = SVAL(inbuf,smb_vwv1);
- int nwritten;
- int outsize;
+ int nwritten = -1;
char *data;
+ size_t outsize;
- if (!p)
- return(ERROR(ERRDOS,ERRbadfid));
+ if (!p) return(ERROR(ERRDOS,ERRbadfid));
data = smb_buf(inbuf) + 3;
if (numtowrite == 0)
+ {
nwritten = 0;
+ }
else
{
- if (p->m != NULL)
- {
- nwritten = write_pipe(p, data, numtowrite);
- }
- else
- {
- nwritten = write_to_pipe(p, data, numtowrite);
- }
+ nwritten = write_pipe(p, data, numtowrite);
}
if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
+ {
+ DEBUG(3,("reply_write_pipe: nwritten: %d numtowrite:%d\n",
+ nwritten, numtowrite));
return (UNIXERROR(ERRDOS,ERRnoaccess));
+ }
outsize = set_message(outbuf,1,0,True);
SSVAL(outbuf,smb_vwv0,nwritten);
-
+
DEBUG(3,("write-IPC pnum=%04x nwritten=%d\n",
p->pnum, nwritten));
- return(outsize);
+ return outsize;
}
/****************************************************************************
@@ -165,20 +163,37 @@ int reply_pipe_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
size_t numtowrite = SVAL(inbuf,smb_vwv10);
int nwritten = -1;
int smb_doff = SVAL(inbuf, smb_vwv11);
+ int write_mode = SVAL(inbuf, smb_vwv7);
char *data;
- if (!p)
- return(ERROR(ERRDOS,ERRbadfid));
+ if (!p) return(ERROR(ERRDOS,ERRbadfid));
data = smb_base(inbuf) + smb_doff;
if (numtowrite == 0)
+ {
nwritten = 0;
+ }
else
- nwritten = write_to_pipe(p, data, numtowrite);
+ {
+ if (write_mode == 0x000c)
+ {
+ nwritten = write_pipe(p, data+2, numtowrite-2);
+ if (nwritten != 0)
+ {
+ nwritten += 2;
+ }
+ }
+ else
+ {
+ nwritten = write_pipe(p, data, numtowrite);
+ }
+ }
if ((nwritten == 0 && numtowrite != 0) || (nwritten < 0))
+ {
return (UNIXERROR(ERRDOS,ERRnoaccess));
+ }
set_message(outbuf,6,0,True);
@@ -203,27 +218,13 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
int smb_mincnt = SVAL(inbuf,smb_vwv6);
int nread = -1;
char *data;
- /* we don't use the offset given to use for pipe reads. This
- is deliberate, instead we always return the next lump of
- data on the pipe */
-#if 0
- uint32 smb_offs = IVAL(inbuf,smb_vwv3);
-#endif
- if (!p)
- return(ERROR(ERRDOS,ERRbadfid));
+ if (!p) return(ERROR(ERRDOS,ERRbadfid));
set_message(outbuf,12,0,True);
data = smb_buf(outbuf);
- if (p->m != NULL)
- {
- nread = read_pipe(p, data, smb_maxcnt);
- }
- else
- {
- nread = read_from_pipe(p, data, smb_maxcnt);
- }
+ nread = read_pipe(p, data, smb_maxcnt);
if (nread < 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -246,13 +247,12 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf)
pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0);
int outsize = set_message(outbuf,0,0,True);
- if (!p)
- return(ERROR(ERRDOS,ERRbadfid));
+ if (!p) return(ERROR(ERRDOS,ERRbadfid));
DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum));
- if (!close_rpc_pipe_hnd(p, conn))
- return(ERROR(ERRDOS,ERRbadfid));
+ if (!close_rpc_pipe_hnd(p)) return(ERROR(ERRDOS,ERRbadfid));
return(outsize);
}
+
diff --git a/source/smbd/predict.c b/source/smbd/predict.c
index 34044b82f22..f51e54a568c 100644
--- a/source/smbd/predict.c
+++ b/source/smbd/predict.c
@@ -37,7 +37,7 @@ static int rp_timeout = 5;
static time_t rp_time = 0;
static char *rp_buffer = NULL;
static BOOL predict_skip=False;
-extern struct timeval smb_last_time;
+extern time_t smb_last_time;
/****************************************************************************
handle read prediction on a file
@@ -53,7 +53,7 @@ ssize_t read_predict(files_struct *fsp, int fd,SMB_OFF_T offset,char *buf,char *
if (fd == rp_fd &&
offset >= rp_offset &&
possible>0 &&
- smb_last_time.tv_secs - rp_time < rp_timeout)
+ smb_last_time-rp_time < rp_timeout)
{
ret = possible;
if (buf)
diff --git a/source/smbd/process.c b/source/smbd/process.c
index 7d6e171d053..0af59cd345f 100644
--- a/source/smbd/process.c
+++ b/source/smbd/process.c
@@ -23,9 +23,9 @@
extern int DEBUGLEVEL;
-struct timeval smb_last_time;
+time_t smb_last_time=(time_t)0;
-static char *InBuffer = NULL;
+char *InBuffer = NULL;
char *OutBuffer = NULL;
char *last_inbuf = NULL;
@@ -48,8 +48,7 @@ extern char *last_inbuf;
extern char *InBuffer;
extern char *OutBuffer;
extern int smb_read_error;
-extern VOLATILE SIG_ATOMIC_T reload_after_sighup;
-extern BOOL global_machine_password_needs_changing;
+extern BOOL reload_after_sighup;
extern fstring global_myworkgroup;
extern pstring global_myname;
extern int max_send;
@@ -173,7 +172,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len,
to.tv_sec = timeout / 1000;
to.tv_usec = (timeout % 1000) * 1000;
- selrtn = sys_select(MAX(maxfd,Client)+1,&fds,timeout>0?&to:NULL);
+ selrtn = sys_select(MAX(maxfd,Client)+1,&fds,NULL, timeout>0?&to:NULL);
/* Check if error */
if(selrtn == -1) {
@@ -231,52 +230,6 @@ BOOL receive_next_smb(char *inbuf, int bufsize, int timeout)
return ret;
}
-/****************************************************************************
- We're terminating and have closed all our files/connections etc.
- If there are any pending local messages we need to respond to them
- before termination so that other smbds don't think we just died whilst
- holding oplocks.
-****************************************************************************/
-
-void respond_to_all_remaining_local_messages(void)
-{
- char buffer[1024];
- fd_set fds;
-
- /*
- * Assert we have no exclusive open oplocks.
- */
-
- if(get_number_of_exclusive_open_oplocks()) {
- DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
- get_number_of_exclusive_open_oplocks() ));
- return;
- }
-
- /*
- * Setup the select read fd set.
- */
-
- FD_ZERO(&fds);
- if(!setup_oplock_select_set(&fds))
- return;
-
- /*
- * Keep doing receive_local_message with a 1 ms timeout until
- * we have no more messages.
- */
-
- while(receive_local_message(&fds, buffer, sizeof(buffer), 1)) {
- /* Deal with oplock break requests from other smbd's. */
- process_local_message(buffer, sizeof(buffer));
-
- FD_ZERO(&fds);
- (void)setup_oplock_select_set(&fds);
- }
-
- return;
-}
-
/*
These flags determine some of the permissions required to do an operation
@@ -329,8 +282,8 @@ struct smb_message_struct
{SMBunlink,"SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
{SMBread,"SMBread",reply_read,AS_USER},
- {SMBwrite,"SMBwrite",reply_write,AS_USER | CAN_IPC },
- {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC },
+ {SMBwrite,"SMBwrite",reply_write,AS_USER | CAN_IPC},
+ {SMBclose,"SMBclose",reply_close,AS_USER | CAN_IPC},
{SMBmkdir,"SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
{SMBrmdir,"SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
{SMBdskattr,"SMBdskattr",reply_dskattr,AS_USER},
@@ -365,9 +318,9 @@ struct smb_message_struct
{SMBwriteBmpx,"SMBwriteBmpx",reply_writebmpx,AS_USER},
{SMBwriteBs,"SMBwriteBs",reply_writebs,AS_USER},
{SMBwritec,"SMBwritec",NULL,AS_USER},
- {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
- {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER },
- {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
+ {SMBsetattrE,"SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE},
+ {SMBgetattrE,"SMBgetattrE",reply_getattrE,AS_USER},
+ {SMBtrans,"SMBtrans",reply_trans,AS_USER | CAN_IPC},
{SMBtranss,"SMBtranss",NULL,AS_USER | CAN_IPC},
{SMBioctls,"SMBioctls",NULL,AS_USER},
{SMBcopy,"SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
@@ -376,7 +329,7 @@ struct smb_message_struct
{SMBopenX,"SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
{SMBreadX,"SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
{SMBwriteX,"SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
- {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER },
+ {SMBlockingX,"SMBlockingX",reply_lockingX,AS_USER},
{SMBffirst,"SMBffirst",reply_search,AS_USER},
{SMBfunique,"SMBfunique",reply_search,AS_USER},
@@ -385,14 +338,14 @@ struct smb_message_struct
/* LANMAN2.0 PROTOCOL FOLLOWS */
{SMBfindnclose, "SMBfindnclose", reply_findnclose, AS_USER},
{SMBfindclose, "SMBfindclose", reply_findclose,AS_USER},
- {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | QUEUE_IN_OPLOCK },
+ {SMBtrans2, "SMBtrans2", reply_trans2, AS_USER | CAN_IPC},
{SMBtranss2, "SMBtranss2", reply_transs2, AS_USER},
/* NT PROTOCOL FOLLOWS */
{SMBntcreateX, "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
- {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
+ {SMBnttrans, "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC },
{SMBnttranss, "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
- {SMBntcancel, "SMBntcancel", reply_ntcancel, 0 },
+ {SMBntcancel, "SMBntcancel", reply_ntcancel, AS_USER },
/* messaging routines */
{SMBsends,"SMBsends",reply_sends,AS_GUEST},
@@ -414,15 +367,14 @@ do a switch on the message type, and return the response size
****************************************************************************/
static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
{
- static pid_t pid= (pid_t)-1;
+ static int pid= -1;
int outsize = 0;
static int num_smb_messages =
sizeof(smb_messages) / sizeof(struct smb_message_struct);
int match;
extern int Client;
- extern int global_smbpid;
- if (pid == (pid_t)-1)
+ if (pid == -1)
pid = getpid();
errno = 0;
@@ -439,10 +391,6 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
if (smb_messages[match].code == type)
break;
- /* yuck! this is an interim measure before we get rid of our
- current inbuf/outbuf system */
- global_smbpid = SVAL(inbuf,smb_pid);
-
if (match == num_smb_messages)
{
DEBUG(0,("Unknown message type %d!\n",type));
@@ -450,25 +398,21 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
}
else
{
- DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,(int)pid));
+ DEBUG(3,("switch message %s (pid %d)\n",smb_messages[match].name,pid));
- if(global_oplock_break)
+ if(global_oplock_break && (smb_messages[match].flags & QUEUE_IN_OPLOCK))
{
- int flags = smb_messages[match].flags;
+ /*
+ * Queue this message as we are the process of an oplock break.
+ */
- if(flags & QUEUE_IN_OPLOCK)
- {
- /*
- * Queue this message as we are the process of an oplock break.
- */
+ DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
+ DEBUGADD( 2, ( "oplock break state.\n" ) );
- DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
- DEBUGADD( 2, ( "oplock break state.\n" ) );
+ push_oplock_pending_smb_message( inbuf, size );
+ return -1;
+ }
- push_oplock_pending_smb_message( inbuf, size );
- return -1;
- }
- }
if (smb_messages[match].fn)
{
int flags = smb_messages[match].flags;
@@ -490,14 +434,21 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
* move it unless you know what you're doing... :-).
* JRA.
*/
- if (session_tag != last_session_tag) {
+ if (session_tag != last_session_tag)
+ {
user_struct *vuser = NULL;
+ vuser_key key;
+ key.pid = pid;
+ key.vuid = session_tag;
last_session_tag = session_tag;
if(session_tag != UID_FIELD_INVALID)
- vuser = get_valid_user_struct(session_tag);
+ vuser = get_valid_user_struct(&key);
if(vuser != NULL)
+ {
pstrcpy( sesssetup_user, vuser->requested_name);
+ vuid_free_user_struct(vuser);
+ }
}
/* does this protocol need to be run as root? */
@@ -509,7 +460,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
if (flags & AS_GUEST)
flags &= ~AS_USER;
else
- return(ERROR(ERRSRV,ERRaccess));
+ return(ERROR(ERRSRV,ERRinvnid));
}
/* this code is to work around a bug is MS client 3 without
introducing a security hole - it needs to be able to do
@@ -561,8 +512,9 @@ static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
int type = CVAL(inbuf,smb_com);
int outsize = 0;
int msg_type = CVAL(inbuf,0);
+ extern int chain_size;
- GetTimeOfDay(&smb_last_time);
+ smb_last_time = time(NULL);
chain_size = 0;
file_chain_reset();
@@ -613,7 +565,7 @@ void process_smb(char *inbuf, char *outbuf)
name" */
static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
DEBUG( 1, ( "Connection denied from %s\n",
- client_addr(Client) ) );
+ client_connection_addr() ) );
send_smb(Client,(char *)buf);
exit_server("connection denied");
}
@@ -694,7 +646,7 @@ char *smb_fn_name(int type)
void construct_reply_common(char *inbuf,char *outbuf)
{
- memset(outbuf,'\0',smb_size);
+ bzero(outbuf,smb_size);
set_message(outbuf,0,0,True);
CVAL(outbuf,smb_com) = CVAL(inbuf,smb_com);
@@ -725,6 +677,7 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
int outsize2;
char inbuf_saved[smb_wct];
char outbuf_saved[smb_wct];
+ extern int chain_size;
int wct = CVAL(outbuf,smb_wct);
int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
@@ -740,14 +693,6 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
orig_outbuf = outbuf;
}
- /*
- * The original Win95 redirector dies on a reply to
- * a lockingX and read chain unless the chain reply is
- * 4 byte aligned. JRA.
- */
-
- outsize = (outsize + 3) & ~3;
-
/* we need to tell the client where the next part of the reply will be */
SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
CVAL(outbuf,smb_vwv0) = smb_com2;
@@ -802,214 +747,71 @@ int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
}
/****************************************************************************
- Setup the needed select timeout.
-****************************************************************************/
-
-static int setup_select_timeout(void)
-{
- int change_notify_timeout = lp_change_notify_timeout() * 1000;
- int select_timeout;
-
- /*
- * Increase the select timeout back to SMBD_SELECT_TIMEOUT if we
- * have removed any blocking locks. JRA.
- */
-
- select_timeout = blocking_locks_pending() ? SMBD_SELECT_TIMEOUT_WITH_PENDING_LOCKS*1000 :
- SMBD_SELECT_TIMEOUT*1000;
-
- if (change_notifies_pending())
- select_timeout = MIN(select_timeout, change_notify_timeout);
-
- return select_timeout;
-}
-
-/****************************************************************************
- Check if services need reloading.
-****************************************************************************/
-
-void check_reload(int t)
-{
- static time_t last_smb_conf_reload_time = 0;
-
- if(last_smb_conf_reload_time == 0)
- last_smb_conf_reload_time = t;
-
- if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK))
- {
- reload_services(True);
- reload_after_sighup = False;
- last_smb_conf_reload_time = t;
- }
-}
-
-/****************************************************************************
- Process any timeout housekeeping. Return False if the caller should exit.
+ process commands from the client
****************************************************************************/
-
-static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_timeout_processing_time)
+void smbd_process(void)
{
extern int Client;
- static time_t last_keepalive_sent_time = 0;
- static time_t last_idle_closed_check = 0;
- time_t t;
- BOOL allidle = True;
- extern int keepalive;
-
- if (smb_read_error == READ_EOF)
- {
- DEBUG(3,("end of file from client\n"));
- return False;
- }
-
- if (smb_read_error == READ_ERROR)
- {
- DEBUG(3,("receive_smb error (%s) exiting\n",
- strerror(errno)));
- return False;
- }
-
- *last_timeout_processing_time = t = time(NULL);
+ extern int ClientPort;
- if(last_keepalive_sent_time == 0)
- last_keepalive_sent_time = t;
-
- if(last_idle_closed_check == 0)
- last_idle_closed_check = t;
-
- /* become root again if waiting */
- unbecome_user();
+ InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+ OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
+ if ((InBuffer == NULL) || (OutBuffer == NULL))
+ return;
- /* check if we need to reload services */
- check_reload(t);
+ InBuffer += SMB_ALIGNMENT;
+ OutBuffer += SMB_ALIGNMENT;
- /* automatic timeout if all connections are closed */
- if (conn_num_open()==0 && (t - last_idle_closed_check) >= IDLE_CLOSED_TIMEOUT)
+#if PRIME_NMBD
+ DEBUG(3,("priming nmbd\n"));
{
- DEBUG( 2, ( "Closing idle connection\n" ) );
- return False;
+ struct in_addr ip;
+ ip = *interpret_addr2("localhost");
+ if (zero_ip(ip)) ip = *interpret_addr2("127.0.0.1");
+ *OutBuffer = 0;
+ send_one_packet(OutBuffer,1,ip,NMB_PORT,SOCK_DGRAM);
}
- else
- last_idle_closed_check = t;
+#endif
- if (keepalive && (t - last_keepalive_sent_time)>keepalive)
- {
- struct cli_state *cli = server_client();
- if (!send_keepalive(Client)) {
- DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
- return False;
- }
- /* also send a keepalive to the password server if its still
- connected */
- if (cli && cli->initialised)
- send_keepalive(cli->fd);
- last_keepalive_sent_time = t;
- }
- /* check for connection timeouts */
- allidle = conn_idle_all(t, deadtime);
+ max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
- if (allidle && conn_num_open()>0) {
- DEBUG(2,("Closing idle connection 2.\n"));
- return False;
- }
+ /* re-initialise the timezone */
+ TimeInit();
- if(global_machine_password_needs_changing)
+ /* if connection on port 445, fake session setup... */
+ if(ClientPort == 445)
{
- unsigned char trust_passwd_hash[16];
- time_t lct;
- pstring remote_machine_list;
-
- /*
- * We're in domain level security, and the code that
- * read the machine password flagged that the machine
- * password needs changing.
- */
-
- /*
- * First, open the machine password file with an exclusive lock.
- */
-
- if(!trust_password_lock( global_myworkgroup, global_myname, True)) {
- DEBUG(0,("process: unable to open the machine account password file for \
-machine %s in domain %s.\n", global_myname, global_myworkgroup ));
- return True;
- }
+ extern fstring remote_machine;
+ extern fstring local_machine;
- if(!get_trust_account_password( trust_passwd_hash, &lct)) {
- DEBUG(0,("process: unable to read the machine account password for \
-machine %s in domain %s.\n", global_myname, global_myworkgroup ));
- trust_password_unlock();
- return True;
- }
+ fstrcpy(remote_machine, dns_to_netbios_name(client_connection_name()));
+ fstrcpy(local_machine, global_myname);
+ remote_machine[15] = 0;
+ local_machine[15] = 0;
+ strlower(remote_machine);
+ strlower(local_machine);
- /*
- * Make sure someone else hasn't already done this.
- */
+ DEBUG(2, ("smbd_process(): faking session setup\n"
+ "client_name: %s my_name: %s\n", remote_machine, local_machine));
- if(t < lct + lp_machine_password_timeout()) {
- trust_password_unlock();
- global_machine_password_needs_changing = False;
- return True;
- }
+ add_session_user(remote_machine);
- pstrcpy(remote_machine_list, lp_passwordserver());
+ reload_services(True);
+ reopen_logs();
- change_trust_account_password( global_myworkgroup, remote_machine_list);
- trust_password_unlock();
- global_machine_password_needs_changing = False;
+ if(lp_status(-1)) {
+ claim_connection(NULL,"STATUS.",MAXSTATUS,True);
+ }
}
- /*
- * Check to see if we have any blocking locks
- * outstanding on the queue.
- */
- process_blocking_lock_queue(t);
-
- /*
- * Check to see if we have any change notifies
- * outstanding on the queue.
- */
- process_pending_change_notify_queue(t);
-
- /*
- * Modify the select timeout depending upon
- * what we have remaining in our queues.
- */
-
- *select_timeout = setup_select_timeout();
-
- return True;
-}
-
-/****************************************************************************
- process commands from the client
-****************************************************************************/
-
-void smbd_process(void)
-{
- extern int smb_echo_count;
- time_t last_timeout_processing_time = time(NULL);
- unsigned int num_smbs = 0;
-
- InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- OutBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN);
- if ((InBuffer == NULL) || (OutBuffer == NULL))
- return;
-
- InBuffer += SMB_ALIGNMENT;
- OutBuffer += SMB_ALIGNMENT;
-
- max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
-
- /* re-initialise the timezone */
- TimeInit();
-
while (True)
{
int deadtime = lp_deadtime()*60;
+ int counter;
+ int last_keepalive=0;
+ int service_load_counter = 0;
BOOL got_smb = False;
- int select_timeout = setup_select_timeout();
if (deadtime <= 0)
deadtime = DEFAULT_SMBD_TIMEOUT;
@@ -1021,55 +823,106 @@ void smbd_process(void)
errno = 0;
- /* free up temporary memory */
- lp_talloc_free();
-
- while(!receive_message_or_smb(InBuffer,BUFFER_SIZE,select_timeout,&got_smb))
+ for (counter=SMBD_SELECT_LOOP;
+ !receive_message_or_smb(InBuffer,BUFFER_SIZE,
+ SMBD_SELECT_LOOP*1000,&got_smb);
+ counter += SMBD_SELECT_LOOP)
{
- if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
+ time_t t;
+ BOOL allidle = True;
+ extern int keepalive;
+
+ if (counter > 365 * 3600) /* big number of seconds. */
+ {
+ counter = 0;
+ service_load_counter = 0;
+ }
+
+ if (smb_read_error == READ_EOF)
+ {
+ DEBUG(3,("end of file from client\n"));
return;
- num_smbs = 0; /* Reset smb counter. */
- }
+ }
+
+ if (smb_read_error == READ_ERROR)
+ {
+ DEBUG(3,("receive_smb error (%s) exiting\n",
+ strerror(errno)));
+ return;
+ }
+
+ t = time(NULL);
+
+ /* become root again if waiting */
+ unbecome_user();
+
+ /* check for smb.conf reload */
+ if (counter >= service_load_counter + SMBD_RELOAD_CHECK)
+ {
+ service_load_counter = counter;
+
+ /* reload services, if files have changed. */
+ reload_services(True);
+ }
- if(got_smb) {
/*
- * Ensure we do timeout processing if the SMB we just got was
- * only an echo request. This allows us to set the select
- * timeout in 'receive_message_or_smb()' to any value we like
- * without worrying that the client will send echo requests
- * faster than the select timeout, thus starving out the
- * essential processing (change notify, blocking locks) that
- * the timeout code does. JRA.
- */
- int num_echos = smb_echo_count;
+ * If reload_after_sighup == True then we got a SIGHUP
+ * and are being asked to reload. Fix from <branko.cibej@hermes.si>
+ */
- process_smb(InBuffer, OutBuffer);
+ if (reload_after_sighup)
+ {
+ DEBUG(0,("Reloading services after SIGHUP\n"));
+ reload_services(False);
+ reload_after_sighup = False;
+ /*
+ * Use this as an excuse to print some stats.
+ */
+ print_stat_cache_statistics();
+ }
- if(smb_echo_count != num_echos) {
- if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
- return;
- num_smbs = 0; /* Reset smb counter. */
+ /* automatic timeout if all connections are closed */
+ if (conn_num_open()==0 && counter >= IDLE_CLOSED_TIMEOUT)
+ {
+ DEBUG( 2, ( "Closing idle connection\n" ) );
+ return;
+ }
+
+ if (keepalive && (counter-last_keepalive)>keepalive)
+ {
+ if (!send_keepalive(Client)) {
+ DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
+ return;
+ }
+ last_keepalive = counter;
}
- num_smbs++;
+ /* close down all idle client-side MSRPC connections */
+ free_connections();
+
+ /* check for connection timeouts */
+ allidle = conn_idle_all(t, deadtime);
+
+ if (allidle && conn_num_open()>0) {
+ DEBUG(2,("Closing idle connection 2.\n"));
+ return;
+ }
/*
- * If we are getting smb requests in a constant stream
- * with no echos, make sure we attempt timeout processing
- * every select_timeout milliseconds - but only check for this
- * every 200 smb requests.
+ * Check to see if we have any blocking locks
+ * outstanding on the queue.
*/
+ process_blocking_lock_queue(t);
- if((num_smbs % 200) == 0) {
- time_t new_check_time = time(NULL);
- if(last_timeout_processing_time - new_check_time >= (select_timeout/1000)) {
- if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
- return;
- num_smbs = 0; /* Reset smb counter. */
- last_timeout_processing_time = new_check_time; /* Reset time. */
- }
- }
+ /*
+ * Check to see if we have any change notifies
+ * outstanding on the queue.
+ */
+ process_pending_change_notify_queue(t);
}
+
+ if(got_smb)
+ process_smb(InBuffer, OutBuffer);
else
process_local_message(InBuffer, BUFFER_SIZE);
}
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index badc0562bc8..afabb1befdf 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -47,6 +47,7 @@ try to get the disk space from disk quotas (LINUX version)
BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
+ uid_t euser_id;
int r;
struct dqblk D;
SMB_STRUCT_STAT S;
@@ -54,9 +55,6 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
struct mntent *mnt;
SMB_DEV_T devno;
int found;
- uid_t euser_id;
-
- euser_id = geteuid();
/* find the block device file */
@@ -83,10 +81,10 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
return(False);
}
- save_re_uid();
- set_effective_uid(0);
+ euser_id=geteuid();
+ seteuid(0);
r=quotactl(QCMD(Q_GETQUOTA,USRQUOTA), mnt->mnt_fsname, euser_id, (caddr_t)&D);
- restore_re_uid();
+ seteuid(euser_id);
/* Use softlimit to determine disk space, except when it has been exceeded */
*bsize = 1024;
@@ -214,11 +212,12 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
*dsize = request.qf_entry.user_q.f_use ;
- if ( *dfree < *dsize )
- *dfree = 0 ;
- else
+ if ( *dfree )
*dfree -= *dsize ;
+ if ( *dfree < 0 )
+ *dfree = 0 ;
+
*bsize = 4096 ; /* Cray blocksize */
return(True) ;
@@ -245,7 +244,7 @@ Quota code by Peter Urbanec (amiga@cse.unsw.edu.au).
BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
- uid_t euser_id;
+ uid_t user_id, euser_id;
int ret;
struct dqblk D;
#if defined(SUNOS5)
@@ -262,8 +261,6 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
SMB_DEV_T devno ;
static SMB_DEV_T devno_cached = 0 ;
int found ;
-
- euser_id = geteuid();
if ( sys_stat(path,&sbuf) == -1 )
return(False) ;
@@ -315,14 +312,18 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
return(False) ;
}
- save_re_uid();
- set_effective_uid(0);
+ euser_id = geteuid();
+ user_id = getuid();
+
+ setuid(0); /* Solaris seems to want to give info only to super-user */
+ seteuid(0);
#if defined(SUNOS5)
DEBUG(5,("disk_quotas: looking for quotas file \"%s\"\n", name));
if((file=sys_open(name, O_RDONLY,0))<0) {
- restore_re_uid();
- return(False);
+ setuid(user_id); /* Restore the original UID status */
+ seteuid(euser_id);
+ return(False);
}
command.op = Q_GETQUOTA;
command.uid = euser_id;
@@ -334,7 +335,8 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
ret = quotactl(Q_GETQUOTA, name, euser_id, &D);
#endif
- restore_re_uid();
+ setuid(user_id); /* Restore the original uid status. */
+ seteuid(euser_id);
if (ret < 0) {
DEBUG(5,("disk_quotas ioctl (Solaris) failed. Error = %s\n", strerror(errno) ));
@@ -351,13 +353,14 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
if (D.dqb_bsoftlimit==0)
return(False);
*bsize = DEV_BSIZE;
+ *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
*dsize = D.dqb_bsoftlimit;
- if (D.dqb_curblocks > D.dqb_bsoftlimit) {
+ if(*dfree < 0)
+ {
*dfree = 0;
*dsize = D.dqb_curblocks;
- } else
- *dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
+ }
DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",
path,(double)*bsize,(double)*dfree,(double)*dsize));
@@ -375,26 +378,21 @@ try to get the disk space from disk quotas - OSF1 version
BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
+ uid_t user_id, euser_id;
int r, save_errno;
struct dqblk D;
SMB_STRUCT_STAT S;
- uid_t euser_id;
- /*
- * This code presumes that OSF1 will only
- * give out quota info when the real uid
- * matches the effective uid. JRA.
- */
euser_id = geteuid();
- save_re_uid();
- if (set_re_uid() != 0) return False;
+ user_id = getuid();
+ setreuid(euser_id, -1);
r= quotactl(path,QCMD(Q_GETQUOTA, USRQUOTA),euser_id,(char *) &D);
- if (r) {
+ if (r)
save_errno = errno;
- }
- restore_re_uid();
+ if (setreuid(user_id, -1) == -1)
+ DEBUG(5,("Unable to reset uid to %d\n", user_id));
*bsize = DEV_BSIZE;
@@ -425,7 +423,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
return (True);
}
-#elif defined (IRIX6)
+#elif defined (SGI6)
/****************************************************************************
try to get the disk space from disk quotas (IRIX 6.2 version)
****************************************************************************/
@@ -471,8 +469,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
}
euser_id=geteuid();
- save_re_uid();
- set_effective_uid(0);
+ seteuid(0);
/* Use softlimit to determine disk space, except when it has been exceeded */
@@ -482,7 +479,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
{
r=quotactl (Q_GETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &D);
- restore_re_uid();
+ seteuid(euser_id); /* Restore the original uid status. */
if (r==-1)
return(False);
@@ -513,7 +510,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
{
r=quotactl (Q_XGETQUOTA, mnt->mnt_fsname, euser_id, (caddr_t) &F);
- restore_re_uid();
+ seteuid(euser_id); /* Restore the original uid status. */
if (r==-1)
return(False);
@@ -542,8 +539,8 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
}
else
{
- restore_re_uid();
- return(False);
+ seteuid(euser_id); /* Restore the original uid status. */
+ return(False);
}
return (True);
@@ -573,9 +570,9 @@ try to get the disk space from disk quotas - default version
BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
+ uid_t euser_id;
int r;
struct dqblk D;
- uid_t euser_id;
#if !defined(__FreeBSD__) && !defined(AIX) && !defined(__OpenBSD__)
char dev_disk[256];
SMB_STRUCT_STAT S;
@@ -587,32 +584,36 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
euser_id = geteuid();
#ifdef HPUX
- /* for HPUX, real uid must be same as euid to execute quotactl for euid */
- save_re_uid();
- if (set_re_uid() != 0) return False;
-
- r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
-
- restore_re_uid();
+ {
+ uid_t user_id;
+
+ /* for HPUX, real uid must be same as euid to execute quotactl for euid */
+ user_id = getuid();
+ setresuid(euser_id,-1,-1);
+ r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
+ if (setresuid(user_id,-1,-1))
+ DEBUG(5,("Unable to reset uid to %d\n", user_id));
+ }
#else
#if defined(__FreeBSD__) || defined(__OpenBSD__)
{
/* FreeBSD patches from Marty Moll <martym@arbor.edu> */
+ uid_t user_id;
gid_t egrp_id;
- save_re_uid();
- set_effective_uid(0);
-
+ /* Need to be root to get quotas in FreeBSD */
+ user_id = getuid();
egrp_id = getegid();
+ setuid(0);
+ seteuid(0);
r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
/* As FreeBSD has group quotas, if getting the user
quota fails, try getting the group instead. */
- if (r) {
- r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D);
- }
-
- restore_re_uid();
+ if (r)
+ r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D);
+ setuid(user_id);
+ seteuid(euser_id);
}
#elif defined(AIX)
/* AIX has both USER and GROUP quotas:
@@ -621,7 +622,7 @@ BOOL disk_quotas(char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB_BIG_U
#else /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
#endif /* !__FreeBSD__ && !AIX && !__OpenBSD__ */
-#endif /* HPUX */
+#endif /* HAVE_SETRES */
/* Use softlimit to determine disk space, except when it has been exceeded */
#if defined(__FreeBSD__) || defined(__OpenBSD__)
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index 3715bd224f0..d83aed39fc4 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -38,25 +38,25 @@ extern BOOL case_sensitive;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
extern pstring sesssetup_user;
-extern pstring global_myname;
extern fstring global_myworkgroup;
+extern fstring global_myname;
extern int Client;
extern int global_oplock_break;
uint32 global_client_caps = 0;
-unsigned int smb_echo_count = 0;
+
/****************************************************************************
report a possible attack via the password buffer overflow bug
****************************************************************************/
-
static void overflow_attack(int len)
{
- if( DEBUGLVL( 0 ) ) {
- dbgtext( "ERROR: Invalid password length %d.\n", len );
- dbgtext( "Your machine may be under attack by someone " );
- dbgtext( "attempting to exploit an old bug.\n" );
- dbgtext( "Attack was from IP = %s.\n", client_addr(Client) );
- }
+ if( DEBUGLVL( 0 ) )
+ {
+ dbgtext( "ERROR: Invalid password length %d.\n", len );
+ dbgtext( "Your machine may be under attack by someone " );
+ dbgtext( "attempting to exploit an old bug.\n" );
+ dbgtext( "Attack was from IP = %s.\n", client_connection_addr() );
+ }
exit_server("possible attack");
}
@@ -64,7 +64,6 @@ static void overflow_attack(int len)
/****************************************************************************
reply to an special message
****************************************************************************/
-
int reply_special(char *inbuf,char *outbuf)
{
int outsize = 4;
@@ -78,10 +77,13 @@ int reply_special(char *inbuf,char *outbuf)
*name1 = *name2 = 0;
- memset(outbuf,'\0',smb_size);
+ bzero(outbuf,smb_size);
smb_setlen(outbuf,0);
+ DEBUG(20,("NBT message\n"));
+ dump_data(20, inbuf, smb_len(inbuf));
+
switch (msg_type) {
case 0x81: /* session request */
CVAL(outbuf,0) = 0x82;
@@ -123,7 +125,7 @@ int reply_special(char *inbuf,char *outbuf)
reopen_logs();
if (lp_status(-1)) {
- claim_connection(NULL,"",MAXSTATUS,True);
+ claim_connection(NULL,"STATUS.",MAXSTATUS,True);
}
break;
@@ -155,11 +157,11 @@ int reply_special(char *inbuf,char *outbuf)
/*******************************************************************
work out what error to give to a failed connection
********************************************************************/
-
static int connection_error(char *inbuf,char *outbuf,int ecode)
{
- if (ecode == ERRnoipc)
+ if (ecode == ERRnoipc) {
return(ERROR(ERRDOS,ERRnoipc));
+ }
return(ERROR(ERRSRV,ecode));
}
@@ -200,14 +202,15 @@ static void parse_connect(char *p,char *service,char *user,
}
}
+
+
+
/****************************************************************************
- Reply to a tcon.
+ reply to a tcon
****************************************************************************/
-
int reply_tcon(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- BOOL doencrypt = SMBENCRYPT();
pstring service;
pstring user;
pstring password;
@@ -221,27 +224,9 @@ int reply_tcon(connection_struct *conn,
parse_connect(smb_buf(inbuf)+1,service,user,password,&pwlen,dev);
- /*
- * Ensure the user and password names are in UNIX codepage format.
- */
-
- dos_to_unix(user,True);
- if (!doencrypt)
- dos_to_unix(password,True);
-
- /*
- * Pass the user through the NT -> unix user mapping
- * function.
- */
-
- (void)map_username(user);
-
- /*
- * Do any UNIX username case mangling.
- */
- (void)Get_Pwnam( user, True);
+ map_nt_and_unix_username(global_myworkgroup, user, user, NULL);
- conn = make_connection(service,user,password,pwlen,dev,vuid,&ecode);
+ conn = make_connection(service,user,global_myworkgroup, password,pwlen,dev,vuid,&ecode);
if (!conn) {
return(connection_error(inbuf,outbuf,ecode));
@@ -258,17 +243,16 @@ int reply_tcon(connection_struct *conn,
return(outsize);
}
+
/****************************************************************************
- Reply to a tcon and X.
+ reply to a tcon and X
****************************************************************************/
-
int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
pstring service;
pstring user;
pstring password;
pstring devicename;
- BOOL doencrypt = SMBENCRYPT();
int ecode = -1;
uint16 vuid = SVAL(inbuf,smb_uid);
int passlen = SVAL(inbuf,smb_vwv3);
@@ -285,7 +269,7 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
if (passlen > MAX_PASS_LEN) {
overflow_attack(passlen);
}
-
+
memcpy(password,smb_buf(inbuf),passlen);
password[passlen]=0;
path = smb_buf(inbuf) + passlen;
@@ -310,27 +294,9 @@ int reply_tcon_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
StrnCpy(devicename,path + strlen(path) + 1,6);
DEBUG(4,("Got device type %s\n",devicename));
- /*
- * Ensure the user and password names are in UNIX codepage format.
- */
-
- dos_to_unix(user,True);
- if (!doencrypt)
- dos_to_unix(password,True);
+ map_nt_and_unix_username(global_myworkgroup, user, user, NULL);
- /*
- * Pass the user through the NT -> unix user mapping
- * function.
- */
-
- (void)map_username(user);
-
- /*
- * Do any UNIX username case mangling.
- */
- (void)Get_Pwnam(user, True);
-
- conn = make_connection(service,user,password,passlen,devicename,vuid,&ecode);
+ conn = make_connection(service,user,global_myworkgroup, password,passlen,devicename,vuid,&ecode);
if (!conn)
return(connection_error(inbuf,outbuf,ecode));
@@ -386,259 +352,57 @@ int reply_unknown(char *inbuf,char *outbuf)
int reply_ioctl(connection_struct *conn,
char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
- uint16 device = SVAL(inbuf,smb_vwv1);
- uint16 function = SVAL(inbuf,smb_vwv2);
- uint32 ioctl_code = (device << 16) + function;
- int replysize, outsize;
- char *p;
-
- DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
-
- switch (ioctl_code)
- {
- case IOCTL_QUERY_JOB_INFO:
- replysize = 32;
- break;
- default:
- return(ERROR(ERRSRV,ERRnosupport));
- }
-
- outsize = set_message(outbuf,8,replysize+1,True);
- SSVAL(outbuf,smb_vwv1,replysize); /* Total data bytes returned */
- SSVAL(outbuf,smb_vwv5,replysize); /* Data bytes this buffer */
- SSVAL(outbuf,smb_vwv6,52); /* Offset to data */
- p = smb_buf(outbuf) + 1; /* Allow for alignment */
-
- switch (ioctl_code)
- {
- case IOCTL_QUERY_JOB_INFO:
- SSVAL(p,0,1); /* Job number */
- StrnCpy(p+2, global_myname, 15); /* Our NetBIOS name */
- StrnCpy(p+18, lp_servicename(SNUM(conn)), 13); /* Service name */
- break;
- }
-
- return outsize;
+ DEBUG(3,("ignoring ioctl\n"));
+#if 0
+ /* we just say it succeeds and hope its all OK.
+ some day it would be nice to interpret them individually */
+ return set_message(outbuf,1,0,True);
+#else
+ return(ERROR(ERRSRV,ERRnosupport));
+#endif
}
/****************************************************************************
always return an error: it's just a matter of which one...
****************************************************************************/
-static int session_trust_account(connection_struct *conn, char *inbuf, char *outbuf, char *user,
+static int session_trust_account(connection_struct *conn,
+ char *inbuf, char *outbuf,
+ char *user, char *domain,
char *smb_passwd, int smb_passlen,
char *smb_nt_passwd, int smb_nt_passlen)
{
- struct smb_passwd *smb_trust_acct = NULL; /* check if trust account exists */
- if (lp_security() == SEC_USER)
- {
- smb_trust_acct = getsmbpwnam(user);
- }
- else
- {
- DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
- }
-
- if (smb_trust_acct == NULL)
- {
- /* lkclXXXX: workstation entry doesn't exist */
- DEBUG(0,("session_trust_account: Trust account %s user doesn't exist\n",user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_NO_SUCH_USER));
- }
- else
- {
- if ((smb_passlen != 24) || (smb_nt_passlen != 24))
- {
- DEBUG(0,("session_trust_account: Trust account %s - password length wrong.\n", user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
- }
-
- if (!smb_password_ok(smb_trust_acct, NULL, (unsigned char *)smb_passwd, (unsigned char *)smb_nt_passwd))
- {
- DEBUG(0,("session_trust_account: Trust Account %s - password failed\n", user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
- }
-
- if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_DOMTRUST))
- {
- DEBUG(0,("session_trust_account: Domain trust account %s denied by server\n",user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT));
- }
-
- if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_SVRTRUST))
- {
- DEBUG(0,("session_trust_account: Server trust account %s denied by server\n",user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT));
- }
-
- if (IS_BITS_SET_ALL(smb_trust_acct->acct_ctrl, ACB_WSTRUST))
- {
- DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", user));
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT));
- }
- }
-
- /* don't know what to do: indicate logon failure */
- SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
-}
-
-/****************************************************************************
- Create a UNIX user on demand.
-****************************************************************************/
+ uchar last_chal[8];
+ uint32 status = 0x0;
-static int smb_create_user(char *unix_user)
-{
- pstring add_script;
- int ret;
-
- pstrcpy(add_script, lp_adduser_script());
- pstring_sub(add_script, "%u", unix_user);
- ret = smbrun(add_script,NULL,False);
- DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
- return ret;
-}
-
-/****************************************************************************
- Delete a UNIX user on demand.
-****************************************************************************/
-
-static int smb_delete_user(char *unix_user)
-{
- pstring del_script;
- int ret;
-
- pstrcpy(del_script, lp_deluser_script());
- pstring_sub(del_script, "%u", unix_user);
- ret = smbrun(del_script,NULL,False);
- DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
- return ret;
-}
-
-/****************************************************************************
- Check user is in correct domain if required
-****************************************************************************/
-
-static BOOL check_domain_match(char *user, char *domain)
-{
- /*
- * If we aren't serving to trusted domains, we must make sure that
- * the validation request comes from an account in the same domain
- * as the Samba server
- */
-
- if (!lp_allow_trusted_domains() &&
- !strequal(lp_workgroup(), domain) ) {
- DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
- return False;
- } else {
- return True;
- }
-}
-
-/****************************************************************************
- Check for a valid username and password in security=server mode.
-****************************************************************************/
-
-static BOOL check_server_security(char *orig_user, char *domain, char *unix_user,
- char *smb_apasswd, int smb_apasslen,
- char *smb_ntpasswd, int smb_ntpasslen)
-{
- BOOL ret = False;
-
- if(lp_security() != SEC_SERVER)
- return False;
-
- if (!check_domain_match(orig_user, domain))
- return False;
-
- ret = server_validate(orig_user, domain,
- smb_apasswd, smb_apasslen,
- smb_ntpasswd, smb_ntpasslen);
- if(ret) {
- /*
- * User validated ok against Domain controller.
- * If the admin wants us to try and create a UNIX
- * user on the fly, do so.
- * Note that we can never delete users when in server
- * level security as we never know if it was a failure
- * due to a bad password, or the user really doesn't exist.
- */
- if(lp_adduser_script() && !Get_Pwnam(unix_user,True)) {
- smb_create_user(unix_user);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- Check for a valid username and password in security=domain mode.
-****************************************************************************/
-
-static BOOL check_domain_security(char *orig_user, char *domain, char *unix_user,
- char *smb_apasswd, int smb_apasslen,
- char *smb_ntpasswd, int smb_ntpasslen)
-{
- BOOL ret = False;
- BOOL user_exists = True;
-
- if(lp_security() != SEC_DOMAIN)
- return False;
-
- if (!check_domain_match(orig_user, domain))
- return False;
-
- ret = domain_client_validate(orig_user, domain,
- smb_apasswd, smb_apasslen,
- smb_ntpasswd, smb_ntpasslen,
- &user_exists);
-
- if(ret) {
- /*
- * User validated ok against Domain controller.
- * If the admin wants us to try and create a UNIX
- * user on the fly, do so.
- */
- if(user_exists && lp_adduser_script() && !Get_Pwnam(unix_user,True)) {
- smb_create_user(unix_user);
- }
- } else {
- /*
- * User failed to validate ok against Domain controller.
- * If the failure was "user doesn't exist" and admin
- * wants us to try and delete that UNIX user on the fly,
- * do so.
- */
- if(!user_exists && lp_deluser_script() && Get_Pwnam(unix_user,True)) {
- smb_delete_user(unix_user);
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- Return a bad password error configured for the correct client type.
-****************************************************************************/
+ if (lp_security() != SEC_USER)
+ {
+ DEBUG(0,("session_trust_account: Trust account %s only supported with security = user\n", user));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_LOGON_FAILURE));
+ }
-static int bad_password_error(char *inbuf,char *outbuf)
-{
- enum remote_arch_types ra_type = get_remote_arch();
+ if (last_challenge(last_chal))
+ {
+ NET_USER_INFO_3 info3;
+ ZERO_STRUCT(info3);
+ status = check_domain_security(user, domain,
+ last_chal,
+ (uchar *)smb_passwd, smb_passlen,
+ (uchar *)smb_nt_passwd, smb_nt_passlen,
+ &info3);
+ }
+ else
+ {
+ status = 0xc0000000|NT_STATUS_LOGON_FAILURE;
+ }
- if(ra_type == RA_WINNT && (global_client_caps & (CAP_NT_SMBS | CAP_STATUS32 ))) {
- SSVAL(outbuf,smb_flg2,FLAGS2_32_BIT_ERROR_CODES);
- return(ERROR(0,0xc0000000|NT_STATUS_LOGON_FAILURE));
- }
+ if (status == 0x0)
+ {
+ status = 0xc0000000|NT_STATUS_LOGON_FAILURE;
+ }
- return(ERROR(ERRSRV,ERRbadpw));
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return ERROR(0, status);
}
/****************************************************************************
@@ -648,14 +412,14 @@ reply to a session setup command
int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
uint16 sess_vuid;
- gid_t gid;
- uid_t uid;
+ NET_USER_INFO_3 info3;
+ int gid;
+ int uid;
int smb_bufsize;
int smb_apasslen = 0;
pstring smb_apasswd;
int smb_ntpasslen = 0;
pstring smb_ntpasswd;
- BOOL valid_nt_password = False;
pstring user;
pstring orig_user;
BOOL guest=False;
@@ -663,54 +427,63 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
BOOL doencrypt = SMBENCRYPT();
char *domain = "";
+ ZERO_STRUCT(info3);
+
*smb_apasswd = 0;
*smb_ntpasswd = 0;
smb_bufsize = SVAL(inbuf,smb_vwv2);
- if (Protocol < PROTOCOL_NT1) {
+ if (Protocol < PROTOCOL_NT1)
+ {
smb_apasslen = SVAL(inbuf,smb_vwv7);
if (smb_apasslen > MAX_PASS_LEN)
- overflow_attack(smb_apasslen);
+ {
+ overflow_attack(smb_apasslen);
+ }
memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
smb_apasswd[smb_apasslen] = 0;
pstrcpy(user,smb_buf(inbuf)+smb_apasslen);
- /*
- * Incoming user is in DOS codepage format. Convert
- * to UNIX.
- */
- dos_to_unix(user,True);
-
+
if (!doencrypt && (lp_security() != SEC_SERVER)) {
- smb_apasslen = strlen(smb_apasswd);
+ smb_apasslen = strlen(smb_apasswd);
}
- } else {
+
+ if (lp_server_ntlmv2() == True)
+ {
+ DEBUG(1,("NTLMv2-only accepted with NT LANMAN 1.0 and above.\n\
+user %s attempted down-level SMB connection\n", user));
+ return(ERROR(ERRSRV,ERRbadpw));
+ }
+ }
+ else
+ {
uint16 passlen1 = SVAL(inbuf,smb_vwv7);
uint16 passlen2 = SVAL(inbuf,smb_vwv8);
enum remote_arch_types ra_type = get_remote_arch();
char *p = smb_buf(inbuf);
- if(global_client_caps == 0)
- global_client_caps = IVAL(inbuf,smb_vwv11);
+ global_client_caps = IVAL(inbuf,smb_vwv11);
/* client_caps is used as final determination if client is NT or Win95.
This is needed to return the correct error codes in some
circumstances.
*/
- if(ra_type == RA_WINNT || ra_type == RA_WIN95) {
+ if(ra_type == RA_WINNT || ra_type == RA_WIN95)
+ {
if(global_client_caps & (CAP_NT_SMBS | CAP_STATUS32))
set_remote_arch( RA_WINNT);
else
set_remote_arch( RA_WIN95);
}
- if (passlen1 != 24 && passlen2 != 24)
+ if (passlen1 != 24 && passlen2 <= 24)
doencrypt = False;
if (passlen1 > MAX_PASS_LEN) {
- overflow_attack(passlen1);
+ overflow_attack(passlen1);
}
passlen1 = MIN(passlen1, MAX_PASS_LEN);
@@ -727,33 +500,18 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
if passlen1>0 and passlen2>0 then maybe its a NT box and its
setting passlen2 to some random value which really stuffs
- things up. we need to fix that one. */
+ things up. we need to fix that one.
- if (passlen1 > 0 && passlen2 > 0 && passlen2 != 24 && passlen2 != 1)
- passlen2 = 0;
- }
+ LKCLXXXX: the random value can be random 16 bit. old test
+ used to have ... && passlen <= 24) which of course fails
+ most of the time.
+ */
- if (lp_restrict_anonymous()) {
- /* there seems to be no reason behind the differences in MS clients formatting
- * various info like the domain, NativeOS, and NativeLanMan fields. Win95
- * in particular seems to have an extra null byte between the username and the
- * domain, or the password length calculation is wrong, which throws off the
- * string extraction routines below. This makes the value of domain be the
- * empty string, which fails the restrict anonymous check further down.
- * This compensates for that, and allows browsing to work in mixed NT and
- * win95 environments even when restrict anonymous is true. AAB
- */
- dump_data(100, p, 0x70);
- DEBUG(9, ("passlen1=%d, passlen2=%d\n", passlen1, passlen2));
- if (ra_type == RA_WIN95 && !passlen1 && !passlen2 && p[0] == 0 && p[1] == 0) {
- DEBUG(0, ("restrict anonymous parameter used in a win95 environment!\n"));
- DEBUG(0, ("client is win95 and broken passlen1 offset -- attempting fix\n"));
- DEBUG(0, ("if win95 cilents are having difficulty browsing, you will be unable to use restrict anonymous\n"));
- passlen1 = 1;
- }
+ if (passlen1 > 0 && passlen2 > 0 && passlen2 != 1)
+ passlen2 = 0;
}
- if(doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
+ if (doencrypt || ((lp_security() == SEC_SERVER) || (lp_security() == SEC_DOMAIN))) {
/* Save the lanman2 password and the NT md4 password. */
smb_apasslen = passlen1;
memcpy(smb_apasswd,p,smb_apasslen);
@@ -761,77 +519,54 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
smb_ntpasslen = passlen2;
memcpy(smb_ntpasswd,p+passlen1,smb_ntpasslen);
smb_ntpasswd[smb_ntpasslen] = 0;
-
- /*
- * Ensure the plaintext passwords are in UNIX format.
- */
- if(!doencrypt) {
- dos_to_unix(smb_apasswd,True);
- dos_to_unix(smb_ntpasswd,True);
- }
-
} else {
/* we use the first password that they gave */
smb_apasslen = passlen1;
StrnCpy(smb_apasswd,p,smb_apasslen);
- /*
- * Ensure the plaintext password is in UNIX format.
- */
- dos_to_unix(smb_apasswd,True);
/* trim the password */
smb_apasslen = strlen(smb_apasswd);
/* wfwg sometimes uses a space instead of a null */
if (strequal(smb_apasswd," ")) {
- smb_apasslen = 0;
- *smb_apasswd = 0;
+ smb_apasslen = 0;
+ *smb_apasswd = 0;
}
}
- p += passlen1 + passlen2;
- fstrcpy(user,p);
- p = skip_string(p,1);
- /*
- * Incoming user is in DOS codepage format. Convert
- * to UNIX.
- */
- dos_to_unix(user,True);
+ if (passlen2 == 0 && smb_apasslen == 0 && ra_type == RA_WIN95)
+ {
+ /* work-around for win95 NULL sessions, where NULL password is
+ actually put in the data stream before the domain name etc */
+ p++;
+ }
+ else
+ {
+ p += passlen1 + passlen2;
+ }
+
+ fstrcpy(user,p); p = skip_string(p,1);
domain = p;
DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n",
- domain,skip_string(p,1),skip_string(p,2)));
+ domain, skip_string(p,1), skip_string(p,2)));
}
-
DEBUG(3,("sesssetupX:name=[%s]\n",user));
/* If name ends in $ then I think it's asking about whether a */
/* computer with that name (minus the $) has access. For now */
/* say yes to everything ending in $. */
-
- if (*user && (user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24)) {
- return session_trust_account(conn, inbuf, outbuf, user,
+ if ((user[strlen(user) - 1] == '$') && (smb_apasslen == 24) && (smb_ntpasslen == 24))
+ {
+ return session_trust_account(conn, inbuf, outbuf, user, domain,
smb_apasswd, smb_apasslen,
smb_ntpasswd, smb_ntpasslen);
}
- if (done_sesssetup && lp_restrict_anonymous()) {
- /* tests show that even if browsing is done over already validated connections
- * without a username and password the domain is still provided, which it
- * wouldn't be if it was a purely anonymous connection. So, in order to
- * restrict anonymous, we only deny connections that have no session
- * information. If a domain has been provided, then it's not a purely
- * anonymous connection. AAB
- */
- if (!*user && !*smb_apasswd && !*domain) {
- DEBUG(0, ("restrict anonymous is True and anonymous connection attempted. Denying access.\n"));
- return(ERROR(ERRDOS,ERRnoaccess));
- }
- }
-
/* If no username is sent use the guest account */
- if (!*user) {
+ if (!*user)
+ {
pstrcpy(user,lp_guestaccount(-1));
/* If no user and no password then set guest flag. */
if( *smb_apasswd == 0)
@@ -839,7 +574,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
}
strlower(user);
-
/*
* In share level security, only overwrite sesssetup_use if
* it's a non null-session share. Helps keep %U and %G
@@ -848,7 +582,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
if((lp_security() != SEC_SHARE) || (*user && !guest))
pstrcpy(sesssetup_user,user);
-
reload_services(True);
/*
@@ -859,17 +592,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
pstrcpy( orig_user, user);
- /*
- * Pass the user through the NT -> unix user mapping
- * function.
- */
-
- (void)map_username(user);
-
- /*
- * Do any UNIX username case mangling.
- */
- (void)Get_Pwnam( user, True);
+ map_nt_and_unix_username(domain, user, user, NULL);
add_session_user(user);
@@ -880,71 +603,46 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
if(!guest && strequal(user,lp_guestaccount(-1)) && (*smb_apasswd == 0))
guest = True;
- /*
- * Check with orig_user for security=server and
- * security=domain.
- */
-
- if (!guest &&
- !check_server_security(orig_user, domain, user,
- smb_apasswd, smb_apasslen,
- smb_ntpasswd, smb_ntpasslen) &&
- !check_domain_security(orig_user, domain, user,
- smb_apasswd, smb_apasslen,
- smb_ntpasswd, smb_ntpasslen) &&
- !check_hosts_equiv(user)
- )
- {
-
- /*
- * If we get here then the user wasn't guest and the remote
- * authentication methods failed. Check the authentication
- * methods on this local server.
- *
- * If an NT password was supplied try and validate with that
- * first. This is superior as the passwords are mixed case
- * 128 length unicode.
- */
-
- if(smb_ntpasslen)
- {
- if(!password_ok(user, smb_ntpasswd,smb_ntpasslen,NULL))
- DEBUG(2,("NT Password did not match for user '%s' ! Defaulting to Lanman\n", user));
- else
- valid_nt_password = True;
- }
+ if (!guest && !check_hosts_equiv(user))
+ {
+ /*
+ * Check with orig_user for security=server and
+ * security=domain.
+ */
- if (!valid_nt_password && !password_ok(user, smb_apasswd,smb_apasslen,NULL))
- {
- if (lp_security() >= SEC_USER)
- {
- if (lp_map_to_guest() == NEVER_MAP_TO_GUEST)
- {
- DEBUG(1,("Rejecting user '%s': authentication failed\n", user));
- return bad_password_error(inbuf,outbuf);
- }
+ DEBUG(10,("Checking SMB password, user %s domain %s\n",
+ user, domain));
+ if(!password_ok(orig_user, domain,
+ smb_apasswd,smb_apasslen,
+ smb_ntpasswd,smb_ntpasslen,
+ NULL, &info3))
+ {
+ DEBUG(0,("SMB LM/NT Password did not match!\n"));
+
+ if (lp_security() >= SEC_USER)
+ {
+ if (lp_map_to_guest() == NEVER_MAP_TO_GUEST)
+ return(ERROR(ERRSRV,ERRbadpw));
+
+ if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER)
+ {
+ if (Get_Pwnam(user,True))
+ return(ERROR(ERRSRV,ERRbadpw));
+ }
- if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_USER)
- {
- if (Get_Pwnam(user,True))
- {
- DEBUG(1,("Rejecting user '%s': bad password\n", user));
- return bad_password_error(inbuf,outbuf);
- }
- }
+ /*
+ * ..else if lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
+ * Then always map to guest account - as done below.
+ */
+ }
- /*
- * ..else if lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_PASSWORD
- * Then always map to guest account - as done below.
- */
- }
+ if (*smb_apasswd || !Get_Pwnam(user,True))
+ pstrcpy(user,lp_guestaccount(-1));
+ DEBUG(3,("Registered username %s for guest access\n",user));
+ guest = True;
+ }
- if (*smb_apasswd || !Get_Pwnam(user,True))
- pstrcpy(user,lp_guestaccount(-1));
- DEBUG(3,("Registered username %s for guest access\n",user));
- guest = True;
- }
- }
+ }
if (!Get_Pwnam(user,True)) {
DEBUG(3,("No such user %s - using guest account\n",user));
@@ -956,12 +654,15 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
lp_servicenumber(user) < 0)
{
int homes = lp_servicenumber(HOMES_NAME);
- char *home = get_user_home_dir(user);
+ char *home = get_unixhome_dir(user);
if (homes >= 0 && home)
- lp_add_home(user,homes,home);
+ {
+ pstring home_dir;
+ fstrcpy(home_dir, home);
+ lp_add_home(user,homes,home_dir);
+ }
}
-
/* it's ok - setup a reply */
if (Protocol < PROTOCOL_NT1) {
set_message(outbuf,3,0,True);
@@ -984,7 +685,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
const struct passwd *pw = Get_Pwnam(user,False);
if (!pw) {
DEBUG(1,("Username %s is invalid on this system\n",user));
- return bad_password_error(inbuf,outbuf);
+ return(ERROR(ERRSRV,ERRbadpw));
}
gid = pw->pw_gid;
uid = pw->pw_uid;
@@ -995,7 +696,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
/* register the name and uid as being validated, so further connections
to a uid can get through without a password, on the same VC */
- sess_vuid = register_vuid(uid,gid,user,sesssetup_user,guest);
+ sess_vuid = register_vuid(getpid(), uid,gid,user,sesssetup_user,guest,&info3);
SSVAL(outbuf,smb_uid,sess_vuid);
SSVAL(inbuf,smb_uid,sess_vuid);
@@ -1024,15 +725,19 @@ int reply_chkpth(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
SMB_STRUCT_STAT st;
pstrcpy(name,smb_buf(inbuf) + 1);
- unix_convert(name,conn,0,&bad_path,&st);
+ if (!unix_dfs_convert(name,conn,0,&bad_path,&st))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
mode = SVAL(inbuf,smb_vwv0);
-
+
if (check_name(name,conn)) {
if(VALID_STAT(st))
ok = S_ISDIR(st.st_mode);
else
- ok = vfs_directory_exist(conn,name,NULL);
+ ok = dos_directory_exist(name,NULL);
}
if (!ok)
@@ -1084,7 +789,7 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
BOOL bad_path = False;
pstrcpy(fname,smb_buf(inbuf) + 1);
-
+
/* dos smetimes asks for a stat of "" - it returns a "hidden directory"
under WfWg - weird! */
if (! (*fname))
@@ -1097,10 +802,14 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
}
else
{
- unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,&sbuf))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
if (check_name(fname,conn))
{
- if (VALID_STAT(sbuf) || dos_stat(fname,&sbuf) == 0)
+ if (VALID_STAT(sbuf) || conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf) == 0)
{
mode = dos_mode(conn,fname,&sbuf);
size = sbuf.st_size;
@@ -1162,12 +871,16 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
BOOL bad_path = False;
pstrcpy(fname,smb_buf(inbuf) + 1);
- unix_convert(fname,conn,0,&bad_path,&st);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,&st))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
mode = SVAL(inbuf,smb_vwv0);
mtime = make_unix_date3(inbuf+smb_vwv1);
- if (VALID_STAT_OF_DIR(st) || vfs_directory_exist(conn, fname, NULL))
+ if (VALID_STAT_OF_DIR(st) || dos_directory_exist(fname,NULL))
mode |= aDIR;
if (check_name(fname,conn))
ok = (file_chmod(conn,fname,mode,NULL) == 0);
@@ -1201,7 +914,7 @@ int reply_dskattr(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
int outsize = 0;
SMB_BIG_UINT dfree,dsize,bsize;
- conn->vfs_ops.disk_free(".",True,&bsize,&dfree,&dsize);
+ conn->vfs_ops.disk_free(".",&bsize,&dfree,&dsize);
outsize = set_message(outbuf,5,0,True);
@@ -1260,70 +973,74 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
/* dirtype &= ~aDIR; */
- DEBUG(5,("reply_search: path=%s status_len=%d\n",path,status_len));
+ DEBUG(5,("path=%s status_len=%d\n",path,status_len));
if (status_len == 0)
+ {
+ pstring dir2;
+
+ pstrcpy(directory,smb_buf(inbuf)+1);
+ pstrcpy(dir2,smb_buf(inbuf)+1);
+ if (!unix_dfs_convert(directory,conn,0,&bad_path,NULL))
{
- pstring dir2;
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
+ unix_format(dir2);
- pstrcpy(directory,smb_buf(inbuf)+1);
- pstrcpy(dir2,smb_buf(inbuf)+1);
- unix_convert(directory,conn,0,&bad_path,NULL);
- unix_format(dir2);
+ if (!check_name(directory,conn))
+ can_open = False;
- if (!check_name(directory,conn))
- can_open = False;
+ p = strrchr(dir2,'/');
+ if (p == NULL)
+ {
+ pstrcpy(mask,dir2);
+ *dir2 = 0;
+ }
+ else
+ {
+ *p = 0;
+ pstrcpy(mask,p+1);
+ }
- p = strrchr(dir2,'/');
- if (p == NULL)
- {
- pstrcpy(mask,dir2);
- *dir2 = 0;
+ p = strrchr(directory,'/');
+ if (!p)
+ *directory = 0;
+ else
+ *p = 0;
+
+ if (strlen(directory) == 0)
+ pstrcpy(directory,"./");
+ bzero(status,21);
+ CVAL(status,0) = dirtype;
}
- else
+ else
{
- *p = 0;
- pstrcpy(mask,p+1);
+ memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
+ memcpy(mask,status+1,11);
+ mask[11] = 0;
+ dirtype = CVAL(status,0) & 0x1F;
+ conn->dirptr = dptr_fetch(status+12,&dptr_num);
+ if (!conn->dirptr)
+ goto SearchEmpty;
+ string_set(&conn->dirpath,dptr_path(dptr_num));
+ if (!case_sensitive)
+ strnorm(mask);
}
- p = strrchr(directory,'/');
- if (!p)
- *directory = 0;
- else
- *p = 0;
-
- if (strlen(directory) == 0)
- pstrcpy(directory,"./");
- memset((char *)status,'\0',21);
- CVAL(status,0) = dirtype;
- }
- else
- {
- memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
- memcpy(mask,status+1,11);
- mask[11] = 0;
- dirtype = CVAL(status,0) & 0x1F;
- conn->dirptr = dptr_fetch(status+12,&dptr_num);
- if (!conn->dirptr)
- goto SearchEmpty;
- string_set(&conn->dirpath,dptr_path(dptr_num));
- if (!case_sensitive)
- strnorm(mask);
- }
-
/* turn strings of spaces into a . */
{
trim_string(mask,NULL," ");
if ((p = strrchr(mask,' ')))
- {
- fstring ext;
- fstrcpy(ext,p+1);
- *p = 0;
- trim_string(mask,NULL," ");
- pstrcat(mask,".");
- pstrcat(mask,ext);
- }
+ {
+ fstring ext;
+ fstrcpy(ext,p+1);
+ *p = 0;
+ trim_string(mask,NULL," ");
+ pstrcat(mask,".");
+ pstrcat(mask,ext);
+ }
}
/* Convert the formatted mask. (This code lives in trans2.c) */
@@ -1334,7 +1051,7 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
p = mask;
while(*p)
{
- if((skip = get_character_len( *p )) != 0 )
+ if((skip = skip_multibyte_char( *p )) != 0 )
{
p += skip;
}
@@ -1351,104 +1068,104 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
}
if (!strchr(mask,'.') && strlen(mask)>8)
- {
- fstring tmp;
- fstrcpy(tmp,&mask[8]);
- mask[8] = '.';
- mask[9] = 0;
- pstrcat(mask,tmp);
- }
+ {
+ fstring tmp;
+ fstrcpy(tmp,&mask[8]);
+ mask[8] = '.';
+ mask[9] = 0;
+ pstrcat(mask,tmp);
+ }
DEBUG(5,("mask=%s directory=%s\n",mask,directory));
if (can_open)
- {
- p = smb_buf(outbuf) + 3;
-
- ok = True;
-
- if (status_len == 0)
{
- dptr_num = dptr_create(conn,directory,True,expect_close,SVAL(inbuf,smb_pid));
- if (dptr_num < 0)
- {
- if(dptr_num == -2)
+ p = smb_buf(outbuf) + 3;
+
+ ok = True;
+
+ if (status_len == 0)
+ {
+ dptr_num = dptr_create(conn,directory,expect_close,SVAL(inbuf,smb_pid));
+ if (dptr_num < 0)
{
- if((errno == ENOENT) && bad_path)
+ if(dptr_num == -2)
{
- unix_ERR_class = ERRDOS;
- unix_ERR_code = ERRbadpath;
+ if((errno == ENOENT) && bad_path)
+ {
+ unix_ERR_class = ERRDOS;
+ unix_ERR_code = ERRbadpath;
+ }
+ return (UNIXERROR(ERRDOS,ERRnofids));
}
- return (UNIXERROR(ERRDOS,ERRnofids));
+ return(ERROR(ERRDOS,ERRnofids));
}
- return(ERROR(ERRDOS,ERRnofids));
- }
- }
+ }
- DEBUG(4,("dptr_num is %d\n",dptr_num));
+ DEBUG(4,("dptr_num is %d\n",dptr_num));
- if (ok)
- {
- if ((dirtype&0x1F) == aVOLID)
- {
- memcpy(p,status,21);
- make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
- dptr_fill(p+12,dptr_num);
- if (dptr_zero(p+12) && (status_len==0))
- numentries = 1;
- else
- numentries = 0;
- p += DIR_STRUCT_SIZE;
- }
- else
- {
- DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
- conn->dirpath,lp_dontdescend(SNUM(conn))));
- if (in_list(conn->dirpath, lp_dontdescend(SNUM(conn)),True))
- check_descend = True;
-
- for (i=numentries;(i<maxentries) && !finished;i++)
- {
- finished =
- !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
- if (!finished)
- {
- memcpy(p,status,21);
- make_dir_struct(p,mask,fname,size,mode,date);
- dptr_fill(p+12,dptr_num);
- numentries++;
- }
- p += DIR_STRUCT_SIZE;
- }
- }
- } /* if (ok ) */
- }
+ if (ok)
+ {
+ if ((dirtype&0x1F) == aVOLID)
+ {
+ memcpy(p,status,21);
+ make_dir_struct(p,"???????????",volume_label(SNUM(conn)),0,aVOLID,0);
+ dptr_fill(p+12,dptr_num);
+ if (dptr_zero(p+12) && (status_len==0))
+ numentries = 1;
+ else
+ numentries = 0;
+ p += DIR_STRUCT_SIZE;
+ }
+ else
+ {
+ DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
+ conn->dirpath,lp_dontdescend(SNUM(conn))));
+ if (in_list(conn->dirpath,
+ lp_dontdescend(SNUM(conn)),True))
+ check_descend = True;
+
+ for (i=numentries;(i<maxentries) && !finished;i++)
+ {
+ finished =
+ !get_dir_entry(conn,mask,dirtype,fname,&size,&mode,&date,check_descend);
+ if (!finished)
+ {
+ memcpy(p,status,21);
+ make_dir_struct(p,mask,fname,size,mode,date);
+ dptr_fill(p+12,dptr_num);
+ numentries++;
+ }
+ p += DIR_STRUCT_SIZE;
+ }
+ }
+ }
+ }
- SearchEmpty:
+ SearchEmpty:
if (numentries == 0 || !ok)
- {
- CVAL(outbuf,smb_rcls) = ERRDOS;
- SSVAL(outbuf,smb_err,ERRnofiles);
- dptr_close(&dptr_num);
- }
+ {
+ CVAL(outbuf,smb_rcls) = ERRDOS;
+ SSVAL(outbuf,smb_err,ERRnofiles);
+ }
/* If we were called as SMBffirst with smb_search_id == NULL
and no entries were found then return error and close dirptr
(X/Open spec) */
if(ok && expect_close && numentries == 0 && status_len == 0)
- {
- CVAL(outbuf,smb_rcls) = ERRDOS;
- SSVAL(outbuf,smb_err,ERRnofiles);
- /* Also close the dptr - we know it's gone */
- dptr_close(&dptr_num);
- }
+ {
+ CVAL(outbuf,smb_rcls) = ERRDOS;
+ SSVAL(outbuf,smb_err,ERRnofiles);
+ /* Also close the dptr - we know it's gone */
+ dptr_close(dptr_num);
+ }
/* If we were called as SMBfunique, then we can close the dirptr now ! */
if(dptr_num >= 0 && CVAL(inbuf,smb_com) == SMBfunique)
- dptr_close(&dptr_num);
+ dptr_close(dptr_num);
SSVAL(outbuf,smb_vwv0,numentries);
SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
@@ -1467,8 +1184,8 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
slprintf(directory, sizeof(directory)-1, "(%s)",dptr_path(dptr_num));
DEBUG( 4, ( "%s mask=%s path=%s dtype=%d nument=%d of %d\n",
- smb_fn_name(CVAL(inbuf,smb_com)),
- mask, directory, dirtype, numentries, maxentries ) );
+ smb_fn_name(CVAL(inbuf,smb_com)),
+ mask, directory, dirtype, numentries, maxentries ) );
return(outsize);
}
@@ -1483,7 +1200,7 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
int status_len;
char *path;
char status[21];
- int dptr_num= -2;
+ int dptr_num= -1;
outsize = set_message(outbuf,1,0,True);
path = smb_buf(inbuf) + 1;
@@ -1497,7 +1214,7 @@ int reply_fclose(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if(dptr_fetch(status+12,&dptr_num)) {
/* Close the dptr - we know it's gone */
- dptr_close(&dptr_num);
+ dptr_close(dptr_num);
}
SSVAL(outbuf,smb_vwv0,0);
@@ -1530,7 +1247,11 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
share_mode = SVAL(inbuf,smb_vwv0);
pstrcpy(fname,smb_buf(inbuf)+1);
- unix_convert(fname,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
fsp = file_new();
if (!fsp)
@@ -1547,10 +1268,11 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- unixmode = unix_mode(conn,aARCH,fname);
+ unixmode = unix_mode(conn,aARCH);
- open_file_shared(fsp,conn,fname,share_mode,(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
- unixmode, oplock_request,&rmode,NULL);
+ open_file_shared(fsp, conn, fname, share_mode,
+ (FILE_FAIL_IF_NOT_EXIST | FILE_EXISTS_OPEN),
+ unixmode, oplock_request, &rmode, NULL);
if (!fsp->open)
{
@@ -1592,7 +1314,7 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ if(fsp->granted_oplock)
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
return(outsize);
}
@@ -1626,13 +1348,19 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
files_struct *fsp;
/* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(conn) && lp_nt_pipe_support())
+ if (IS_IPC(conn) && lp_nt_pipe_support() && lp_security() != SEC_SHARE)
+ {
return reply_open_pipe_and_X(conn, inbuf,outbuf,length,bufsize);
+ }
/* XXXX we need to handle passed times, sattr and flags */
pstrcpy(fname,smb_buf(inbuf));
- unix_convert(fname,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
fsp = file_new();
if (!fsp)
@@ -1649,10 +1377,10 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- unixmode = unix_mode(conn,smb_attr | aARCH, fname);
+ unixmode = unix_mode(conn,smb_attr | aARCH);
- open_file_shared(fsp,conn,fname,smb_mode,smb_ofun,unixmode,
- oplock_request, &rmode,&smb_action);
+ open_file_shared(fsp, conn, fname, smb_mode, smb_ofun, unixmode,
+ oplock_request, &rmode, &smb_action);
if (!fsp->open)
{
@@ -1687,7 +1415,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
smb_action |= EXTENDED_OPLOCK_GRANTED;
}
- if(ex_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ if(ex_oplock_request && fsp->granted_oplock) {
smb_action |= EXTENDED_OPLOCK_GRANTED;
}
@@ -1700,7 +1428,7 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if(core_oplock_request && EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
+ if(core_oplock_request && fsp->granted_oplock) {
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
@@ -1725,9 +1453,14 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
uint16 vuid = SVAL(inbuf,smb_uid);
- user_struct *vuser = get_valid_user_struct(vuid);
+ vuser_key key;
+ user_struct *vuser = NULL;
+ key.pid = conn != NULL ? conn->smbd_pid : getpid();
+ key.vuid = vuid;
+ vuser = get_valid_user_struct(&key);
- if(vuser == 0) {
+ if (vuser == 0)
+ {
DEBUG(3,("ulogoff, vuser id %d does not map to user.\n", vuid));
}
@@ -1737,7 +1470,7 @@ int reply_ulogoffX(connection_struct *conn, char *inbuf,char *outbuf,int length,
file_close_user(vuid);
}
- invalidate_vuid(vuid);
+ invalidate_vuid(&key);
set_message(outbuf,2,0,True);
@@ -1766,14 +1499,18 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
createmode = SVAL(inbuf,smb_vwv0);
pstrcpy(fname,smb_buf(inbuf)+1);
- unix_convert(fname,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
if (createmode & aVOLID)
{
DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
}
- unixmode = unix_mode(conn,createmode,fname);
+ unixmode = unix_mode(conn,createmode);
fsp = file_new();
if (!fsp)
@@ -1793,17 +1530,18 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if(com == SMBmknew)
{
/* We should fail if file exists. */
- ofun = FILE_CREATE_IF_NOT_EXIST;
+ ofun = 0x10;
}
else
{
/* SMBcreate - Create if file doesn't exist, truncate if it does. */
- ofun = FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_TRUNCATE;
+ ofun = 0x12;
}
/* Open file in dos compatibility share mode. */
- open_file_shared(fsp,conn,fname,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
- ofun, unixmode, oplock_request, NULL, NULL);
+ open_file_shared(fsp, conn, fname,
+ SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
+ ofun, unixmode, oplock_request, NULL, NULL);
if (!fsp->open)
{
@@ -1823,7 +1561,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ if(fsp->granted_oplock)
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
DEBUG( 2, ( "new file %s\n", fname ) );
@@ -1851,9 +1589,13 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
createmode = SVAL(inbuf,smb_vwv0);
pstrcpy(fname,smb_buf(inbuf)+1);
pstrcat(fname,"/TMXXXXXX");
- unix_convert(fname,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
- unixmode = unix_mode(conn,createmode,fname);
+ unixmode = unix_mode(conn,createmode);
fsp = file_new();
if (fsp)
@@ -1870,12 +1612,14 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- pstrcpy(fname2,(char *)smbd_mktemp(fname));
+ pstrcpy(fname2,(char *)mktemp(fname));
/* Open file in dos compatibility share mode. */
/* We should fail if file exists. */
- open_file_shared(fsp,conn,fname2,SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
- (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unixmode, oplock_request, NULL, NULL);
+ open_file_shared(fsp,conn,fname2,
+ SET_DENY_MODE(DENY_FCB)|SET_OPEN_MODE(DOS_OPEN_FCB),
+ (FILE_CREATE_IF_NOT_EXIST | FILE_EXISTS_FAIL),
+ unixmode, oplock_request, NULL, NULL);
if (!fsp->open)
{
@@ -1897,7 +1641,7 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ if(fsp->granted_oplock)
CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
DEBUG( 2, ( "created temp file %s\n", fname2 ) );
@@ -1931,9 +1675,8 @@ static BOOL can_delete(char *fname,connection_struct *conn, int dirtype)
}
/****************************************************************************
- Reply to a unlink
+ reply to a unlink
****************************************************************************/
-
int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = 0;
@@ -1947,7 +1690,6 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
BOOL has_wild;
BOOL exists=False;
BOOL bad_path = False;
- BOOL rc = True;
*directory = *mask = 0;
@@ -1957,7 +1699,11 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
DEBUG(3,("reply_unlink : %s\n",name));
- rc = unix_convert(name,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(name,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
p = strrchr(name,'/');
if (!p) {
@@ -1969,16 +1715,7 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
pstrcpy(mask,p+1);
}
- /*
- * We should only check the mangled cache
- * here if unix_convert failed. This means
- * that the path in 'mask' doesn't exist
- * on the file system and so we need to look
- * for a possible mangle. This patch from
- * Tine Smukavec <valentin.smukavec@hermes.si>.
- */
-
- if (!rc && is_mangled(mask))
+ if (is_mangled(mask))
check_mangled_cache( mask );
has_wild = strchr(mask,'*') || strchr(mask,'?');
@@ -1986,10 +1723,11 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (!has_wild) {
pstrcat(directory,"/");
pstrcat(directory,mask);
- if (can_delete(directory,conn,dirtype) && !dos_unlink(directory))
+ if (can_delete(directory,conn,dirtype) &&
+ !conn->vfs_ops.unlink(dos_to_unix(directory,False)))
count++;
if (!count)
- exists = vfs_file_exist(conn,directory,NULL);
+ exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL);
} else {
void *dirptr = NULL;
char *dname;
@@ -2049,7 +1787,6 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
/****************************************************************************
reply to a readbraw (core+ protocol)
****************************************************************************/
-
int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
{
size_t maxcount,mincount;
@@ -2075,45 +1812,13 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
fsp = file_fsp(inbuf,smb_vwv0);
- if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
- /*
- * fsp could be NULL here so use the value from the packet. JRA.
- */
- DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
- _smb_setlen(header,0);
- transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
- return(-1);
- }
-
- CHECK_FSP(fsp,conn);
-
- flush_write_cache(fsp, READRAW_FLUSH);
-
startpos = IVAL(inbuf,smb_vwv1);
+#ifdef LARGE_SMB_OFF_T
if(CVAL(inbuf,smb_wct) == 10) {
/*
* This is a large offset (64 bit) read.
*/
-#ifdef LARGE_SMB_OFF_T
-
startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
-
-#else /* !LARGE_SMB_OFF_T */
-
- /*
- * Ensure we haven't been sent a >32 bit offset.
- */
-
- if(IVAL(inbuf,smb_vwv8) != 0) {
- DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
-64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
- _smb_setlen(header,0);
- transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
- return(-1);
- }
-
-#endif /* LARGE_SMB_OFF_T */
-
if(startpos < 0) {
DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n",
(double)startpos ));
@@ -2122,6 +1827,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
return(-1);
}
}
+#endif /* LARGE_SMB_OFF_T */
maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
@@ -2129,7 +1835,14 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
maxcount = MIN(65535,maxcount);
maxcount = MAX(mincount,maxcount);
- if (!is_locked(fsp,conn,maxcount,startpos, READ_LOCK))
+ if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
+ DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",fsp->fnum));
+ _smb_setlen(header,0);
+ transfer_file(0,Client,(SMB_OFF_T)0,header,4,0);
+ return(-1);
+ }
+
+ if (!is_locked(fsp,conn,maxcount,startpos, F_RDLCK))
{
SMB_OFF_T size = fsp->size;
SMB_OFF_T sizeneeded = startpos + maxcount;
@@ -2151,7 +1864,7 @@ int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_s
DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%d min=%d nread=%d\n",
fsp->fnum, (double)startpos,
- (int)maxcount, (int)mincount, (int)nread ) );
+ maxcount, mincount, nread ) );
#if UNSAFE_READRAW
{
@@ -2219,15 +1932,8 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
outsize = set_message(outbuf,5,3,True);
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
data = smb_buf(outbuf) + 3;
-
- /*
- * NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
- * protocol request that predates the read/write lock concept.
- * Thus instead of asking for a read lock here we need to ask
- * for a write lock. JRA.
- */
-
- if(!do_lock( fsp, conn, numtoread, startpos, WRITE_LOCK, &eclass, &ecode)) {
+
+ if(!do_lock( fsp, conn, numtoread, startpos, F_RDLCK, &eclass, &ecode)) {
if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
/*
* A blocking lock was requested. Package up
@@ -2251,7 +1957,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
SSVAL(smb_buf(outbuf),1,nread);
DEBUG( 3, ( "lockread fnum=%d num=%d nread=%d\n",
- fsp->fnum, (int)numtoread, (int)nread ) );
+ fsp->fnum, numtoread, nread ) );
return(outsize);
}
@@ -2260,8 +1966,7 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
/****************************************************************************
reply to a read
****************************************************************************/
-
-int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
size_t numtoread;
ssize_t nread = 0;
@@ -2281,11 +1986,12 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
data = smb_buf(outbuf) + 3;
- if (is_locked(fsp,conn,numtoread,startpos, READ_LOCK))
+ if (is_locked(fsp,conn,numtoread,startpos, F_RDLCK))
return(ERROR(ERRDOS,ERRlock));
- if (numtoread > 0)
+ if (numtoread > 0) {
nread = read_file(fsp,data,startpos,numtoread);
+ }
if (nread < 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2297,7 +2003,7 @@ int reply_read(connection_struct *conn, char *inbuf,char *outbuf, int size, int
SSVAL(smb_buf(outbuf),1,nread);
DEBUG( 3, ( "read fnum=%d num=%d nread=%d\n",
- fsp->fnum, (int)numtoread, (int)nread ) );
+ fsp->fnum, numtoread, nread ) );
return(outsize);
}
@@ -2326,42 +2032,28 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
set_message(outbuf,12,0,True);
data = smb_buf(outbuf);
- if(CVAL(inbuf,smb_wct) == 12) {
#ifdef LARGE_SMB_OFF_T
+ if(CVAL(inbuf,smb_wct) == 12) {
/*
* This is a large offset (64 bit) read.
*/
startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
-
-#else /* !LARGE_SMB_OFF_T */
-
- /*
- * Ensure we haven't been sent a >32 bit offset.
- */
-
- if(IVAL(inbuf,smb_vwv10) != 0) {
- DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
-64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
- return(ERROR(ERRDOS,ERRbadaccess));
- }
-
-#endif /* LARGE_SMB_OFF_T */
-
}
+#endif /* LARGE_SMB_OFF_T */
- if (is_locked(fsp,conn,smb_maxcnt,startpos, READ_LOCK))
+ if (is_locked(fsp,conn,smb_maxcnt,startpos, F_RDLCK))
return(ERROR(ERRDOS,ERRlock));
nread = read_file(fsp,data,startpos,smb_maxcnt);
-
+
if (nread < 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
SSVAL(outbuf,smb_vwv5,nread);
SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
SSVAL(smb_buf(outbuf),-2,nread);
-
+
DEBUG( 3, ( "readX fnum=%d min=%d max=%d nread=%d\n",
- fsp->fnum, (int)smb_mincnt, (int)smb_maxcnt, (int)nread ) );
+ fsp->fnum, smb_mincnt, smb_maxcnt, nread ) );
return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -2369,8 +2061,7 @@ int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
/****************************************************************************
reply to a writebraw (core+ or LANMAN1.0 protocol)
****************************************************************************/
-
-int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
ssize_t nwritten=0;
ssize_t total_written=0;
@@ -2404,14 +2095,19 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
CVAL(inbuf,smb_com) = SMBwritec;
CVAL(outbuf,smb_com) = SMBwritec;
- if (is_locked(fsp,conn,tcount,startpos, WRITE_LOCK))
+ if (is_locked(fsp,conn,tcount,startpos, F_WRLCK))
return(ERROR(ERRDOS,ERRlock));
+ if (seek_file(fsp,startpos) == -1) {
+ DEBUG(0,("couldn't seek to %.0f in writebraw\n",(double)startpos));
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+
if (numtowrite>0)
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ nwritten = write_file(fsp,data,numtowrite);
DEBUG(3,("writebraw1 fnum=%d start=%.0f num=%d wrote=%d sync=%d\n",
- fsp->fnum, (double)startpos, (int)numtowrite, (int)nwritten, (int)write_through));
+ fsp->fnum, (double)startpos, numtowrite, nwritten, write_through));
if (nwritten < numtowrite)
return(UNIXERROR(ERRHRD,ERRdiskfull));
@@ -2436,7 +2132,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
if (tcount > nwritten+numtowrite) {
DEBUG(3,("Client overestimated the write %d %d %d\n",
- (int)tcount,(int)nwritten,(int)numtowrite));
+ tcount,nwritten,numtowrite));
}
nwritten = vfs_transfer_file(Client, NULL, -1, fsp,
@@ -2456,10 +2152,10 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
if ((lp_syncalways(SNUM(conn)) || write_through) &&
lp_strict_sync(SNUM(conn)))
- conn->vfs_ops.fsync(fsp->fd_ptr->fd);
+ conn->vfs_ops.sync(fsp->fd_ptr->fd);
DEBUG(3,("writebraw2 fnum=%d start=%.0f num=%d wrote=%d\n",
- fsp->fnum, (double)startpos, (int)numtowrite,(int)total_written));
+ fsp->fnum, (double)startpos, numtowrite, total_written));
/* we won't return a status if write through is not selected - this
follows what WfWg does */
@@ -2472,8 +2168,7 @@ int reply_writebraw(connection_struct *conn, char *inbuf,char *outbuf, int size,
/****************************************************************************
reply to a writeunlock (core+)
****************************************************************************/
-
-int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
ssize_t nwritten = -1;
size_t numtowrite;
@@ -2492,19 +2187,22 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
startpos = IVAL(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (is_locked(fsp,conn,numtowrite,startpos, WRITE_LOCK))
+ if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
return(ERROR(ERRDOS,ERRlock));
+ if(seek_file(fsp,startpos) == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
/* The special X/Open SMB protocol handling of
zero length writes is *NOT* done for
this call */
if(numtowrite == 0)
nwritten = 0;
else
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ nwritten = write_file(fsp,data,numtowrite);
- if (lp_syncalways(SNUM(conn)))
- conn->vfs_ops.fsync(fsp->fd_ptr->fd);
+ if (lp_syncalways(SNUM(conn)) && lp_strict_sync(SNUM(conn)))
+ conn->vfs_ops.sync(fsp->fd_ptr->fd);
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2517,7 +2215,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
SSVAL(outbuf,smb_vwv0,nwritten);
DEBUG( 3, ( "writeunlock fnum=%d num=%d wrote=%d\n",
- fsp->fnum, (int)numtowrite, (int)nwritten ) );
+ fsp->fnum, numtowrite, nwritten ) );
return(outsize);
}
@@ -2525,7 +2223,7 @@ int reply_writeunlock(connection_struct *conn, char *inbuf,char *outbuf, int siz
/****************************************************************************
reply to a write
****************************************************************************/
-int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int dum_buffsize)
+int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int dum_size,int dum_buffsize)
{
size_t numtowrite;
ssize_t nwritten = -1;
@@ -2534,9 +2232,9 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
int outsize = 0;
- /* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(conn))
- return reply_pipe_write(inbuf,outbuf,size,dum_buffsize);
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(conn))
+ return reply_pipe_write(inbuf,outbuf,dum_size,dum_buffsize);
CHECK_FSP(fsp,conn);
CHECK_WRITE(fsp);
@@ -2546,20 +2244,22 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
startpos = IVAL(inbuf,smb_vwv2);
data = smb_buf(inbuf) + 3;
- if (is_locked(fsp,conn,numtowrite,startpos, WRITE_LOCK))
+ if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
return(ERROR(ERRDOS,ERRlock));
+ if(seek_file(fsp,startpos) == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
/* X/Open SMB protocol says that if smb_vwv1 is
zero then the file size should be extended or
truncated to the size given in smb_vwv[2-3] */
- if(numtowrite == 0) {
- if((nwritten = set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T)startpos)) >= 0) /* tpot vfs */
- set_filelen_write_cache(fsp, startpos);
- } else
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ if(numtowrite == 0)
+ nwritten = set_filelen(fsp->fd_ptr->fd, (SMB_OFF_T)startpos);
+ else
+ nwritten = write_file(fsp,data,numtowrite);
- if (lp_syncalways(SNUM(conn)))
- conn->vfs_ops.fsync(fsp->fd_ptr->fd);
+ if (lp_syncalways(SNUM(conn)) && lp_strict_sync(SNUM(conn)))
+ conn->vfs_ops.sync(fsp->fd_ptr->fd);
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2574,7 +2274,7 @@ int reply_write(connection_struct *conn, char *inbuf,char *outbuf,int size,int d
}
DEBUG(3,("write fnum=%d num=%d wrote=%d\n",
- fsp->fnum, (int)numtowrite, (int)nwritten));
+ fsp->fnum, numtowrite, nwritten));
return(outsize);
}
@@ -2603,31 +2303,21 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
data = smb_base(inbuf) + smb_doff;
- if(CVAL(inbuf,smb_wct) == 14) {
#ifdef LARGE_SMB_OFF_T
+ if(CVAL(inbuf,smb_wct) == 14) {
/*
* This is a large offset (64 bit) write.
*/
startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
-
-#else /* !LARGE_SMB_OFF_T */
-
- /*
- * Ensure we haven't been sent a >32 bit offset.
- */
-
- if(IVAL(inbuf,smb_vwv12) != 0) {
- DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
-64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
- return(ERROR(ERRDOS,ERRbadaccess));
- }
-
-#endif /* LARGE_SMB_OFF_T */
}
+#endif /* LARGE_SMB_OFF_T */
- if (is_locked(fsp,conn,numtowrite,startpos, WRITE_LOCK))
+ if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
return(ERROR(ERRDOS,ERRlock));
+ if(seek_file(fsp,startpos) == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
/* X/Open SMB protocol says that, unlike SMBwrite
if the length is zero then NO truncation is
done, just a write of zero. To truncate a file,
@@ -2635,7 +2325,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
if(numtowrite == 0)
nwritten = 0;
else
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ nwritten = write_file(fsp,data,numtowrite);
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0))
return(UNIXERROR(ERRDOS,ERRnoaccess));
@@ -2650,10 +2340,11 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
}
DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
- fsp->fnum, (int)numtowrite, (int)nwritten));
+ fsp->fnum, numtowrite, nwritten));
- if (lp_syncalways(SNUM(conn)) || write_through)
- conn->vfs_ops.fsync(fsp->fd_ptr->fd);
+ if ((lp_syncalways(SNUM(conn)) || write_through) &&
+ lp_strict_sync(SNUM(conn)))
+ conn->vfs_ops.sync(fsp->fd_ptr->fd);
return chain_reply(inbuf,outbuf,length,bufsize);
}
@@ -2662,8 +2353,7 @@ int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int leng
/****************************************************************************
reply to a lseek
****************************************************************************/
-
-int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
SMB_OFF_T startpos;
SMB_OFF_T res= -1;
@@ -2674,12 +2364,11 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
CHECK_FSP(fsp,conn);
CHECK_ERROR(fsp);
- flush_write_cache(fsp, SEEK_FLUSH);
-
mode = SVAL(inbuf,smb_vwv1) & 3;
- startpos = IVALS(inbuf,smb_vwv2);
+ startpos = IVAL(inbuf,smb_vwv2);
- switch (mode) {
+ switch (mode & 3)
+ {
case 0: umode = SEEK_SET; break;
case 1: umode = SEEK_CUR; break;
case 2: umode = SEEK_END; break;
@@ -2687,48 +2376,16 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
umode = SEEK_SET; break;
}
- if((res = conn->vfs_ops.lseek(fsp->fd_ptr->fd,startpos,umode)) == -1) {
- /*
- * Check for the special case where a seek before the start
- * of the file sets the offset to zero. Added in the CIFS spec,
- * section 4.2.7.
- */
-
- if(errno == EINVAL) {
- SMB_OFF_T current_pos = startpos;
-
- if(umode == SEEK_CUR) {
-
- if((current_pos = conn->vfs_ops.lseek(fsp->fd_ptr->fd,0,SEEK_CUR)) == -1)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- current_pos += startpos;
-
- } else if (umode == SEEK_END) {
-
- SMB_STRUCT_STAT sbuf;
-
- if(conn->vfs_ops.fstat(fsp->fd_ptr->fd, &sbuf) == -1)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- current_pos += sbuf.st_size;
- }
-
- if(current_pos < 0)
- res = conn->vfs_ops.lseek(fsp->fd_ptr->fd,0,SEEK_SET);
- }
-
- if(res == -1)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
+ if((res = conn->vfs_ops.lseek(fsp->fd_ptr->fd,startpos,umode)) == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
fsp->pos = res;
outsize = set_message(outbuf,2,0,True);
- SIVAL(outbuf,smb_vwv0,res);
+ SIVALS(outbuf,smb_vwv0,res);
- DEBUG(3,("lseek fnum=%d ofs=%.0f newpos = %.0f mode=%d\n",
- fsp->fnum, (double)startpos, (double)res, mode));
+ DEBUG(3,("lseek fnum=%d ofs=%.0f mode=%d\n",
+ fsp->fnum, (double)startpos, mode));
return(outsize);
}
@@ -2736,8 +2393,7 @@ int reply_lseek(connection_struct *conn, char *inbuf,char *outbuf, int size, int
/****************************************************************************
reply to a flush
****************************************************************************/
-
-int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = set_message(outbuf,0,0,True);
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
@@ -2750,7 +2406,7 @@ int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int
if (!fsp) {
file_sync_all(conn);
} else {
- conn->vfs_ops.fsync(fsp->fd_ptr->fd);
+ conn->vfs_ops.sync(fsp->fd_ptr->fd);
}
DEBUG(3,("flush\n"));
@@ -2774,8 +2430,8 @@ int reply_exit(connection_struct *conn,
/****************************************************************************
Reply to a close - has to deal with closing a directory opened by NT SMB's.
****************************************************************************/
-int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
- int dum_buffsize)
+int reply_close(connection_struct *conn,
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = 0;
time_t mtime;
@@ -2785,8 +2441,9 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
outsize = set_message(outbuf,0,0,True);
/* If it's an IPC, pass off to the pipe handler. */
- if (IS_IPC(conn))
+ if (IS_IPC(conn)) {
return reply_pipe_close(conn, inbuf,outbuf);
+ }
fsp = file_fsp(inbuf,smb_vwv0);
@@ -2794,26 +2451,25 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
* We can only use CHECK_FSP if we know it's not a directory.
*/
- if(!fsp || !fsp->open || (fsp->conn != conn))
- return(ERROR(ERRDOS,ERRbadfid));
+ if(!fsp || !fsp->open || (fsp->conn != conn))
+ return(ERROR(ERRDOS,ERRbadfid));
if(HAS_CACHED_ERROR(fsp)) {
eclass = fsp->wbmpx_ptr->wr_errclass;
err = fsp->wbmpx_ptr->wr_error;
}
- if(fsp->is_directory || fsp->stat_open) {
+ if(fsp->is_directory) {
/*
- * Special case - close NT SMB directory or stat file
+ * Special case - close NT SMB directory
* handle.
*/
- DEBUG(3,("close %s fnum=%d\n", fsp->is_directory ? "directory" : "stat file open", fsp->fnum));
- close_file(fsp,True);
+ DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
+ close_directory(fsp);
} else {
/*
* Close ordinary file.
*/
- int close_err;
/*
* If there was a modify time outstanding,
@@ -2831,19 +2487,10 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
set_filetime(conn, fsp->fsp_name,mtime);
DEBUG(3,("close fd=%d fnum=%d (numopen=%d)\n",
- fsp->fd_ptr ? fsp->fd_ptr->fd : -1, fsp->fnum,
+ fsp->fd_ptr->fd, fsp->fnum,
conn->num_files_open));
-
- /*
- * close_file() returns the unix errno if an error
- * was detected on close - normally this is due to
- * a disk full error. If not then it was probably an I/O error.
- */
-
- if((close_err = close_file(fsp,True)) != 0) {
- errno = close_err;
- return (UNIXERROR(ERRHRD,ERRgeneral));
- }
+
+ close_file(fsp,True);
}
/* We have a cached error */
@@ -2857,14 +2504,12 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
/****************************************************************************
reply to a writeclose (Core+ protocol)
****************************************************************************/
-
int reply_writeclose(connection_struct *conn,
- char *inbuf,char *outbuf, int size, int dum_buffsize)
+ char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
size_t numtowrite;
ssize_t nwritten = -1;
int outsize = 0;
- int close_err = 0;
SMB_OFF_T startpos;
char *data;
time_t mtime;
@@ -2879,27 +2524,25 @@ int reply_writeclose(connection_struct *conn,
mtime = make_unix_date3(inbuf+smb_vwv4);
data = smb_buf(inbuf) + 1;
- if (is_locked(fsp,conn,numtowrite,startpos, WRITE_LOCK))
+ if (is_locked(fsp,conn,numtowrite,startpos, F_WRLCK))
return(ERROR(ERRDOS,ERRlock));
-
- nwritten = write_file(fsp,data,startpos,numtowrite);
+
+ if(seek_file(fsp,startpos) == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+
+ nwritten = write_file(fsp,data,numtowrite);
set_filetime(conn, fsp->fsp_name,mtime);
- close_err = close_file(fsp,True);
+ close_file(fsp,True);
DEBUG(3,("writeclose fnum=%d num=%d wrote=%d (numopen=%d)\n",
- fsp->fnum, (int)numtowrite, (int)nwritten,
+ fsp->fnum, numtowrite, nwritten,
conn->num_files_open));
if (nwritten <= 0)
return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- if(close_err != 0) {
- errno = close_err;
- return(UNIXERROR(ERRHRD,ERRgeneral));
- }
-
+
outsize = set_message(outbuf,1,0,True);
SSVAL(outbuf,smb_vwv0,nwritten);
@@ -2928,7 +2571,7 @@ int reply_lock(connection_struct *conn,
DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
fsp->fd_ptr->fd, fsp->fnum, (double)offset, (double)count));
- if (!do_lock(fsp, conn, count, offset, WRITE_LOCK, &eclass, &ecode)) {
+ if (!do_lock(fsp, conn, count, offset, F_WRLCK, &eclass, &ecode)) {
if((ecode == ERRlock) && lp_blocking_locks(SNUM(conn))) {
/*
* A blocking lock was requested. Package up
@@ -2948,7 +2591,7 @@ int reply_lock(connection_struct *conn,
/****************************************************************************
reply to a unlock
****************************************************************************/
-int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+int reply_unlock(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
int outsize = set_message(outbuf,0,0,True);
SMB_OFF_T count,offset;
@@ -3027,8 +2670,6 @@ int reply_echo(connection_struct *conn,
DEBUG(3,("echo %d times\n", smb_reverb));
- smb_echo_count++;
-
return -1;
}
@@ -3069,7 +2710,7 @@ int reply_printopen(connection_struct *conn,
if (!fsp)
return(ERROR(ERRSRV,ERRnofids));
- pstrcpy(fname2,(char *)smbd_mktemp(fname));
+ pstrcpy(fname2,(char *)mktemp(fname));
if (!check_name(fname2,conn)) {
file_free(fsp);
@@ -3078,7 +2719,7 @@ int reply_printopen(connection_struct *conn,
/* Open for exclusive use, write only. */
open_file_shared(fsp,conn,fname2, SET_DENY_MODE(DENY_ALL)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
- (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unix_mode(conn,0,fname2), 0, NULL, NULL);
+ (FILE_CREATE_IF_NOT_EXIST|FILE_EXISTS_FAIL), unix_mode(conn,0), 0, NULL, NULL);
if (!fsp->open) {
file_free(fsp);
@@ -3106,7 +2747,6 @@ int reply_printclose(connection_struct *conn,
{
int outsize = set_message(outbuf,0,0,True);
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
- int close_err = 0;
CHECK_FSP(fsp,conn);
CHECK_ERROR(fsp);
@@ -3117,12 +2757,7 @@ int reply_printclose(connection_struct *conn,
DEBUG(3,("printclose fd=%d fnum=%d\n",
fsp->fd_ptr->fd,fsp->fnum));
- close_err = close_file(fsp,True);
-
- if(close_err != 0) {
- errno = close_err;
- return(UNIXERROR(ERRHRD,ERRgeneral));
- }
+ close_file(fsp,True);
return(outsize);
}
@@ -3137,6 +2772,8 @@ int reply_printqueue(connection_struct *conn,
int outsize = set_message(outbuf,2,3,True);
int max_count = SVAL(inbuf,smb_vwv0);
int start_index = SVAL(inbuf,smb_vwv1);
+ uint16 vuid = SVAL(inbuf,smb_uid);
+ VUSER_KEY;
/* we used to allow the client to get the cnum wrong, but that
is really quite gross and only worked when there was only
@@ -3156,7 +2793,7 @@ int reply_printqueue(connection_struct *conn,
{
print_queue_struct *queue = NULL;
char *p = smb_buf(outbuf) + 3;
- int count = get_printqueue(SNUM(conn), conn,&queue,NULL);
+ int count = get_printqueue(SNUM(conn), conn, &key, &queue,NULL);
int num_to_get = ABS(max_count);
int first = (max_count>0?start_index:start_index+max_count+1);
int i;
@@ -3215,7 +2852,7 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
numtowrite = SVAL(smb_buf(inbuf),1);
data = smb_buf(inbuf) + 3;
- if (write_file(fsp,data,-1,numtowrite) != numtowrite)
+ if (write_file(fsp,data,numtowrite) != numtowrite)
return(UNIXERROR(ERRDOS,ERRnoaccess));
DEBUG( 3, ( "printwrite fnum=%d num=%d\n", fsp->fnum, numtowrite ) );
@@ -3234,11 +2871,15 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
BOOL bad_path = False;
pstrcpy(directory,smb_buf(inbuf) + 1);
- unix_convert(directory,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(directory,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
if (check_name(directory, conn))
ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
- unix_mode(conn,aDIR,directory));
+ unix_mode(conn,aDIR));
if (ret < 0)
{
@@ -3261,12 +2902,11 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
Static function used by reply_rmdir to delete an entire directory
tree recursively.
****************************************************************************/
-
static BOOL recursive_rmdir(connection_struct *conn, char *directory)
{
char *dname = NULL;
BOOL ret = False;
- void *dirptr = OpenDir(NULL, directory, False);
+ void *dirptr = OpenDir(conn, directory, False);
if(dirptr == NULL)
return True;
@@ -3320,97 +2960,8 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
}
/****************************************************************************
- The internals of the rmdir code - called elsewhere.
+ reply to a rmdir
****************************************************************************/
-
-BOOL rmdir_internals(connection_struct *conn, char *directory)
-{
- BOOL ok;
-
- ok = (conn->vfs_ops.rmdir(dos_to_unix(directory, False)) == 0);
- if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn)))
- {
- /*
- * Check to see if the only thing in this directory are
- * vetoed files/directories. If so then delete them and
- * retry. If we fail to delete any of them (and we *don't*
- * do a recursive delete) then fail the rmdir.
- */
- BOOL all_veto_files = True;
- char *dname;
- void *dirptr = OpenDir(conn, directory, False);
-
- if(dirptr != NULL)
- {
- int dirpos = TellDir(dirptr);
- while ((dname = ReadDirName(dirptr)))
- {
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
- continue;
- if(!IS_VETO_PATH(conn, dname))
- {
- all_veto_files = False;
- break;
- }
- }
- if(all_veto_files)
- {
- SeekDir(dirptr,dirpos);
- while ((dname = ReadDirName(dirptr)))
- {
- pstring fullname;
- SMB_STRUCT_STAT st;
-
- if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
- continue;
-
- /* Construct the full name. */
- if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
- {
- errno = ENOMEM;
- break;
- }
- pstrcpy(fullname, directory);
- pstrcat(fullname, "/");
- pstrcat(fullname, dname);
-
- if(conn->vfs_ops.lstat(dos_to_unix(fullname, False), &st) != 0)
- break;
- if(st.st_mode & S_IFDIR)
- {
- if(lp_recursive_veto_delete(SNUM(conn)))
- {
- if(recursive_rmdir(conn, fullname) != 0)
- break;
- }
- if(conn->vfs_ops.rmdir(dos_to_unix(fullname, False)) != 0)
- break;
- }
- else if(conn->vfs_ops.unlink(dos_to_unix(fullname, False)) != 0)
- break;
- }
- CloseDir(dirptr);
- /* Retry the rmdir */
- ok = (conn->vfs_ops.rmdir(dos_to_unix(directory, False)) == 0);
- }
- else
- CloseDir(dirptr);
- }
- else
- errno = ENOTEMPTY;
- }
-
- if (!ok)
- DEBUG(3,("rmdir_internals: couldn't remove directory %s : %s\n",
- directory,strerror(errno)));
-
- return ok;
-}
-
-/****************************************************************************
- Reply to a rmdir.
-****************************************************************************/
-
int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
pstring directory;
@@ -3419,14 +2970,94 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
BOOL bad_path = False;
pstrcpy(directory,smb_buf(inbuf) + 1);
- unix_convert(directory,conn, NULL,&bad_path,NULL);
-
- if (check_name(directory,conn))
+ if (!unix_dfs_convert(directory,conn, NULL,&bad_path,NULL))
{
- dptr_closepath(directory,SVAL(inbuf,smb_pid));
- ok = rmdir_internals(conn, directory);
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
}
+ if (check_name(directory,conn))
+ {
+
+ dptr_closepath(directory,SVAL(inbuf,smb_pid));
+ ok = (conn->vfs_ops.rmdir(dos_to_unix(directory,False)) == 0);
+ if(!ok && (errno == ENOTEMPTY) && lp_veto_files(SNUM(conn)))
+ {
+ /* Check to see if the only thing in this directory are
+ vetoed files/directories. If so then delete them and
+ retry. If we fail to delete any of them (and we *don't*
+ do a recursive delete) then fail the rmdir. */
+ BOOL all_veto_files = True;
+ char *dname;
+ void *dirptr = OpenDir(conn, directory, False);
+
+ if(dirptr != NULL)
+ {
+ int dirpos = TellDir(dirptr);
+ while ((dname = ReadDirName(dirptr)))
+ {
+ if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+ continue;
+ if(!IS_VETO_PATH(conn, dname))
+ {
+ all_veto_files = False;
+ break;
+ }
+ }
+ if(all_veto_files)
+ {
+ SeekDir(dirptr,dirpos);
+ while ((dname = ReadDirName(dirptr)))
+ {
+ pstring fullname;
+ SMB_STRUCT_STAT st;
+
+ if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
+ continue;
+
+ /* Construct the full name. */
+ if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname))
+ {
+ errno = ENOMEM;
+ break;
+ }
+ pstrcpy(fullname, directory);
+ pstrcat(fullname, "/");
+ pstrcat(fullname, dname);
+
+ if(conn->vfs_ops.lstat(dos_to_unix(fullname,False),
+ &st) != 0)
+ break;
+ if(st.st_mode & S_IFDIR)
+ {
+ if(lp_recursive_veto_delete(SNUM(conn)))
+ {
+ DEBUG(0, ("ERROR: recursive_rmdir()\n"));
+ if(recursive_rmdir(conn, fullname) != 0)
+ break;
+ }
+ if(conn->vfs_ops.rmdir(dos_to_unix(fullname,False)) != 0)
+ break;
+ }
+ else if(conn->vfs_ops.unlink(dos_to_unix(fullname,False)) != 0)
+ break;
+ }
+ CloseDir(dirptr);
+ /* Retry the rmdir */
+ ok = (conn->vfs_ops.rmdir(dos_to_unix(directory,False)) == 0);
+ }
+ else
+ CloseDir(dirptr);
+ }
+ else
+ errno = ENOTEMPTY;
+ }
+
+ if (!ok)
+ DEBUG(3,("couldn't remove directory %s : %s\n",
+ directory,strerror(errno)));
+ }
+
if (!ok)
{
if((errno == ENOENT) && bad_path)
@@ -3542,16 +3173,23 @@ int rename_internals(connection_struct *conn,
int count=0;
int error = ERRnoaccess;
BOOL exists=False;
- BOOL rc = True;
*directory = *mask = 0;
- rc = unix_convert(name,conn,0,&bad_path1,NULL);
- unix_convert(newname,conn,newname_last_component,&bad_path2,NULL);
+ if (!unix_dfs_convert(name,conn,0,&bad_path1,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
+ if (!unix_dfs_convert(newname,conn,newname_last_component,&bad_path2,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
/*
* Split the old name into directory and last component
- * strings. Note that unix_convert may have stripped off a
+ * strings. Note that if (!unix_dfs_convert may have stripped off a
* leading ./ from both name and newname if the rename is
* at the root of the share. We need to make sure either both
* name and newname contain a / character or neither of them do
@@ -3569,16 +3207,7 @@ int rename_internals(connection_struct *conn,
*p = '/'; /* Replace needed for exceptional test below. */
}
- /*
- * We should only check the mangled cache
- * here if unix_convert failed. This means
- * that the path in 'mask' doesn't exist
- * on the file system and so we need to look
- * for a possible mangle. This patch from
- * Tine Smukavec <valentin.smukavec@hermes.si>.
- */
-
- if (!rc && is_mangled(mask))
+ if (is_mangled(mask))
check_mangled_cache( mask );
has_wild = strchr(mask,'*') || strchr(mask,'?');
@@ -3654,7 +3283,7 @@ int rename_internals(connection_struct *conn,
} else {
if (resolve_wildcards(directory,newname) &&
can_rename(directory,conn) &&
- !vfs_file_exist(conn,newname,NULL) &&
+ !vfs_file_exist(conn,dos_to_unix(newname,False),NULL) &&
!conn->vfs_ops.rename(dos_to_unix(directory,False),
newname))
count++;
@@ -3663,8 +3292,8 @@ int rename_internals(connection_struct *conn,
DEBUG(3,("rename_internals: %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed",
directory,newname));
- if (!count) exists = vfs_file_exist(conn,directory,NULL);
- if (!count && exists && vfs_file_exist(conn,newname,NULL)) {
+ if (!count) exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL);
+ if (!count && exists && vfs_file_exist(conn,dos_to_unix(newname,False),NULL)) {
exists = True;
error = ERRrename;
}
@@ -3701,20 +3330,17 @@ int rename_internals(connection_struct *conn,
pstrcpy(destname,newname);
if (!resolve_wildcards(fname,destname)) {
- DEBUG(6,("resolve_wildcards %s %s failed\n",
- fname, destname));
+ DEBUG(6,("resolve_wildcards %s %s failed\n", fname, destname));
continue;
}
- if (!replace_if_exists &&
- vfs_file_exist(conn,destname, NULL)) {
+ if (!replace_if_exists && vfs_file_exist(conn,dos_to_unix(destname,False),NULL)) {
DEBUG(6,("file_exist %s\n", destname));
error = 183;
continue;
}
- if (!conn->vfs_ops.rename(dos_to_unix(fname,False),
- destname))
+ if (!conn->vfs_ops.rename(dos_to_unix(fname,False),destname))
count++;
DEBUG(3,("rename_internals: doing rename on %s -> %s\n",fname,destname));
}
@@ -3764,16 +3390,14 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, in
******************************************************************/
static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
- int count,BOOL target_is_directory, int *err_ret)
+ int count,BOOL target_is_directory)
{
int Access,action;
SMB_STRUCT_STAT st;
- SMB_OFF_T ret=-1;
+ int ret=-1;
files_struct *fsp1,*fsp2;
pstring dest;
- *err_ret = 0;
-
pstrcpy(dest,dest1);
if (target_is_directory) {
char *p = strrchr(src,'/');
@@ -3785,15 +3409,16 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
pstrcat(dest,p);
}
- if (!vfs_file_exist(conn,src,&st))
+ if (!vfs_file_exist(conn,dos_to_unix(src,False),&st))
return(False);
fsp1 = file_new();
- if (!fsp1)
+ if (!fsp1)
return(False);
- open_file_shared(fsp1,conn,src,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
- (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),0,0,&Access,&action);
+ open_file_shared(fsp1, conn, src,
+ SET_DENY_MODE(DENY_NONE) | SET_OPEN_MODE(DOS_OPEN_RDONLY),
+ (FILE_FAIL_IF_NOT_EXIST | FILE_EXISTS_OPEN), 0, 0, &Access, &action);
if (!fsp1->open) {
file_free(fsp1);
@@ -3808,8 +3433,9 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
close_file(fsp1,False);
return(False);
}
- open_file_shared(fsp2,conn,dest,SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_WRONLY),
- ofun,st.st_mode,0,&Access,&action);
+ open_file_shared(fsp2, conn, dest,
+ SET_DENY_MODE(DENY_NONE) | SET_OPEN_MODE(DOS_OPEN_WRONLY),
+ ofun, st.st_mode, 0, &Access, &action);
if (!fsp2->open) {
close_file(fsp1,False);
@@ -3833,15 +3459,9 @@ static BOOL copy_file(char *src,char *dest1,connection_struct *conn, int ofun,
ret = vfs_transfer_file(-1, fsp1, -1, fsp2, st.st_size, NULL, 0, 0);
close_file(fsp1,False);
- /*
- * As we are opening fsp1 read-only we only expect
- * an error on close on fsp2 if we are out of space.
- * Thus we don't look at the error return from the
- * close of fsp1.
- */
- *err_ret = close_file(fsp2,False);
+ close_file(fsp2,False);
- return(ret == (SMB_OFF_T)st.st_size);
+ return(ret == st.st_size);
}
@@ -3858,7 +3478,6 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
char *p;
int count=0;
int error = ERRnoaccess;
- int err = 0;
BOOL has_wild;
BOOL exists=False;
int tid2 = SVAL(inbuf,smb_vwv0);
@@ -3867,7 +3486,6 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
BOOL target_is_directory=False;
BOOL bad_path1 = False;
BOOL bad_path2 = False;
- BOOL rc = True;
*directory = *mask = 0;
@@ -3882,10 +3500,18 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return(ERROR(ERRSRV,ERRinvdevice));
}
- rc = unix_convert(name,conn,0,&bad_path1,NULL);
- unix_convert(newname,conn,0,&bad_path2,NULL);
+ if (!unix_dfs_convert(name,conn,0,&bad_path1,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
+ if (!unix_dfs_convert(newname,conn,0,&bad_path2,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
- target_is_directory = vfs_directory_exist(conn,False,NULL);
+ target_is_directory = dos_directory_exist(newname,NULL);
if ((flags&1) && target_is_directory) {
return(ERROR(ERRDOS,ERRbadfile));
@@ -3895,7 +3521,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return(ERROR(ERRDOS,ERRbadpath));
}
- if ((flags&(1<<5)) && vfs_directory_exist(conn,name,NULL)) {
+ if ((flags&(1<<5)) && dos_directory_exist(name,NULL)) {
/* wants a tree copy! XXXX */
DEBUG(3,("Rejecting tree copy\n"));
return(ERROR(ERRSRV,ERRerror));
@@ -3911,16 +3537,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
pstrcpy(mask,p+1);
}
- /*
- * We should only check the mangled cache
- * here if unix_convert failed. This means
- * that the path in 'mask' doesn't exist
- * on the file system and so we need to look
- * for a possible mangle. This patch from
- * Tine Smukavec <valentin.smukavec@hermes.si>.
- */
-
- if (!rc && is_mangled(mask))
+ if (is_mangled(mask))
check_mangled_cache( mask );
has_wild = strchr(mask,'*') || strchr(mask,'?');
@@ -3930,12 +3547,8 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
pstrcat(directory,mask);
if (resolve_wildcards(directory,newname) &&
copy_file(directory,newname,conn,ofun,
- count,target_is_directory,&err)) count++;
- if(!count && err) {
- errno = err;
- return(UNIXERROR(ERRHRD,ERRgeneral));
- }
- if (!count) exists = vfs_file_exist(conn,directory,NULL);
+ count,target_is_directory)) count++;
+ if (!count) exists = vfs_file_exist(conn,dos_to_unix(directory,False),NULL);
} else {
void *dirptr = NULL;
char *dname;
@@ -3944,38 +3557,33 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
if (check_name(directory,conn))
dirptr = OpenDir(conn, directory, True);
- if (dirptr) {
+ if (dirptr)
+ {
error = ERRbadfile;
if (strequal(mask,"????????.???"))
pstrcpy(mask,"*");
- while ((dname = ReadDirName(dirptr))) {
+ while ((dname = ReadDirName(dirptr)))
+ {
pstring fname;
pstrcpy(fname,dname);
- if(!mask_match(fname, mask, case_sensitive, False))
- continue;
+ if(!mask_match(fname, mask, case_sensitive, False)) continue;
error = ERRnoaccess;
slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
pstrcpy(destname,newname);
if (resolve_wildcards(fname,destname) &&
- copy_file(fname,destname,conn,ofun,
- count,target_is_directory,&err)) count++;
+ copy_file(directory,newname,conn,ofun,
+ count,target_is_directory)) count++;
DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
}
CloseDir(dirptr);
- }
+ }
}
if (count == 0) {
- if(err) {
- /* Error on close... */
- errno = err;
- return(UNIXERROR(ERRHRD,ERRgeneral));
- }
-
if (exists)
return(ERROR(ERRDOS,error));
else
@@ -4015,7 +3623,7 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (strlen(newdir) == 0) {
ok = True;
} else {
- ok = vfs_directory_exist(conn,newdir,NULL);
+ ok = dos_directory_exist(newdir,NULL);
if (ok) {
string_set(&conn->connectpath,newdir);
}
@@ -4033,154 +3641,14 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
}
/****************************************************************************
- Get a lock count, dealing with large count requests.
-****************************************************************************/
-
-SMB_OFF_T get_lock_count( char *data, int data_offset, BOOL large_file_format, BOOL *err)
-{
- SMB_OFF_T count = 0;
-
- *err = False;
-
- if(!large_file_format) {
- count = (SMB_OFF_T)IVAL(data,SMB_LKLEN_OFFSET(data_offset));
- } else {
-
-#if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS)
-
- count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset))) << 32) |
- ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)));
-
-#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
-
- /*
- * NT4.x seems to be broken in that it sends large file
- * lockingX calls even if the CAP_LARGE_FILES was *not*
- * negotiated. For boxes without large file locks truncate the
- * lock count by dropping the top 32 bits.
- */
-
- if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
- DEBUG(3,("get_lock_count: truncating lock count (high)0x%x (low)0x%x to just low count.\n",
- (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
- (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
- SIVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset),0);
- }
-
- if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) != 0) {
- /*
- * Before we error out, see if we can sensibly map the top bits
- * down to the lower bits - or lose the top bits if they are all 1's.
- * It seems that NT has this horrible bug where it will send 64 bit
- * lock requests even if told not to. JRA.
- */
-
- if(IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) == (uint32)0xFFFFFFFF)
- count = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset));
- else if (IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)) == (uint32)0xFFFFFFFF)
- count = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
- else {
-
- DEBUG(0,("get_lock_count: Error : a large file count (%x << 32 | %x) was sent and we don't \
-support large counts.\n", (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(data_offset)),
- (unsigned int)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset)) ));
-
- *err = True;
- return (SMB_OFF_T)-1;
- }
- }
- else
- count = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(data_offset));
-
-#endif /* LARGE_SMB_OFF_T */
- }
- return count;
-}
-
-/****************************************************************************
- Get a lock offset, dealing with large offset requests.
-****************************************************************************/
-
-SMB_OFF_T get_lock_offset( char *data, int data_offset, BOOL large_file_format, BOOL *err)
-{
- SMB_OFF_T offset = 0;
-
- *err = False;
-
- if(!large_file_format) {
- offset = (SMB_OFF_T)IVAL(data,SMB_LKOFF_OFFSET(data_offset));
- } else {
-
-#if defined(LARGE_SMB_OFF_T) && !defined(HAVE_BROKEN_FCNTL64_LOCKS)
-
- offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset))) << 32) |
- ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)));
-
-#else /* !LARGE_SMB_OFF_T || HAVE_BROKEN_FCNTL64_LOCKS */
-
- /*
- * NT4.x seems to be broken in that it sends large file
- * lockingX calls even if the CAP_LARGE_FILES was *not*
- * negotiated. For boxes without large file locks mangle the
- * lock offset by mapping the top 32 bits onto the lower 32.
- */
-
- if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0) {
- uint32 low = IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
- uint32 high = IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
- uint32 new_low = 0;
-
- if((new_low = map_lock_offset(high, low)) == 0) {
- *err = True;
- return (SMB_OFF_T)-1;
- }
-
- DEBUG(3,("get_lock_offset: truncating lock offset (high)0x%x (low)0x%x to offset 0x%x.\n",
- (unsigned int)high, (unsigned int)low, (unsigned int)new_low ));
- SIVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset),0);
- SIVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset),new_low);
- }
-
- if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) != 0){
- /*
- * Before we error out, see if we can sensibly map the top bits
- * down to the lower bits - or lose the top bits if they are all 1's.
- * It seems that NT has this horrible bug where it will send 64 bit
- * lock requests even if told not to. JRA.
- */
-
- if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)) == (uint32)0xFFFFFFFF)
- offset = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset));
- else if(IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)) == (uint32)0xFFFFFFFF)
- offset = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
- else {
-
- DEBUG(0,("get_lock_count: Error : a large file offset (%x << 32 | %x) was sent and we don't \
-support large offsets.\n", (unsigned int)IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(data_offset)),
- (unsigned int)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset)) ));
-
- *err = True;
- return (SMB_OFF_T)-1;
- }
- }
- else
- offset = (SMB_OFF_T)IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(data_offset));
-
-#endif /* LARGE_SMB_OFF_T */
- }
- return offset;
-}
-
-/****************************************************************************
reply to a lockingX request
****************************************************************************/
-
int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
{
files_struct *fsp = file_fsp(inbuf,smb_vwv2);
- unsigned char locktype = CVAL(inbuf,smb_vwv3);
+ uchar locktype = CVAL(inbuf,smb_vwv3);
#if 0
- unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
+ uchar oplocklevel = CVAL(inbuf,smb_vwv3+1);
#endif
uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
uint16 num_locks = SVAL(inbuf,smb_vwv7);
@@ -4191,8 +3659,6 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
uint32 ecode=0, dummy2;
int eclass=0, dummy1;
BOOL large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
- BOOL err1, err2;
-
CHECK_FSP(fsp,conn);
CHECK_ERROR(fsp);
@@ -4203,28 +3669,34 @@ int reply_lockingX(connection_struct *conn, char *inbuf,char *outbuf,int length,
*/
if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
{
+ SMB_DEV_T dev = fsp->fd_ptr->dev;
+ SMB_INO_T inode = fsp->fd_ptr->inode;
+
DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n",
fsp->fnum));
-
/*
- * Make sure we have granted an exclusive or batch oplock on this file.
+ * Make sure we have granted an oplock on this file.
*/
-
- if(!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ if(!fsp->granted_oplock)
{
DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \
-no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
-
- /* if this is a pure oplock break request then don't send a reply */
- if (num_locks == 0 && num_ulocks == 0)
- return -1;
- else
- return ERROR(ERRDOS,ERRlock);
+no oplock granted on this file.\n", fsp->fnum));
+ return ERROR(ERRDOS,ERRlock);
}
- if (remove_oplock(fsp) == False) {
- DEBUG(0,("reply_lockingX: error in removing oplock on file %s\n",
- fsp->fsp_name ));
+ /* Remove the oplock flag from the sharemode. */
+ lock_share_entry(fsp->conn, dev, inode);
+ if(remove_share_oplock(fsp)==False) {
+
+ DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
+dev = %x, inode = %.0f\n", fsp->fnum, (unsigned int)dev, (double)inode));
+
+ unlock_share_entry(fsp->conn, dev, inode);
+ } else {
+ unlock_share_entry(fsp->conn, dev, inode);
+
+ /* Clear the granted flag and return. */
+ fsp->granted_oplock = False;
}
/* if this is a pure oplock break request then don't send a reply */
@@ -4242,19 +3714,23 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
/* Data now points at the beginning of the list
of smb_unlkrng structs */
for(i = 0; i < (int)num_ulocks; i++) {
- count = get_lock_count( data, i, large_file_format, &err1);
- offset = get_lock_offset( data, i, large_file_format, &err2);
-
- /*
- * There is no error code marked "stupid client bug".... :-).
- */
- if(err1 || err2)
- return ERROR(ERRDOS,ERRnoaccess);
+ if(!large_file_format) {
+ count = IVAL(data,SMB_LKLEN_OFFSET(i));
+ offset = IVAL(data,SMB_LKOFF_OFFSET(i));
+ }
+#ifdef LARGE_SMB_OFF_T
+ else {
+ count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
+ ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
+ offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
+ ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
+ }
+#endif /* LARGE_SMB_OFF_T */
DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for file %s\n",
(double)offset, (double)count, fsp->fsp_name ));
- if(!do_unlock(fsp,conn,count,offset, &eclass, &ecode))
+ if(!do_unlock(fsp,conn,count,offset,&eclass, &ecode))
return ERROR(eclass,ecode);
}
@@ -4268,19 +3744,23 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
of smb_lkrng structs */
for(i = 0; i < (int)num_locks; i++) {
- count = get_lock_count( data, i, large_file_format, &err1);
- offset = get_lock_offset( data, i, large_file_format, &err2);
-
- /*
- * There is no error code marked "stupid client bug".... :-).
- */
- if(err1 || err2)
- return ERROR(ERRDOS,ERRnoaccess);
+ if(!large_file_format) {
+ count = IVAL(data,SMB_LKLEN_OFFSET(i));
+ offset = IVAL(data,SMB_LKOFF_OFFSET(i));
+ }
+#ifdef LARGE_SMB_OFF_T
+ else {
+ count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
+ ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
+ offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
+ ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
+ }
+#endif /* LARGE_SMB_OFF_T */
DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for file %s\n",
(double)offset, (double)count, fsp->fsp_name ));
- if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? READ_LOCK : WRITE_LOCK),
+ if(!do_lock(fsp,conn,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
&eclass, &ecode)) {
if((ecode == ERRlock) && (lock_timeout != 0) && lp_blocking_locks(SNUM(conn))) {
/*
@@ -4298,21 +3778,20 @@ no oplock granted on this file (%s).\n", fsp->fnum, fsp->fsp_name));
/* If any of the above locks failed, then we must unlock
all of the previous locks (X/Open spec). */
if(i != num_locks && num_locks != 0) {
- /*
- * Ensure we don't do a remove on the lock that just failed,
- * as under POSIX rules, if we have a lock already there, we
- * will delete it (and we shouldn't) .....
- */
- for(i--; i >= 0; i--) {
- count = get_lock_count( data, i, large_file_format, &err1);
- offset = get_lock_offset( data, i, large_file_format, &err2);
+ for(; i >= 0; i--) {
+ if(!large_file_format) {
+ count = IVAL(data,SMB_LKLEN_OFFSET(i));
+ offset = IVAL(data,SMB_LKOFF_OFFSET(i));
+ }
+#ifdef LARGE_SMB_OFF_T
+ else {
+ count = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_HIGH(i))) << 32) |
+ ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKLEN_OFFSET_LOW(i)));
+ offset = (((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_HIGH(i))) << 32) |
+ ((SMB_OFF_T) IVAL(data,SMB_LARGE_LKOFF_OFFSET_LOW(i)));
+ }
+#endif /* LARGE_SMB_OFF_T */
- /*
- * There is no error code marked "stupid client bug".... :-).
- */
- if(err1 || err2)
- return ERROR(ERRDOS,ERRnoaccess);
-
do_unlock(fsp,conn,count,offset,&dummy1,&dummy2);
}
return ERROR(eclass,ecode);
@@ -4365,7 +3844,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
tcount = maxcount;
total_read = 0;
- if (is_locked(fsp,conn,maxcount,startpos, READ_LOCK))
+ if (is_locked(fsp,conn,maxcount,startpos, F_RDLCK))
return(ERROR(ERRDOS,ERRlock));
do
@@ -4398,8 +3877,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
/****************************************************************************
reply to a SMBwritebmpx (write block multiplex primary) request
****************************************************************************/
-
-int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
size_t numtowrite;
ssize_t nwritten = -1;
@@ -4427,13 +3905,17 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
not an SMBwritebmpx - set this up now so we don't forget */
CVAL(outbuf,smb_com) = SMBwritec;
- if (is_locked(fsp,conn,tcount,startpos,WRITE_LOCK))
+ if (is_locked(fsp,conn,tcount,startpos,F_WRLCK))
return(ERROR(ERRDOS,ERRlock));
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ if(seek_file(fsp,startpos) == -1)
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
- if(lp_syncalways(SNUM(conn)) || write_through)
- conn->vfs_ops.fsync(fsp->fd_ptr->fd);
+ nwritten = write_file(fsp,data,numtowrite);
+
+ if((lp_syncalways(SNUM(conn)) || write_through) &&
+ lp_strict_sync(SNUM(conn)))
+ conn->vfs_ops.sync(fsp->fd_ptr->fd);
if(nwritten < (ssize_t)numtowrite)
return(UNIXERROR(ERRHRD,ERRdiskfull));
@@ -4471,7 +3953,7 @@ int reply_writebmpx(connection_struct *conn, char *inbuf,char *outbuf, int size,
SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
DEBUG( 3, ( "writebmpx fnum=%d num=%d wrote=%d\n",
- fsp->fnum, (int)numtowrite, (int)nwritten ) );
+ fsp->fnum, numtowrite, nwritten ) );
if (write_through && tcount==nwritten) {
/* we need to send both a primary and a secondary response */
@@ -4531,10 +4013,23 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
if(wbms->wr_discard)
return -1; /* Just discard the packet */
- nwritten = write_file(fsp,data,startpos,numtowrite);
+ if(seek_file(fsp,startpos) == -1)
+ {
+ if(write_through)
+ {
+ /* We are returning an error - we can delete the aux struct */
+ if (wbms) free((char *)wbms);
+ fsp->wbmpx_ptr = NULL;
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
+ return(CACHE_ERROR(wbms,ERRDOS,ERRnoaccess));
+ }
+
+ nwritten = write_file(fsp,data,numtowrite);
- if(lp_syncalways(SNUM(conn)) || write_through)
- conn->vfs_ops.fsync(fsp->fd_ptr->fd);
+ if((lp_syncalways(SNUM(conn)) || write_through) &&
+ lp_strict_sync(SNUM(conn)))
+ conn->vfs_ops.sync(fsp->fd_ptr->fd);
if (nwritten < (ssize_t)numtowrite)
{
@@ -4574,8 +4069,7 @@ int reply_writebs(connection_struct *conn, char *inbuf,char *outbuf, int dum_siz
/****************************************************************************
reply to a SMBsetattrE
****************************************************************************/
-
-int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
struct utimbuf unix_times;
int outsize = 0;
@@ -4627,8 +4121,7 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
/****************************************************************************
reply to a SMBgetattrE
****************************************************************************/
-
-int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+int reply_getattrE(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
{
SMB_STRUCT_STAT sbuf;
int outsize = 0;
diff --git a/source/smbd/server.c b/source/smbd/server.c
index d1788678a7c..584c10448b2 100644
--- a/source/smbd/server.c
+++ b/source/smbd/server.c
@@ -25,7 +25,9 @@
pstring servicesf = CONFIGFILE;
extern pstring debugf;
extern fstring global_myworkgroup;
+extern fstring global_sam_name;
extern pstring global_myname;
+extern dfs_internal dfs_struct;
int am_parent = 1;
@@ -35,6 +37,7 @@ int last_message = -1;
/* a useful macro to debug the last message processed */
#define LAST_MESSAGE() smb_fn_name(last_message)
+extern pstring scope;
extern int DEBUGLEVEL;
extern pstring user_socket_options;
@@ -46,6 +49,8 @@ extern int dcelogin_atmost_once;
extern fstring remote_machine;
extern pstring OriginalDir;
+extern pstring myhostname;
+
/****************************************************************************
when exiting, take the whole family
@@ -71,11 +76,13 @@ static void killkids(void)
static BOOL open_sockets_inetd(void)
{
extern int Client;
+ extern int ClientPort;
/* Started from inetd. fd 0 is the socket. */
/* We will abort gracefully when the client or remote system
goes away */
Client = dup(0);
+ ClientPort = SMB_PORT;
/* close our standard file descriptors */
close_low_fds();
@@ -86,19 +93,40 @@ static BOOL open_sockets_inetd(void)
return True;
}
+/****************************************************************************
+ open and listen to a socket
+****************************************************************************/
+static int open_server_socket(int port, uint32 ipaddr)
+{
+ int s;
+
+ s = open_socket_in(SOCK_STREAM, port, 0, ipaddr, True);
+ if(s == -1)
+ return -1;
+ /* ready to listen */
+ if (listen(s, 5) == -1) {
+ DEBUG(0,("listen: %s\n", strerror(errno)));
+ close(s);
+ return -1;
+ }
+ return s;
+}
/****************************************************************************
open the socket communication
****************************************************************************/
-static BOOL open_sockets(BOOL is_daemon,int port)
+static BOOL open_sockets(BOOL is_daemon,int port,int port445)
{
extern int Client;
+ extern int ClientPort;
int num_interfaces = iface_count();
int fd_listenset[FD_SETSIZE];
fd_set listen_set;
int s;
int i;
+ memset(&fd_listenset, 0, sizeof(fd_listenset));
+
if (!is_daemon) {
return open_sockets_inetd();
}
@@ -117,7 +145,6 @@ static BOOL open_sockets(BOOL is_daemon,int port)
/* Stop zombies */
CatchChild();
-
FD_ZERO(&listen_set);
if(lp_interfaces() && lp_bind_interfaces_only()) {
@@ -126,7 +153,7 @@ static BOOL open_sockets(BOOL is_daemon,int port)
socket per interface and bind to only these.
*/
- if(num_interfaces > FD_SETSIZE) {
+ if(num_interfaces * 2 > FD_SETSIZE) {
DEBUG(0,("open_sockets: Too many interfaces specified to bind to. Number was %d \
max can be %d\n",
num_interfaces, FD_SETSIZE));
@@ -142,16 +169,14 @@ max can be %d\n",
DEBUG(0,("open_sockets: interface %d has NULL IP address !\n", i));
continue;
}
- s = fd_listenset[i] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
- if(s == -1)
- return False;
- /* ready to listen */
- if (listen(s, 5) == -1) {
- DEBUG(0,("listen: %s\n",strerror(errno)));
- close(s);
- return False;
- }
+ s = fd_listenset[i * 2] = open_server_socket(port, ifip->s_addr);
+ if(s == -1) return False;
FD_SET(s,&listen_set);
+#if 0
+ s = fd_listenset[i * 2 + 1] = open_server_socket(port445, ifip->s_addr);
+ if(s == -1) return False;
+ FD_SET(s,&listen_set);
+#endif
}
} else {
/* Just bind to 0.0.0.0 - accept connections
@@ -159,21 +184,18 @@ max can be %d\n",
num_interfaces = 1;
/* open an incoming socket */
- s = open_socket_in(SOCK_STREAM, port, 0,
- interpret_addr(lp_socket_address()),True);
+ s = open_server_socket(port, interpret_addr(lp_socket_address()));
if (s == -1)
return(False);
-
- /* ready to listen */
- if (listen(s, 5) == -1) {
- DEBUG(0,("open_sockets: listen: %s\n",
- strerror(errno)));
- close(s);
- return False;
- }
-
fd_listenset[0] = s;
FD_SET(s,&listen_set);
+#if 0
+ s = open_server_socket(port445, interpret_addr(lp_socket_address()));
+ if (s == -1)
+ return(False);
+ fd_listenset[1] = s;
+ FD_SET(s,&listen_set);
+#endif
}
/* now accept incoming connections - forking a new process
@@ -186,14 +208,11 @@ max can be %d\n",
memcpy((char *)&lfds, (char *)&listen_set,
sizeof(listen_set));
- num = sys_select(FD_SETSIZE,&lfds,NULL);
+ num = sys_select(256,&lfds,NULL, NULL);
if (num == -1 && errno == EINTR)
continue;
- /* check if we need to reload services */
- check_reload(time(NULL));
-
/* Find the sockets that are read-ready -
accept on these. */
for( ; num > 0; num--) {
@@ -202,13 +221,26 @@ max can be %d\n",
s = -1;
for(i = 0; i < num_interfaces; i++) {
- if(FD_ISSET(fd_listenset[i],&lfds)) {
- s = fd_listenset[i];
+ if(FD_ISSET(fd_listenset[i * 2],&lfds)) {
+ s = fd_listenset[i * 2];
+ ClientPort = SMB_PORT;
+
+ /* Clear this so we don't look
+ at it again. */
+ FD_CLR(fd_listenset[i * 2], &lfds);
+ break;
+ }
+#if 0
+ if(FD_ISSET(fd_listenset[i * 2 + 1],&lfds)) {
+ s = fd_listenset[i * 2 + 1];
+ ClientPort = SMB_PORT2;
+
/* Clear this so we don't look
at it again. */
- FD_CLR(fd_listenset[i],&lfds);
+ FD_CLR(fd_listenset[i * 2 + 1], &lfds);
break;
}
+#endif
}
Client = accept(s,&addr,&in_addrlen);
@@ -320,7 +352,6 @@ BOOL reload_services(BOOL test)
}
reset_mangled_cache();
- reset_stat_cache();
/* this forces service parameters to be flushed */
become_service(NULL,True);
@@ -331,10 +362,9 @@ BOOL reload_services(BOOL test)
/****************************************************************************
- Catch a sighup.
+this prevents zombie child processes
****************************************************************************/
-
-VOLATILE SIG_ATOMIC_T reload_after_sighup = False;
+BOOL reload_after_sighup = False;
static void sig_hup(int sig)
{
@@ -409,8 +439,6 @@ void exit_server(char *reason)
conn_close_all();
- respond_to_all_remaining_local_messages();
-
#ifdef WITH_DFS
if (dcelogin_atmost_once) {
dfs_unlogin();
@@ -433,6 +461,13 @@ void exit_server(char *reason)
locking_end();
DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
+#ifdef MEM_MAN
+ {
+ extern FILE *dbf;
+ smb_mem_write_verbose(dbf);
+ dbgflush();
+ }
+#endif
exit(0);
}
@@ -441,37 +476,13 @@ void exit_server(char *reason)
/****************************************************************************
initialise connect, service and file structs
****************************************************************************/
-static void init_structs(void )
+static void init_structs(void)
{
- /*
- * Set the machine NETBIOS name if not already
- * set from the config file.
- */
-
- if (!*global_myname) {
- char *p;
- fstrcpy( global_myname, myhostname() );
- p = strchr( global_myname, '.' );
- if (p)
- *p = 0;
- }
-
- strupper( global_myname );
-
conn_init();
-
file_init();
-
- /* for RPC pipes */
- init_rpc_pipe_hnd();
-
- /* for LSA handles */
- init_lsa_policy_hnd();
-
- /* for SPOOLSS handles */
- init_printer_hnd();
-
+ init_rpc_pipe_hnd(); /* for RPC pipes */
init_dptrs();
+ init_dfs_table();
}
/****************************************************************************
@@ -479,21 +490,20 @@ usage on the program
****************************************************************************/
static void usage(char *pname)
{
-
- printf("Usage: %s [-DaoPh?V] [-d debuglevel] [-l log basename] [-p port]\n", pname);
- printf(" [-O socket options] [-s services file]\n");
- printf("\t-D Become a daemon\n");
- printf("\t-a Append to log file (default)\n");
- printf("\t-o Overwrite log file, don't append\n");
- printf("\t-P Passive only\n");
- printf("\t-h Print usage\n");
- printf("\t-? Print usage\n");
- printf("\t-V Print version\n");
- printf("\t-d debuglevel Set the debuglevel\n");
+ DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
+
+ printf("Usage: %s [-D] [-p port] [-d debuglevel] ", pname);
+ printf("[-l log basename] [-s services file]\n" );
+ printf("Version %s\n",VERSION);
+ printf("\t-D become a daemon\n");
+ printf("\t-p port listen on the specified port\n");
+ printf("\t-d debuglevel set the debuglevel\n");
printf("\t-l log basename. Basename for log/debug files\n");
- printf("\t-p port Listen on the specified port\n");
- printf("\t-O socket options Socket options\n");
printf("\t-s services file. Filename of services file\n");
+ printf("\t-P passive only\n");
+ printf("\t-a append to log file (default)\n");
+ printf("\t-o overwrite log file, don't append\n");
+ printf("\t-i scope NetBIOS scope to use (default none)\n");
printf("\n");
}
@@ -503,13 +513,11 @@ static void usage(char *pname)
****************************************************************************/
int main(int argc,char *argv[])
{
- fstring sam_name;
-
extern BOOL append_log;
/* shall I run as a daemon */
BOOL is_daemon = False;
- BOOL specified_logfile = False;
int port = SMB_PORT;
+ int port445 = SMB_PORT2;
int opt;
extern char *optarg;
@@ -517,18 +525,64 @@ static void usage(char *pname)
set_auth_parameters(argc,argv);
#endif
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ append_log = True;
+
+ TimeInit();
+
+ pstrcpy(debugf,SMBLOGFILE);
+
+ pstrcpy(remote_machine, "smb");
+
+ setup_logging(argv[0],False);
+
+ charset_initialise();
+
+ /* make absolutely sure we run as root - to handle cases where people
+ are crazy enough to have it setuid */
+#ifdef HAVE_SETRESUID
+ setresuid(0,0,0);
+#else
+ setuid(0);
+ seteuid(0);
+ setuid(0);
+ seteuid(0);
+#endif
+
+ fault_setup((void (*)(void *))exit_server);
+ CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
+
+ /* we are never interested in SIGPIPE */
+ BlockSignals(True,SIGPIPE);
+
+ /* we want total control over the permissions on created files,
+ so set our umask to 0 */
+ umask(0);
+
+ dos_GetWd(OriginalDir);
+
+ init_uid();
+
/* this is for people who can't start the program correctly */
while (argc > 1 && (*argv[1] != '-')) {
argv++;
argc--;
}
- while ( EOF != (opt = getopt(argc, argv, "O:l:s:d:Dp:h?VPaof:")) )
+ while ( EOF != (opt = getopt(argc, argv, "O:i:l:s:d:Dp:h?Paof:")) )
switch (opt) {
case 'O':
pstrcpy(user_socket_options,optarg);
break;
+ case 'i':
+ pstrcpy(scope,optarg);
+ break;
+
case 'P':
{
extern BOOL passive;
@@ -541,7 +595,6 @@ static void usage(char *pname)
break;
case 'l':
- specified_logfile = True;
pstrcpy(debugf,optarg);
break;
@@ -574,73 +627,11 @@ static void usage(char *pname)
exit(0);
break;
- case 'V':
- printf("Version %s\n",VERSION);
- exit(0);
- break;
default:
- DEBUG(0,("Incorrect program usage - are you sure the command line is correct?\n"));
usage(argv[0]);
exit(1);
}
-#ifdef HAVE_SETLUID
- /* needed for SecureWare on SCO */
- setluid(0);
-#endif
-
- /*
- * gain_root_privilege uses an assert than will cause a core
- * dump if euid != 0. Ensure this is the case.
- */
-
- if(geteuid() != (uid_t)0) {
- fprintf(stderr, "%s: Version %s : Must have effective user id of zero to run.\n", argv[0], VERSION);
- exit(1);
- }
-
- append_log = True;
-
- TimeInit();
-
- if(!specified_logfile)
- pstrcpy(debugf,SMBLOGFILE);
-
- pstrcpy(remote_machine, "smb");
-
- setup_logging(argv[0],False);
-
- charset_initialise();
-
- /* we want to re-seed early to prevent time delays causing
- client problems at a later date. (tridge) */
- generate_random_buffer(NULL, 0, False);
-
- /* make absolutely sure we run as root - to handle cases where people
- are crazy enough to have it setuid */
-
- gain_root_privilege();
- gain_root_group_privilege();
-
- fault_setup((void (*)(void *))exit_server);
- CatchSignal(SIGTERM , SIGNAL_CAST dflt_sig);
-
- /* we are never interested in SIGPIPE */
- BlockSignals(True,SIGPIPE);
-
-#if defined(SIGFPE)
- /* we are never interested in SIGFPE */
- BlockSignals(True,SIGFPE);
-#endif
-
- /* we want total control over the permissions on created files,
- so set our umask to 0 */
- umask(0);
-
- dos_GetWd(OriginalDir);
-
- init_uid();
-
reopen_logs();
DEBUG(1,( "smbd version %s started.\n", VERSION));
@@ -654,15 +645,13 @@ static void usage(char *pname)
exit(1);
}
- /*
- * Do this before reload_services.
- */
+ get_myname(myhostname,NULL);
if (!reload_services(False))
return(-1);
init_structs();
-
+
#ifdef WITH_PROFILE
if (!profile_setup(False)) {
DEBUG(0,("ERROR: failed to setup profiling\n"));
@@ -670,6 +659,16 @@ static void usage(char *pname)
}
#endif
+ /*
+ * Set the machine NETBIOS name if not already
+ * set from the config file.
+ */
+ if (!*global_myname)
+ {
+ fstrcpy(global_myname, dns_to_netbios_name(myhostname));
+ }
+ strupper(global_myname);
+
#ifdef WITH_SSL
{
extern BOOL sslEnabled;
@@ -681,7 +680,10 @@ static void usage(char *pname)
codepage_initialise(lp_client_code_page());
- fstrcpy(global_myworkgroup, lp_workgroup());
+ if (!pwdb_initialise(True))
+ {
+ exit(1);
+ }
CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
@@ -691,6 +693,7 @@ static void usage(char *pname)
/* If we are using the malloc debug code we can't use
SIGUSR1 and SIGUSR2 to do debug level changes. */
+#ifndef MEM_MAN
#if defined(SIGUSR1)
CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
#endif /* SIGUSR1 */
@@ -698,6 +701,7 @@ static void usage(char *pname)
#if defined(SIGUSR2)
CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
#endif /* SIGUSR2 */
+#endif /* MEM_MAN */
DEBUG(3,( "loaded services\n"));
@@ -721,40 +725,15 @@ static void usage(char *pname)
pidfile_create("smbd");
}
- if (!open_sockets(is_daemon,port))
+ if (!open_sockets(is_daemon,port,port445))
exit(1);
- /*
- * Note that this call should be done after the fork() call
- * in open_sockets(), as some versions of the locking shared
- * memory code register openers in a flat file.
- */
-
if (!locking_init(0))
exit(1);
- if(!initialize_password_db())
- exit(1);
-
/* possibly reload the services file. */
reload_services(True);
-
- /* obtain or create a SAM SID */
- if (lp_domain_logons())
- {
- fstrcpy(sam_name, global_myworkgroup);
- }
- else
- {
- fstrcpy(sam_name, global_myname);
- }
-
- if(!pdb_generate_sam_sid(sam_name, NULL))
- {
- DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
- exit(1);
- }
-
+
if (*lp_rootdir()) {
if (sys_chroot(lp_rootdir()) == 0)
DEBUG(2,("Changed root to %s\n", lp_rootdir()));
diff --git a/source/smbd/service.c b/source/smbd/service.c
index 3abd55de0c7..cae9672e507 100644
--- a/source/smbd/service.c
+++ b/source/smbd/service.c
@@ -23,7 +23,7 @@
extern int DEBUGLEVEL;
-extern struct timeval smb_last_time;
+extern time_t smb_last_time;
extern int case_default;
extern BOOL case_preserve;
extern BOOL short_case_preserve;
@@ -49,7 +49,7 @@ BOOL become_service(connection_struct *conn,BOOL do_chdir)
return(False);
}
- conn->lastused = smb_last_time.tv_sec;
+ conn->lastused = smb_last_time;
snum = SNUM(conn);
@@ -84,23 +84,24 @@ int find_service(char *service)
{
int iService;
- all_string_sub(service,"\\","/",0);
+ string_sub(service,"\\","/");
iService = lp_servicenumber(service);
/* now handle the special case of a home directory */
if (iService < 0)
{
- char *phome_dir = get_user_home_dir(service);
+ char *phome_dir = get_unixhome_dir(service);
+ pstring home_dir;
- if(!phome_dir)
+ if(phome_dir == NULL)
{
/*
* Try mapping the servicename, it may
* be a Windows to unix mapped user name.
*/
if(map_username(service))
- phome_dir = get_user_home_dir(service);
+ phome_dir = get_unixhome_dir(service);
}
DEBUG(3,("checking for home directory %s gave %s\n",service,
@@ -109,9 +110,10 @@ int find_service(char *service)
if (phome_dir)
{
int iHomeService;
+ pstrcpy(home_dir, phome_dir);
if ((iHomeService = lp_servicenumber(HOMES_NAME)) >= 0)
{
- lp_add_home(service,iHomeService,phome_dir);
+ lp_add_home(service,iHomeService,home_dir);
iService = lp_servicenumber(service);
}
}
@@ -166,7 +168,7 @@ int find_service(char *service)
iService = find_service(defservice);
if (iService >= 0)
{
- all_string_sub(service,"_","/",0);
+ string_sub(service,"_","/");
iService = lp_add_service(service,iService);
}
}
@@ -189,21 +191,26 @@ int find_service(char *service)
/****************************************************************************
make a connection to a service
****************************************************************************/
-connection_struct *make_connection(char *service,char *user,char *password, int pwlen, char *dev,uint16 vuid, int *ecode)
+connection_struct *make_connection(char *service,char *user,
+ char *domain,
+ char *password, int pwlen,
+ char *dev,uint16 vuid, int *ecode)
{
int snum;
- struct passwd *pass = NULL;
+ const struct passwd *pass = NULL;
BOOL guest = False;
BOOL force = False;
extern int Client;
connection_struct *conn;
- int ret;
+ vuser_key key;
+
+ key.pid = getpid();
+ key.vuid = vuid;
strlower(service);
snum = find_service(service);
if (snum < 0) {
- extern int Client;
if (strequal(service,"IPC$")) {
DEBUG(3,("refusing IPC connection\n"));
*ecode = ERRnoipc;
@@ -211,37 +218,30 @@ connection_struct *make_connection(char *service,char *user,char *password, int
}
DEBUG(0,("%s (%s) couldn't find service %s\n",
- remote_machine, client_addr(Client), service));
+ remote_machine, client_connection_addr(), service));
*ecode = ERRinvnetname;
return NULL;
}
if (strequal(service,HOMES_NAME)) {
- if (*user && Get_Pwnam(user,True)) {
- fstring dos_username;
- fstrcpy(dos_username, user);
- unix_to_dos(dos_username, True);
- return(make_connection(dos_username,user,password,
+ if (*user && Get_Pwnam(user,True))
+ return(make_connection(user,user,domain,password,
pwlen,dev,vuid,ecode));
- }
- if(lp_security() != SEC_SHARE) {
- if (validated_username(vuid)) {
- fstring dos_username;
- fstrcpy(user,validated_username(vuid));
- fstrcpy(dos_username, user);
- unix_to_dos(dos_username, True);
- return(make_connection(dos_username,user,password,pwlen,dev,vuid,ecode));
+ if(lp_security() != SEC_SHARE)
+ {
+ fstring user_name;
+ if (validated_username(&key, user_name, sizeof(user_name)))
+ {
+ pstrcpy(user, user_name);
+ return(make_connection(user,user,domain,password,pwlen,dev,vuid,ecode));
}
} else {
/* Security = share. Try with sesssetup_user
* as the username. */
if(*sesssetup_user) {
- fstring dos_username;
- fstrcpy(user,sesssetup_user);
- fstrcpy(dos_username, user);
- unix_to_dos(dos_username, True);
- return(make_connection(dos_username,user,password,pwlen,dev,vuid,ecode));
+ pstrcpy(user,sesssetup_user);
+ return(make_connection(user,user,domain,password,pwlen,dev,vuid,ecode));
}
}
}
@@ -280,7 +280,8 @@ connection_struct *make_connection(char *service,char *user,char *password, int
add_session_user(service);
/* shall we let them in? */
- if (!authorise_login(snum,user,password,pwlen,&guest,&force,vuid)) {
+ if (!authorise_login(snum,user,domain,password,pwlen,&guest,&force,&key))
+ {
DEBUG( 2, ( "Invalid username/password for %s\n", service ) );
*ecode = ERRbadpw;
return NULL;
@@ -309,13 +310,13 @@ connection_struct *make_connection(char *service,char *user,char *password, int
{
pstring list;
StrnCpy(list,lp_readlist(snum),sizeof(pstring)-1);
- pstring_sub(list,"%S",service);
+ string_sub(list,"%S",service);
if (user_in_list(user,list))
conn->read_only = True;
StrnCpy(list,lp_writelist(snum),sizeof(pstring)-1);
- pstring_sub(list,"%S",service);
+ string_sub(list,"%S",service);
if (user_in_list(user,list))
conn->read_only = False;
@@ -342,7 +343,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
conn->vuid = vuid;
conn->uid = pass->pw_uid;
conn->gid = pass->pw_gid;
- safe_strcpy(conn->client_address, client_addr(Client), sizeof(conn->client_address)-1);
+ safe_strcpy(conn->client_address, client_connection_addr(), sizeof(conn->client_address)-1);
conn->num_files_open = 0;
conn->lastused = time(NULL);
conn->service = snum;
@@ -355,36 +356,6 @@ connection_struct *make_connection(char *service,char *user,char *password, int
conn->veto_oplock_list = NULL;
string_set(&conn->dirpath,"");
string_set(&conn->user,user);
-
- conn->vfs_conn = (struct vfs_connection_struct *)
- malloc(sizeof(struct vfs_connection_struct));
-
- if (conn->vfs_conn == NULL) {
- DEBUG(0, ("No memory to create vfs_connection_struct"));
- return NULL;
- }
-
- ZERO_STRUCTP(conn->vfs_conn);
-
- /* Copy across relevant data from connection struct */
-
- conn->vfs_conn->printer = conn->printer;
- conn->vfs_conn->ipc = conn->ipc;
- conn->vfs_conn->read_only = conn->read_only;
- conn->vfs_conn->admin_user = conn->admin_user;
-
- pstrcpy(conn->vfs_conn->dirpath, conn->dirpath);
- pstrcpy(conn->vfs_conn->connectpath, conn->connectpath);
- pstrcpy(conn->vfs_conn->origpath, conn->origpath);
-
- pstrcpy(conn->vfs_conn->service, service);
- pstrcpy(conn->vfs_conn->user, conn->user);
-
- conn->vfs_conn->uid = conn->uid;
- conn->vfs_conn->gid = conn->gid;
- conn->vfs_conn->ngroups = conn->ngroups;
- conn->vfs_conn->groups = (gid_t *)memdup(conn->groups,
- conn->ngroups * sizeof(gid_t));
/* Initialise VFS function pointers */
@@ -410,87 +381,47 @@ connection_struct *make_connection(char *service,char *user,char *password, int
vfs_init_default(conn);
}
- /*
- * If force user is true, then store the
- * given userid and also the primary groupid
- * of the user we're forcing.
- */
-
- if (*lp_force_user(snum)) {
- struct passwd *pass2;
- pstring fuser;
- pstrcpy(fuser,lp_force_user(snum));
-
- /* Allow %S to be used by force user. */
- pstring_sub(fuser,"%S",service);
-
- pass2 = (struct passwd *)Get_Pwnam(fuser,True);
- if (pass2) {
- conn->uid = pass2->pw_uid;
- conn->gid = pass2->pw_gid;
- string_set(&conn->user,fuser);
- fstrcpy(user,fuser);
- conn->force_user = True;
- DEBUG(3,("Forced user %s\n",fuser));
- } else {
- DEBUG(1,("Couldn't find user %s\n",fuser));
- }
- }
-
#ifdef HAVE_GETGRNAM
- /*
- * If force group is true, then override
- * any groupid stored for the connecting user.
- */
-
if (*lp_force_group(snum)) {
struct group *gptr;
pstring gname;
- pstring tmp_gname;
- BOOL user_must_be_member = False;
- StrnCpy(tmp_gname,lp_force_group(snum),sizeof(pstring)-1);
-
- if (tmp_gname[0] == '+') {
- user_must_be_member = True;
- StrnCpy(gname,&tmp_gname[1],sizeof(pstring)-2);
- } else {
- StrnCpy(gname,tmp_gname,sizeof(pstring)-1);
- }
+ StrnCpy(gname,lp_force_group(snum),sizeof(pstring)-1);
/* default service may be a group name */
- pstring_sub(gname,"%S",service);
+ string_sub(gname,"%S",service);
gptr = (struct group *)getgrnam(gname);
if (gptr) {
- /*
- * If the user has been forced and the forced group starts
- * with a '+', then we only set the group to be the forced
- * group if the forced user is a member of that group.
- * Otherwise, the meaning of the '+' would be ignored.
- */
- if (conn->force_user && user_must_be_member) {
- int i;
- for (i = 0; gptr->gr_mem[i] != NULL; i++) {
- if (strcmp(user,gptr->gr_mem[i]) == 0) {
- conn->gid = gptr->gr_gid;
- DEBUG(3,("Forced group %s for member %s\n",gname,user));
- break;
- }
- }
- } else {
- conn->gid = gptr->gr_gid;
- DEBUG(3,("Forced group %s\n",gname));
- }
+ conn->gid = gptr->gr_gid;
+ DEBUG(3,("Forced group %s\n",gname));
} else {
DEBUG(1,("Couldn't find group %s\n",gname));
}
}
-#endif /* HAVE_GETGRNAM */
+#endif
+
+ if (*lp_force_user(snum)) {
+ const struct passwd *pass2;
+ fstring fuser;
+ fstrcpy(fuser,lp_force_user(snum));
+ pass2 = (const struct passwd *)Get_Pwnam(fuser,True);
+ if (pass2) {
+ conn->uid = pass2->pw_uid;
+ string_set(&conn->user,fuser);
+ fstrcpy(user,fuser);
+ conn->force_user = True;
+ DEBUG(3,("Forced user %s\n",fuser));
+ } else {
+ DEBUG(1,("Couldn't find user %s\n",fuser));
+ }
+ }
{
pstring s;
+ user_struct *vuser = get_valid_user_struct(&key);
pstrcpy(s,lp_pathname(snum));
- standard_sub(conn,s);
+ standard_sub(conn,vuser, s);
+ vuid_free_user_struct(vuser);
string_set(&conn->connectpath,s);
DEBUG(3,("Connect path is %s\n",s));
}
@@ -502,7 +433,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
if (!IS_IPC(conn)) {
/* Find all the groups this uid is in and
store them. Used by become_user() */
- setup_groups(conn->user,conn->uid,conn->gid,
+ get_unixgroups(conn->user,conn->uid,conn->gid,
&conn->ngroups,&conn->groups);
/* check number of connections */
@@ -517,23 +448,20 @@ connection_struct *make_connection(char *service,char *user,char *password, int
}
if (lp_status(SNUM(conn)))
- claim_connection(conn,"",
+ claim_connection(conn,"STATUS.",
MAXSTATUS,False);
} /* IS_IPC */
/* execute any "root preexec = " line */
- if (*lp_rootpreexec(SNUM(conn))) {
+ if (*lp_rootpreexec(SNUM(conn)))
+ {
pstring cmd;
+ user_struct *vuser = get_valid_user_struct(&key);
pstrcpy(cmd,lp_rootpreexec(SNUM(conn)));
- standard_sub(conn,cmd);
+ standard_sub(conn,vuser, cmd);
+ vuid_free_user_struct(vuser);
DEBUG(5,("cmd=%s\n",cmd));
- ret = smbrun(cmd,NULL,False);
- if (ret != 0 && lp_rootpreexec_close(SNUM(conn))) {
- DEBUG(1,("preexec gave %d - failing connection\n", ret));
- conn_free(conn);
- *ecode = ERRsrverror;
- return NULL;
- }
+ smbrun(cmd,NULL,False);
}
if (!become_user(conn, conn->vuid)) {
@@ -543,7 +471,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
lp_servicename(SNUM(conn)),
lp_max_connections(SNUM(conn)));
if (lp_status(SNUM(conn))) {
- yield_connection(conn,"",MAXSTATUS);
+ yield_connection(conn,"STATUS.",MAXSTATUS);
}
}
conn_free(conn);
@@ -560,7 +488,7 @@ connection_struct *make_connection(char *service,char *user,char *password, int
lp_servicename(SNUM(conn)),
lp_max_connections(SNUM(conn)));
if (lp_status(SNUM(conn)))
- yield_connection(conn,"",MAXSTATUS);
+ yield_connection(conn,"STATUS.",MAXSTATUS);
}
conn_free(conn);
*ecode = ERRinvnetname;
@@ -583,30 +511,14 @@ connection_struct *make_connection(char *service,char *user,char *password, int
add_session_user(user);
/* execute any "preexec = " line */
- if (*lp_preexec(SNUM(conn))) {
+ if (*lp_preexec(SNUM(conn)))
+ {
pstring cmd;
+ user_struct *vuser = get_valid_user_struct(&key);
pstrcpy(cmd,lp_preexec(SNUM(conn)));
- standard_sub(conn,cmd);
- ret = smbrun(cmd,NULL,False);
- if (ret != 0 && lp_preexec_close(SNUM(conn))) {
- DEBUG(1,("preexec gave %d - failing connection\n", ret));
- conn_free(conn);
- *ecode = ERRsrverror;
- return NULL;
- }
- }
-
- /*
- * Print out the 'connected as' stuff here as we need
- * to know the effective uid and gid we will be using.
- */
-
- if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
- dbgtext( "%s (%s) ", remote_machine, conn->client_address );
- dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) );
- dbgtext( "as user %s ", user );
- dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() );
- dbgtext( "(pid %d)\n", (int)getpid() );
+ standard_sub(conn,vuser, cmd);
+ vuid_free_user_struct(vuser);
+ smbrun(cmd,NULL,False);
}
/* we've finished with the sensitive stuff */
@@ -619,15 +531,58 @@ connection_struct *make_connection(char *service,char *user,char *password, int
set_namearray( &conn->veto_oplock_list, lp_veto_oplocks(SNUM(conn)));
}
- /* Invoke VFS make connection hook */
+ if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) {
+
+ dbgtext( "%s (%s) ", remote_machine, client_connection_addr() );
+ dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)));
+ dbgtext( "as user %s ", user );
+ dbgtext( "(uid=%d, gid=%d) ", (int)conn->uid, (int)conn->gid );
+ dbgtext( "(pid %d)\n", (int)key.pid );
+ }
- if (conn->vfs_ops.connect) {
- if (conn->vfs_ops.connect(conn->vfs_conn, service, user) < 0) {
- return NULL;
- }
- }
-
- return(conn);
+ /* Invoke make connection hook */
+
+ if (conn->vfs_ops.connect) {
+ struct vfs_connection_struct *vconn;
+
+ vconn = (struct vfs_connection_struct *)
+ malloc(sizeof(struct vfs_connection_struct));
+
+ if (vconn == NULL) {
+ DEBUG(0, ("No memory to create vfs_connection_struct"));
+ return NULL;
+ }
+
+ ZERO_STRUCTP(vconn);
+
+ /* Copy across relevant data from connection struct */
+
+ vconn->printer = conn->printer;
+ vconn->ipc = conn->ipc;
+ vconn->read_only = conn->read_only;
+ vconn->admin_user = conn->admin_user;
+
+ pstrcpy(vconn->dirpath, conn->dirpath);
+ pstrcpy(vconn->connectpath, conn->connectpath);
+ pstrcpy(vconn->origpath, conn->origpath);
+
+ pstrcpy(vconn->service, service);
+ pstrcpy(vconn->user, conn->user);
+
+ vconn->uid = conn->uid;
+ vconn->gid = conn->gid;
+ vconn->ngroups = conn->ngroups;
+ vconn->groups = (gid_t *)memdup(conn->groups,
+ conn->ngroups * sizeof(gid_t));
+
+ /* Call connect hook */
+
+ if (conn->vfs_ops.connect(vconn, service, user) < 0) {
+ return NULL;
+ }
+ }
+
+ return(conn);
}
@@ -636,65 +591,68 @@ close a cnum
****************************************************************************/
void close_cnum(connection_struct *conn, uint16 vuid)
{
+ VUSER_KEY;
+
DirCacheFlush(SNUM(conn));
unbecome_user();
DEBUG(IS_IPC(conn)?3:1, ("%s (%s) closed connection to service %s\n",
- remote_machine,conn->client_address,
+ remote_machine,client_connection_addr(),
lp_servicename(SNUM(conn))));
if (conn->vfs_ops.disconnect != NULL) {
- /* Call VFS disconnect hook */
+ /* Call disconnect hook */
conn->vfs_ops.disconnect();
- }
-
- /* Close dlopen() handle */
-
- if (conn->vfs_conn->dl_handle != NULL) {
- dlclose(conn->vfs_conn->dl_handle); /* should we check return val? */
- }
-
- /* Free vfs_connection_struct */
+ /* Free vfs_connection_struct */
- if (conn->vfs_conn != NULL) {
- if (conn->vfs_conn->groups != NULL) {
- free(conn->vfs_conn->groups);
- }
- free(conn->vfs_conn);
- }
+ if (conn->vfs_conn != NULL) {
+ if (conn->vfs_conn->groups != NULL) {
+ free(conn->vfs_conn->groups);
+ }
+ free(conn->vfs_conn);
+ }
+ }
yield_connection(conn,
lp_servicename(SNUM(conn)),
lp_max_connections(SNUM(conn)));
if (lp_status(SNUM(conn)))
- yield_connection(conn,"",MAXSTATUS);
+ yield_connection(conn,"STATUS.",MAXSTATUS);
file_close_conn(conn);
dptr_closecnum(conn);
/* execute any "postexec = " line */
if (*lp_postexec(SNUM(conn)) &&
- become_user(conn, vuid)) {
+ become_user(conn, vuid))
+ {
+ user_struct *vuser = get_valid_user_struct(&key);
pstring cmd;
pstrcpy(cmd,lp_postexec(SNUM(conn)));
- standard_sub(conn,cmd);
+ standard_sub(conn,vuser, cmd);
+ vuid_free_user_struct(vuser);
smbrun(cmd,NULL,False);
unbecome_user();
}
unbecome_user();
/* execute any "root postexec = " line */
- if (*lp_rootpostexec(SNUM(conn))) {
+ if (*lp_rootpostexec(SNUM(conn)))
+ {
+ user_struct *vuser = get_valid_user_struct(&key);
pstring cmd;
pstrcpy(cmd,lp_rootpostexec(SNUM(conn)));
- standard_sub(conn,cmd);
+ standard_sub(conn,vuser, cmd);
+ vuid_free_user_struct(vuser);
smbrun(cmd,NULL,False);
}
conn_free(conn);
}
+
+
diff --git a/source/smbd/ssl.c b/source/smbd/ssl.c
index be9aae7c5c3..1f098b2533d 100644
--- a/source/smbd/ssl.c
+++ b/source/smbd/ssl.c
@@ -19,14 +19,14 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/*
- * since includes.h pulls in config.h which is were WITH_SSL will be
- * defined, we want to include includes.h before testing for WITH_SSL
- * RJS 26-Jan-1999
- */
-
#include "includes.h"
+/*
+ * Hmmm, only check on WITH_SSL after we have included includes.h
+ * which pulls in config.h which is where WITH_SSL is defined, if
+ * at all :-)
+ */
+
#ifdef WITH_SSL /* should always be defined if this module is compiled */
#include <ssl.h>
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index dff57a41c2a..1a8fdd12962 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -22,6 +22,7 @@
*/
#include "includes.h"
+#include "nterr.h"
#include "trans2.h"
extern int DEBUGLEVEL;
@@ -31,7 +32,7 @@ extern int Client;
extern int smb_read_error;
extern fstring local_machine;
extern int global_oplock_break;
-extern uint32 global_client_caps;
+extern dfs_internal dfs_struct;
/****************************************************************************
Send the required number of replies back.
@@ -95,14 +96,7 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params,
total_sent_thistime = params_to_send + data_to_send +
alignment_offset + data_alignment_offset;
/* We can never send more than useable_space */
- /*
- * Note that 'useable_space' does not include the alignment offsets,
- * but we must include the alignment offsets in the calculation of
- * the length of the data we send over the wire, as the alignment offsets
- * are sent here. Fix from Marc_Jacobsen@hp.com.
- */
- total_sent_thistime = MIN(total_sent_thistime, useable_space +
- alignment_offset + data_alignment_offset);
+ total_sent_thistime = MIN(total_sent_thistime, useable_space);
set_message(outbuf, 10, total_sent_thistime, True);
@@ -120,7 +114,8 @@ static int send_trans2_replies(char *outbuf, int bufsize, char *params,
SSVAL(outbuf,smb_prcnt, params_sent_thistime);
if(params_sent_thistime == 0)
{
- SSVAL(outbuf,smb_proff,0);
+ /*SSVAL(outbuf,smb_proff,0);*/
+ SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
SSVAL(outbuf,smb_prdisp,0);
}
else
@@ -222,7 +217,11 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
/* XXXX we need to handle passed times, sattr and flags */
- unix_convert(fname,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
fsp = file_new();
if (!fsp)
@@ -239,7 +238,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
- unixmode = unix_mode(conn,open_attr | aARCH, fname);
+ unixmode = unix_mode(conn,open_attr | aARCH);
open_file_shared(fsp,conn,fname,open_mode,open_ofun,unixmode,
oplock_request, &rmode,&smb_action);
@@ -274,7 +273,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
if(params == NULL)
return(ERROR(ERRDOS,ERRnomem));
- memset((char *)params,'\0',28);
+ bzero(params,28);
SSVAL(params,0,fsp->fnum);
SSVAL(params,2,fmode);
put_dos_date2(params,4, mtime);
@@ -300,12 +299,12 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
/****************************************************************************
get a level dependent lanman2 dir entry.
****************************************************************************/
-static BOOL get_lanman2_dir_entry(connection_struct *conn,
+static int get_lanman2_dir_entry(connection_struct *conn,
char *path_mask,int dirtype,int info_level,
int requires_resume_key,
BOOL dont_descend,char **ppdata,
char *base_data, int space_remaining,
- BOOL *out_of_space, BOOL *got_exact_match,
+ BOOL *out_of_space,
int *last_name_off)
{
char *dname;
@@ -331,7 +330,6 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
*fname = 0;
*out_of_space = False;
- *got_exact_match = False;
if (!conn->dirptr)
return(False);
@@ -349,8 +347,6 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
while (!found)
{
- BOOL got_match;
-
/* Needed if we run out of space */
prev_dirpos = TellDir(conn->dirptr);
dname = ReadDirName(conn->dirptr);
@@ -372,26 +368,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstrcpy(fname,dname);
- if(!(got_match = *got_exact_match = exact_match(fname, mask, case_sensitive)))
- got_match = mask_match(fname, mask, case_sensitive, True);
-
- if(!got_match && !is_8_3(fname, False)) {
-
- /*
- * It turns out that NT matches wildcards against
- * both long *and* short names. This may explain some
- * of the wildcard wierdness from old DOS clients
- * that some people have been seeing.... JRA.
- */
-
- pstring newname;
- pstrcpy( newname, fname);
- name_map_mangle( newname, True, False, SNUM(conn));
- if(!(got_match = *got_exact_match = exact_match(newname, mask, case_sensitive)))
- got_match = mask_match(newname, mask, case_sensitive, True);
- }
-
- if(got_match)
+ if(mask_match(fname, mask, case_sensitive, True))
{
BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
if (dont_descend && !isdots)
@@ -430,7 +407,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
}
}
- name_map_mangle(fname,False,True,SNUM(conn));
+ name_map_mangle(fname,False,SNUM(conn));
p = pdata;
nameptr = p;
@@ -526,7 +503,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
SIVAL(p,0,0); p += 4;
if (!was_8_3) {
pstrcpy(p+2,fname);
- if (!name_map_mangle(p+2,True,True,SNUM(conn)))
+ if (!name_map_mangle(p+2,True,SNUM(conn)))
(p+2)[12] = 0;
} else
*(p+2) = 0;
@@ -603,7 +580,6 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
*last_name_off = PTR_DIFF(nameptr,base_data);
/* Advance the data pointer to the next slot */
*ppdata = p;
-
return(found);
}
@@ -635,9 +611,8 @@ void mask_convert( char *mask)
}
/****************************************************************************
- Reply to a TRANS2_FINDFIRST.
+ reply to a TRANS2_FINDFIRST
****************************************************************************/
-
static int call_trans2findfirst(connection_struct *conn,
char *inbuf, char *outbuf, int bufsize,
char **pparams, char **ppdata)
@@ -695,7 +670,11 @@ static int call_trans2findfirst(connection_struct *conn,
DEBUG(5,("path=%s\n",directory));
- unix_convert(directory,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(directory,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
if(!check_name(directory,conn)) {
if((errno == ENOENT) && bad_path)
{
@@ -730,25 +709,40 @@ static int call_trans2findfirst(connection_struct *conn,
pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
if(!*ppdata)
return(ERROR(ERRDOS,ERRnomem));
- memset((char *)pdata,'\0',max_data_bytes + 1024);
+ bzero(pdata,max_data_bytes);
/* Realloc the params space */
params = *pparams = Realloc(*pparams, 10);
if(params == NULL)
return(ERROR(ERRDOS,ERRnomem));
- dptr_num = dptr_create(conn,directory, False, True ,SVAL(inbuf,smb_pid));
+ dptr_num = dptr_create(conn,directory, True ,SVAL(inbuf,smb_pid));
if (dptr_num < 0)
return(UNIXERROR(ERRDOS,ERRbadfile));
/* Convert the formatted mask. */
mask_convert(mask);
+#if 0 /* JRA */
+ /*
+ * Now we have a working mask_match in util.c, I believe
+ * we no longer need these hacks (in fact they break
+ * things). JRA.
+ */
+
+ /* a special case for 16 bit apps */
+ if (strequal(mask,"????????.???")) pstrcpy(mask,"*");
+
+ /* handle broken clients that send us old 8.3 format */
+ string_sub(mask,"????????","*");
+ string_sub(mask,".???",".*");
+#endif /* JRA */
+
/* Save the wildcard match and attribs we are using on this directory -
needed as lanman2 assumes these are being saved between calls */
if(!(wcard = strdup(mask))) {
- dptr_close(&dptr_num);
+ dptr_close(dptr_num);
return(ERROR(ERRDOS,ERRnomem));
}
@@ -770,49 +764,39 @@ static int call_trans2findfirst(connection_struct *conn,
out_of_space = False;
for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
- {
- BOOL got_exact_match;
-
- /* this is a heuristic to avoid seeking the dirptr except when
- absolutely necessary. It allows for a filename of about 40 chars */
- if (space_remaining < DIRLEN_GUESS && numentries > 0)
{
- out_of_space = True;
- finished = False;
- }
- else
- {
- finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
- requires_resume_key,dont_descend,
- &p,pdata,space_remaining, &out_of_space, &got_exact_match,
- &last_name_off);
- }
- if (finished && out_of_space)
- finished = False;
-
- if (!finished && !out_of_space)
- numentries++;
-
- /*
- * As an optimisation if we know we aren't looking
- * for a wildcard name (ie. the name matches the wildcard exactly)
- * then we can finish on any (first) match.
- * This speeds up large directory searches. JRA.
- */
+ /* this is a heuristic to avoid seeking the dirptr except when
+ absolutely necessary. It allows for a filename of about 40 chars */
+ if (space_remaining < DIRLEN_GUESS && numentries > 0)
+ {
+ out_of_space = True;
+ finished = False;
+ }
+ else
+ {
+ finished =
+ !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
+ requires_resume_key,dont_descend,
+ &p,pdata,space_remaining, &out_of_space,
+ &last_name_off);
+ }
- if(got_exact_match)
- finished = True;
+ if (finished && out_of_space)
+ finished = False;
- space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
- }
+ if (!finished && !out_of_space)
+ numentries++;
+ space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
+ }
/* Check if we can close the dirptr */
if(close_after_first || (finished && close_if_end))
- {
- DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
- dptr_close(&dptr_num);
- }
+ {
+ dptr_close(dptr_num);
+ DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
+ dptr_num = -1;
+ }
/*
* If there are no matching entries we must return ERRDOS/ERRbadfile -
@@ -820,10 +804,7 @@ static int call_trans2findfirst(connection_struct *conn,
*/
if(numentries == 0)
- {
- dptr_close(&dptr_num);
return(ERROR(ERRDOS,ERRbadfile));
- }
/* At this point pdata points to numentries directory entries. */
@@ -843,17 +824,6 @@ static int call_trans2findfirst(connection_struct *conn,
smb_fn_name(CVAL(inbuf,smb_com)),
mask, directory, dirtype, numentries ) );
- /*
- * Force a name mangle here to ensure that the
- * mask as an 8.3 name is top of the mangled cache.
- * The reasons for this are subtle. Don't remove
- * this code unless you know what you are doing
- * (see PR#13758). JRA.
- */
-
- if(!is_8_3( mask, False))
- name_map_mangle(mask, True, True, SNUM(conn));
-
return(-1);
}
@@ -874,7 +844,7 @@ static int call_trans2findnext(connection_struct *conn,
int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
- int dptr_num = SVAL(params,0);
+ int16 dptr_num = SVAL(params,0);
int maxentries = SVAL(params,2);
uint16 info_level = SVAL(params,4);
uint32 resume_key = IVAL(params,6);
@@ -922,7 +892,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
if(!*ppdata)
return(ERROR(ERRDOS,ERRnomem));
- memset((char *)pdata,'\0',max_data_bytes + 1024);
+ bzero(pdata,max_data_bytes);
/* Realloc the params space */
params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
@@ -999,7 +969,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
*/
if(dname != NULL)
- name_map_mangle( dname, False, True, SNUM(conn));
+ name_map_mangle( dname, False, SNUM(conn));
if(dname && strcsequal( resume_name, dname))
{
@@ -1027,7 +997,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
*/
if(dname != NULL)
- name_map_mangle( dname, False, True, SNUM(conn));
+ name_map_mangle( dname, False, SNUM(conn));
if(dname && strcsequal( resume_name, dname))
{
@@ -1040,49 +1010,38 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
} /* end if requires_resume_key && !continue_bit */
for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
- {
- BOOL got_exact_match;
-
- /* this is a heuristic to avoid seeking the dirptr except when
- absolutely necessary. It allows for a filename of about 40 chars */
- if (space_remaining < DIRLEN_GUESS && numentries > 0)
- {
- out_of_space = True;
- finished = False;
- }
- else
{
- finished = !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
- requires_resume_key,dont_descend,
- &p,pdata,space_remaining, &out_of_space, &got_exact_match,
- &last_name_off);
- }
-
- if (finished && out_of_space)
- finished = False;
-
- if (!finished && !out_of_space)
- numentries++;
-
- /*
- * As an optimisation if we know we aren't looking
- * for a wildcard name (ie. the name matches the wildcard exactly)
- * then we can finish on any (first) match.
- * This speeds up large directory searches. JRA.
- */
+ /* this is a heuristic to avoid seeking the dirptr except when
+ absolutely necessary. It allows for a filename of about 40 chars */
+ if (space_remaining < DIRLEN_GUESS && numentries > 0)
+ {
+ out_of_space = True;
+ finished = False;
+ }
+ else
+ {
+ finished =
+ !get_lanman2_dir_entry(conn,mask,dirtype,info_level,
+ requires_resume_key,dont_descend,
+ &p,pdata,space_remaining, &out_of_space,
+ &last_name_off);
+ }
- if(got_exact_match)
- finished = True;
+ if (finished && out_of_space)
+ finished = False;
- space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
- }
+ if (!finished && !out_of_space)
+ numentries++;
+ space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
+ }
/* Check if we can close the dirptr */
if(close_after_request || (finished && close_if_end))
- {
- DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
- dptr_close(&dptr_num); /* This frees up the saved mask */
- }
+ {
+ dptr_close(dptr_num); /* This frees up the saved mask */
+ DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
+ dptr_num = -1;
+ }
/* Set up the return parameter block */
@@ -1112,7 +1071,6 @@ static int call_trans2qfsinfo(connection_struct *conn,
int length, int bufsize,
char **pparams, char **ppdata)
{
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *pdata = *ppdata;
char *params = *pparams;
uint16 info_level = SVAL(params,0);
@@ -1121,6 +1079,7 @@ static int call_trans2qfsinfo(connection_struct *conn,
char *vname = volume_label(SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
+ extern uint32 global_client_caps;
DEBUG(3,("call_trans2qfsinfo: level = %d\n", info_level));
@@ -1129,8 +1088,7 @@ static int call_trans2qfsinfo(connection_struct *conn,
return (ERROR(ERRSRV,ERRinvdevice));
}
- pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
- memset((char *)pdata,'\0',max_data_bytes + 1024);
+ pdata = *ppdata = Realloc(*ppdata, 1024); bzero(pdata,1024);
switch (info_level)
{
@@ -1138,7 +1096,7 @@ static int call_trans2qfsinfo(connection_struct *conn,
{
SMB_BIG_UINT dfree,dsize,bsize;
data_len = 18;
- conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
+ conn->vfs_ops.disk_free(".",&bsize,&dfree,&dsize);
SIVAL(pdata,l1_idFileSystem,st.st_dev);
SIVAL(pdata,l1_cSectorUnit,bsize/512);
SIVAL(pdata,l1_cUnit,dsize);
@@ -1167,22 +1125,16 @@ static int call_trans2qfsinfo(connection_struct *conn,
break;
}
case SMB_QUERY_FS_ATTRIBUTE_INFO:
- {
- int fstype_len;
- SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
- FILE_DEVICE_IS_MOUNTED|
- (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */
+ data_len = 12 + 2*strlen(fstype);
+ SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH); /* FS ATTRIBUTES */
#if 0 /* Old code. JRA. */
SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
#endif /* Old code. */
-
SIVAL(pdata,4,128); /* Max filename component length */
- fstype_len = dos_PutUniCode(pdata+12,unix_to_dos(fstype,False),sizeof(pstring)/2);
- SIVAL(pdata,8,fstype_len);
- data_len = 12 + fstype_len;
+ SIVAL(pdata,8,2*strlen(fstype));
+ ascii_to_unibuf(pdata+12, fstype, 1024-2-12);
SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
break;
- }
case SMB_QUERY_FS_LABEL_INFO:
data_len = 4 + strlen(vname);
SIVAL(pdata,0,strlen(vname));
@@ -1207,19 +1159,19 @@ static int call_trans2qfsinfo(connection_struct *conn,
} else {
data_len = 18 + 2*strlen(vname);
SIVAL(pdata,12,strlen(vname)*2);
- dos_PutUniCode(pdata+18,unix_to_dos(vname,False),sizeof(pstring)/2);
+ ascii_to_unibuf(pdata+18, vname, 1024-2-18);
}
DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n",
- (int)strlen(vname),vname));
+ strlen(vname),vname));
break;
case SMB_QUERY_FS_SIZE_INFO:
{
SMB_BIG_UINT dfree,dsize,bsize;
data_len = 24;
- conn->vfs_ops.disk_free(".",False,&bsize,&dfree,&dsize);
- SBIG_UINT(pdata,0,dsize);
- SBIG_UINT(pdata,8,dfree);
+ conn->vfs_ops.disk_free(".",&bsize,&dfree,&dsize);
+ SIVAL(pdata,0,dsize);
+ SIVAL(pdata,8,dfree);
SIVAL(pdata,16,bsize/512);
SIVAL(pdata,20,512);
break;
@@ -1285,7 +1237,6 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
char **pparams,char **ppdata,
int total_data)
{
- int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
char *params = *pparams;
char *pdata = *ppdata;
uint16 tran_call = SVAL(inbuf, smb_setup0);
@@ -1306,18 +1257,20 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
files_struct *fsp = file_fsp(params,0);
info_level = SVAL(params,2);
- DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QFILEINFO: level = %d\n", info_level));
-
- if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
+ if(fsp && fsp->open && fsp->is_directory) {
/*
* This is actually a QFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
* to do this call. JRA.
*/
fname = fsp->fsp_name;
- unix_convert(fname,conn,0,&bad_path,&sbuf);
- if (!check_name(fname,conn) ||
- (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,&sbuf))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
+ if (!check_name(fname,conn) || (!VALID_STAT(sbuf) &&
+ conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
if((errno == ENOENT) && bad_path)
{
@@ -1326,9 +1279,6 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
}
return(UNIXERROR(ERRDOS,ERRbadpath));
}
-
- delete_pending = fsp->directory_delete_on_close;
-
} else {
/*
* Original code - this is an open file.
@@ -1349,14 +1299,16 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
} else {
/* qpathinfo */
info_level = SVAL(params,0);
-
- DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level));
-
fname = &fname1[0];
pstrcpy(fname,&params[6]);
- unix_convert(fname,conn,0,&bad_path,&sbuf);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,&sbuf))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
if (!check_name(fname,conn) ||
- (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),&sbuf))) {
+ (!VALID_STAT(sbuf) && conn->vfs_ops.stat(dos_to_unix(fname,False),
+ &sbuf))) {
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
if((errno == ENOENT) && bad_path)
{
@@ -1384,9 +1336,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
/* from now on we only want the part after the / */
fname = p;
- params = *pparams = Realloc(*pparams,2);
- memset((char *)params,'\0',2);
- data_size = max_data_bytes + 1024;
+ params = *pparams = Realloc(*pparams,2); bzero(params,2);
+ data_size = 1024;
pdata = *ppdata = Realloc(*ppdata, data_size);
if (total_data > 0 && IVAL(pdata,0) == total_data) {
@@ -1395,7 +1346,7 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
}
- memset((char *)pdata,'\0',data_size);
+ bzero(pdata,data_size);
switch (info_level)
{
@@ -1466,37 +1417,26 @@ static int call_trans2qfilepathinfo(connection_struct *conn,
case SMB_QUERY_FILE_ALT_NAME_INFO:
{
pstring short_name;
+ char *data_end;
+
pstrcpy(short_name,p);
/* Mangle if not already 8.3 */
if(!is_8_3(short_name, True))
{
- if(!name_map_mangle(short_name,True,True,SNUM(conn)))
+ if(!name_map_mangle(short_name,True,SNUM(conn)))
*short_name = '\0';
}
strupper(short_name);
- l = strlen(short_name);
- dos_PutUniCode(pdata + 4, unix_to_dos(short_name,False),sizeof(pstring)*2);
- data_size = 4 + (2*l);
- SIVAL(pdata,0,2*l);
+ data_end = ascii_to_unibuf(pdata + 4, short_name, 1024-2-4);
+ data_size = data_end - pdata;
+ SIVAL(pdata,0,2*(data_size-4));
}
break;
case SMB_QUERY_FILE_NAME_INFO:
- /*
- * The first part of this code is essential
- * to get security descriptors to work on mapped
- * drives. Don't ask how I discovered this unless
- * you like hearing about me suffering.... :-). JRA.
- */
- if(strequal(".", fname) && (global_client_caps & CAP_UNICODE)) {
- l = l*2;
- SSVAL(outbuf,smb_flg2,SVAL(outbuf,smb_flg2)|FLAGS2_UNICODE_STRINGS);
- dos_PutUniCode(pdata + 4, unix_to_dos("\\",False),sizeof(pstring)*2);
- } else {
- pstrcpy(pdata+4,fname);
- }
data_size = 4 + l;
SIVAL(pdata,0,l);
+ pstrcpy(pdata+4,fname);
break;
case SMB_QUERY_FILE_ALLOCATION_INFO:
@@ -1588,16 +1528,20 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
fsp = file_fsp(params,0);
info_level = SVAL(params,2);
- if(fsp && fsp->open && (fsp->is_directory || fsp->stat_open)) {
+ if(fsp && fsp->open && fsp->is_directory) {
/*
* This is actually a SETFILEINFO on a directory
* handle (returned from an NT SMB). NT5.0 seems
* to do this call. JRA.
*/
fname = fsp->fsp_name;
- unix_convert(fname,conn,0,&bad_path,&st);
- if (!check_name(fname,conn) ||
- (!VALID_STAT(st) && conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,&st))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
+ if (!check_name(fname,conn) || (!VALID_STAT(st) &&
+ conn->vfs_ops.stat(dos_to_unix(fname,False),&st))) {
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
if((errno == ENOENT) && bad_path)
{
@@ -1626,7 +1570,11 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
info_level = SVAL(params,0);
fname = fname1;
pstrcpy(fname,&params[6]);
- unix_convert(fname,conn,0,&bad_path,&st);
+ if (!unix_dfs_convert(fname,conn,0,&bad_path,&st))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
if(!check_name(fname, conn))
{
if((errno == ENOENT) && bad_path)
@@ -1652,12 +1600,10 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
tran_call,fname,info_level,total_data));
/* Realloc the parameter and data sizes */
- params = *pparams = Realloc(*pparams,2);
+ params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
if(params == NULL)
return(ERROR(ERRDOS,ERRnomem));
- SSVAL(params,0,0);
-
size = st.st_size;
tvs.modtime = st.st_mtime;
tvs.actime = st.st_atime;
@@ -1705,25 +1651,14 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
case SMB_SET_FILE_BASIC_INFO:
{
- /* Patch to do this correctly from Paul Eggert <eggert@twinsun.com>. */
- time_t write_time;
- time_t changed_time;
-
/* Ignore create time at offset pdata. */
/* access time */
tvs.actime = interpret_long_date(pdata+8);
- write_time = interpret_long_date(pdata+16);
- changed_time = interpret_long_date(pdata+24);
-
- tvs.modtime = MIN(write_time, changed_time);
-
- /* Prefer a defined time to an undefined one. */
- if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
- tvs.modtime = (write_time == (time_t)0 || write_time == (time_t)-1
- ? changed_time
- : write_time);
+ /* write time + changed time, combined. */
+ tvs.modtime=MAX(interpret_long_date(pdata+16),
+ interpret_long_date(pdata+24));
#if 0 /* Needs more testing... */
/* Test from Luke to prevent Win95 from
@@ -1738,26 +1673,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
break;
}
- /*
- * NT seems to use this call with a size of zero
- * to mean truncate the file. JRA.
- */
-
- case SMB_SET_FILE_ALLOCATION_INFO:
- {
- SMB_OFF_T newsize = IVAL(pdata,0);
-#ifdef LARGE_SMB_OFF_T
- newsize |= (((SMB_OFF_T)IVAL(pdata,4)) << 32);
-#else /* LARGE_SMB_OFF_T */
- if (IVAL(pdata,4) != 0) /* more than 32 bits? */
- return(ERROR(ERRDOS,ERRunknownlevel));
-#endif /* LARGE_SMB_OFF_T */
- DEBUG(10,("call_trans2setfilepathinfo: Set file allocation info for file %s to %.0f\n", fname, (double)newsize ));
- if(newsize == 0)
- size = 0;
- break;
- }
-
case SMB_SET_FILE_END_OF_FILE_INFO:
{
size = IVAL(pdata,0);
@@ -1767,10 +1682,12 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
if (IVAL(pdata,4) != 0) /* more than 32 bits? */
return(ERROR(ERRDOS,ERRunknownlevel));
#endif /* LARGE_SMB_OFF_T */
- DEBUG(10,("call_trans2setfilepathinfo: Set end of file info for file %s to %.0f\n", fname, (double)size ));
break;
}
+ case SMB_SET_FILE_ALLOCATION_INFO:
+ break; /* We don't need to do anything for this call. */
+
case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
{
if ((tran_call == TRANSACT2_SETFILEINFO) && (fsp != NULL))
@@ -1778,133 +1695,121 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
BOOL delete_on_close = (CVAL(pdata,0) ? True : False);
if(fsp->is_directory)
- {
- fsp->directory_delete_on_close = delete_on_close;
- DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, directory %s\n",
- delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ return(ERROR(ERRDOS,ERRnoaccess));
- }
- else if(fsp->stat_open)
- {
- DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, stat open %s\n",
- delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
- }
- else
+ /*
+ * We can only set the delete on close flag if
+ * the share mode contained ALLOW_SHARE_DELETE
+ */
+
+ if(lp_share_modes(SNUM(conn)))
{
+ if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
+ return(ERROR(ERRDOS,ERRnoaccess));
/*
- * We can only set the delete on close flag if
- * the share mode contained ALLOW_SHARE_DELETE
+ * If the flag has been set then
+ * modify the share mode entry for all files we have open
+ * on this device and inode to tell other smbds we have
+ * changed the delete on close flag.
*/
- if(lp_share_modes(SNUM(conn)))
+ if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
{
- if(!GET_ALLOW_SHARE_DELETE(fsp->share_mode))
+ int i;
+ files_struct *iterate_fsp;
+ SMB_DEV_T dev = fsp->fd_ptr->dev;
+ SMB_INO_T inode = fsp->fd_ptr->inode;
+ int num_share_modes;
+ share_mode_entry *current_shares = NULL;
+
+ if(lock_share_entry(fsp->conn, dev, inode) == False)
return(ERROR(ERRDOS,ERRnoaccess));
/*
- * If the flag has been set then
- * modify the share mode entry for all files we have open
- * on this device and inode to tell other smbds we have
- * changed the delete on close flag.
+ * Before we allow this we need to ensure that all current opens
+ * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
+ * do not then we deny this (as we are essentially deleting the
+ * file at this point.
*/
- if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode))
+ num_share_modes = get_share_modes(conn, dev, inode, &current_shares);
+ for(i = 0; i < num_share_modes; i++)
{
- int i;
- files_struct *iterate_fsp;
- SMB_DEV_T dev = fsp->fd_ptr->dev;
- SMB_INO_T inode = fsp->fd_ptr->inode;
- int num_share_modes;
- share_mode_entry *current_shares = NULL;
-
- if(lock_share_entry(fsp->conn, dev, inode) == False)
- return(ERROR(ERRDOS,ERRnoaccess));
-
- /*
- * Before we allow this we need to ensure that all current opens
- * on the file have the GET_ALLOW_SHARE_DELETE flag set. If they
- * do not then we deny this (as we are essentially deleting the
- * file at this point.
- */
-
- num_share_modes = get_share_modes(conn, dev, inode, &current_shares);
- for(i = 0; i < num_share_modes; i++)
+ if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
{
- if(!GET_ALLOW_SHARE_DELETE(current_shares[i].share_mode))
- {
- DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
+ DEBUG(5,("call_trans2setfilepathinfo: refusing to set delete on close flag for fnum = %d, \
file %s as a share exists that was not opened with FILE_DELETE access.\n",
- fsp->fnum, fsp->fsp_name ));
- /*
- * Release the lock.
- */
+ fsp->fnum, fsp->fsp_name ));
+ /*
+ * Release the lock.
+ */
- unlock_share_entry(fsp->conn, dev, inode);
+ unlock_share_entry(fsp->conn, dev, inode);
- /*
- * current_shares was malloced by get_share_modes - free it here.
- */
+ /*
+ * current_shares was malloced by get_share_modes - free it here.
+ */
- free((char *)current_shares);
+ free((char *)current_shares);
- /*
- * Even though share violation would be more appropriate here,
- * return ERRnoaccess as that's what NT does.
- */
+ /*
+ * Even though share violation would be more appropriate here,
+ * return ERRnoaccess as that's what NT does.
+ */
- return(ERROR(ERRDOS,ERRnoaccess));
- }
+ return(ERROR(ERRDOS,ERRnoaccess));
}
+ }
- /*
- * current_shares was malloced by get_share_modes - free it here.
- */
+ /*
+ * current_shares was malloced by get_share_modes - free it here.
+ */
- free((char *)current_shares);
+ free((char *)current_shares);
- DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
- delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
+ DEBUG(10,("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Adding" : "Removing", fsp->fnum, fsp->fsp_name ));
- /*
- * Go through all files we have open on the same device and
- * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
- * Other smbd's that have this file open will have to fend for themselves. We
- * take care of this (rare) case in close_file(). See the comment there.
- */
+ /*
+ * Go through all files we have open on the same device and
+ * inode (hanging off the same hash bucket) and set the DELETE_ON_CLOSE_FLAG.
+ * Other smbd's that have this file open will have to fend for themselves. We
+ * take care of this (rare) case in close_file(). See the comment there.
+ */
- for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
- iterate_fsp = file_find_di_next(iterate_fsp))
- {
- int new_share_mode = (delete_on_close ?
- (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
- (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
+ for(iterate_fsp = file_find_di_first(dev, inode); iterate_fsp;
+ iterate_fsp = file_find_di_next(iterate_fsp))
+ {
+ int new_share_mode = (delete_on_close ?
+ (iterate_fsp->share_mode | DELETE_ON_CLOSE_FLAG) :
+ (iterate_fsp->share_mode & ~DELETE_ON_CLOSE_FLAG) );
- DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
+ DEBUG(10,("call_trans2setfilepathinfo: Changing share mode for fnum %d, file %s \
dev = %x, inode = %.0f from %x to %x\n",
- iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
- (double)inode, iterate_fsp->share_mode, new_share_mode ));
+ iterate_fsp->fnum, iterate_fsp->fsp_name, (unsigned int)dev,
+ (double)inode, iterate_fsp->share_mode, new_share_mode ));
- if(modify_share_mode(iterate_fsp, new_share_mode, iterate_fsp->oplock_type)==False)
- DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
+ if(modify_share_mode(iterate_fsp, new_share_mode,
+ iterate_fsp->granted_oplock ? LEVEL_II_OPLOCK : NO_OPLOCK)==False)
+ DEBUG(0,("call_trans2setfilepathinfo: failed to change delete on close for fnum %d, \
dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode));
- }
+ }
- /*
- * Set the delete on close flag in the reference
- * counted struct. Delete when the last reference
- * goes away.
- */
- fsp->fd_ptr->delete_on_close = delete_on_close;
+ /*
+ * Set the delete on close flag in the reference
+ * counted struct. Delete when the last reference
+ * goes away.
+ */
+ fsp->fd_ptr->delete_on_close = delete_on_close;
+ unlock_share_entry(fsp->conn, dev, inode);
- unlock_share_entry(fsp->conn, dev, inode);
+ DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
+ delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
- DEBUG(10, ("call_trans2setfilepathinfo: %s delete on close flag for fnum = %d, file %s\n",
- delete_on_close ? "Added" : "Removed", fsp->fnum, fsp->fsp_name ));
+ } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
+ } /* end if lp_share_modes() */
- } /* end if(delete_on_close && !GET_DELETE_ON_CLOSE_FLAG(fsp->share_mode)) */
- } /* end if lp_share_modes() */
- } /* end if is_directory. */
} else
return(ERROR(ERRDOS,ERRunknownlevel));
break;
@@ -1916,33 +1821,23 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
}
}
- /* get some defaults (no modifications) if any info is zero or -1. */
- if (tvs.actime == (time_t)0 || tvs.actime == (time_t)-1)
- tvs.actime = st.st_atime;
-
- if (tvs.modtime == (time_t)0 || tvs.modtime == (time_t)-1)
- tvs.modtime = st.st_mtime;
-
DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
DEBUG(6,("size: %.0f ", (double)size));
DEBUG(6,("mode: %x\n" , mode));
- if(!((info_level == SMB_SET_FILE_END_OF_FILE_INFO) ||
- (info_level == SMB_SET_FILE_ALLOCATION_INFO))) {
- /*
- * Only do this test if we are not explicitly
- * changing the size of a file.
- */
- if (!size)
- size = st.st_size;
- }
+ /* get some defaults (no modifications) if any info is zero. */
+ if (!tvs.actime) tvs.actime = st.st_atime;
+ if (!tvs.modtime) tvs.modtime = st.st_mtime;
+ if (!size) size = st.st_size;
/* Try and set the times, size and mode of this file -
if they are different from the current values
*/
- if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
- if(fsp != NULL) {
+ if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
+ {
+ if(fsp != NULL)
+ {
/*
* This was a setfileinfo on an open file.
* NT does this a lot. It's actually pointless
@@ -1950,51 +1845,38 @@ dev = %x, inode = %.0f\n", iterate_fsp->fnum, (unsigned int)dev, (double)inode))
* on the next write, so we save the request
* away and will set it on file code. JRA.
*/
-
- if (tvs.modtime != (time_t)0 && tvs.modtime != (time_t)-1) {
- DEBUG(10,("call_trans2setfilepathinfo: setting pending modtime to %s\n",
- ctime(&tvs.modtime) ));
- fsp->pending_modtime = tvs.modtime;
- }
-
- } else {
-
- DEBUG(10,("call_trans2setfilepathinfo: setting utimes to modified values.\n"));
-
- if(file_utime(conn, fname, &tvs)!=0)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ fsp->pending_modtime = tvs.modtime;
}
- }
-
- /* check the mode isn't different, before changing it */
- if ((mode != 0) && (mode != dos_mode(conn, fname, &st))) {
-
- DEBUG(10,("call_trans2setfilepathinfo: file %s : setting dos mode %x\n",
- fname, mode ));
-
- if(file_chmod(conn, fname, mode, NULL)) {
- DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
+ else if(file_utime(conn, fname, &tvs)!=0)
+ {
return(UNIXERROR(ERRDOS,ERRnoaccess));
}
}
- if(size != st.st_size) {
-
- DEBUG(10,("call_trans2setfilepathinfo: file %s : setting new size to %.0f\n",
- fname, (double)size ));
+ /* check the mode isn't different, before changing it */
+ if (mode != dos_mode(conn, fname, &st) && file_chmod(conn, fname, mode, NULL))
+ {
+ DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
+ return(UNIXERROR(ERRDOS,ERRnoaccess));
+ }
- if (fd == -1) {
- fd = conn->vfs_ops.open(dos_to_unix(fname,False),O_RDWR,0);
+ if(size != st.st_size)
+ {
+ if (fd == -1)
+ {
+DEBUG(0, ("@@@ 23 @@@\n"));
+ fd = dos_open(fname,O_RDWR,0);
if (fd == -1)
+ {
return(UNIXERROR(ERRDOS,ERRbadpath));
- set_filelen(fd, size); /* tpot vfs */
- conn->vfs_ops.close(fd);
- } else {
- set_filelen(fd, size); /* tpot vfs */
+ }
+ set_filelen(fd, size);
+ close(fd);
+ }
+ else
+ {
+ set_filelen(fd, size);
}
-
- if(fsp)
- set_filelen_write_cache(fsp, size);
}
SSVAL(params,0,0);
@@ -2023,10 +1905,14 @@ static int call_trans2mkdir(connection_struct *conn,
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
- unix_convert(directory,conn,0,&bad_path,NULL);
+ if (!unix_dfs_convert(directory,conn,0,&bad_path,NULL))
+ {
+ SSVAL(outbuf, smb_flg2, FLAGS2_32_BIT_ERROR_CODES);
+ return(ERROR(0, 0xc0000000|NT_STATUS_PATH_NOT_COVERED));
+ }
if (check_name(directory,conn))
ret = conn->vfs_ops.mkdir(dos_to_unix(directory,False),
- unix_mode(conn,aDIR,directory));
+ unix_mode(conn,aDIR));
if(ret < 0)
{
@@ -2127,11 +2013,11 @@ int reply_findclose(connection_struct *conn,
char *inbuf,char *outbuf,int length,int bufsize)
{
int outsize = 0;
- int dptr_num=SVALS(inbuf,smb_vwv0);
+ int16 dptr_num=SVALS(inbuf,smb_vwv0);
DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
- dptr_close(&dptr_num);
+ dptr_close(dptr_num);
outsize = set_message(outbuf,0,0,True);
@@ -2164,6 +2050,237 @@ int reply_findnclose(connection_struct *conn,
return(outsize);
}
+#define UNICODE_DFS
+
+/****************************************************************************
+ reply to a TRANS2_GET_DFS_REFERRAL
+ ****************************************************************************/
+static int call_trans2getdfsreferral(connection_struct *conn,
+ char *inbuf, char *outbuf, int length,
+ int bufsize,
+ char **pparams, char **ppdata,
+ int total_data)
+{
+ char *params = *pparams;
+ char *pdata;
+ char *pheader;
+ char *localstring_offset;
+ char *mangledstring_offset;
+ char *sharename_offset;
+ char *referal_offset;
+
+ int i;
+ int j;
+ unsigned int total_params = SVAL(inbuf, smb_tpscnt);
+ int query_file_len=0;
+ int bytesreq=0;
+ int filename_len;
+
+ BOOL first_one=True;
+
+ referal_trans_param rtp;
+ dfs_internal_table *list=dfs_struct.table;
+ dfs_response reply;
+
+ DEBUG(0,("call_trans2getdfsreferral:1\n"));
+
+ ZERO_STRUCT(rtp);
+ ZERO_STRUCT(reply);
+
+ /* decode the param member of query */
+ rtp.level=SVAL(params, 0);
+ DEBUGADD(0,("rtp.level:[%d]\n",rtp.level));
+
+ DEBUGADD(0,("total_params:[%d]\n",total_params));
+ for (i=0; i<(total_params-2)/2; i++)
+ {
+ rtp.directory[i]=SVAL(params, 2+2*i);
+ }
+/*
+ strupper(rtp.directory);
+*/
+ query_file_len=strlen(rtp.directory);
+ DEBUGADD(0,("rtp.directory:[%s]\n",rtp.directory));
+ DEBUGADD(0,("query_file_len:[%d]\n",query_file_len));
+
+ /*
+ lookup in the internal DFS table all the entries
+ and calculate the required data buffer size
+ */
+ bytesreq=8; /* the header */
+ reply.number_of_referal=0;
+ DEBUGADD(0,("call_trans2getdfsreferral:2\n"));
+
+ for(i=0; i<dfs_struct.size; i++)
+ {
+ filename_len=list[i].localpath_length;
+ DEBUGADD(0,("checking against [%s][%d]\n", list[i].localpath, filename_len));
+
+ if( (filename_len==query_file_len) &&
+ (!StrnCaseCmp(rtp.directory, list[i].localpath, query_file_len)) )
+ {
+
+ bytesreq+=22; /* the referal size */
+ bytesreq+=2*(list[i].sharename_length+1); /* the string length */
+ reply.number_of_referal++;
+ DEBUGADD(0,("found\n"));
+
+ if (first_one) {
+ DEBUGADD(0,("first one\n"));
+ bytesreq+=2*(list[i].localpath_length+1);
+ bytesreq+=2*(list[i].mangledpath_length+1);
+
+ reply.path_consumed=list[i].localpath_length;
+
+ strncpy(reply.filename, list[i].localpath, list[i].localpath_length+1);
+ strncpy(reply.mangledname, list[i].mangledpath, list[i].mangledpath_length+1);
+ rtp.type=list[i].type;
+ first_one=False;
+ }
+ }
+ }
+ DEBUGADD(0,("call_trans2getdfsreferral:3\n"));
+
+ /* allocate memory for the reply data */
+ pdata = *ppdata = Realloc(*ppdata, bytesreq + 1024);
+ bzero(*ppdata, bytesreq+22);
+
+ pdata = *ppdata;
+ pheader = pdata;
+
+ localstring_offset = pdata + 8 + reply.number_of_referal*22;
+
+#ifdef UNICODE_DFS
+ mangledstring_offset = localstring_offset + 2*(1+strlen(reply.filename));
+ sharename_offset = mangledstring_offset + 2*(1+strlen(reply.mangledname));
+
+#else
+ mangledstring_offset = localstring_offset + (1+strlen(reply.filename));
+ sharename_offset = mangledstring_offset + (1+strlen(reply.mangledname));
+#endif
+ referal_offset = pdata + 8;
+
+ /* right now respond storage server */
+/*
+ reply.server_function=rtp.type;
+*/
+ reply.server_function=0x3;
+
+ /* write the header */
+#ifdef UNICODE_DFS
+ SSVAL(pheader, 0, reply.path_consumed*2);
+#else
+ SSVAL(pheader, 0, reply.path_consumed);
+#endif
+ SSVAL(pheader, 2, reply.number_of_referal);
+ SIVAL(pheader, 4, reply.server_function);
+
+ /* write the local path string */
+#ifdef UNICODE_DFS
+ for(i=0; i<strlen(reply.filename); i++)
+ {
+ SSVAL(localstring_offset, 2*i, (uint16) reply.filename[i]);
+ }
+ SSVAL(localstring_offset, 2*strlen(reply.filename), 0);
+#else
+
+ for(i=0; i<strlen(reply.filename); i++)
+ {
+ localstring_offset[i]=reply.filename[i];
+ }
+ localstring_offset[strlen(reply.filename)]=0;
+#endif
+ DEBUG(0,("reply.filename is [%s]:[%d], i is [%d]\n", reply.filename, strlen(reply.filename), i));
+
+ /* write the mangled local path string */
+#ifdef UNICODE_DFS
+ for(i=0; i<strlen(reply.mangledname); i++)
+ {
+ SSVAL(mangledstring_offset, 2*i, (uint16) reply.mangledname[i]);
+ }
+ SSVAL(mangledstring_offset, 2*i, 0);
+#else
+ for(i=0; i<strlen(reply.mangledname); i++)
+ {
+ mangledstring_offset[i]=reply.mangledname[i];
+ }
+ mangledstring_offset[i]=0;
+#endif
+ DEBUGADD(0,("call_trans2getdfsreferral:4\n"));
+
+ /* the order of the referals defines the load balancing */
+
+ /* write each referal */
+ for(i=0; i<dfs_struct.size; i++)
+ {
+ filename_len=list[i].localpath_length;
+
+ if(filename_len==query_file_len &&
+ !strncasecmp(rtp.directory, list[i].localpath, query_file_len))
+ {
+
+ SSVAL(referal_offset, 0, 2); /* version */
+ SSVAL(referal_offset, 2, 22); /* size */
+
+ if (rtp.type==3)
+ SSVAL(referal_offset, 4, 1); /* type SMB server*/
+ else
+ SSVAL(referal_offset, 4, 0); /* type unknown */
+ SSVAL(referal_offset, 6, 1); /* flags */
+ SIVAL(referal_offset, 8, list[i].proximity); /* proximity */
+ SIVAL(referal_offset, 12, 300); /* ttl */
+ SSVAL(referal_offset, 16, localstring_offset-referal_offset);
+ SSVAL(referal_offset, 18, mangledstring_offset-referal_offset);
+ SSVAL(referal_offset, 20, sharename_offset-referal_offset);
+
+#ifdef UNICODE_DFS
+ for(j=0; j<list[i].sharename_length; j++)
+ {
+ SSVAL(sharename_offset, 2*j, (uint16) list[i].sharename[j]);
+ }
+ SSVAL(sharename_offset, 2*j, 0);
+
+ sharename_offset=sharename_offset + 2*(1+list[i].sharename_length);
+#else
+ for(j=0; j<list[i].sharename_length; j++)
+ {
+ sharename_offset[j]=list[i].sharename[j];
+ }
+ sharename_offset[j]=0;
+
+ sharename_offset=sharename_offset + (1+list[i].sharename_length);
+#endif
+
+ referal_offset=referal_offset+22;
+ }
+ }
+
+ DEBUGADD(0,("call_trans2getdfsreferral:5\n"));
+
+ send_trans2_replies(outbuf, bufsize, params, 0, *ppdata, bytesreq+22);
+
+/* send_trans2_replies(outbuf, bufsize, *ppdata, bytesreq, params, 0);*/
+ DEBUGADD(0,("call_trans2getdfsreferral:6\n"));
+
+ return(-1);
+}
+
+
+/****************************************************************************
+reply to a TRANS2_REPORT_DFS_INCONSISTANCY
+****************************************************************************/
+static int call_trans2reportdfsinconsistancy(connection_struct *conn,
+ char *inbuf, char *outbuf, int length,
+ int bufsize,
+ char **pparams, char **ppdata)
+{
+ char *params = *pparams;
+
+ DEBUG(4,("call_trans2reportdfsinconsistancy\n"));
+ send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
+ return(-1);
+}
+
/****************************************************************************
reply to a SMBtranss2 - just ignore it!
@@ -2294,73 +2411,104 @@ int reply_trans2(connection_struct *conn,
}
/* Now we must call the relevant TRANS2 function */
- switch(tran_call) {
- case TRANSACT2_OPEN:
- outsize = call_trans2open(conn,
+ switch(tran_call)
+ {
+ case TRANSACT2_OPEN:
+ {
+ outsize = call_trans2open(conn,
inbuf, outbuf, bufsize,
&params, &data);
- break;
-
- case TRANSACT2_FINDFIRST:
- outsize = call_trans2findfirst(conn, inbuf, outbuf,
- bufsize, &params, &data);
- break;
-
- case TRANSACT2_FINDNEXT:
- outsize = call_trans2findnext(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data);
- break;
-
- case TRANSACT2_QFSINFO:
- outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
- length, bufsize, &params,
- &data);
- break;
-
- case TRANSACT2_SETFSINFO:
- outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data);
- break;
-
- case TRANSACT2_QPATHINFO:
- case TRANSACT2_QFILEINFO:
- outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data, total_data);
- break;
- case TRANSACT2_SETPATHINFO:
- case TRANSACT2_SETFILEINFO:
- outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data,
- total_data);
- break;
-
- case TRANSACT2_FINDNOTIFYFIRST:
- outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data);
- break;
-
- case TRANSACT2_FINDNOTIFYNEXT:
- outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
- length, bufsize,
- &params, &data);
- break;
- case TRANSACT2_MKDIR:
- outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
- bufsize, &params, &data);
- break;
- default:
- /* Error in request */
- DEBUG(2,("Unknown request %d in trans2 call\n", tran_call));
- if(params)
- free(params);
- if(data)
- free(data);
- return (ERROR(ERRSRV,ERRerror));
+ break;
+ }
+ case TRANSACT2_FINDFIRST:
+ {
+ outsize = call_trans2findfirst(conn, inbuf, outbuf,
+ bufsize, &params, &data);
+ break;
+ }
+ case TRANSACT2_FINDNEXT:
+ {
+ outsize = call_trans2findnext(conn, inbuf, outbuf,
+ length, bufsize,
+ &params, &data);
+ break;
+ }
+ case TRANSACT2_QFSINFO:
+ {
+ outsize = call_trans2qfsinfo(conn, inbuf, outbuf,
+ length, bufsize, &params,
+ &data);
+ break;
+ }
+ case TRANSACT2_SETFSINFO:
+ {
+ outsize = call_trans2setfsinfo(conn, inbuf, outbuf,
+ length, bufsize,
+ &params, &data);
+ break;
+ }
+ case TRANSACT2_QPATHINFO:
+ case TRANSACT2_QFILEINFO:
+ {
+ outsize = call_trans2qfilepathinfo(conn, inbuf, outbuf,
+ length, bufsize,
+ &params, &data, total_data);
+ break;
+ }
+ case TRANSACT2_SETPATHINFO:
+ case TRANSACT2_SETFILEINFO:
+ {
+ outsize = call_trans2setfilepathinfo(conn, inbuf, outbuf,
+ length, bufsize,
+ &params, &data,
+ total_data);
+ break;
+ }
+ case TRANSACT2_FINDNOTIFYFIRST:
+ {
+ outsize = call_trans2findnotifyfirst(conn, inbuf, outbuf,
+ length, bufsize,
+ &params, &data);
+ break;
+ }
+ case TRANSACT2_FINDNOTIFYNEXT:
+ {
+ outsize = call_trans2findnotifynext(conn, inbuf, outbuf,
+ length, bufsize,
+ &params, &data);
+ break;
+ }
+ case TRANSACT2_MKDIR:
+ {
+ outsize = call_trans2mkdir(conn, inbuf, outbuf, length,
+ bufsize, &params, &data);
+ break;
+ }
+ case TRANSACT2_GET_DFS_REFERRAL:
+ {
+ outsize = call_trans2getdfsreferral(conn, inbuf, outbuf,
+ length, bufsize, &params,
+ &data, total_data);
+ break;
+ }
+ case TRANSACT2_REPORT_DFS_INCONSISTANCY:
+ {
+ outsize = call_trans2reportdfsinconsistancy(conn, inbuf, outbuf,
+ length, bufsize,
+ &params, &data);
+ break;
+ }
+ default:
+ {
+ /* Error in request */
+ DEBUG(2,("Unknown request %d in trans2 call\n",
+ tran_call));
+ if(params)
+ free(params);
+ if(data)
+ free(data);
+ return (ERROR(ERRSRV,ERRerror));
+ }
}
/* As we do not know how many data packets will need to be
@@ -2378,3 +2526,4 @@ int reply_trans2(connection_struct *conn,
call_trans2xxx calls have already sent
it. If outsize != -1 then it is returning */
}
+
diff --git a/source/smbd/uid.c b/source/smbd/uid.c
index ce0631e418a..83717be0567 100644
--- a/source/smbd/uid.c
+++ b/source/smbd/uid.c
@@ -23,148 +23,37 @@
extern int DEBUGLEVEL;
-/* what user is current? */
extern struct current_user current_user;
-pstring OriginalDir;
-
-/****************************************************************************
- Initialise the uid routines.
-****************************************************************************/
-
-void init_uid(void)
-{
- current_user.uid = geteuid();
- current_user.gid = getegid();
-
- if (current_user.gid != 0 && current_user.uid == 0) {
- gain_root_group_privilege();
- }
-
- current_user.conn = NULL;
- current_user.vuid = UID_FIELD_INVALID;
-
- dos_ChDir(OriginalDir);
-}
-
-/****************************************************************************
- Become the specified uid.
-****************************************************************************/
-
-static BOOL become_uid(uid_t uid)
-{
- if (uid == (uid_t)-1 || ((sizeof(uid_t) == 2) && (uid == (uid_t)65535))) {
- static int done;
- if (!done) {
- DEBUG(1,("WARNING: using uid %d is a security risk\n",(int)uid));
- done=1;
- }
- }
-
- set_effective_uid(uid);
-
- current_user.uid = uid;
-
-#ifdef WITH_PROFILE
- profile_p->uid_changes++;
-#endif
-
- return(True);
-}
-
-
-/****************************************************************************
- Become the specified gid.
-****************************************************************************/
-
-static BOOL become_gid(gid_t gid)
-{
- if (gid == (gid_t)-1 || ((sizeof(gid_t) == 2) && (gid == (gid_t)65535))) {
- DEBUG(1,("WARNING: using gid %d is a security risk\n",(int)gid));
- }
-
- set_effective_gid(gid);
-
- current_user.gid = gid;
-
- return(True);
-}
-
-
/****************************************************************************
- Become the specified uid and gid.
-****************************************************************************/
-
-static BOOL become_id(uid_t uid,gid_t gid)
-{
- return(become_gid(gid) && become_uid(uid));
-}
-
-/****************************************************************************
- Become the guest user.
+ Become the user of a connection number.
****************************************************************************/
-
-BOOL become_guest(void)
-{
- BOOL ret;
- static struct passwd *pass=NULL;
-
- if (!pass)
- pass = Get_Pwnam(lp_guestaccount(-1),True);
- if (!pass) return(False);
-
-#ifdef AIX
- /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before setting IDs */
- initgroups(pass->pw_name, (gid_t)pass->pw_gid);
-#endif
-
- ret = become_id(pass->pw_uid,pass->pw_gid);
-
- if (!ret) {
- DEBUG(1,("Failed to become guest. Invalid guest account?\n"));
- }
-
- current_user.conn = NULL;
- current_user.vuid = UID_FIELD_INVALID;
-
- return(ret);
-}
-
-/*******************************************************************
- Check if a username is OK.
-********************************************************************/
-
-static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum)
+BOOL become_user(connection_struct *conn, uint16 vuid)
{
- int i;
- for (i=0;i<conn->uid_cache.entries;i++)
- if (conn->uid_cache.list[i] == vuser->uid) return(True);
-
- if (!user_ok(vuser->name,snum)) return(False);
+ extern vuser_key *user_key;
+ static vuser_key key;
+ key.pid = getpid();
+ key.vuid = vuid;
- i = conn->uid_cache.entries % UID_CACHE_SIZE;
- conn->uid_cache.list[i] = vuser->uid;
+ user_key = &key;
- if (conn->uid_cache.entries < UID_CACHE_SIZE)
- conn->uid_cache.entries++;
-
- return(True);
+ return become_userk(conn, &key);
}
-
-
/****************************************************************************
Become the user of a connection number.
****************************************************************************/
-
-BOOL become_user(connection_struct *conn, uint16 vuid)
+BOOL become_userk(connection_struct *conn, const vuser_key *key)
{
- user_struct *vuser = get_valid_user_struct(vuid);
+ user_struct *vuser = NULL;
int snum;
- gid_t gid;
- uid_t uid;
+ gid_t gid = -1;
+ uid_t uid = -1;
char group_c;
+ int ngroups = 0;
+ gid_t *groups = NULL;
- if (!conn) {
+ if (!conn)
+ {
DEBUG(2,("Connection not open\n"));
return(False);
}
@@ -177,13 +66,23 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
*/
if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
- (current_user.uid == conn->uid)) {
+ (current_user.uid == conn->uid))
+ {
DEBUG(4,("Skipping become_user - already user\n"));
+
return(True);
- } else if ((current_user.conn == conn) &&
- (vuser != 0) && (current_user.vuid == vuid) &&
- (current_user.uid == vuser->uid)) {
+ }
+
+ vuser = get_valid_user_struct(key);
+
+ if ((current_user.conn == conn) &&
+ (vuser != NULL) &&
+ (current_user.key.vuid == key->vuid) &&
+ (current_user.key.pid == key->pid) &&
+ (current_user.uid == vuser->uid))
+ {
DEBUG(4,("Skipping become_user - already user\n"));
+ vuid_free_user_struct(vuser);
return(True);
}
@@ -191,25 +90,28 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
snum = SNUM(conn);
- if((vuser != NULL) && !check_user_ok(conn, vuser, snum))
+ if((vuser != NULL) && !check_vuser_ok(&conn->uid_cache, vuser, snum))
+ {
+ vuid_free_user_struct(vuser);
return False;
+ }
if (conn->force_user ||
lp_security() == SEC_SHARE ||
!(vuser) || (vuser->guest)) {
uid = conn->uid;
gid = conn->gid;
- current_user.groups = conn->groups;
- current_user.ngroups = conn->ngroups;
+ groups = conn->groups;
+ ngroups = conn->ngroups;
} else {
if (!vuser) {
- DEBUG(2,("Invalid vuid used %d\n",vuid));
+ DEBUG(2,("Invalid vuid used %d\n",key->vuid));
return(False);
}
uid = vuser->uid;
gid = vuser->gid;
- current_user.ngroups = vuser->n_groups;
- current_user.groups = vuser->groups;
+ ngroups = vuser->n_groups;
+ groups = vuser->groups;
}
/*
@@ -240,184 +142,22 @@ BOOL become_user(connection_struct *conn, uint16 vuid)
}
}
- if (!become_gid(gid))
- return(False);
-
-#ifdef HAVE_SETGROUPS
- if (!(conn && conn->ipc)) {
- /* groups stuff added by ih/wreu */
- if (current_user.ngroups > 0)
- if (sys_setgroups(current_user.ngroups,
- current_user.groups)<0) {
- DEBUG(0,("sys_setgroups call failed!\n"));
- }
- }
-#endif
+ vuid_free_user_struct(vuser);
- if (!conn->admin_user && !become_uid(uid))
- return(False);
-
- current_user.conn = conn;
- current_user.vuid = vuid;
-
- DEBUG(5,("become_user uid=(%d,%d) gid=(%d,%d)\n",
- (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
-
- return(True);
+ return become_unix_sec_ctx(key, conn, uid, gid, ngroups, groups);
}
/****************************************************************************
- Unbecome the user of a connection number.
+ unbecome the user of a connection number
****************************************************************************/
-
BOOL unbecome_user(void )
{
- if (!current_user.conn)
- return(False);
-
- dos_ChDir(OriginalDir);
-
- set_effective_uid(0);
- set_effective_gid(0);
-
- if (geteuid() != 0) {
- DEBUG(0,("Warning: You appear to have a trapdoor uid system\n"));
- }
- if (getegid() != 0) {
- DEBUG(0,("Warning: You appear to have a trapdoor gid system\n"));
- }
-
- current_user.uid = 0;
- current_user.gid = 0;
-
- if (dos_ChDir(OriginalDir) != 0)
- DEBUG( 0, ( "chdir(%s) failed in unbecome_user\n", OriginalDir ) );
-
- DEBUG(5,("unbecome_user now uid=(%d,%d) gid=(%d,%d)\n",
- (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
-
- current_user.conn = NULL;
- current_user.vuid = UID_FIELD_INVALID;
-
- return(True);
-}
-
-/****************************************************************************
- Become the user of an authenticated connected named pipe.
- When this is called we are currently running as the connection
- user.
-****************************************************************************/
-
-BOOL become_authenticated_pipe_user(pipes_struct *p)
-{
- /*
- * Go back to root.
- */
+ extern vuser_key *user_key;
+ user_key = NULL;
- if(!unbecome_user())
- return False;
-
- /*
- * Now become the authenticated user stored in the pipe struct.
- */
+ if (!current_user.conn)
+ return(False);
- if(!become_id(p->uid, p->gid)) {
- /* Go back to the connection user. */
- become_user(p->conn, p->vuid);
- return False;
- }
-
- return True;
+ return unbecome_to_initial_uid();
}
-/****************************************************************************
- Unbecome the user of an authenticated connected named pipe.
- When this is called we are running as the authenticated pipe
- user and need to go back to being the connection user.
-****************************************************************************/
-
-BOOL unbecome_authenticated_pipe_user(pipes_struct *p)
-{
- if(!become_id(0,0)) {
- DEBUG(0,("unbecome_authenticated_pipe_user: Unable to go back to root.\n"));
- return False;
- }
-
- return become_user(p->conn, p->vuid);
-}
-
-static struct current_user current_user_saved;
-static int become_root_depth;
-static pstring become_root_dir;
-
-/****************************************************************************
-This is used when we need to do a privileged operation (such as mucking
-with share mode files) and temporarily need root access to do it. This
-call should always be paired with an unbecome_root() call immediately
-after the operation
-
-Set save_dir if you also need to save/restore the CWD
-****************************************************************************/
-
-void become_root(BOOL save_dir)
-{
- if (become_root_depth) {
- DEBUG(0,("ERROR: become root depth is non zero\n"));
- }
- if (save_dir)
- dos_GetWd(become_root_dir);
-
- current_user_saved = current_user;
- become_root_depth = 1;
-
- become_uid(0);
- become_gid(0);
-}
-
-/****************************************************************************
-When the privileged operation is over call this
-
-Set save_dir if you also need to save/restore the CWD
-****************************************************************************/
-
-void unbecome_root(BOOL restore_dir)
-{
- if (become_root_depth != 1) {
- DEBUG(0,("ERROR: unbecome root depth is %d\n",
- become_root_depth));
- }
-
- /* we might have done a become_user() while running as root,
- if we have then become root again in order to become
- non root! */
- if (current_user.uid != 0) {
- become_uid(0);
- }
-
- /* restore our gid first */
- if (!become_gid(current_user_saved.gid)) {
- DEBUG(0,("ERROR: Failed to restore gid\n"));
- exit_server("Failed to restore gid");
- }
-
-#ifdef HAVE_SETGROUPS
- if (current_user_saved.ngroups > 0) {
- if (sys_setgroups(current_user_saved.ngroups,
- current_user_saved.groups)<0)
- DEBUG(0,("ERROR: sys_setgroups call failed!\n"));
- }
-#endif
-
- /* now restore our uid */
- if (!become_uid(current_user_saved.uid)) {
- DEBUG(0,("ERROR: Failed to restore uid\n"));
- exit_server("Failed to restore uid");
- }
-
- if (restore_dir)
- dos_ChDir(become_root_dir);
-
- current_user = current_user_saved;
-
- become_root_depth = 0;
-}
diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c
index 24e45a6d24a..3493c231789 100644
--- a/source/smbd/vfs-wrap.c
+++ b/source/smbd/vfs-wrap.c
@@ -1,7 +1,7 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
-s Wrap disk only vfs functions to sidestep dodgy compilers.
+ Wrap disk only vfs functions to sidestep dodgy compilers.
Copyright (C) Tim Potter 1998
This program is free software; you can redistribute it and/or modify
@@ -41,7 +41,7 @@ void vfswrap_dummy_disconnect(void)
/* Disk operations */
-SMB_BIG_UINT vfswrap_disk_free(char *path, BOOL small_query, SMB_BIG_UINT *bsize,
+SMB_BIG_UINT vfswrap_disk_free(char *path, SMB_BIG_UINT *bsize,
SMB_BIG_UINT *dfree, SMB_BIG_UINT *dsize)
{
SMB_BIG_UINT result;
@@ -54,7 +54,7 @@ SMB_BIG_UINT vfswrap_disk_free(char *path, BOOL small_query, SMB_BIG_UINT *bsize
}
#endif
- result = sys_disk_free(path, small_query, bsize, dfree, dsize);
+ result = sys_disk_free(path, bsize, dfree, dsize);
return result;
}
@@ -204,9 +204,9 @@ int vfswrap_rename(char *old, char *new)
return result;
}
-void vfswrap_fsync(int fd)
+void vfswrap_sync_file(int fd)
{
- fsync(fd);
+ sys_sync_file(fd);
}
int vfswrap_stat(char *fname, SMB_STRUCT_STAT *sbuf)
@@ -252,6 +252,15 @@ int vfswrap_lstat(char *path,
return result;
}
+BOOL vfswrap_fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count,
+ int type)
+{
+ BOOL result;
+
+ result = fcntl_lock(fd, op, offset, count, type);
+ return result;
+}
+
int vfswrap_unlink(char *path)
{
int result;
diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c
index 44f44bd169a..18aaf0d3604 100644
--- a/source/smbd/vfs.c
+++ b/source/smbd/vfs.c
@@ -20,6 +20,9 @@
*/
#include "includes.h"
+#ifdef HAVE_LIBDL
+#include <dlfcn.h>
+#endif
extern int DEBUGLEVEL;
@@ -58,10 +61,11 @@ struct vfs_ops default_vfs_ops = {
vfswrap_write,
vfswrap_lseek,
vfswrap_rename,
- vfswrap_fsync,
+ vfswrap_sync_file,
vfswrap_stat,
vfswrap_fstat,
vfswrap_lstat,
+ vfswrap_fcntl_lock,
vfswrap_unlink,
vfswrap_chmod,
vfswrap_utime
@@ -92,9 +96,7 @@ BOOL vfs_init_custom(connection_struct *conn)
/* Open object file */
- handle = dlopen(lp_vfsobj(SNUM(conn)), RTLD_NOW | RTLD_GLOBAL);
- conn->vfs_conn->dl_handle = handle;
-
+ handle = dlopen(lp_vfsobj(SNUM(conn)), RTLD_NOW);
if (!handle) {
DEBUG(0, ("Error opening %s: %s\n", lp_vfsobj(SNUM(conn)),
dlerror()));
@@ -104,17 +106,17 @@ BOOL vfs_init_custom(connection_struct *conn)
/* Get handle on vfs_init() symbol */
fptr = dlsym(handle, "vfs_init");
-
if (fptr == NULL) {
DEBUG(0, ("No vfs_init() symbol found in %s\n",
lp_vfsobj(SNUM(conn))));
return False;
}
+ dlclose(handle);
+
/* Initialise vfs_ops structure */
- if ((ops = fptr(NULL)) == NULL) {
- DEBUG(0, ("vfs_init function from %s failed\n", lp_vfsobj(SNUM(conn))));
+ if ((ops = fptr(lp_vfsoptions(SNUM(conn)))) == NULL) {
return False;
}
@@ -180,8 +182,8 @@ BOOL vfs_init_custom(connection_struct *conn)
conn->vfs_ops.rename = default_vfs_ops.rename;
}
- if (conn->vfs_ops.fsync == NULL) {
- conn->vfs_ops.fsync = default_vfs_ops.fsync;
+ if (conn->vfs_ops.sync == NULL) {
+ conn->vfs_ops.sync = default_vfs_ops.sync;
}
if (conn->vfs_ops.stat == NULL) {
@@ -196,6 +198,10 @@ BOOL vfs_init_custom(connection_struct *conn)
conn->vfs_ops.lstat = default_vfs_ops.lstat;
}
+ if (conn->vfs_ops.lock == NULL) {
+ conn->vfs_ops.lock = default_vfs_ops.lock;
+ }
+
if (conn->vfs_ops.unlink == NULL) {
conn->vfs_ops.unlink = default_vfs_ops.unlink;
}
@@ -212,24 +218,6 @@ BOOL vfs_init_custom(connection_struct *conn)
}
#endif
-BOOL vfs_directory_exist(connection_struct *conn, char *dname,
- SMB_STRUCT_STAT *st)
-{
- SMB_STRUCT_STAT st2;
- BOOL ret;
-
- if (!st) st = &st2;
-
- if (conn->vfs_ops.stat(dos_to_unix(dname,False),st) != 0)
- return(False);
-
- ret = S_ISDIR(st->st_mode);
- if(!ret)
- errno = ENOTDIR;
-
- return ret;
-}
-
/*******************************************************************
check if a vfs file exists
********************************************************************/
@@ -389,69 +377,3 @@ char *vfs_readdirname(connection_struct *conn, void *p)
unix_to_dos(dname, True);
return(dname);
}
-
-/* VFS options not quite working yet */
-
-#if 0
-
-/***************************************************************************
- handle the interpretation of the vfs option parameter
- *************************************************************************/
-static BOOL handle_vfs_option(char *pszParmValue, char **ptr)
-{
- struct vfs_options *new_option, **options = (struct vfs_options **)ptr;
- int i;
-
- /* Create new vfs option */
-
- new_option = (struct vfs_options *)malloc(sizeof(*new_option));
- if (new_option == NULL) {
- return False;
- }
-
- ZERO_STRUCTP(new_option);
-
- /* Get name and value */
-
- new_option->name = strtok(pszParmValue, "=");
-
- if (new_option->name == NULL) {
- return False;
- }
-
- while(isspace(*new_option->name)) {
- new_option->name++;
- }
-
- for (i = strlen(new_option->name); i > 0; i--) {
- if (!isspace(new_option->name[i - 1])) break;
- }
-
- new_option->name[i] = '\0';
- new_option->name = strdup(new_option->name);
-
- new_option->value = strtok(NULL, "=");
-
- if (new_option->value != NULL) {
-
- while(isspace(*new_option->value)) {
- new_option->value++;
- }
-
- for (i = strlen(new_option->value); i > 0; i--) {
- if (!isspace(new_option->value[i - 1])) break;
- }
-
- new_option->value[i] = '\0';
- new_option->value = strdup(new_option->value);
- }
-
- /* Add to list */
-
- DLIST_ADD(*options, new_option);
-
- return True;
-}
-
-#endif
-
diff --git a/source/smbwrapper/realcalls.h b/source/smbwrapper/realcalls.h
index 251c2673372..d6440b46be2 100644
--- a/source/smbwrapper/realcalls.h
+++ b/source/smbwrapper/realcalls.h
@@ -58,6 +58,8 @@
#elif HAVE___OPEN64
#define real_open64(fn,flags,mode) (__open64(fn,flags,mode))
#define NO_OPEN64_ALIAS
+#else
+#error No open64() wrapper
#endif
#ifdef HAVE__FORK
@@ -66,6 +68,8 @@
#define real_fork() (__fork())
#elif SYS_fork
#define real_fork() (syscall(SYS_fork))
+#else
+#error No fork() wrapper
#endif
#ifdef HAVE__OPENDIR
@@ -74,6 +78,8 @@
#define real_opendir(fn) (syscall(SYS_opendir,(fn)))
#elif HAVE___OPENDIR
#define real_opendir(fn) (__opendir(fn))
+#else
+#error No opendir() wrapper
#endif
#ifdef HAVE__READDIR
@@ -82,6 +88,8 @@
#define real_readdir(d) (__readdir(d))
#elif SYS_readdir
#define real_readdir(d) (syscall(SYS_readdir,(d)))
+#else
+#error No readdir() wrapper
#endif
#ifdef HAVE__CLOSEDIR
@@ -90,6 +98,8 @@
#define real_closedir(d) (syscall(SYS_closedir,(d)))
#elif HAVE___CLOSEDIR
#define real_closedir(d) (__closedir(d))
+#else
+#error No closedir() wrapper
#endif
#ifdef HAVE__SEEKDIR
@@ -100,6 +110,7 @@
#define real_seekdir(d,l) (__seekdir(d,l))
#else
#define NO_SEEKDIR_WRAPPER
+#error No seekdir() wrapper
#endif
#ifdef HAVE__TELLDIR
@@ -108,6 +119,8 @@
#define real_telldir(d) (syscall(SYS_telldir,(d)))
#elif HAVE___TELLDIR
#define real_telldir(d) (__telldir(d))
+#else
+#error No telldir() wrapper
#endif
#ifdef HAVE__DUP
@@ -116,6 +129,8 @@
#define real_dup(d) (syscall(SYS_dup,(d)))
#elif HAVE___DUP
#define real_dup(d) (__dup(d))
+#else
+#error No dup() wrapper
#endif
#ifdef HAVE__DUP2
@@ -124,6 +139,8 @@
#define real_dup2(d1,d2) (syscall(SYS_dup2,(d1),(d2)))
#elif HAVE___DUP2
#define real_dup2(d1,d2) (__dup2(d1,d2))
+#else
+#error No dup2() wrapper
#endif
#ifdef HAVE__GETCWD
@@ -132,6 +149,8 @@
#define real_getcwd(b,s) ((char *)syscall(SYS_getcwd,(b),(s)))
#elif HAVE___GETCWD
#define real_getcwd(b,s) ((char *)__getcwd(b,s))
+#else
+#error No getcwd() wrapper
#endif
#ifdef HAVE__STAT
@@ -140,6 +159,8 @@
#define real_stat(fn,st) (syscall(SYS_stat,(fn),(st)))
#elif HAVE___STAT
#define real_stat(fn,st) (__stat(fn,st))
+#else
+#error No stat() wrapper
#endif
#ifdef HAVE__LSTAT
@@ -148,6 +169,8 @@
#define real_lstat(fn,st) (syscall(SYS_lstat,(fn),(st)))
#elif HAVE___LSTAT
#define real_lstat(fn,st) (__lstat(fn,st))
+#else
+#error No lstat() wrapper
#endif
#ifdef HAVE__FSTAT
@@ -156,6 +179,8 @@
#define real_fstat(fd,st) (syscall(SYS_fstat,(fd),(st)))
#elif HAVE___FSTAT
#define real_fstat(fd,st) (__fstat(fd,st))
+#else
+#error No fstat() wrapper
#endif
#if defined(HAVE_SYS_ACL_H) && defined(HAVE__ACL)
@@ -183,24 +208,32 @@
#define real_stat64(fn,st) (_stat64(fn,st))
#elif HAVE___STAT64
#define real_stat64(fn,st) (__stat64(fn,st))
+#else
+#error No stat64() wrapper
#endif
#ifdef HAVE__LSTAT64
#define real_lstat64(fn,st) (_lstat64(fn,st))
#elif HAVE___LSTAT64
#define real_lstat64(fn,st) (__lstat64(fn,st))
+#else
+#error No lstat64() wrapper
#endif
#ifdef HAVE__FSTAT64
#define real_fstat64(fd,st) (_fstat64(fd,st))
#elif HAVE___FSTAT64
#define real_fstat64(fd,st) (__fstat64(fd,st))
+#else
+#error No fstat64() wrapper
#endif
#ifdef HAVE__READDIR64
#define real_readdir64(d) (_readdir64(d))
#elif HAVE___READDIR64
#define real_readdir64(d) (__readdir64(d))
+#else
+#error No readdir64() wrapper
#endif
#ifdef HAVE__LLSEEK
@@ -209,6 +242,10 @@
#define real_llseek(fd,ofs,whence) (__llseek(fd,ofs,whence))
#elif HAVE___SYS_LLSEEK
#define real_llseek(fd,ofs,whence) (__sys_llseek(fd,ofs,whence))
+#elif IRIX
+#define real_llseek(fd,ofs,whence) (lseek64(fd, ofs, whence)) /* is this true? neither the IRIX or Linux man pages match this */
+#else
+#error No llseek() wrapper
#endif
@@ -216,24 +253,32 @@
#define real_pread(fd,buf,size,ofs) (_pread(fd,buf,size,ofs))
#elif HAVE___PREAD
#define real_pread(fd,buf,size,ofs) (__pread(fd,buf,size,ofs))
+#else
+#error No pread() wrapper
#endif
#ifdef HAVE__PREAD64
#define real_pread64(fd,buf,size,ofs) (_pread64(fd,buf,size,ofs))
#elif HAVE___PREAD64
#define real_pread64(fd,buf,size,ofs) (__pread64(fd,buf,size,ofs))
+#else
+#error No pread64() wrapper
#endif
#ifdef HAVE__PWRITE
#define real_pwrite(fd,buf,size,ofs) (_pwrite(fd,buf,size,ofs))
#elif HAVE___PWRITE
#define real_pwrite(fd,buf,size,ofs) (__pwrite(fd,buf,size,ofs))
+#else
+#error No pwrite() wrapper
#endif
#ifdef HAVE__PWRITE64
#define real_pwrite64(fd,buf,size,ofs) (_pwrite64(fd,buf,size,ofs))
#elif HAVE___PWRITE64
#define real_pwrite64(fd,buf,size,ofs) (__pwrite64(fd,buf,size,ofs))
+#else
+#error No pwrite64() wrapper
#endif
diff --git a/source/smbwrapper/shared.c b/source/smbwrapper/shared.c
index f7f7b8c8ea9..010c5ae19a3 100644
--- a/source/smbwrapper/shared.c
+++ b/source/smbwrapper/shared.c
@@ -37,7 +37,7 @@ void smbw_setup_shared(void)
slprintf(s,sizeof(s)-1, "%s/smbw.XXXXXX",tmpdir());
- fstrcpy(name,(char *)smbd_mktemp(s));
+ fstrcpy(name,(char *)mktemp(s));
/* note zero permissions! don't change this */
fd = sys_open(name,O_RDWR|O_CREAT|O_TRUNC|O_EXCL,0);
diff --git a/source/smbwrapper/smbsh.c b/source/smbwrapper/smbsh.c
index e11244d4fb3..8c9d00bd981 100644
--- a/source/smbwrapper/smbsh.c
+++ b/source/smbwrapper/smbsh.c
@@ -93,7 +93,7 @@ int main(int argc, char *argv[])
sys_getwd(wd);
- slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
+ slprintf(line,sizeof(line)-1,"PWD_%d", getpid());
smbw_setshared(line, wd);
diff --git a/source/smbwrapper/smbw.c b/source/smbwrapper/smbw.c
index 4c246e1e40a..407922d03d1 100644
--- a/source/smbwrapper/smbw.c
+++ b/source/smbwrapper/smbw.c
@@ -81,7 +81,7 @@ void smbw_init(void)
lp_load(servicesf,True,False,False);
- get_myname(global_myname);
+ get_myname(global_myname,NULL);
if ((p=smbw_getshared("DEBUG"))) {
DEBUGLEVEL = atoi(p);
@@ -93,11 +93,11 @@ void smbw_init(void)
if ((p=smbw_getshared("PREFIX"))) {
slprintf(smbw_prefix,sizeof(fstring)-1, "/%s/", p);
- all_string_sub(smbw_prefix,"//", "/", 0);
+ string_sub(smbw_prefix,"//", "/");
DEBUG(2,("SMBW_PREFIX is %s\n", smbw_prefix));
}
- slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
+ slprintf(line,sizeof(line)-1,"PWD_%d", getpid());
p = smbw_getshared(line);
if (!p) {
@@ -320,7 +320,7 @@ char *smbw_parse_path(const char *fname, char *server, char *share, char *path)
pstrcpy(path,p);
- all_string_sub(path, "/", "\\", 0);
+ string_sub(path, "/", "\\");
ok:
DEBUG(4,("parsed path name=%s cwd=%s [%s] [%s] [%s]\n",
@@ -341,9 +341,6 @@ int smbw_path(const char *path)
char *cwd;
int len;
- if(!path)
- return 0;
-
/* this is needed to prevent recursion with the BSD malloc which
opens /etc/malloc.conf on the first call */
if (strncmp(path,"/etc/", 5) == 0) {
@@ -381,7 +378,7 @@ int smbw_errno(struct cli_state *c)
uint32 ecode;
int ret;
- ret = cli_error(c, &eclass, &ecode, NULL);
+ ret = cli_error(c, &eclass, &ecode);
if (ret) {
DEBUG(3,("smbw_error %d %d (0x%x) -> %d\n",
@@ -491,12 +488,12 @@ struct smbw_server *smbw_server(char *server, char *share)
return NULL;
}
- if (!cli_session_setup(&c, username,
+ if (!cli_session_setup_x(&c, username,
password, strlen(password),
password, strlen(password),
workgroup) &&
/* try an anonymous login if it failed */
- !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) {
+ !cli_session_setup_x(&c, "", "", 1,"", 0, workgroup)) {
cli_shutdown(&c);
errno = EPERM;
return NULL;
@@ -702,7 +699,7 @@ ssize_t smbw_pread(int fd, void *buf, size_t count, off_t ofs)
return -1;
}
- ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, ofs, count);
+ ret = cli_read(&file->srv->cli, file->f->cli_fd, buf, ofs, count, True);
if (ret == -1) {
errno = smbw_errno(&file->srv->cli);
@@ -734,7 +731,7 @@ ssize_t smbw_read(int fd, void *buf, size_t count)
}
ret = cli_read(&file->srv->cli, file->f->cli_fd, buf,
- file->f->offset, count);
+ file->f->offset, count, True);
if (ret == -1) {
errno = smbw_errno(&file->srv->cli);
@@ -769,7 +766,7 @@ ssize_t smbw_write(int fd, void *buf, size_t count)
return -1;
}
- ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, file->f->offset, count);
+ ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, file->f->offset, count, count);
if (ret == -1) {
errno = smbw_errno(&file->srv->cli);
@@ -800,7 +797,7 @@ ssize_t smbw_pwrite(int fd, void *buf, size_t count, off_t ofs)
return -1;
}
- ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, ofs, count);
+ ret = cli_write(&file->srv->cli, file->f->cli_fd, 0, buf, ofs, count, count);
if (ret == -1) {
errno = smbw_errno(&file->srv->cli);
@@ -1388,7 +1385,7 @@ int smbw_fork(void)
smbw_srv_close(srv);
}
- slprintf(line,sizeof(line)-1,"PWD_%d", (int)getpid());
+ slprintf(line,sizeof(line)-1,"PWD_%d", getpid());
smbw_setshared(line,smbw_cwd);
/* unblock the parent */
diff --git a/source/smbwrapper/smbw_dir.c b/source/smbwrapper/smbw_dir.c
index 09294282736..7c6e6db70ad 100644
--- a/source/smbwrapper/smbw_dir.c
+++ b/source/smbwrapper/smbw_dir.c
@@ -146,7 +146,8 @@ static void smbw_printjob_add(struct print_job_info *job)
finfo.mtime = job->t;
finfo.atime = job->t;
finfo.ctime = job->t;
- finfo.uid = nametouid(job->user);
+ finfo.uid = (uid_t)-1;
+ nametouid(job->user, &finfo.uid);
finfo.mode = aRONLY;
finfo.size = job->size;
@@ -197,7 +198,7 @@ int smbw_dir_open(const char *fname)
cur_dir = dir;
slprintf(mask, sizeof(mask)-1, "%s\\*", path);
- all_string_sub(mask,"\\\\","\\",0);
+ string_sub(mask,"\\\\","\\");
if ((p=strstr(srv->server_name,"#1D"))) {
DEBUG(4,("doing NetServerEnum\n"));
diff --git a/source/smbwrapper/wrapped.c b/source/smbwrapper/wrapped.c
index 1b356e6a26d..4703614d649 100644
--- a/source/smbwrapper/wrapped.c
+++ b/source/smbwrapper/wrapped.c
@@ -30,10 +30,6 @@
#include <errno.h>
#include "realcalls.h"
-#ifndef NULL
-# define NULL ((void *)0)
-#endif
-
int open(char *name, int flags, mode_t mode)
{
if (smbw_path(name)) {
@@ -691,7 +687,7 @@
static double xx[70];
void *d;
d = (void *)readdir(dir);
- if (!d) return NULL;
+ if (!d) return (void *)0;
dirent64_convert(d, xx);
return xx;
}
@@ -703,4 +699,3 @@
{
return smbw_fork();
}
-
diff --git a/source/spoolssd/spoolssd.c b/source/spoolssd/spoolssd.c
new file mode 100644
index 00000000000..0b969d924ef
--- /dev/null
+++ b/source/spoolssd/spoolssd.c
@@ -0,0 +1,121 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+fstring pipe_name;
+
+pstring servicesf = CONFIGFILE;
+extern pstring debugf;
+extern BOOL append_log;
+
+/*****************************************************************************
+ initialise srv_auth_fns array
+ *****************************************************************************/
+static void auth_init(rpcsrv_struct *l)
+{
+}
+
+/*************************************************************************
+ initialise an msrpc service
+ *************************************************************************/
+static void service_init(char* service_name)
+{
+ add_msrpc_command_processor( pipe_name, service_name, api_spoolss_rpc );
+ generate_wellknown_sids();
+}
+
+/****************************************************************************
+ reload the services file
+ **************************************************************************/
+static BOOL reload_msrpc(BOOL test)
+{
+ BOOL ret;
+
+ if (lp_loaded()) {
+ pstring fname;
+ pstrcpy(fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
+ reopen_logs();
+
+ if (test && !lp_file_list_changed())
+ return(True);
+
+ lp_killunused(NULL);
+
+ ret = lp_load(servicesf,False,False,True);
+
+ load_printers();
+
+ /* perhaps the config filename is now set */
+ if (!test)
+ reload_msrpc(True);
+
+ reopen_logs();
+
+ load_interfaces();
+
+ return(ret);
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+static int main_init(int argc,char *argv[])
+{
+#ifdef HAVE_SET_AUTH_PARAMETERS
+ set_auth_parameters(argc,argv);
+#endif
+
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ append_log = True;
+
+ TimeInit();
+
+ setup_logging(argv[0],False);
+ fstrcpy(pipe_name, "spoolss");
+ slprintf(debugf, sizeof(debugf), "%s/log.%s", LOGFILEBASE, pipe_name);
+
+ return 0;
+}
+
+static msrpc_service_fns fn_table =
+{
+ auth_init,
+ service_init,
+ reload_msrpc,
+ main_init,
+ NULL
+};
+
+msrpc_service_fns *get_service_fns(void)
+{
+ return &fn_table;
+}
diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/spoolssd/srv_spoolss_nt.c
index 90a0ef6d608..1ccf7914f6e 100644..100755
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/spoolssd/srv_spoolss_nt.c
@@ -23,6 +23,7 @@
#include "includes.h"
+#include "rpc_parse.h"
#include "nterr.h"
extern int DEBUGLEVEL;
@@ -35,251 +36,276 @@ extern pstring global_myname;
#define PRINTER_HANDLE_IS_PRINTER 0
#define PRINTER_HANDLE_IS_PRINTSERVER 1
-/* structure to store the printer handles */
-/* and a reference to what it's pointing to */
-/* and the notify info asked about */
-/* that's the central struct */
-typedef struct _Printer{
- ubi_dlNode Next;
- ubi_dlNode Prev;
-
- BOOL open;
- BOOL document_started;
- BOOL page_started;
- uint32 current_jobid;
- uint32 document_fd;
- uint32 document_lastwritten;
- pstring document_name;
- pstring job_name;
- POLICY_HND printer_hnd;
- BOOL printer_type;
- union {
- fstring printername;
- fstring printerservername;
- } dev;
- uint32 type;
- uint32 access;
- struct {
- uint32 flags;
- uint32 options;
- fstring localmachine;
- uint32 printerlocal;
- SPOOL_NOTIFY_OPTION *option;
- } notify;
- struct {
- fstring machine;
- fstring user;
- } client;
-} Printer_entry;
-
-static ubi_dlList Printer_list;
-
-#define OPEN_HANDLE(pnum) ((pnum!=NULL) && (pnum->open!=False))
+static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
+ NT_PRINTER_INFO_LEVEL *printer,
+ uint32 level)
+{
+ switch (level)
+ {
+ case 2:
+ {
+ uni_2_asc_printer_info_2(uni->info_2,
+ &(printer->info_2));
+ break;
+ }
+ default:
+ break;
+ }
+
-/****************************************************************************
- initialise printer handle states...
-****************************************************************************/
-void init_printer_hnd(void)
+
+ return True;
+}
+
+static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
+ NT_PRINTER_DRIVER_INFO_LEVEL *printer,
+ uint32 level)
{
- ubi_dlInitList(&Printer_list);
+ switch (level)
+ {
+ case 3:
+ {
+ printer->info_3=NULL;
+ uni_2_asc_printer_driver_3(uni->info_3, &(printer->info_3));
+ break;
+ }
+ default:
+ break;
+ }
+
+
+
+ return True;
}
-/****************************************************************************
- create a unique printer handle
-****************************************************************************/
-static void create_printer_hnd(POLICY_HND *hnd)
+static BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode)
{
- static uint32 prt_hnd_low = 0;
- static uint32 prt_hnd_high = 0;
+ unistr_to_ascii(nt_devmode->devicename,
+ devmode.devicename.buffer,
+ 31);
- if (hnd == NULL) return;
+ unistr_to_ascii(nt_devmode->formname,
+ devmode.formname.buffer,
+ 31);
+
+ nt_devmode->specversion=devmode.specversion;
+ nt_devmode->driverversion=devmode.driverversion;
+ nt_devmode->size=devmode.size;
+ nt_devmode->driverextra=devmode.driverextra;
+ nt_devmode->fields=devmode.fields;
+ nt_devmode->orientation=devmode.orientation;
+ nt_devmode->papersize=devmode.papersize;
+ nt_devmode->paperlength=devmode.paperlength;
+ nt_devmode->paperwidth=devmode.paperwidth;
+ nt_devmode->scale=devmode.scale;
+ nt_devmode->copies=devmode.copies;
+ nt_devmode->defaultsource=devmode.defaultsource;
+ nt_devmode->printquality=devmode.printquality;
+ nt_devmode->color=devmode.color;
+ nt_devmode->duplex=devmode.duplex;
+ nt_devmode->yresolution=devmode.yresolution;
+ nt_devmode->ttoption=devmode.ttoption;
+ nt_devmode->collate=devmode.collate;
- /* i severely doubt that prt_hnd_high will ever be non-zero... */
- prt_hnd_low++;
- if (prt_hnd_low == 0) prt_hnd_high++;
+ nt_devmode->logpixels=devmode.logpixels;
+ nt_devmode->bitsperpel=devmode.bitsperpel;
+ nt_devmode->pelswidth=devmode.pelswidth;
+ nt_devmode->pelsheight=devmode.pelsheight;
+ nt_devmode->displayflags=devmode.displayflags;
+ nt_devmode->displayfrequency=devmode.displayfrequency;
+ nt_devmode->icmmethod=devmode.icmmethod;
+ nt_devmode->icmintent=devmode.icmintent;
+ nt_devmode->mediatype=devmode.mediatype;
+ nt_devmode->dithertype=devmode.dithertype;
+ nt_devmode->reserved1=devmode.reserved1;
+ nt_devmode->reserved2=devmode.reserved2;
+ nt_devmode->panningwidth=devmode.panningwidth;
+ nt_devmode->panningheight=devmode.panningheight;
+
+ if (nt_devmode->driverextra != 0)
+ {
+ /* if we had a previous private delete it and make a new one */
+ if (nt_devmode->private != NULL)
+ free(nt_devmode->private);
+ nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8));
+ memcpy(nt_devmode->private, devmode.private, nt_devmode->driverextra);
+ }
+
- SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */
- SIVAL(hnd->data, 4 , prt_hnd_low ); /* second bit is incrementing */
- SIVAL(hnd->data, 8 , prt_hnd_high); /* second bit is incrementing */
- SIVAL(hnd->data, 12, time(NULL)); /* something random */
- SIVAL(hnd->data, 16, getpid()); /* something more random */
+ return True;
}
+
+
+/* structure to store the printer handles */
+/* and a reference to what it's pointing to */
+/* and the notify info asked about */
+/* that's the central struct */
+
+typedef struct print_hnd_info
+{
+ BOOL document_started;
+ BOOL page_started;
+ uint32 current_jobid;
+ uint32 document_fd;
+ uint32 document_lastwritten;
+ pstring document_name;
+ pstring job_name;
+ BOOL printer_type;
+ union
+ {
+ fstring printername;
+ fstring printerservername;
+ } dev;
+ uint32 type;
+ uint32 access;
+ uint32 number_of_notify;
+ SPOOL_NOTIFY_OPTION_TYPE notify_info[MAX_PRINTER_NOTIFY+MAX_JOB_NOTIFY];
+
+} PRINT_HND_INFO;
+
+#define INVALID_HANDLE(pnum) (pnum == NULL)
+
/****************************************************************************
- find printer index by handle
+ set printer handle
****************************************************************************/
-static Printer_entry *find_printer_index_by_hnd(const POLICY_HND *hnd)
+static BOOL set_printhndinfo(struct policy_cache *cache, POLICY_HND *hnd)
{
- Printer_entry *find_printer;
-
- find_printer = (Printer_entry *)ubi_dlFirst(&Printer_list);
+ PRINT_HND_INFO *dev;
+ dev = malloc(sizeof(*dev));
- for(; find_printer; find_printer = (Printer_entry *)ubi_dlNext(find_printer)) {
+ DEBUG(3,("Setting policy info\n"));
- if (memcmp(&(find_printer->printer_hnd), hnd, sizeof(*hnd)) == 0)
+ if (dev != NULL)
+ {
+ ZERO_STRUCTP(dev);
+ if (set_policy_state(cache, hnd, NULL, (void*)dev))
{
- DEBUG(4,("Found printer handle \n"));
- /*dump_data(4, hnd->data, sizeof(hnd->data));*/
- return find_printer;
+ DEBUG(3,("Service setting policy info\n"));
+ return True;
}
+ free(dev);
+ return False;
}
-
- DEBUG(3,("Whoops, Printer handle not found: "));
- /*dump_data(4, hnd->data, sizeof(hnd->data));*/
- return NULL;
+ DEBUG(3,("Error setting policy sid\n"));
+ return False;
}
/****************************************************************************
- clear an handle
+ get printer handle
****************************************************************************/
-static void clear_handle(POLICY_HND *hnd)
+static BOOL get_printhndinfo(struct policy_cache *cache, const POLICY_HND *hnd,
+ PRINT_HND_INFO **pnum)
{
- memset(hnd->data, 0, POLICY_HND_SIZE);
+ PRINT_HND_INFO *d = (PRINT_HND_INFO*)get_policy_state_info(cache, hnd);
+
+ if (d != NULL)
+ {
+ (*pnum) = d;
+ return True;
+ }
+
+ DEBUG(3,("Error getting policy print handle\n"));
+ return False;
}
/****************************************************************************
- close printer index by handle
-****************************************************************************/
-static BOOL close_printer_handle(POLICY_HND *hnd)
+ find first available printer slot. creates a printer handle for you.
+ ****************************************************************************/
+static BOOL open_printer_hnd(POLICY_HND *hnd, uint32 access_mask)
{
- Printer_entry *Printer = find_printer_index_by_hnd(hnd);
-
- if (!OPEN_HANDLE(Printer))
+ if (!open_policy_hnd(get_global_hnd_cache(),
+ get_sec_ctx(), hnd, access_mask))
{
- DEBUG(3,("Error closing printer handle\n"));
return False;
}
-
- Printer->open=False;
- Printer->notify.flags=0;
- Printer->notify.options=0;
- Printer->notify.localmachine[0]='\0';
- Printer->notify.printerlocal=0;
- safe_free(Printer->notify.option);
- Printer->notify.option=NULL;
-
- clear_handle(hnd);
-
- ubi_dlRemThis(&Printer_list, Printer);
-
- safe_free(Printer);
-
- return True;
-}
+ return set_printhndinfo(get_global_hnd_cache(), hnd);
+}
/****************************************************************************
- return the snum of a printer corresponding to an handle
+ find printer index by handle
****************************************************************************/
-static BOOL get_printer_snum(const POLICY_HND *hnd, int *number)
+static PRINT_HND_INFO *find_printer_index_by_hnd(const POLICY_HND *hnd)
{
- int snum;
- Printer_entry *Printer = find_printer_index_by_hnd(hnd);
- int n_services=lp_numservices();
-
- if (!OPEN_HANDLE(Printer)) {
- DEBUG(3,("Error getting printer - take a nap quickly !\n"));
- return False;
- }
+ PRINT_HND_INFO *pnum = NULL;
- switch (Printer->printer_type) {
- case PRINTER_HANDLE_IS_PRINTER:
- DEBUG(4,("short name:%s\n", Printer->dev.printername));
- for (snum=0;snum<n_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
- DEBUG(4,("share:%s\n",lp_servicename(snum)));
- if ( ( strlen(lp_servicename(snum)) == strlen( Printer->dev.printername ) )
- && ( !strncasecmp(lp_servicename(snum),
- Printer->dev.printername,
- strlen( lp_servicename(snum) ))) ) {
- DEBUG(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum));
- *number=snum;
- return True;
- break;
- }
- }
- }
- return False;
- break;
- case PRINTER_HANDLE_IS_PRINTSERVER:
- return False;
- break;
- default:
- return False;
- break;
+ if (get_printhndinfo(get_global_hnd_cache(), hnd, &pnum))
+ {
+ return pnum;
}
+ return NULL;
}
/****************************************************************************
- find first available printer slot. creates a printer handle for you.
- ****************************************************************************/
-static BOOL open_printer_hnd(POLICY_HND *hnd)
+ close printer index by handle
+****************************************************************************/
+static BOOL close_printer_handle(POLICY_HND *hnd)
{
- Printer_entry *new_printer;
-
- new_printer=(Printer_entry *)malloc(sizeof(Printer_entry));
- ZERO_STRUCTP(new_printer);
-
- new_printer->open = True;
- new_printer->notify.option=NULL;
-
- memcpy(&(new_printer->printer_hnd), hnd, sizeof(*hnd));
-
- ubi_dlAddHead( &Printer_list, (ubi_dlNode *)new_printer);
-
- return True;
-}
+ return close_policy_hnd(get_global_hnd_cache(), hnd);
+}
/****************************************************************************
set printer handle type.
****************************************************************************/
static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required)
{
- Printer_entry *Printer = find_printer_index_by_hnd(hnd);
+ PRINT_HND_INFO *pnum = find_printer_index_by_hnd(hnd);
- if (!OPEN_HANDLE(Printer)) {
- DEBUG(4,("Error setting printer type=%x", access_required));
+ if (INVALID_HANDLE(pnum))
+ {
+ DEBUG(4,("Error setting printer type=%x\n",
+ access_required));
return False;
}
+ else
+ {
+ DEBUG(4,("Setting printer access=%x\n",
+ access_required));
- DEBUG(4,("Setting printer access=%x\n", access_required));
- Printer->access = access_required;
- return True;
+
+
+ pnum->access = access_required;
+ return True;
+ }
+ return False;
}
/****************************************************************************
set printer handle type.
- check if it's \\server or \\server\printer
****************************************************************************/
static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername)
{
- Printer_entry *Printer = find_printer_index_by_hnd(hnd);
+ PRINT_HND_INFO *pnum = find_printer_index_by_hnd(hnd);
- if (!OPEN_HANDLE(Printer)) {
- DEBUGADD(4,("Error setting printer name %s", printername));
+ if (INVALID_HANDLE(pnum))
+ {
+ DEBUGADD(4,("Error setting printer name %s",
+ printername));
return False;
}
-
DEBUG(3,("Setting printer type=%s\n", printername));
- if ( strlen(printername) < 3 ) {
+ if ( strlen(printername) < 3 )
+ {
DEBUGADD(4,("A print server must have at least 1 char ! %s\n", printername));
return False;
}
- /* it's a print server */
- if (!strchr(printername+2, '\\')) {
+ /* check if it's \\server or \\server\printer */
+ /* +2 is to skip the leading \\ */
+ if (!strchr(printername+2, '\\'))
+ {
+ /* it's a print server */
DEBUGADD(4,("Printer is a print server\n"));
- Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
- return True;
+ pnum->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;
}
- /* it's a printer */
- else {
+ else
+ {
+ /* it's a printer */
DEBUGADD(4,("Printer is a printer\n"));
- Printer->printer_type = PRINTER_HANDLE_IS_PRINTER;
- return True;
- }
-
- return False;
+ pnum->printer_type = PRINTER_HANDLE_IS_PRINTER;
+ }
+ return True;
}
/****************************************************************************
@@ -287,119 +313,154 @@ static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername)
****************************************************************************/
static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername)
{
- Printer_entry *Printer = find_printer_index_by_hnd(hnd);
+ PRINT_HND_INFO *pnum = find_printer_index_by_hnd(hnd);
+ char *back;
NT_PRINTER_INFO_LEVEL printer;
int snum;
int n_services=lp_numservices();
- char *aprinter;
- BOOL found=False;
+ uint32 marche;
- if (!OPEN_HANDLE(Printer))
+ if (INVALID_HANDLE(pnum))
{
- DEBUG(0,("Error setting printer name=%s\n", printername));
+ DEBUG(0,("Error setting printer name=%s\n",
+ printername));
return False;
}
- DEBUG(4,("Setting printer name=%s (len=%d)\n", printername, strlen(printername)));
+ DEBUG(4,("Setting printer name=%s (len=%d)\n",
+ printername,strlen(printername)));
+
+ switch (pnum->printer_type)
+ {
+ case PRINTER_HANDLE_IS_PRINTER:
+ back=strchr(printername+2, '\\');
+ back=back+1;
+ DEBUGADD(5,("searching for %s (len=%d)\n", back,strlen(back)));
+ /*
+ * store the Samba share name in it
+ * in back we have the long printer name
+ * need to iterate all the snum and do a
+ * get_a_printer each time to find the printer
+ * faster to do it here than later.
+ */
+ for (snum=0;snum<n_services; snum++)
+ {
+ if (lp_browseable(snum) &&
+ lp_snum_ok(snum) &&
+ lp_print_ok(snum) )
+ {
+ DEBUGADD(5,("share:%s\n",lp_servicename(snum)));
+
+ marche=get_a_printer(&printer, 2, lp_servicename(snum));
+ DEBUGADD(6,("marche:%d\n",marche));
+
+ if ( marche==0 && ( strlen(printer.info_2->printername) == strlen(back) )
+ && ( !strncasecmp(printer.info_2->printername, back, strlen(back)))
+ )
+ {
+ DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum));
+ ZERO_STRUCT(pnum->dev.printername);
+ strncpy(pnum->dev.printername, lp_servicename(snum), strlen(lp_servicename(snum)));
+ free_a_printer(printer, 2);
+ return True;
+ break;
+ }
+ free_a_printer(printer, 2);
+ }
+ }
- if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
- ZERO_STRUCT(Printer->dev.printerservername);
- strncpy(Printer->dev.printerservername, printername, strlen(printername));
+ return False;
+ break;
+ case PRINTER_HANDLE_IS_PRINTSERVER:
+ ZERO_STRUCT(pnum->dev.printerservername);
+ strncpy(pnum->dev.printerservername, printername, strlen(printername));
return True;
- }
-
- if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
+ break;
+ default:
return False;
-
- aprinter=strchr(printername+2, '\\');
- aprinter++;
-
- DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
- /*
- * store the Samba share name in it
- * in back we have the long printer name
- * need to iterate all the snum and do a
- * get_a_printer each time to find the printer
- * faster to do it here than later.
- */
-
- for (snum=0;snum<n_services && found==False;snum++) {
-
- if ( !(lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) )
- continue;
-
- DEBUGADD(5,("share:%s\n",lp_servicename(snum)));
-
- if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
- continue;
+ break;
+ }
+}
- if ( strlen(printer.info_2->printername) != strlen(aprinter) ) {
- free_a_printer(printer, 2);
- continue;
- }
-
- if ( strncasecmp(printer.info_2->printername, aprinter, strlen(aprinter))) {
- free_a_printer(printer, 2);
- continue;
- }
+/****************************************************************************
+ return the snum of a printer corresponding to an handle
+****************************************************************************/
+static BOOL get_printer_snum(const POLICY_HND *hnd, int *number)
+{
+ int snum;
+ PRINT_HND_INFO *pnum = find_printer_index_by_hnd(hnd);
+ int n_services=lp_numservices();
- found=True;
- }
-
- if (found==False)
+ if (INVALID_HANDLE(pnum))
{
- DEBUGADD(4,("Printer not found\n"));
+ DEBUG(3,("Error getting printer - take a nap quickly !\n"));
return False;
}
-
- snum--;
- DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum));
- ZERO_STRUCT(Printer->dev.printername);
- strncpy(Printer->dev.printername, lp_servicename(snum), strlen(lp_servicename(snum)));
- free_a_printer(printer, 2);
-
- return True;
+ switch (pnum->printer_type)
+ {
+ case PRINTER_HANDLE_IS_PRINTER:
+ DEBUG(4,("short name:%s\n", pnum->dev.printername));
+ for (snum=0;snum<n_services; snum++)
+ {
+ if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
+ {
+ DEBUG(4,("share:%s\n",lp_servicename(snum)));
+ if ( ( strlen(lp_servicename(snum)) == strlen( pnum->dev.printername ) )
+ && ( !strncasecmp(lp_servicename(snum),
+ pnum->dev.printername,
+ strlen( lp_servicename(snum) )))
+ )
+ {
+ DEBUG(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum));
+ *number=snum;
+ return True;
+ break;
+ }
+ }
+ }
+ return False;
+ break;
+ case PRINTER_HANDLE_IS_PRINTSERVER:
+ return False;
+ break;
+ default:
+ return False;
+ break;
+ }
}
/********************************************************************
- Return True is the handle is a print server.
********************************************************************/
static BOOL handle_is_printserver(const POLICY_HND *handle)
{
- Printer_entry *Printer=find_printer_index_by_hnd(handle);
+ PRINT_HND_INFO *pnum=find_printer_index_by_hnd(handle);
- if (!OPEN_HANDLE(Printer))
- return False;
-
- if (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
+ if (INVALID_HANDLE(pnum))
+ {
return False;
-
- return True;
+ }
+ switch (pnum->printer_type)
+ {
+ case PRINTER_HANDLE_IS_PRINTSERVER:
+ {
+ return True;
+ }
+ case PRINTER_HANDLE_IS_PRINTER:
+ {
+ return False;
+ }
+ }
+ return False;
}
-/****************************************************************************
- allocate more memory for a BUFFER.
-****************************************************************************/
-static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
+/********************************************************************
+ ********************************************************************/
+/*
+static BOOL handle_is_printer(POLICY_HND *handle)
{
- prs_struct *ps;
- uint32 extra_space;
-
- ps=&(buffer->prs);
-
- /* damn, I'm doing the reverse operation of prs_grow() :) */
- if (buffer_size < prs_data_size(ps))
- extra_space=0;
- else
- extra_space = buffer_size - prs_data_size(ps);
-
- if (!prs_grow(ps, extra_space))
- return False;
-
- buffer->string_at_end=prs_data_size(ps);
-
- return True;
+ return (!handle_is_printserver(handle));
}
+*/
/********************************************************************
* spoolss_open_printer
@@ -407,17 +468,24 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
* called from the spoolss dispatcher
********************************************************************/
uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
- const PRINTER_DEFAULT *printer_default,
- uint32 user_switch, SPOOL_USER_CTR user_ctr,
- POLICY_HND *handle)
+
+ uint32 unknown0, uint32 cbbuf,
+ uint32 devmod, uint32 access_required,
+ uint32 unknown1, uint32 unknown2,
+ uint32 unknown3, uint32 unknown4,
+ uint32 unknown5, uint32 unknown6,
+ uint32 unknown7, uint32 unknown8,
+ uint32 unknown9, uint32 unknown10,
+ const UNISTR2 *station, const UNISTR2 *username,
+ POLICY_HND *handle)
{
+ BOOL printer_open = False;
fstring name;
- fstring datatype;
-
- clear_handle(handle);
-
+
if (printername == NULL)
+ {
return NT_STATUS_ACCESS_DENIED;
+ }
/* some sanity check because you can open a printer or a print server */
/* aka: \\server\printer or \\server */
@@ -425,118 +493,23 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername,
DEBUGADD(3,("checking name: %s\n",name));
- create_printer_hnd(handle);
-
- open_printer_hnd(handle);
+ printer_open = open_printer_hnd(handle, access_required);
+ set_printer_hnd_printertype(handle, name);
- if (!set_printer_hnd_printertype(handle, name)) {
- close_printer_handle(handle);
- return NT_STATUS_ACCESS_DENIED;
- }
-
- if (!set_printer_hnd_printername(handle, name)) {
- close_printer_handle(handle);
- return NT_STATUS_ACCESS_DENIED;
- }
-
-/*
- if (printer_default->datatype_ptr != NULL)
+ if ( !set_printer_hnd_printername(handle, name) )
{
- unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1);
- set_printer_hnd_datatype(handle, datatype);
+ if (close_printer_handle(handle))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ return NT_STATUS_INVALID_HANDLE;
}
- else
- set_printer_hnd_datatype(handle, "");
-*/
- if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) {
- close_printer_handle(handle);
- return NT_STATUS_ACCESS_DENIED;
- }
-
- return NT_STATUS_NO_PROBLEMO;
-}
+ set_printer_hnd_accesstype(handle, access_required);
-/****************************************************************************
-****************************************************************************/
-static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
- NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
- switch (level) {
- case 2:
- uni_2_asc_printer_info_2(uni->info_2, &(printer->info_2));
- break;
- default:
- break;
- }
-
- return True;
-}
-
-static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
- NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
-{
- switch (level) {
- case 3:
- printer->info_3=NULL;
- uni_2_asc_printer_driver_3(uni->info_3, &(printer->info_3));
- break;
- default:
- break;
- }
-
- return True;
-}
-
-static BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode)
-{
- unistr_to_ascii(nt_devmode->devicename, devmode.devicename.buffer, 31);
- unistr_to_ascii(nt_devmode->formname, devmode.formname.buffer, 31);
-
- nt_devmode->specversion=devmode.specversion;
- nt_devmode->driverversion=devmode.driverversion;
- nt_devmode->size=devmode.size;
- nt_devmode->driverextra=devmode.driverextra;
- nt_devmode->fields=devmode.fields;
- nt_devmode->orientation=devmode.orientation;
- nt_devmode->papersize=devmode.papersize;
- nt_devmode->paperlength=devmode.paperlength;
- nt_devmode->paperwidth=devmode.paperwidth;
- nt_devmode->scale=devmode.scale;
- nt_devmode->copies=devmode.copies;
- nt_devmode->defaultsource=devmode.defaultsource;
- nt_devmode->printquality=devmode.printquality;
- nt_devmode->color=devmode.color;
- nt_devmode->duplex=devmode.duplex;
- nt_devmode->yresolution=devmode.yresolution;
- nt_devmode->ttoption=devmode.ttoption;
- nt_devmode->collate=devmode.collate;
-
- nt_devmode->logpixels=devmode.logpixels;
- nt_devmode->bitsperpel=devmode.bitsperpel;
- nt_devmode->pelswidth=devmode.pelswidth;
- nt_devmode->pelsheight=devmode.pelsheight;
- nt_devmode->displayflags=devmode.displayflags;
- nt_devmode->displayfrequency=devmode.displayfrequency;
- nt_devmode->icmmethod=devmode.icmmethod;
- nt_devmode->icmintent=devmode.icmintent;
- nt_devmode->mediatype=devmode.mediatype;
- nt_devmode->dithertype=devmode.dithertype;
- nt_devmode->reserved1=devmode.reserved1;
- nt_devmode->reserved2=devmode.reserved2;
- nt_devmode->panningwidth=devmode.panningwidth;
- nt_devmode->panningheight=devmode.panningheight;
-
- if (nt_devmode->driverextra != 0)
- {
- /* if we had a previous private delete it and make a new one */
- if (nt_devmode->private != NULL)
- free(nt_devmode->private);
- nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8));
- memcpy(nt_devmode->private, devmode.private, nt_devmode->driverextra);
- }
-
- return True;
+ /* if there is a error free the printer entry */
+
+ return NT_STATUS_NOPROBLEMO;
}
/********************************************************************
@@ -544,86 +517,104 @@ static BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode)
********************************************************************/
uint32 _spoolss_closeprinter(POLICY_HND *handle)
{
- if (!close_printer_handle(handle))
- return NT_STATUS_INVALID_HANDLE;
-
- return NT_STATUS_NO_PROBLEMO;
+ if (close_printer_handle(handle))
+ {
+ return NT_STATUS_NOPROBLEMO;
+ }
+ return NT_STATUS_INVALID_HANDLE;
}
/********************************************************************
- GetPrinterData on a printer server Handle.
-********************************************************************/
-static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
+ ********************************************************************/
+static BOOL getprinterdata_printer_server(fstring value, uint32 size, uint32 *type,
+ uint32 *numeric_data, uint8 **data, uint32 *needed)
{
int i;
-
- DEBUG(8,("getprinterdata_printer_server:%s\n", value));
if (!strcmp(value, "BeepEnabled"))
{
- *type = 0x4;
- *data = (uint8 *)malloc( 4*sizeof(uint8) );
- SIVAL(*data, 0, 0x01);
- *needed = 0x4;
+ *type = 0x4;
+ *data = (uint8 *)malloc( 4*sizeof(uint8) );
+ ZERO_STRUCTP(*data);
+ (*data)[0]=0x01;
+ (*data)[1]=0x00;
+ (*data)[2]=0x00;
+ (*data)[3]=0x00;
+ *numeric_data = 0x1; /* beep enabled */
+ *needed = 0x4;
return True;
}
if (!strcmp(value, "EventLog"))
{
- *type = 0x4;
- *data = (uint8 *)malloc( 4*sizeof(uint8) );
- SIVAL(*data, 0, 0x1B);
- *needed = 0x4;
+ *type = 0x4;
+ *data = (uint8 *)malloc( 4*sizeof(uint8) );
+ ZERO_STRUCTP(*data);
+ (*data)[0]=0x1B;
+ (*data)[1]=0x00;
+ (*data)[2]=0x00;
+ (*data)[3]=0x00;
+ *numeric_data = 0x1B; /* Don't know ??? */
+ *needed = 0x4;
return True;
}
if (!strcmp(value, "NetPopup"))
{
- *type = 0x4;
- *data = (uint8 *)malloc( 4*sizeof(uint8) );
- SIVAL(*data, 0, 0x01);
- *needed = 0x4;
+ *type = 0x4;
+ *data = (uint8 *)malloc( 4*sizeof(uint8) );
+ ZERO_STRUCTP(*data);
+ (*data)[0]=0x01;
+ (*data)[1]=0x00;
+ (*data)[2]=0x00;
+ (*data)[3]=0x00;
+ *numeric_data = 0x1; /* popup enabled */
+ *needed = 0x4;
return True;
}
if (!strcmp(value, "MajorVersion"))
{
- *type = 0x4;
- *data = (uint8 *)malloc( 4*sizeof(uint8) );
- SIVAL(*data, 0, 0x02);
- *needed = 0x4;
+ *type = 0x4;
+ *data = (uint8 *)malloc( 4*sizeof(uint8) );
+ (*data)[0]=0x02;
+ (*data)[1]=0x00;
+ (*data)[2]=0x00;
+ (*data)[3]=0x00;
+ *numeric_data = 0x2; /* it's 2, period. */
+ *needed = 0x4;
return True;
}
if (!strcmp(value, "DefaultSpoolDirectory"))
{
- pstring string="You are using a Samba server";
+ pstring directory="You are using a Samba server";
*type = 0x1;
- *needed = 2*(strlen(string)+1);
- *data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8));
- memset(*data, 0, (*needed > in_size) ? *needed:in_size);
+ *data = (uint8 *)malloc( size*sizeof(uint8) );
+ ZERO_STRUCTP(*data);
/* it's done by hand ready to go on the wire */
- for (i=0; i<strlen(string); i++)
+ for (i=0; i<strlen(directory); i++)
{
- (*data)[2*i]=string[i];
+ (*data)[2*i]=directory[i];
(*data)[2*i+1]='\0';
}
+ *needed = 2*(strlen(directory)+1);
return True;
}
if (!strcmp(value, "Architecture"))
{
- pstring string="Windows NT x86";
+ pstring directory="Windows NT x86";
*type = 0x1;
- *needed = 2*(strlen(string)+1);
- *data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8));
- memset(*data, 0, (*needed > in_size) ? *needed:in_size);
- for (i=0; i<strlen(string); i++)
+ *data = (uint8 *)malloc( size*sizeof(uint8) );
+ ZERO_STRUCTP(*data);
+ for (i=0; i<strlen(directory); i++)
{
- (*data)[2*i]=string[i];
+ (*data)[2*i]=directory[i];
(*data)[2*i+1]='\0';
}
+ *needed = 2*(strlen(directory)+1);
return True;
}
@@ -631,93 +622,118 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **d
}
/********************************************************************
- GetPrinterData on a printer Handle.
-********************************************************************/
+ ********************************************************************/
static BOOL getprinterdata_printer(const POLICY_HND *handle,
- fstring value, uint32 *type,
- uint8 **data, uint32 *needed, uint32 in_size )
+ fstring value, uint32 size, uint32 *type,
+ uint32 *numeric_data, uint8 **data,
+ uint32 *needed )
{
NT_PRINTER_INFO_LEVEL printer;
+ PRINT_HND_INFO *pnum = find_printer_index_by_hnd(handle);
int snum=0;
uint8 *idata=NULL;
uint32 len;
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
DEBUG(5,("getprinterdata_printer\n"));
- if (OPEN_HANDLE(Printer))
+ if (INVALID_HANDLE(pnum))
{
- get_printer_snum(handle, &snum);
- get_a_printer(&printer, 2, lp_servicename(snum));
-
- if (get_specific_param(printer, 2, value, &idata, type, &len))
+ return (False);
+ }
+
+ get_printer_snum(handle, &snum);
+ get_a_printer(&printer, 2, lp_servicename(snum));
+
+ if (get_specific_param(printer, 2, value, &idata, type, &len))
+ {
+ /*switch (*type)
{
- *data = (uint8 *)malloc( (len>in_size)?len:in_size *sizeof(uint8) );
- memset(*data, 0, sizeof(uint8)*len);
- memcpy(*data, idata, (len>in_size)?len:in_size);
- *needed = len;
-
- if (idata) free(idata);
- return (True);
- }
- free_a_printer(printer, 2);
+ case 1:
+ case 3:
+ case 4:*/
+ *data = (uint8 *)malloc( size*sizeof(uint8) );
+ bzero(*data, sizeof(uint8)*size);
+ memcpy(*data, idata, len>size?size:len);
+ *needed = len;
+ if (idata) free(idata);
+ /*break;*/
+ /*case 4:
+ *numeric_data=atoi(idata);
+ break;*/
+ /*}*/
+ return (True);
}
+ free_a_printer(printer, 2);
- return (False);
+ return False;
}
/********************************************************************
* spoolss_getprinterdata
********************************************************************/
uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename,
- uint32 in_size,
uint32 *type,
- uint32 *out_size,
+ uint32 *size,
uint8 **data,
+ uint32 *numeric_data,
uint32 *needed)
{
fstring value;
- BOOL found=False;
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
+ BOOL found;
+ PRINT_HND_INFO *pnum = find_printer_index_by_hnd(handle);
/*
* Reminder: when it's a string, the length is in BYTES
* even if UNICODE is negociated.
*
+ * type is the kind of data
+ * 1 is a string
+ * 4 is a uint32
+ *
+ * I think it's documented in MSDN somewhere in
+ * the registry data type (yep it's linked ...)
+ *
* JFM, 4/19/1999
*/
- *out_size=in_size;
-
- /* in case of problem, return some default values */
- *needed=0;
- *type=0;
-
- DEBUG(4,("_spoolss_getprinterdata\n"));
-
- if (!OPEN_HANDLE(Printer)) {
- *data=(uint8 *)malloc(4*sizeof(uint8));
+ if (INVALID_HANDLE(pnum))
+ {
return NT_STATUS_INVALID_HANDLE;
}
+
+ (*type) = 0x4;
+ (*needed) = 0x0;
+ (*data) = NULL;
+ (*numeric_data) =0x0;
unistr2_to_ascii(value, valuename, sizeof(value)-1);
if (handle_is_printserver(handle))
- found=getprinterdata_printer_server(value, type, data, needed, *out_size);
+ {
+ found=getprinterdata_printer_server(value, *size,
+ type, numeric_data,
+ data, needed);
+ }
else
- found=getprinterdata_printer(handle, value, type, data, needed, *out_size);
+ {
+ found=getprinterdata_printer(handle, value, *size,
+ type, numeric_data,
+ data, needed);
+ }
- if (found==False) {
+ if (found==False)
+ {
+ safe_free(data);
/* reply this param doesn't exist */
- *data=(uint8 *)malloc(4*sizeof(uint8));
- memset(*data, 0x0, 4);
+ (*type) = 0x4;
+ (*size) = 0x0;
+ (*data) = NULL;
+ (*numeric_data)=0x0;
+ (*needed) = 0x0;
return ERROR_INVALID_PARAMETER;
}
-
- if (*needed > *out_size)
- return ERROR_INSUFFICIENT_BUFFER;
- else
- return NT_STATUS_NO_PROBLEMO;
+
+ return NT_STATUS_NOPROBLEMO;
}
/********************************************************************
@@ -731,24 +747,43 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename,
* in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
* called from api_spoolss_rffpcnex
********************************************************************/
-uint32 _spoolss_rffpcnex(const POLICY_HND *handle, uint32 flags, uint32 options,
- const UNISTR2 *localmachine, uint32 printerlocal,
- SPOOL_NOTIFY_OPTION *option)
+uint32 _spoolss_rffpcnex(const POLICY_HND *handle,
+ uint32 flags, uint32 options,
+ const UNISTR2 *localmachine,
+ uint32 printerlocal,
+ SPOOL_NOTIFY_OPTION *option)
{
+ PRINT_HND_INFO *i;
+ int j, k;
+
/* store the notify value in the printer struct */
- Printer_entry *Printer=find_printer_index_by_hnd(handle);
+ i=find_printer_index_by_hnd(handle);
- if (!OPEN_HANDLE(Printer))
+ if (INVALID_HANDLE(i))
+ {
return NT_STATUS_INVALID_HANDLE;
+ }
+
+ i->number_of_notify=option->count;
+
+ DEBUG(3,("Copying %x notify option info\n",i->number_of_notify));
- Printer->notify.flags=flags;
- Printer->notify.options=options;
- Printer->notify.printerlocal=printerlocal;
- Printer->notify.option=option;
- unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
+ for (j=0;j<i->number_of_notify;j++)
+ {
+ i->notify_info[j].count=option->type[j].count;
+ i->notify_info[j].type=option->type[j].type ;
+
+ DEBUG(4,("Copying %x info fields of type %x\n",
+ i->notify_info[j].count,
+ i->notify_info[j].type));
+ for(k=0;k<i->notify_info[j].count;k++)
+ {
+ i->notify_info[j].fields[k]=option->type[j].fields[k];
+ }
+ }
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_NOPROBLEMO;
}
/*******************************************************************
@@ -961,9 +996,9 @@ static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_
print_queue_struct *q=NULL;
print_status_struct status;
- memset(&status, 0, sizeof(status));
+ bzero(&status,sizeof(status));
- count=get_printqueue(snum, NULL, &q, &status);
+ count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &q, &status);
data->notify_data.value[0]=(uint32) status.status;
if (q) free(q);
@@ -977,9 +1012,9 @@ static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_q
print_queue_struct *q=NULL;
print_status_struct status;
- memset(&status, 0, sizeof(status));
+ bzero(&status,sizeof(status));
- data->notify_data.value[0]=get_printqueue(snum, NULL, &q, &status);
+ data->notify_data.value[0]=get_printqueue(snum, NULL, UID_FIELD_INVALID, &q, &status);
if (q) free(q);
}
@@ -1163,30 +1198,40 @@ static int search_notify(uint16 type, uint16 field, int *value)
int j;
BOOL found;
+ DEBUG(4,("\tsearch_notify: in\n"));
for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++)
{
if ( (notify_info_data_table[j].type == type ) &&
(notify_info_data_table[j].field == field ) )
+ {
found=True;
+ }
}
*value=--j;
if ( found && (notify_info_data_table[j].fn != NULL) )
- return True;
+ {
+ DEBUG(4,("\tsearch_notify: out TRUE\n"));
+ return (True);
+ }
else
- return False;
+ {
+ DEBUG(4,("\tsearch_notify: out FALSE\n"));
+ return (False);
+ }
}
/****************************************************************************
****************************************************************************/
static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
{
+ DEBUG(4,("\tconstruct_info_data: in\n"));
info_data->type = type;
info_data->field = field;
- info_data->reserved = 0;
info_data->id = id;
info_data->size = size_of_notify_info_data(type, field);
info_data->enc_type = type_of_notify_info_data(type, field);
+ DEBUG(4,("\tconstruct_info_data: out\n"));
}
@@ -1195,48 +1240,49 @@ static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type,
* fill a notify_info struct with info asked
*
********************************************************************/
-static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
+static void construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, PRINT_HND_INFO *pnum,
+ int snum, int i, uint32 id)
{
- int field_num,j;
+
+ int k,j;
uint16 type;
uint16 field;
- SPOOL_NOTIFY_INFO_DATA *current_data;
- NT_PRINTER_INFO_LEVEL printer;
+ SPOOL_NOTIFY_INFO_DATA *info_data;
print_queue_struct *queue=NULL;
+ NT_PRINTER_INFO_LEVEL printer;
DEBUG(4,("construct_notify_printer_info\n"));
- type=option_type->type;
-
- DEBUGADD(4,("Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
- (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
- option_type->count, lp_servicename(snum)));
+ info_data=&(info->data[info->count]);
- if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
- {
- return False;
- }
+ type = pnum->notify_info[i].type;
- for(field_num=0; field_num<option_type->count; field_num++)
+ DEBUGADD(4,("Notify number %d -> number of notify info: %d\n",i,pnum->notify_info[i].count));
+
+ if (!get_a_printer(&printer, 2, lp_servicename(snum)))
{
- field = option_type->fields[field_num];
- DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", field_num, type, field));
-
- if (!search_notify(type, field, &j) )
- continue;
- info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA));
- current_data=&(info->data[info->count]);
-
- construct_info_data(current_data, type, field, id);
- notify_info_data_table[j].fn(snum, current_data, queue, &printer);
+ for(k=0; k<pnum->notify_info[i].count; k++)
+ {
+ field = pnum->notify_info[i].fields[k];
+ DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", k, type, field));
- info->count++;
+ if (search_notify(type, field, &j) )
+ {
+ DEBUGADD(4,("j=[%d]:%s\n", j, notify_info_data_table[j].name));
+ construct_info_data(info_data, type, field, id);
+
+ DEBUGADD(4,("notify_info_data_table: in\n"));
+ notify_info_data_table[j].fn(snum, info_data, queue, &printer);
+ DEBUGADD(4,("notify_info_data_table: out\n"));
+ info->count++;
+ info_data=&(info->data[info->count]);
+ }
+ }
+
+ free_a_printer(printer, 2);
}
-
- free_a_printer(printer, 2);
- return True;
}
/*******************************************************************
@@ -1244,72 +1290,46 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int snum, SPO
* fill a notify_info struct with info asked
*
********************************************************************/
-static BOOL construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id)
+static void construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info,
+ PRINT_HND_INFO *pnum, int snum, int i, uint32 id)
{
- int field_num,j;
+
+ int k,j;
uint16 type;
uint16 field;
- SPOOL_NOTIFY_INFO_DATA *current_data;
+ SPOOL_NOTIFY_INFO_DATA *info_data;
NT_PRINTER_INFO_LEVEL printer;
DEBUG(4,("construct_notify_jobs_info\n"));
+ info_data=&(info->data[info->count]);
- type = option_type->type;
+ type = pnum->notify_info[i].type;
- DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
- (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
- option_type->count));
+ DEBUGADD(4,("Notify number %d -> number of notify info: %d\n",i,pnum->notify_info[i].count));
- if (get_a_printer(&printer, 2, lp_servicename(snum))!=0)
+ if (!get_a_printer(&printer, 2, lp_servicename(snum)))
{
- return False;
- }
-
- for(field_num=0; field_num<option_type->count; field_num++)
- {
- field = option_type->fields[field_num];
-
- if (!search_notify(type, field, &j) )
- continue;
-
- info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA));
- current_data=&(info->data[info->count]);
+ for(k=0; k<pnum->notify_info[i].count; k++)
+ {
+ field = pnum->notify_info[i].fields[k];
+ DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n",k, type, field));
- construct_info_data(current_data, type, field, id);
- notify_info_data_table[j].fn(snum, current_data, queue, &printer);
- info->count++;
+ if (search_notify(type, field, &j) )
+ {
+ DEBUGADD(4,("j=[%d]:%s\n", j, notify_info_data_table[j].name));
+ construct_info_data(info_data, type, field, id);
+ DEBUGADD(4,("notify_info_data_table: in\n"));
+ notify_info_data_table[j].fn(snum, info_data, queue, &printer);
+ DEBUGADD(4,("notify_info_data_table: out\n"));
+ info->count++;
+ info_data=&(info->data[info->count]);
+ }
+ }
+ free_a_printer(printer, 2);
}
-
- free_a_printer(printer, 2);
-
- return True;
}
-/*
- * JFM: The enumeration is not that simple, it's even non obvious.
- *
- * let's take an example: I want to monitor the PRINTER SERVER for
- * the printer's name and the number of jobs currently queued.
- * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
- * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
- *
- * I have 3 printers on the back of my server.
- *
- * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
- * structures.
- * Number Data Id
- * 1 printer 1 name 1
- * 2 printer 1 cjob 1
- * 3 printer 2 name 2
- * 4 printer 2 cjob 2
- * 5 printer 3 name 3
- * 6 printer 3 name 3
- *
- * that's the print server case, the printer case is even worse.
- */
-
-
/*******************************************************************
*
@@ -1317,54 +1337,40 @@ static BOOL construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_I
* fill a notify_info struct with info asked
*
********************************************************************/
-static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
+static uint32 printserver_notify_info(const POLICY_HND *hnd,
+ SPOOL_NOTIFY_INFO *info)
{
int snum;
- Printer_entry *Printer=find_printer_index_by_hnd(hnd);
+ PRINT_HND_INFO *pnum=find_printer_index_by_hnd(hnd);
int n_services=lp_numservices();
- int i;
- uint32 id;
- SPOOL_NOTIFY_OPTION *option;
- SPOOL_NOTIFY_OPTION_TYPE *option_type;
-
- DEBUG(4,("printserver_notify_info\n"));
-
- option=Printer->notify.option;
- id=1;
- info->version=2;
- info->data=NULL;
+ int i=0;
+ uint32 id=1;
info->count=0;
- for (i=0; i<option->count; i++)
+ if (INVALID_HANDLE(pnum))
{
- option_type=&(option->ctr.type[i]);
-
- if (option_type->type!=PRINTER_NOTIFY_TYPE)
- continue;
-
- for (snum=0; snum<n_services; snum++)
- if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
- if (construct_notify_printer_info(info, snum, option_type, id))
- id++;
+ return NT_STATUS_INVALID_HANDLE;
}
-
- /*
- * Debugging information, don't delete.
- */
- /*
- DEBUG(1,("dumping the NOTIFY_INFO\n"));
- DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
- DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
-
- for (i=0; i<info->count; i++)
+
+ DEBUG(4,("Enumerating printers\n"));
+
+ for (i=0; i<pnum->number_of_notify; i++)
{
- DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
- i, info->data[i].type, info->data[i].field, info->data[i].reserved,
- info->data[i].id, info->data[i].size, info->data[i].enc_type));
+ if ( pnum->notify_info[i].type == PRINTER_NOTIFY_TYPE )
+ {
+ for (snum=0; snum<n_services; snum++)
+ {
+ if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
+ {
+ construct_notify_printer_info(info, pnum, snum, i, id);
+ id++;
+ }
+ }
+ }
}
- */
-
- return NT_STATUS_NO_PROBLEMO;
+ DEBUG(4,("All printers enumerated\n"));
+
+ return NT_STATUS_NOPROBLEMO;
}
/*******************************************************************
@@ -1372,104 +1378,82 @@ static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *
* fill a notify_info struct with info asked
*
********************************************************************/
-static uint32 printer_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info)
+static uint32 printer_notify_info(const POLICY_HND *hnd,
+ SPOOL_NOTIFY_INFO *info)
{
int snum;
- Printer_entry *Printer=find_printer_index_by_hnd(hnd);
- int i;
- uint32 id;
- SPOOL_NOTIFY_OPTION *option;
- SPOOL_NOTIFY_OPTION_TYPE *option_type;
- int count,j;
- print_queue_struct *queue=NULL;
- print_status_struct status;
+ PRINT_HND_INFO *pnum=find_printer_index_by_hnd(hnd);
+ int i=0, j;
+ uint32 id=0xFFFF;
- DEBUG(4,("printer_notify_info\n"));
-
- option=Printer->notify.option;
- id=1;
- info->version=2;
- info->data=NULL;
info->count=0;
- get_printer_snum(hnd, &snum);
-
- for (i=0; i<option->count; i++)
+ if (INVALID_HANDLE(pnum) || !get_printer_snum(hnd, &snum) )
{
- option_type=&(option->ctr.type[i]);
-
- switch ( option_type->type ) {
- case PRINTER_NOTIFY_TYPE:
- if(construct_notify_printer_info(info, snum, option_type, id))
- id++;
- break;
-
- case JOB_NOTIFY_TYPE:
- memset(&status, 0, sizeof(status));
- count=get_printqueue(snum, NULL, &queue, &status);
- for (j=0; j<count; j++)
- if (construct_notify_jobs_info(&(queue[j]), info, snum, option_type, id))
- id++;
- safe_free(queue);
- break;
- }
+ return NT_STATUS_INVALID_HANDLE;
}
-
- /*
- * Debugging information, don't delete.
- */
- /*
- DEBUG(1,("dumping the NOTIFY_INFO\n"));
- DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
- DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
-
- for (i=0; i<info->count; i++)
+
+ for (i=0; i<pnum->number_of_notify; i++)
{
- DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
- i, info->data[i].type, info->data[i].field, info->data[i].reserved,
- info->data[i].id, info->data[i].size, info->data[i].enc_type));
+ switch ( pnum->notify_info[i].type )
+ {
+ case PRINTER_NOTIFY_TYPE:
+ {
+ construct_notify_printer_info(info, pnum, snum, i, id);
+ id--;
+ break;
+ }
+ case JOB_NOTIFY_TYPE:
+ {
+ int count;
+ print_queue_struct *queue=NULL;
+ print_status_struct status;
+ bzero(&status, sizeof(status));
+ count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &status);
+ for (j=0; j<count; j++)
+ {
+ construct_notify_jobs_info(&(queue[j]), info, pnum, snum, i, queue[j].job);
+ }
+ safe_free(queue);
+ break;
+ }
+ }
}
- */
- return NT_STATUS_NO_PROBLEMO;
+
+ return NT_STATUS_NOPROBLEMO;
}
/********************************************************************
* spoolss_rfnpcnex
********************************************************************/
-uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, uint32 change,
- SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info)
+uint32 _spoolss_rfnpcnex( const POLICY_HND *handle,
+ uint32 change,
+ const SPOOL_NOTIFY_OPTION *option,
+ uint32 *count,
+ SPOOL_NOTIFY_INFO *info)
{
- Printer_entry *Printer=find_printer_index_by_hnd(handle);
+ PRINT_HND_INFO *pnum=find_printer_index_by_hnd(handle);
- if (!OPEN_HANDLE(Printer))
+ if (INVALID_HANDLE(pnum))
+ {
return NT_STATUS_INVALID_HANDLE;
+ }
- DEBUG(4,("Printer type %x\n",Printer->printer_type));
-
- /* jfm: the change value isn't used right now.
- * we will honour it when
- * a) we'll be able to send notification to the client
- * b) we'll have a way to communicate between the spoolss process.
- *
- * same thing for option->flags
- * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
- * I don't have a global notification system, I'm sending back all the
- * informations even when _NOTHING_ has changed.
- */
+ DEBUG(4,("Printer of type %x\n",pnum->printer_type));
- /* just discard the SPOOL_NOTIFY_OPTION */
- if (option!=NULL)
- safe_free(option->ctr.type);
-
- safe_free(option);
+ /* lkxlXXXX - jfm, is this right? put a warning in for you to review! */
+ DEBUG(0,("_spoolss_rfnpcnex: change, option and count ignored\n"));
- switch (Printer->printer_type) {
+ switch (pnum->printer_type)
+ {
case PRINTER_HANDLE_IS_PRINTSERVER:
+ {
return printserver_notify_info(handle, info);
- break;
+ }
case PRINTER_HANDLE_IS_PRINTER:
+ {
return printer_notify_info(handle, info);
- break;
+ }
}
return NT_STATUS_INVALID_INFO_CLASS;
@@ -1487,22 +1471,22 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s
print_queue_struct *queue=NULL;
print_status_struct status;
- memset(&status, 0, sizeof(status));
+ bzero(&status,sizeof(status));
if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
{
return (False);
}
- count=get_printqueue(snum, NULL, &queue, &status);
+ count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &status);
/* the description and the name are of the form \\server\share */
slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter.info_2->printername);
- init_unistr(&(printer->printername), chaine);
+ make_unistr(&(printer->printername), chaine);
slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername);
- init_unistr(&(printer->servername), chaine);
+ make_unistr(&(printer->servername), chaine);
printer->cjobs = count;
printer->attributes = PRINTER_ATTRIBUTE_SHARED \
@@ -1527,7 +1511,7 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s
printer->unknown14 = 0x1;
printer->unknown15 = 0x024a; /*586 Pentium ? */
printer->unknown16 = 0x0;
- printer->unknown17 = 0x423ed444; /* CacheChangeID */
+ printer->unknown17 = 0x423ed444;
printer->unknown18 = 0x0;
printer->status = status.status;
printer->unknown20 = 0x0;
@@ -1545,10 +1529,9 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s
* construct_printer_info_1
* fill a printer_info_1 struct
********************************************************************/
-static BOOL construct_printer_info_1(PRINTER_INFO_1 *printer, int snum, pstring servername)
+static BOOL construct_printer_info_1(PRINTER_INFO_1 *printer,int snum, pstring servername)
{
pstring chaine;
- pstring chaine2;
NT_PRINTER_INFO_LEVEL ntprinter;
if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0)
@@ -1556,23 +1539,21 @@ static BOOL construct_printer_info_1(PRINTER_INFO_1 *printer, int snum, pstring
return (False);
}
- printer->flags=PRINTER_ENUM_ICON8;
+ printer->flags=PRINTER_ENUM_NAME;
/* the description and the name are of the form \\server\share */
-
- snprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s,%s,%s",servername,
+ slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s,%s,%s",servername,
ntprinter.info_2->printername,
ntprinter.info_2->drivername,
lp_comment(snum));
- init_unistr(&(printer->description), chaine);
+ make_unistr(&(printer->description), chaine);
- snprintf(chaine2,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername);
- init_unistr(&(printer->name), chaine2);
+ slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername);
+ make_unistr(&(printer->name), chaine);
- init_unistr(&(printer->comment), lp_comment(snum));
+ make_unistr(&(printer->comment), lp_comment(snum));
free_a_printer(ntprinter, 2);
-
return (True);
}
@@ -1587,8 +1568,8 @@ static void construct_dev_mode(DEVICEMODE *devmode, int snum, char *servername)
DEBUG(7,("construct_dev_mode\n"));
- memset(&(devmode->devicename), 0, 2*sizeof(adevice));
- memset(&(devmode->formname), 0, 2*sizeof(aform));
+ bzero(&(devmode->devicename), 2*sizeof(adevice));
+ bzero(&(devmode->formname), 2*sizeof(aform));
DEBUGADD(8,("getting printer characteristics\n"));
@@ -1598,10 +1579,10 @@ static void construct_dev_mode(DEVICEMODE *devmode, int snum, char *servername)
DEBUGADD(8,("loading DEVICEMODE\n"));
snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname,
printer.info_2->printername);
- init_unistr(&(devmode->devicename), adevice);
+ make_unistr(&(devmode->devicename), adevice);
snprintf(aform, sizeof(aform), ntdevmode->formname);
- init_unistr(&(devmode->formname), aform);
+ make_unistr(&(devmode->formname), aform);
devmode->specversion = ntdevmode->specversion;
devmode->driverversion = ntdevmode->driverversion;
@@ -1649,8 +1630,8 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring
print_queue_struct *queue=NULL;
print_status_struct status;
- memset(&status, 0, sizeof(status));
- count=get_printqueue(snum, NULL, &queue, &status);
+ bzero(&status, sizeof(status));
+ count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &status);
if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 )
{
@@ -1658,22 +1639,22 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring
}
snprintf(chaine, sizeof(chaine)-1, "\\\\%s", servername);
- init_unistr(&(printer->servername), chaine); /* servername*/
+ make_unistr(&(printer->servername), chaine); /* servername*/
snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", servername, ntprinter.info_2->printername);
- init_unistr(&(printer->printername), chaine); /* printername*/
+ make_unistr(&(printer->printername), chaine); /* printername*/
- init_unistr(&(printer->sharename), lp_servicename(snum)); /* sharename */
+ make_unistr(&(printer->sharename), lp_servicename(snum)); /* sharename */
- init_unistr(&(printer->portname), lp_servicename(snum)); /* port */
- init_unistr(&(printer->drivername), ntprinter.info_2->drivername); /* drivername */
+ make_unistr(&(printer->portname), lp_servicename(snum)); /* port */
+ make_unistr(&(printer->drivername), ntprinter.info_2->drivername); /* drivername */
- init_unistr(&(printer->comment), ntprinter.info_2->comment); /* comment */
- init_unistr(&(printer->location), ntprinter.info_2->location); /* location */
- init_unistr(&(printer->sepfile), ntprinter.info_2->sepfile); /* separator file */
- init_unistr(&(printer->printprocessor), ntprinter.info_2->printprocessor);/* print processor */
- init_unistr(&(printer->datatype), ntprinter.info_2->datatype); /* datatype */
- init_unistr(&(printer->parameters), ntprinter.info_2->parameters); /* parameters (of print processor) */
+ make_unistr(&(printer->comment), ntprinter.info_2->comment); /* comment */
+ make_unistr(&(printer->location), ntprinter.info_2->location); /* location */
+ make_unistr(&(printer->sepfile), ntprinter.info_2->sepfile); /* separator file */
+ make_unistr(&(printer->printprocessor), ntprinter.info_2->printprocessor);/* print processor */
+ make_unistr(&(printer->datatype), ntprinter.info_2->datatype); /* datatype */
+ make_unistr(&(printer->parameters), ntprinter.info_2->parameters); /* parameters (of print processor) */
printer->attributes = PRINTER_ATTRIBUTE_SHARED \
| PRINTER_ATTRIBUTE_NETWORK \
@@ -1701,26 +1682,29 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring
* enum_printer_info_1
* glue between spoolss_enumprinters and construct_printer_info_1
********************************************************************/
-static BOOL get_printer_info_1(PRINTER_INFO_1 **printer, int snum, int number)
+static BOOL enum_printer_info_1(PRINTER_INFO_1 **printer, int snum, int number)
{
pstring servername;
*printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1));
DEBUG(4,("Allocated memory for ONE PRINTER_INFO_1 at [%p]\n", *printer));
pstrcpy(servername, global_myname);
- if (!construct_printer_info_1(*printer, snum, servername)) {
+ if (!construct_printer_info_1(*printer, snum, servername))
+ {
free(*printer);
- return False;
+ return (False);
}
else
- return True;
+ {
+ return (True);
+ }
}
/********************************************************************
* enum_printer_info_2
* glue between spoolss_enumprinters and construct_printer_info_2
********************************************************************/
-static BOOL get_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number)
+static BOOL enum_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number)
{
pstring servername;
@@ -1743,100 +1727,26 @@ static BOOL get_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number)
*
* called from api_spoolss_enumprinters (see this to understand)
********************************************************************/
-static BOOL enum_printer_info_1(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static void enum_all_printers_info_1(PRINTER_INFO_1 ***printers, uint32 *number)
{
int snum;
- int i;
int n_services=lp_numservices();
- PRINTER_INFO_1 *printer=NULL;
-DEBUG(1,("enum_printer_info_1\n"));
- for (snum=0; snum<n_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
- DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
-
- /*
- JFM: here we should check the name
-
- */
-
- if (get_printer_info_1(&printer , snum, *returned) )
- (*returned)++;
- }
- }
-
- /* check the required size. */
- for (i=0; i<*returned; i++)
- (*needed) += spoolss_size_printer_info_1(printer);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ *printers=NULL;
+ *number=0;
- /* fill the buffer with the structures */
-
- for (i=0; i<*returned; i++)
- new_smb_io_printer_info_1("", buffer, printer, 0);
-
- /* clear memory */
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/********************************************************************
- Spoolss_enumprinters.
-********************************************************************/
-static BOOL enum_all_printers_info_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
-{
- int snum;
- int i;
- int n_services=lp_numservices();
- PRINTER_INFO_1 *printers=NULL;
- PRINTER_INFO_1 current_prt;
- pstring servername;
-
- DEBUG(4,("enum_all_printers_info_1\n"));
-
- pstrcpy(servername, global_myname);
-
- for (snum=0; snum<n_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
- DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
-
- if (construct_printer_info_1(&current_prt, snum, servername))
- {
- printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1));
- DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
- memcpy(&(printers[*returned]), &current_prt, sizeof(PRINTER_INFO_1));
- (*returned)++;
+ for (snum=0;snum<n_services; snum++)
+ {
+ if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
+ {
+ DEBUG(4,("Found a printer: %s[%x]\n",lp_servicename(snum),snum));
+ *printers=Realloc(*printers, (*number+1)*sizeof(PRINTER_INFO_1 *));
+ DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1 pointers at [%p]\n", *number+1, *printers));
+ if (enum_printer_info_1( &((*printers)[*number]), snum, *number) )
+ {
+ (*number)++;
}
}
}
-
- /* check the required size. */
- for (i=0; i<*returned; i++)
- (*needed) += spoolss_size_printer_info_1(&(printers[i]));
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
-
- /* fill the buffer with the structures */
-
- for (i=0; i<*returned; i++)
- new_smb_io_printer_info_1("", buffer, &(printers[i]), 0);
-
- /* clear memory */
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
}
/********************************************************************
@@ -1844,90 +1754,26 @@ static BOOL enum_all_printers_info_1(NEW_BUFFER *buffer, uint32 offered, uint32
*
* called from api_spoolss_enumprinters (see this to understand)
********************************************************************/
-static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static void enum_all_printers_info_2(PRINTER_INFO_2 ***printers, uint32 *number)
{
int snum;
- int i;
int n_services=lp_numservices();
- PRINTER_INFO_2 **printers=NULL;
+ *printers=NULL;
+ *number=0;
- for (snum=0; snum<n_services; snum++) {
- if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
-
- DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
-
- printers=Realloc(printers, ((*returned)+1)*sizeof(PRINTER_INFO_2 *));
-
- DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2 pointers\n", (*returned)+1));
-
- if (get_printer_info_2( &(printers[*returned]), snum, *returned) )
- (*returned)++;
+ for (snum=0;snum<n_services; snum++)
+ {
+ if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
+ {
+ DEBUG(4,("Found a printer: %s[%x]\n",lp_servicename(snum),snum));
+ *printers=Realloc(*printers, (*number+1)*sizeof(PRINTER_INFO_2 *));
+ DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2 pointers at [%p]\n", *number+1, *printers));
+ if (enum_printer_info_2( &((*printers)[*number]), snum, *number) )
+ {
+ (*number)++;
+ }
}
}
-
- /* check the required size. */
- for (i=0; i<*returned; i++)
- (*needed) += spoolss_size_printer_info_2(printers[i]);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the structures */
- for (i=0; i<*returned; i++)
- new_smb_io_printer_info_2("", buffer, printers[i], 0);
-
- /* clear memory */
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/********************************************************************
- * handle enumeration of printers at level 1
- ********************************************************************/
-static uint32 enumprinters_level1( uint32 flags, fstring name,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
-{
- if (flags && PRINTER_ENUM_NETWORK)
- return enum_all_printers_info_1(buffer, offered, needed, returned);
-
- if (flags && PRINTER_ENUM_NAME) {
- if (*name=='\0')
- return enum_all_printers_info_1(buffer, offered, needed, returned);
- else
- return enum_printer_info_1(name, buffer, offered, needed, returned);
- }
-
- if (flags && PRINTER_ENUM_REMOTE)
- return enum_all_printers_info_1(buffer, offered, needed, returned);
-
-
-}
-
-/********************************************************************
- * handle enumeration of printers at level 2
- ********************************************************************/
-static uint32 enumprinters_level2( uint32 flags, fstring servername,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
-{
- return enum_all_printers_info_2(buffer, offered, needed, returned);
-}
-
-/********************************************************************
- * handle enumeration of printers at level 5
- ********************************************************************/
-static uint32 enumprinters_level5( uint32 flags, fstring servername,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
-{
-/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
- return NT_STATUS_NO_PROBLEMO;
}
/********************************************************************
@@ -1935,167 +1781,118 @@ static uint32 enumprinters_level5( uint32 flags, fstring servername,
*
* called from api_spoolss_enumprinters (see this to understand)
********************************************************************/
-uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
-{
- fstring name;
-
- DEBUG(4,("_spoolss_enumprinters\n"));
-
- *needed=0;
- *returned=0;
-
- /*
- * Level 1:
- * flags==PRINTER_ENUM_NAME
- * if name=="" then enumerates all printers
- * if name!="" then enumerate the printer
- * flags==PRINTER_ENUM_REMOTE
- * name is NULL, enumerate printers
- * Level 2: name!="" enumerates printers, name can't be NULL
- * Level 3: doesn't exist
- * Level 4: does a local registry lookup
- * Level 5: same as Level 2
- */
-
- unistr2_to_ascii(name, servername, sizeof(name)-1);
-
- switch (level) {
- case 1:
- return enumprinters_level1(flags, name, buffer, offered, needed, returned);
- break;
- case 2:
- return enumprinters_level2(flags, name, buffer, offered, needed, returned);
- break;
- case 5:
- return enumprinters_level5(flags, name, buffer, offered, needed, returned);
- break;
- case 3:
- case 4:
- default:
- return NT_STATUS_INVALID_LEVEL;
- break;
- }
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 getprinter_level_0(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- PRINTER_INFO_0 *printer=NULL;
-
- printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0));
- construct_printer_info_0(printer, snum, servername);
-
- /* check the required size. */
- *needed += spoolss_size_printer_info_0(printer);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the structures */
- new_smb_io_printer_info_0("", buffer, printer, 0);
-
- /* clear memory */
- safe_free(printer);
-
- if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 getprinter_level_1(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+uint32 _spoolss_enumprinters(
+ uint32 flags,
+ const UNISTR2 *servername,
+ uint32 level,
+ const BUFFER *buffer,
+ uint32 buf_size,
+ uint32 *offered,
+ uint32 *needed,
+ PRINTER_INFO_CTR *ctr,
+ uint32 *returned)
{
- PRINTER_INFO_1 *printer=NULL;
-
- printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1));
- construct_printer_info_1(printer, snum, servername);
-
- /* check the required size. */
- *needed += spoolss_size_printer_info_1(printer);
+ DEBUG(4,("Enumerating printers\n"));
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the structures */
- new_smb_io_printer_info_1("", buffer, printer, 0);
-
- /* clear memory */
- safe_free(printer);
+ (*returned)=0;
- if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
+ switch (level)
+ {
+ case 1:
+ if (flags == PRINTER_ENUM_NAME ||
+ flags == PRINTER_ENUM_NETWORK )
+ {
+ /*if (is_a_printerserver(servername))*/
+ enum_all_printers_info_1(&ctr->printer.printers_1, returned );
+ /*else
+ enum_one_printer_info_1(&r_u);*/
+ break;
+ }
+ case 2:
+ if (flags == PRINTER_ENUM_NAME ||
+ flags == PRINTER_ENUM_NETWORK )
+ {
+ /*if (is_a_printerserver(servername))*/
+ enum_all_printers_info_2(&ctr->printer.printers_2, returned );
+ /*else
+ enum_one_printer_info_2(&r_u);*/
+ break;
+ }
+ case 3: /* doesn't exist */
+ return NT_STATUS_INVALID_INFO_CLASS;
+ case 4: /* can't, always on local machine */
+ break;
+ case 5:
+ return NT_STATUS_INVALID_INFO_CLASS;
+
}
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 getprinter_level_2(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- PRINTER_INFO_2 *printer=NULL;
-
- printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2));
- construct_printer_info_2(printer, snum, servername);
-
- /* check the required size. */
- *needed += spoolss_size_printer_info_2(printer);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ DEBUG(4,("%d printers enumerated\n", *returned));
+ (*offered) = buffer->size;
- /* fill the buffer with the structures */
- new_smb_io_printer_info_2("", buffer, printer, 0);
-
- /* clear memory */
- safe_free(printer);
-
- if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
- NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+uint32 _spoolss_getprinter( POLICY_HND *handle,
+ uint32 level,
+ PRINTER_INFO *ctr,
+ uint32 *offered,
+ uint32 *needed)
{
int snum;
pstring servername;
- *needed=0;
-
pstrcpy(servername, global_myname);
- if (!get_printer_snum(handle, &snum))
+ if (!get_printer_snum(handle,&snum))
{
return NT_STATUS_INVALID_HANDLE;
}
- switch (level) {
- case 0:
- return getprinter_level_0(servername, snum, buffer, offered, needed);
- break;
- case 1:
- return getprinter_level_1(servername,snum, buffer, offered, needed);
- break;
- case 2:
- return getprinter_level_2(servername,snum, buffer, offered, needed);
- break;
- default:
- return NT_STATUS_INVALID_LEVEL;
- break;
+ DEBUG(0,("_spoolss_getprinter: offered and needed params ignored\n"));
+
+ switch (level)
+ {
+ case 0:
+ {
+ PRINTER_INFO_0 *printer;
+
+ printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0));
+ construct_printer_info_0(printer, snum, servername);
+ ctr->printer.info0=printer;
+
+ return NT_STATUS_NOPROBLEMO;
+ }
+ case 1:
+ {
+ PRINTER_INFO_1 *printer;
+
+ printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1));
+ construct_printer_info_1(printer, snum, servername);
+ ctr->printer.info1=printer;
+
+ return NT_STATUS_NOPROBLEMO;
+ }
+ case 2:
+ {
+ PRINTER_INFO_2 *printer;
+
+ printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2));
+ construct_printer_info_2(printer, snum, servername);
+ ctr->printer.info2=printer;
+
+ return NT_STATUS_NOPROBLEMO;
+ }
+ default:
+ {
+ break;
+ }
}
-}
-
+
+ return NT_STATUS_INVALID_INFO_CLASS;
+}
+
/********************************************************************
* construct_printer_driver_info_1
* fill a construct_printer_driver_info_1 struct
@@ -2104,7 +1901,7 @@ static void fill_printer_driver_info_1(DRIVER_INFO_1 *info,
NT_PRINTER_DRIVER_INFO_LEVEL driver,
pstring servername, fstring architecture)
{
- init_unistr( &(info->name), driver.info_3->name);
+ make_unistr( &(info->name), driver.info_3->name);
}
static void construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum,
@@ -2142,20 +1939,20 @@ static void fill_printer_driver_info_2(DRIVER_INFO_2 *info,
info->version=driver.info_3->cversion;
- init_unistr( &(info->name), driver.info_3->name );
- init_unistr( &(info->architecture), architecture );
+ make_unistr( &(info->name), driver.info_3->name );
+ make_unistr( &(info->architecture), architecture );
snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where,
driver.info_3->driverpath);
- init_unistr( &(info->driverpath), temp_driverpath );
+ make_unistr( &(info->driverpath), temp_driverpath );
snprintf(temp_datafile, sizeof(temp_datafile)-1, "%s%s", where,
driver.info_3->datafile);
- init_unistr( &(info->datafile), temp_datafile );
+ make_unistr( &(info->datafile), temp_datafile );
snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where,
driver.info_3->configfile);
- init_unistr( &(info->configfile), temp_configfile );
+ make_unistr( &(info->configfile), temp_configfile );
}
/********************************************************************
@@ -2180,13 +1977,13 @@ static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum,
/********************************************************************
* copy a strings array and convert to UNICODE
********************************************************************/
-static void init_unistr_array(UNISTR ***uni_array, char **char_array, char *where)
+static void make_unistr_array(UNISTR ***uni_array, char **char_array, char *where)
{
int i=0;
char *v;
pstring line;
- DEBUG(6,("init_unistr_array\n"));
+ DEBUG(6,("make_unistr_array\n"));
for (v=char_array[i]; *v!='\0'; v=char_array[i])
{
@@ -2200,7 +1997,7 @@ static void init_unistr_array(UNISTR ***uni_array, char **char_array, char *wher
DEBUGADD(7,("alloc:[%p],", (*uni_array)[i]));
snprintf(line, sizeof(line)-1, "%s%s", where, v);
- init_unistr( (*uni_array)[i], line );
+ make_unistr( (*uni_array)[i], line );
DEBUGADD(7,("copy\n"));
i++;
@@ -2233,26 +2030,26 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info,
info->version=driver.info_3->cversion;
- init_unistr( &(info->name), driver.info_3->name );
- init_unistr( &(info->architecture), architecture );
+ make_unistr( &(info->name), driver.info_3->name );
+ make_unistr( &(info->architecture), architecture );
snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, driver.info_3->driverpath);
- init_unistr( &(info->driverpath), temp_driverpath );
+ make_unistr( &(info->driverpath), temp_driverpath );
snprintf(temp_datafile, sizeof(temp_datafile)-1, "%s%s", where, driver.info_3->datafile);
- init_unistr( &(info->datafile), temp_datafile );
+ make_unistr( &(info->datafile), temp_datafile );
snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where, driver.info_3->configfile);
- init_unistr( &(info->configfile), temp_configfile );
+ make_unistr( &(info->configfile), temp_configfile );
snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "%s%s", where, driver.info_3->helpfile);
- init_unistr( &(info->helpfile), temp_helpfile );
+ make_unistr( &(info->helpfile), temp_helpfile );
- init_unistr( &(info->monitorname), driver.info_3->monitorname );
- init_unistr( &(info->defaultdatatype), driver.info_3->defaultdatatype );
+ make_unistr( &(info->monitorname), driver.info_3->monitorname );
+ make_unistr( &(info->defaultdatatype), driver.info_3->defaultdatatype );
info->dependentfiles=NULL;
- init_unistr_array(&(info->dependentfiles), driver.info_3->dependentfiles, where);
+ make_unistr_array(&(info->dependentfiles), driver.info_3->dependentfiles, where);
}
/********************************************************************
@@ -2276,162 +2073,95 @@ static void construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum,
/****************************************************************************
****************************************************************************/
-static uint32 getprinterdriver2_level1(pstring servername, pstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- DRIVER_INFO_1 *info=NULL;
-
- info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1));
-
- construct_printer_driver_info_1(info, snum, servername, architecture);
-
- /* check the required size. */
- *needed += spoolss_size_printer_driver_info_1(info);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the structures */
- new_smb_io_printer_driver_info_1("", buffer, info, 0);
-
- /* clear memory */
- safe_free(info);
-
- if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 getprinterdriver2_level2(pstring servername, pstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- DRIVER_INFO_2 *info=NULL;
-
- info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2));
-
- construct_printer_driver_info_2(info, snum, servername, architecture);
-
- /* check the required size. */
- *needed += spoolss_size_printer_driver_info_2(info);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the structures */
- new_smb_io_printer_driver_info_2("", buffer, info, 0);
-
- /* clear memory */
- safe_free(info);
-
- if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 getprinterdriver2_level3(pstring servername, pstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- DRIVER_INFO_3 *info=NULL;
-
- info=(DRIVER_INFO_3 *)malloc(sizeof(DRIVER_INFO_3));
-
- construct_printer_driver_info_3(info, snum, servername, architecture);
-
- /* check the required size. */
- *needed += spoolss_size_printer_driver_info_3(info);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the structures */
- new_smb_io_printer_driver_info_3("", buffer, info, 0);
-
- /* clear memory */
- safe_free(info);
-
- if (*needed > offered) {
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
-****************************************************************************/
-uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, uint32 unknown,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *unknown0, uint32 *unknown1)
+uint32 _spoolss_getprinterdriver2( const POLICY_HND *handle,
+ const UNISTR2 *uni_arch,
+ uint32 level,
+ DRIVER_INFO *ctr,
+ uint32 *offered,
+ uint32 *needed)
{
pstring servername;
fstring architecture;
int snum;
-
- DEBUG(4,("_spoolss_getprinterdriver2\n"));
-
- *needed=0;
- *unknown0=0;
- *unknown1=0;
+ DRIVER_INFO_1 *info1=NULL;
+ DRIVER_INFO_2 *info2=NULL;
+ DRIVER_INFO_3 *info3=NULL;
pstrcpy(servername, global_myname);
- unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
- if (!get_printer_snum(handle, &snum))
+ if (!get_printer_snum(handle,&snum))
{
return NT_STATUS_INVALID_HANDLE;
}
- switch (level) {
- case 1:
- return getprinterdriver2_level1(servername, architecture, snum, buffer, offered, needed);
- break;
- case 2:
- return getprinterdriver2_level2(servername, architecture, snum, buffer, offered, needed);
- break;
- case 3:
- return getprinterdriver2_level3(servername, architecture, snum, buffer, offered, needed);
- break;
- default:
- return NT_STATUS_INVALID_LEVEL;
- break;
+ unistr2_to_ascii(architecture, uni_arch, sizeof(architecture) );
+
+ DEBUG(1,("spoolss_getprinterdriver2:[%d]\n", level));
+
+ switch (level)
+ {
+ case 1:
+ {
+ info1=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1));
+ construct_printer_driver_info_1(info1, snum, servername, architecture);
+ ctr->driver.info1=info1;
+
+ return NT_STATUS_NOPROBLEMO;
+ }
+ case 2:
+ {
+ info2=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2));
+ construct_printer_driver_info_2(info2, snum, servername, architecture);
+ ctr->driver.info2=info2;
+
+ return NT_STATUS_NOPROBLEMO;
+ }
+ case 3:
+ {
+ info3=(DRIVER_INFO_3 *)malloc(sizeof(DRIVER_INFO_3));
+ construct_printer_driver_info_3(info3, snum, servername, architecture);
+ ctr->driver.info3=info3;
+
+ return NT_STATUS_NOPROBLEMO;
+ }
+ default:
+ {
+ break;
+ }
}
+ return NT_STATUS_INVALID_INFO_CLASS;
}
/****************************************************************************
****************************************************************************/
uint32 _spoolss_startpageprinter(const POLICY_HND *handle)
{
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
+ PRINT_HND_INFO *pnum = find_printer_index_by_hnd(handle);
- if (OPEN_HANDLE(Printer))
+ if (INVALID_HANDLE(pnum))
{
- Printer->page_started=True;
- return 0x0;
+ DEBUG(3,("Error in startpageprinter printer handle\n"));
+ return NT_STATUS_INVALID_HANDLE;
}
- DEBUG(3,("Error in startpageprinter printer handle\n"));
- return NT_STATUS_INVALID_HANDLE;
+ pnum->page_started=True;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
****************************************************************************/
uint32 _spoolss_endpageprinter(const POLICY_HND *handle)
{
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
+ PRINT_HND_INFO *pnum = find_printer_index_by_hnd(handle);
- if (!OPEN_HANDLE(Printer))
+ if (INVALID_HANDLE(pnum))
{
DEBUG(3,("Error in endpageprinter printer handle\n"));
return NT_STATUS_INVALID_HANDLE;
}
-
- Printer->page_started=False;
- return NT_STATUS_NO_PROBLEMO;
+ pnum->page_started=False;
+ return NT_STATUS_NOPROBLEMO;
}
@@ -2450,9 +2180,11 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level,
pstring datatype;
int fd = -1;
int snum;
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
+ PRINT_HND_INFO *pnum;
+
+ pnum = find_printer_index_by_hnd(handle);
- if (!OPEN_HANDLE(Printer))
+ if (INVALID_HANDLE(pnum))
{
return NT_STATUS_INVALID_HANDLE;
}
@@ -2495,16 +2227,18 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level,
fd=open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR );
DEBUG(4,("Temp spool file created: [%s]\n", fname));
- Printer->current_jobid=fd;
- pstrcpy(Printer->document_name, fname);
+ pnum->current_jobid=fd;
+ pstrcpy(pnum->document_name,fname);
- unistr2_to_ascii(Printer->job_name, &info_1->docname, sizeof(Printer->job_name));
+ unistr2_to_ascii(pnum->job_name,
+ &info_1->docname,
+ sizeof(pnum->job_name));
- Printer->document_fd=fd;
- Printer->document_started=True;
- (*jobid) = Printer->current_jobid;
+ pnum->document_fd=fd;
+ pnum->document_started=True;
+ (*jobid) = pnum->current_jobid;
- return 0x0;
+ return NT_STATUS_NOPROBLEMO;
}
/********************************************************************
@@ -2514,28 +2248,29 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level,
********************************************************************/
uint32 _spoolss_enddocprinter(const POLICY_HND *handle)
{
+ PRINT_HND_INFO *pnum;
int snum;
pstring filename;
pstring filename1;
pstring job_name;
pstring syscmd;
char *tstr;
- Printer_entry *Printer=find_printer_index_by_hnd(handle);
*syscmd=0;
- if (!OPEN_HANDLE(Printer))
+ pnum = find_printer_index_by_hnd(handle);
+
+ if (INVALID_HANDLE(pnum))
{
DEBUG(3,("Error in enddocprinter handle\n"));
return NT_STATUS_INVALID_HANDLE;
}
-
- Printer->document_started=False;
- close(Printer->document_fd);
+ pnum->document_started=False;
+ close(pnum->document_fd);
DEBUG(4,("Temp spool file closed, printing now ...\n"));
- pstrcpy(filename1, Printer->document_name);
- pstrcpy(job_name, Printer->job_name);
+ pstrcpy(filename1, pnum->document_name);
+ pstrcpy(job_name, pnum->job_name);
if (!get_printer_snum(handle,&snum))
{
@@ -2554,10 +2289,10 @@ uint32 _spoolss_enddocprinter(const POLICY_HND *handle)
if (strstr(syscmd,"%s"))
{
pstrcpy(filename,filename1);
- pstring_sub(syscmd, "%s", filename);
+ string_sub(syscmd, "%s", filename);
}
- pstring_sub(syscmd, "%f", filename1);
+ string_sub(syscmd, "%f", filename1);
/* Does the service have a printername? If not, make a fake and empty
* printer name. That way a %p is treated sanely if no printer
@@ -2571,10 +2306,10 @@ uint32 _spoolss_enddocprinter(const POLICY_HND *handle)
tstr = SERVICE(snum);
}
- pstring_sub(syscmd, "%p", tstr);
+ string_sub(syscmd, "%p", tstr);
/* If the lpr command support the 'Job' option replace here */
- pstring_sub(syscmd, "%j", job_name);
+ string_sub(syscmd, "%j", job_name);
if ( *syscmd != '\0')
{
@@ -2595,7 +2330,7 @@ uint32 _spoolss_enddocprinter(const POLICY_HND *handle)
lpq_reset(snum);
- return 0x0;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
@@ -2605,20 +2340,22 @@ uint32 _spoolss_writeprinter( const POLICY_HND *handle,
const uint8 *buffer,
uint32 *buffer_written)
{
+ PRINT_HND_INFO *pnum;
int fd;
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
- if (!OPEN_HANDLE(Printer))
+ pnum = find_printer_index_by_hnd(handle);
+
+ if (INVALID_HANDLE(pnum))
{
DEBUG(3,("Error in writeprinter handle\n"));
return NT_STATUS_INVALID_HANDLE;
}
- fd = Printer->document_fd;
+ fd = pnum->document_fd;
(*buffer_written) = write(fd, buffer, buffer_size);
- Printer->document_lastwritten = (*buffer_written);
+ pnum->document_lastwritten = (*buffer_written);
- return 0x0;
+ return NT_STATUS_NOPROBLEMO;
}
/********************************************************************
@@ -2628,36 +2365,27 @@ uint32 _spoolss_writeprinter( const POLICY_HND *handle,
********************************************************************/
static uint32 control_printer(const POLICY_HND *handle, uint32 command)
{
+ PRINT_HND_INFO *pnum;
int snum;
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
-
- if (!OPEN_HANDLE(Printer))
- return NT_STATUS_INVALID_HANDLE;
+ pnum = find_printer_index_by_hnd(handle);
- if (!get_printer_snum(handle, &snum) )
+ if ( INVALID_HANDLE(pnum) || !get_printer_snum(handle, &snum) )
+ {
return NT_STATUS_INVALID_HANDLE;
+ }
- switch (command) {
+ switch (command)
+ {
case PRINTER_CONTROL_PAUSE:
/* pause the printer here */
- status_printqueue(NULL, snum, LPSTAT_STOPPED);
- return 0x0;
- break;
+ return status_printqueue(NULL, UID_FIELD_INVALID, snum, LPSTAT_STOPPED);
+
case PRINTER_CONTROL_RESUME:
case PRINTER_CONTROL_UNPAUSE:
/* UN-pause the printer here */
- status_printqueue(NULL, snum, LPSTAT_OK);
- return 0x0;
- break;
+ return status_printqueue(NULL, UID_FIELD_INVALID, snum, LPSTAT_OK);
case PRINTER_CONTROL_PURGE:
- /*
- * It's not handled by samba
- * we need a smb.conf param to do
- * lprm -P%p - on BSD
- * lprm -P%p all on LPRNG
- * I don't know on SysV
- * we could do it by looping in the job's list...
- */
+ /* Envoi des dragées FUCA dans l'imprimante */
break;
}
@@ -2672,34 +2400,35 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level,
const SPOOL_PRINTER_INFO_LEVEL *info,
const DEVICEMODE *devmode)
{
+ PRINT_HND_INFO *pnum;
int snum;
NT_PRINTER_INFO_LEVEL printer;
NT_DEVICEMODE *nt_devmode;
- uint32 status = 0x0;
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
+ uint32 status = NT_STATUS_NOPROBLEMO;
nt_devmode=NULL;
DEBUG(8,("update_printer\n"));
- if (level!=2) {
- DEBUG(0,("Send a mail to jfm@samba.org\n"));
+ if (level!=2)
+ {
+ DEBUG(0,("Send a mail to samba-bugs@samba.org\n"));
DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
return NT_STATUS_INVALID_INFO_CLASS;
}
- if (!OPEN_HANDLE(Printer))
- return NT_STATUS_INVALID_HANDLE;
-
- if (!get_printer_snum(handle, &snum) )
+ pnum = find_printer_index_by_hnd(handle);
+ if ( INVALID_HANDLE(pnum) || !get_printer_snum(handle, &snum) )
+ {
return NT_STATUS_INVALID_HANDLE;
-
- get_a_printer(&printer, 2, lp_servicename(snum));
+ }
+ get_a_printer(&printer, level, lp_servicename(snum));
DEBUGADD(8,("Converting info_2 struct\n"));
convert_printer_info(info, &printer, level);
- if ((info->info_2)->devmode_ptr != 0) {
+ if ((info->info_2)->devmode_ptr != 0)
+ {
/* we have a valid devmode
convert it and link it*/
@@ -2715,44 +2444,48 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level,
convert_devicemode(*devmode, nt_devmode);
}
- else {
+ else
+ {
if (printer.info_2->devmode != NULL)
+ {
free(printer.info_2->devmode);
+ }
printer.info_2->devmode=NULL;
}
- if (add_a_printer(printer, 2)!=0) {
- free_a_printer(printer, 2);
-
- /* I don't really know what to return here !!! */
- return NT_STATUS_INVALID_INFO_CLASS;
+ if (status == 0x0)
+ {
+ status = add_a_printer(printer, level);
+ }
+ if (status == 0x0)
+ {
+ status = free_a_printer(printer, level);
}
- free_a_printer(printer, 2);
-
- return NT_STATUS_NO_PROBLEMO;
+ return status;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level,
- const SPOOL_PRINTER_INFO_LEVEL *info,
- const DEVMODE_CTR devmode_ctr,
- uint32 command)
+uint32 _spoolss_setprinter( const POLICY_HND *handle,
+ uint32 level,
+ const SPOOL_PRINTER_INFO_LEVEL *info,
+ const DEVICEMODE *devmode,
+ uint32 sec_buf_size,
+ const char *sec_buf,
+ uint32 command)
{
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
+ PRINT_HND_INFO *pnum = find_printer_index_by_hnd(handle);
- if (!OPEN_HANDLE(Printer))
+ if (INVALID_HANDLE(pnum))
+ {
return NT_STATUS_INVALID_HANDLE;
-
+ }
/* check the level */
- switch (level) {
- case 0:
- return control_printer(handle, command);
- break;
- case 2:
- return update_printer(handle, level, info, devmode_ctr.devmode);
- break;
+ switch (level)
+ {
+ case 0: return control_printer(handle, command);
+ case 2: return update_printer(handle, level, info, devmode);
}
return NT_STATUS_INVALID_INFO_CLASS;
@@ -2760,29 +2493,18 @@ uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level,
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_fcpn(const POLICY_HND *handle)
+uint32 _spoolss_fcpn( const POLICY_HND *handle)
{
- Printer_entry *Printer= find_printer_index_by_hnd(handle);
-
- if (!OPEN_HANDLE(Printer))
- return NT_STATUS_INVALID_HANDLE;
-
- Printer->notify.flags=0;
- Printer->notify.options=0;
- Printer->notify.localmachine[0]='\0';
- Printer->notify.printerlocal=0;
- safe_free(Printer->notify.option);
- Printer->notify.option=NULL;
-
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_addjob(const POLICY_HND *handle, uint32 level,
- NEW_BUFFER *buffer, uint32 offered)
+uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level,
+ const BUFFER *buffer,
+ uint32 buf_size)
{
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
@@ -2799,12 +2521,12 @@ static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname);
job_info->jobid=queue->job;
- init_unistr(&(job_info->printername), lp_servicename(snum));
- init_unistr(&(job_info->machinename), temp_name);
- init_unistr(&(job_info->username), queue->user);
- init_unistr(&(job_info->document), queue->file);
- init_unistr(&(job_info->datatype), "RAW");
- init_unistr(&(job_info->text_status), "");
+ make_unistr(&(job_info->printername), lp_servicename(snum));
+ make_unistr(&(job_info->machinename), temp_name);
+ make_unistr(&(job_info->username), queue->user);
+ make_unistr(&(job_info->document), queue->file);
+ make_unistr(&(job_info->datatype), "RAW");
+ make_unistr(&(job_info->text_status), "");
job_info->status=queue->status;
job_info->priority=queue->priority;
job_info->position=position;
@@ -2838,16 +2560,16 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
job_info->jobid=queue->job;
snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter.info_2->printername);
- init_unistr(&(job_info->printername), chaine);
+ make_unistr(&(job_info->printername), chaine);
- init_unistr(&(job_info->machinename), temp_name);
- init_unistr(&(job_info->username), queue->user);
- init_unistr(&(job_info->document), queue->file);
- init_unistr(&(job_info->notifyname), queue->user);
- init_unistr(&(job_info->datatype), "RAW");
- init_unistr(&(job_info->printprocessor), "winprint");
- init_unistr(&(job_info->parameters), "");
- init_unistr(&(job_info->text_status), "");
+ make_unistr(&(job_info->machinename), temp_name);
+ make_unistr(&(job_info->username), queue->user);
+ make_unistr(&(job_info->document), queue->file);
+ make_unistr(&(job_info->notifyname), queue->user);
+ make_unistr(&(job_info->datatype), "RAW");
+ make_unistr(&(job_info->printprocessor), "winprint");
+ make_unistr(&(job_info->parameters), "");
+ make_unistr(&(job_info->text_status), "");
/* and here the security descriptor */
@@ -2872,131 +2594,82 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
}
/****************************************************************************
- Enumjobs at level 1.
****************************************************************************/
-static uint32 enumjobs_level1(print_queue_struct *queue, int snum,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
-{
- JOB_INFO_1 *info;
- int i;
-
- info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
-
- for (i=0; i<*returned; i++)
- {
- fill_job_info_1(&(info[i]), &(queue[i]), i, snum);
- }
-
- /* check the required size. */
- for (i=0; i<*returned; i++)
- (*needed) += spoolss_size_job_info_1(&(info[i]));
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the structures */
- for (i=0; i<*returned; i++)
- new_smb_io_job_info_1("", buffer, &(info[i]), 0);
-
- /* clear memory */
- safe_free(queue);
- safe_free(info);
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
- Enumjobs at level 2.
-****************************************************************************/
-static uint32 enumjobs_level2(print_queue_struct *queue, int snum,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
+uint32 _spoolss_enumjobs( const POLICY_HND *handle,
+ uint32 reqfirstjob,
+ uint32 reqnumofjobs,
+ uint32 level,
+ JOB_INFO_CTR *ctr,
+ uint32 *buf_size,
+ uint32 *numofjobs)
{
- JOB_INFO_2 *info;
- int i;
-
- info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
-
- for (i=0; i<*returned; i++)
- {
- fill_job_info_2(&(info[i]), &(queue[i]), i, snum);
- }
-
- /* check the required size. */
- for (i=0; i<*returned; i++)
- (*needed) += spoolss_size_job_info_2(&(info[i]));
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the structures */
- for (i=0; i<*returned; i++)
- new_smb_io_job_info_2("", buffer, &(info[i]), 0);
-
- /* clear memory */
- safe_free(queue);
- safe_free(info);
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
- Enumjobs.
-****************************************************************************/
-uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
-{
int snum;
+ int count;
+ int i;
print_queue_struct *queue=NULL;
print_status_struct prt_status;
- DEBUG(4,("_spoolss_enumjobs\n"));
-
+ DEBUG(4,("spoolss_enumjobs\n"));
+
ZERO_STRUCT(prt_status);
- *needed=0;
- *returned=0;
-
if (!get_printer_snum(handle, &snum))
{
return NT_STATUS_INVALID_HANDLE;
}
- *returned = get_printqueue(snum, NULL, &queue, &prt_status);
- DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
-
- switch (level) {
- case 1:
- return enumjobs_level1(queue, snum, buffer, offered, needed, returned);
- break;
- case 2:
- return enumjobs_level2(queue, snum, buffer, offered, needed, returned);
- break;
- default:
- return NT_STATUS_INVALID_LEVEL;
- break;
+ count = get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &prt_status);
+ (*numofjobs) = 0;
+
+ DEBUG(4,("count:[%d], status:[%d], [%s]\n",
+ count, prt_status.status, prt_status.message));
+
+ switch (level)
+ {
+ case 1:
+ {
+ for (i=0; i<count; i++)
+ {
+ JOB_INFO_1 *job_info_1;
+ job_info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
+ add_job1_to_array(numofjobs,
+ &ctr->job.job_info_1,
+ job_info_1);
+
+ fill_job_info_1(ctr->job.job_info_1[i],
+ &(queue[i]), i, snum);
+ }
+ safe_free(queue);
+ return NT_STATUS_NOPROBLEMO;
+ }
+ case 2:
+ {
+ for (i=0; i<count; i++)
+ {
+ JOB_INFO_2 *job_info_2;
+ job_info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
+ add_job2_to_array(numofjobs,
+ &ctr->job.job_info_2,
+ job_info_2);
+
+ fill_job_info_2(ctr->job.job_info_2[i],
+ &(queue[i]), i, snum);
+ }
+ safe_free(queue);
+ return NT_STATUS_NOPROBLEMO;
+ }
}
-}
+ safe_free(queue);
+ return NT_STATUS_INVALID_INFO_CLASS;
+}
/****************************************************************************
****************************************************************************/
uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid)
{
- return 0x0;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
@@ -3015,14 +2688,14 @@ uint32 _spoolss_setjob( const POLICY_HND *handle,
BOOL found=False;
int count;
- memset(&prt_status, 0, sizeof(prt_status));
+ bzero(&prt_status,sizeof(prt_status));
if (!get_printer_snum(handle, &snum))
{
return NT_STATUS_INVALID_HANDLE;
}
- count=get_printqueue(snum, NULL, &queue, &prt_status);
+ count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &prt_status);
while ( (i<count) && found==False )
{
@@ -3040,21 +2713,21 @@ uint32 _spoolss_setjob( const POLICY_HND *handle,
case JOB_CONTROL_CANCEL:
case JOB_CONTROL_DELETE:
{
- del_printqueue(NULL, snum, jobid);
+ del_printqueue(NULL, UID_FIELD_INVALID, snum, jobid);
safe_free(queue);
- return 0x0;
+ return NT_STATUS_NOPROBLEMO;
}
case JOB_CONTROL_PAUSE:
{
- status_printjob(NULL, snum, jobid, LPQ_PAUSED);
+ status_printjob(NULL, UID_FIELD_INVALID, snum, jobid, LPQ_PAUSED);
safe_free(queue);
- return 0x0;
+ return NT_STATUS_NOPROBLEMO;
}
case JOB_CONTROL_RESUME:
{
- status_printjob(NULL, snum, jobid, LPQ_QUEUED);
+ status_printjob(NULL, UID_FIELD_INVALID, snum, jobid, LPQ_QUEUED);
safe_free(queue);
- return 0x0;
+ return NT_STATUS_NOPROBLEMO;
}
}
}
@@ -3064,166 +2737,86 @@ uint32 _spoolss_setjob( const POLICY_HND *handle,
}
/****************************************************************************
- Enumerates all printer drivers at level 1.
****************************************************************************/
-static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+uint32 _spoolss_enumprinterdrivers( const UNISTR2 *name,
+ const UNISTR2 *environment,
+ uint32 level,
+ DRIVER_INFO *ctr,
+ uint32 *offered,
+ uint32 *numofdrivers)
{
- int i;
NT_PRINTER_DRIVER_INFO_LEVEL driver;
- DRIVER_INFO_1 *driver_info_1=NULL;
- driver_info_1=(DRIVER_INFO_1 *)malloc(*returned * sizeof(DRIVER_INFO_1));
-
- for (i=0; i<*returned; i++) {
- get_a_printer_driver(&driver, 3, list[i], architecture);
- fill_printer_driver_info_1(&(driver_info_1[i]), driver, servername, architecture );
- free_a_printer_driver(driver, 3);
- }
-
- /* check the required size. */
- for (i=0; i<*returned; i++)
- {
- DEBUGADD(6,("adding driver [%d]'s size\n",i));
- *needed += spoolss_size_printer_driver_info_1(&(driver_info_1[i]));
- }
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the form structures */
- for (i=0; i<*returned; i++)
- {
- DEBUGADD(6,("adding driver [%d] to buffer\n",i));
- new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0);
- }
-
- safe_free(list);
-
- if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
- Enumerates all printer drivers at level 2.
-****************************************************************************/
-static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
-{
+ int count;
int i;
- NT_PRINTER_DRIVER_INFO_LEVEL driver;
- DRIVER_INFO_2 *driver_info_2=NULL;
- driver_info_2=(DRIVER_INFO_2 *)malloc(*returned * sizeof(DRIVER_INFO_2));
+ fstring *list;
+ fstring servername;
+ fstring architecture;
- for (i=0; i<*returned; i++) {
- get_a_printer_driver(&driver, 3, list[i], architecture);
- fill_printer_driver_info_2(&(driver_info_2[i]), driver, servername, architecture );
- free_a_printer_driver(driver, 3);
- }
-
- /* check the required size. */
- for (i=0; i<*returned; i++)
- {
- DEBUGADD(6,("adding driver [%d]'s size\n",i));
- *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
- }
+ DEBUG(4,("spoolss_enumdrivers\n"));
+ fstrcpy(servername, global_myname);
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ unistr2_to_ascii(architecture, environment, sizeof(architecture));
+ count=get_ntdrivers(&list, architecture);
- /* fill the buffer with the form structures */
- for (i=0; i<*returned; i++)
+ DEBUGADD(4,("we have: [%d] drivers on archi [%s]\n",count, architecture));
+ for (i=0; i<count; i++)
{
- DEBUGADD(6,("adding driver [%d] to buffer\n",i));
- new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
- }
-
- safe_free(list);
-
- if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
- Enumerates all printer drivers at level 3.
-****************************************************************************/
-static uint32 enumprinterdrivers_level3(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
-{
- int i;
- NT_PRINTER_DRIVER_INFO_LEVEL driver;
- DRIVER_INFO_3 *driver_info_3=NULL;
- driver_info_3=(DRIVER_INFO_3 *)malloc((*returned)*sizeof(DRIVER_INFO_3));
-
- for (i=0; i<*returned; i++) {
- get_a_printer_driver(&driver, 3, list[i], architecture);
- fill_printer_driver_info_3(&(driver_info_3[i]), driver, servername, architecture );
- free_a_printer_driver(driver, 3);
+ DEBUGADD(5,("driver [%s]\n",list[i]));
}
- /* check the required size. */
- for (i=0; i<*returned; i++)
+ (*numofdrivers)=count;
+
+ switch (level)
{
- DEBUGADD(6,("adding driver [%d]'s size\n",i));
- *needed += spoolss_size_printer_driver_info_3(&(driver_info_3[i]));
- }
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ case 1:
+ {
+ DRIVER_INFO_1 *driver_info_1=NULL;
+ driver_info_1=(DRIVER_INFO_1 *)malloc(count*sizeof(DRIVER_INFO_1));
- /* fill the buffer with the form structures */
- for (i=0; i<*returned; i++)
- {
- DEBUGADD(6,("adding form [%d] to buffer\n",i));
- new_smb_io_printer_driver_info_3("", buffer, &(driver_info_3[i]), 0);
+ for (i=0; i<count; i++)
+ {
+ get_a_printer_driver(&driver, 3, list[i], architecture);
+ fill_printer_driver_info_1(&(driver_info_1[i]), driver, servername, architecture );
+ free_a_printer_driver(driver, 3);
+ }
+ ctr->driver.info1=driver_info_1;
+ break;
+ }
+ case 2:
+ {
+ DRIVER_INFO_2 *driver_info_2=NULL;
+ driver_info_2=(DRIVER_INFO_2 *)malloc(count*sizeof(DRIVER_INFO_2));
+
+ for (i=0; i<count; i++)
+ {
+ get_a_printer_driver(&driver, 3, list[i], architecture);
+ fill_printer_driver_info_2(&(driver_info_2[i]), driver, servername, architecture );
+ free_a_printer_driver(driver, 3);
+ }
+ ctr->driver.info2=driver_info_2;
+ break;
+ }
+ case 3:
+ {
+ DRIVER_INFO_3 *driver_info_3=NULL;
+ driver_info_3=(DRIVER_INFO_3 *)malloc(count*sizeof(DRIVER_INFO_3));
+
+ for (i=0; i<count; i++)
+ {
+ get_a_printer_driver(&driver, 3, list[i], architecture);
+ fill_printer_driver_info_3(&(driver_info_3[i]), driver, servername, architecture );
+ free_a_printer_driver(driver, 3);
+ }
+ ctr->driver.info3=driver_info_3;
+ break;
+ }
+ default:
+ {
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
}
+ return NT_STATUS_NOPROBLEMO;
- safe_free(list);
-
- if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
- Enumerates all printer drivers.
-****************************************************************************/
-uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
-{
- int i;
- fstring *list;
- fstring servername;
- fstring architecture;
-
- DEBUG(4,("_spoolss_enumprinterdrivers\n"));
- fstrcpy(servername, global_myname);
- *needed=0;
- *returned=0;
-
- unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
- *returned=get_ntdrivers(&list, architecture);
-
- DEBUGADD(4,("we have: [%d] drivers in environment [%s]\n", *returned, architecture));
- for (i=0; i<*returned; i++)
- DEBUGADD(5,("driver: [%s]\n", list[i]));
-
- switch (level) {
- case 1:
- return enumprinterdrivers_level1(list, servername, architecture, buffer, offered, needed, returned);
- break;
- case 2:
- return enumprinterdrivers_level2(list, servername, architecture, buffer, offered, needed, returned);
- break;
- case 3:
- return enumprinterdrivers_level3(list, servername, architecture, buffer, offered, needed, returned);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
}
/****************************************************************************
@@ -3231,7 +2824,7 @@ uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32
static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position)
{
form->flag=list->flag;
- init_unistr(&(form->name), list->name);
+ make_unistr(&(form->name), list->name);
form->width=list->width;
form->length=list->length;
form->left=list->left;
@@ -3239,239 +2832,129 @@ static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position)
form->right=list->right;
form->bottom=list->bottom;
}
-
+
/****************************************************************************
****************************************************************************/
-uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *numofforms)
+uint32 _spoolss_enumforms( const POLICY_HND *handle,
+ uint32 level,
+ FORM_1 **forms_1,
+ uint32 *offered,
+ uint32 *numofforms)
{
- nt_forms_struct *list=NULL;
- FORM_1 *forms_1;
- int buffer_size=0;
+ int count;
int i;
+ nt_forms_struct *list=NULL;
+ (*forms_1)=NULL;
- DEBUG(4,("_new_spoolss_enumforms\n"));
- DEBUGADD(5,("Offered buffer size [%d]\n", offered));
- DEBUGADD(5,("Info level [%d]\n", level));
+ DEBUG(4,("spoolss_enumforms\n"));
+
+ count = get_ntforms(&list);
+ (*numofforms) = count;
- *numofforms = get_ntforms(&list);
+ DEBUGADD(5,("Offered buffer size [%d]\n", *offered));
DEBUGADD(5,("Number of forms [%d]\n", *numofforms));
-
- switch (level) {
- case 1:
- forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1));
-
- /* construct the list of form structures */
- for (i=0; i<*numofforms; i++)
- {
- DEBUGADD(6,("Filling form number [%d]\n",i));
- fill_form_1(&(forms_1[i]), &(list[i]), i);
- }
-
- /* check the required size. */
- for (i=0; i<*numofforms; i++)
- {
- DEBUGADD(6,("adding form [%d]'s size\n",i));
- buffer_size += spoolss_size_form_1(&(forms_1[i]));
- }
-
- *needed=buffer_size;
+ DEBUGADD(5,("Info level [%d]\n", level));
- if (!alloc_buffer_size(buffer, buffer_size))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the form structures */
- for (i=0; i<*numofforms; i++)
+ switch (level)
+ {
+ case 1:
{
- DEBUGADD(6,("adding form [%d] to buffer\n",i));
- new_smb_io_form_1("", buffer, &(forms_1[i]), 0);
- }
-
- safe_free(list);
-
- if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
- else
- return NT_STATUS_NO_PROBLEMO;
-
- default:
- safe_free(list);
- return NT_STATUS_INVALID_INFO_CLASS;
+ (*forms_1)=(FORM_1 *)malloc(count*sizeof(FORM_1));
+ for (i=0; i<count; i++)
+ {
+ DEBUGADD(6,("Filling form number [%d]\n",i));
+ fill_form_1(&((*forms_1)[i]), &(list[i]), i);
+ }
+ safe_free(list);
+ return NT_STATUS_NOPROBLEMO;
+ }
}
-}
-
-/****************************************************************************
-****************************************************************************/
-static void fill_port_1(PORT_INFO_1 *port, char *name)
-{
- init_unistr(&(port->port_name), name);
+ safe_free(list);
+ return NT_STATUS_INVALID_INFO_CLASS;
}
/****************************************************************************
****************************************************************************/
static void fill_port_2(PORT_INFO_2 *port, char *name)
{
- init_unistr(&(port->port_name), name);
- init_unistr(&(port->monitor_name), "Moniteur Local");
- init_unistr(&(port->description), "Local Port");
+ make_unistr(&(port->port_name), name);
+ make_unistr(&(port->monitor_name), "Moniteur Local");
+ make_unistr(&(port->description), "Local Port");
#define PORT_TYPE_WRITE 1
port->port_type=PORT_TYPE_WRITE;
port->reserved=0x0;
}
/****************************************************************************
- enumports level 1.
****************************************************************************/
-static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
-{
- int n_services=lp_numservices();
- int snum;
- int i=0;
-
- PORT_INFO_1 *ports=NULL;
-
- for (snum=0; snum<n_services; snum++)
- if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
- (*returned)++;
-
- ports=(PORT_INFO_1 *)malloc( (*returned+1) * sizeof(PORT_INFO_1) );
-
- for (snum=0; snum<n_services; snum++)
- {
- if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
- DEBUGADD(6,("Filling port number [%d]\n", i));
- fill_port_1(&(ports[i]), lp_servicename(snum));
- i++;
- }
- }
-
- /* check the required size. */
- for (i=0; i<*returned; i++)
- {
- DEBUGADD(6,("adding port [%d]'s size\n", i));
- *needed += spoolss_size_port_info_1(&(ports[i]));
- }
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- /* fill the buffer with the ports structures */
- for (i=0; i<*returned; i++)
- {
- DEBUGADD(6,("adding port [%d] to buffer\n", i));
- new_smb_io_port_1("", buffer, &(ports[i]), 0);
- }
-
- safe_free(ports);
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-
-/****************************************************************************
- enumports level 2.
-****************************************************************************/
-static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+uint32 _spoolss_enumports( const UNISTR2 *name,
+ uint32 level,
+ PORT_INFO_CTR *ctr,
+ uint32 *offered,
+ uint32 *numofports)
{
int n_services=lp_numservices();
int snum;
- int i=0;
-
- PORT_INFO_2 *ports=NULL;
- for (snum=0; snum<n_services; snum++)
- if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
- (*returned)++;
-
- ports=(PORT_INFO_2 *)malloc( (*returned+1) * sizeof(PORT_INFO_2) );
+ DEBUG(4,("spoolss_enumports\n"));
- for (snum=0; snum<n_services; snum++)
- {
- if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
- DEBUGADD(6,("Filling port number [%d]\n", i));
- fill_port_2(&(ports[i]), lp_servicename(snum));
- i++;
- }
- }
-
- /* check the required size. */
- for (i=0; i<*returned; i++)
- {
- DEBUGADD(6,("adding port [%d]'s size\n", i));
- *needed += spoolss_size_port_info_2(&(ports[i]));
- }
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ (*numofports) = 0;
- /* fill the buffer with the ports structures */
- for (i=0; i<*returned; i++)
+ switch (level)
{
- DEBUGADD(6,("adding port [%d] to buffer\n", i));
- new_smb_io_port_2("", buffer, &(ports[i]), 0);
- }
-
- safe_free(ports);
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
+ case 2:
+ {
+ PORT_INFO_2 *ports_2=NULL;
+ ports_2=(PORT_INFO_2 *)malloc(n_services*sizeof(PORT_INFO_2));
+ for (snum=0; snum<n_services; snum++)
+ {
+ if ( lp_browseable(snum) &&
+ lp_snum_ok(snum) &&
+ lp_print_ok(snum) )
+ {
+ DEBUGADD(6,("Filling port no [%d]\n",
+ (*numofports)));
+ fill_port_2(&(ports_2[(*numofports)]),
+ lp_servicename(snum));
+ (*numofports)++;
+ }
+ }
+ ctr->port.info_2=ports_2;
+ return NT_STATUS_NOPROBLEMO;
+ }
}
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-/****************************************************************************
- enumports.
-****************************************************************************/
-uint32 _spoolss_enumports( UNISTR2 *name, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
-{
- DEBUG(4,("_spoolss_enumports\n"));
-
- *returned=0;
- *needed=0;
-
- switch (level) {
- case 1:
- return enumports_level_1(buffer, offered, needed, returned);
- break;
- case 2:
- return enumports_level_2(buffer, offered, needed, returned);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
+ return NT_STATUS_INVALID_INFO_CLASS;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
+uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name,
+ uint32 level,
const SPOOL_PRINTER_INFO_LEVEL *info,
- uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
- uint32 user_switch, const SPOOL_USER_CTR *user,
+ uint32 unk0,
+ uint32 unk1,
+ uint32 unk2,
+ uint32 unk3,
+ uint32 user_level,
+ const SPOOL_USER_LEVEL *user,
POLICY_HND *handle)
{
NT_PRINTER_INFO_LEVEL printer;
- fstring name;
+ fstring ascii_name;
+ fstring server_name;
fstring share_name;
-
- clear_handle(handle);
+ UNISTR2 *portname;
+ SPOOL_PRINTER_INFO_LEVEL_2 *info2;
+ uint32 status = NT_STATUS_NOPROBLEMO;
-/*
- * FIX: JFM: we need to check the user here !!!!
- *
- * as the code is running as root, anybody can add printers to the server
- */
+ DEBUG(0,("spoolss_addprinterex: unknown access mask parameter\n"));
+ if (!open_printer_hnd(handle, unk0))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
/* NULLify info_2 here */
/* don't put it in convert_printer_info as it's used also with non-NULL values */
printer.info_2=NULL;
@@ -3479,31 +2962,31 @@ uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
/* convert from UNICODE to ASCII */
convert_printer_info(info, &printer, level);
- unistr2_to_ascii(share_name, &((info->info_2)->portname), sizeof(share_name)-1);
-
- slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname, share_name);
-
- create_printer_hnd(handle);
-
- open_printer_hnd(handle);
-
- if (!set_printer_hnd_printertype(handle, name)) {
+ /* write the ASCII on disk */
+ status = add_a_printer(printer, level);
+ if (status != 0x0)
+ {
close_printer_handle(handle);
- return NT_STATUS_ACCESS_DENIED;
+ return status;
}
+
+ info2=info->info_2;
+ portname=&(info2->portname);
+
+ StrnCpy(server_name, global_myname, strlen(global_myname) );
+ unistr2_to_ascii(share_name, portname, sizeof(share_name)-1);
- if (!set_printer_hnd_printername(handle, name)) {
+ slprintf(ascii_name, sizeof(ascii_name)-1, "\\\\%s\\%s",
+ server_name, share_name);
+
+ if (!set_printer_hnd_printertype(handle, ascii_name) ||
+ !set_printer_hnd_printername(handle, ascii_name))
+ {
close_printer_handle(handle);
return NT_STATUS_ACCESS_DENIED;
}
- /* write the ASCII on disk */
- if (add_a_printer(printer, level) != 0x0) {
- close_printer_handle(handle);
- return NT_STATUS_ACCESS_DENIED;
- }
-
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
@@ -3513,84 +2996,46 @@ uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
{
NT_PRINTER_DRIVER_INFO_LEVEL driver;
-
convert_printer_driver_info(info, &driver, level);
-
- if (add_a_printer_driver(driver, level)!=0)
- return NT_STATUS_ACCESS_DENIED;
-
- return NT_STATUS_NO_PROBLEMO;
+ return add_a_printer_driver(driver, level);
}
/****************************************************************************
****************************************************************************/
-static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
-{
- init_unistr(&(info->name), name);
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+uint32 _spoolss_getprinterdriverdirectory( const UNISTR2 *name,
+ const UNISTR2 *uni_environment,
+ uint32 level,
+ DRIVER_DIRECTORY_CTR *ctr,
+ uint32 *offered)
{
pstring chaine;
pstring long_archi;
- pstring short_archi;
- DRIVER_DIRECTORY_1 *info=NULL;
-
- info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1));
-
+ pstring archi;
+
unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
- get_short_archi(short_archi, long_archi);
+ get_short_archi(archi, long_archi);
- slprintf(chaine, sizeof(chaine)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
+ slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\print$\\%s",
+ global_myname, archi);
DEBUG(4,("printer driver directory: [%s]\n", chaine));
+
+ make_unistr(&(ctr->driver.info_1.name), chaine);
- fill_driverdir_1(info, chaine);
-
- *needed += spoolss_size_driverdir_info_1(info);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- new_smb_io_driverdir_1("", buffer, info, 0);
-
- safe_free(info);
-
- if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
- else
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed)
-{
- DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
-
- *needed=0;
-
- switch(level) {
- case 1:
- return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
-}
-
-/****************************************************************************
-****************************************************************************/
-uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 index,
- uint32 in_value_len, uint32 in_data_len,
- uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len,
- uint32 *out_type,
- uint32 *out_max_data_len, uint8 **out_data, uint32 *out_data_len)
+uint32 _spoolss_enumprinterdata(const POLICY_HND *handle,
+ uint32 idx,
+ uint32 *valuesize,
+ UNISTR *uni_value,
+ uint32 *realvaluesize,
+ uint32 *type,
+ uint32 *datasize,
+ uint8 **data,
+ uint32 *realdatasize)
{
NT_PRINTER_INFO_LEVEL printer;
@@ -3600,102 +3045,94 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 index,
uint32 biggest_valuesize;
uint32 biggest_datasize;
uint32 data_len;
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
+ uint32 status = NT_STATUS_NOPROBLEMO;
+
+ PRINT_HND_INFO *pnum = find_printer_index_by_hnd(handle);
int snum;
- uint8 *data=NULL;
- uint32 type;
ZERO_STRUCT(printer);
-
- *out_max_value_len=0;
- *out_value=NULL;
- *out_value_len=0;
-
- *out_type=0;
-
- *out_max_data_len=0;
- *out_data=NULL;
- *out_data_len=0;
+ (*data)=NULL;
DEBUG(5,("spoolss_enumprinterdata\n"));
- if (!OPEN_HANDLE(Printer))
+ if (INVALID_HANDLE(pnum))
+ {
return NT_STATUS_INVALID_HANDLE;
-
+ }
if (!get_printer_snum(handle, &snum))
+ {
return NT_STATUS_INVALID_HANDLE;
-
- if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0x0)
- return NT_STATUS_INVALID_HANDLE;
+ }
+ status = get_a_printer(&printer, 2, lp_servicename(snum));
- /*
- * The NT machine wants to know the biggest size of value and data
- *
- * cf: MSDN EnumPrinterData remark section
- */
- if ( (in_value_len==0) && (in_data_len==0) ) {
+ if (status != 0x0)
+ {
+ return status;
+ }
+
+ /* The NT machine wants to know the biggest size of value and data */
+ if ( ((*valuesize)==0) && ((*datasize)==0) )
+ {
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
+ (*valuesize)=0;
+ (*realvaluesize)=0;
+ (*type)=0;
+ (*datasize)=0;
+ (*realdatasize)=0;
+ status=0;
+
param_index=0;
biggest_valuesize=0;
biggest_datasize=0;
- while (get_specific_param_by_index(printer, 2, param_index, value, &data, &type, &data_len)) {
+ while (get_specific_param_by_index(printer, 2, param_index, value, data, type, &data_len))
+ {
if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value);
- if (data_len > biggest_datasize) biggest_datasize=data_len;
-
- DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize));
+ if (data_len > biggest_datasize) biggest_datasize=data_len;
- safe_free(data);
param_index++;
}
-
- /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */
- *out_value_len=2*(1+biggest_valuesize);
- *out_data_len=biggest_datasize;
-
- DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
-
- free_a_printer(printer, 2);
- return NT_STATUS_NO_PROBLEMO;
- }
-
- /*
- * the value len is wrong in NT sp3
- * that's the number of bytes not the number of unicode chars
- */
-
- if (!get_specific_param_by_index(printer, 2, index, value, &data, &type, &data_len)) {
- free_a_printer(printer, 2);
- return 0x0103; /* ERROR_NO_MORE_ITEMS */
+
+ /* I wrote it, I didn't designed the protocol */
+ if (biggest_valuesize!=0)
+ {
+ SIVAL(&(value),0, 2*(biggest_valuesize+1) );
+ }
+ (*data)=(uint8 *)malloc(4*sizeof(uint8));
+ SIVAL((*data), 0, biggest_datasize );
}
+ else
+ {
+ /*
+ * the value len is wrong in NT sp3
+ * that's the number of bytes not the number of unicode chars
+ */
+
+ if (get_specific_param_by_index(printer, 2, idx, value, data, type, &data_len))
+ {
+ make_unistr(uni_value, value);
- /*
- * the value is:
- * - counted in bytes in the request
- * - counted in UNICODE chars in the max reply
- * - counted in bytes in the real size
- *
- * take a pause *before* coding not *during* coding
- */
-
- *out_max_value_len=in_value_len/2;
- *out_value=(uint16 *)malloc(in_value_len*sizeof(uint8));
- ascii_to_unistr(*out_value, value, *out_max_value_len);
- *out_value_len=2*(1+strlen(value));
-
- *out_type=type;
-
- /* the data is counted in bytes */
- *out_max_data_len=in_data_len;
- *out_data=(uint8 *)malloc(in_data_len*sizeof(uint8));
- memcpy(*out_data, data, data_len);
- *out_data_len=data_len;
-
- safe_free(data);
+ /* the length are in bytes including leading NULL */
+ (*realvaluesize)=2*(strlen(value)+1);
+ (*realdatasize)=data_len;
+
+ status=0;
+ }
+ else
+ {
+ (*valuesize)=0;
+ (*realvaluesize)=0;
+ (*datasize)=0;
+ (*realdatasize)=0;
+ (*type)=0;
+ status=0x0103; /* ERROR_NO_MORE_ITEMS */
+ }
+ }
free_a_printer(printer, 2);
- return NT_STATUS_NO_PROBLEMO;
+
+ return status;
}
/****************************************************************************
@@ -3711,22 +3148,28 @@ uint32 _spoolss_setprinterdata( const POLICY_HND *handle,
NT_PRINTER_INFO_LEVEL printer;
NT_PRINTER_PARAM *param = NULL;
+ PRINT_HND_INFO *pnum=0;
int snum=0;
- uint32 status = 0x0;
- Printer_entry *Printer=find_printer_index_by_hnd(handle);
+ uint32 status = NT_STATUS_NOPROBLEMO;
DEBUG(5,("spoolss_setprinterdata\n"));
+ pnum = find_printer_index_by_hnd(handle);
- if (!OPEN_HANDLE(Printer))
+ if (INVALID_HANDLE(pnum))
+ {
return NT_STATUS_INVALID_HANDLE;
-
+ }
if (!get_printer_snum(handle, &snum))
+ {
return NT_STATUS_INVALID_HANDLE;
+ }
status = get_a_printer(&printer, 2, lp_servicename(snum));
if (status != 0x0)
+ {
return status;
+ }
convert_specific_param(&param, value , type, data, real_len);
unlink_specific_param_if_exist(printer.info_2, param);
@@ -3750,14 +3193,18 @@ uint32 _spoolss_addform( const POLICY_HND *handle,
uint32 level,
const FORM *form)
{
+ PRINT_HND_INFO *pnum=0;
int count=0;
nt_forms_struct *list=NULL;
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
DEBUG(5,("spoolss_addform\n"));
- if (!OPEN_HANDLE(Printer))
+ pnum = find_printer_index_by_hnd(handle);
+
+ if (INVALID_HANDLE(pnum))
+ {
return NT_STATUS_INVALID_HANDLE;
+ }
count=get_ntforms(&list);
add_a_form(&list, form, &count);
@@ -3765,7 +3212,7 @@ uint32 _spoolss_addform( const POLICY_HND *handle,
safe_free(list);
- return 0x0;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
@@ -3775,13 +3222,14 @@ uint32 _spoolss_setform( const POLICY_HND *handle,
uint32 level,
const FORM *form)
{
+ PRINT_HND_INFO *pnum=NULL;
int count=0;
nt_forms_struct *list=NULL;
- Printer_entry *Printer = find_printer_index_by_hnd(handle);
DEBUG(5,("spoolss_setform\n"));
- if (!OPEN_HANDLE(Printer))
+ pnum = find_printer_index_by_hnd(handle);
+ if (INVALID_HANDLE(pnum))
{
return NT_STATUS_INVALID_HANDLE;
}
@@ -3791,43 +3239,17 @@ uint32 _spoolss_setform( const POLICY_HND *handle,
safe_free(list);
- return 0x0;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
- enumprintprocessors level 1.
****************************************************************************/
-static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
-{
- PRINTPROCESSOR_1 *info_1=NULL;
-
- info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1));
- (*returned) = 0x1;
-
- init_unistr(&(info_1->name), "winprint");
-
- *needed += spoolss_size_printprocessor_info_1(info_1);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- smb_io_printprocessor_info_1("", buffer, info_1, 0);
-
- safe_free(info_1);
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
-****************************************************************************/
-uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
+uint32 _spoolss_enumprintprocessors(const UNISTR2 *name,
+ const UNISTR2 *environment,
+ uint32 level,
+ PRINTPROCESSOR_1 **info_1,
+ uint32 *offered,
+ uint32 *numofprintprocessors)
{
DEBUG(5,("spoolss_enumprintprocessors\n"));
@@ -3838,134 +3260,26 @@ uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32
* and I can use my nice printer checker.
*/
- *returned=0;
- *needed=0;
-
- switch (level) {
- case 1:
- return enumprintprocessors_level_1(buffer, offered, needed, returned);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
-}
-
-/****************************************************************************
- enumprintprocdatatypes level 1.
-****************************************************************************/
-static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
-{
- PRINTPROCDATATYPE_1 *info_1=NULL;
-
- info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1));
- (*returned) = 0x1;
+ (*numofprintprocessors) = 0x1;
+ (*info_1) = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1));
- init_unistr(&(info_1->name), "RAW");
-
- *needed += spoolss_size_printprocdatatype_info_1(info_1);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
-
- safe_free(info_1);
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
-****************************************************************************/
-uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
-{
- DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
-
- *returned=0;
- *needed=0;
-
- switch (level) {
- case 1:
- return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- break;
+ if ((*info_1) == NULL)
+ {
+ return NT_STATUS_NO_MEMORY;
}
-}
-
-/****************************************************************************
- enumprintmonitors level 1.
-****************************************************************************/
-static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
-{
- PRINTMONITOR_1 *info_1=NULL;
-
- info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1));
- (*returned) = 0x1;
-
- init_unistr(&(info_1->name), "Local Port");
-
- *needed += spoolss_size_printmonitor_info_1(info_1);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
- smb_io_printmonitor_info_1("", buffer, info_1, 0);
+ make_unistr(&((*info_1)->name), "winprint");
- safe_free(info_1);
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
- enumprintmonitors level 2.
****************************************************************************/
-static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
-{
- PRINTMONITOR_2 *info_2=NULL;
-
- info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2));
- (*returned) = 0x1;
-
- init_unistr(&(info_2->name), "Local Port");
- init_unistr(&(info_2->environment), "Windows NT X86");
- init_unistr(&(info_2->dll_name), "localmon.dll");
-
- *needed += spoolss_size_printmonitor_info_2(info_2);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- smb_io_printmonitor_info_2("", buffer, info_2, 0);
-
- safe_free(info_2);
-
- if (*needed > offered) {
- *returned=0;
- return ERROR_INSUFFICIENT_BUFFER;
- }
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-/****************************************************************************
-****************************************************************************/
-uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed, uint32 *returned)
+uint32 _spoolss_enumprintmonitors( const UNISTR2 *name,
+ uint32 level,
+ PRINTMONITOR_1 **info_1,
+ uint32 *offered,
+ uint32 *numofprintmonitors)
{
DEBUG(5,("spoolss_enumprintmonitors\n"));
@@ -3976,145 +3290,98 @@ uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level,
* and I can use my nice printer checker.
*/
- *returned=0;
- *needed=0;
-
- switch (level) {
- case 1:
- return enumprintmonitors_level_1(buffer, offered, needed, returned);
- break;
- case 2:
- return enumprintmonitors_level_2(buffer, offered, needed, returned);
- break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
- break;
- }
-}
-
-/****************************************************************************
-****************************************************************************/
-static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- int i=0;
- BOOL found=False;
- JOB_INFO_1 *info_1=NULL;
- info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
-
- if (info_1 == NULL) {
- safe_free(queue);
- return NT_STATUS_NO_MEMORY;
- }
-
- for (i=0; i<count && found==False; i++) {
- if (queue[i].job==(int)jobid)
- found=True;
- }
-
- if (found==False) {
- safe_free(queue);
- /* I shoud reply something else ... I can't find the good one */
- return NT_STATUS_NO_PROBLEMO;
- }
-
- fill_job_info_1(info_1, &(queue[i]), i, snum);
-
- *needed += spoolss_size_job_info_1(info_1);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
-
- new_smb_io_job_info_1("", buffer, info_1, 0);
-
- safe_free(info_1);
-
- if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
- else
- return NT_STATUS_NO_PROBLEMO;
-}
-
-
-/****************************************************************************
-****************************************************************************/
-static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
-{
- int i=0;
- BOOL found=False;
- JOB_INFO_2 *info_2=NULL;
- info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
-
- if (info_2 == NULL) {
- safe_free(queue);
+ (*numofprintmonitors) = 0x1;
+ (*info_1) = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1));
+ if ((*info_1) == NULL)
+ {
return NT_STATUS_NO_MEMORY;
}
-
- for (i=0; i<count && found==False; i++) {
- if (queue[i].job==(int)jobid)
- found=True;
- }
- if (found==False) {
- safe_free(queue);
- /* I shoud reply something else ... I can't find the good one */
- return NT_STATUS_NO_PROBLEMO;
- }
-
- fill_job_info_2(info_2, &(queue[i]), i, snum);
-
- *needed += spoolss_size_job_info_2(info_2);
-
- if (!alloc_buffer_size(buffer, *needed))
- return ERROR_INSUFFICIENT_BUFFER;
+ make_unistr(&((*info_1)->name), "Local Port");
- new_smb_io_job_info_2("", buffer, info_2, 0);
-
- safe_free(info_2);
-
- if (*needed > offered)
- return ERROR_INSUFFICIENT_BUFFER;
- else
- return NT_STATUS_NO_PROBLEMO;
+ return NT_STATUS_NOPROBLEMO;
}
/****************************************************************************
****************************************************************************/
-uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level,
- NEW_BUFFER *buffer, uint32 offered,
- uint32 *needed)
+uint32 _spoolss_getjob( const POLICY_HND *handle,
+ uint32 jobid,
+ uint32 level,
+ PJOB_INFO *ctr,
+ uint32 *offered)
{
int snum;
int count;
+ int i;
print_queue_struct *queue=NULL;
print_status_struct prt_status;
- DEBUG(5,("spoolss_getjob\n"));
+ DEBUG(4,("spoolss_getjob\n"));
- memset(&prt_status, 0, sizeof(prt_status));
+ bzero(&prt_status,sizeof(prt_status));
- *needed=0;
-
if (!get_printer_snum(handle, &snum))
{
return NT_STATUS_INVALID_HANDLE;
}
-
- count=get_printqueue(snum, NULL, &queue, &prt_status);
+ count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &prt_status);
DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
count, prt_status.status, prt_status.message));
-
- switch (level) {
- case 1:
- return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
- break;
- case 2:
- return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed);
- break;
- default:
- safe_free(queue);
- return NT_STATUS_INVALID_INFO_CLASS;
- break;
+
+ switch (level)
+ {
+ case 1:
+ {
+ JOB_INFO_1 *job_info_1=NULL;
+ job_info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
+
+ if (job_info_1 == NULL)
+ {
+ safe_free(queue);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<count; i++)
+ {
+ if (queue[i].job==(int)jobid)
+ {
+ fill_job_info_1(job_info_1,
+ &(queue[i]), i, snum);
+ }
+ }
+ ctr->job.job_info_1=job_info_1;
+ break;
+ }
+ case 2:
+ {
+ JOB_INFO_2 *job_info_2=NULL;
+ job_info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
+
+ if (job_info_2 == NULL)
+ {
+ safe_free(queue);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<count; i++)
+ {
+ if (queue[i].job==(int)jobid)
+ {
+ fill_job_info_2(job_info_2,
+ &(queue[i]), i, snum);
+ }
+ }
+ ctr->job.job_info_2=job_info_2;
+ break;
+ }
+ default:
+ {
+ safe_free(queue);
+ return NT_STATUS_INVALID_INFO_CLASS;
+ }
}
+
+ safe_free(queue);
+ return NT_STATUS_NOPROBLEMO;
}
-
diff --git a/source/srvsvcd/srv_srvsvc_nt.c b/source/srvsvcd/srv_srvsvc_nt.c
new file mode 100644
index 00000000000..adf0b059efb
--- /dev/null
+++ b/source/srvsvcd/srv_srvsvc_nt.c
@@ -0,0 +1,1102 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Jean-Francois Micouleau 1999-2000
+ Copyright (C) Sean Millichamp 2000
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+
+extern pstring global_myname;
+extern int DEBUGLEVEL;
+
+/*******************************************************************
+time of day
+********************************************************************/
+uint32 _srv_net_remote_tod( UNISTR2 *srv_name, TIME_OF_DAY_INFO *tod )
+{
+ struct tm *t;
+ time_t unixdate = time(NULL);
+
+ t = gmtime(&unixdate);
+
+ /* set up the */
+ make_time_of_day_info(tod,
+ unixdate,
+ 0,
+ t->tm_hour,
+ t->tm_min,
+ t->tm_sec,
+ 0,
+ TimeDiff(unixdate)/60,
+ 10000,
+ t->tm_mday,
+ t->tm_mon + 1,
+ 1900+t->tm_year,
+ t->tm_wday);
+ return 0x0;
+}
+
+/*******************************************************************
+ makes a SRV_INFO_101 structure.
+ ********************************************************************/
+static BOOL make_r_srv_info_101(SRV_INFO_101 *sv101, uint32 platform_id,
+ char *name, int32 ver_major, uint32 ver_minor,
+ uint32 srv_type, char *comment)
+{
+ if (sv101 == NULL) return False;
+
+ DEBUG(5,("make_srv_info_101\n"));
+
+ sv101->platform_id = platform_id;
+ make_buf_unistr2(&(sv101->uni_name), &(sv101->ptr_name) , name );
+ sv101->ver_major = ver_major;
+ sv101->ver_minor = ver_minor;
+ sv101->srv_type = srv_type;
+ make_buf_unistr2(&(sv101->uni_comment ), &(sv101->ptr_comment) , comment );
+
+return True;
+}
+
+/*******************************************************************
+ makes a SRV_INFO_102 structure.
+ ********************************************************************/
+static BOOL make_r_srv_info_102(SRV_INFO_102 *sv102, uint32 platform_id,
+ char *name, char *comment, uint32 ver_major,
+ uint32 ver_minor, uint32 srv_type, uint32 users,
+ uint32 disc, uint32 hidden, uint32 announce,
+ uint32 ann_delta, uint32 licenses, char *usr_path)
+{
+ if (sv102 == NULL) return False;
+
+ DEBUG(5,("make_srv_info_102\n"));
+
+ sv102->platform_id = platform_id;
+ make_buf_unistr2(&(sv102->uni_name ), &(sv102->ptr_name ), name );
+ sv102->ver_major = ver_major;
+ sv102->ver_minor = ver_minor;
+ sv102->srv_type = srv_type;
+ make_buf_unistr2(&(sv102->uni_comment ), &(sv102->ptr_comment ), comment );
+
+ /* same as 101 up to here */
+
+ sv102->users = users;
+ sv102->disc = disc;
+ sv102->hidden = hidden;
+ sv102->announce = announce;
+ sv102->ann_delta = ann_delta;
+ sv102->licenses = licenses;
+ make_buf_unistr2(&(sv102->uni_usr_path), &(sv102->ptr_usr_path), usr_path);
+
+ return True;
+}
+
+
+/*******************************************************************
+net server get info
+********************************************************************/
+uint32 _srv_net_srv_get_info( UNISTR2 *srv_name, uint32 switch_value,
+ SRV_INFO_CTR *ctr)
+{
+ switch (switch_value)
+ {
+ case 102:
+ {
+ make_r_srv_info_102(&(ctr->srv.sv102),
+ 500, /* platform id */
+ global_myname,
+ lp_serverstring(),
+ lp_major_announce_version(),
+ lp_minor_announce_version(),
+ lp_default_server_announce(),
+ 0xffffffff, /* users */
+ 0xf, /* disc */
+ 0, /* hidden */
+ 240, /* announce */
+ 3000, /* announce delta */
+ 100000, /* licenses */
+ "c:\\"); /* user path */
+ break;
+ }
+ case 101:
+ {
+ make_r_srv_info_101(&(ctr->srv.sv101),
+ 500, /* platform id */
+ global_myname,
+ lp_major_announce_version(),
+ lp_minor_announce_version(),
+ lp_default_server_announce(),
+ lp_serverstring());
+ break;
+ }
+ default:
+ {
+ return (NT_STATUS_INVALID_INFO_CLASS);
+ break;
+ }
+ }
+ return 0x0;
+}
+
+/*******************************************************************
+ fill in a share info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ see ipc.c:fill_share_info()
+
+ ********************************************************************/
+static void make_srv_share_1_info(SH_INFO_1 *sh1,
+ SH_INFO_1_STR *str1, int snum)
+{
+ int len_net_name;
+ pstring net_name;
+ pstring remark;
+ uint32 type;
+
+ pstrcpy(net_name, lp_servicename(snum));
+ pstrcpy(remark , lp_comment (snum));
+ len_net_name = strlen(net_name);
+
+ /* work out the share type */
+ type = STYPE_DISKTREE;
+
+ if (lp_print_ok(snum)) type = STYPE_PRINTQ;
+ if (strequal("IPC$", net_name)) type = STYPE_IPC;
+ if (net_name[len_net_name] == '$') type |= STYPE_HIDDEN;
+
+ make_srv_share_info1 (sh1 , net_name, type, remark);
+ make_srv_share_info1_str(str1, net_name, remark);
+}
+
+/*******************************************************************
+ fill in a share info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_share_info_1(SRV_SHARE_INFO_1 *sh1, uint32 *snum,
+ uint32 *svcs)
+{
+ uint32 num_entries = 0;
+ (*svcs) = lp_numservices();
+
+ if (sh1 == NULL)
+ {
+ (*snum) = 0;
+ return;
+ }
+
+ sh1->info_1 = g_new(SH_INFO_1 *, (*svcs));
+ sh1->info_1_str = g_new(SH_INFO_1_STR *, (*svcs));
+
+ DEBUG(5,("make_srv_share_1_sh1\n"));
+
+ for (; (*snum) < (*svcs); (*snum)++)
+ {
+ if (lp_browseable((*snum)) && lp_snum_ok((*snum)))
+ {
+ sh1->info_1 [num_entries] = g_new(SH_INFO_1, 1);
+ sh1->info_1_str[num_entries] = g_new(SH_INFO_1_STR, 1);
+
+ make_srv_share_1_info(sh1->info_1 [num_entries],
+ sh1->info_1_str[num_entries],
+ (*snum));
+
+ /* move on to creating next share */
+ num_entries++;
+ }
+ }
+
+ sh1->num_entries_read = num_entries;
+ sh1->ptr_share_info = num_entries > 0 ? 1 : 0;
+ sh1->num_entries_read2 = num_entries;
+
+ if ((*snum) >= (*svcs))
+ {
+ (*snum) = 0;
+ }
+}
+
+/*******************************************************************
+ fill in a share info level 2 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ see ipc.c:fill_share_info()
+
+ ********************************************************************/
+static void make_srv_share_2_info(SH_INFO_2 *sh2,
+ SH_INFO_2_STR *str2, int snum)
+{
+ int len_net_name;
+ pstring net_name;
+ pstring remark;
+ pstring path;
+ pstring passwd;
+ uint32 type;
+
+ pstrcpy(net_name, lp_servicename(snum));
+ pstrcpy(remark , lp_comment (snum));
+ pstrcpy(path , lp_pathname (snum));
+ pstrcpy(passwd , "");
+ len_net_name = strlen(net_name);
+
+ /* work out the share type */
+ type = STYPE_DISKTREE;
+
+ if (lp_print_ok(snum)) type = STYPE_PRINTQ;
+ if (strequal("IPC$", net_name)) type = STYPE_IPC;
+ if (net_name[len_net_name] == '$') type |= STYPE_HIDDEN;
+
+ make_srv_share_info2 (sh2 , net_name, type, remark, 0,
+ 0xffffffff, 1, path, passwd);
+ make_srv_share_info2_str(str2, net_name, remark, path, passwd);
+}
+
+/*******************************************************************
+ fill in a share info level 2 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_share_info_2(SRV_SHARE_INFO_2 *sh2, uint32 *snum,
+ uint32 *svcs)
+{
+ uint32 num_entries = 0;
+ (*svcs) = lp_numservices();
+
+ if (sh2 == NULL)
+ {
+ (*snum) = 0;
+ return;
+ }
+
+ sh2->info_2 = g_new(SH_INFO_2 *, (*svcs));
+ sh2->info_2_str = g_new(SH_INFO_2_STR *, (*svcs));
+
+ DEBUG(5,("make_srv_share_2_sh1\n"));
+
+ for (; (*snum) < (*svcs); (*snum)++)
+ {
+ if (lp_browseable((*snum)) && lp_snum_ok((*snum)))
+ {
+ sh2->info_2 [num_entries] = g_new(SH_INFO_2, 1);
+ sh2->info_2_str[num_entries] = g_new(SH_INFO_2_STR, 1);
+
+ make_srv_share_2_info(sh2->info_2 [num_entries],
+ sh2->info_2_str[num_entries],
+ (*snum));
+
+ /* move on to creating next share */
+ num_entries++;
+ }
+ }
+
+ sh2->num_entries_read = num_entries;
+ sh2->ptr_share_info = num_entries > 0 ? 1 : 0;
+ sh2->num_entries_read2 = num_entries;
+
+ if ((*snum) >= (*svcs))
+ {
+ (*snum) = 0;
+ }
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_SHARE_ENUM structure.
+********************************************************************/
+static uint32 make_srv_share_info_ctr(SRV_SHARE_INFO_CTR *ctr,
+ int switch_value, uint32 *resume_hnd,
+ uint32 *total_entries)
+{
+ uint32 status = 0x0;
+ DEBUG(5,("make_srv_share_info_ctr: %d\n", __LINE__));
+
+ ctr->switch_value = switch_value;
+
+ switch (switch_value)
+ {
+ case 1:
+ {
+ make_srv_share_info_1(&(ctr->share.info1),
+ resume_hnd,
+ total_entries);
+ ctr->ptr_share_ctr = 1;
+ break;
+ }
+ case 2:
+ {
+ make_srv_share_info_2(&(ctr->share.info2),
+ resume_hnd,
+ total_entries);
+ ctr->ptr_share_ctr = 2;
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("make_srv_share_info_ctr: unsupported switch value %d\n",
+ switch_value));
+ (*resume_hnd = 0);
+ (*total_entries) = 0;
+ ctr->ptr_share_ctr = 0;
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_SHARE_ENUM structure.
+********************************************************************/
+static uint32 make_srv_r_net_share_enum( uint32 resume_hnd,
+ int switch_value, SRV_SHARE_INFO_CTR *ctr,
+ uint32 *total_entries, ENUM_HND *enum_hnd,
+ uint32 share_level )
+{
+ uint32 status;
+
+ DEBUG(5,("make_srv_r_net_share_enum: %d\n", __LINE__));
+
+ if (share_level == 0)
+ {
+ status = (NT_STATUS_INVALID_INFO_CLASS);
+ }
+ else
+ {
+ status = make_srv_share_info_ctr(ctr, switch_value,
+ &resume_hnd, total_entries);
+ }
+
+ if (status != 0x0)
+ {
+ resume_hnd = 0;
+ }
+ make_enum_hnd(enum_hnd, resume_hnd);
+
+ return status;
+}
+
+/*******************************************************************
+net share enum
+********************************************************************/
+uint32 _srv_net_share_enum( const UNISTR2 *srv_name,
+ uint32 switch_value, SRV_SHARE_INFO_CTR *ctr,
+ uint32 preferred_len, ENUM_HND *enum_hnd,
+ uint32 *total_entries, uint32 share_level )
+{
+ uint32 status;
+
+ DEBUG(5,("_srv_net_srv_share_enum: %d\n", __LINE__));
+
+ status = make_srv_r_net_share_enum( get_enum_hnd(enum_hnd),
+ ctr->switch_value,
+ ctr,
+ total_entries,
+ enum_hnd,
+ share_level );
+
+ DEBUG(5,("_srv_net_srv_share_enum: %d\n", __LINE__));
+
+ return status;
+}
+
+/*******************************************************************
+ fill in a sess info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_sess_0_info(SESS_INFO_0 *se0, SESS_INFO_0_STR *str0,
+ char *name)
+{
+ make_srv_sess_info0 (se0 , name);
+ make_srv_sess_info0_str(str0, name);
+}
+
+/*******************************************************************
+ fill in a sess info level 0 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_sess_info_0(SRV_SESS_INFO_0 *ss0, uint32 *snum, uint32 *stot)
+{
+ uint32 num_entries = 0;
+ struct connect_record *crec;
+ uint32 session_count;
+
+ if (!get_session_count(&crec, &session_count))
+ {
+ (*snum) = 0;
+ (*stot) = 0;
+ return;
+ }
+
+ (*stot) = session_count;
+
+ DEBUG(0,("Session Count : %u\n",session_count));
+
+ if (ss0 == NULL)
+ {
+ (*snum) = 0;
+ free(crec);
+ return;
+ }
+
+ if (snum)
+ {
+ DEBUG(0,("snum ok\n"));
+ for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
+ {
+ make_srv_sess_0_info(&(ss0->info_0 [num_entries]),
+ &(ss0->info_0_str[num_entries]), crec[num_entries].machine);
+
+ DEBUG(0,("make_srv_sess_0_info\n"));
+ /* move on to creating next session */
+ /* move on to creating next sess */
+ num_entries++;
+ }
+
+ ss0->num_entries_read = num_entries;
+ ss0->ptr_sess_info = num_entries > 0 ? 1 : 0;
+ ss0->num_entries_read2 = num_entries;
+
+ if ((*snum) >= (*stot))
+ {
+ (*snum) = 0;
+ }
+ }
+ else
+ {
+ ss0->num_entries_read = 0;
+ ss0->ptr_sess_info = 0;
+ ss0->num_entries_read2 = 0;
+ }
+ free(crec);
+}
+
+/*******************************************************************
+ fill in a sess info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_sess_1_info(SESS_INFO_1 *se1, SESS_INFO_1_STR *str1,
+ char *name, char *user,
+ uint32 num_opens,
+ uint32 open_time, uint32 idle_time,
+ uint32 usr_flgs)
+{
+ make_srv_sess_info1 (se1 , name, user, num_opens, open_time, idle_time, usr_flgs);
+ make_srv_sess_info1_str(str1, name, user);
+}
+
+/*******************************************************************
+ fill in a sess info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_sess_info_1(SRV_SESS_INFO_1 *ss1, uint32 *snum, uint32 *stot)
+{
+ uint32 num_entries = 0;
+ struct connect_record *crec;
+ uint32 session_count;
+
+ if (!get_session_count(&crec, &session_count))
+ {
+ (*snum) = 0;
+ (*stot) = 0;
+ return;
+ }
+
+ (*stot) = session_count;
+
+ DEBUG(0,("Session Count (info1) : %u\n",session_count));
+ if (ss1 == NULL)
+ {
+ (*snum) = 0;
+ free(crec);
+ return;
+ }
+
+ DEBUG(5,("make_srv_sess_1_ss1\n"));
+
+ if (snum)
+ {
+ for (; (*snum) < (*stot) && num_entries < MAX_SESS_ENTRIES; (*snum)++)
+ {
+ DEBUG(0,("sess1 machine: %s, uid : %u\n",crec[num_entries].machine,crec[num_entries].uid));
+ make_srv_sess_1_info(&(ss1->info_1 [num_entries]),
+ &(ss1->info_1_str[num_entries]),
+ crec[num_entries].machine,
+ uidtoname(crec[num_entries].uid), 1, 10, 5, 0);
+/* What are these on the End ??? */
+
+ /* move on to creating next session */
+ /* move on to creating next sess */
+ num_entries++;
+ }
+
+ ss1->num_entries_read = num_entries;
+ ss1->ptr_sess_info = num_entries > 0 ? 1 : 0;
+ ss1->num_entries_read2 = num_entries;
+
+ if ((*snum) >= (*stot))
+ {
+ (*snum) = 0;
+ }
+ }
+ else
+ {
+ ss1->num_entries_read = 0;
+ ss1->ptr_sess_info = 0;
+ ss1->num_entries_read2 = 0;
+
+ (*stot) = 0;
+ }
+ free(crec);
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_SESS_ENUM structure.
+********************************************************************/
+static uint32 make_srv_sess_info_ctr(SRV_SESS_INFO_CTR *ctr,
+ int switch_value, uint32 *resume_hnd,
+ uint32 *total_entries)
+{
+ uint32 status = 0x0;
+ DEBUG(5,("make_srv_sess_info_ctr: %d\n", __LINE__));
+
+ ctr->switch_value = switch_value;
+
+ switch (switch_value)
+ {
+ case 0:
+ {
+ make_srv_sess_info_0(&(ctr->sess.info0), resume_hnd,
+ total_entries);
+ ctr->ptr_sess_ctr = 1;
+ break;
+ }
+ case 1:
+ {
+ make_srv_sess_info_1(&(ctr->sess.info1), resume_hnd,
+ total_entries);
+ ctr->ptr_sess_ctr = 1;
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("make_srv_sess_info_ctr: unsupported switch value %d\n",
+ switch_value));
+ (*resume_hnd) = 0;
+ (*total_entries) = 0;
+ ctr->ptr_sess_ctr = 0;
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+ return status;
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_SESS_ENUM structure.
+********************************************************************/
+static uint32 make_srv_r_net_sess_enum( uint32 resume_hnd,
+ int switch_value, SRV_SESS_INFO_CTR *ctr,
+ uint32 *total_entries, ENUM_HND *enum_hnd,
+ uint32 sess_level )
+{
+ uint32 status;
+
+ DEBUG(5,("make_srv_r_net_sess_enum: %d\n", __LINE__));
+
+ if (sess_level == -1)
+ {
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ else
+ {
+ status = make_srv_sess_info_ctr(ctr, switch_value,
+ &resume_hnd, total_entries);
+ }
+ if (status != 0x0)
+ {
+ resume_hnd = 0;
+ }
+ make_enum_hnd(enum_hnd, resume_hnd);
+
+ return status;
+}
+
+/*******************************************************************
+net sess enum
+********************************************************************/
+uint32 _srv_net_sess_enum( const UNISTR2 *srv_name,
+ uint32 switch_value, SRV_SESS_INFO_CTR *ctr,
+ uint32 preferred_len, ENUM_HND *enum_hnd,
+ uint32 *total_entries, uint32 sess_level )
+{
+ uint32 status;
+
+ DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
+
+ /* set up the */
+ status = make_srv_r_net_sess_enum(get_enum_hnd(enum_hnd),
+ ctr->switch_value,
+ ctr,
+ total_entries,
+ enum_hnd,
+ sess_level );
+
+ DEBUG(5,("_srv_net_sess_enum: %d\n", __LINE__));
+
+ return status;
+}
+
+/*******************************************************************
+ fill in a conn info level 0 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_conn_info_0(SRV_CONN_INFO_0 *ss0, uint32 *snum, uint32 *stot)
+{
+ uint32 num_entries = 0;
+ struct connect_record *crec;
+ uint32 connection_count;
+
+ if (!get_connection_status(&crec, &connection_count))
+ {
+ (*snum) = 0;
+ (*stot) = 0;
+ return;
+ }
+
+ (*stot) = connection_count;
+
+ if (ss0 == NULL)
+ {
+ (*snum) = 0;
+ return;
+ }
+
+ DEBUG(0,("make_srv_conn_0_ss0\n"));
+
+ if (snum)
+ {
+ for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
+ {
+ make_srv_conn_info0(&(ss0->info_0 [num_entries]), (*snum));
+
+ /* move on to creating next connection */
+ /* move on to creating next conn */
+ num_entries++;
+ }
+
+ ss0->num_entries_read = num_entries;
+ ss0->ptr_conn_info = num_entries > 0 ? 1 : 0;
+ ss0->num_entries_read2 = num_entries;
+
+
+
+ if ((*snum) >= (*stot))
+ {
+ (*snum) = 0;
+ }
+ }
+ else
+ {
+ ss0->num_entries_read = 0;
+ ss0->ptr_conn_info = 0;
+ ss0->num_entries_read2 = 0;
+
+ (*stot) = 0;
+ }
+
+ free(crec);
+}
+
+/*******************************************************************
+ fill in a conn info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_conn_1_info(CONN_INFO_1 *se1, CONN_INFO_1_STR *str1,
+ uint32 id, uint32 type,
+ uint32 num_opens, uint32 num_users, uint32 open_time,
+ char *usr_name, char *net_name)
+{
+ make_srv_conn_info1 (se1 , id, type, num_opens, num_users, open_time, usr_name, net_name);
+ make_srv_conn_info1_str(str1, usr_name, net_name);
+}
+
+/*******************************************************************
+ fill in a conn info level 1 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_conn_info_1(SRV_CONN_INFO_1 *ss1, uint32 *snum, uint32 *stot)
+{
+ uint32 num_entries = 0;
+ time_t current_time;
+ time_t diff;
+
+ struct connect_record *crec;
+ uint32 connection_count;
+
+ if (!get_connection_status(&crec, &connection_count))
+ {
+ (*snum) = 0;
+ (*stot) = 0;
+ return;
+ }
+
+ (*stot) = connection_count;
+
+ if (ss1 == NULL)
+ {
+ (*snum) = 0;
+ return;
+ }
+
+ current_time=time(NULL);
+
+ DEBUG(5,("make_srv_conn_1_ss1\n"));
+
+ if (snum)
+ {
+ for (; (*snum) < (*stot) && num_entries < MAX_CONN_ENTRIES; (*snum)++)
+ {
+ diff = current_time - crec[num_entries].start;
+ make_srv_conn_1_info(&(ss1->info_1 [num_entries]),
+ &(ss1->info_1_str[num_entries]),
+ (*snum), 0, 0, 1, diff,uidtoname(crec[num_entries].uid),
+ crec[num_entries].name);
+
+/* FIXME : type of connection + number of locked files */
+
+ /* move on to creating next connection */
+ /* move on to creating next conn */
+ num_entries++;
+ }
+
+ ss1->num_entries_read = num_entries;
+ ss1->ptr_conn_info = num_entries > 0 ? 1 : 0;
+ ss1->num_entries_read2 = num_entries;
+
+
+ if ((*snum) >= (*stot))
+ {
+ (*snum) = 0;
+ }
+ }
+ else
+ {
+ ss1->num_entries_read = 0;
+ ss1->ptr_conn_info = 0;
+ ss1->num_entries_read2 = 0;
+
+ (*stot) = 0;
+ }
+
+ free(crec);
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_CONN_ENUM structure.
+********************************************************************/
+static uint32 make_srv_conn_info_ctr(SRV_CONN_INFO_CTR *ctr,
+ int switch_value, uint32 *resume_hnd, uint32 *total_entries)
+{
+ uint32 status = NT_STATUS_NOPROBLEMO;
+ DEBUG(5,("make_srv_conn_info_ctr: %d\n", __LINE__));
+
+ ctr->switch_value = switch_value;
+
+ switch (switch_value)
+ {
+ case 0:
+ {
+ make_srv_conn_info_0(&(ctr->conn.info0), resume_hnd, total_entries);
+ ctr->ptr_conn_ctr = 1;
+ break;
+ }
+ case 1:
+ {
+ make_srv_conn_info_1(&(ctr->conn.info1), resume_hnd, total_entries);
+ ctr->ptr_conn_ctr = 1;
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("make_srv_conn_info_ctr: unsupported switch value %d\n",
+ switch_value));
+ (*resume_hnd = 0);
+ (*total_entries) = 0;
+ ctr->ptr_conn_ctr = 0;
+ status = 0xC0000000 | NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_CONN_ENUM structure.
+********************************************************************/
+static uint32 make_srv_r_net_conn_enum( uint32 resume_hnd,
+ int switch_value, SRV_CONN_INFO_CTR *ctr,
+ uint32 *total_entries, ENUM_HND *enum_hnd,
+ uint32 conn_level )
+{
+ uint32 status;
+
+ DEBUG(5,("make_srv_r_net_conn_enum: %d\n", __LINE__));
+
+ if (conn_level == -1)
+ {
+ status = (0xC0000000 | NT_STATUS_INVALID_INFO_CLASS);
+ }
+ else
+ {
+ status = make_srv_conn_info_ctr(ctr, switch_value,
+ &resume_hnd, total_entries);
+ }
+ if (status != NT_STATUS_NOPROBLEMO)
+ {
+ resume_hnd = 0;
+ }
+ make_enum_hnd(enum_hnd, resume_hnd);
+
+ return status;
+}
+
+/*******************************************************************
+net conn enum
+********************************************************************/
+uint32 _srv_net_conn_enum( const UNISTR2 *srv_name,
+ uint32 switch_value, SRV_CONN_INFO_CTR *ctr,
+ uint32 preferred_len, ENUM_HND *enum_hnd,
+ uint32 *total_entries, uint32 conn_level )
+{
+ uint32 status;
+
+ DEBUG(5,("_srv_net_conn_enum: %d\n", __LINE__));
+
+ /* set up the */
+ status = make_srv_r_net_conn_enum(get_enum_hnd(enum_hnd),
+ ctr->switch_value,
+ ctr,
+ total_entries,
+ enum_hnd,
+ conn_level );
+
+ DEBUG(5,("_srv_net_conn_enum: %d\n", __LINE__));
+
+ return status;
+}
+
+/*******************************************************************
+ fill in a file info level 3 structure.
+ ********************************************************************/
+static void make_srv_file_3_info(FILE_INFO_3 *fl3, FILE_INFO_3_STR *str3,
+ uint32 fnum, uint32 perms, uint32 num_locks,
+ char *path_name, char *user_name)
+{
+ make_srv_file_info3 (fl3 , fnum, perms, num_locks, path_name, user_name);
+ make_srv_file_info3_str(str3, path_name, user_name);
+}
+
+/*******************************************************************
+ fill in a file info level 3 structure.
+
+ this function breaks the rule that i'd like to be in place, namely
+ it doesn't receive its data as arguments: it has to call lp_xxxx()
+ functions itself. yuck.
+
+ ********************************************************************/
+static void make_srv_file_info_3(SRV_FILE_INFO_3 *fl3, uint32 *fnum, uint32 *ftot)
+{
+ uint32 num_entries = 0;
+ (*ftot) = 1;
+
+ if (fl3 == NULL)
+ {
+ (*fnum) = 0;
+ return;
+ }
+
+ DEBUG(5,("make_srv_file_3_fl3\n"));
+
+ fl3->info_3 = g_new0(FILE_INFO_3 *, (*ftot));
+ fl3->info_3_str = g_new0(FILE_INFO_3_STR *, (*ftot));
+
+ if (fl3->info_3 == NULL || fl3->info_3_str == NULL)
+ {
+ safe_free(fl3->info_3);
+ safe_free(fl3->info_3_str);
+ (*fnum) = 0;
+ return;
+ }
+
+ for (; (*fnum) < (*ftot); (*fnum)++)
+ {
+ fl3->info_3 [num_entries] = g_new(FILE_INFO_3, 1);
+ fl3->info_3_str[num_entries] = g_new(FILE_INFO_3_STR, 1);
+
+ make_srv_file_3_info(fl3->info_3 [num_entries],
+ fl3->info_3_str[num_entries],
+ (*fnum), 0x35, 0,
+ "\\PIPE\\samr", "dummy user");
+
+ /* move on to creating next file */
+ num_entries++;
+ }
+
+ fl3->num_entries_read = num_entries;
+ fl3->ptr_file_info = num_entries > 0 ? 1 : 0;
+ fl3->num_entries_read2 = num_entries;
+
+ if ((*fnum) >= (*ftot))
+ {
+ (*fnum) = 0;
+ }
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_FILE_ENUM structure.
+********************************************************************/
+static uint32 make_srv_file_info_ctr(SRV_FILE_INFO_CTR *ctr,
+ int switch_value, uint32 *resume_hnd, uint32 *total_entries)
+{
+ uint32 status = NT_STATUS_NOPROBLEMO;
+ DEBUG(5,("make_srv_file_info_ctr: %d\n", __LINE__));
+
+ ctr->switch_value = switch_value;
+
+ switch (switch_value)
+ {
+ case 3:
+ {
+ make_srv_file_info_3(&(ctr->file.info3), resume_hnd, total_entries);
+ ctr->ptr_file_ctr = 1;
+ break;
+ }
+ default:
+ {
+ DEBUG(5,("make_srv_file_info_ctr: unsupported switch value %d\n",
+ switch_value));
+ (*resume_hnd = 0);
+ (*total_entries) = 0;
+ ctr->ptr_file_ctr = 0;
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ break;
+ }
+ }
+
+ return status;
+}
+
+/*******************************************************************
+ makes a SRV_R_NET_CONN_ENUM structure.
+********************************************************************/
+static uint32 make_srv_r_net_file_enum( uint32 resume_hnd,
+ int switch_value, SRV_FILE_INFO_CTR *ctr,
+ uint32 *total_entries, ENUM_HND *enum_hnd,
+ uint32 file_level )
+{
+ uint32 status;
+
+ DEBUG(5,("make_srv_r_net_file_enum: %d\n", __LINE__));
+
+ if (file_level == 0)
+ {
+ status = NT_STATUS_INVALID_INFO_CLASS;
+ }
+ else
+ {
+ status = make_srv_file_info_ctr(ctr, switch_value,
+ &resume_hnd, total_entries);
+ }
+ if (status != NT_STATUS_NOPROBLEMO)
+ {
+ resume_hnd = 0;
+ }
+ make_enum_hnd(enum_hnd, resume_hnd);
+
+ return status;
+}
+
+/*******************************************************************
+net file enum
+********************************************************************/
+uint32 _srv_net_file_enum( const UNISTR2 *srv_name,
+ uint32 switch_value, SRV_FILE_INFO_CTR *ctr,
+ uint32 preferred_len, ENUM_HND *enum_hnd,
+ uint32 *total_entries, uint32 file_level )
+{
+ uint32 status;
+
+ DEBUG(5,("_srv_net_file_enum: %d\n", __LINE__));
+
+ /* set up the */
+ status = make_srv_r_net_file_enum(get_enum_hnd(enum_hnd),
+ ctr->switch_value,
+ ctr,
+ total_entries,
+ enum_hnd,
+ file_level );
+
+ DEBUG(5,("_srv_net_file_enum: %d\n", __LINE__));
+
+ return status;
+}
diff --git a/source/srvsvcd/srvsvcd.c b/source/srvsvcd/srvsvcd.c
new file mode 100644
index 00000000000..a224657f2ad
--- /dev/null
+++ b/source/srvsvcd/srvsvcd.c
@@ -0,0 +1,119 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+fstring pipe_name;
+
+pstring servicesf = CONFIGFILE;
+extern pstring debugf;
+extern BOOL append_log;
+
+/*****************************************************************************
+ initialise srv_auth_fns array
+ *****************************************************************************/
+static void msrpc_auth_init(rpcsrv_struct *l)
+{
+}
+
+/*************************************************************************
+ initialise an msrpc service
+ *************************************************************************/
+static void service_init(char* service_name)
+{
+ add_msrpc_command_processor( pipe_name, service_name, api_srvsvc_rpc );
+ generate_wellknown_sids();
+}
+
+/****************************************************************************
+ reload the services file
+ **************************************************************************/
+static BOOL reload_msrpc(BOOL test)
+{
+ BOOL ret;
+
+ if (lp_loaded()) {
+ pstring fname;
+ pstrcpy(fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
+ reopen_logs();
+
+ if (test && !lp_file_list_changed())
+ return(True);
+
+ lp_killunused(NULL);
+
+ ret = lp_load(servicesf,False,False,True);
+
+ /* perhaps the config filename is now set */
+ if (!test)
+ reload_msrpc(True);
+
+ reopen_logs();
+
+ load_interfaces();
+
+ return(ret);
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+static int main_init(int argc,char *argv[])
+{
+#ifdef HAVE_SET_AUTH_PARAMETERS
+ set_auth_parameters(argc,argv);
+#endif
+
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ append_log = True;
+
+ TimeInit();
+
+ setup_logging(argv[0],False);
+ fstrcpy(pipe_name, "srvsvc");
+ slprintf(debugf, sizeof(debugf), "%s/log.%s", LOGFILEBASE, pipe_name);
+
+ return 0;
+}
+
+static msrpc_service_fns fn_table =
+{
+ msrpc_auth_init,
+ service_init,
+ reload_msrpc,
+ main_init,
+ NULL
+};
+
+msrpc_service_fns *get_service_fns(void)
+{
+ return &fn_table;
+}
diff --git a/source/svcctld/srv_svcctl_nt.c b/source/svcctld/srv_svcctl_nt.c
new file mode 100644
index 00000000000..128f6fe39d3
--- /dev/null
+++ b/source/svcctld/srv_svcctl_nt.c
@@ -0,0 +1,345 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-2000,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
+ * Copyright (C) Sander Striker 2000.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+ get_policy_svc_name
+****************************************************************************/
+static BOOL get_policy_svc_name(struct policy_cache *cache,
+ const POLICY_HND *hnd,
+ fstring name)
+{
+ char *dev;
+ dev = (char *)get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ fstrcpy(name, dev);
+ DEBUG(5,("getting policy svc name=%s\n", name));
+ return True;
+ }
+
+ DEBUG(3,("Error getting policy svc name\n"));
+ return False;
+}
+
+/****************************************************************************
+ set_policy_svc_name
+****************************************************************************/
+static BOOL set_policy_svc_name(struct policy_cache *cache, POLICY_HND *hnd,
+ fstring name)
+{
+ char *dev = strdup(name);
+ if (dev != NULL)
+ {
+ if (set_policy_state(cache, hnd, NULL, (void*)dev))
+ {
+ DEBUG(3,("Service setting policy name=%s\n", name));
+ return True;
+ }
+ free(dev);
+ return True;
+ }
+
+ DEBUG(3,("Error setting policy name=%s\n", name));
+ return False;
+}
+
+/*******************************************************************
+ _svc_close
+ ********************************************************************/
+uint32 _svc_close(POLICY_HND *pol)
+{
+
+ /* close the policy handle */
+ if (!close_policy_hnd(get_global_hnd_cache(), pol))
+ {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+
+ /* strikerXXXX Luke, is this line below needed, or does close_policy_hnd()
+ * take care of this? */
+
+ /* set up the REG unknown_1 response */
+ bzero(pol->data, POL_HND_SIZE);
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _svc_open_service
+ ********************************************************************/
+uint32 _svc_open_service(const POLICY_HND *scman_pol,
+ const UNISTR2* uni_svc_name,
+ uint32 des_access,
+ POLICY_HND *pol)
+{
+ fstring name;
+
+ if (find_policy_by_hnd(get_global_hnd_cache(), scman_pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ scman_pol, pol, des_access))
+ {
+ return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
+ }
+
+ unistr2_to_ascii(name, uni_svc_name, sizeof(name)-1);
+
+ DEBUG(5,("svc_open_service: %s\n", name));
+ /* lkcl XXXX do a check on the name, here */
+
+ if (!set_policy_svc_name(get_global_hnd_cache(), pol, name))
+ {
+ return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _svc_stop_service
+ ********************************************************************/
+uint32 _svc_stop_service(const POLICY_HND *pol,
+ uint32 unknown,
+ uint32 *unknown0,
+ uint32 *unknown1,
+ uint32 *unknown2,
+ uint32 *unknown3,
+ uint32 *unknown4,
+ uint32 *unknown5,
+ uint32 *unknown6)
+{
+ fstring svc_name;
+ fstring script;
+
+ if (find_policy_by_hnd(get_global_hnd_cache(), pol) == -1 ||
+ !get_policy_svc_name(get_global_hnd_cache(), pol, svc_name))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ slprintf(script, sizeof(script)-1, "%s/rc.service stop %s/%s.pid %s/%s",
+ SBINDIR, LOCKDIR, svc_name, BINDIR, svc_name);
+
+ DEBUG(10,("stop_service: %s\n", script));
+
+ /* stop the service here */
+ if (smbrun(script, "/tmp/foo", False) == 0)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _svc_start_service
+ ********************************************************************/
+uint32 _svc_start_service(const POLICY_HND *pol,
+ uint32 argc,
+ uint32 argc2,
+ const UNISTR2 *argv)
+{
+ fstring svc_name;
+ pstring script;
+
+ if (find_policy_by_hnd(get_global_hnd_cache(), pol) == -1 ||
+ !get_policy_svc_name(get_global_hnd_cache(), pol, svc_name))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ slprintf(script, sizeof(script)-1, "%s/rc.service start %s/%s.pid %s/%s",
+ SBINDIR, LOCKDIR, svc_name, BINDIR, svc_name);
+
+ DEBUG(10,("svc_start_service: %s\n", script));
+
+ /* start the service here */
+ if (smbrun(script, "/tmp/foo", False) == 0)
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _svc_open_sc_man
+ ********************************************************************/
+uint32 _svc_open_sc_man(const UNISTR2 *uni_srv_name,
+ const UNISTR2 *uni_db_name,
+ uint32 des_access,
+ POLICY_HND *pol)
+{
+ fstring name;
+
+ if (!open_policy_hnd(get_global_hnd_cache(),
+ get_sec_ctx(), pol, des_access))
+ {
+ return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
+ }
+
+ unistr2_to_ascii(name, uni_srv_name, sizeof(name)-1);
+
+ DEBUG(5,("svc_open_sc_man: %s\n", name));
+ /* lkcl XXXX do a check on the name, here */
+
+ if (!set_policy_svc_name(get_global_hnd_cache(), pol, name))
+ {
+ return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _svc_enum_svcs_status
+ ********************************************************************/
+uint32 _svc_enum_svcs_status(const POLICY_HND *pol,
+ uint32 service_type,
+ uint32 service_state,
+ uint32 *buf_size,
+ ENUM_HND *resume_hnd,
+ ENUM_SRVC_STATUS *svcs,
+ uint32 *more_buf_size,
+ uint32 *num_svcs)
+{
+ uint32 dos_status = 0;
+ int i = get_enum_hnd(resume_hnd);
+ uint32 local_resume_hnd = 0;
+ uint32 local_buf_size = 0;
+ uint32 num_entries = 10;
+ char *services[] =
+ {
+ "lsarpcd",
+ "srvsvcd",
+ "wkssvcd",
+ "smbd",
+ "nmbd",
+ "svcctld",
+ "samrd",
+ "spoolssd",
+ "browserd",
+ "winregd"
+ };
+
+ *more_buf_size = 0x10000;
+ *num_svcs = 0;
+
+ if (find_policy_by_hnd(get_global_hnd_cache(), pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ for (i = 0; i < num_entries; i++)
+ {
+ ENUM_SRVC_STATUS *svc = NULL;
+ fstring svc_name;
+ int len;
+
+ fstrcpy(svc_name, services[i]);
+ len = strlen(services[i]);
+
+ local_buf_size += (len+1) * 2;
+ local_buf_size += 9 * sizeof(uint32);
+
+ DEBUG(10,("r_buf_size: %d q_buf_size: %d\n",
+ local_buf_size, *buf_size));
+
+ if (local_buf_size >= *more_buf_size)
+ {
+ local_resume_hnd = i;
+ break;
+ }
+
+ if (local_buf_size > *buf_size)
+ {
+ dos_status = ERRmoredata;
+ break;
+ }
+
+ (*num_svcs)++;
+ if (*num_svcs > MAX_SERVICES)
+ {
+ dos_status = ERRnomem;
+ *num_svcs = 0;
+ break;
+ }
+
+ svc = &svcs[(*num_svcs) - 1];
+ ZERO_STRUCTP(svc);
+
+ make_unistr(&svc->uni_srvc_name, svc_name);
+ make_unistr(&svc->uni_disp_name, svc_name);
+
+ DEBUG(10,("show service: %s\n", svc_name));
+ }
+
+ /*
+ * check for finished condition: no resume handle and last buffer fits
+ */
+
+ if (local_resume_hnd == 0 && local_buf_size <= *buf_size)
+ {
+ /* this indicates, along with resume_hnd of 0, an end. */
+ *more_buf_size = 0;
+ }
+
+ *buf_size = local_buf_size;
+ make_enum_hnd(resume_hnd, local_resume_hnd);
+
+ return dos_status;
+}
+
+/*******************************************************************
+ _svc_query_disp_name
+ ********************************************************************/
+uint32 _svc_query_disp_name(const POLICY_HND *scman_pol,
+ const UNISTR2 *uni_svc_name,
+ uint32 buf_size,
+ UNISTR2 *uni_disp_name,
+ uint32 *pbuf_size)
+{
+ if (find_policy_by_hnd(get_global_hnd_cache(), scman_pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* for now display name = service name */
+ copy_unistr2(uni_disp_name, uni_svc_name);
+ /* and thus the length of the strings is the same */
+ *pbuf_size = buf_size;
+
+ return NT_STATUS_NOPROBLEMO;
+}
diff --git a/source/svcctld/svcctld.c b/source/svcctld/svcctld.c
new file mode 100644
index 00000000000..a2c59a7bd95
--- /dev/null
+++ b/source/svcctld/svcctld.c
@@ -0,0 +1,119 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+fstring pipe_name;
+
+pstring servicesf = CONFIGFILE;
+extern pstring debugf;
+extern BOOL append_log;
+
+/*****************************************************************************
+ initialise srv_auth_fns array
+ *****************************************************************************/
+static void auth_init(rpcsrv_struct *l)
+{
+}
+
+/*************************************************************************
+ initialise an msrpc service
+ *************************************************************************/
+static void service_init(char* service_name)
+{
+ add_msrpc_command_processor( pipe_name, service_name, api_svcctl_rpc );
+ generate_wellknown_sids();
+}
+
+/****************************************************************************
+ reload the services file
+ **************************************************************************/
+static BOOL reload_msrpc(BOOL test)
+{
+ BOOL ret;
+
+ if (lp_loaded()) {
+ pstring fname;
+ pstrcpy(fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
+ reopen_logs();
+
+ if (test && !lp_file_list_changed())
+ return(True);
+
+ lp_killunused(NULL);
+
+ ret = lp_load(servicesf,False,False,True);
+
+ /* perhaps the config filename is now set */
+ if (!test)
+ reload_msrpc(True);
+
+ reopen_logs();
+
+ load_interfaces();
+
+ return(ret);
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+static int main_init(int argc,char *argv[])
+{
+#ifdef HAVE_SET_AUTH_PARAMETERS
+ set_auth_parameters(argc,argv);
+#endif
+
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ append_log = True;
+
+ TimeInit();
+
+ setup_logging(argv[0],False);
+ fstrcpy(pipe_name, "svcctl");
+ slprintf(debugf, sizeof(debugf), "%s/log.%s", LOGFILEBASE, pipe_name);
+
+ return 0;
+}
+
+static msrpc_service_fns fn_table =
+{
+ auth_init,
+ service_init,
+ reload_msrpc,
+ main_init,
+ NULL
+};
+
+msrpc_service_fns *get_service_fns(void)
+{
+ return &fn_table;
+}
diff --git a/source/tdb/.cvsignore b/source/tdb/.cvsignore
index afd8da72c94..af9d6be961b 100644
--- a/source/tdb/.cvsignore
+++ b/source/tdb/.cvsignore
@@ -1,6 +1 @@
-tdbtool
-tdbtest
-tdbtorture
-test.db
-test.gdbm
-test.tdb
+*.lo \ No newline at end of file
diff --git a/source/tdb/README b/source/tdb/README
index 9eef521075a..3b070bdc400 100644
--- a/source/tdb/README
+++ b/source/tdb/README
@@ -66,11 +66,6 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open
----------------------------------------------------------------------
-char *tdb_error(TDB_CONTEXT *tdb);
-
- return a error string for the last tdb error
-
-----------------------------------------------------------------------
int tdb_close(TDB_CONTEXT *tdb);
close a database
@@ -101,10 +96,9 @@ int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key);
----------------------------------------------------------------------
int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb,
- TDB_DATA key, TDB_DATA dbuf, void *state), void *state);
+ TDB_DATA key, TDB_DATA dbuf));
- traverse the entire database - calling fn(tdb, key, data, state) on each
- element.
+ traverse the entire database - calling fn(tdb, key, data) on each element.
return -1 on error or the record count traversed
diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c
index c7b70aa1533..a754c583e60 100644
--- a/source/tdb/tdb.c
+++ b/source/tdb/tdb.c
@@ -92,8 +92,6 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
#else
struct flock fl;
- if (tdb->fd == -1) return 0; /* for in memory tdb */
-
if (tdb->read_only) return -1;
fl.l_type = set==LOCK_SET?rw_type:F_UNLCK;
@@ -196,7 +194,7 @@ static tdb_off tdb_hash_top(TDB_CONTEXT *tdb, unsigned hash)
static int tdb_oob(TDB_CONTEXT *tdb, tdb_off offset)
{
struct stat st;
- if ((offset <= tdb->map_size) || (tdb->fd == -1)) return 0;
+ if (offset <= tdb->map_size) return 0;
fstat(tdb->fd, &st);
if (st.st_size <= (ssize_t)offset) {
@@ -339,10 +337,8 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
length = ((tdb->map_size + length + TDB_PAGE_SIZE) & ~(TDB_PAGE_SIZE - 1)) - tdb->map_size;
/* expand the file itself */
- if (tdb->fd != -1) {
- lseek(tdb->fd, tdb->map_size + length - 1, SEEK_SET);
- if (write(tdb->fd, &b, 1) != 1) goto fail;
- }
+ lseek(tdb->fd, tdb->map_size + length - 1, SEEK_SET);
+ if (write(tdb->fd, &b, 1) != 1) goto fail;
/* form a new freelist record */
offset = FREELIST_TOP;
@@ -353,7 +349,7 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
}
#if HAVE_MMAP
- if (tdb->fd != -1 && tdb->map_ptr) {
+ if (tdb->map_ptr) {
munmap(tdb->map_ptr, tdb->map_size);
tdb->map_ptr = NULL;
}
@@ -361,10 +357,6 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
tdb->map_size += length;
- if (tdb->fd == -1) {
- tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size);
- }
-
/* write it out */
if (rec_write(tdb, tdb->map_size - length, &rec) == -1) {
goto fail;
@@ -375,13 +367,10 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length)
if (ofs_write(tdb, offset, &ptr) == -1) goto fail;
#if HAVE_MMAP
- if (tdb->fd != -1) {
- tdb->map_ptr = (void *)mmap(NULL, tdb->map_size,
- PROT_READ|PROT_WRITE,
- MAP_SHARED | MAP_FILE, tdb->fd, 0);
- }
+ tdb->map_ptr = (void *)mmap(NULL, tdb->map_size,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED | MAP_FILE, tdb->fd, 0);
#endif
-
tdb_unlock(tdb, -1);
return 0;
@@ -489,52 +478,37 @@ static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size)
{
struct tdb_header header;
tdb_off offset;
- int i, size = 0;
+ int i;
tdb_off buf[16];
- /* create the header */
- memset(&header, 0, sizeof(header));
- memcpy(header.magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
- header.version = TDB_VERSION;
- header.hash_size = hash_size;
- lseek(tdb->fd, 0, SEEK_SET);
- ftruncate(tdb->fd, 0);
-
- if (tdb->fd != -1 && write(tdb->fd, &header, sizeof(header)) !=
- sizeof(header)) {
- tdb->ecode = TDB_ERR_IO;
- return -1;
- } else size += sizeof(header);
-
- /* the freelist and hash pointers */
- offset = 0;
- memset(buf, 0, sizeof(buf));
-
- for (i=0;(hash_size+1)-i >= 16; i += 16) {
- if (tdb->fd != -1 && write(tdb->fd, buf, sizeof(buf)) !=
- sizeof(buf)) {
- tdb->ecode = TDB_ERR_IO;
- return -1;
- } else size += sizeof(buf);
- }
-
- for (;i<hash_size+1; i++) {
- if (tdb->fd != -1 && write(tdb->fd, buf, sizeof(tdb_off)) !=
- sizeof(tdb_off)) {
- tdb->ecode = TDB_ERR_IO;
- return -1;
- } else size += sizeof(tdb_off);
- }
+ /* create the header */
+ memset(&header, 0, sizeof(header));
+ memcpy(header.magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1);
+ header.version = TDB_VERSION;
+ header.hash_size = hash_size;
+ lseek(tdb->fd, 0, SEEK_SET);
+ ftruncate(tdb->fd, 0);
- if (tdb->fd == -1) {
- tdb->map_ptr = calloc(size, 1);
- tdb->map_size = size;
- if (tdb->map_ptr == NULL) {
- tdb->ecode = TDB_ERR_IO;
- return -1;
- }
- memcpy(&tdb->header, &header, sizeof(header));
- }
+ if (write(tdb->fd, &header, sizeof(header)) != sizeof(header)) {
+ tdb->ecode = TDB_ERR_IO;
+ return -1;
+ }
+
+ /* the freelist and hash pointers */
+ offset = 0;
+ memset(buf, 0, sizeof(buf));
+ for (i=0;(hash_size+1)-i >= 16; i += 16) {
+ if (write(tdb->fd, buf, sizeof(buf)) != sizeof(buf)) {
+ tdb->ecode = TDB_ERR_IO;
+ return -1;
+ }
+ }
+ for (;i<hash_size+1; i++) {
+ if (write(tdb->fd, buf, sizeof(tdb_off)) != sizeof(tdb_off)) {
+ tdb->ecode = TDB_ERR_IO;
+ return -1;
+ }
+ }
#if TDB_DEBUG
printf("initialised database of hash_size %u\n",
@@ -623,13 +597,6 @@ int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf)
tdb_off rec_ptr;
int ret = -1;
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_update() called with null context\n");
-#endif
- return -1;
- }
-
/* find which hash bucket it is in */
hash = tdb_hash(&key);
@@ -667,13 +634,6 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key)
struct list_struct rec;
TDB_DATA ret = null_data;
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_fetch() called with null context\n");
-#endif
- return null_data;
- }
-
/* find which hash bucket it is in */
hash = tdb_hash(&key);
@@ -727,13 +687,6 @@ int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB
char *data;
TDB_DATA key, dbuf;
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_traverse() called with null context\n");
-#endif
- return -1;
- }
-
/* loop over all hash chains */
for (h = 0; h < tdb->header.hash_size; h++) {
tdb_lock(tdb, BUCKET(h));
@@ -796,13 +749,6 @@ TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb)
unsigned hash;
TDB_DATA ret;
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_firstkey() called with null context\n");
-#endif
- return null_data;
- }
-
/* look for a non-empty hash chain */
for (hash = 0, rec_ptr = 0;
hash < tdb->header.hash_size;
@@ -848,13 +794,6 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key)
struct list_struct rec;
TDB_DATA ret;
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_nextkey() called with null context\n");
-#endif
- return null_data;
- }
-
/* find which hash bucket it is in */
hash = tdb_hash(&key);
hbucket = BUCKET(hash);
@@ -903,13 +842,6 @@ int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key)
struct list_struct rec, lastrec;
char *data = NULL;
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_delete() called with null context\n");
-#endif
- return -1;
- }
-
/* find which hash bucket it is in */
hash = tdb_hash(&key);
@@ -1008,13 +940,6 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag)
tdb_off rec_ptr, offset;
char *p = NULL;
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_store() called with null context\n");
-#endif
- return -1;
- }
-
/* find which hash bucket it is in */
hash = tdb_hash(&key);
@@ -1108,8 +1033,6 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
TDB_CONTEXT tdb, *ret;
struct stat st;
- memset(&tdb, 0, sizeof(tdb));
-
tdb.fd = -1;
tdb.name = NULL;
tdb.map_ptr = NULL;
@@ -1120,14 +1043,14 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
if (hash_size == 0) hash_size = DEFAULT_HASH_SIZE;
+ memset(&tdb, 0, sizeof(tdb));
+
tdb.read_only = ((open_flags & O_ACCMODE) == O_RDONLY);
- if (name != NULL) {
- tdb.fd = open(name, open_flags, mode);
- if (tdb.fd == -1) {
+ tdb.fd = open(name, open_flags, mode);
+ if (tdb.fd == -1) {
goto fail;
- }
- }
+ }
/* ensure there is only one process initialising at once */
tdb_brlock(&tdb, GLOBAL_LOCK, LOCK_SET, F_WRLCK, F_SETLKW);
@@ -1154,32 +1077,23 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
if (tdb_new_database(&tdb, hash_size) == -1) goto fail;
lseek(tdb.fd, 0, SEEK_SET);
- if (tdb.fd != -1 && read(tdb.fd, &tdb.header,
- sizeof(tdb.header)) !=
- sizeof(tdb.header))
- goto fail;
+ if (read(tdb.fd, &tdb.header, sizeof(tdb.header)) != sizeof(tdb.header)) goto fail;
}
- if (tdb.fd != -1) {
- fstat(tdb.fd, &st);
-
- /* map the database and fill in the return structure */
- tdb.name = (char *)strdup(name);
- tdb.map_size = st.st_size;
- }
-
- tdb.locked = (int *)calloc(tdb.header.hash_size+1,
- sizeof(tdb.locked[0]));
- if (!tdb.locked) {
- goto fail;
- }
+ fstat(tdb.fd, &st);
+ /* map the database and fill in the return structure */
+ tdb.name = (char *)strdup(name);
+ tdb.locked = (int *)calloc(tdb.header.hash_size+1,
+ sizeof(tdb.locked[0]));
+ if (!tdb.locked) {
+ goto fail;
+ }
+ tdb.map_size = st.st_size;
#if HAVE_MMAP
- if (tdb.fd != -1) {
- tdb.map_ptr = (void *)mmap(NULL, st.st_size,
- tdb.read_only? PROT_READ : PROT_READ|PROT_WRITE,
- MAP_SHARED | MAP_FILE, tdb.fd, 0);
- }
+ tdb.map_ptr = (void *)mmap(NULL, st.st_size,
+ tdb.read_only? PROT_READ : PROT_READ|PROT_WRITE,
+ MAP_SHARED | MAP_FILE, tdb.fd, 0);
#endif
ret = (TDB_CONTEXT *)malloc(sizeof(tdb));
@@ -1196,7 +1110,7 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags,
return ret;
fail:
- if (tdb.name) free(tdb.name);
+ if (tdb.name) free(tdb.name);
if (tdb.fd != -1) close(tdb.fd);
if (tdb.map_ptr) munmap(tdb.map_ptr, tdb.map_size);
@@ -1210,16 +1124,9 @@ int tdb_close(TDB_CONTEXT *tdb)
if (tdb->name) free(tdb->name);
if (tdb->fd != -1) close(tdb->fd);
+ if (tdb->map_ptr) munmap(tdb->map_ptr, tdb->map_size);
if (tdb->locked) free(tdb->locked);
- if (tdb->map_ptr) {
- if (tdb->fd != -1) {
- munmap(tdb->map_ptr, tdb->map_size);
- } else {
- free(tdb->map_ptr);
- }
- }
-
memset(tdb, 0, sizeof(*tdb));
free(tdb);
@@ -1229,26 +1136,12 @@ int tdb_close(TDB_CONTEXT *tdb)
/* lock the database. If we already have it locked then don't do anything */
int tdb_writelock(TDB_CONTEXT *tdb)
{
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_writelock() called with null context\n");
-#endif
- return -1;
- }
-
return tdb_lock(tdb, -1);
}
/* unlock the database. */
int tdb_writeunlock(TDB_CONTEXT *tdb)
{
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_writeunlock() called with null context\n");
-#endif
- return -1;
- }
-
return tdb_unlock(tdb, -1);
}
@@ -1256,13 +1149,6 @@ int tdb_writeunlock(TDB_CONTEXT *tdb)
contention - it cannot guarantee how many records will be locked */
int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key)
{
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_lockchain() called with null context\n");
-#endif
- return -1;
- }
-
return tdb_lock(tdb, BUCKET(tdb_hash(&key)));
}
@@ -1270,12 +1156,5 @@ int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key)
/* unlock one hash chain */
int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key)
{
- if (tdb == NULL) {
-#ifdef TDB_DEBUG
- printf("tdb_unlockchain() called with null context\n");
-#endif
- return -1;
- }
-
return tdb_unlock(tdb, BUCKET(tdb_hash(&key)));
}
diff --git a/source/tdb/tdbtest.c b/source/tdb/tdbtest.c
index 9728e59a017..0018fd06f25 100644
--- a/source/tdb/tdbtest.c
+++ b/source/tdb/tdbtest.c
@@ -168,7 +168,7 @@ static void addrec_gdbm(void)
free(d);
}
-static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, void *state)
+static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, void* state)
{
#if 0
printf("[%s] [%s]\n", key.dptr, dbuf.dptr);
diff --git a/source/tdb/tdbtool.c b/source/tdb/tdbtool.c
index 317ad9b4fc5..43c7faf2bf1 100644
--- a/source/tdb/tdbtool.c
+++ b/source/tdb/tdbtool.c
@@ -134,7 +134,12 @@ static void delete_tdb(void)
}
}
-static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+static int del_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void*)
+{
+ tdb_delete(tdb, key);
+}
+
+static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void*)
{
printf("%*.*s : %*.*s\n",
(int)key.dsize, (int)key.dsize, key.dptr,
@@ -144,7 +149,7 @@ static int print_rec(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
static int total_bytes;
-static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
+static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void*)
{
total_bytes += dbuf.dsize;
return 0;
@@ -170,12 +175,6 @@ static char *getline(char *prompt)
return p?line:NULL;
}
-static int do_delete_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf,
- void *state)
-{
- return tdb_delete(tdb, key);
-}
-
int main(int argc, char *argv[])
{
char *line;
@@ -205,7 +204,7 @@ int main(int argc, char *argv[])
} else if (strcmp(tok,"show") == 0) {
show_tdb();
} else if (strcmp(tok,"erase") == 0) {
- tdb_traverse(tdb, do_delete_fn, NULL);
+ tdb_traverse(tdb, del_rec, NULL);
} else if (strcmp(tok,"delete") == 0) {
delete_tdb();
} else if (strcmp(tok,"dump") == 0) {
diff --git a/source/tdb/tdbtorture.c b/source/tdb/tdbtorture.c
index 90dcc38aba1..8957fcd6278 100644
--- a/source/tdb/tdbtorture.c
+++ b/source/tdb/tdbtorture.c
@@ -74,8 +74,7 @@ static void addrec_db(void)
free(d);
}
-static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf,
- void *state)
+static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, void* state)
{
tdb_delete(db, key);
return 0;
diff --git a/source/tests/fcntl_lock.c b/source/tests/fcntl_lock.c
index 32aecb87439..a90e00aa000 100644
--- a/source/tests/fcntl_lock.c
+++ b/source/tests/fcntl_lock.c
@@ -1,9 +1,5 @@
/* test whether fcntl locking works on this system */
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -37,8 +33,7 @@ static int sys_waitpid(pid_t pid,int *status,int options)
int main(int argc, char *argv[])
{
struct flock lock;
- int fd, ret, status=1;
- pid_t pid;
+ int fd, pid, ret, status=1;
if (!(pid=fork())) {
sleep(2);
@@ -80,15 +75,5 @@ int main(int argc, char *argv[])
unlink(DATA);
-#if defined(WIFEXITED) && defined(WEXITSTATUS)
- if(WIFEXITED(status)) {
- status = WEXITSTATUS(status);
- } else {
- status = 1;
- }
-#else /* defined(WIFEXITED) && defined(WEXITSTATUS) */
- status = (status == 0) ? 0 : 1;
-#endif /* defined(WIFEXITED) && defined(WEXITSTATUS) */
-
exit(status);
}
diff --git a/source/tests/ftruncate.c b/source/tests/ftruncate.c
index 93282782eed..8d5e8942e37 100644
--- a/source/tests/ftruncate.c
+++ b/source/tests/ftruncate.c
@@ -1,9 +1,6 @@
/* test whether ftruncte() can extend a file */
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
-
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
diff --git a/source/tests/getgroups.c b/source/tests/getgroups.c
index 343fd5a184f..37990e010b8 100644
--- a/source/tests/getgroups.c
+++ b/source/tests/getgroups.c
@@ -7,10 +7,6 @@
array of ints! Ultrix is one culprit
*/
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
diff --git a/source/tests/sgi_sysv_hack.c b/source/tests/sgi_sysv_hack.c
deleted file mode 100644
index 0fb16f11f86..00000000000
--- a/source/tests/sgi_sysv_hack.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* this tests if we need to define SGI_SEMUN_HACK
- if we're using gcc on IRIX 6.5.x. */
-
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/sem.h>
-
-#ifndef HAVE_UNION_SEMUN
-union semun {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
-};
-#endif
-
-union semun_hack {
- int val;
- struct semid_ds *buf;
- unsigned short *array;
- char __dummy[5];
-};
-
-main() {
- struct semid_ds sem_ds;
- union semun_hack suh;
- union semun su;
- int sem_id, ret;
-
- ret = 1;
- sem_id = semget(0xdead6666,1,IPC_CREAT|IPC_EXCL|0777);
- su.buf = &sem_ds;
- suh.buf = &sem_ds;
- if (sem_id != -1) {
- if ((semctl(sem_id, 0, IPC_STAT, su) == -1) &&
- (semctl(sem_id, 0, IPC_STAT, suh) != -1)) {
- ret = 0;
- }
- }
- semctl(sem_id, 0, IPC_RMID, 0);
- return ret;
-}
diff --git a/source/tests/shared_mmap.c b/source/tests/shared_mmap.c
index fcef75d0d61..fb8a2a32d5f 100644
--- a/source/tests/shared_mmap.c
+++ b/source/tests/shared_mmap.c
@@ -1,9 +1,7 @@
/* this tests whether we can use a shared writeable mmap on a file -
as needed for the mmap varient of FAST_SHARE_MODES */
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -18,7 +16,7 @@
main()
{
int *buf;
- int i;
+ int i, pid;
int fd = open(DATA,O_RDWR|O_CREAT|O_TRUNC,0666);
int count=7;
diff --git a/source/tests/sysv_ipc.c b/source/tests/sysv_ipc.c
index 9f0e20957a2..13956ec6f08 100644
--- a/source/tests/sysv_ipc.c
+++ b/source/tests/sysv_ipc.c
@@ -1,9 +1,7 @@
/* this tests whether we can use a sysv shared memory segment
as needed for the sysv varient of FAST_SHARE_MODES */
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ipc.h>
diff --git a/source/tests/trapdoor.c b/source/tests/trapdoor.c
new file mode 100644
index 00000000000..83e10d06130
--- /dev/null
+++ b/source/tests/trapdoor.c
@@ -0,0 +1,25 @@
+/* test for a trapdoor uid system */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+
+main()
+{
+ if (getuid() != 0) {
+ fprintf(stderr,"ERROR: This test must be run as root - assuming non-trapdoor system\n");
+ exit(0);
+ }
+
+ if (seteuid(1) != 0) exit(1);
+ if (geteuid() != 1) exit(1);
+ if (seteuid(0) != 0) exit(1);
+ if (geteuid() != 0) exit(1);
+
+ if (setegid(1) != 0) exit(1);
+ if (getegid() != 1) exit(1);
+ if (setegid(0) != 0) exit(1);
+ if (getegid() != 0) exit(1);
+
+ exit(0);
+}
diff --git a/source/ubiqx/.cvsignore b/source/ubiqx/.cvsignore
index 07da2225c72..5bdd0d0bbe6 100644
--- a/source/ubiqx/.cvsignore
+++ b/source/ubiqx/.cvsignore
@@ -1,3 +1,3 @@
-*.po
+*.[lp]o
*.po32
diff --git a/source/ubiqx/debugparse.c b/source/ubiqx/debugparse.c
index 5da5280f19e..f86ef62fd86 100644
--- a/source/ubiqx/debugparse.c
+++ b/source/ubiqx/debugparse.c
@@ -1,4 +1,4 @@
-/* ========================================================================== **
+/* ************************************************************************== **
* debugparse.c
*
* Copyright (C) 1998 by Christopher R. Hertel
@@ -26,7 +26,7 @@
* -------------------------------------------------------------------------- **
* The important function in this module is dbg_char2token(). The rest is
* basically fluff. (Potentially useful fluff, but still fluff.)
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "debugparse.h"
@@ -305,4 +305,4 @@ void dbg_test( void )
* }
*/
-/* ========================================================================== */
+/* ************************************************************************== */
diff --git a/source/ubiqx/debugparse.h b/source/ubiqx/debugparse.h
index 9ed1777e956..4a576e64e71 100644
--- a/source/ubiqx/debugparse.h
+++ b/source/ubiqx/debugparse.h
@@ -1,6 +1,6 @@
#ifndef DEBUGPARSE_H
#define DEBUGPARSE_H
-/* ========================================================================== **
+/* ************************************************************************== **
* debugparse.c
*
* Copyright (C) 1998 by Christopher R. Hertel
@@ -28,7 +28,7 @@
* -------------------------------------------------------------------------- **
* The important function in this module is dbg_char2token(). The rest is
* basically fluff. (Potentially useful fluff, but still fluff.)
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "sys_include.h"
diff --git a/source/ubiqx/sys_include.h b/source/ubiqx/sys_include.h
index 8ff270afe85..2ed30e0510b 100644
--- a/source/ubiqx/sys_include.h
+++ b/source/ubiqx/sys_include.h
@@ -1,6 +1,6 @@
#ifndef SYS_INCLUDE_H
#define SYS_INCLUDE_H
-/* ========================================================================== **
+/* ************************************************************************== **
* sys_include.h
*
* Copyright (C) 1998 by Christopher R. Hertel
@@ -29,7 +29,7 @@
*
* Samba version of sys_include.h
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#ifndef _INCLUDES_H
@@ -40,7 +40,6 @@
*/
#define _PROTO_H_
#define _NAMESERV_H_
-#define _HASH_H_
/* The main Samba system-adaptive header file.
*/
@@ -48,5 +47,5 @@
#endif /* _INCLUDES_H */
-/* ================================ The End ================================= */
+/* ******************************** The End ********************************= */
#endif /* SYS_INCLUDE_H */
diff --git a/source/ubiqx/ubi_BinTree.c b/source/ubiqx/ubi_BinTree.c
index 4e96c1d0ac8..c5a3ea930e5 100644
--- a/source/ubiqx/ubi_BinTree.c
+++ b/source/ubiqx/ubi_BinTree.c
@@ -1,4 +1,4 @@
-/* ========================================================================== **
+/* ************************************************************************== **
* ubi_BinTree.c
*
* Copyright (C) 1991-1998 by Christopher R. Hertel
@@ -152,12 +152,12 @@
*
* V0.0 - June, 1991 - Written by Christopher R. Hertel (CRH).
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "ubi_BinTree.h" /* Header for this module. */
-/* ========================================================================== **
+/* ************************************************************************== **
* Static data.
*/
@@ -166,7 +166,7 @@ static char ModuleID[] = "ubi_BinTree\n\
\tDate: 1998/10/21 06:14:42\n\
\tAuthor: crh\n";
-/* ========================================================================== **
+/* ************************************************************************== **
* Internal (private) functions.
*/
@@ -462,7 +462,7 @@ static ubi_btNodePtr Border( ubi_btRootPtr RootPtr,
} /* Border */
-/* ========================================================================== **
+/* ************************************************************************== **
* Exported utilities.
*/
@@ -1092,4 +1092,4 @@ int ubi_btModuleID( int size, char *list[] )
} /* ubi_btModuleID */
-/* ========================================================================== */
+/* ************************************************************************== */
diff --git a/source/ubiqx/ubi_BinTree.h b/source/ubiqx/ubi_BinTree.h
index 53758246572..3be16e322ba 100644
--- a/source/ubiqx/ubi_BinTree.h
+++ b/source/ubiqx/ubi_BinTree.h
@@ -1,6 +1,6 @@
#ifndef UBI_BINTREE_H
#define UBI_BINTREE_H
-/* ========================================================================== **
+/* ************************************************************************== **
* ubi_BinTree.h
*
* Copyright (C) 1991-1998 by Christopher R. Hertel
@@ -154,7 +154,7 @@
*
* V0.0 - June, 1991 - Written by Christopher R. Hertel (CRH).
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "sys_include.h" /* Global include file, used to adapt the ubiqx
@@ -824,5 +824,5 @@ int ubi_btModuleID( int size, char *list[] );
#define ubi_trModuleID( s, l ) ubi_btModuleID( s, l )
-/* ========================================================================== */
+/* ************************************************************************== */
#endif /* UBI_BINTREE_H */
diff --git a/source/ubiqx/ubi_Cache.c b/source/ubiqx/ubi_Cache.c
index f6081374ef9..59d7bd95743 100644
--- a/source/ubiqx/ubi_Cache.c
+++ b/source/ubiqx/ubi_Cache.c
@@ -1,4 +1,4 @@
-/* ========================================================================== **
+/* ************************************************************************== **
* ubi_Cache.c
*
* Copyright (C) 1997 by Christopher R. Hertel
@@ -105,7 +105,7 @@
* Revision 0.0 1997/12/18 06:24:33 crh
* Initial Revision.
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "ubi_Cache.h" /* Header for *this* module. */
diff --git a/source/ubiqx/ubi_Cache.h b/source/ubiqx/ubi_Cache.h
index 76aab3172e5..35cc5ca516f 100644
--- a/source/ubiqx/ubi_Cache.h
+++ b/source/ubiqx/ubi_Cache.h
@@ -1,6 +1,6 @@
#ifndef UBI_CACHE_H
#define UBI_CACHE_H
-/* ========================================================================== **
+/* ************************************************************************== **
* ubi_Cache.h
*
* Copyright (C) 1997 by Christopher R. Hertel
@@ -107,7 +107,7 @@
* Revision 0.0 1997/12/18 06:25:23 crh
* Initial Revision.
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "ubi_SplayTree.h"
diff --git a/source/ubiqx/ubi_SplayTree.c b/source/ubiqx/ubi_SplayTree.c
index ad8d568658d..88f6c1f6548 100644
--- a/source/ubiqx/ubi_SplayTree.c
+++ b/source/ubiqx/ubi_SplayTree.c
@@ -1,4 +1,4 @@
-/* ========================================================================== **
+/* ************************************************************************== **
* ubi_SplayTree.c
*
* Copyright (C) 1993-1998 by Christopher R. Hertel
@@ -153,12 +153,12 @@
* Initial version, written by Christopher R. Hertel.
* This module implements Splay Trees using the ubi_BinTree module as a basis.
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "ubi_SplayTree.h" /* Header for THIS module. */
-/* ========================================================================== **
+/* ************************************************************************== **
* Static data.
*/
@@ -168,7 +168,7 @@ static char ModuleID[] = "ubi_SplayTree\n\
\tAuthor: crh \n";
-/* ========================================================================== **
+/* ************************************************************************== **
* Private functions...
*/
@@ -247,7 +247,7 @@ static ubi_btNodePtr Splay( ubi_btNodePtr SplayWithMe )
return( SplayWithMe );
} /* Splay */
-/* ========================================================================== **
+/* ************************************************************************== **
* Exported utilities.
*/
@@ -505,5 +505,5 @@ int ubi_sptModuleID( int size, char *list[] )
return( 0 );
} /* ubi_sptModuleID */
-/* ================================ The End ================================= */
+/* ******************************** The End ********************************= */
diff --git a/source/ubiqx/ubi_SplayTree.h b/source/ubiqx/ubi_SplayTree.h
index 0b62f7f7e79..6a311f3958d 100644
--- a/source/ubiqx/ubi_SplayTree.h
+++ b/source/ubiqx/ubi_SplayTree.h
@@ -1,6 +1,6 @@
#ifndef UBI_SPLAYTREE_H
#define UBI_SPLAYTREE_H
-/* ========================================================================== **
+/* ************************************************************************== **
* ubi_SplayTree.h
*
* Copyright (C) 1993-1998 by Christopher R. Hertel
@@ -148,12 +148,12 @@
* Initial version, written by Christopher R. Hertel.
* This module implements Splay Trees using the ubi_BinTree module as a basis.
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "ubi_BinTree.h" /* Base binary tree functions, types, etc. */
-/* ========================================================================== **
+/* ************************************************************************== **
* Function prototypes...
*/
@@ -367,5 +367,5 @@ int ubi_sptModuleID( int size, char *list[] );
#define ubi_trModuleID( s, l ) ubi_sptModuleID( s, l )
-/* ================================ The End ================================= */
+/* ******************************** The End ********************************= */
#endif /* UBI_SPLAYTREE_H */
diff --git a/source/ubiqx/ubi_dLinkList.c b/source/ubiqx/ubi_dLinkList.c
index c780bd1df84..8f716c7228a 100644
--- a/source/ubiqx/ubi_dLinkList.c
+++ b/source/ubiqx/ubi_dLinkList.c
@@ -1,4 +1,4 @@
-/* ========================================================================== **
+/* ************************************************************************== **
* ubi_dLinkList.c
*
* Copyright (C) 1997, 1998 by Christopher R. Hertel
@@ -67,12 +67,12 @@
* while the ubi_slRemove() function (in ubi_sLinkList) removes the node
* *following* the indicated node.
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "ubi_dLinkList.h" /* Header for *this* module. */
-/* ========================================================================== **
+/* ************************************************************************== **
* Functions...
*/
@@ -162,4 +162,4 @@ ubi_dlNodePtr ubi_dlRemove( ubi_dlListPtr ListPtr, ubi_dlNodePtr Old )
return( Old );
} /* ubi_dlRemove */
-/* ================================ The End ================================= */
+/* ******************************** The End ********************************= */
diff --git a/source/ubiqx/ubi_dLinkList.h b/source/ubiqx/ubi_dLinkList.h
index 548f8e5200d..868672e15f8 100644
--- a/source/ubiqx/ubi_dLinkList.h
+++ b/source/ubiqx/ubi_dLinkList.h
@@ -1,6 +1,6 @@
#ifndef UBI_DLINKLIST_H
#define UBI_DLINKLIST_H
-/* ========================================================================== **
+/* ************************************************************************== **
* ubi_dLinkList.h
*
* Copyright (C) 1997, 1998 by Christopher R. Hertel
@@ -69,12 +69,12 @@
* while the ubi_slRemove() function (in ubi_sLinkList) removes the node
* *following* the indicated node.
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "sys_include.h" /* System-specific includes. */
-/* ========================================================================== **
+/* ************************************************************************== **
* Typedefs...
*
* ubi_dlNode - This is the basic node structure.
@@ -101,7 +101,7 @@ typedef struct
typedef ubi_dlList *ubi_dlListPtr;
-/* ========================================================================== **
+/* ************************************************************************== **
* Macros...
*
* ubi_dlNewList - Macro used to declare and initialize a new list in one
@@ -181,7 +181,7 @@ typedef ubi_dlList *ubi_dlListPtr;
#define ubi_dlEnqueue ubi_dlAddTail
#define ubi_dlDequeue ubi_dlRemHead
-/* ========================================================================== **
+/* ************************************************************************== **
* Function prototypes...
*/
@@ -232,5 +232,5 @@ ubi_dlNodePtr ubi_dlRemove( ubi_dlListPtr ListPtr, ubi_dlNodePtr Old );
* ------------------------------------------------------------------------ **
*/
-/* ================================ The End ================================= */
+/* ******************************** The End ********************************= */
#endif /* UBI_DLINKLIST_H */
diff --git a/source/ubiqx/ubi_sLinkList.c b/source/ubiqx/ubi_sLinkList.c
index 25eb5f7e41e..0a19b389e44 100644
--- a/source/ubiqx/ubi_sLinkList.c
+++ b/source/ubiqx/ubi_sLinkList.c
@@ -1,4 +1,4 @@
-/* ========================================================================== **
+/* ************************************************************************== **
* ubi_sLinkList.c
*
* Copyright (C) 1997, 1998 by Christopher R. Hertel
@@ -92,12 +92,12 @@
* node. In ubi_dLinkList, the ubi_dlRemove() function removes
* the 'current' node.
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "ubi_sLinkList.h" /* Header for *this* module. */
-/* ========================================================================== **
+/* ************************************************************************== **
* Functions...
*/
@@ -178,4 +178,4 @@ ubi_slNodePtr ubi_slRemove( ubi_slListPtr ListPtr, ubi_slNodePtr After )
return( DelNode );
} /* ubi_slRemove */
-/* ================================ The End ================================= */
+/* ******************************** The End ********************************= */
diff --git a/source/ubiqx/ubi_sLinkList.h b/source/ubiqx/ubi_sLinkList.h
index 1f331cd5b94..aff588c4756 100644
--- a/source/ubiqx/ubi_sLinkList.h
+++ b/source/ubiqx/ubi_sLinkList.h
@@ -1,6 +1,6 @@
#ifndef UBI_SLINKLIST_H
#define UBI_SLINKLIST_H
-/* ========================================================================== **
+/* ************************************************************************== **
* ubi_sLinkList.h
*
* Copyright (C) 1997, 1998 by Christopher R. Hertel
@@ -94,12 +94,12 @@
* node. In ubi_dLinkList, the ubi_dlRemove() function removes
* the 'current' node.
*
- * ========================================================================== **
+ * ************************************************************************== **
*/
#include "sys_include.h" /* System-specific includes. */
-/* ========================================================================== **
+/* ************************************************************************== **
* Typedefs...
*
* ubi_slNode - This is the basic node structure.
@@ -126,7 +126,7 @@ typedef struct
typedef ubi_slList *ubi_slListPtr;
-/* ========================================================================== **
+/* ************************************************************************** **
* Macros...
*
* ubi_slNewList - Macro used to declare and initialize a list header in
@@ -192,7 +192,7 @@ typedef ubi_slList *ubi_slListPtr;
#define ubi_slEnqueue ubi_slAddTail
#define ubi_slDequeue ubi_slRemHead
-/* ========================================================================== **
+/* ************************************************************************** **
* Function prototypes...
*/
@@ -244,5 +244,5 @@ ubi_slNodePtr ubi_slRemove( ubi_slListPtr ListPtr, ubi_slNodePtr After );
* ------------------------------------------------------------------------ **
*/
-/* ================================ The End ================================= */
+/* ******************************** The End ********************************* */
#endif /* UBI_SLINKLIST_H */
diff --git a/source/utils/debug2html.c b/source/utils/debug2html.c
index f9a1f43f461..b6ba43ea368 100644
--- a/source/utils/debug2html.c
+++ b/source/utils/debug2html.c
@@ -1,4 +1,4 @@
-/* ========================================================================== **
+/* ************************************************************************** **
* debug2html.c
*
* Copyright (C) 1998 by Christopher R. Hertel
@@ -28,36 +28,19 @@
* does a decent job of converting Samba logs into HTML.
* -------------------------------------------------------------------------- **
*
- * Revision 1.4 1998/11/13 03:37:01 tridge
- * fixes for OSF1 compilation
+ * $Revision: 1.9.2.1 $
*
- * Revision 1.3 1998/10/28 20:33:35 crh
- * I've moved the debugparse module files into the ubiqx directory because I
- * know that 'make proto' will ignore them there. The debugparse.h header
- * file is included in includes.h, and includes.h is included in debugparse.c,
- * so all of the pieces "see" each other. I've compiled and tested this,
- * and it does seem to work. It's the same compromise model I used when
- * adding the ubiqx modules into the system, which is why I put it all into
- * the same directory.
- *
- * Chris -)-----
- *
- * Revision 1.1 1998/10/26 23:21:37 crh
- * Here is the simple debug parser and the debug2html converter. Still to do:
- *
- * * Debug message filtering.
- * * I need to add all this to Makefile.in
- * (If it looks at all strange I'll ask for help.)
- *
- * If you want to compile debug2html, you'll need to do it by hand until I
- * make the changes to Makefile.in. Sorry.
- *
- * Chris -)-----
- *
- * ========================================================================== **
+ * ************************************************************************** **
*/
-#include "debugparse.h"
+#include "includes.h"
+
+/* -------------------------------------------------------------------------- **
+ * Global values.
+ */
+
+FILE *infile;
+FILE *outfile;
/* -------------------------------------------------------------------------- **
* The size of the read buffer.
@@ -98,7 +81,7 @@ static dbg_Token modechange( dbg_Token new, dbg_Token mode )
if( dbg_message != mode )
{
/* Switching to message mode. */
- (void)printf( "<PRE>\n" );
+ (void)fprintf( outfile, "<PRE>\n" );
return( dbg_message );
}
break;
@@ -106,7 +89,7 @@ static dbg_Token modechange( dbg_Token new, dbg_Token mode )
if( dbg_message == mode )
{
/* Switching out of message mode. */
- (void)printf( "</PRE>\n\n" );
+ (void)fprintf( outfile, "</PRE>\n\n" );
return( dbg_null );
}
}
@@ -134,29 +117,33 @@ static void newblock( dbg_Token old, dbg_Token new )
switch( old )
{
case dbg_timestamp:
- (void)printf( ",</B>" );
+ (void)fprintf( outfile, ",</B>" );
break;
case dbg_level:
- (void)printf( "</FONT>]</B>\n " );
+ (void)fprintf( outfile, "</FONT>]</B>\n " );
break;
case dbg_sourcefile:
- (void)printf( ":" );
+ (void)fprintf( outfile, ":" );
break;
case dbg_lineno:
- (void)printf( ")" );
+ (void)fprintf( outfile, ")" );
+ break;
+ default:
break;
}
switch( new )
{
case dbg_timestamp:
- (void)printf( "<B>[" );
+ (void)fprintf( outfile, "<B>[" );
break;
case dbg_level:
- (void)printf( " <B><FONT COLOR=MAROON>" );
+ (void)fprintf( outfile, " <B><FONT COLOR=MAROON>" );
break;
case dbg_lineno:
- (void)printf( "(" );
+ (void)fprintf( outfile, "(" );
+ break;
+ default:
break;
}
} /* newblock */
@@ -180,41 +167,38 @@ static void charprint( dbg_Token tok, int c )
break;
case dbg_null:
case dbg_eof:
- (void)putchar( '\n' );
+ (void)putc( '\n', outfile );
break;
default:
switch( c )
{
case '<':
- (void)printf( "&lt;" );
+ (void)fprintf( outfile, "&lt;" );
break;
case '>':
- (void)printf( "&gt;" );
+ (void)fprintf( outfile, "&gt;" );
break;
case '&':
- (void)printf( "&amp;" );
+ (void)fprintf( outfile, "&amp;" );
break;
case '\"':
- (void)printf( "&#34;" );
+ (void)fprintf( outfile, "&#34;" );
break;
default:
- (void)putchar( c );
+ (void)putc( c, outfile );
break;
}
}
} /* charprint */
-int main( int argc, char *argv[] )
+static void convert( void )
/* ------------------------------------------------------------------------ **
- * This simple program scans and parses Samba debug logs, and produces HTML
- * output.
- *
- * Input: argc - Currently ignored.
- * argv - Currently ignored.
- *
- * Output: Always zero.
+ * Read the input logfile, converting the entries to HTML.
*
- * Notes: The HTML output is sent to stdout.
+ * Input: none.
+ * output: none.
+ * Notes: Reads from the global infile, writes to the global outfile.
+ * These default to stdin and stdout, respectively.
*
* ------------------------------------------------------------------------ **
*/
@@ -227,12 +211,8 @@ int main( int argc, char *argv[] )
state = dbg_null,
mode = dbg_null;
- (void)printf( "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n" );
- (void)printf( "<HTML>\n<HEAD>\n" );
- (void)printf( " <TITLE>Samba Debug Output</TITLE>\n</HEAD>\n\n<BODY>\n" );
-
- while( (!feof( stdin ))
- && ((len = fread( bufr, 1, DBG_BSIZE, stdin )) > 0) )
+ while( (!feof( infile ))
+ && ((len = fread( bufr, 1, DBG_BSIZE, infile )) > 0) )
{
for( i = 0; i < len; i++ )
{
@@ -248,6 +228,94 @@ int main( int argc, char *argv[] )
}
(void)modechange( dbg_eof, mode );
- (void)printf( "</BODY>\n</HTML>\n" );
+ } /* convert */
+
+static void usage( void )
+ /* ------------------------------------------------------------------------ **
+ * Prints a usage message on stderr, then gently exits.
+ *
+ * Input: none.
+ * Output: none. Exits with return code of 0.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ fprintf( stderr, "This utility converts Samba log files " );
+ fprintf( stderr, "into HTML documents.\n" );
+ fprintf( stderr, "Usage:\n" );
+ fprintf( stderr, " debug2html <infile> <outfile>\n" );
+ exit( 0 );
+ } /* usage */
+
+static FILE *carefull_fopen( const char *path, const char *type )
+ /* ------------------------------------------------------------------------ **
+ * Checks for leading '-' characters, which are generically regarded as
+ * flags. Also exits the program gracefully should the file fail to open.
+ *
+ * Input: path - pathname of the file to open.
+ * type - open mode. See fopen(3S).
+ *
+ * Output: Pointer to open file.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ FILE *tmp;
+
+ if( '-' == path[0] || '\0' == path[0] )
+ usage();
+
+ tmp = sys_fopen( path, type );
+ if( NULL == tmp )
+ {
+ fprintf( stderr, "Error opening file %s: %s\n", path, strerror(errno) );
+ exit( 1 );
+ }
+ return( tmp );
+ } /* carefull_fopen */
+
+int main( int argc, char *argv[] )
+ /* ------------------------------------------------------------------------ **
+ * This simple program scans and parses Samba debug logs, and produces HTML
+ * output.
+ *
+ * Input: argc - Argument count.
+ * argv[1] - Input file name.
+ * argv[2] - Output file name.
+ * A '-' character by itself means use defaults (i.e.,
+ * <stdin> or <stdout> depending upon the argument.
+ * A string beginning with '-' and containing more than
+ * that one character will generate a usage message.
+ *
+ * Output: An exit value of 1 is returned if an error was encountered
+ * while opening a file, else 0.
+ *
+ * Notes: The HTML output is sent to stdout.
+ *
+ * ------------------------------------------------------------------------ **
+ */
+ {
+ if( argc > 3 )
+ usage();
+
+ infile = stdin;
+ outfile = stdout;
+
+ if( argc > 1 && 0 != strcmp( argv[1], "-" ) )
+ infile = carefull_fopen( argv[1], "r" );
+
+ if( argc > 2 && 0 != strcmp( argv[2], "-" ) )
+ infile = carefull_fopen( argv[2], "w" );
+
+ (void)fprintf( outfile,
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n" );
+ (void)fprintf( outfile, "<HTML>\n<HEAD>\n" );
+ (void)fprintf( outfile,
+ " <TITLE>Samba Log</TITLE>\n</HEAD>\n\n<BODY>\n" );
+
+ convert();
+
+ (void)fprintf( outfile, "</BODY>\n</HTML>\n" );
+
return( 0 );
} /* main */
diff --git a/source/utils/make_printerdef.c b/source/utils/make_printerdef.c
index 33aec325c2e..68b603bf1f6 100644
--- a/source/utils/make_printerdef.c
+++ b/source/utils/make_printerdef.c
@@ -27,7 +27,7 @@
*/
char *files_to_copy;
-char *driverfile, *datafile, *helpfile, *languagemonitor, *datatype, *vendorsetup;
+char *driverfile, *datafile, *helpfile, *languagemonitor, *datatype;
char buffer[50][sizeof(pstring)];
char sbuffer[50][sizeof(pstring)];
char sub_dir[50][2][sizeof(pstring)];
@@ -96,20 +96,13 @@ static char *scan(char *chaine,char **entry)
i++;
}
(*entry)[i]='\0';
- if (temp[i]!='\0') {
- i++;
- }
- while( temp[i]==' ' && temp[i]!='\0') {
- i++;
- }
- pstrcpy(value,temp+i);
+ pstrcpy(value,temp+i+1);
return (value);
}
static void build_subdir(void)
{
int i=0;
- int j=0;
char *entry;
char *data;
@@ -118,18 +111,12 @@ static void build_subdir(void)
#ifdef DEBUGIT
fprintf(stderr,"\tentry=data %s:%s\n",entry,data);
#endif
- j = strlen(entry);
- while (j) {
- if (entry[j-1] != ' ') break;
- j--;
- }
- entry[j] = '\0';
- if (strncmp(data,"11",2)==0) {
+ if (strcmp(data,"11")==0) {
pstrcpy(sub_dir[i][0],entry);
pstrcpy(sub_dir[i][1],"");
}
- if (strncmp(data,"23",2)==0) {
+ if (strcmp(data,"23")==0) {
pstrcpy(sub_dir[i][0],entry);
pstrcpy(sub_dir[i][1],"color\\");
}
@@ -189,13 +176,6 @@ static void lookup_strings(FILE *fichier)
pointeur++;
}
}
-
- /* CCMRCF Mod, seg fault or worse if not found */
- if (pointeur == 0) {
- fprintf(stderr,"Printer not found\tNo [Strings] block in inf file\n");
- exit(2);
- }
-
#ifdef DEBUGIT
fprintf(stderr,"\t\tFound %d entries\n",pointeur-1);
#endif
@@ -375,21 +355,15 @@ static void scan_copyfiles(FILE *fichier, char *chaine)
else break;
}
}
- if (*buffer[i] != ';') {
- if (strlen(files_to_copy) != 0)
- pstrcat(files_to_copy,",");
- pstrcat(files_to_copy,direc);
- pstrcat(files_to_copy,buffer[i]);
- fprintf(stderr,"%s%s\n",direc,buffer[i]);
- }
+ if (strlen(files_to_copy) != 0)
+ pstrcat(files_to_copy,",");
+ pstrcat(files_to_copy,direc);
+ pstrcat(files_to_copy,buffer[i]);
+ fprintf(stderr,"%s%s\n",direc,buffer[i]);
i++;
}
}
part=strtok(NULL,",");
- if (part)
- while( *part ==' ' && *part != '\0') {
- part++;
- }
}
while (part!=NULL);
fprintf(stderr,"\n");
@@ -404,7 +378,6 @@ static void scan_short_desc(FILE *fichier, char *short_desc)
helpfile=0;
languagemonitor=0;
- vendorsetup=0;
datatype="RAW";
if((temp=(char *)malloc(sizeof(pstring))) == NULL) {
fprintf(stderr, "scan_short_desc: malloc fail !\n");
@@ -434,8 +407,6 @@ static void scan_short_desc(FILE *fichier, char *short_desc)
languagemonitor=scan(buffer[i],&temp);
else if (strncasecmp(buffer[i],"DefaultDataType",15)==0)
datatype=scan(buffer[i],&temp);
- else if (strncasecmp(buffer[i],"VendorSetup",11)==0)
- vendorsetup=scan(buffer[i],&temp);
i++;
}
@@ -461,8 +432,6 @@ static void scan_short_desc(FILE *fichier, char *short_desc)
languagemonitor=scan(buffer[i],&temp);
else if (strncasecmp(buffer[i],"DefaultDataType",15)==0)
datatype=scan(buffer[i],&temp);
- else if (strncasecmp(buffer[i],"VendorSetup",11)==0)
- vendorsetup=scan(buffer[i],&temp);
i++;
}
}
@@ -488,8 +457,6 @@ static void scan_short_desc(FILE *fichier, char *short_desc)
helpfile?helpfile:"(null)");
fprintf(stderr,"LanguageMonitor: %s\n",
languagemonitor?languagemonitor:"(null)");
- fprintf(stderr,"VendorSetup: %s\n",
- vendorsetup?vendorsetup:"(null)");
if (copyfiles) scan_copyfiles(fichier,copyfiles);
}
diff --git a/source/utils/make_smbcodepage.c b/source/utils/make_smbcodepage.c
index f0b68a7baea..a57af2fc440 100644
--- a/source/utils/make_smbcodepage.c
+++ b/source/utils/make_smbcodepage.c
@@ -3,7 +3,7 @@
Version 1.9.
Create codepage files from codepage_def.XXX files.
- Copyright (C) Jeremy Allison 1997-1999.
+ Copyright (C) Jeremy Allison 1997-1998.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -62,7 +62,7 @@ static void read_line( char **buf, char *line_buf, int size)
* Returns the number of lines copied.
*/
-static int clean_data( char **buf, size_t *size)
+static int clean_data( char **buf, uint32 *size)
{
pstring linebuf;
char *p = *buf;
@@ -165,7 +165,7 @@ static void parse_error(char *buf, char *msg)
static int do_compile(int codepage, char *input_file, char *output_file)
{
FILE *fp = NULL;
- size_t size = 0;
+ uint32 size = 0;
char *buf = NULL;
char output_buf[CODEPAGE_HEADER_SIZE + 4 * MAXCODEPAGELINES];
int num_lines = 0;
@@ -309,7 +309,7 @@ definition file. File %s has %d.\n", prog_name, MAXCODEPAGELINES, input_file, nu
static int do_decompile( int codepage, char *input_file, char *output_file)
{
- size_t size = 0;
+ uint32 size = 0;
SMB_STRUCT_STAT st;
char header_buf[CODEPAGE_HEADER_SIZE];
char *buf = NULL;
@@ -325,7 +325,7 @@ static int do_decompile( int codepage, char *input_file, char *output_file)
exit(1);
}
- size = (size_t)st.st_size;
+ size = (uint32)st.st_size;
if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 256))
{
diff --git a/source/utils/masktest.c b/source/utils/masktest.c
deleted file mode 100644
index a1fe6d21868..00000000000
--- a/source/utils/masktest.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 2.0
- mask_match tester
- Copyright (C) Andrew Tridgell 1999
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program 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 General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#define NO_SYSLOG
-
-#include "includes.h"
-
-extern int DEBUGLEVEL;
-static fstring password;
-static fstring username;
-static fstring workgroup;
-static int got_pass;
-
-static BOOL showall = False;
-
-static char *maskchars = "<>\"?*abc.";
-static char *filechars = "abcdefghijklm.";
-
-char *standard_masks[] = {"*", "*.", "*.*",
- ".*", "d2.??", "d2\">>", "??",
- NULL};
-char *standard_files[] = {"abc", "abc.", ".abc",
- "abc.def", "abc.de.f",
- "d2.x",
- NULL};
-
-
-#include <regex.h>
-
-static BOOL reg_match_one(char *pattern, char *file)
-{
- pstring rpattern;
- pstring rfile;
-
- pstrcpy(rpattern, pattern);
-
- if (strcmp(file,"..") == 0) file = ".";
- if (strcmp(rpattern,".") == 0) return False;
-
- all_string_sub(rpattern,"\"", ".", 0);
- all_string_sub(rpattern,"<", "*", 0);
-
- all_string_sub(rpattern,"*>", "*", 0);
- all_string_sub(rpattern,">*", "*", 0);
- all_string_sub(rpattern,">", "?", 0);
-
- if (is_8_3(file, False)) {
- return fnmatch(rpattern, file, 0)==0;
- }
-
- pstrcpy(rfile, file);
- mangle_name_83(rfile);
- strlower(rfile);
-
- return (fnmatch(rpattern, file, 0)==0 ||
- fnmatch(rpattern, rfile, 0)==0);
-}
-
-static BOOL regex_reg_match_one(char *pattern, char *file)
-{
- pstring rpattern;
- regex_t preg;
- BOOL ret = False;
-
- return fnmatch(pattern, file, 0)==0;
-
- if (strcmp(file,"..") == 0) file = ".";
- if (strcmp(pattern,".") == 0) return False;
-
- if (strcmp(pattern,"") == 0) {
- if (strcmp(file,".") == 0) return False;
- return True;
- }
-
- pstrcpy(rpattern,"^");
- pstrcat(rpattern, pattern);
-
- all_string_sub(rpattern,".", "[.]", 0);
- all_string_sub(rpattern,"?", ".{1}", 0);
- all_string_sub(rpattern,"*", ".*", 0);
- all_string_sub(rpattern+strlen(rpattern)-1,">", "([^.]?|[.]?$)", 0);
- all_string_sub(rpattern,">", "[^.]?", 0);
-
- all_string_sub(rpattern,"<[.]", ".*[.]", 0);
- all_string_sub(rpattern,"<\"", "(.*[.]|.*$)", 0);
- all_string_sub(rpattern,"<", "([^.]*|[^.]*[.]|[.][^.]*|[.].*[.])", 0);
- if (strlen(pattern)>1) {
- all_string_sub(rpattern+strlen(rpattern)-1,"\"", "[.]?", 0);
- }
- all_string_sub(rpattern,"\"", "([.]|$)", 0);
- pstrcat(rpattern,"$");
-
- /* printf("pattern=[%s] rpattern=[%s]\n", pattern, rpattern); */
-
- regcomp(&preg, rpattern, REG_ICASE|REG_NOSUB|REG_EXTENDED);
- ret = (regexec(&preg, file, 0, NULL, 0) == 0);
-
- regfree(&preg);
-
- return ret;
-}
-
-static char *reg_test(char *pattern, char *file)
-{
- static fstring ret;
- fstrcpy(ret, "---");
-
- pattern = 1+strrchr(pattern,'\\');
- file = 1+strrchr(file,'\\');
-
- if (reg_match_one(pattern, ".")) ret[0] = '+';
- if (reg_match_one(pattern, "..")) ret[1] = '+';
- if (reg_match_one(pattern, file)) ret[2] = '+';
- return ret;
-}
-
-
-/*****************************************************
-return a connection to a server
-*******************************************************/
-struct cli_state *connect_one(char *share)
-{
- struct cli_state *c;
- struct nmb_name called, calling;
- char *server_n;
- char *server;
- struct in_addr ip;
- extern struct in_addr ipzero;
-
- server = share+2;
- share = strchr(server,'\\');
- if (!share) return NULL;
- *share = 0;
- share++;
-
- server_n = server;
-
- ip = ipzero;
-
- make_nmb_name(&calling, "masktest", 0x0);
- make_nmb_name(&called , server, 0x20);
-
- again:
- ip = ipzero;
-
- /* have to open a new connection */
- if (!(c=cli_initialise(NULL)) || (cli_set_port(c, 139) == 0) ||
- !cli_connect(c, server_n, &ip)) {
- DEBUG(0,("Connection to %s failed\n", server_n));
- return NULL;
- }
-
- if (!cli_session_request(c, &calling, &called)) {
- DEBUG(0,("session request to %s failed\n", called.name));
- cli_shutdown(c);
- if (strcmp(called.name, "*SMBSERVER")) {
- make_nmb_name(&called , "*SMBSERVER", 0x20);
- goto again;
- }
- return NULL;
- }
-
- DEBUG(4,(" session request ok\n"));
-
- if (!cli_negprot(c)) {
- DEBUG(0,("protocol negotiation failed\n"));
- cli_shutdown(c);
- return NULL;
- }
-
- if (!got_pass) {
- char *pass = getpass("Password: ");
- if (pass) {
- pstrcpy(password, pass);
- }
- }
-
- if (!cli_session_setup(c, username,
- password, strlen(password),
- password, strlen(password),
- workgroup)) {
- DEBUG(0,("session setup failed: %s\n", cli_errstr(c)));
- return NULL;
- }
-
- /*
- * These next two lines are needed to emulate
- * old client behaviour for people who have
- * scripts based on client output.
- * QUESTION ? Do we want to have a 'client compatibility
- * mode to turn these on/off ? JRA.
- */
-
- if (*c->server_domain || *c->server_os || *c->server_type)
- DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
- c->server_domain,c->server_os,c->server_type));
-
- DEBUG(4,(" session setup ok\n"));
-
- if (!cli_send_tconX(c, share, "?????",
- password, strlen(password)+1)) {
- DEBUG(0,("tree connect failed: %s\n", cli_errstr(c)));
- cli_shutdown(c);
- return NULL;
- }
-
- DEBUG(4,(" tconx ok\n"));
-
- return c;
-}
-
-static char *resultp;
-
-void listfn(file_info *f, const char *s)
-{
- if (strcmp(f->name,".") == 0) {
- resultp[0] = '+';
- } else if (strcmp(f->name,"..") == 0) {
- resultp[1] = '+';
- } else {
- resultp[2] = '+';
- }
-}
-
-
-static void testpair(struct cli_state *cli1, struct cli_state *cli2,
- char *mask, char *file)
-{
- int fnum;
- fstring res1, res2;
- char *res3;
- static int count;
-
- count++;
-
- fstrcpy(res1, "---");
- fstrcpy(res2, "---");
-
- fnum = cli_open(cli1, file, O_CREAT|O_TRUNC|O_RDWR, 0);
- if (fnum == -1) {
- DEBUG(0,("Can't create %s on cli1\n", file));
- return;
- }
- cli_close(cli1, fnum);
-
- fnum = cli_open(cli2, file, O_CREAT|O_TRUNC|O_RDWR, 0);
- if (fnum == -1) {
- DEBUG(0,("Can't create %s on cli2\n", file));
- return;
- }
- cli_close(cli2, fnum);
-
- resultp = res1;
- cli_list(cli1, mask, aHIDDEN | aDIR, listfn);
-
- res3 = reg_test(mask, file);
-
- resultp = res2;
- cli_list(cli2, mask, aHIDDEN | aDIR, listfn);
-
- if (showall || strcmp(res1, res3)) {
- char *p;
- pstring rfile;
- p = strrchr(file,'\\');
- pstrcpy(rfile, p+1);
- mangle_name_83(rfile);
- strlower(rfile);
- DEBUG(0,("%s %s %s %d mask=[%s] file=[%s] mfile=[%s]\n",
- res1, res2, res3, count, mask, file, rfile));
- }
-
- cli_unlink(cli1, file);
- cli_unlink(cli2, file);
-
-
- if (count % 500 == 0) DEBUG(0,("%d\n", count));
-}
-
-static void test_mask(int argc, char *argv[],
- struct cli_state *cli1, struct cli_state *cli2)
-{
- pstring mask, file;
- int l1, l2, i, j, l;
- int mc_len = strlen(maskchars);
- int fc_len = strlen(filechars);
-
- cli_mkdir(cli1, "masktest");
- cli_mkdir(cli2, "masktest");
-
- cli_unlink(cli1, "\\masktest\\*");
- cli_unlink(cli2, "\\masktest\\*");
-
- if (argc >= 2) {
- while (argc >= 2) {
- pstrcpy(mask,"\\masktest\\");
- pstrcpy(file,"\\masktest\\");
- pstrcat(mask, argv[0]);
- pstrcat(file, argv[1]);
- testpair(cli1, cli2, mask, file);
- argv += 2;
- argc -= 2;
- }
- goto finished;
- }
-
-#if 1
- for (i=0; standard_masks[i]; i++) {
- for (j=0; standard_files[j]; j++) {
- pstrcpy(mask,"\\masktest\\");
- pstrcpy(file,"\\masktest\\");
- pstrcat(mask, standard_masks[i]);
- pstrcat(file, standard_files[j]);
- testpair(cli1, cli2, mask, file);
- }
- }
-#endif
-
- while (1) {
- l1 = 1 + random() % 20;
- l2 = 1 + random() % 20;
- pstrcpy(mask,"\\masktest\\");
- pstrcpy(file,"\\masktest\\");
- l = strlen(mask);
- for (i=0;i<l1;i++) {
- mask[i+l] = maskchars[random() % mc_len];
- }
- mask[l+l1] = 0;
-
- for (i=0;i<l2;i++) {
- file[i+l] = filechars[random() % fc_len];
- }
- file[l+l2] = 0;
-
- if (strcmp(file+l,".") == 0 ||
- strcmp(file+l,"..") == 0 ||
- strcmp(mask+l,"..") == 0) continue;
-
- testpair(cli1, cli2, mask, file);
- }
-
- finished:
- cli_rmdir(cli1, "\\masktest");
- cli_rmdir(cli2, "\\masktest");
-}
-
-
-static void usage(void)
-{
- printf(
-"Usage:\n\
- masktest //server1/share1 //server2/share2 [options..]\n\
- options:\n\
- -U user%%pass\n\
- -s seed\n\
- -f filechars (default %s)\n\
- -m maskchars (default %s)\n\
- -a show all tests\n\
-\n\
- This program tests wildcard matching between two servers. It generates\n\
- random pairs of filenames/masks and tests that they match in the same\n\
- way on two servers\n\
-",
- filechars, maskchars);
-}
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
- char *share1, *share2;
- struct cli_state *cli1, *cli2;
- extern char *optarg;
- extern int optind;
- extern FILE *dbf;
- int opt;
- char *p;
- int seed;
-
- setlinebuf(stdout);
-
- dbf = stderr;
-
- if (argv[1][0] == '-' || argc < 3) {
- usage();
- exit(1);
- }
-
- share1 = argv[1];
- share2 = argv[2];
-
- all_string_sub(share1,"/","\\",0);
- all_string_sub(share2,"/","\\",0);
-
- setup_logging(argv[0],True);
-
- argc -= 2;
- argv += 2;
-
- TimeInit();
- charset_initialise();
-
- if (getenv("USER")) {
- pstrcpy(username,getenv("USER"));
- }
-
- seed = time(NULL);
-
- while ((opt = getopt(argc, argv, "U:s:hm:f:a")) != EOF) {
- switch (opt) {
- case 'U':
- pstrcpy(username,optarg);
- p = strchr(username,'%');
- if (p) {
- *p = 0;
- pstrcpy(password, p+1);
- got_pass = 1;
- }
- break;
- case 's':
- seed = atoi(optarg);
- break;
- case 'h':
- usage();
- exit(1);
- case 'm':
- maskchars = optarg;
- break;
- case 'f':
- filechars = optarg;
- break;
- case 'a':
- showall = 1;
- break;
- default:
- printf("Unknown option %c (%d)\n", (char)opt, opt);
- exit(1);
- }
- }
-
- argc -= optind;
- argv += optind;
-
- DEBUG(0,("seed=%d\n", seed));
- srandom(seed);
-
- cli1 = connect_one(share1);
- if (!cli1) {
- DEBUG(0,("Failed to connect to %s\n", share1));
- exit(1);
- }
-
- cli2 = connect_one(share2);
- if (!cli2) {
- DEBUG(0,("Failed to connect to %s\n", share2));
- exit(1);
- }
-
-
- test_mask(argc, argv, cli1, cli2);
-
- return(0);
-}
diff --git a/source/utils/nmb-agent.c b/source/utils/nmb-agent.c
new file mode 100644
index 00000000000..cdb260ad863
--- /dev/null
+++ b/source/utils/nmb-agent.c
@@ -0,0 +1,306 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2
+ SMB agent/socket plugin
+ Copyright (C) Andrew Tridgell 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "smb.h"
+
+#define SECURITY_MASK 0
+#define SECURITY_SET 0
+
+/* this forces non-unicode */
+#define CAPABILITY_MASK CAP_UNICODE
+#define CAPABILITY_SET 0
+
+/* and non-unicode for the client too */
+#define CLI_CAPABILITY_MASK CAP_UNICODE
+#define CLI_CAPABILITY_SET 0
+
+extern int DEBUGLEVEL;
+
+static int ClientNMB = -1;
+
+/****************************************************************************
+terminate sockent connection
+****************************************************************************/
+static void free_sock(void *sock)
+{
+ if (sock != NULL)
+ {
+ free(sock);
+ }
+}
+
+static void filter_reply(struct packet_struct *p, int tr_id)
+{
+ p->packet.nmb.header.name_trn_id = tr_id;
+}
+
+static BOOL process_cli_sock(struct sock_redir **socks,
+ uint32 num_socks,
+ struct sock_redir *sock)
+{
+ struct packet_struct *p;
+ struct nmb_state *nmb;
+ static uint16 trn_id = 0x0;
+
+ p = receive_packet(sock->c, NMB_SOCK_PACKET, 0);
+ if (p == NULL)
+ {
+ DEBUG(0,("client closed connection\n"));
+ return False;
+ }
+
+ nmb = (struct nmb_state*)malloc(sizeof(struct nmb_state));
+ if (nmb == NULL)
+ {
+ free_packet(p);
+ return False;
+ }
+
+ sock->s = ClientNMB;
+ sock->n = nmb;
+ sock->c_id = p->packet.nmb.header.name_trn_id;
+ sock->s_id = trn_id;
+
+ trn_id++;
+ if (trn_id > 0xffff)
+ {
+ trn_id = 0x0;
+ }
+
+ DEBUG(10,("new trn_id: %d\n", trn_id));
+
+ filter_reply(p, sock->s_id);
+
+ nmb->ip = p->ip;
+ nmb->port = p->port;
+
+ p->fd = ClientNMB;
+ p->packet_type = NMB_PACKET;
+
+ if (!send_packet(p))
+ {
+ DEBUG(0,("server is dead\n"));
+ free_packet(p);
+ return False;
+ }
+ free_packet(p);
+ return True;
+}
+
+static BOOL process_srv_sock(struct sock_redir **socks,
+ uint32 num_socks,
+ int fd)
+{
+ int nmb_id;
+ int tr_id;
+ int i;
+
+ struct packet_struct *p;
+
+ p = receive_packet(fd, NMB_PACKET, 0);
+ if (p == NULL)
+ {
+ return True;
+ }
+
+#if 0
+ if (!p->packet.nmb.header.response)
+ {
+ DEBUG(10,("skipping response packet\n"));
+ free_packet(p);
+ return True;
+ }
+#endif
+
+ nmb_id = p->packet.nmb.header.name_trn_id;
+ DEBUG(10,("process_srv_sock:\tnmb_id:\t%d\n", nmb_id));
+
+ for (i = 0; i < num_socks; i++)
+ {
+ if (socks[i] == NULL)
+ {
+ continue;
+ }
+
+ tr_id = socks[i]->s_id;
+
+ DEBUG(10,("list:\tfd:\t%d\tc_id:\t%d\ttr_id:\t%d\n",
+ socks[i]->c,
+ socks[i]->c_id,
+ tr_id));
+
+ if (nmb_id != tr_id)
+ {
+ continue;
+ }
+
+ filter_reply(p, socks[i]->c_id);
+ p->fd = socks[i]->c;
+ p->packet_type = NMB_SOCK_PACKET;
+
+ if (!send_packet(p))
+ {
+ DEBUG(0,("client is dead\n"));
+ return False;
+ }
+ return True;
+ }
+ return True;
+}
+
+static int get_agent_sock(char *id)
+{
+ int s;
+ fstring dir;
+ fstring path;
+
+ slprintf(dir, sizeof(dir)-1, "/tmp/.nmb");
+ slprintf(path, sizeof(path)-1, "%s/agent", dir);
+
+ s = create_pipe_socket(dir, 0777, path, 0777);
+
+ if (s == -1)
+ return -1;
+ /* ready to listen */
+ if (listen(s, 5) == -1) {
+ DEBUG(0,("listen: %s\n", strerror(errno)));
+ close(s);
+ return -1;
+ }
+ return s;
+}
+
+static void start_nmb_agent(void)
+{
+ struct vagent_ops va =
+ {
+ free_sock,
+ get_agent_sock,
+ process_cli_sock,
+ process_srv_sock,
+ NULL,
+ NULL,
+ 0
+ };
+
+ CatchChild();
+
+ start_agent(&va);
+}
+
+/******************************************************************************
+ open the socket communication
+ *****************************************************************************/
+static BOOL open_sockets(BOOL isdaemon, int port)
+{
+ /* The sockets opened here will be used to receive broadcast
+ packets *only*. Interface specific sockets are opened in
+ make_subnet() in namedbsubnet.c. Thus we bind to the
+ address "0.0.0.0". The parameter 'socket address' is
+ now deprecated.
+ */
+
+ if ( isdaemon )
+ ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0,True);
+ else
+ ClientNMB = 0;
+
+ if ( ClientNMB == -1 )
+ return( False );
+
+ /* we are never interested in SIGPIPE */
+ BlockSignals(True,SIGPIPE);
+
+ set_socket_options( ClientNMB, "SO_BROADCAST" );
+
+ DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
+ return( True );
+} /* open_sockets */
+
+/****************************************************************************
+usage on the program
+****************************************************************************/
+static void usage(char *pname)
+{
+ printf("Usage: %s [-D]", pname);
+
+ printf("\nVersion %s\n",VERSION);
+ printf("\t-D run as a daemon\n");
+ printf("\t-h usage\n");
+ printf("\n");
+}
+
+int main(int argc, char *argv[])
+{
+ pstring configfile;
+ BOOL is_daemon = False;
+ int opt;
+ extern pstring debugf;
+ int global_nmb_port = NMB_PORT;
+
+ TimeInit();
+
+ pstrcpy(configfile,CONFIGFILE);
+
+ while ((opt = getopt(argc, argv, "Dh")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'D':
+ {
+ is_daemon = True;
+ break;
+ }
+ case 'h':
+ default:
+ {
+ usage(argv[0]);
+ break;
+ }
+ }
+ }
+
+ slprintf(debugf, sizeof(debugf)-1, "log.%s", argv[0]);
+ setup_logging(argv[0], !is_daemon);
+
+ charset_initialise();
+
+ if (!lp_load(configfile,True,False,False))
+ {
+ DEBUG(0,("Unable to load config file\n"));
+ }
+
+ if (is_daemon)
+ {
+ DEBUG(0,("%s: becoming daemon\n", argv[0]));
+ become_daemon();
+ }
+
+ if (!open_sockets(True, global_nmb_port))
+ {
+ return 1;
+ }
+
+ start_nmb_agent();
+
+ return 0;
+}
diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c
index 8e26a206ca2..b203eef93c4 100644
--- a/source/utils/nmblookup.c
+++ b/source/utils/nmblookup.c
@@ -26,38 +26,51 @@
extern int DEBUGLEVEL;
+extern pstring scope;
+
+extern pstring myhostname;
extern struct in_addr ipzero;
-static BOOL use_bcast = True;
-static BOOL got_bcast = False;
-static struct in_addr bcast_addr;
-static BOOL recursion_desired = False;
-static BOOL translate_addresses = False;
-static int ServerFD= -1;
-static int RootPort = 0;
-static BOOL find_status=False;
+int ServerFD= -1;
+
+BOOL RootPort = False;
/****************************************************************************
open the socket communication
**************************************************************************/
static BOOL open_sockets(void)
{
- ServerFD = open_socket_in( SOCK_DGRAM,
- (RootPort ? 137 :0),
- 3,
- interpret_addr(lp_socket_address()), True );
-
- if (ServerFD == -1)
- return(False);
-
- set_socket_options(ServerFD,"SO_BROADCAST");
+ if (RootPort)
+ {
+ ServerFD = open_socket_in( SOCK_DGRAM,
+ 137,
+ 3,
+ interpret_addr(lp_socket_address()),True );
+
+ if (ServerFD == -1)
+ {
+ return(False);
+ }
+ set_socket_options(ServerFD,"SO_BROADCAST");
DEBUG(3, ("Socket opened.\n"));
+ }
return True;
}
/****************************************************************************
+ initialise connect, service and file structs
+****************************************************************************/
+static BOOL init_structs(void )
+{
+ if (!get_myname(myhostname,NULL))
+ return(False);
+
+ return True;
+}
+
+/****************************************************************************
usage on the program
****************************************************************************/
static void usage(void)
@@ -70,71 +83,16 @@ static void usage(void)
printf("\t-M searches for a master browser\n");
printf("\t-R set recursion desired in packet\n");
printf("\t-S lookup node status as well\n");
- printf("\t-T translate IP addresses into names\n");
printf("\t-r Use root port 137 (Win95 only replies to this)\n");
printf("\t-A Do a node status on <name> as an IP Address\n");
printf("\t-i NetBIOS scope Use the given NetBIOS scope for name queries\n");
printf("\t-s smb.conf file Use the given path to the smb.conf file\n");
printf("\t-h Print this help message.\n");
- printf("\n If you specify -M and name is \"-\", nmblookup looks up __MSBROWSE__<01>\n");
printf("\n");
}
/****************************************************************************
-send out one query
-****************************************************************************/
-static BOOL query_one(char *lookup, unsigned int lookup_type)
-{
- int j, count;
- struct in_addr *ip_list=NULL;
-
- if (got_bcast) {
- printf("querying %s on %s\n", lookup, inet_ntoa(bcast_addr));
- ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
- use_bcast?True:recursion_desired,
- bcast_addr,&count);
- } else {
- struct in_addr *bcast;
- for (j=iface_count() - 1;
- !ip_list && j >= 0;
- j--) {
- bcast = iface_n_bcast(j);
- printf("querying %s on %s\n",
- lookup, inet_ntoa(*bcast));
- ip_list = name_query(ServerFD,lookup,lookup_type,
- use_bcast,
- use_bcast?True:recursion_desired,
- *bcast,&count);
- }
- }
-
- if (!ip_list) return False;
-
- for (j=0;j<count;j++) {
- if (translate_addresses) {
- struct hostent *host = gethostbyaddr((char *)&ip_list[j], sizeof(ip_list[j]), AF_INET);
- if (host) {
- printf("%s, ", host -> h_name);
- }
- }
- printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
- }
-
- /* We can only do find_status if the ip address returned
- was valid - ie. name_query returned true.
- */
- if (find_status) {
- printf("Looking up status of %s\n",inet_ntoa(ip_list[0]));
- name_status(ServerFD,lookup,lookup_type,True,ip_list[0],NULL,NULL);
- printf("\n");
- }
-
- return (ip_list != NULL);
-}
-
-
-/****************************************************************************
main program
****************************************************************************/
int main(int argc,char *argv[])
@@ -145,10 +103,14 @@ int main(int argc,char *argv[])
extern int optind;
extern char *optarg;
BOOL find_master=False;
+ BOOL find_status=False;
int i;
static pstring servicesf = CONFIGFILE;
+ struct in_addr bcast_addr;
+ BOOL use_bcast = True;
+ BOOL got_bcast = False;
BOOL lookup_by_ip = False;
- int commandline_debuglevel = -2;
+ BOOL recursion_desired = False;
DEBUGLEVEL = 1;
*lookup = 0;
@@ -159,29 +121,25 @@ int main(int argc,char *argv[])
charset_initialise();
- while ((opt = getopt(argc, argv, "d:B:U:i:s:SMrhART")) != EOF)
+ while ((opt = getopt(argc, argv, "d:B:U:i:s:SMrhAR")) != EOF)
switch (opt)
{
case 'B':
+ iface_set_default(NULL,optarg,NULL);
bcast_addr = *interpret_addr2(optarg);
got_bcast = True;
use_bcast = True;
break;
case 'U':
+ iface_set_default(NULL,optarg,NULL);
bcast_addr = *interpret_addr2(optarg);
got_bcast = True;
use_bcast = False;
break;
- case 'T':
- translate_addresses = !translate_addresses;
- break;
case 'i':
- {
- extern pstring global_scope;
- pstrcpy(global_scope,optarg);
- strupper(global_scope);
- }
- break;
+ fstrcpy(scope,optarg);
+ strupper(scope);
+ break;
case 'M':
find_master = True;
break;
@@ -192,13 +150,13 @@ int main(int argc,char *argv[])
recursion_desired = True;
break;
case 'd':
- commandline_debuglevel = DEBUGLEVEL = atoi(optarg);
+ DEBUGLEVEL = atoi(optarg);
break;
case 's':
pstrcpy(servicesf, optarg);
break;
case 'r':
- RootPort = -1;
+ RootPort = True;
break;
case 'h':
usage();
@@ -217,25 +175,27 @@ int main(int argc,char *argv[])
exit(1);
}
+ init_structs();
+
if (!lp_load(servicesf,True,False,False)) {
fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
}
- /*
- * Ensure we reset DEBUGLEVEL if someone specified it
- * on the command line.
- */
-
- if(commandline_debuglevel != -2)
- DEBUGLEVEL = commandline_debuglevel;
-
load_interfaces();
if (!open_sockets()) return(1);
+ if (!got_bcast)
+ bcast_addr = *iface_bcast(ipzero);
+
+ DEBUG(1,("Sending queries to %s\n",inet_ntoa(bcast_addr)));
+
+
for (i=optind;i<argc;i++)
{
+ int j, count;
char *p;
struct in_addr ip;
+ struct in_addr *ip_list;
fstrcpy(lookup,argv[i]);
@@ -244,7 +204,7 @@ int main(int argc,char *argv[])
fstrcpy(lookup,"*");
ip = *interpret_addr2(argv[i]);
printf("Looking up status of %s\n",inet_ntoa(ip));
- name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL);
+ name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL,NULL);
printf("\n");
continue;
}
@@ -265,7 +225,21 @@ int main(int argc,char *argv[])
sscanf(p+1,"%x",&lookup_type);
}
- if (!query_one(lookup, lookup_type)) {
+ if ((ip_list = name_query(ServerFD,lookup,lookup_type,use_bcast,
+ use_bcast?True:recursion_desired,
+ bcast_addr,&count,NULL))) {
+ for (j=0;j<count;j++)
+ printf("%s %s<%02x>\n",inet_ntoa(ip_list[j]),lookup, lookup_type);
+
+ /* We can only do find_status if the ip address returned
+ was valid - ie. name_query returned true.
+ */
+ if (find_status) {
+ printf("Looking up status of %s\n",inet_ntoa(ip_list[0]));
+ name_status(ServerFD,lookup,lookup_type,True,ip_list[0],NULL,NULL,NULL);
+ printf("\n");
+ }
+ } else {
printf("name_query failed to find name %s\n", lookup);
}
}
diff --git a/source/utils/rpctorture.c b/source/utils/rpctorture.c
index c80cfe4adea..dd421bba80c 100644
--- a/source/utils/rpctorture.c
+++ b/source/utils/rpctorture.c
@@ -1,8 +1,9 @@
/*
Unix SMB/Netbios implementation.
Version 1.9.
- SMB client
- Copyright (C) Andrew Tridgell 1994-1998
+ RPC Torture client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,531 +30,523 @@
#define REGISTER 0
#endif
-extern pstring global_myname;
-
-extern pstring user_socket_options;
-
-
-extern pstring debugf;
extern int DEBUGLEVEL;
+static int numops = 2;
+static int nprocs = 1;
-extern file_info def_finfo;
-
-#define CNV_LANG(s) dos2unix_format(s,False)
-#define CNV_INPUT(s) unix2dos_format(s,True)
-
-static struct cli_state smbcli;
-struct cli_state *smb_cli = &smbcli;
-
-FILE *out_hnd;
-
-static pstring password; /* local copy only, if one is entered */
+extern FILE* out_hnd;
/****************************************************************************
-initialise smb client structure
+ log in as an nt user, log out again.
****************************************************************************/
-void rpcclient_init(void)
+void run_enums_test(struct client_info *info, int argc, char *argv[])
{
- memset((char *)smb_cli, '\0', sizeof(smb_cli));
- cli_initialise(smb_cli);
- smb_cli->capabilities |= CAP_NT_SMBS;
+ int i;
+
+ /* establish connections. nothing to stop these being re-established. */
+ for (i = 0; i < numops; i++)
+ {
+ cmd_srv_enum_sess(info, argc, argv);
+ cmd_srv_enum_shares(info, argc, argv);
+ cmd_srv_enum_files(info, argc, argv);
+ cmd_srv_enum_conn(info, argc, argv);
+ }
}
/****************************************************************************
-make smb client connection
+ log in as an nt user, log out again.
****************************************************************************/
-static BOOL rpcclient_connect(struct client_info *info)
+void run_ntlogin_test(struct client_info *info, int argc, char *argv[])
{
- struct nmb_name calling;
- struct nmb_name called;
-
- make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type);
- make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0);
+ int i;
- if (!cli_establish_connection(smb_cli,
- info->dest_host, &info->dest_ip,
- &calling, &called,
- info->share, info->svc_type,
- False, True))
+ for (i = 0; i < numops; i++)
{
- DEBUG(0,("rpcclient_connect: connection failed\n"));
- cli_shutdown(smb_cli);
- return False;
+ cmd_netlogon_login_test(info, argc, argv);
}
-
- return True;
}
-/****************************************************************************
-stop the smb connection(s?)
-****************************************************************************/
-static void rpcclient_stop(void)
+#if 0
+/* generate a random buffer */
+static void rand_buf(char *buf, int len)
{
- cli_shutdown(smb_cli);
+ while (len--) {
+ *buf = sys_random();
+ buf++;
+ }
}
/****************************************************************************
- log in as an nt user, log out again.
+do a random rpc command
****************************************************************************/
-void run_enums_test(int num_ops, struct client_info *cli_info, struct cli_state *cli)
+BOOL do_random_rpc(struct cli_state *cli, uint16 nt_pipe_fnum, int max_len)
{
- pstring cmd;
- int i;
+ prs_struct rbuf;
+ prs_struct buf;
+ uint8 opcode;
+ int param_len;
+ BOOL response = False;
- /* establish connections. nothing to stop these being re-established. */
- rpcclient_connect(cli_info);
-
- DEBUG(5,("rpcclient_connect: cli->fd:%d\n", cli->fd));
- if (cli->fd <= 0)
+ if ((sys_random() % 20) == 0)
{
- fprintf(out_hnd, "warning: connection could not be established to %s<%02x>\n",
- cli_info->dest_host, cli_info->name_type);
- return;
+ param_len = (sys_random() % 256) + 4;
}
-
- for (i = 0; i < num_ops; i++)
+ else
{
- set_first_token("");
- cmd_srv_enum_sess(cli_info);
- set_first_token("");
- cmd_srv_enum_shares(cli_info);
- set_first_token("");
- cmd_srv_enum_files(cli_info);
-
- if (password[0] != 0)
- {
- slprintf(cmd, sizeof(cmd)-1, "1");
- set_first_token(cmd);
- }
- else
+ param_len = (sys_random() % max_len) + 4;
+ }
+
+ prs_init(&buf , param_len, 4, SAFETY_MARGIN, False);
+ prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True );
+
+ opcode = sys_random() % 256;
+
+ /* turn parameters into data stream */
+ rand_buf(mem_data(buf.data, 0), param_len);
+ buf.offset = param_len;
+
+ /* send the data on \PIPE\ */
+ if (rpc_api_pipe_req(cli, nt_pipe_fnum, opcode, &buf, &rbuf))
+ {
+ response = rbuf.offset != 0;
+
+ if (response)
{
- set_first_token("");
+ DEBUG(0,("response! opcode: 0x%x\n", opcode));
+ DEBUG(0,("request: length %d\n", param_len));
+ dump_data(0, mem_data(buf.data , 0), MIN(param_len, 128));
+ DEBUG(0,("response: length %d\n", rbuf.data->offset.end));
+ dump_data(0, mem_data(rbuf.data, 0), rbuf.data->offset.end);
}
- cmd_srv_enum_conn(cli_info);
}
- rpcclient_stop();
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+ return response;
}
-/****************************************************************************
- log in as an nt user, log out again.
-****************************************************************************/
-void run_ntlogin_test(int num_ops, struct client_info *cli_info, struct cli_state *cli)
+
+/* send random IPC commands */
+static void random_rpc_pipe_enc(char *pipe_name, struct client_info *info, int argc, char *argv[],
+ int numops)
{
- pstring cmd;
+ uint16 nt_pipe_fnum;
int i;
- /* establish connections. nothing to stop these being re-established. */
- rpcclient_connect(cli_info);
+ DEBUG(0,("starting random rpc test on %s (encryped)\n", pipe_name));
- DEBUG(5,("rpcclient_connect: cli->fd:%d\n", cli->fd));
- if (cli->fd <= 0)
+ /* establish connections. nothing to stop these being re-established. */
+ if (!rpcclient_connect(info))
{
- fprintf(out_hnd, "warning: connection could not be established to %s<%02x>\n",
- cli_info->dest_host, cli_info->name_type);
+ DEBUG(0,("random rpc test: connection failed\n"));
return;
}
-
- for (i = 0; i < num_ops; i++)
+
+ cli_nt_set_ntlmssp_flgs(smb_cli,
+ NTLMSSP_NEGOTIATE_UNICODE |
+ NTLMSSP_NEGOTIATE_OEM |
+ NTLMSSP_NEGOTIATE_SIGN |
+ NTLMSSP_NEGOTIATE_SEAL |
+ NTLMSSP_NEGOTIATE_LM_KEY |
+ NTLMSSP_NEGOTIATE_NTLM |
+ NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
+ NTLMSSP_NEGOTIATE_00001000 |
+ NTLMSSP_NEGOTIATE_00002000);
+
+ for (i = 1; i <= numops ; i++)
{
- slprintf(cmd, sizeof(cmd)-1, "%s %s", cli->user_name, password);
- set_first_token(cmd);
+ /* open session. */
+ cli_nt_session_open(smb_cli, pipe_name, &nt_pipe_fnum);
+
+ do_random_rpc(smb_cli, nt_pipe_fnum, 1024);
+ if (i % 500 == 0)
+ {
+ DEBUG(0,("calls: %i\n", i));
+ }
- cmd_netlogon_login_test(cli_info);
+ /* close the session */
+ cli_nt_session_close(smb_cli, nt_pipe_fnum);
}
+ /* close the rpc pipe */
rpcclient_stop();
+ DEBUG(0,("finished random rpc test on %s\n", pipe_name));
}
-/****************************************************************************
- runs n simultaneous functions.
-****************************************************************************/
-static void create_procs(int nprocs, int numops,
- struct client_info *cli_info, struct cli_state *cli,
- void (*fn)(int, struct client_info *, struct cli_state *))
+/* send random IPC commands */
+static void random_rpc_pipe(char *pipe_name, struct client_info *info, int argc, char *argv[],
+ int numops)
{
- int i, status;
+ uint16 nt_pipe_fnum;
+ int i;
- for (i=0;i<nprocs;i++)
+ DEBUG(0,("starting random rpc test on %s\n", pipe_name));
+
+ /* establish connections. nothing to stop these being re-established. */
+ if (!rpcclient_connect(info))
{
- if (fork() == 0)
- {
- pid_t mypid = getpid();
- sys_srandom(mypid ^ time(NULL));
- fn(numops, cli_info, cli);
- fflush(out_hnd);
- _exit(0);
- }
+ DEBUG(0,("random rpc test: connection failed\n"));
+ return;
}
- for (i=0;i<nprocs;i++)
+ /* open session. */
+ if (!cli_nt_session_open(smb_cli, pipe_name, &nt_pipe_fnum))
{
- waitpid(0, &status, 0);
+ DEBUG(0,("random rpc test: session open failed\n"));
+ return;
}
-}
-/****************************************************************************
-usage on the program - OUT OF DATE!
-****************************************************************************/
-static void usage(char *pname)
-{
- fprintf(out_hnd, "Usage: %s service <password> [-d debuglevel] [-l log] ",
- pname);
-
- fprintf(out_hnd, "\nVersion %s\n",VERSION);
- fprintf(out_hnd, "\t-d debuglevel set the debuglevel\n");
- fprintf(out_hnd, "\t-l log basename. Basename for log/debug files\n");
- fprintf(out_hnd, "\t-n netbios name. Use this name as my netbios name\n");
- fprintf(out_hnd, "\t-m max protocol set the max protocol level\n");
- fprintf(out_hnd, "\t-I dest IP use this IP to connect to\n");
- fprintf(out_hnd, "\t-E write messages to stderr instead of stdout\n");
- fprintf(out_hnd, "\t-U username set the network username\n");
- fprintf(out_hnd, "\t-W workgroup set the workgroup name\n");
- fprintf(out_hnd, "\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n");
- fprintf(out_hnd, "\n");
-}
-
-enum client_action
-{
- CLIENT_NONE,
- CLIENT_IPC,
- CLIENT_SVC
-};
-
-/****************************************************************************
- main program
-****************************************************************************/
- int main(int argc,char *argv[])
-{
- char *pname = argv[0];
- int opt;
- extern FILE *dbf;
- extern char *optarg;
- extern int optind;
- static pstring servicesf = CONFIGFILE;
- pstring term_code;
- BOOL got_pass = False;
- char *cmd_str="";
- mode_t myumask = 0755;
- enum client_action cli_action = CLIENT_NONE;
- int nprocs = 1;
- int numops = 100;
- struct client_info cli_info;
+ for (i = 1; i <= numops ; i++)
+ {
+ do_random_rpc(smb_cli, nt_pipe_fnum, 8192);
+ if (i % 500 == 0)
+ {
+ DEBUG(0,("calls: %i\n", i));
+ }
+ }
- out_hnd = stdout;
+ /* close the session */
+ cli_nt_session_close(smb_cli, nt_pipe_fnum);
- rpcclient_init();
+ /* close the rpc pipe */
+ rpcclient_stop();
-#ifdef KANJI
- pstrcpy(term_code, KANJI);
-#else /* KANJI */
- *term_code = 0;
-#endif /* KANJI */
+ DEBUG(0,("finished random rpc test on %s\n", pipe_name));
+}
- if (!lp_load(servicesf,True, False, False))
+static void run_randomrpc(struct client_info *info, int argc, char *argv[])
+{
+ char *pipes[] =
{
- fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf);
+ PIPE_SAMR ,
+ PIPE_WINREG ,
+ PIPE_SRVSVC ,
+ PIPE_WKSSVC ,
+ PIPE_NETLOGON ,
+ PIPE_NTSVCS ,
+ PIPE_LSARPC ,
+ NULL
+ };
+
+ int i = 0;
+
+ while (pipes[i] != NULL)
+ {
+ random_rpc_pipe(pipes[i], info, numops);
+#if 0
+ random_rpc_pipe_enc(pipes[i], info, numops);
+#endif
+
+ i++;
}
+}
- codepage_initialise(lp_client_code_page());
+#endif
- DEBUGLEVEL = 0;
+static void run_samhandles(struct client_info *info, int argc, char *argv[])
+{
+ int i;
+ int count = 0;
+ int failed = 0;
+ fstring srv_name;
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->dest_host);
+ strupper(srv_name);
- cli_info.put_total_size = 0;
- cli_info.put_total_time_ms = 0;
- cli_info.get_total_size = 0;
- cli_info.get_total_time_ms = 0;
+ DEBUG(0,("starting sam handle test\n"));
- cli_info.dir_total = 0;
- cli_info.newer_than = 0;
- cli_info.archive_level = 0;
- cli_info.print_mode = 1;
+ for (i = 1; i <= numops ; i++)
+ {
+ POLICY_HND pol;
+ if (!samr_connect(srv_name, 0x20, &pol))
+ {
+ failed++;
+ }
+/*
+ if (!samr_open_domain(smb_cli, nt_pipe_fnum, srv_name, 0x00000020, &pol))
+ {
+ DEBUG(0,("samhandle domain open test (%i): failed\n", i));
+ }
+ */
+ if (i % 500 == 0)
+ {
+ DEBUG(0,("calls: %i\n", i));
+ }
+ count++;
+ }
- cli_info.translation = False;
- cli_info.recurse_dir = False;
- cli_info.lowercase = False;
- cli_info.prompt = True;
- cli_info.abort_mget = True;
+ DEBUG(0,("finished samhandle test. count: %d failed: %d\n", count, failed));
+}
- cli_info.dest_ip.s_addr = 0;
- cli_info.name_type = 0x20;
- pstrcpy(cli_info.cur_dir , "\\");
- pstrcpy(cli_info.file_sel, "");
- pstrcpy(cli_info.base_dir, "");
- pstrcpy(smb_cli->domain, "");
- pstrcpy(smb_cli->user_name, "");
- pstrcpy(cli_info.myhostname, "");
- pstrcpy(cli_info.dest_host, "");
+static void run_lsahandles(struct client_info *info, int argc, char *argv[])
+{
+ int i;
+ int count = 0;
+ int failed = 0;
+ fstring srv_name;
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->myhostname);
+ strupper(srv_name);
- pstrcpy(cli_info.svc_type, "A:");
- pstrcpy(cli_info.share, "");
- pstrcpy(cli_info.service, "");
+ DEBUG(0,("starting lsa handle test\n"));
- ZERO_STRUCT(cli_info.dom.level3_sid);
- pstrcpy(cli_info.dom.level3_dom, "");
- ZERO_STRUCT(cli_info.dom.level5_sid);
- pstrcpy(cli_info.dom.level5_dom, "");
+ /* establish connections. nothing to stop these being re-established. */
+ for (i = 1; i <= numops; i++)
+ {
+ POLICY_HND pol;
+ if (!lsa_open_policy(srv_name, &pol, False, 0x02000000))
+ {
+ failed++;
+ }
+ if (i % 500 == 0)
+ {
+ DEBUG(0,("calls: %i\n", i));
+ }
+ count++;
+ }
- smb_cli->nt_pipe_fnum = 0xffff;
+ DEBUG(0,("finished lsahandle test. count: %d failed: %d\n", count, failed));
+}
- setup_logging(pname, True);
- TimeInit();
- charset_initialise();
+#if 0
+static void run_pipegobble(struct client_info *info, int argc, char *argv[], char *pipe_name)
+{
+ uint16 nt_pipe_fnum;
+ int i;
+ int count = 0;
+ int failed = 0;
+ int retry = 500;
+ fstring srv_name;
+ fstrcpy(srv_name, "\\\\");
+ fstrcat(srv_name, info->myhostname);
+ strupper(srv_name);
- myumask = umask(0);
- umask(myumask);
+ DEBUG(0,("starting pipe gobble test (%s)\n", pipe_name));
- if (!get_myname(global_myname))
+ /* establish connections. nothing to stop these being re-established. */
+ while (retry > 0 && !rpcclient_connect(info))
{
- fprintf(stderr, "Failed to get my hostname.\n");
+ retry--;
}
- password[0] = 0;
-
- if (argc < 2)
+ if (retry == 0)
{
- usage(pname);
- exit(1);
+ DEBUG(0,("pipe gobble test: connection failed\n"));
+ return;
}
-
- if (*argv[1] != '-')
+ for (i = 1; i <= numops ; i++)
{
- pstrcpy(cli_info.service, argv[1]);
- /* Convert any '/' characters in the service name to '\' characters */
- string_replace( cli_info.service, '/','\\');
- argc--;
- argv++;
-
- DEBUG(1,("service: %s\n", cli_info.service));
-
- if (count_chars(cli_info.service,'\\') < 3)
+ /* open session. */
+ if (!cli_nt_session_open(smb_cli, pipe_name, &nt_pipe_fnum))
{
- usage(pname);
- printf("\n%s: Not enough '\\' characters in service\n", cli_info.service);
- exit(1);
+ DEBUG(0,("pipe gobble test: session open failed\n"));
}
- /*
- if (count_chars(cli_info.service,'\\') > 3)
+ if (i % 500 == 0)
{
- usage(pname);
- printf("\n%s: Too many '\\' characters in service\n", cli_info.service);
- exit(1);
+ DEBUG(0,("calls: %i\n", i));
}
- */
+ count++;
+ }
- if (argc > 1 && (*argv[1] != '-'))
- {
- got_pass = True;
- pstrcpy(password,argv[1]);
- memset(argv[1],'X',strlen(argv[1]));
- argc--;
- argv++;
- }
+ rpcclient_stop();
- cli_action = CLIENT_SVC;
- }
+ DEBUG(0,("finished pipe gobble test (%s). count: %d failed: %d\n",
+ pipe_name, count, failed));
+}
- while ((opt = getopt(argc, argv,"s:O:M:S:i:N:o:n:d:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF)
- {
- switch (opt)
- {
- case 'm':
- {
- /* FIXME ... max_protocol seems to be funny here */
+static void run_pipegobbler(struct client_info *info, int argc, char *argv[])
+{
+ run_pipegobble(numops, info, PIPE_SAMR);
+ run_pipegobble(numops, info, PIPE_LSARPC);
+}
- int max_protocol = 0;
- max_protocol = interpret_protocol(optarg,max_protocol);
- fprintf(stderr, "max protocol not currently supported\n");
- break;
- }
- case 'O':
- {
- pstrcpy(user_socket_options,optarg);
- break;
- }
+static void run_handles(struct client_info *info, int argc, char *argv[])
+{
+ run_lsahandles(numops, info);
+ run_samhandles(numops, info);
+}
- case 'S':
- {
- pstrcpy(cli_info.dest_host,optarg);
- strupper(cli_info.dest_host);
- cli_action = CLIENT_IPC;
- break;
- }
+/****************************************************************************
+make tcp connection
+****************************************************************************/
+static void run_tcpconnect(struct client_info *info)
+{
+ int i;
+ int failed = 0;
- case 'i':
- {
- pstrcpy(scope, optarg);
- break;
- }
+ for (i = 0; i < numops; i++)
+ {
+ rpcclient_init();
- case 'U':
- {
- char *lp;
- pstrcpy(smb_cli->user_name,optarg);
- if ((lp=strchr(smb_cli->user_name,'%')))
- {
- *lp = 0;
- pstrcpy(password,lp+1);
- got_pass = True;
- memset(strchr(optarg,'%')+1,'X',strlen(password));
- }
- break;
- }
+ if (!cli_connect(smb_cli, info->dest_host, &info->dest_ip))
+ {
+ failed++;
+ }
+ cli_shutdown(smb_cli);
+ }
- case 'W':
- {
- pstrcpy(smb_cli->domain,optarg);
- break;
- }
+ DEBUG(0,("tcp connections: count: %d failed: %d\n", numops, failed));
+}
- case 'E':
- {
- dbf = stderr;
- break;
- }
+#endif
- case 'I':
- {
- cli_info.dest_ip = *interpret_addr2(optarg);
- if (zero_ip(cli_info.dest_ip))
- {
- exit(1);
- }
- break;
- }
+static void run_torture_set(struct client_info *info, int *argc, char **argv[])
+{
+ int opt;
+ int skiparg = 0;
+ int i;
+ extern int optind;
+ while ((opt = getopt(*argc, *argv,"N:o:")) != EOF)
+ {
+ switch (opt)
+ {
case 'N':
{
nprocs = atoi(optarg);
+ skiparg+=2;
break;
}
case 'o':
{
numops = atoi(optarg);
+ skiparg+=2;
break;
}
+ }
+ }
- case 'n':
- {
- fstrcpy(global_myname, optarg);
- break;
- }
-
- case 'd':
- {
- if (*optarg == 'A')
- DEBUGLEVEL = 10000;
- else
- DEBUGLEVEL = atoi(optarg);
- break;
- }
-
- case 'l':
- {
- slprintf(debugf, sizeof(debugf)-1,
- "%s.client",optarg);
- break;
- }
-
- case 'c':
- {
- cmd_str = optarg;
- got_pass = True;
- break;
- }
-
- case 'h':
- {
- usage(pname);
- exit(0);
- break;
- }
-
- case 's':
- {
- pstrcpy(servicesf, optarg);
- break;
- }
+ report(out_hnd,"Num Operations: %d. Num Processes: %d\n",
+ numops, nprocs);
- case 't':
- {
- pstrcpy(term_code, optarg);
- break;
- }
+ optind = 0;
- default:
- {
- usage(pname);
- exit(1);
- break;
- }
- }
+ /* remove the already-used arguments! */
+ for (i = 0; i < skiparg; i++)
+ {
+ int arg = 1+i;
+ DEBUG(10,("freeing arg %d - %s\n", arg, (*argv)[arg]));
+ safe_free((*argv)[arg]);
+ (*argv)[arg] = NULL;
}
-
- if (cli_action == CLIENT_NONE)
+ /* shift-down the arguments */
+ for (i = 0; i < skiparg; i++)
{
- usage(pname);
- exit(1);
+ int arg = 1+i;
+ DEBUG(10,("skipping arg %d - %s\n", arg, (*argv)[arg]));
+ (*argv)[arg] = (*argv)[arg+skiparg];
}
-
- strupper(global_myname);
- fstrcpy(cli_info.myhostname, global_myname);
-
- DEBUG(3,("%s client started (version %s)\n",timestring(False),VERSION));
-
- if (*smb_cli->domain == 0)
+ for (i = (*argc)-skiparg; i < (*argc); i++)
{
- pstrcpy(smb_cli->domain,lp_workgroup());
+ /* zero the last arguments */
+ (*argv)[i] = NULL;
}
- strupper(smb_cli->domain);
+ (*argc) -= skiparg;
+}
- load_interfaces();
+static void cmd_torture_set(struct client_info *info, int argc, char *argv[])
+{
+ run_torture_set(info, &argc, &argv);
+}
- if (cli_action == CLIENT_IPC)
- {
- pstrcpy(cli_info.share, "IPC$");
- pstrcpy(cli_info.svc_type, "IPC");
- }
+/****************************************************************************
+ runs n simultaneous functions.
+****************************************************************************/
+static void create_procs(
+ struct client_info *info, int argc, char *argv[],
+ void (*fn)(struct client_info *, int, char *[]))
+{
+ int i, status;
- fstrcpy(cli_info.mach_acct, cli_info.myhostname);
- strupper(cli_info.mach_acct);
- fstrcat(cli_info.mach_acct, "$");
+ run_torture_set(info, &argc, &argv);
- /* set the password cache info */
- if (got_pass)
+ for (i=0;i<nprocs;i++)
{
- if (password[0] == 0)
- {
- pwd_set_nullpwd(&(smb_cli->pwd));
- }
- else
+ if (fork() == 0)
{
- pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
+ int mypid = getpid();
+ sys_srandom(mypid ^ time(NULL));
+ fn(info, argc, argv);
+ dbgflush();
+ _exit(0);
}
}
- else
+
+ for (i=0;i<nprocs;i++)
{
- char *pwd = getpass("Enter Password:");
- safe_strcpy(password, pwd, sizeof(password));
- pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */
+ waitpid(0, &status, 0);
}
+}
+
+#define CMD_PROC_WRAP(cmd_fn_name, run_fn_name) \
+static void cmd_fn_name(struct client_info *info, int argc, char *argv[]) \
+{ \
+ create_procs(info, argc, argv, run_fn_name); \
+}
- create_procs(nprocs, numops, &cli_info, smb_cli, run_enums_test);
+CMD_PROC_WRAP(cmd_enums_test, run_enums_test)
+CMD_PROC_WRAP(cmd_lsa_handles_test, run_lsahandles)
+CMD_PROC_WRAP(cmd_sam_handles_test, run_samhandles)
+CMD_PROC_WRAP(cmd_login_test, run_ntlogin_test)
- if (password[0] != 0)
+struct command_set tor_commands[] =
+{
+ {
+ "setenv",
+ cmd_torture_set,
+ "Sets default for Num ops (-o) and Num Process (-N)",
+ {NULL, NULL}
+ },
+ {
+ "samhandles",
+ cmd_sam_handles_test,
+ "SamrConnect - Handles test",
+ {NULL, NULL}
+ },
{
- create_procs(nprocs, numops, &cli_info, smb_cli, run_ntlogin_test);
+ "lsahandles",
+ cmd_lsa_handles_test,
+ "LsarOpenPolicy - Handles test",
+ {NULL, NULL}
+ },
+ {
+ "logintest",
+ cmd_login_test,
+ "NT User Login",
+ {NULL, NULL}
+ },
+ {
+ "enumtest",
+ cmd_enums_test,
+ "NetShareEnum, NetConnectionEnum, NetFileEnum, NetSessionEnum",
+ {NULL, NULL}
+ },
+ /*
+ * oop!
+ */
+
+ {
+ "",
+ NULL,
+ NULL,
+ {NULL, NULL}
}
+};
- fflush(out_hnd);
+/****************************************************************************
+ This defines the commands supported by this client
+ ****************************************************************************/
- return(0);
+ int main(int argc, char *argv[])
+{
+ add_command_set(tor_commands);
+ return command_main(argc, argv);
}
diff --git a/source/utils/smb-agent.c b/source/utils/smb-agent.c
new file mode 100644
index 00000000000..c974469cbd6
--- /dev/null
+++ b/source/utils/smb-agent.c
@@ -0,0 +1,396 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 2
+ SMB agent/socket plugin
+ Copyright (C) Andrew Tridgell 1999
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "smb.h"
+
+#define SECURITY_MASK 0
+#define SECURITY_SET 0
+
+/* this forces non-unicode */
+#define CAPABILITY_MASK CAP_UNICODE
+#define CAPABILITY_SET 0
+
+/* and non-unicode for the client too */
+#define CLI_CAPABILITY_MASK CAP_UNICODE
+#define CLI_CAPABILITY_SET 0
+
+static char packet[BUFFER_SIZE];
+
+extern int DEBUGLEVEL;
+
+
+static uint16 mid_offset = 0x0;
+
+/****************************************************************************
+terminate sockent connection
+****************************************************************************/
+static void free_sock(void *sock)
+{
+ if (sock != NULL)
+ {
+ struct cli_state *n = (struct cli_state *)sock;
+ cli_net_use_del(n->desthost, &n->usr, False, NULL);
+ }
+}
+
+
+static struct cli_state *init_client_connection(int c)
+{
+ pstring buf;
+ struct user_creds usr;
+ int rl;
+ uint32 len;
+ BOOL new_con = False;
+ CREDS_CMD cmd;
+ prs_struct ps;
+ BOOL reuse = False;
+
+ ZERO_STRUCT(usr);
+ ZERO_STRUCT(cmd);
+ cmd.cred = &usr;
+
+ ZERO_STRUCT(usr);
+
+ DEBUG(10, ("init_client_connection: first request\n"));
+
+ rl = read(c, &buf, sizeof(len));
+
+ if (rl != sizeof(len))
+ {
+ DEBUG(0, ("Unable to read length\n"));
+ dump_data(0, buf, sizeof(len));
+ return NULL;
+ }
+
+ len = IVAL(buf, 0);
+
+ if (len > sizeof(buf))
+ {
+ DEBUG(0, ("length %d too long\n", len));
+ return NULL;
+ }
+
+ rl = read(c, buf, len);
+
+ if (rl < 0)
+ {
+ DEBUG(0, ("Unable to read from connection\n"));
+ return NULL;
+ }
+
+#ifdef DEBUG_PASSWORD
+ dump_data(100, buf, rl);
+#endif
+ /* make a static data parsing structure from the api_fd_reply data */
+ prs_init(&ps, 0, 4, True);
+ prs_append_data(&ps, buf, rl);
+
+ if (!creds_io_cmd("creds", &cmd, &ps, 0))
+ {
+ DEBUG(0, ("Unable to parse credentials\n"));
+ prs_free_data(&ps);
+ return NULL;
+ }
+
+ prs_free_data(&ps);
+
+ if (ps.offset != rl)
+ {
+ DEBUG(0, ("Buffer size %d %d!\n", ps.offset, rl));
+ return NULL;
+ }
+
+ switch (cmd.command)
+ {
+ case AGENT_CMD_CON:
+ {
+ new_con = True;
+ break;
+ }
+ case AGENT_CMD_CON_REUSE:
+ {
+ new_con = True;
+ reuse = True;
+ break;
+ }
+ default:
+ {
+ DEBUG(0, ("unknown command %d\n", cmd.command));
+ return NULL;
+ }
+ }
+
+ if (new_con)
+ {
+ struct cli_state *n;
+ n =
+ cli_net_use_add(cmd.name, cmd.key, &usr.ntc, False,
+ reuse);
+
+ if (n == NULL)
+ {
+ DEBUG(0, ("Unable to connect to %s\n", cmd.name));
+ return NULL;
+ }
+
+ mid_offset += MIN(MAX(n->max_mux, 1), MAX_MAX_MUX_LIMIT);
+
+ if (mid_offset > 0xffff)
+ {
+ mid_offset = 0x0;
+ }
+ DEBUG(10, ("new mid offset: %d\n", mid_offset));
+
+ if (write(c, n, sizeof(*n)) < 0)
+ {
+ DEBUG(0, ("Could not write connection down pipe.\n"));
+ cli_net_use_del(cmd.name, &usr.ntc, False, NULL);
+ return NULL;
+ }
+ return n;
+ }
+ return NULL;
+}
+
+static void filter_reply(char *buf, int moff)
+{
+ int msg_type = CVAL(buf, 0);
+ int x;
+
+ if (msg_type != 0x0)
+ return;
+
+ /* alter the mid */
+ x = SVAL(buf, smb_mid);
+ x += moff;
+
+ if (x < 0)
+ {
+ x += 0x10000;
+ }
+ if (x > 0xffff)
+ {
+ x -= 0x10000;
+ }
+
+ SCVAL(buf, smb_mid, x);
+
+}
+
+static BOOL process_cli_sock(struct sock_redir **socks, uint32 num_socks,
+ struct sock_redir *sock)
+{
+ struct cli_state *n = (struct cli_state *)sock->n;
+ if (n == NULL)
+ {
+ n = init_client_connection(sock->c);
+ if (n == NULL)
+ {
+ return False;
+ }
+ sock->n = (void *)n;
+ sock->s_id = mid_offset;
+ sock->s = n->fd;
+ }
+ else
+ {
+ if (!receive_smb(sock->c, packet, 0))
+ {
+ DEBUG(0, ("client closed connection\n"));
+ return False;
+ }
+
+ filter_reply(packet, sock->s_id);
+ /* ignore keep-alives */
+ if (CVAL(packet, 0) != 0x85)
+ {
+ if (!send_smb(sock->s, packet))
+ {
+ DEBUG(0, ("server is dead\n"));
+ return False;
+ }
+ }
+ }
+ return True;
+}
+
+static int get_smbmid(char *buf)
+{
+ int msg_type = CVAL(buf, 0);
+
+ if (msg_type != 0x0)
+ {
+ return -1;
+ }
+
+ return SVAL(buf, smb_mid);
+}
+
+static BOOL process_srv_sock(struct sock_redir **socks, uint32 num_socks,
+ int fd)
+{
+ int smbmid;
+ int i;
+ if (!receive_smb(fd, packet, 0))
+ {
+ DEBUG(0, ("server closed connection\n"));
+ return False;
+ }
+
+ smbmid = get_smbmid(packet);
+
+ DEBUG(10, ("process_srv_sock:\tfd:\t%d\tmid:\t%d\n", fd, smbmid));
+
+ if (smbmid == -1)
+ {
+ return True;
+ }
+
+ for (i = 0; i < num_socks; i++)
+ {
+ int moff;
+ struct cli_state *n;
+ if (socks[i] == NULL || socks[i]->n == NULL)
+ {
+ continue;
+ }
+ moff = socks[i]->s_id;
+ n = (struct cli_state *)socks[i]->n;
+ DEBUG(10, ("list:\tfd:\t%d\tmid:\t%d\tmoff:\t%d\n",
+ socks[i]->s, n->mid, moff));
+ if (smbmid != n->mid + moff)
+ {
+ continue;
+ }
+ filter_reply(packet, -moff);
+ if (!send_smb(socks[i]->c, packet))
+ {
+ DEBUG(0, ("client is dead\n"));
+ return False;
+ }
+ return True;
+ }
+ return False;
+}
+
+static int get_agent_sock(char *id)
+{
+ int s;
+ fstring path;
+ fstring dir;
+
+ slprintf(dir, sizeof(dir) - 1, "/tmp/.smb.%d", getuid());
+ slprintf(path, sizeof(path) - 1, "%s/agent", dir);
+
+ s = create_pipe_socket(dir, 0700, path, 0700);
+
+ if (s == -1)
+ return -1;
+ /* ready to listen */
+ if (listen(s, 5) == -1)
+ {
+ DEBUG(0, ("listen: %s\n", strerror(errno)));
+ close(s);
+ return -1;
+ }
+ return s;
+}
+
+static void start_smb_agent(void)
+{
+ struct vagent_ops va = {
+ free_sock,
+ get_agent_sock,
+ process_cli_sock,
+ process_srv_sock,
+ NULL,
+ NULL,
+ 0
+ };
+
+ CatchChild();
+
+ start_agent(&va);
+}
+
+/****************************************************************************
+usage on the program
+****************************************************************************/
+static void usage(char *pname)
+{
+ printf("Usage: %s [-D]", pname);
+
+ printf("\nVersion %s\n", VERSION);
+ printf("\t-D run as a daemon\n");
+ printf("\t-h usage\n");
+ printf("\n");
+}
+
+int main(int argc, char *argv[])
+{
+ pstring configfile;
+ BOOL is_daemon = False;
+ int opt;
+ extern pstring debugf;
+
+ TimeInit();
+
+ pstrcpy(configfile, CONFIGFILE);
+
+ while ((opt = getopt(argc, argv, "Dh")) != EOF)
+ {
+ switch (opt)
+ {
+ case 'D':
+ {
+ is_daemon = True;
+ break;
+ }
+ case 'h':
+ default:
+ {
+ usage(argv[0]);
+ break;
+ }
+ }
+ }
+
+ slprintf(debugf, sizeof(debugf) - 1, "log.%s", argv[0]);
+ setup_logging(argv[0], !is_daemon);
+
+ charset_initialise();
+
+ if (!lp_load(configfile, True, False, False))
+ {
+ DEBUG(0, ("Unable to load config file\n"));
+ }
+
+ if (is_daemon)
+ {
+ DEBUG(0, ("%s: becoming daemon\n", argv[0]));
+ become_daemon();
+ }
+
+ start_smb_agent();
+
+ return 0;
+}
diff --git a/source/utils/smbfilter.c b/source/utils/smbfilter.c
index 81b10e4519a..27e1f9ef67d 100644
--- a/source/utils/smbfilter.c
+++ b/source/utils/smbfilter.c
@@ -120,7 +120,7 @@ static void filter_child(int c, struct in_addr dest_ip)
if (s != -1) FD_SET(s, &fds);
if (c != -1) FD_SET(c, &fds);
- num = sys_select(MAX(s+1, c+1),&fds,NULL);
+ num = sys_select(MAX(s+1, c+1),&fds,NULL, NULL);
if (num <= 0) continue;
if (c != -1 && FD_ISSET(c, &fds)) {
@@ -184,7 +184,7 @@ static void start_filter(char *desthost)
FD_ZERO(&fds);
FD_SET(s, &fds);
- num = sys_select(s+1,&fds,NULL);
+ num = sys_select(s+1,&fds,NULL, NULL);
if (num > 0) {
c = accept(s, &addr, &in_addrlen);
if (c != -1) {
diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c
index dcfafaa8b92..82dfbfa8600 100644
--- a/source/utils/smbpasswd.c
+++ b/source/utils/smbpasswd.c
@@ -1,6 +1,7 @@
/*
- * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module. Copyright
- * (C) Jeremy Allison 1995-1998
+ * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module.
+ * Copyright (C) Jeremy Allison 1995-2000
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
@@ -19,7 +20,9 @@
#include "includes.h"
+extern pstring myhostname;
extern pstring global_myname;
+extern pstring global_myworkgroup;
extern int DEBUGLEVEL;
/*
@@ -61,87 +64,15 @@ static void usage(void)
if (getuid() == 0) {
printf(" -R ORDER name resolve order\n");
- printf(" -j DOMAIN join domain name\n");
printf(" -a add user\n");
- printf(" -x delete user\n");
printf(" -d disable user\n");
printf(" -e enable user\n");
printf(" -n set no password\n");
- printf(" -m machine trust account\n");
- }
- exit(1);
-}
-
-/*********************************************************
-Join a domain.
-**********************************************************/
-static int join_domain(char *domain, char *remote)
-{
- pstring remote_machine;
- fstring trust_passwd;
- unsigned char orig_trust_passwd_hash[16];
- BOOL ret;
-
- pstrcpy(remote_machine, remote ? remote : "");
- fstrcpy(trust_passwd, global_myname);
- strlower(trust_passwd);
- E_md4hash( (uchar *)trust_passwd, orig_trust_passwd_hash);
-
- /* Ensure that we are not trying to join a
- domain if we are locally set up as a domain
- controller. */
-
- if(strequal(remote, global_myname)) {
- fprintf(stderr, "Cannot join domain %s as the domain controller name is our own. We cannot be a domain controller for a domain and also be a domain member.\n", domain);
- return 1;
- }
-
- /*
- * Create the machine account password file.
- */
- if(!trust_password_lock( domain, global_myname, True)) {
- fprintf(stderr, "Unable to open the machine account password file for \
-machine %s in domain %s.\n", global_myname, domain);
- return 1;
- }
-
- /*
- * Write the old machine account password.
- */
-
- if(!set_trust_account_password( orig_trust_passwd_hash)) {
- fprintf(stderr, "Unable to write the machine account password for \
-machine %s in domain %s.\n", global_myname, domain);
- trust_password_unlock();
- return 1;
- }
-
- /*
- * If we are given a remote machine assume this is the PDC.
- */
-
- if(remote == NULL) {
- pstrcpy(remote_machine, lp_passwordserver());
- }
-
- if(!*remote_machine) {
- fprintf(stderr, "No password server list given in smb.conf - \
-unable to join domain.\n");
- trust_password_unlock();
- return 1;
- }
-
- ret = change_trust_account_password( domain, remote_machine);
- trust_password_unlock();
-
- if(!ret) {
- trust_password_delete( domain, global_myname);
- fprintf(stderr,"Unable to join domain %s.\n",domain);
- } else {
- printf("Joined domain %s.\n",domain);
+ printf(" -p user cannot change password\n");
+ printf(" -x user can change password\n");
}
- return (int)ret;
+ exit(1);
}
@@ -210,7 +141,6 @@ static char *prompt_for_new_password(BOOL stdin_get)
if (strcmp(p, new_passwd)) {
fprintf(stderr, "Mismatch - password unchanged.\n");
- ZERO_ARRAY(new_passwd);
return NULL;
}
@@ -219,109 +149,173 @@ static char *prompt_for_new_password(BOOL stdin_get)
/*************************************************************
- Change a password either locally or remotely.
+change a password either locally or remotely
*************************************************************/
-
static BOOL password_change(const char *remote_machine, char *user_name,
- char *old_passwd, char *new_passwd, int local_flags)
+ char *old_passwd, char *new_passwd,
+ BOOL add_user,
+ uint16 acb_info, uint16 acb_mask)
{
BOOL ret;
pstring err_str;
pstring msg_str;
- if (remote_machine != NULL) {
- if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|
- LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) {
+ if (remote_machine != NULL)
+ {
+ if (add_user ||
+ IS_BITS_SET_SOME(acb_info, ACB_PWNOTREQ | ACB_WSTRUST | ACB_DOMTRUST | ACB_SVRTRUST) ||
+ (IS_BITS_SET_SOME(acb_mask, ACB_DISABLED) &&
+ IS_BITS_CLR_ALL(acb_info, ACB_DISABLED)))
+ {
/* these things can't be done remotely yet */
return False;
}
ret = remote_password_change(remote_machine, user_name,
- old_passwd, new_passwd, err_str, sizeof(err_str));
- if(*err_str)
+ old_passwd, new_passwd,
+ err_str, sizeof(err_str));
+ if (*err_str != 0)
+ {
fprintf(stderr, err_str);
+ }
return ret;
}
- ret = local_password_change(user_name, local_flags, new_passwd,
- err_str, sizeof(err_str), msg_str, sizeof(msg_str));
+ ret = local_password_change(user_name, add_user, acb_info, acb_mask,
+ new_passwd,
+ err_str, sizeof(err_str),
+ msg_str, sizeof(msg_str));
- if(*msg_str)
+ if (*msg_str != 0)
+ {
printf(msg_str);
- if(*err_str)
+ }
+ if (*err_str != 0)
+ {
fprintf(stderr, err_str);
+ }
return ret;
}
/*************************************************************
- Handle password changing for root.
+handle password changing for root
*************************************************************/
-
static int process_root(int argc, char *argv[])
{
struct passwd *pwd;
int ch;
- BOOL joining_domain = False;
- int local_flags = 0;
+ uint16 acb_info = 0;
+ uint16 acb_mask = 0;
+ BOOL add_user = False;
+ BOOL disable_user = False;
+ BOOL enable_user = False;
+ BOOL set_no_password = False;
BOOL stdin_passwd_get = False;
+ BOOL lock_password = False;
+ BOOL unlock_password = False;
char *user_name = NULL;
- char *new_domain = NULL;
char *new_passwd = NULL;
char *old_passwd = NULL;
char *remote_machine = NULL;
- while ((ch = getopt(argc, argv, "a:x:d:e:mnj:r:sR:D:U:")) != EOF) {
- switch(ch) {
- case 'a':
- local_flags |= LOCAL_ADD_USER;
- user_name = optarg;
- break;
- case 'x':
- local_flags |= LOCAL_DELETE_USER;
- user_name = optarg;
- new_passwd = "XXXXXX";
- break;
- case 'd':
- local_flags |= LOCAL_DISABLE_USER;
- user_name = optarg;
- new_passwd = "XXXXXX";
- break;
- case 'e':
- local_flags |= LOCAL_ENABLE_USER;
- user_name = optarg;
- break;
- case 'm':
- local_flags |= LOCAL_TRUST_ACCOUNT;
- break;
- case 'n':
- local_flags |= LOCAL_SET_NO_PASSWORD;
- new_passwd = "NO PASSWORD";
- case 'j':
- new_domain = optarg;
- strupper(new_domain);
- joining_domain = True;
- break;
- case 'r':
- remote_machine = optarg;
- break;
- case 's':
- set_line_buffering(stdin);
- set_line_buffering(stdout);
- set_line_buffering(stderr);
- stdin_passwd_get = True;
- break;
- case 'R':
- lp_set_name_resolve_order(optarg);
- break;
- case 'D':
- DEBUGLEVEL = atoi(optarg);
- break;
- case 'U':
- user_name = optarg;
- break;
- default:
- usage();
+ while ((ch = getopt(argc, argv, "abdehimnpxj:Sr:sR:D:U:")) != EOF)
+ {
+ switch(ch)
+ {
+ case 'a':
+ {
+ add_user = True;
+ break;
+ }
+ case 'd':
+ {
+ disable_user = True;
+ new_passwd = "XXXXXX";
+ break;
+ }
+ case 'e':
+ {
+ enable_user = True;
+ break;
+ }
+ case 'D':
+ {
+ DEBUGLEVEL = atoi(optarg);
+ break;
+ }
+ case 'n':
+ {
+ set_no_password = True;
+ new_passwd = "NO PASSWORD";
+ }
+ case 'r':
+ {
+ remote_machine = optarg;
+ break;
+ }
+ case 's':
+ {
+ set_line_buffering(stdin);
+ set_line_buffering(stdout);
+ set_line_buffering(stderr);
+ stdin_passwd_get = True;
+ break;
+ }
+ case 'R':
+ {
+ lp_set_name_resolve_order(optarg);
+ break;
+ }
+ case 'i':
+ {
+ fprintf(stderr, "The -i option has been disabled. Please use samedit's createtrust command.\n");
+ exit(-1);
+ break;
+ }
+ case 'b':
+ {
+ fprintf(stderr, "The -b option is disabled. Please use samedit's createuser account$ -j command.\n");
+ exit(-1);
+ break;
+ }
+ case 'm':
+ {
+ fprintf(stderr, "The -m option is disabled. Please use samedit's createuser account$ command.\n");
+ exit(-1);
+ break;
+ }
+ case 'j':
+ {
+ fprintf(stderr, "The -j option is disabled. Please use samedit's createuser account$ -j command.\n");
+ exit(-1);
+ break;
+ }
+ case 'S':
+ {
+ fprintf(stderr, "The -S option is disabled. Please use samedit's samsync command.\n");
+ exit(-1);
+ break;
+ }
+ case 'U':
+ {
+ user_name = optarg;
+ break;
+ }
+ case 'p':
+ {
+ lock_password = True;
+ break;
+ }
+ case 'x':
+ {
+ unlock_password = True;
+ break;
+ }
+ default:
+ {
+ usage();
+ }
}
}
@@ -330,20 +324,6 @@ static int process_root(int argc, char *argv[])
/*
- * Ensure add/delete user and either remote machine or join domain are
- * not both set.
- */
- if((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) && ((remote_machine != NULL) || joining_domain)) {
- usage();
- }
-
- if(joining_domain) {
- if (argc != 0)
- usage();
- return join_domain(new_domain, remote_machine);
- }
-
- /*
* Deal with root - can add a user, but only locally.
*/
@@ -361,7 +341,7 @@ static int process_root(int argc, char *argv[])
usage();
}
- if (!user_name && (pwd = sys_getpwuid(0))) {
+ if (!user_name && (pwd = getpwuid(0))) {
user_name = xstrdup(pwd->pw_name);
}
@@ -370,39 +350,18 @@ static int process_root(int argc, char *argv[])
exit(1);
}
- if (local_flags & LOCAL_TRUST_ACCOUNT) {
- /* add the $ automatically */
- static fstring buf;
-
- /*
- * Remove any trailing '$' before we
- * generate the initial machine password.
- */
-
- if (user_name[strlen(user_name)-1] == '$') {
- user_name[strlen(user_name)-1] = 0;
- }
-
- if (local_flags & LOCAL_ADD_USER) {
- new_passwd = xstrdup(user_name);
- strlower(new_passwd);
- }
-
- /*
- * Now ensure the username ends in '$' for
- * the machine add.
- */
-
- slprintf(buf, sizeof(buf)-1, "%s$", user_name);
- user_name = buf;
+ if (!remote_machine && !Get_Pwnam(user_name, True)) {
+ fprintf(stderr, "User \"%s\" was not found in system password file.\n",
+ user_name);
+ exit(1);
}
if (remote_machine != NULL) {
old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
}
- if (!new_passwd) {
-
+ if (!new_passwd)
+ {
/*
* If we are trying to enable a user, first we need to find out
* if they are using a modern version of the smbpasswd file that
@@ -412,35 +371,73 @@ static int process_root(int argc, char *argv[])
* smbpasswd file) then we need to prompt for a new password.
*/
- if(local_flags & LOCAL_ENABLE_USER) {
+ if (enable_user)
+ {
struct smb_passwd *smb_pass = getsmbpwnam(user_name);
- if((smb_pass != NULL) && (smb_pass->smb_passwd != NULL)) {
+ if((smb_pass != NULL) && (smb_pass->smb_passwd != NULL))
+ {
new_passwd = "XXXX"; /* Don't care. */
}
}
if(!new_passwd)
+ {
new_passwd = prompt_for_new_password(stdin_passwd_get);
-
- if(!new_passwd) {
- fprintf(stderr, "Unable to get new password.\n");
- exit(1);
}
}
- if (!password_change(remote_machine, user_name, old_passwd, new_passwd, local_flags)) {
- fprintf(stderr,"Failed to modify password entry for user %s\n", user_name);
+ if (enable_user)
+ {
+ acb_mask |= ACB_DISABLED;
+ acb_info &= ~ACB_DISABLED;
+ }
+
+ if (disable_user)
+ {
+ acb_mask |= ACB_DISABLED;
+ acb_info |= ACB_DISABLED;
+ }
+
+ if (set_no_password)
+ {
+ acb_mask |= ACB_PWNOTREQ;
+ acb_info |= ACB_PWNOTREQ;
+ }
+
+ if (lock_password)
+ {
+ acb_mask |= ACB_PWLOCK;
+ acb_info |= ACB_PWLOCK;
+ }
+
+ if (unlock_password)
+ {
+ acb_mask |= ACB_PWLOCK;
+ acb_info &= ~ACB_PWLOCK;
+ }
+
+ if (!password_change(remote_machine, user_name, old_passwd, new_passwd,
+ add_user, acb_info, acb_mask))
+ {
+ fprintf(stderr,"Failed to change password entry for %s\n", user_name);
return 1;
}
- if(!(local_flags & (LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|LOCAL_DELETE_USER|LOCAL_SET_NO_PASSWORD))) {
- struct smb_passwd *smb_pass = getsmbpwnam(user_name);
- printf("Password changed for user %s.", user_name );
- if((smb_pass != NULL) && (smb_pass->acct_ctrl & ACB_DISABLED ))
- printf(" User has disabled flag set.");
- if((smb_pass != NULL) && (smb_pass->acct_ctrl & ACB_PWNOTREQ))
- printf(" User has no password flag set.");
- printf("\n");
+ if (disable_user)
+ {
+ printf("User %s disabled.\n", user_name);
+ }
+ if (enable_user)
+ {
+ printf("User %s enabled.\n", user_name);
+ }
+ if (set_no_password)
+ {
+ printf("User %s - set to no password.\n", user_name);
+ }
+ if (!disable_user && !enable_user && !set_no_password)
+ {
+ printf("Password changed for user %s\n", user_name);
}
return 0;
}
@@ -458,9 +455,11 @@ static int process_nonroot(int argc, char *argv[])
char *remote_machine = NULL;
char *user_name = NULL;
char *new_passwd = NULL;
-
- while ((ch = getopt(argc, argv, "hD:r:sU:")) != EOF) {
- switch(ch) {
+
+ while ((ch = getopt(argc, argv, "hD:r:sU:")) != EOF)
+ {
+ switch(ch)
+ {
case 'D':
DEBUGLEVEL = atoi(optarg);
break;
@@ -493,7 +492,7 @@ static int process_nonroot(int argc, char *argv[])
}
if (!user_name) {
- pwd = sys_getpwuid(getuid());
+ pwd = getpwuid(getuid());
if (pwd) {
user_name = xstrdup(pwd->pw_name);
} else {
@@ -511,7 +510,6 @@ static int process_nonroot(int argc, char *argv[])
remote_machine = "127.0.0.1";
}
-
if (remote_machine != NULL) {
old_passwd = get_pass("Old SMB password:",stdin_passwd_get);
}
@@ -521,11 +519,14 @@ static int process_nonroot(int argc, char *argv[])
}
if (!new_passwd) {
- fprintf(stderr, "Unable to get new password.\n");
- exit(1);
+ printf("unable to get new password\n");
+ exit(0);
}
- if (!password_change(remote_machine, user_name, old_passwd, new_passwd, 0)) {
+ if (!password_change(remote_machine, user_name,
+ old_passwd, new_passwd,
+ False, 0x0, 0x0))
+ {
fprintf(stderr,"Failed to change password for %s\n", user_name);
return 1;
}
@@ -543,27 +544,23 @@ int main(int argc, char **argv)
{
static pstring servicesf = CONFIGFILE;
-#if defined(HAVE_SET_AUTH_PARAMETERS)
- set_auth_parameters(argc, argv);
-#endif /* HAVE_SET_AUTH_PARAMETERS */
-
TimeInit();
setup_logging("smbpasswd", True);
charset_initialise();
- if(!initialize_password_db()) {
- fprintf(stderr, "Can't setup password database vectors.\n");
- exit(1);
- }
-
if (!lp_load(servicesf,True,False,False)) {
fprintf(stderr, "Can't load %s - run testparm to debug it\n",
servicesf);
exit(1);
}
+ if(!get_myname(myhostname,NULL)) {
+ fprintf(stderr, "unable to get my hostname.\n");
+ exit(1);
+ }
+
/*
* Set the machine NETBIOS name if not already
* set from the config file.
@@ -571,7 +568,7 @@ int main(int argc, char **argv)
if (!*global_myname) {
char *p;
- fstrcpy(global_myname, myhostname());
+ fstrcpy(global_myname, myhostname);
p = strchr(global_myname, '.' );
if (p) *p = 0;
}
@@ -581,6 +578,12 @@ int main(int argc, char **argv)
load_interfaces();
+ if (!init_myworkgroup() || !initialise_password_db())
+ {
+ fprintf(stderr, "Can't setup password database vectors.\n");
+ exit(1);
+ }
+
/* Check the effective uid - make sure we are not setuid */
if ((geteuid() == (uid_t)0) && (getuid() != (uid_t)0)) {
fprintf(stderr, "smbpasswd must *NOT* be setuid root.\n");
diff --git a/source/utils/smbrun.c b/source/utils/smbrun.c
index b7c678411c6..2a94ac32353 100644
--- a/source/utils/smbrun.c
+++ b/source/utils/smbrun.c
@@ -48,17 +48,35 @@ It takes 3 arguments as uid,gid,command and runs command after
becoming a non-root user */
int main(int argc,char *argv[])
{
- uid_t uid;
- gid_t gid;
+ int uid,gid;
close_fds();
if (argc != 4) exit(2);
- uid = (uid_t)atoi(argv[1]);
- gid = (gid_t)atoi(argv[2]);
+ uid = atoi(argv[1]);
+ gid = atoi(argv[2]);
+
+ /* first become root - we may need to do this in order to lose
+ our privilages! */
+#ifdef HAVE_SETRESUID
+ setresgid(0,0,0);
+ setresuid(0,0,0);
+#else
+ setuid(0);
+ seteuid(0);
+#endif
+
+#ifdef HAVE_SETRESUID
+ setresgid(gid,gid,gid);
+ setresuid(uid,uid,uid);
+#else
+ setgid(gid);
+ setegid(gid);
+ setuid(uid);
+ seteuid(uid);
+#endif
- become_user_permanently( uid, gid);
/* paranoia :-) */
if (getuid() != uid)
diff --git a/source/utils/status.c b/source/utils/status.c
index 5c01409737c..b5c3ab0d2c4 100644
--- a/source/utils/status.c
+++ b/source/utils/status.c
@@ -55,11 +55,6 @@ static int verbose, brief;
static int shares_only = 0; /* Added by RJS */
static int locks_only = 0; /* Added by RJS */
static BOOL processes_only=False;
-static int show_brl;
-
-/* we need these because we link to locking*.o */
- void become_root(BOOL save_dir) {}
- void unbecome_root(BOOL restore_dir) {}
/* added by OH */
@@ -108,13 +103,12 @@ static void print_share_mode(share_mode_entry *e, char *fname)
if (Ucrit_checkPid(e->pid)) {
printf("%-5d ",(int)e->pid);
- switch (GET_DENY_MODE(e->share_mode)) {
+ switch ((e->share_mode>>4)&0xF) {
case DENY_NONE: printf("DENY_NONE "); break;
case DENY_ALL: printf("DENY_ALL "); break;
case DENY_DOS: printf("DENY_DOS "); break;
case DENY_READ: printf("DENY_READ "); break;
case DENY_WRITE:printf("DENY_WRITE "); break;
- case DENY_FCB: printf("DENY_FCB "); break;
}
switch (e->share_mode&0xF) {
case 0: printf("RDONLY "); break;
@@ -140,24 +134,6 @@ static void print_share_mode(share_mode_entry *e, char *fname)
}
}
-static void print_brl(SMB_DEV_T dev, SMB_INO_T ino, int pid,
- enum brl_type lock_type,
- br_off start, br_off size)
-{
- static int count;
- if (count==0) {
- printf("Byte range locks:\n");
- printf(" Pid dev:inode R/W start size\n");
- printf("------------------------------------------------\n");
- }
- count++;
-
- printf("%6d %05x:%05x %s %9.0f %9.0f\n",
- (int)pid, (int)dev, (int)ino,
- lock_type==READ_LOCK?"R":"W",
- (double)start, (double)size);
-}
-
/*******************************************************************
dump the elements of the profile structure
@@ -180,7 +156,7 @@ static int profile_dump(void)
}
-static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state)
+static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void* state)
{
static pid_t last_pid;
struct session_record *ptr;
@@ -258,14 +234,11 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
return(1);
}
- while ((c = getopt(argc, argv, "pdLSs:u:bPB")) != EOF) {
+ while ((c = getopt(argc, argv, "pdLSs:u:bP")) != EOF) {
switch (c) {
case 'b':
brief = 1;
break;
- case 'B':
- show_brl = 1;
- break;
case 'd':
verbose = 1;
break;
@@ -363,10 +336,6 @@ static int traverse_fn1(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st
}
printf("\n");
-
- if (show_brl) {
- brl_forall(print_brl);
- }
locking_end();
}
diff --git a/source/utils/testparm.c b/source/utils/testparm.c
index e4f603e0ce2..dea9ed28dd0 100644
--- a/source/utils/testparm.c
+++ b/source/utils/testparm.c
@@ -38,153 +38,46 @@
/* these live in util.c */
extern FILE *dbf;
extern int DEBUGLEVEL;
+extern pstring myhostname;
/***********************************************
Here we do a set of 'hard coded' checks for bad
configuration settings.
************************************************/
-
-static int do_global_checks(void)
+static void do_global_checks(void)
{
- int ret = 0;
SMB_STRUCT_STAT st;
-
if (lp_security() > SEC_SHARE && lp_revalidate(-1)) {
printf("WARNING: the 'revalidate' parameter is ignored in all but \
'security=share' mode.\n");
}
- if (lp_security() == SEC_DOMAIN && !lp_encrypted_passwords()) {
+ if (lp_security() == SEC_DOMAIN && !lp_encrypted_passwords()) {
printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must also be set to 'true'.\n");
- ret = 1;
}
if (lp_wins_support() && *lp_wins_server()) {
printf("ERROR: both 'wins support = true' and 'wins server = <server>' \
cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
- ret = 1;
}
if (!directory_exist(lp_lockdir(), &st)) {
printf("ERROR: lock directory %s does not exist\n",
lp_lockdir());
- ret = 1;
} else if ((st.st_mode & 0777) != 0755) {
printf("WARNING: lock directory %s should have permissions 0755 for browsing to work\n",
lp_lockdir());
- ret = 1;
- }
-
- /*
- * Password server sanity checks.
- */
-
- if((lp_security() == SEC_SERVER || lp_security() == SEC_DOMAIN) && !lp_passwordserver()) {
- pstring sec_setting;
- if(lp_security() == SEC_SERVER)
- pstrcpy(sec_setting, "server");
- else if(lp_security() == SEC_DOMAIN)
- pstrcpy(sec_setting, "domain");
-
- printf("ERROR: The setting 'security=%s' requires the 'password server' parameter be set \
-to a valid password server.\n", sec_setting );
- ret = 1;
- }
-
- /*
- * Password chat sanity checks.
- */
-
- if(lp_security() == SEC_USER && lp_unix_password_sync()) {
-
- /*
- * Check that we have a valid lp_passwd_program().
- */
-
- if(lp_passwd_program() == NULL) {
- printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \
-parameter.\n" );
- ret = 1;
- } else {
- pstring passwd_prog;
- pstring truncated_prog;
- char *p;
-
- pstrcpy( passwd_prog, lp_passwd_program());
- p = passwd_prog;
- *truncated_prog = '\0';
- next_token(&p, truncated_prog, NULL, sizeof(pstring));
-
- if(access(truncated_prog, F_OK) == -1) {
- printf("ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \
-cannot be executed (error was %s).\n", truncated_prog, strerror(errno) );
- ret = 1;
- }
- }
-
- if(lp_passwd_chat() == NULL) {
- printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \
-parameter.\n");
- ret = 1;
- }
-
- /*
- * Check that we have a valid script and that it hasn't
- * been written to expect the old password.
- */
-
- if(lp_encrypted_passwords()) {
- if(strstr( lp_passwd_chat(), "%o")!=NULL) {
- printf("ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \
-via the %%o substitution. With encrypted passwords this is not possible.\n", lp_passwd_chat() );
- ret = 1;
- }
- }
- }
-
- /*
- * WINS server line sanity checks.
- */
-
- if(*lp_wins_server()) {
- fstring server;
- int count = 0;
- char *p = lp_wins_server();
-
- while(next_token(&p,server,LIST_SEP,sizeof(server)))
- count++;
- if(count > 1) {
- printf("ERROR: the 'wins server' parameter must only contain one WINS server.\n");
- ret = -1;
- }
}
-
- return ret;
}
-static void usage(char *pname)
-{
- printf("Usage: %s [-sh] [-L servername] [configfilename] [hostname hostIP]\n", pname);
- printf("\t-s Suppress prompt for enter\n");
- printf("\t-h Print usage\n");
- printf("\t-L servername Set %%L macro to servername\n");
- printf("\tconfigfilename Configuration file to test\n");
- printf("\thostname hostIP. Hostname and Host IP address to test\n");
- printf("\t against \"host allow\" and \"host deny\"\n");
- printf("\n");
-}
-
-
-int main(int argc, char *argv[])
+ int main(int argc, char *argv[])
{
extern char *optarg;
extern int optind;
- extern fstring local_machine;
pstring configfile;
int opt;
int s;
BOOL silent_mode = False;
- int ret = 0;
TimeInit();
@@ -192,23 +85,11 @@ int main(int argc, char *argv[])
charset_initialise();
- while ((opt = getopt(argc, argv,"shL:")) != EOF) {
+ while ((opt = getopt(argc, argv,"s")) != EOF) {
switch (opt) {
case 's':
silent_mode = True;
break;
- case 'L':
- fstrcpy(local_machine,optarg);
- break;
- case 'h':
- usage(argv[0]);
- exit(0);
- break;
- default:
- printf("Incorrect program usage\n");
- usage(argv[0]);
- exit(1);
- break;
}
}
@@ -224,87 +105,71 @@ int main(int argc, char *argv[])
printf("Load smb config files from %s\n",configfile);
- if (!lp_load(configfile,False,True,False)) {
+ if(!get_myname(myhostname,NULL))
+ {
+ printf("Failed to get my hostname.\n");
+ return(1);
+ }
+
+ if (!lp_load(configfile,False,True,False))
+ {
printf("Error loading services.\n");
return(1);
- }
+ }
+
printf("Loaded services file OK.\n");
- ret = do_global_checks();
+ do_global_checks();
- for (s=0;s<1000;s++) {
+ for (s=0;s<1000;s++)
if (VALID_SNUM(s))
if (strlen(lp_servicename(s)) > 8) {
- printf("WARNING: You have some share names that are longer than 8 chars\n");
- printf("These may give errors while browsing or may not be accessible\nto some older clients\n");
- break;
- }
- }
-
- for (s=0;s<1000;s++) {
- if (VALID_SNUM(s)) {
- char *deny_list = lp_hostsdeny(s);
- char *allow_list = lp_hostsallow(s);
- if(deny_list) {
- char *hasstar = strchr(deny_list, '*');
- char *hasquery = strchr(deny_list, '?');
- if(hasstar || hasquery) {
- printf("Invalid character %c in hosts deny list %s for service %s.\n",
- hasstar ? *hasstar : *hasquery, deny_list, lp_servicename(s) );
- }
+ printf("WARNING: You have some share names that are longer than 8 chars\n");
+ printf("These may give errors while browsing or may not be accessible\nto some older clients\n");
+ break;
}
- if(allow_list) {
- char *hasstar = strchr(allow_list, '*');
- char *hasquery = strchr(allow_list, '?');
- if(hasstar || hasquery) {
- printf("Invalid character %c in hosts allow list %s for service %s.\n",
- hasstar ? *hasstar : *hasquery, allow_list, lp_servicename(s) );
- }
+ if (argc < 3)
+ {
+ if (!silent_mode) {
+ printf("Press enter to see a dump of your service definitions\n");
+ fflush(stdout);
+ getc(stdin);
}
-
- if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
- printf("Invalid combination of parameters for service %s. \
-Level II oplocks can only be set if oplocks are also set.\n",
- lp_servicename(s) );
- }
- }
- }
-
- if (argc < 3) {
- if (!silent_mode) {
- printf("Press enter to see a dump of your service definitions\n");
- fflush(stdout);
- getc(stdin);
+ lp_dump(stdout,True);
}
- lp_dump(stdout,True, lp_numservices());
- }
- if (argc >= 3) {
- char *cname;
- char *caddr;
+ if (argc >= 3)
+ {
+ char *cname;
+ char *caddr;
- if (argc == 3) {
- cname = argv[optind];
- caddr = argv[optind+1];
- } else {
- cname = argv[optind+1];
- caddr = argv[optind+2];
- }
-
- /* this is totally ugly, a real `quick' hack */
- for (s=0;s<1000;s++) {
- if (VALID_SNUM(s)) {
- if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr)) {
- printf("Allow connection from %s (%s) to %s\n",
- cname,caddr,lp_servicename(s));
- } else {
- printf("Deny connection from %s (%s) to %s\n",
- cname,caddr,lp_servicename(s));
- }
+ if (argc == 3) {
+ cname = argv[optind];
+ caddr = argv[optind+1];
+ } else {
+ cname = argv[optind+1];
+ caddr = argv[optind+2];
}
+
+ /* this is totally ugly, a real `quick' hack */
+ for (s=0;s<1000;s++)
+ if (VALID_SNUM(s))
+ {
+ if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr))
+ {
+ printf("Allow connection from %s (%s) to %s\n",
+ cname,caddr,lp_servicename(s));
+ }
+ else
+ {
+ printf("Deny connection from %s (%s) to %s\n",
+ cname,caddr,lp_servicename(s));
+ }
+ }
}
- }
- return(ret);
+ return(0);
}
+
+
diff --git a/source/utils/torture.c b/source/utils/torture.c
index ad14461ff5b..1af3e71e228 100644
--- a/source/utils/torture.c
+++ b/source/utils/torture.c
@@ -23,13 +23,12 @@
#include "includes.h"
+extern int DEBUGLEVEL;
+extern pstring debugf;
+
static fstring host, workgroup, share, password, username, myname;
static int max_protocol = PROTOCOL_NT1;
-static char *sockops="TCP_NODELAY";
-static int nprocs=1, numops=100;
-static struct cli_state current_cli;
-
-static double create_procs(void (*fn)(int));
+static char *sockops="";
static struct timeval tp1,tp2;
@@ -46,101 +45,82 @@ static double end_timer(void)
(tp2.tv_usec - tp1.tv_usec)*1.0e-6);
}
+#define FAILED_NO_ERROR 0
+#define FAILED_TCP_CONNECT 1
+#define FAILED_SESSION_REQ 2
+#define FAILED_SMB_SESS_SETUP 3
+#define FAILED_SMB_TCON 4
+#define FAILED_SMB_NEGPROT 5
+#define FAILED_CLI_STATE_INIT 6
+#define NUM_ERR_STATES 7
-/* return a pointer to a anonymous shared memory segment of size "size"
- which will persist across fork() but will disappear when all processes
- exit
-
- The memory is not zeroed
-
- This function uses system5 shared memory. It takes advantage of a property
- that the memory is not destroyed if it is attached when the id is removed
- */
-static void *shm_setup(int size)
+static char *smb_messages[] =
{
- int shmid;
- void *ret;
-
- shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
- if (shmid == -1) {
- printf("can't get shared memory\n");
- exit(1);
- }
- ret = (void *)shmat(shmid, 0, 0);
- if (!ret || ret == (void *)-1) {
- printf("can't attach to shared memory\n");
- return NULL;
- }
- /* the following releases the ipc, but note that this process
- and all its children will still have access to the memory, its
- just that the shmid is no longer valid for other shm calls. This
- means we don't leave behind lots of shm segments after we exit
-
- See Stevens "advanced programming in unix env" for details
- */
- shmctl(shmid, IPC_RMID, 0);
-
- return ret;
-}
-
-
-static BOOL open_connection(struct cli_state *c)
+ "No errors in connection",
+ "TCP connection ",
+ "NetBIOS Session Request",
+ "SMB Session Setup ",
+ "SMB Tcon ",
+ "SMB Negprot ",
+ "Client initialisation "
+};
+
+static int open_connection(struct cli_state *c)
{
struct nmb_name called, calling;
- struct in_addr ip;
- extern struct in_addr ipzero;
ZERO_STRUCTP(c);
- make_nmb_name(&calling, myname, 0x0);
- make_nmb_name(&called , host, 0x20);
+ make_nmb_name(&calling, myname, 0x0, "");
+ make_nmb_name(&called , host, 0x20, "");
- ip = ipzero;
-
- if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
- printf("Failed to connect with %s\n", host);
- return False;
+ if (!cli_initialise(c))
+ {
+ DEBUG(0,("Failed to connect with %s\n", host));
+ return FAILED_CLI_STATE_INIT;
}
- c->timeout = 120000; /* set a really long timeout (2 minutes) */
+ if (!cli_connect(c, host, NULL)) {
+ DEBUG(0,("Failed to connect with %s\n", host));
+ return FAILED_TCP_CONNECT;
+ }
if (!cli_session_request(c, &calling, &called)) {
- printf("%s rejected the session\n",host);
cli_shutdown(c);
- return False;
+ DEBUG(0,("%s rejected the session\n",host));
+ return FAILED_SESSION_REQ;
}
if (!cli_negprot(c)) {
- printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
+ DEBUG(0,("%s rejected the negprot (%s)\n",host, cli_errstr(c)));
cli_shutdown(c);
- return False;
+ return FAILED_SMB_NEGPROT;
}
if (!cli_session_setup(c, username,
password, strlen(password),
password, strlen(password),
workgroup)) {
- printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
+ DEBUG(0,("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c)));
cli_shutdown(c);
- return False;
+ return FAILED_SMB_SESS_SETUP;
}
if (!cli_send_tconX(c, share, "?????",
password, strlen(password)+1)) {
- printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
+ DEBUG(0,("%s refused tree connect (%s)\n", host, cli_errstr(c)));
cli_shutdown(c);
- return False;
+ return FAILED_SMB_TCON;
}
- return True;
+ return FAILED_NO_ERROR;
}
-
static void close_connection(struct cli_state *c)
{
if (!cli_tdis(c)) {
- printf("tdis failed (%s)\n", cli_errstr(c));
+ DEBUG(0,("tdis failed (%s)\n", cli_errstr(c)));
}
cli_shutdown(c);
@@ -153,13 +133,14 @@ static BOOL check_error(struct cli_state *c,
{
uint8 class;
uint32 num;
- (void)cli_error(c, &class, &num, NULL);
+ int eno;
+ eno = cli_error(c, &class, &num);
if ((eclass != class || ecode != num) &&
num != (nterr&0xFFFFFF)) {
- printf("unexpected error code class=%d code=%d\n",
- (int)class, (int)num);
- printf(" expected %d/%d %d\n",
- (int)eclass, (int)ecode, (int)nterr);
+ DEBUG(0,("unexpected error code class=%d code=%d\n",
+ (int)class, (int)num));
+ DEBUG(0,(" expected %d/%d %d\n",
+ (int)eclass, (int)ecode, (int)nterr));
return False;
}
return True;
@@ -168,20 +149,20 @@ static BOOL check_error(struct cli_state *c,
static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
{
- while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
+ while (!cli_lock(c, fnum, offset, len, -1)) {
if (!check_error(c, ERRDOS, ERRlock, 0)) return False;
}
return True;
}
-static BOOL rw_torture(struct cli_state *c)
+static BOOL rw_torture(struct cli_state *c, int numops)
{
char *lockfname = "\\torture.lck";
fstring fname;
int fnum;
int fnum2;
- pid_t pid2, pid = getpid();
+ int pid2, pid = getpid();
int i, j;
char buf[1024];
@@ -190,7 +171,7 @@ static BOOL rw_torture(struct cli_state *c)
if (fnum2 == -1)
fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
if (fnum2 == -1) {
- printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
+ DEBUG(0,("open of %s failed (%s)\n", lockfname, cli_errstr(c)));
return False;
}
@@ -198,7 +179,7 @@ static BOOL rw_torture(struct cli_state *c)
for (i=0;i<numops;i++) {
unsigned n = (unsigned)sys_random()%10;
if (i % 10 == 0) {
- printf("%d\r", i); fflush(stdout);
+ DEBUG(0,("%d\r", i));
}
slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
@@ -208,194 +189,92 @@ static BOOL rw_torture(struct cli_state *c)
fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
if (fnum == -1) {
- printf("open failed (%s)\n", cli_errstr(c));
+ DEBUG(0,("open failed (%s)\n", cli_errstr(c)));
break;
}
- if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
- printf("write failed (%s)\n", cli_errstr(c));
+ if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid), 0) != sizeof(pid)) {
+ DEBUG(0,("write failed (%s)\n", cli_errstr(c)));
}
for (j=0;j<50;j++) {
if (cli_write(c, fnum, 0, (char *)buf,
sizeof(pid)+(j*sizeof(buf)),
- sizeof(buf)) != sizeof(buf)) {
- printf("write failed (%s)\n", cli_errstr(c));
+ sizeof(buf), 0) != sizeof(buf)) {
+ DEBUG(0,("write failed (%s)\n", cli_errstr(c)));
}
}
pid2 = 0;
- if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
- printf("read failed (%s)\n", cli_errstr(c));
+ if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid), True) != sizeof(pid)) {
+ DEBUG(0,("read failed (%s)\n", cli_errstr(c)));
}
if (pid2 != pid) {
- printf("data corruption!\n");
+ DEBUG(0,("data corruption!\n"));
}
if (!cli_close(c, fnum)) {
- printf("close failed (%s)\n", cli_errstr(c));
+ DEBUG(0,("close failed (%s)\n", cli_errstr(c)));
}
if (!cli_unlink(c, fname)) {
- printf("unlink failed (%s)\n", cli_errstr(c));
+ DEBUG(0,("unlink failed (%s)\n", cli_errstr(c)));
}
- if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
- printf("unlock failed (%s)\n", cli_errstr(c));
+ if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int), -1)) {
+ DEBUG(0,("unlock failed (%s)\n", cli_errstr(c)));
}
}
cli_close(c, fnum2);
cli_unlink(c, lockfname);
- printf("%d\n", i);
+ DEBUG(0,("%d\n", i));
return True;
}
-static void run_torture(int dummy)
+static void usage(void)
{
- struct cli_state cli;
-
- cli = current_cli;
+ printf("Usage: smbtorture //server/share <options>\n");
- cli_sockopt(&cli, sockops);
+ printf("\t-U user%%pass\n");
+ printf("\t-N numprocs\n");
+ printf("\t-n my_netbios_name\n");
+ printf("\t-W workgroup\n");
+ printf("\t-o num_operations\n");
+ printf("\t-O socket_options\n");
+ printf("\t-m maximum protocol\n");
+ printf("\n");
- rw_torture(&cli);
-
- close_connection(&cli);
+ exit(1);
}
-int line_count = 0;
-
-/* run a test that simulates an approximate netbench client load */
-static void run_netbench(int client)
-{
- struct cli_state cli;
- int i;
- fstring fname;
- pstring line;
- char cname[20];
- FILE *f;
- char *params[20];
- cli = current_cli;
- cli_sockopt(&cli, sockops);
+static void run_torture(int numops)
+{
+ static struct cli_state cli;
- nb_setup(&cli);
+ if (open_connection(&cli) == 0)
+ {
+ cli_sockopt(&cli, sockops);
- slprintf(cname,sizeof(fname), "CLIENT%d", client);
+ DEBUG(0,("pid %d OK\n", getpid()));
- f = fopen("client.txt", "r");
+ rw_torture(&cli, numops);
- if (!f) {
- perror("client.txt");
- return;
+ close_connection(&cli);
}
-
- while (fgets(line, sizeof(line)-1, f)) {
- line_count++;
-
- line[strlen(line)-1] = 0;
-
- /* printf("[%d] %s\n", line_count, line); */
-
- all_string_sub(line,"CLIENT1", cname, sizeof(line));
-
- for (i=0;i<20;i++) params[i] = "";
-
- /* parse the command parameters */
- params[0] = strtok(line," ");
- i = 0;
- while (params[i]) params[++i] = strtok(NULL," ");
-
- params[i] = "";
-
- if (i < 2) continue;
-
- if (strcmp(params[1],"REQUEST") == 0) {
- if (!strcmp(params[0],"SMBopenX")) {
- fstrcpy(fname, params[5]);
- } else if (!strcmp(params[0],"SMBclose")) {
- nb_close(atoi(params[3]));
- } else if (!strcmp(params[0],"SMBmkdir")) {
- nb_mkdir(params[3]);
- } else if (!strcmp(params[0],"CREATE")) {
- nb_create(params[3], atoi(params[5]));
- } else if (!strcmp(params[0],"SMBrmdir")) {
- nb_rmdir(params[3]);
- } else if (!strcmp(params[0],"SMBunlink")) {
- fstrcpy(fname, params[3]);
- } else if (!strcmp(params[0],"SMBmv")) {
- nb_rename(params[3], params[5]);
- } else if (!strcmp(params[0],"SMBgetatr")) {
- fstrcpy(fname, params[3]);
- } else if (!strcmp(params[0],"SMBwrite")) {
- nb_write(atoi(params[3]),
- atoi(params[5]), atoi(params[7]));
- } else if (!strcmp(params[0],"SMBwritebraw")) {
- nb_write(atoi(params[3]),
- atoi(params[7]), atoi(params[5]));
- } else if (!strcmp(params[0],"SMBreadbraw")) {
- nb_read(atoi(params[3]),
- atoi(params[7]), atoi(params[5]));
- } else if (!strcmp(params[0],"SMBread")) {
- nb_read(atoi(params[3]),
- atoi(params[5]), atoi(params[7]));
- }
- } else {
- if (!strcmp(params[0],"SMBopenX")) {
- if (!strncmp(params[2], "ERR", 3)) continue;
- nb_open(fname, atoi(params[3]), atoi(params[5]));
- } else if (!strcmp(params[0],"SMBgetatr")) {
- if (!strncmp(params[2], "ERR", 3)) continue;
- nb_stat(fname, atoi(params[3]));
- } else if (!strcmp(params[0],"SMBunlink")) {
- if (!strncmp(params[2], "ERR", 3)) continue;
- nb_unlink(fname);
- }
- }
+ else
+ {
+ DEBUG(0,("pid %d failed\n", getpid()));
}
- fclose(f);
-
- slprintf(fname,sizeof(fname), "CLIENTS/CLIENT%d", client);
- rmdir(fname);
- rmdir("CLIENTS");
-
- printf("+");
-
- close_connection(&cli);
-}
-
-/* run a test that simulates an approximate netbench w9X client load */
-static void run_nbw95(int dummy)
-{
- double t;
- t = create_procs(run_netbench);
- /* to produce a netbench result we scale accoding to the
- netbench measured throughput for the run that produced the
- sniff that was used to produce client.txt. That run used 2
- clients and ran for 660 seconds to produce a result of
- 4MBit/sec. */
- printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
- 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
}
-/* run a test that simulates an approximate netbench wNT client load */
-static void run_nbwnt(int dummy)
-{
- double t;
- t = create_procs(run_netbench);
- printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
- 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
-}
-
-
-
/*
This test checks for two things:
@@ -403,57 +282,57 @@ static void run_nbwnt(int dummy)
must not use posix semantics)
2) support for lock timeouts
*/
-static void run_locktest1(int dummy)
+static void run_locktest1(void)
{
static struct cli_state cli1, cli2;
char *fname = "\\lockt1.lck";
int fnum1, fnum2, fnum3;
time_t t1, t2;
- if (!open_connection(&cli1) || !open_connection(&cli2)) {
+ if (open_connection(&cli1) != 0 || open_connection(&cli2) != 0) {
return;
}
cli_sockopt(&cli1, sockops);
cli_sockopt(&cli2, sockops);
- printf("starting locktest1\n");
+ DEBUG(0,("starting locktest1\n"));
cli_unlink(&cli1, 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));
+ DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli1)));
return;
}
fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
if (fnum2 == -1) {
- printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+ DEBUG(0,("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1)));
return;
}
fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
if (fnum3 == -1) {
- printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+ DEBUG(0,("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2)));
return;
}
- if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
- printf("lock1 failed (%s)\n", cli_errstr(&cli1));
+ if (!cli_lock(&cli1, fnum1, 0, 4, 0)) {
+ DEBUG(0,("lock1 failed (%s)\n", cli_errstr(&cli1)));
return;
}
- if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
- printf("lock2 succeeded! This is a locking bug\n");
+ if (cli_lock(&cli2, fnum3, 0, 4, 0)) {
+ DEBUG(0,("lock2 succeeded! This is a locking bug\n"));
return;
} else {
if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
}
- printf("Testing lock timeouts\n");
+ DEBUG(0,("Testing lock timeouts\n"));
t1 = time(NULL);
- if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) {
- printf("lock3 succeeded! This is a locking bug\n");
+ if (cli_lock(&cli2, fnum3, 0, 4, 10*1000)) {
+ DEBUG(0,("lock3 succeeded! This is a locking bug\n"));
return;
} else {
if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
@@ -461,33 +340,33 @@ static void run_locktest1(int dummy)
t2 = time(NULL);
if (t2 - t1 < 5) {
- printf("error: This server appears not to support timed lock requests\n");
+ DEBUG(0,("error: This server appears not to support timed lock requests\n"));
}
if (!cli_close(&cli1, fnum2)) {
- printf("close1 failed (%s)\n", cli_errstr(&cli1));
+ DEBUG(0,("close1 failed (%s)\n", cli_errstr(&cli1)));
return;
}
- if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
- printf("lock4 succeeded! This is a locking bug\n");
+ if (cli_lock(&cli2, fnum3, 0, 4, 0)) {
+ DEBUG(0,("lock4 succeeded! This is a locking bug\n"));
return;
} else {
if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return;
}
if (!cli_close(&cli1, fnum1)) {
- printf("close2 failed (%s)\n", cli_errstr(&cli1));
+ DEBUG(0,("close2 failed (%s)\n", cli_errstr(&cli1)));
return;
}
if (!cli_close(&cli2, fnum3)) {
- printf("close3 failed (%s)\n", cli_errstr(&cli2));
+ DEBUG(0,("close3 failed (%s)\n", cli_errstr(&cli2)));
return;
}
if (!cli_unlink(&cli1, fname)) {
- printf("unlink failed (%s)\n", cli_errstr(&cli1));
+ DEBUG(0,("unlink failed (%s)\n", cli_errstr(&cli1)));
return;
}
@@ -495,7 +374,7 @@ static void run_locktest1(int dummy)
close_connection(&cli1);
close_connection(&cli2);
- printf("Passed locktest1\n");
+ DEBUG(0,("Passed locktest1\n"));
}
@@ -510,19 +389,19 @@ static void run_locktest1(int dummy)
3) the server denies unlock requests by an incorrect client PID
*/
-static void run_locktest2(int dummy)
+static void run_locktest2(void)
{
static struct cli_state cli;
char *fname = "\\lockt2.lck";
int fnum1, fnum2, fnum3;
- if (!open_connection(&cli)) {
+ if (open_connection(&cli) != 0) {
return;
}
cli_sockopt(&cli, sockops);
- printf("starting locktest2\n");
+ DEBUG(0,("starting locktest2\n"));
cli_unlink(&cli, fname);
@@ -530,13 +409,13 @@ static void run_locktest2(int dummy)
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));
+ DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli)));
return;
}
fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
if (fnum2 == -1) {
- printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
+ DEBUG(0,("open2 of %s failed (%s)\n", fname, cli_errstr(&cli)));
return;
}
@@ -544,31 +423,31 @@ static void run_locktest2(int dummy)
fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
if (fnum3 == -1) {
- printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
+ DEBUG(0,("open3 of %s failed (%s)\n", fname, cli_errstr(&cli)));
return;
}
cli_setpid(&cli, 1);
- if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
- printf("lock1 failed (%s)\n", cli_errstr(&cli));
+ if (!cli_lock(&cli, fnum1, 0, 4, 0)) {
+ DEBUG(0,("lock1 failed (%s)\n", cli_errstr(&cli)));
return;
}
- if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
- printf("lock2 succeeded! This is a locking bug\n");
+ if (cli_lock(&cli, fnum2, 0, 4, 0)) {
+ DEBUG(0,("lock2 succeeded! This is a locking bug\n"));
} else {
if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
}
cli_setpid(&cli, 2);
- if (cli_unlock(&cli, fnum1, 0, 8)) {
- printf("unlock1 succeeded! This is a locking bug\n");
+ if (cli_unlock(&cli, fnum1, 0, 4, 0)) {
+ DEBUG(0,("unlock1 succeeded! This is a locking bug\n"));
}
- if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
- printf("lock3 succeeded! This is a locking bug\n");
+ if (cli_lock(&cli, fnum3, 0, 4, 0)) {
+ DEBUG(0,("lock3 succeeded! This is a locking bug\n"));
} else {
if (!check_error(&cli, ERRDOS, ERRlock, 0)) return;
}
@@ -576,23 +455,23 @@ static void run_locktest2(int dummy)
cli_setpid(&cli, 1);
if (!cli_close(&cli, fnum1)) {
- printf("close1 failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("close1 failed (%s)\n", cli_errstr(&cli)));
return;
}
if (!cli_close(&cli, fnum2)) {
- printf("close2 failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("close2 failed (%s)\n", cli_errstr(&cli)));
return;
}
if (!cli_close(&cli, fnum3)) {
- printf("close3 failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("close3 failed (%s)\n", cli_errstr(&cli)));
return;
}
close_connection(&cli);
- printf("locktest2 finished\n");
+ DEBUG(0,("locktest2 finished\n"));
}
@@ -601,7 +480,7 @@ static void run_locktest2(int dummy)
1) the server supports the full offset range in lock requests
*/
-static void run_locktest3(int dummy)
+static void run_locktest3(int numops)
{
static struct cli_state cli1, cli2;
char *fname = "\\lockt3.lck";
@@ -610,40 +489,40 @@ static void run_locktest3(int dummy)
#define NEXT_OFFSET offset += (~(uint32)0) / numops
- if (!open_connection(&cli1) || !open_connection(&cli2)) {
+ if (open_connection(&cli1) != 0 || open_connection(&cli2) != 0) {
return;
}
cli_sockopt(&cli1, sockops);
cli_sockopt(&cli2, sockops);
- printf("starting locktest3\n");
+ DEBUG(0,("starting locktest3\n"));
cli_unlink(&cli1, 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));
+ DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli1)));
return;
}
fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
if (fnum2 == -1) {
- printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+ DEBUG(0,("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2)));
return;
}
for (offset=i=0;i<numops;i++) {
NEXT_OFFSET;
- if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
- printf("lock1 %d failed (%s)\n",
+ if (!cli_lock(&cli1, fnum1, offset-1, 1, 0)) {
+ DEBUG(0,("lock1 %d failed (%s)\n",
i,
- cli_errstr(&cli1));
+ cli_errstr(&cli1)));
return;
}
- if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
- printf("lock2 %d failed (%s)\n",
+ if (!cli_lock(&cli2, fnum2, offset-2, 1, 0)) {
+ DEBUG(0,("lock2 %d failed (%s)\n",
i,
- cli_errstr(&cli1));
+ cli_errstr(&cli1)));
return;
}
}
@@ -651,23 +530,23 @@ static void run_locktest3(int dummy)
for (offset=i=0;i<numops;i++) {
NEXT_OFFSET;
- if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
- printf("error: lock1 %d succeeded!\n", i);
+ if (cli_lock(&cli1, fnum1, offset-2, 1, 0)) {
+ DEBUG(0,("error: lock1 %d succeeded!\n", i));
return;
}
- if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
- printf("error: lock2 %d succeeded!\n", i);
+ if (cli_lock(&cli2, fnum2, offset-1, 1, 0)) {
+ DEBUG(0,("error: lock2 %d succeeded!\n", i));
return;
}
- if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
- printf("error: lock3 %d succeeded!\n", i);
+ if (cli_lock(&cli1, fnum1, offset-1, 1, 0)) {
+ DEBUG(0,("error: lock3 %d succeeded!\n", i));
return;
}
- if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
- printf("error: lock4 %d succeeded!\n", i);
+ if (cli_lock(&cli2, fnum2, offset-2, 1, 0)) {
+ DEBUG(0,("error: lock4 %d succeeded!\n", i));
return;
}
}
@@ -675,404 +554,70 @@ static void run_locktest3(int dummy)
for (offset=i=0;i<numops;i++) {
NEXT_OFFSET;
- if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
- printf("unlock1 %d failed (%s)\n",
+ if (!cli_unlock(&cli1, fnum1, offset-1, 1, 0)) {
+ DEBUG(0,("unlock1 %d failed (%s)\n",
i,
- cli_errstr(&cli1));
+ cli_errstr(&cli1)));
return;
}
- if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
- printf("unlock2 %d failed (%s)\n",
+ if (!cli_unlock(&cli2, fnum2, offset-2, 1, 0)) {
+ DEBUG(0,("unlock2 %d failed (%s)\n",
i,
- cli_errstr(&cli1));
+ cli_errstr(&cli1)));
return;
}
}
if (!cli_close(&cli1, fnum1)) {
- printf("close1 failed (%s)\n", cli_errstr(&cli1));
+ DEBUG(0,("close1 failed (%s)\n", cli_errstr(&cli1)));
}
if (!cli_close(&cli2, fnum2)) {
- printf("close2 failed (%s)\n", cli_errstr(&cli2));
+ DEBUG(0,("close2 failed (%s)\n", cli_errstr(&cli2)));
}
if (!cli_unlink(&cli1, fname)) {
- printf("unlink failed (%s)\n", cli_errstr(&cli1));
+ DEBUG(0,("unlink failed (%s)\n", cli_errstr(&cli1)));
return;
}
close_connection(&cli1);
close_connection(&cli2);
- printf("finished locktest3\n");
-}
-
-#define EXPECTED(ret, v) if ((ret) != (v)) printf("** ")
-
-/*
- looks at overlapping locks
-*/
-static void run_locktest4(int dummy)
-{
- static struct cli_state cli1, cli2;
- char *fname = "\\lockt4.lck";
- int fnum1, fnum2;
- BOOL ret;
- char buf[1000];
-
- if (!open_connection(&cli1) || !open_connection(&cli2)) {
- return;
- }
-
- cli_sockopt(&cli1, sockops);
- cli_sockopt(&cli2, sockops);
-
- printf("starting locktest4\n");
-
- cli_unlink(&cli1, fname);
-
- fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
- fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
-
- memset(buf, 0, sizeof(buf));
-
- if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
- printf("Failed to create file\n");
- goto fail;
- }
-
- ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
- cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
- EXPECTED(ret, False);
- printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
-
- ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
- cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
- EXPECTED(ret, True);
- printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
-
- ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
- cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
- EXPECTED(ret, False);
- printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
-
- ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
- cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
- EXPECTED(ret, True);
- printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
-
- ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
- (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
- EXPECTED(ret, False);
- printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
-
- ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
- (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
- EXPECTED(ret, True);
- printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
-
- ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
- cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
- EXPECTED(ret, True);
- printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
-
- ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
- cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
- EXPECTED(ret, False);
- printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
-
- ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
- cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
- EXPECTED(ret, False);
- printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
-
- ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
- cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
- EXPECTED(ret, True);
- printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
-
- ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
- (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
- EXPECTED(ret, False);
- printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
-
- ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
- cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
- cli_unlock(&cli1, fnum1, 110, 6);
- EXPECTED(ret, False);
- printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
-
-
- ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
- (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
- EXPECTED(ret, False);
- printf("this server %s strict write locking\n", ret?"doesn't do":"does");
-
- ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
- (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
- EXPECTED(ret, False);
- printf("this server %s strict read locking\n", ret?"doesn't do":"does");
-
-
- ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
- cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
- cli_unlock(&cli1, fnum1, 140, 4) &&
- cli_unlock(&cli1, fnum1, 140, 4);
- EXPECTED(ret, True);
- printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
-
-
- ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
- cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
- cli_unlock(&cli1, fnum1, 150, 4) &&
- (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
- !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
- cli_unlock(&cli1, fnum1, 150, 4);
- EXPECTED(ret, True);
- printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
-
- ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
- cli_unlock(&cli1, fnum1, 160, 4) &&
- (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&
- (cli_read(&cli2, fnum2, buf, 160, 4) == 4);
- EXPECTED(ret, True);
- printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
-
- ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
- cli_unlock(&cli1, fnum1, 170, 4) &&
- (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&
- (cli_read(&cli2, fnum2, buf, 170, 4) == 4);
- EXPECTED(ret, True);
- printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
-
- ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
- cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
- cli_unlock(&cli1, fnum1, 190, 4) &&
- !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&
- (cli_read(&cli2, fnum2, buf, 190, 4) == 4);
- EXPECTED(ret, True);
- printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
-
- fail:
- cli_close(&cli1, fnum1);
- cli_close(&cli1, fnum2);
- cli_unlink(&cli1, fname);
- close_connection(&cli1);
- close_connection(&cli2);
-
- printf("finished locktest4\n");
+ DEBUG(0,("finished locktest3\n"));
}
/*
- this produces a matrix of deny mode behaviour
- */
-static void run_denytest1(int dummy)
-{
- static struct cli_state cli1, cli2;
- int fnum1, fnum2;
- int f, d1, d2, o1, o2, x=0;
- char *fnames[] = {"denytest1.exe", "denytest1.dat", NULL};
- struct {
- int v;
- char *name;
- } deny_modes[] = {
- {DENY_DOS, "DENY_DOS"},
- {DENY_ALL, "DENY_ALL"},
- {DENY_WRITE, "DENY_WRITE"},
- {DENY_READ, "DENY_READ"},
- {DENY_NONE, "DENY_NONE"},
- {DENY_FCB, "DENY_FCB"},
- {-1, NULL}};
- struct {
- int v;
- char *name;
- } open_modes[] = {
- {O_RDWR, "O_RDWR"},
- {O_RDONLY, "O_RDONLY"},
- {O_WRONLY, "O_WRONLY"},
- {-1, NULL}};
-
- if (!open_connection(&cli1) || !open_connection(&cli2)) {
- return;
- }
- cli_sockopt(&cli1, sockops);
- cli_sockopt(&cli2, sockops);
-
- printf("starting denytest1\n");
-
- for (f=0;fnames[f];f++) {
- cli_unlink(&cli1, fnames[f]);
-
- fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
- cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
- cli_close(&cli1, fnum1);
-
- for (d1=0;deny_modes[d1].name;d1++)
- for (o1=0;open_modes[o1].name;o1++)
- for (d2=0;deny_modes[d2].name;d2++)
- for (o2=0;open_modes[o2].name;o2++) {
- fnum1 = cli_open(&cli1, fnames[f],
- open_modes[o1].v,
- deny_modes[d1].v);
- fnum2 = cli_open(&cli2, fnames[f],
- open_modes[o2].v,
- deny_modes[d2].v);
-
- printf("%s %8s %10s %8s %10s ",
- fnames[f],
- open_modes[o1].name,
- deny_modes[d1].name,
- open_modes[o2].name,
- deny_modes[d2].name);
-
- if (fnum1 == -1) {
- printf("X");
- } else if (fnum2 == -1) {
- printf("-");
- } else {
- if (cli_read(&cli2, fnum2, (void *)&x, 0, 1) == 1) {
- printf("R");
- }
- if (cli_write(&cli2, fnum2, 0, (void *)&x, 0, 1) == 1) {
- printf("W");
- }
- }
-
- printf("\n");
- cli_close(&cli1, fnum1);
- cli_close(&cli2, fnum2);
- }
-
- cli_unlink(&cli1, fnames[f]);
- }
-
- close_connection(&cli1);
- close_connection(&cli2);
-
- printf("finshed denytest1\n");
-}
-
-
-/*
- this produces a matrix of deny mode behaviour for two opens on the
- same connection
- */
-static void run_denytest2(int dummy)
-{
- static struct cli_state cli1;
- int fnum1, fnum2;
- int f, d1, d2, o1, o2, x=0;
- char *fnames[] = {"denytest2.exe", "denytest2.dat", NULL};
- struct {
- int v;
- char *name;
- } deny_modes[] = {
- {DENY_DOS, "DENY_DOS"},
- {DENY_ALL, "DENY_ALL"},
- {DENY_WRITE, "DENY_WRITE"},
- {DENY_READ, "DENY_READ"},
- {DENY_NONE, "DENY_NONE"},
- {DENY_FCB, "DENY_FCB"},
- {-1, NULL}};
- struct {
- int v;
- char *name;
- } open_modes[] = {
- {O_RDWR, "O_RDWR"},
- {O_RDONLY, "O_RDONLY"},
- {O_WRONLY, "O_WRONLY"},
- {-1, NULL}};
-
- if (!open_connection(&cli1)) {
- return;
- }
- cli_sockopt(&cli1, sockops);
-
- printf("starting denytest2\n");
-
- for (f=0;fnames[f];f++) {
- cli_unlink(&cli1, fnames[f]);
-
- fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
- cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
- cli_close(&cli1, fnum1);
-
- for (d1=0;deny_modes[d1].name;d1++)
- for (o1=0;open_modes[o1].name;o1++)
- for (d2=0;deny_modes[d2].name;d2++)
- for (o2=0;open_modes[o2].name;o2++) {
- fnum1 = cli_open(&cli1, fnames[f],
- open_modes[o1].v,
- deny_modes[d1].v);
- fnum2 = cli_open(&cli1, fnames[f],
- open_modes[o2].v,
- deny_modes[d2].v);
-
- printf("%s %8s %10s %8s %10s ",
- fnames[f],
- open_modes[o1].name,
- deny_modes[d1].name,
- open_modes[o2].name,
- deny_modes[d2].name);
-
- if (fnum1 == -1) {
- printf("X");
- } else if (fnum2 == -1) {
- printf("-");
- } else {
- if (cli_read(&cli1, fnum2, (void *)&x, 0, 1) == 1) {
- printf("R");
- }
- if (cli_write(&cli1, fnum2, 0, (void *)&x, 0, 1) == 1) {
- printf("W");
- }
- }
-
- printf("\n");
- cli_close(&cli1, fnum1);
- cli_close(&cli1, fnum2);
- }
-
- cli_unlink(&cli1, fnames[f]);
- }
-
- close_connection(&cli1);
-
- printf("finshed denytest2\n");
-}
-
-/*
test whether fnums and tids open on one VC are available on another (a major
security hole)
*/
-static void run_fdpasstest(int dummy)
+static void run_fdpasstest(void)
{
static struct cli_state cli1, cli2;
char *fname = "\\fdpass.tst";
int fnum1;
pstring buf;
- if (!open_connection(&cli1) || !open_connection(&cli2)) {
+ if (open_connection(&cli1) != 0 || open_connection(&cli2) != 0) {
return;
}
cli_sockopt(&cli1, sockops);
cli_sockopt(&cli2, sockops);
- printf("starting fdpasstest\n");
+ DEBUG(0,("starting fdpasstest\n"));
cli_unlink(&cli1, 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));
+ DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli1)));
return;
}
- if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
- printf("write failed (%s)\n", cli_errstr(&cli1));
+ if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13, 0) != 13) {
+ DEBUG(0,("write failed (%s)\n", cli_errstr(&cli1)));
return;
}
@@ -1081,9 +626,9 @@ static void run_fdpasstest(int dummy)
cli2.pid = cli1.pid;
- if (cli_read(&cli2, fnum1, buf, 0, 13) == 13) {
- printf("read succeeded! nasty security hole [%s]\n",
- buf);
+ if (cli_read(&cli2, fnum1, buf, 0, 13, True) == 13) {
+ DEBUG(0,("read succeeded! nasty security hole [%s]\n",
+ buf));
return;
}
@@ -1093,7 +638,7 @@ static void run_fdpasstest(int dummy)
close_connection(&cli1);
close_connection(&cli2);
- printf("finished fdpasstest\n");
+ DEBUG(0,("finished fdpasstest\n"));
}
@@ -1102,19 +647,19 @@ static void run_fdpasstest(int dummy)
1) the server does not allow an unlink on a file that is open
*/
-static void run_unlinktest(int dummy)
+static void run_unlinktest(void)
{
static struct cli_state cli;
char *fname = "\\unlink.tst";
int fnum;
- if (!open_connection(&cli)) {
+ if (open_connection(&cli) != 0) {
return;
}
cli_sockopt(&cli, sockops);
- printf("starting unlink test\n");
+ DEBUG(0,("starting unlink test\n"));
cli_unlink(&cli, fname);
@@ -1122,12 +667,12 @@ static void run_unlinktest(int dummy)
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));
+ DEBUG(0,("open of %s failed (%s)\n", fname, cli_errstr(&cli)));
return;
}
if (cli_unlink(&cli, fname)) {
- printf("error: server allowed unlink on an open file\n");
+ DEBUG(0,("error: server allowed unlink on an open file\n"));
}
cli_close(&cli, fnum);
@@ -1135,56 +680,59 @@ static void run_unlinktest(int dummy)
close_connection(&cli);
- printf("unlink test finished\n");
+ DEBUG(0,("unlink test finished\n"));
}
/*
test how many open files this server supports on the one socket
*/
-static void run_maxfidtest(int dummy)
+static void run_maxfidtest(int n)
{
static struct cli_state cli;
char *template = "\\maxfid.%d.%d";
fstring fname;
int fnum;
int retries=4;
- int n = numops;
- cli = current_cli;
+ srandom(getpid());
+
+ while (open_connection(&cli) != 0 && retries--) msleep(random() % 2000);
if (retries <= 0) {
- printf("failed to connect\n");
+ DEBUG(0,("failed to connect\n"));
return;
}
cli_sockopt(&cli, sockops);
+ DEBUG(0,("starting maxfid test\n"));
+
fnum = 0;
while (1) {
- slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
+ slprintf(fname,sizeof(fname)-1,template, fnum,getpid());
if (cli_open(&cli, fname,
O_RDWR|O_CREAT|O_TRUNC, DENY_NONE) ==
-1) {
- printf("open of %s failed (%s)\n",
- fname, cli_errstr(&cli));
- printf("maximum fnum is %d\n", fnum);
+ DEBUG(0,("open of %s failed (%s)\n",
+ fname, cli_errstr(&cli)));
+ DEBUG(0,("maximum fnum is %d\n", fnum));
break;
}
fnum++;
}
- printf("cleaning up\n");
+ DEBUG(0,("cleaning up\n"));
while (fnum > n) {
fnum--;
- slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
+ slprintf(fname,sizeof(fname)-1,template, fnum,getpid());
if (cli_unlink(&cli, fname)) {
- printf("unlink of %s failed (%s)\n",
- fname, cli_errstr(&cli));
+ DEBUG(0,("unlink of %s failed (%s)\n",
+ fname, cli_errstr(&cli)));
}
}
- printf("maxfid test finished\n");
+ DEBUG(0,("maxfid test finished\n"));
close_connection(&cli);
}
@@ -1192,45 +740,116 @@ static void run_maxfidtest(int dummy)
static void rand_buf(char *buf, int len)
{
while (len--) {
- *buf = (char)sys_random();
+ *buf = sys_random();
buf++;
}
}
+#define TORT_BUFFER_SIZE 1024
+
/* send random IPC commands */
-static void run_randomipc(int dummy)
+static void run_randomipc(int numops)
{
char *rparam = NULL;
char *rdata = NULL;
int rdrcnt,rprcnt;
- pstring param;
+ char param[TORT_BUFFER_SIZE];
int api, param_len, i;
+ int reconnect_count = 500;
static struct cli_state cli;
- printf("starting random ipc test\n");
+ DEBUG(0,("starting random ipc test\n"));
+
+ while (reconnect_count > 0 && open_connection(&cli) != 0)
+ {
+ DEBUG(0,("connection failed: retrying %d\n", reconnect_count));
+ msleep(sys_random() % 5000);
+ reconnect_count--;
+ }
- if (!open_connection(&cli)) {
+ if (reconnect_count == 0)
+ {
return;
}
- for (i=0;i<50000;i++) {
+ for (i=0;i<numops * 100;i++)
+ {
api = sys_random() % 500;
- param_len = (sys_random() % 64);
+ if ((sys_random() % 10) == 0)
+ {
+ param_len = (sys_random() % TORT_BUFFER_SIZE);
+ }
+ else
+ {
+ param_len = (sys_random() % 64);
+ }
rand_buf(param, param_len);
SSVAL(param,0,api);
- cli_api(&cli,
+ cli_api(&cli,
param, param_len, 8,
NULL, 0, BUFFER_SIZE,
- &rparam, &rprcnt,
+ &rparam, &rprcnt,
&rdata, &rdrcnt);
}
close_connection(&cli);
- printf("finished random ipc test\n");
+ DEBUG(0,("finished random ipc test\n"));
+}
+
+/* send random IPC commands */
+static void run_randomipc_nowait(int numops)
+{
+ char param[TORT_BUFFER_SIZE];
+ int api, param_len, i;
+ int reconnect_count = 500;
+ static struct cli_state cli;
+
+ DEBUG(0,("start random ipc test no waiting for SMBtrans response\n"));
+
+ while (reconnect_count > 0 && open_connection(&cli) != 0)
+ {
+ DEBUG(0,("connection failed: retrying %d\n", reconnect_count));
+ msleep(sys_random() % 5000);
+ reconnect_count--;
+ }
+
+ if (reconnect_count == 0)
+ {
+ return;
+ }
+
+ for (i=0;i<numops * 100;i++)
+ {
+ api = sys_random() % 500;
+ if ((sys_random() % 10) == 0)
+ {
+ param_len = (sys_random() % TORT_BUFFER_SIZE);
+ }
+ else
+ {
+ param_len = (sys_random() % 64);
+ }
+
+ rand_buf(param, param_len);
+
+ SSVAL(param,0,api);
+
+ cli_send_trans(&cli,SMBtrans,
+ PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */
+ 0,0, /* fid, flags */
+ NULL,0,0, /* Setup, length, max */
+
+ param, param_len, 8,
+ NULL, 0, BUFFER_SIZE);
+ }
+
+ close_connection(&cli);
+
+ DEBUG(0,("finished random ipc test\n"));
}
@@ -1238,7 +857,7 @@ static void run_randomipc(int dummy)
static void browse_callback(const char *sname, uint32 stype,
const char *comment)
{
- printf("\t%20.20s %08x %s\n", sname, stype, comment);
+ DEBUG(0,("\t%20.20s %08x %s\n", sname, stype, comment));
}
@@ -1247,45 +866,45 @@ static void browse_callback(const char *sname, uint32 stype,
This test checks the browse list code
*/
-static void run_browsetest(int dummy)
+static void run_browsetest(void)
{
static struct cli_state cli;
- printf("starting browse test\n");
+ DEBUG(0,("starting browse test\n"));
- if (!open_connection(&cli)) {
+ if (open_connection(&cli) != 0) {
return;
}
- printf("domain list:\n");
- cli_NetServerEnum(&cli, cli.server_domain,
+ DEBUG(0,("domain list:\n"));
+ cli_NetServerEnum(&cli, workgroup,
SV_TYPE_DOMAIN_ENUM,
browse_callback);
- printf("machine list:\n");
- cli_NetServerEnum(&cli, cli.server_domain,
+ DEBUG(0,("machine list:\n"));
+ cli_NetServerEnum(&cli, workgroup,
SV_TYPE_ALL,
browse_callback);
close_connection(&cli);
- printf("browse test finished\n");
+ DEBUG(0,("browse test finished\n"));
}
/*
This checks how the getatr calls works
*/
-static void run_attrtest(int dummy)
+static void run_attrtest(void)
{
static struct cli_state cli;
int fnum;
time_t t, t2;
char *fname = "\\attrib.tst";
- printf("starting attrib test\n");
+ DEBUG(0,("starting attrib test\n"));
- if (!open_connection(&cli)) {
+ if (open_connection(&cli) != 0) {
return;
}
@@ -1294,43 +913,43 @@ static void run_attrtest(int dummy)
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
cli_close(&cli, fnum);
if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
- printf("getatr failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("getatr failed (%s)\n", cli_errstr(&cli)));
}
if (abs(t - time(NULL)) > 2) {
- printf("ERROR: SMBgetatr bug. time is %s",
- ctime(&t));
+ DEBUG(0,("ERROR: SMBgetatr bug. time is %s",
+ ctime(&t)));
t = time(NULL);
}
t2 = t-60*60*24; /* 1 day ago */
if (!cli_setatr(&cli, fname, 0, t2)) {
- printf("setatr failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("setatr failed (%s)\n", cli_errstr(&cli)));
}
if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
- printf("getatr failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("getatr failed (%s)\n", cli_errstr(&cli)));
}
if (t != t2) {
- printf("ERROR: getatr/setatr bug. times are\n%s",
- ctime(&t));
- printf("%s", ctime(&t2));
+ DEBUG(0,("ERROR: getatr/setatr bug. times are\n%s",
+ ctime(&t)));
+ DEBUG(0,("%s", ctime(&t2)));
}
cli_unlink(&cli, fname);
close_connection(&cli);
- printf("attrib test finished\n");
+ DEBUG(0,("attrib test finished\n"));
}
/*
This checks a couple of trans2 calls
*/
-static void run_trans2test(int dummy)
+static void run_trans2test(void)
{
static struct cli_state cli;
int fnum;
@@ -1340,9 +959,9 @@ static void run_trans2test(int dummy)
char *dname = "\\trans2";
char *fname2 = "\\trans2\\trans2.tst";
- printf("starting trans2 test\n");
+ DEBUG(0,("starting trans2 test\n"));
- if (!open_connection(&cli)) {
+ if (open_connection(&cli) != 0) {
return;
}
@@ -1351,7 +970,7 @@ static void run_trans2test(int dummy)
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
NULL, NULL)) {
- printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli)));
}
cli_close(&cli, fnum);
@@ -1363,20 +982,20 @@ static void run_trans2test(int dummy)
cli_close(&cli, fnum);
if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
- printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli)));
} else {
if (c_time != m_time) {
- printf("create time=%s", ctime(&c_time));
- printf("modify time=%s", ctime(&m_time));
- printf("This system appears to have sticky create times\n");
+ DEBUG(0,("create time=%s", ctime(&c_time)));
+ DEBUG(0,("modify time=%s", ctime(&m_time)));
+ DEBUG(0,("This system appears to have sticky create times\n"));
}
if (a_time % (60*60) == 0) {
- printf("access time=%s", ctime(&a_time));
- printf("This system appears to set a midnight access time\n");
+ DEBUG(0,("access time=%s", ctime(&a_time)));
+ DEBUG(0,("This system appears to set a midnight access time\n"));
}
if (abs(m_time - time(NULL)) > 60*60*24*7) {
- printf("ERROR: totally incorrect times - maybe word reversed?\n");
+ DEBUG(0,("ERROR: totally incorrect times - maybe word reversed?\n"));
}
}
@@ -1387,11 +1006,11 @@ static void run_trans2test(int dummy)
cli_close(&cli, fnum);
if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
&w_time, &size, NULL, NULL)) {
- printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
} else {
if (w_time < 60*60*24*2) {
- printf("write time=%s", ctime(&w_time));
- printf("This system appears to set a initial 0 write time\n");
+ DEBUG(0,("write time=%s", ctime(&w_time)));
+ DEBUG(0,("This system appears to set a initial 0 write time\n"));
}
}
@@ -1401,24 +1020,24 @@ static void run_trans2test(int dummy)
/* check if the server updates the directory modification time
when creating a new file */
if (!cli_mkdir(&cli, dname)) {
- printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("ERROR: mkdir failed (%s)\n", cli_errstr(&cli)));
}
sleep(3);
if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
&w_time, &size, NULL, NULL)) {
- printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
}
fnum = cli_open(&cli, fname2,
O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
- cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
+ cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum), 0);
cli_close(&cli, fnum);
if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
&w_time, &size, NULL, NULL)) {
- printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+ DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)));
} else {
if (m_time2 == m_time)
- printf("This system does not update directory modification times\n");
+ DEBUG(0,("This system does not update directory modification times\n"));
}
cli_unlink(&cli, fname2);
cli_rmdir(&cli, dname);
@@ -1426,300 +1045,105 @@ static void run_trans2test(int dummy)
close_connection(&cli);
- printf("trans2 test finished\n");
-}
-
-
-/*
- this is a harness for some oplock tests
- */
-static void run_oplock(int dummy)
-{
- static struct cli_state cli1;
- char *fname = "\\lockt1.lck";
- int fnum1;
-
- printf("starting oplock test\n");
-
- if (!open_connection(&cli1)) {
- return;
- }
-
- cli_unlink(&cli1, fname);
-
- cli_sockopt(&cli1, sockops);
-
- cli1.use_oplocks = True;
-
- 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));
- return;
- }
-
- cli1.use_oplocks = False;
-
- cli_unlink(&cli1, fname);
- cli_unlink(&cli1, fname);
-
- if (!cli_close(&cli1, fnum1)) {
- printf("close2 failed (%s)\n", cli_errstr(&cli1));
- return;
- }
-
- if (!cli_unlink(&cli1, fname)) {
- printf("unlink failed (%s)\n", cli_errstr(&cli1));
- return;
- }
-
-
- close_connection(&cli1);
-
- printf("finished oplock test\n");
+ DEBUG(0,("trans2 test finished\n"));
}
-static void list_fn(file_info *finfo, const char *name)
-{
-
-}
-
-/*
- test directory listing speed
- */
-static void run_dirtest(int dummy)
+static void run_connection(int numops)
{
+ struct cli_state c;
+ int count = 0;
+ int failed[NUM_ERR_STATES];
int i;
- static struct cli_state cli;
- int fnum;
- double t1;
- printf("starting directory test\n");
+ DEBUG(0,("Connection test starts:\n"));
- if (!open_connection(&cli)) {
- return;
+ for (i = 0; i < NUM_ERR_STATES; i++)
+ {
+ failed[i] = 0;
}
- cli_sockopt(&cli, sockops);
-
- srandom(0);
- for (i=0;i<numops;i++) {
- fstring fname;
- slprintf(fname, sizeof(fname), "%x", (int)random());
- fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
- if (fnum == -1) {
- fprintf(stderr,"Failed to open %s\n", fname);
- return;
+ for (i = 0; i < numops; i++)
+ {
+ int err;
+ DEBUG(0,("Connection test %d %d\n", i, numops));
+ if ((err = open_connection(&c)))
+ {
+ failed[err]++;
}
- cli_close(&cli, fnum);
+ count++;
}
- t1 = end_timer();
-
- printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn));
- printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn));
- printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn));
+ {
+ int failtotal = 0;
- printf("dirtest core %g seconds\n", end_timer() - t1);
-
- srandom(0);
- for (i=0;i<numops;i++) {
- fstring fname;
- slprintf(fname, sizeof(fname), "%x", (int)random());
- cli_unlink(&cli, fname);
+ for (i = 0, failtotal = 0; i < NUM_ERR_STATES; i++)
+ {
+ failtotal += failed[i];
+ }
+ DEBUG(0,("Connection test results: count %d success %d\n", count, count-failtotal));
+ }
+ for (i = 0; i < NUM_ERR_STATES; i++)
+ {
+ DEBUG(0,("%s: failed: %d\n", smb_messages[i], failed[i]));
}
-
- close_connection(&cli);
-
- printf("finished dirtest\n");
}
-
-
-static double create_procs(void (*fn)(int))
+static void create_procs(int nprocs, int numops, void (*fn)(int ))
{
int i, status;
- volatile int *child_status;
- int synccount;
- int tries = 8;
-
- start_timer();
-
- synccount = 0;
- child_status = (volatile int *)shm_setup(sizeof(int)*nprocs);
- if (!child_status) {
- printf("Failed to setup shared memory\n");
- return end_timer();
- }
-
- memset((char *)child_status, 0, sizeof(int)*nprocs);
-
- for (i=0;i<nprocs;i++) {
- if (fork() == 0) {
- pid_t mypid = getpid();
- sys_srandom(((int)mypid) ^ ((int)time(NULL)));
-
- slprintf(myname,sizeof(myname),"CLIENT%d", i);
-
- while (1) {
- memset(&current_cli, 0, sizeof(current_cli));
- if (open_connection(&current_cli)) break;
- if (tries-- == 0) {
- printf("pid %d failed to start\n", (int)getpid());
- _exit(1);
- }
- msleep(10);
+ for (i=0;i<nprocs;i++)
+ {
+ if (fork() == 0)
+ {
+ int mypid = getpid();
+ sys_srandom(mypid ^ time(NULL));
+
+ if (!dbg_interactive())
+ {
+ slprintf(debugf, sizeof(debugf), "./log.torture.%d", mypid);
+ reopen_logs();
}
- child_status[i] = getpid();
-
- while (child_status[i]) msleep(2);
-
- fn(i);
+ fn(numops);
+ dbgflush();
_exit(0);
}
}
- do {
- synccount = 0;
- for (i=0;i<nprocs;i++) {
- if (child_status[i]) synccount++;
- }
- if (synccount == nprocs) break;
- msleep(10);
- } while (end_timer() < 30);
-
- if (synccount != nprocs) {
- printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
- return end_timer();
- }
-
- /* start the client load */
- start_timer();
-
- for (i=0;i<nprocs;i++) {
- child_status[i] = 0;
- }
-
- printf("%d clients started\n", nprocs);
-
- for (i=0;i<nprocs;i++) {
+ for (i=0;i<nprocs;i++)
+ {
waitpid(0, &status, 0);
- printf("*");
}
- printf("\n");
- return end_timer();
}
-#define FLAG_MULTIPROC 1
-
-static struct {
- char *name;
- void (*fn)(int);
- unsigned flags;
-} torture_ops[] = {
- {"FDPASS", run_fdpasstest, 0},
- {"LOCK1", run_locktest1, 0},
- {"LOCK2", run_locktest2, 0},
- {"LOCK3", run_locktest3, 0},
- {"LOCK4", run_locktest4, 0},
- {"UNLINK", run_unlinktest, 0},
- {"BROWSE", run_browsetest, 0},
- {"ATTR", run_attrtest, 0},
- {"TRANS2", run_trans2test, 0},
- {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
- {"TORTURE",run_torture, FLAG_MULTIPROC},
- {"RANDOMIPC", run_randomipc, 0},
- {"NBW95", run_nbw95, 0},
- {"NBWNT", run_nbwnt, 0},
- {"OPLOCK", run_oplock, 0},
- {"DIR", run_dirtest, 0},
- {"DENY1", run_denytest1, 0},
- {"DENY2", run_denytest2, 0},
- {NULL, NULL, 0}};
-
-
-/****************************************************************************
-run a specified test or "ALL"
-****************************************************************************/
-static void run_test(char *name)
-{
- int i;
- if (strequal(name,"ALL")) {
- for (i=0;torture_ops[i].name;i++) {
- run_test(torture_ops[i].name);
- }
- }
-
- for (i=0;torture_ops[i].name;i++) {
- if (strequal(name, torture_ops[i].name)) {
- start_timer();
- printf("Running %s\n", name);
- if (torture_ops[i].flags & FLAG_MULTIPROC) {
- create_procs(torture_ops[i].fn);
- } else {
- torture_ops[i].fn(0);
- }
- printf("%s took %g secs\n\n", name, end_timer());
- }
- }
-}
-
-
-static void usage(void)
-{
- int i;
-
- printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
-
- printf("\t-U user%%pass\n");
- printf("\t-N numprocs\n");
- printf("\t-n my_netbios_name\n");
- printf("\t-W workgroup\n");
- printf("\t-o num_operations\n");
- printf("\t-O socket_options\n");
- printf("\t-m maximum protocol\n");
- printf("\n\n");
-
- printf("tests are:");
- for (i=0;torture_ops[i].name;i++) {
- printf(" %s", torture_ops[i].name);
- }
- printf("\n");
-
- printf("default test is ALL\n");
-
- exit(1);
-}
-
-
-
+#define DEBUG_INTERACTIVE True
/****************************************************************************
main program
****************************************************************************/
int main(int argc,char *argv[])
{
- int opt, i;
+ int nprocs=1, numops=100;
+ int opt;
char *p;
int gotpass = 0;
extern char *optarg;
extern int optind;
- extern FILE *dbf;
- static pstring servicesf = CONFIGFILE;
+ extern BOOL append_log;
+ extern BOOL timestamp_log;
- dbf = stdout;
-
- setbuffer(stdout, NULL, 0);
+ DEBUGLEVEL = 0;
+ pstrcpy(debugf,"./log.torture");
+ setup_logging(argv[0], DEBUG_INTERACTIVE);
+ append_log = True;
+ timestamp_log = False;
charset_initialise();
- lp_load(servicesf,True,False,False);
- load_interfaces();
-
if (argc < 2) {
usage();
}
@@ -1740,7 +1164,7 @@ static void usage(void)
*p = 0;
fstrcpy(share, p+1);
- get_myname(myname);
+ get_myname(myname,NULL);
if (*username == 0 && getenv("LOGNAME")) {
pstrcpy(username,getenv("LOGNAME"));
@@ -1750,8 +1174,6 @@ static void usage(void)
argv++;
- fstrcpy(workgroup, lp_workgroup());
-
while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:")) != EOF) {
switch (opt) {
case 'W':
@@ -1796,16 +1218,35 @@ static void usage(void)
}
}
- printf("host=%s share=%s user=%s myname=%s\n",
- host, share, username, myname);
+ printf("host=%s share=%s user=%s myname=%s procs=%d ops=%d\n",
+ host, share, username, myname, nprocs, numops);
- if (argc == 1) {
- run_test("ALL");
- } else {
- for (i=1;i<argc;i++) {
- run_test(argv[i]);
- }
- }
+ create_procs(nprocs, numops, run_randomipc);
+/*
+ create_procs(nprocs, numops, run_randomipc_nowait);
+
+ create_procs(nprocs, numops, run_connection);
+
+ run_fdpasstest();
+ run_locktest1();
+ run_locktest2();
+ run_locktest3(numops);
+ run_unlinktest();
+ run_browsetest();
+ run_attrtest();
+ run_trans2test();
+
+ create_procs(nprocs, numops, run_maxfidtest);
+
+
+
+ start_timer();
+ create_procs(nprocs, numops, run_torture);
+ printf("rw_torture: %g secs\n", end_timer());
+*/
+ dbgflush();
return(0);
}
+
+
diff --git a/source/web/cgi.c b/source/web/cgi.c
index 62a5e71e051..48ffbfc62bc 100644
--- a/source/web/cgi.c
+++ b/source/web/cgi.c
@@ -333,7 +333,7 @@ handle a http authentication line
static BOOL cgi_handle_authorization(char *line)
{
char *p, *user, *user_pass;
- struct passwd *pass = NULL;
+ const struct passwd *pass = NULL;
BOOL ret = False;
if (strncasecmp(line,"Basic ", 6)) {
@@ -558,7 +558,7 @@ void cgi_setup(char *rootdir, int auth_required)
*p = 0;
}
- string_sub(url, "/swat/", "", 0);
+ string_sub(url, "/swat/", "");
if (url[0] != '/' && strstr(url,"..")==0 && file_exist(url, NULL)) {
cgi_download(url);
diff --git a/source/web/diagnose.c b/source/web/diagnose.c
index f22fe0d9b25..a5754f61f9b 100644
--- a/source/web/diagnose.c
+++ b/source/web/diagnose.c
@@ -32,10 +32,10 @@ BOOL nmbd_running(void)
struct in_addr *ip_list;
if ((fd = open_socket_in(SOCK_DGRAM, 0, 3,
- interpret_addr("127.0.0.1"), True)) != -1) {
+ interpret_addr("127.0.0.1"),True)) != -1) {
if ((ip_list = name_query(fd, "__SAMBA__", 0,
True, True, loopback_ip,
- &count)) != NULL) {
+ &count,0)) != NULL) {
free(ip_list);
close(fd);
return True;
diff --git a/source/web/startstop.c b/source/web/startstop.c
index 9eeac96cc0c..6a15e7a46f8 100644
--- a/source/web/startstop.c
+++ b/source/web/startstop.c
@@ -37,7 +37,7 @@ void start_smbd(void)
return;
}
- slprintf(binfile, sizeof(pstring) - 1, "%s/smbd", SBINDIR);
+ slprintf(binfile, sizeof(pstring) - 1, "%s/smbd", BINDIR);
become_daemon();
@@ -58,7 +58,7 @@ void start_nmbd(void)
return;
}
- slprintf(binfile, sizeof(pstring) - 1, "%s/nmbd", SBINDIR);
+ slprintf(binfile, sizeof(pstring) - 1, "%s/nmbd", BINDIR);
become_daemon();
diff --git a/source/web/statuspage.c b/source/web/statuspage.c
index 5c800797c04..a59a5354f11 100644
--- a/source/web/statuspage.c
+++ b/source/web/statuspage.c
@@ -134,7 +134,8 @@ void status_page(void)
TDB_CONTEXT *tdb;
if (cgi_variable("smbd_restart")) {
- stop_smbd();
+ if (smbd_running())
+ stop_smbd();
start_smbd();
}
@@ -147,7 +148,8 @@ void status_page(void)
}
if (cgi_variable("nmbd_restart")) {
- stop_nmbd();
+ if (nmbd_running())
+ stop_nmbd();
start_nmbd();
}
if (cgi_variable("nmbd_start")) {
diff --git a/source/web/swat.c b/source/web/swat.c
index 3c9858a3d38..b2da9301b3d 100644
--- a/source/web/swat.c
+++ b/source/web/swat.c
@@ -31,8 +31,6 @@
static pstring servicesf = CONFIGFILE;
static BOOL demo_mode = False;
static BOOL have_write_access = False;
-static BOOL have_read_access = False;
-static int iNumNonAutoPrintServices = 0;
/*
* Password Management Globals
@@ -44,14 +42,10 @@ static int iNumNonAutoPrintServices = 0;
#define CHG_S_PASSWD_FLAG "chg_s_passwd_flag"
#define CHG_R_PASSWD_FLAG "chg_r_passwd_flag"
#define ADD_USER_FLAG "add_user_flag"
-#define DELETE_USER_FLAG "delete_user_flag"
#define DISABLE_USER_FLAG "disable_user_flag"
#define ENABLE_USER_FLAG "enable_user_flag"
#define RHOST "remote_host"
-/* we need these because we link to locking*.o */
- void become_root(BOOL save_dir) {}
- void unbecome_root(BOOL restore_dir) {}
/****************************************************************************
****************************************************************************/
@@ -218,10 +212,9 @@ static void show_parameter(int snum, struct parm_struct *parm)
break;
case P_OCTAL:
- printf("<input type=text size=8 name=\"parm_%s\" value=%s>", make_parm_name(parm->label), octal_string(*(int *)ptr));
- printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'%s\'\">",
- make_parm_name(parm->label),
- octal_string((int)(parm->def.ivalue)));
+ printf("<input type=text size=8 name=\"parm_%s\" value=0%o>", make_parm_name(parm->label), *(int *)ptr);
+ printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.value=\'0%o\'\">",
+ make_parm_name(parm->label),(int)(parm->def.ivalue));
break;
case P_ENUM:
@@ -232,7 +225,8 @@ static void show_parameter(int snum, struct parm_struct *parm)
printf("<input type=button value=\"Set Default\" onClick=\"swatform.parm_%s.selectedIndex=\'%d\'\">",
make_parm_name(parm->label),enum_index((int)(parm->def.ivalue),parm->enum_list));
break;
- case P_SEP:
+
+ default:
break;
}
printf("</td></tr>\n");
@@ -256,18 +250,10 @@ static void show_parameters(int snum, int allparameters, int advanced, int print
continue;
}
if (parm->flags & FLAG_HIDE) continue;
- if (snum >= 0) {
- if (printers & !(parm->flags & FLAG_PRINT)) continue;
- if (!printers & !(parm->flags & FLAG_SHARE)) continue;
- }
if (!advanced) {
- if (!(parm->flags & FLAG_BASIC)) {
+ if (!printers && !(parm->flags & FLAG_BASIC)) {
void *ptr = parm->ptr;
- if (parm->class == P_LOCAL && snum >= 0) {
- ptr = lp_local_ptr(snum, ptr);
- }
-
switch (parm->type) {
case P_CHAR:
if (*(char *)ptr == (char)(parm->def.cvalue)) continue;
@@ -297,7 +283,8 @@ static void show_parameters(int snum, int allparameters, int advanced, int print
case P_ENUM:
if (*(int *)ptr == (int)(parm->def.ivalue)) continue;
break;
- case P_SEP:
+
+ default:
continue;
}
}
@@ -312,30 +299,21 @@ static void show_parameters(int snum, int allparameters, int advanced, int print
}
/****************************************************************************
- load the smb.conf file into loadparm.
-****************************************************************************/
-static BOOL load_config(BOOL save_def)
-{
- lp_resetnumservices();
- return lp_load(servicesf,False,save_def,False);
-}
-
-/****************************************************************************
write a config file
****************************************************************************/
static void write_config(FILE *f, BOOL show_defaults)
{
fprintf(f, "# Samba config file created using SWAT\n");
fprintf(f, "# from %s (%s)\n", cgi_remote_host(), cgi_remote_addr());
- fprintf(f, "# Date: %s\n\n", timestring(False));
+ fprintf(f, "# Date: %s\n\n", timestring());
- lp_dump(f, show_defaults, iNumNonAutoPrintServices);
+ lp_dump(f, show_defaults);
}
/****************************************************************************
save and reoad the smb.conf config file
****************************************************************************/
-static int save_reload(int snum)
+static int save_reload(void)
{
FILE *f;
@@ -346,18 +324,14 @@ static int save_reload(int snum)
}
write_config(f, False);
- if (snum)
- lp_dump_one(f, False, snum);
fclose(f);
lp_killunused(NULL);
- if (!load_config(False)) {
+ if (!lp_load(servicesf,False,False,False)) {
printf("Can't reload %s\n", servicesf);
return 0;
}
- iNumNonAutoPrintServices = lp_numservices();
- load_printers();
return 1;
}
@@ -405,6 +379,14 @@ static void commit_parameters(int snum)
}
/****************************************************************************
+ load the smb.conf file into loadparm.
+****************************************************************************/
+static BOOL load_config(void)
+{
+ return lp_load(servicesf,False,True,False);
+}
+
+/****************************************************************************
spit out the html for a link with an image
****************************************************************************/
static void image_link(char *name,char *hlink, char *src)
@@ -419,22 +401,13 @@ static void image_link(char *name,char *hlink, char *src)
****************************************************************************/
static void show_main_buttons(void)
{
- char *p;
-
- if ((p = cgi_user_name()) && strcmp(p, "root")) {
- printf("Logged in as <b>%s</b><p>\n", p);
- }
-
image_link("Home", "", "images/home.gif");
- if (have_write_access) {
- image_link("Globals", "globals", "images/globals.gif");
- image_link("Shares", "shares", "images/shares.gif");
- image_link("Printers", "printers", "images/printers.gif");
- }
- if (have_read_access) {
- image_link("Status", "status", "images/status.gif");
- image_link("View Config", "viewconfig","images/viewconfig.gif");
- }
+
+ image_link("Globals", "globals", "images/globals.gif");
+ image_link("Shares", "shares", "images/shares.gif");
+ image_link("Printers", "printers", "images/printers.gif");
+ image_link("Status", "status", "images/status.gif");
+ image_link("View Config", "viewconfig","images/viewconfig.gif");
image_link("Password Management", "passwd", "images/passwd.gif");
printf("<HR>\n");
@@ -488,7 +461,7 @@ static void globals_page(void)
if (cgi_variable("Commit")) {
commit_parameters(GLOBALS_SNUM);
- save_reload(0);
+ save_reload();
}
printf("<FORM name=\"swatform\" method=post>\n");
@@ -537,29 +510,26 @@ static void shares_page(void)
if (cgi_variable("Commit") && snum >= 0) {
commit_parameters(snum);
- save_reload(0);
+ save_reload();
}
if (cgi_variable("Delete") && snum >= 0) {
lp_remove_service(snum);
- save_reload(0);
+ save_reload();
share = NULL;
snum = -1;
}
if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
- load_config(False);
lp_copy_service(GLOBALS_SNUM, share);
- iNumNonAutoPrintServices = lp_numservices();
- save_reload(0);
+ save_reload();
snum = lp_servicenumber(share);
}
printf("<FORM name=\"swatform\" method=post>\n");
printf("<table>\n");
- printf("<tr>\n");
- printf("<td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
+ printf("<tr><td><input type=submit name=selectshare value=\"Choose Share\"></td>\n");
printf("<td><select name=share>\n");
if (snum < 0)
printf("<option value=\" \"> \n");
@@ -571,18 +541,10 @@ static void shares_page(void)
s, s);
}
}
- printf("</select></td>\n");
- if (have_write_access) {
- printf("<td><input type=submit name=\"Delete\" value=\"Delete Share\"></td>\n");
- }
- printf("</tr>\n");
- printf("</table>");
- printf("<table>");
- if (have_write_access) {
- printf("<tr>\n");
- printf("<td><input type=submit name=createshare value=\"Create Share\"></td>\n");
- printf("<td><input type=text size=30 name=newshare></td></tr>\n");
- }
+ printf("</select></td></tr><p>");
+
+ printf("<tr><td><input type=submit name=createshare value=\"Create Share\"></td>\n");
+ printf("<td><input type=text size=30 name=newshare></td></tr>\n");
printf("</table>");
@@ -591,7 +553,7 @@ static void shares_page(void)
printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
}
- printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
+ printf("<input type=submit name=\"Delete\" value=\"Delete Share\">\n");
if (advanced == 0) {
printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
} else {
@@ -618,9 +580,11 @@ change a password either locally or remotely
*************************************************************/
static BOOL change_password(const char *remote_machine, char *user_name,
char *old_passwd, char *new_passwd,
- int local_flags)
+ BOOL add_user, BOOL enable_user, BOOL disable_user)
{
BOOL ret = False;
+ uint16 acb_info = 0;
+ uint16 acb_mask = 0;
pstring err_str;
pstring msg_str;
@@ -637,13 +601,28 @@ static BOOL change_password(const char *remote_machine, char *user_name,
return ret;
}
- if(!initialize_password_db()) {
+ if (!init_myworkgroup() || !initialise_password_db())
+ {
printf("Can't setup password database vectors.\n<p>");
return False;
}
- ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str),
- msg_str, sizeof(msg_str));
+ if (enable_user)
+ {
+ acb_mask |= ACB_DISABLED;
+ acb_info &= ~ACB_DISABLED;
+ }
+
+ if (disable_user)
+ {
+ acb_mask |= ACB_DISABLED;
+ acb_info |= ACB_DISABLED;
+ }
+
+ ret = local_password_change(user_name, add_user,
+ acb_info, acb_mask,
+ new_passwd, err_str, sizeof(err_str),
+ msg_str, sizeof(msg_str));
if(*msg_str)
printf("%s\n<p>", msg_str);
@@ -660,7 +639,6 @@ static void chg_passwd(void)
{
char *host;
BOOL rslt;
- int local_flags = 0;
/* Make sure users name has been specified */
if (strlen(cgi_variable(SWAT_USER)) == 0) {
@@ -669,10 +647,10 @@ static void chg_passwd(void)
}
/*
- * smbpasswd doesn't require anything but the users name to delete, disable or enable the user,
+ * smbpasswd doesn't require anything but the users name to disable or enable the user,
* so if that's what we're doing, skip the rest of the checks
*/
- if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) {
+ if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG)) {
/*
* If current user is not root, make sure old password has been specified
@@ -711,27 +689,18 @@ static void chg_passwd(void)
} else {
host = "127.0.0.1";
}
-
- /*
- * Set up the local flags.
- */
-
- local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0);
- local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0);
- local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0);
- local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0);
-
rslt = change_password(host,
cgi_variable(SWAT_USER),
cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD),
- local_flags);
+ cgi_variable(ADD_USER_FLAG)? True : False,
+ cgi_variable(ENABLE_USER_FLAG)? True : False,
+ cgi_variable(DISABLE_USER_FLAG)? True : False);
- if(local_flags == 0) {
- if (rslt == True) {
- printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER));
- } else {
- printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER));
- }
+
+ if (rslt == True) {
+ printf("<p> The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER));
+ } else {
+ printf("<p> The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER));
}
return;
@@ -783,8 +752,6 @@ static void passwd_page(void)
if (demo_mode || am_root()) {
printf("<input type=submit name=%s value=\"Add New User\">\n",
ADD_USER_FLAG);
- printf("<input type=submit name=%s value=\"Delete User\">\n",
- DELETE_USER_FLAG);
printf("<input type=submit name=%s value=\"Disable User\">\n",
DISABLE_USER_FLAG);
printf("<input type=submit name=%s value=\"Enable User\">\n",
@@ -796,7 +763,7 @@ static void passwd_page(void)
* Do some work if change, add, disable or enable was
* requested. It could be this is the first time through this
* code, so there isn't anything to do. */
- if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
+ if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) ||
(cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
chg_passwd();
}
@@ -819,7 +786,7 @@ static void passwd_page(void)
printf("<tr><td> Re-type New Password : </td>\n");
printf("<td><input type=password size=30 name=%s></td></tr>\n",NEW2_PSWD);
printf("<tr><td> Remote Machine : </td>\n");
- printf("<td><input type=text size=30 name=%s></td></tr>\n",RHOST);
+ printf("<td><input type=password size=30 name=%s></td></tr>\n",RHOST);
printf("</table>");
@@ -858,37 +825,26 @@ static void printers_page(void)
printf("<H2>Printer Parameters</H2>\n");
- printf("<H3>Important Note:</H3>\n");
- printf("Printer names marked with [*] in the Choose Printer drop-down box ");
- printf("are autoloaded printers from ");
- printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">Printcap Name</A>.\n");
- printf("Attempting to delete these printers from SWAT will have no effect.\n");
-
if (cgi_variable("Advanced") && !cgi_variable("Basic"))
advanced = 1;
if (cgi_variable("Commit") && snum >= 0) {
commit_parameters(snum);
- if (snum >= iNumNonAutoPrintServices)
- save_reload(snum);
- else
- save_reload(0);
+ save_reload();
}
if (cgi_variable("Delete") && snum >= 0) {
lp_remove_service(snum);
- save_reload(0);
+ save_reload();
share = NULL;
snum = -1;
}
if (cgi_variable("createshare") && (share=cgi_variable("newshare"))) {
- load_config(False);
lp_copy_service(GLOBALS_SNUM, share);
- iNumNonAutoPrintServices = lp_numservices();
snum = lp_servicenumber(share);
lp_do_parameter(snum, "print ok", "Yes");
- save_reload(0);
+ save_reload();
snum = lp_servicenumber(share);
}
@@ -902,36 +858,23 @@ static void printers_page(void)
for (i=0;i<lp_numservices();i++) {
s = lp_servicename(i);
if (s && (*s) && strcmp(s,"IPC$") && lp_print_ok(i)) {
- if (i >= iNumNonAutoPrintServices)
- printf("<option %s value=\"%s\">[*]%s\n",
- (share && strcmp(share,s)==0)?"SELECTED":"",
- s, s);
- else
printf("<option %s value=\"%s\">%s\n",
(share && strcmp(share,s)==0)?"SELECTED":"",
s, s);
}
}
- printf("</select></td>");
- if (have_write_access) {
- printf("<td><input type=submit name=\"Delete\" value=\"Delete Printer\"></td>\n");
- }
- printf("</tr>");
- printf("</table>\n");
+ printf("</select></td></tr><p>");
- if (have_write_access) {
- printf("<table>\n");
- printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
- printf("<td><input type=text size=30 name=newshare></td></tr>\n");
- printf("</table>");
- }
+ printf("<tr><td><input type=submit name=createshare value=\"Create Printer\"></td>\n");
+ printf("<td><input type=text size=30 name=newshare></td></tr>\n");
+ printf("</table>");
if (snum >= 0) {
if (have_write_access) {
printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
}
- printf("<input type=reset name=\"Reset Values\" value=\"Reset Values\">\n");
+ printf("<input type=submit name=\"Delete\" value=\"Delete Printer\">\n");
if (advanced == 0) {
printf("<input type=submit name=\"Advanced\" value=\"Advanced View\">\n");
} else {
@@ -964,21 +907,12 @@ static void printers_page(void)
int opt;
char *page;
- fault_setup(NULL);
-
-#if defined(HAVE_SET_AUTH_PARAMETERS)
- set_auth_parameters(argc, argv);
-#endif /* HAVE_SET_AUTH_PARAMETERS */
-
/* just in case it goes wild ... */
alarm(300);
dbf = sys_fopen("/dev/null", "w");
- if (!dbf) dbf = stderr;
- /* we don't want stderr screwing us up */
- close(2);
- open("/dev/null", O_WRONLY);
+ if (!dbf) dbf = stderr;
while ((opt = getopt(argc, argv,"s:a")) != EOF) {
switch (opt) {
@@ -992,9 +926,7 @@ static void printers_page(void)
}
charset_initialise();
- load_config(True);
- iNumNonAutoPrintServices = lp_numservices();
- load_printers();
+ load_config();
cgi_setup(SWATDIR, !demo_mode);
@@ -1002,34 +934,24 @@ static void printers_page(void)
cgi_load_variables(NULL);
- if (!file_exist(servicesf, NULL)) {
- have_read_access = True;
- have_write_access = True;
- } else {
- /* check if the authenticated user has write access - if not then
- don't show write options */
- have_write_access = (access(servicesf,W_OK) == 0);
-
- /* if the user doesn't have read access to smb.conf then
- don't let them view it */
- have_read_access = (access(servicesf,R_OK) == 0);
- }
-
-
show_main_buttons();
page = cgi_pathinfo();
+ /* check if the authenticated user has write access - if not then
+ don't show write options */
+ have_write_access = (access(servicesf,W_OK) == 0);
+
/* Root gets full functionality */
- if (have_read_access && strcmp(page, "globals")==0) {
+ if (strcmp(page, "globals")==0) {
globals_page();
- } else if (have_read_access && strcmp(page,"shares")==0) {
+ } else if (strcmp(page,"shares")==0) {
shares_page();
- } else if (have_read_access && strcmp(page,"printers")==0) {
+ } else if (strcmp(page,"printers")==0) {
printers_page();
- } else if (have_read_access && strcmp(page,"status")==0) {
+ } else if (strcmp(page,"status")==0) {
status_page();
- } else if (have_read_access && strcmp(page,"viewconfig")==0) {
+ } else if (strcmp(page,"viewconfig")==0) {
viewconfig_page();
} else if (strcmp(page,"passwd")==0) {
passwd_page();
diff --git a/source/winregd/srv_reg_nt.c b/source/winregd/srv_reg_nt.c
new file mode 100644
index 00000000000..e213f721e59
--- /dev/null
+++ b/source/winregd/srv_reg_nt.c
@@ -0,0 +1,224 @@
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997,
+ * Copyright (C) Lars Kneschke 2000.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+
+/****************************************************************************
+ set reg name
+****************************************************************************/
+static BOOL set_policy_reg_name(struct policy_cache *cache, POLICY_HND * hnd,
+ fstring name)
+{
+ char *dev = strdup(name);
+ if (dev != NULL)
+ {
+ if (set_policy_state(cache, hnd, NULL, (void *)dev))
+ {
+ DEBUG(3, ("Registry setting policy name=%s\n", name));
+ return True;
+ }
+ free(dev);
+ }
+
+ DEBUG(3, ("Error setting policy name=%s\n", name));
+ return False;
+}
+
+/****************************************************************************
+ get reg name
+****************************************************************************/
+static BOOL get_policy_reg_name(struct policy_cache *cache, POLICY_HND * hnd,
+ fstring name)
+{
+ char *dev = (char *)get_policy_state_info(cache, hnd);
+
+ if (dev != NULL)
+ {
+ fstrcpy(name, dev);
+ DEBUG(5, ("getting policy reg name=%s\n", name));
+ return True;
+ }
+
+ DEBUG(3, ("Error getting policy reg name\n"));
+ return False;
+}
+
+#if 0
+/*******************************************************************
+ reg_reply_unknown_1
+ ********************************************************************/
+static void reg_reply_close(REG_Q_CLOSE * q_r, prs_struct * rdata)
+{
+ REG_R_CLOSE r_u;
+
+ /* set up the REG unknown_1 response */
+ bzero(r_u.pol.data, POL_HND_SIZE);
+
+ /* close the policy handle */
+ if (close_policy_hnd(get_global_hnd_cache(), &(q_r->pol)))
+ {
+ r_u.status = NT_STATUS_NOPROBLEMO;
+ }
+ else
+ {
+ r_u.status = NT_STATUS_OBJECT_NAME_INVALID;
+ }
+
+ DEBUG(5, ("reg_unknown_1: %d\n", __LINE__));
+
+ /* store the response in the SMB stream */
+ reg_io_r_close("", &r_u, rdata, 0);
+
+ DEBUG(5, ("reg_unknown_1: %d\n", __LINE__));
+}
+
+
+#endif
+/*******************************************************************
+ _reg_close
+ ********************************************************************/
+uint32 _reg_close(POLICY_HND * pol)
+{
+ /* close the policy handle */
+ if (!close_policy_hnd(get_global_hnd_cache(), pol))
+ {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _reg_open
+ ********************************************************************/
+uint32 _reg_open(POLICY_HND * pol, uint32 access_mask)
+{
+ /* get a (unique) handle. open a policy on it. */
+ if (!open_policy_hnd(get_global_hnd_cache(), get_sec_ctx(),
+ pol, access_mask))
+ {
+ return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _reg_open_entry
+ ********************************************************************/
+uint32 _reg_open_entry(const POLICY_HND * pol, const UNISTR2 * uni_name,
+ uint32 unknown_0, uint32 access_mask,
+ POLICY_HND * entry_pol)
+{
+ fstring name;
+
+ if (find_policy_by_hnd(get_global_hnd_cache(), pol) == -1)
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!open_policy_hnd_link(get_global_hnd_cache(),
+ pol, entry_pol, access_mask))
+ {
+ return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
+ }
+
+ unistr2_to_ascii(name, uni_name, sizeof(name) - 1);
+
+ /* lkcl XXXX do a check on the name, here */
+ if (!strequal
+ (name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions")
+ && !strequal(name,
+ "SYSTEM\\CurrentControlSet\\Services\\NETLOGON\\Parameters\\"))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ if (!set_policy_reg_name(get_global_hnd_cache(), entry_pol, name))
+ {
+ return NT_STATUS_TOO_MANY_SECRETS; /* ha ha very droll */
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+/*******************************************************************
+ _reg_info
+ ********************************************************************/
+uint32 _reg_info(POLICY_HND* pol, BUFFER2* buf, uint32* type)
+{
+ fstring name;
+
+ if (!get_policy_reg_name(get_global_hnd_cache(), pol, name))
+ {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (strequal(name, "SYSTEM\\CurrentControlSet\\Control\\ProductOptions"))
+ {
+ char *key;
+ if (lp_server_role() == ROLE_DOMAIN_PDC)
+ {
+ key = "ServerNT";
+ }
+ else
+ {
+ key = "LanmanNT";
+ }
+ make_buffer2(buf, key, strlen(key));
+ *type = 0x1;
+ }
+ else
+ {
+ return 0x2; /* Win32 status code. ick */
+ }
+
+ return NT_STATUS_NOPROBLEMO;
+}
+
+#if 0
+
+/*******************************************************************
+ array of \PIPE\reg operations
+ ********************************************************************/
+static struct api_struct api_reg_cmds[] = {
+ {"REG_CLOSE", REG_CLOSE, api_reg_close},
+ {"REG_OPEN_ENTRY", REG_OPEN_ENTRY, api_reg_open_entry},
+ {"REG_OPEN", REG_OPEN_HKLM, api_reg_open},
+ {"REG_INFO", REG_INFO, api_reg_info},
+ {NULL, 0, NULL}
+};
+
+/*******************************************************************
+ receives a reg pipe and responds.
+ ********************************************************************/
+BOOL api_reg_rpc(rpcsrv_struct * p)
+{
+ return api_rpcTNP(p, "api_reg_rpc", api_reg_cmds);
+}
+#endif
diff --git a/source/winregd/winregd.c b/source/winregd/winregd.c
new file mode 100644
index 00000000000..122e65ca760
--- /dev/null
+++ b/source/winregd/winregd.c
@@ -0,0 +1,119 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+fstring pipe_name;
+
+pstring servicesf = CONFIGFILE;
+extern pstring debugf;
+extern BOOL append_log;
+
+/*****************************************************************************
+ initialise srv_auth_fns array
+ *****************************************************************************/
+static void auth_init(rpcsrv_struct *l)
+{
+}
+
+/*************************************************************************
+ initialise an msrpc service
+ *************************************************************************/
+static void service_init(char* service_name)
+{
+ add_msrpc_command_processor( pipe_name, service_name, api_reg_rpc );
+ generate_wellknown_sids();
+}
+
+/****************************************************************************
+ reload the services file
+ **************************************************************************/
+static BOOL reload_msrpc(BOOL test)
+{
+ BOOL ret;
+
+ if (lp_loaded()) {
+ pstring fname;
+ pstrcpy(fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
+ reopen_logs();
+
+ if (test && !lp_file_list_changed())
+ return(True);
+
+ lp_killunused(NULL);
+
+ ret = lp_load(servicesf,False,False,True);
+
+ /* perhaps the config filename is now set */
+ if (!test)
+ reload_msrpc(True);
+
+ reopen_logs();
+
+ load_interfaces();
+
+ return(ret);
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+static int main_init(int argc,char *argv[])
+{
+#ifdef HAVE_SET_AUTH_PARAMETERS
+ set_auth_parameters(argc,argv);
+#endif
+
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ append_log = True;
+
+ TimeInit();
+
+ setup_logging(argv[0],False);
+ fstrcpy(pipe_name, "winreg");
+ slprintf(debugf, sizeof(debugf), "%s/log.%s", LOGFILEBASE, pipe_name);
+
+ return 0;
+}
+
+static msrpc_service_fns fn_table =
+{
+ auth_init,
+ service_init,
+ reload_msrpc,
+ main_init,
+ NULL
+};
+
+msrpc_service_fns *get_service_fns(void)
+{
+ return &fn_table;
+}
diff --git a/source/wkssvcd/srv_wkssvc_nt.c b/source/wkssvcd/srv_wkssvc_nt.c
new file mode 100644
index 00000000000..dbcf2db902c
--- /dev/null
+++ b/source/wkssvcd/srv_wkssvc_nt.c
@@ -0,0 +1,75 @@
+
+/*
+ * Unix SMB/Netbios implementation.
+ * Version 1.9.
+ * RPC Pipe client / server routines
+ * Copyright (C) Andrew Tridgell 1992-1997,
+ * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ * Copyright (C) Paul Ashton 1997.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include "includes.h"
+#include "rpc_parse.h"
+#include "nterr.h"
+
+extern int DEBUGLEVEL;
+extern pstring global_myname;
+
+
+/*******************************************************************
+ create_wks_info_100
+ ********************************************************************/
+static void create_wks_info_100(WKS_INFO_100 *inf)
+{
+ pstring my_name;
+ pstring domain;
+
+ DEBUG(5,("create_wks_info_100: %d\n", __LINE__));
+
+ pstrcpy (my_name, global_myname);
+ strupper(my_name);
+
+ pstrcpy (domain , lp_workgroup());
+ strupper(domain);
+
+ make_wks_info_100(inf,
+ 0x000001f4, /* platform id info */
+ lp_major_announce_version(),
+ lp_minor_announce_version(),
+ my_name, domain);
+}
+
+/*******************************************************************
+ _wks_query_info
+
+ only supports info level 100 at the moment.
+ ********************************************************************/
+uint32 _wks_query_info( const UNISTR2 *srv_name, uint16 switch_value,
+ WKS_INFO_100 *wks100)
+{
+ switch (switch_value)
+ {
+ case 100:
+ {
+ create_wks_info_100(wks100);
+ return NT_STATUS_NOPROBLEMO;
+ }
+ }
+ return NT_STATUS_INVALID_INFO_CLASS;
+}
+
diff --git a/source/wkssvcd/wkssvcd.c b/source/wkssvcd/wkssvcd.c
new file mode 100644
index 00000000000..7c6141bb185
--- /dev/null
+++ b/source/wkssvcd/wkssvcd.c
@@ -0,0 +1,119 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 1.9.
+ Main SMB server routines
+ Copyright (C) Andrew Tridgell 1992-1998
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+fstring pipe_name;
+
+pstring servicesf = CONFIGFILE;
+extern pstring debugf;
+extern BOOL append_log;
+
+/*****************************************************************************
+ initialise srv_auth_fns array
+ *****************************************************************************/
+static void auth_init(rpcsrv_struct *l)
+{
+}
+
+/*************************************************************************
+ initialise an msrpc service
+ *************************************************************************/
+static void service_init(char* service_name)
+{
+ add_msrpc_command_processor( pipe_name, service_name, api_wkssvc_rpc );
+ generate_wellknown_sids();
+}
+
+/****************************************************************************
+ reload the services file
+ **************************************************************************/
+static BOOL reload_msrpc(BOOL test)
+{
+ BOOL ret;
+
+ if (lp_loaded()) {
+ pstring fname;
+ pstrcpy(fname,lp_configfile());
+ if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) {
+ pstrcpy(servicesf,fname);
+ test = False;
+ }
+ }
+
+ reopen_logs();
+
+ if (test && !lp_file_list_changed())
+ return(True);
+
+ lp_killunused(NULL);
+
+ ret = lp_load(servicesf,False,False,True);
+
+ /* perhaps the config filename is now set */
+ if (!test)
+ reload_msrpc(True);
+
+ reopen_logs();
+
+ load_interfaces();
+
+ return(ret);
+}
+
+/****************************************************************************
+ main program
+****************************************************************************/
+static int main_init(int argc,char *argv[])
+{
+#ifdef HAVE_SET_AUTH_PARAMETERS
+ set_auth_parameters(argc,argv);
+#endif
+
+#ifdef HAVE_SETLUID
+ /* needed for SecureWare on SCO */
+ setluid(0);
+#endif
+
+ append_log = True;
+
+ TimeInit();
+
+ setup_logging(argv[0],False);
+ fstrcpy(pipe_name, "wkssvc");
+ slprintf(debugf, sizeof(debugf), "%s/log.%s", LOGFILEBASE, pipe_name);
+
+ return 0;
+}
+
+static msrpc_service_fns fn_table =
+{
+ auth_init,
+ service_init,
+ reload_msrpc,
+ main_init,
+ NULL
+};
+
+msrpc_service_fns *get_service_fns(void)
+{
+ return &fn_table;
+}
diff --git a/swat/help/welcome.html b/swat/help/welcome.html
index 48579d62722..bbde61e5490 100644
--- a/swat/help/welcome.html
+++ b/swat/help/welcome.html
@@ -24,7 +24,6 @@ Please choose a configuration action using one of the above buttons
<li><a href="/swat/help/nmblookup.1.html" target="docs">nmblookup</a> - NetBIOS name query tool
<li><a href="/swat/help/smbtar.1.html" target="docs">smbtar</a> - SMB backup tool
<li><a href="/swat/help/smbclient.1.html" target="docs">smbclient</a> - command line SMB client
- <li><a href="/swat/help/smbspool.8.html" target="docs">smbspool</a> - command line SMB print client
</ul>
<li><b>Configuration Files</b>
<ul>
@@ -35,8 +34,7 @@ Please choose a configuration action using one of the above buttons
<li><b>Miscellaneous</b>
<ul>
<li><a href="/swat/help/samba.7.html" target="docs">Samba introduction</a>
- <li><a href="/swat/help/DOMAIN_MEMBER.html" target="docs">Joining an NT Domain</a>
- <li><a href="/swat/help/NT_Security.html" target="docs">Changing UNIX permissions using NT</a>
+ <li><a href="/swat/help/DOMAIN_MEMBER.html" target="docs">Joining a NT Domain</a>
<li><a href="/swat/help/smbrun.1.html" target="docs">smbrun</a> - internal smbd utility
</ul>
</ul>